Warning, /education/kstars/README.timekeeping is written in an unsupported language. File is not indexed.

0001 README.timekeeping:  Keeping time in KStars
0002 copyright 2002 by Jason Harris and the KStars team.
0003 This document is licensed under the terms of the GNU Free Documentation License
0004 -------------------------------------------------------------------------------
0005 
0006 
0007 1. The Basics
0008 
0009 Timekeeping is handled by the SimClock class.  SimClock stores the 
0010 simulation time as the Julian Day, in a long double variable 
0011 ("julian").  A long double is required to provide sub-second resolution 
0012 in the Julian Day value.  The date can be converted to a calendar date 
0013 (QDateTime object) with the UTC() function.  julian is updated every 
0014 0.1 sec by an internal QTimer, using the SimClock::tick() SLOT, 
0015 connected to the internal QTimer's timeout() SIGNAL.
0016 
0017 We make a distinction between "system time" and "simulation time".  
0018 System time is real time, according to the computer's CPU clock.  
0019 Simulation time is the time according to KStars; since the time and 
0020 date are adjustable, system time and simulation time can have an 
0021 arbitrary offset.  Furthermore, SimClock has an adjustable Scale 
0022 parameter that determines how many seconds of simulation time pass for 
0023 each second of system time.  Scale can even be negative, indicating 
0024 that the simulation clock is running backwards.
0025 
0026 The simplest way to advance the simulation time would be to add 
0027 (0.1*Scale) seconds to julian every time tick() is called.  However, 
0028 this is not accurate, because there is always some error associated 
0029 with the time it takes to execute tick(), and these errors would 
0030 accumulate during each cycle.  Instead, tick() measures the elapsed 
0031 time since some fixed system-time marker ("sysmark"), and adds 
0032 (elapsed_time*Scale) seconds to "julianmark", a fixed simulation-time 
0033 marker that was the exact simulation time at the moment the system-time 
0034 marker was set.  This is much more accurate, because any errors in 
0035 tick() do not accumulate.  Any time the clock is started, or its 
0036 scale changed, the sysmark and julianmark markers are reset (they are 
0037 also reset if they have not changed in more than 24 hours of real time).
0038 
0039 tick() emits the timeAdvanced() signal, which is connected to 
0040 KStarsData::updateTime(), which takes care of updating object 
0041 coordinates and drawing the skymap (see below for details).
0042 
0043 Note also that the SimClock class only handles the Julian Day and the 
0044 Universal Time, not the local time.  Time zone corrections and daylight
0045 savings time are handled by KStarsData::updateTime().
0046 
0047 
0048 2. Manual Mode
0049 
0050 The above procedure works well, as long as tick() takes less than 0.1 sec, 
0051 on average (including the time taken by KStarsData::updateTime()).  In 
0052 practice, large values of Scale cause more calls to updateTime() than the 
0053 CPU is able to handle.  This results in some time steps being skipped 
0054 altogether, which makes the simulation seem jerky.
0055 
0056 To compensate for this, we implemented a "Manual Mode" for SimClock.  In 
0057 Manual mode, the internal QTimer is stopped, so that tick() is not 
0058 triggered every 0.1 seconds.  Instead, a similar function (manualTick()) 
0059 is called whenever KStarsData::updateTime() has finished.  manualTick()
0060 adds Scale seconds to the simulation time.  So, the Scale parameter has
0061 a slightly different meaning in Manual mode.  The simulation time
0062 no longer runs at strictly Scale seconds per real-time second; rather, 
0063 every update of the simulation occurs exactly Scale simulation-seconds 
0064 after the previous update, no matter how long the update takes.
0065 
0066 There are two bool variables in SimClock, ManualMode and ManualActive. 
0067 The first controls whether the clock is using Manual Mode (accessed by 
0068 isManualMode()); the second controls whether the clock is running in 
0069 Manual Mode (recall that the internal timer is halted when in Manual 
0070 Mode).  The function isActive() returns whether the clock is running, 
0071 for both the standard mode and Manual Mode.
0072 
0073 
0074 3. KStarsData::updateTime()
0075 
0076 updateTime() is a SLOT connected to the SimClock's timeAdvanced() 
0077 SIGNAL, which is emitted every tick() or manualTick().
0078 
0079 KStarsData keeps its own representation of the universal time as a 
0080 QDateTime object (UTime); the first thing that updateTime() does is to
0081 reset this with clock->UTC().  It then sets the local time QDateTime 
0082 object (LTime) by adding 3600*geo->TZ() seconds to UTime.  It then 
0083 checks if it has reached the next daylight savings time change point, 
0084 and adjusts the Time Zone offset, if necessary.
0085 
0086 There is a group of time-dependent numbers such as the obliquity and 
0087 the sun's mean anomaly; these are kept in the KSNumbers class.  The next 
0088 thing updateTime() does is create a KSNumbers object appropriate for the 
0089 current julian day value [we may be able to save some time by keeping a 
0090 persistent KSNumbers object, and not updating it on every call to 
0091 updateTime(), as the values stored there don't change very quickly].
0092 
0093 There are several things that don't need to be updated on every call to
0094 updateTime().  To save time, we only update them if a certain amount of 
0095 time has passed since the last update.  For example, the LastNumUpdate 
0096 variable stores the julian day of the last time object coordinates were 
0097 updated for precession/nutation/aberration.  This needs to happen once 
0098 per simulation day, so whenever (CurrentDate-LastNumUpdate) exceeds 1.0,
0099 it signals the update (by setting needNewCoords=true) and resets 
0100 LastNumUpdate to CurrentDate.  Similarly, we use LastPlanetUpdate to 
0101 update planet coordinates 100 times per day.  LastSkyUpdate monitors
0102 the last time the horizontal coordinates were updated (the update 
0103 interval is dependent on the current zoom setting).  
0104 
0105 Next, we update the focus position.  If no object is being tracked, and
0106 useAltAz=true, then the focus RA needs to advance at the sidereal rate 
0107 (one second on the sky per sidereal second of time).  If the simulation 
0108 is tracking an object, then the focus is set to the object's coordinates.
0109 (See README.skymap for details on the focus position and animated 
0110 slewing)
0111 
0112 Finally, the last thing updateTime() does is to re-draw the sky by calling
0113 SkyMap::update(); see README.skymap for details.