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.