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