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.