Program Listing for File TimeKeeper.h#
↰ Return to documentation for file (include/Karana/SOADyn/TimeKeeper.h)
/*
* Copyright (c) 2024-2026 Karana Dynamics Pty Ltd. All rights reserved.
*
* NOTICE TO USER:
*
* This source code and/or documentation (the "Licensed Materials") is
* the confidential and proprietary information of Karana Dynamics Inc.
* Use of these Licensed Materials is governed by the terms and conditions
* of a separate software license agreement between Karana Dynamics and the
* Licensee ("License Agreement"). Unless expressly permitted under that
* agreement, any reproduction, modification, distribution, or disclosure
* of the Licensed Materials, in whole or in part, to any third party
* without the prior written consent of Karana Dynamics is strictly prohibited.
*
* THE LICENSED MATERIALS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
* KARANA DYNAMICS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL KARANA DYNAMICS BE LIABLE FOR ANY DAMAGES WHATSOEVER,
* INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, DATA, OR USE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, WHETHER IN CONTRACT, TORT,
* OR OTHERWISE ARISING OUT OF OR IN CONNECTION WITH THE LICENSED MATERIALS.
*
* U.S. Government End Users: The Licensed Materials are a "commercial item"
* as defined at 48 C.F.R. 2.101, and are provided to the U.S. Government
* only as a commercial end item under the terms of this license.
*
* Any use of the Licensed Materials in individual or commercial software must
* include, in the user documentation and internal source code comments,
* this Notice, Disclaimer, and U.S. Government Use Provision.
*/
/**
* @file
* @brief Contains the declarations for the TimeKeeper classes.
*/
#pragma once
#include "Karana/Frame/FrameContainer.h"
#include "Karana/Math/Defs.h"
namespace Karana::Dynamics {
namespace km = Karana::Math;
namespace kc = Karana::Core;
namespace kf = Karana::Frame;
// Forward declaration
class TimeKeeper;
/**
* @brief The time types that TimeKeeper can convert to/from.
*/
enum class TimeType {
/**
* @brief ET ephemeris time in seconds. This is the number of seconds past the J2000 epoch
* in TDB (Barycentric Dynamical Time).
*/
ET,
TAI, ///< International Atomic Time seconds since the ephemeris J2000 epoch in TAI.
UTC, ///< Coordinated Universal Time seconds since the J2000 epoch in UTC.
GPS, ///< GPS Time seconds since the J2000 epoch in GPS.
UT1, ///< UT1 seconds since the J2000 epoch in UT1.
TT, ///< Terrestrial Time seconds since the J2000 epoch in TT.
JDTT, ///< Terrestrial Time Julian Date in days since J2000.
JDUTC, ///< Coordinated Universal Time Julian Date in days since J2000.
MJDTT, ///< Terrestrial Time Modified Julian Date in days since J2000.
MJDUTC, ///< Coordinated Universal Time Modified Julian Date in days since J2000.
};
/**
* @class TimeKeeperVars
* @brief Vars for the TimeKeeper class.
*/
class TimeKeeperVars : public kc::BaseVars {
public:
/**
* @brief TimeKeeperVars constructor. The constructor is not meant to be
* called directly. Please use the create(...) method instead to create
* an instance.
*
* @param time_keeper The TimeKeeper associated with these vars.
*/
TimeKeeperVars(const kc::ks_ptr<const TimeKeeper> time_keeper);
/**
* @brief Destructor.
*/
~TimeKeeperVars();
/**
* @brief Create a new instanced of TimeKeeperVars.
*
* @param time_keeper The TimeKeeper associated with these vars.
* @returns A pointer to the newly created instance of TimeKeeperVars.
*/
static kc::ks_ptr<TimeKeeperVars> create(const kc::ks_ptr<const TimeKeeper> time_keeper);
/// The current time.
kc::ks_ptr<kc::Var_T<double>> time;
/**
* @brief Get all the Vars that this TimeKeeperVars has.
*
* @returns A NestedVars struct with all of this TimeKeeperVars's vars.
*/
kc::NestedVars getAllVars() const override;
};
/**
* @brief Keeps track of time.
*/
class TimeKeeper : public kc::BaseWithVars {
public:
/**
* @brief System-clock time point with microsecond storage.
*/
using TimePoint =
std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;
/**
* @brief TimeKeeper constructor. The constructor is not meant to be called
* directly. Please use the corresponding create(...) method instead to create an
* instance.
*
* @param fc FrameContainer. Used to update ephemeris in derived classes.
* The _initial_ephemeris will also be set to the FrameContainer's current ephemeris.
*/
TimeKeeper(const kc::ks_ptr<kf::FrameContainer> &fc);
/**
* @brief Create a new instance of TimeKeeper.
*
* @param fc FrameContainer. Used to update ephemeris in derived classes.
* The _initial_ephemeris will also be set to the FrameContainer's current ephemeris.
* @returns A pointer to the newly created instance of TimeKeeper.
*/
static kc::ks_ptr<TimeKeeper> create(const kc::ks_ptr<kf::FrameContainer> &fc);
/**
* @brief Copy constructor.
*
* @param other The TimeKeeper instance to copy from.
*/
TimeKeeper(const TimeKeeper &other);
/**
* @brief Get the time since the initial ephemeris from TimeKeeper.
*
* This is the time from the initial ephemeris in ET time.
*
* @return The current time in seconds since the initial ephemeris.
*/
const km::Ktime &getTime() const;
/**
* @brief Get the current time in the requested representation.
*
* @param time_type Requested output representation.
* @return The number of seconds or days since the J2000 epoch.
* Seconds for second-based types and days for Julian-date-like.
* types.
*/
double getTime(TimeType time_type) const;
/**
* @brief Get the current time as a UTC-like system clock time.
*
* @return The current time converted to a UTC-like system clock time.
*/
TimePoint getDateTime() const;
/**
* @brief Set the TimeKeeper's time.
*
* @param time The current time.
*/
virtual void setTime(const km::Ktime &time);
/**
* @brief Determine if the TimeKeeper is initialized.
*
* @return true if initialized, false otherwise.
*/
bool isReady() const override;
/**
* @brief Set the initial ephemeris.
*
* @param initial_ephemeris The initial ephemeris. This is in seconds for second-based
* types, and days for `JD` and `MJD`.
* @param type Time representation of `initial_ephemeris`.
*/
void setInitialEphemeris(double initial_ephemeris, TimeType type);
/**
* @brief Set the initial ephemeris from a UTC-like time point.
*
* @param time_point The UTC time point to use as the initial ephemeris.
*/
void setInitialEphemeris(const TimePoint &time_point);
/**
* @brief Set \f$\Delta UT1 = UT1 - UTC\f$.
*
* @param delta_ut1_seconds UT1 offset in seconds.
*/
void setUT1Offset(double delta_ut1_seconds);
/**
* @brief Get the configured \f$\Delta UT1 = UT1 - UTC\f$.
*
* @return UT1 offset in seconds.
* @throws std::runtime_error if the value is still uninitialized.
*/
double getUT1Offset() const;
/**
* @brief Enable or disable the periodic relativistic correction.
*
* @param enable If true, inputs/outputs include the periodic ET-to-TT
* correction; if false, ET and TT seconds are treated as equal.
*/
void setRelativisticCorrection(bool enable);
/**
* @brief Check whether the periodic relativistic correction is enabled.
*
* @return True when the relativistic correction is enabled; false otherwise.
*/
bool getRelativisticCorrection() const;
/**
* @brief Set the leap seconds file.
*
* @param leap_seconds_file Filepath to the leap seconds file.
*/
void setLeapSecondsFile(const std::filesystem::path &leap_seconds_file);
/**
* @brief Get the loaded leap-second filepath.
*
* @return Configured path to the leap seconds file.
*/
const std::filesystem::path &getLeapSecondsFile() const;
protected:
Karana::Core::ks_ptr<Karana::Core::BaseVars> _getVars() const override;
/// The current time.
km::Ktime _time;
/// The FrameContainer to keep in sync.
kc::ks_ptr<kf::FrameContainer> _fc;
/// Initial ephemeris.
double _initial_ephemeris = km::notReadyNaN;
private:
/**
* @brief Load the configured leap second table into memory.
*/
void _loadLeapSeconds();
/**
* @brief Convert a user scalar input to ET seconds.
*
* @param value Input value. Seconds for second-based types, days for
* days-based types.
* @param type Time representation of `value`.
* @return ET elapsed seconds under the current conversion settings since
* the J2000 epoch.
*/
[[nodiscard]] double _convertToEt(double value, TimeType type) const;
/**
* @brief Recompute the stored initial ephemeris from saved user input.
*
* This is used when conversion settings change after the user has already
* provided an initial epoch.
*/
void _updateInitialEphemeris();
/**
* @brief Saved scalar input value used to recompute `_initial_ephemeris`.
*/
double _initial_input_value{Math::notReadyNaN};
/**
* @brief Saved scalar input type used to recompute `_initial_ephemeris`.
*/
TimeType _initial_input_type{TimeType::ET};
/**
* @brief Configured \f$\Delta UT1 = UT1 - UTC\f$ in seconds.
*/
double _ut1_offset_seconds{km::notReadyNaN};
/**
* @brief Whether to apply the periodic ET-TT relativistic correction.
*/
bool _relativistic_correction_enabled{true};
/**
* @brief Path to the TAI-UTC leap-second table.
*/
std::filesystem::path _leap_seconds_path{};
};
} // namespace Karana::Dynamics