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 */