C++ Module: spiceInterface
Executive Summary
The SPICE interface class gets time and planetary or spacecraft body information from the JPL ephemeris library
The module
PDF Description
contains further information on this module’s function,
how to run it, as well as testing.
Message Connection Descriptions
The following table lists all the module input and output messages. The module msg connection is set by the user from python. The msg type contains a link to the message structure definition, while the description provides information on what this message is used for.
Msg Variable Name |
Msg Type |
Description |
|---|---|---|
spiceTimeOutMsg |
spice time sampling output message. |
|
epochInMsg |
(optional) input epoch message. |
|
planetStateOutMsgs |
vector of planet state output messages. |
|
scStateOutMsgs |
vector of spacecraft state messages. |
|
attRefStateOutMsgs |
vector of spacecraft attitude reference state output messages. |
|
transRefStateOutMsgs |
vector of spacecraft translation reference state output messages. |
User Guide
This module uses the JPL Spice software to determine the position and orientation of both a celestial body, or a spacecraft. The appropriate Spice kernel must be loaded up to provide the state information for the selected body names.
To setup a celestial body, use the module method addPlanetNames(vector<string>) in python. Multiple object names can be
provided by providing a list of names. With each module update cycle, the corresponding celestial body
states are provided in the vector of output messages planetStateOutMsgs[]. Note that the vector elements are in
the order that the celestial body names were added.
To use this module to read in spacecraft states from a spice kernel, then the spacecraft Spice name is added using
the method addSpacecraftNames(vector<string>). The module provides a vector out corresponding spacecraft state output
messages in three different formats.
scStateOutMsgs[]: these are the SCStatesMsgPayload state output messages that the C++ Module: spacecraft module providesattRefStateOutMsgs[]: these are the attitude reference messages AttRefMsgPayload. These are useful to only prescribe the spacecraft attitude motion.transRefStateOutMsgs[]: these are the translational reference message TransRefMsgPayload. These are useful to only prescribe the translational motion and leave the attitude motion free.
-
class SpiceKernel
- #include <spiceInterface.h>
Thin RAII wrapper around a single SPICE kernel.
The class furnishes a kernel on construction and unloads it on destruction, and provides a static request function that caches instances by canonical absolute path so that a given kernel file is not furnished multiple times.
Public Functions
-
~SpiceKernel() noexcept
Destructor unloads the kernel from SPICE if the load succeeded.
This runs once when the last shared_ptr owning this SpiceKernel instance is destroyed.
-
inline const std::string &getPath() const
Canonical absolute path used as the cache key and SPICE file name.
-
inline bool wasLoadSuccesful() const
True if furnsh_c succeeded for this kernel.
-
SpiceKernel(const SpiceKernel&) = delete
-
SpiceKernel &operator=(const SpiceKernel&) = delete
Public Static Functions
-
static std::shared_ptr<SpiceKernel> request(const std::filesystem::path &path)
Request a shared handle for the kernel at the given path.
The first call for a canonical path constructs a SpiceKernel, which furnishes the kernel once. Later calls for the same path reuse the existing instance as long as it is still alive.
Private Functions
-
explicit SpiceKernel(std::string path)
Construct a SpiceKernel by furnishing the given canonical path.
The constructor switches SPICE into RETURN mode, calls furnsh_c, checks failed_c, and records the load status. The destructor will unload only if loadSucceeded is true.
Private Members
-
std::string path
Canonical absolute path used as the cache key and SPICE file name.
-
bool loadSucceeded
True if furnsh_c succeeded for this kernel.
Private Static Attributes
-
static std::mutex mutex
Static mutex guarding the shared kernel cache.
All access to SpiceKernel::cache must take this lock so that repeated calls to request from different threads do not race.
-
static std::unordered_map<std::string, std::weak_ptr<SpiceKernel>> cache
Global cache mapping canonical absolute paths to weak pointers.
A non expired weak pointer means there is already a live SpiceKernel instance owning that kernel, so request can reuse it instead of calling furnsh_c again.
-
~SpiceKernel() noexcept
-
class SpiceInterface : public SysModel
- #include <spiceInterface.h>
spice interface class
SPICE query reconstruction (opt-in, per planet, per channel)
By default a planet’s state is queried from SPICE at the exact simulation time on every
UpdateStatecall. On a dynamics task evaluated once per integrator sub-step (e.g. MJScene) that is one SPICE call per stage per body. These methods instead reconstruct a planet’s position and/or orientation from a coarse grid of cached SPICE “knots” (spacingknotStepnanoseconds), cutting the SPICE cost to abouthorizon / knotStepper channel.Knobs:
nKnots(stencil size / polynomial order),useVelocity(also match the SPICE velocity at each knot for a Hermite fit, vs a position-only Lagrange fit), andinterpolate(bracket the time with past and future knots, vs past-only extrapolation). The enabled defaults are cubic Hermite interpolation on a 60 s grid.An unconfigured channel stays on the exact SPICE path, bit-for-bit. The emitted velocity and orientation rate are the derivatives of the same reconstruction, so a consumer that Euler-extrapolates them (the classic
gravityEffector) stays self-consistent.-
static uint64_t defaultKnotStep = 60000000000
Default knot spacing when reconstruction is enabled without an explicit
knotStep[ns].
-
void setPlanetPositionReconstruction(const std::string &planetName, uint64_t knotStep = defaultKnotStep, int nKnots = 2, bool useVelocity = true, bool interpolate = true)
Reconstruct this planet’s position from a coarse knot grid.
knotStepin nanoseconds.
-
void setPlanetOrientationReconstruction(const std::string &planetName, uint64_t knotStep = defaultKnotStep, int nKnots = 2, bool useVelocity = true, bool interpolate = true)
Reconstruct this planet’s orientation from a coarse knot grid.
knotStepin nanoseconds.
-
void setPlanetPositionDisabled(const std::string &planetName)
Turn this planet’s position channel off: emit zero position/velocity, no SPICE query.
-
void setPlanetOrientationDisabled(const std::string &planetName)
Turn this planet’s orientation channel off: emit identity attitude/zero rate, no SPICE query.
-
void setPlanetExactSpice(const std::string &planetName)
Revert both channels of this planet to the exact per-call SPICE query (the default).
-
std::pair<long, long> getPlanetSpiceQueryCount(const std::string &planetName)
Total SPICE evaluations spent on this planet since the last Reset, as {position, orientation}. Counts every spkezr_c/sxform_c call regardless of whether the planet uses reconstruction: exact-path calls (once per update) and reconstruction-knot fills alike. A planet added but never queried (e.g. a disabled channel) reads {0, 0}; a name that was never added via addPlanetNames reads {-1, -1}.
Public Functions
-
SpiceInterface()
This constructor initializes the variables that spice uses. Most of them are not intended to be changed, but a couple are user configurable.
-
~SpiceInterface()
The only needed activity in the destructor is to delete the spice I/O buffer that was allocated in the constructor
-
void UpdateState(uint64_t CurrentSimNanos)
This method is the interface point between the upper level simulation and the SPICE interface at runtime. It calls all of the necessary lower level methods.
- Parameters:
CurrentSimNanos – The current clock time for the simulation
-
int loadSpiceKernel(char *kernelName, const char *dataPath)
Load a SPICE kernel for use by this interface.
This function takes a kernel file name and a base directory and ensures that the corresponding SPICE kernel is available to the simulation. Internally the module keeps track of which kernels it has already loaded so that the same file is not loaded multiple times.
- Parameters:
kernelName – File name of the kernel inside dataPath.
dataPath – Directory where the kernel is located.
- Returns:
0 on success, 1 if loading the kernel failed.
-
int unloadSpiceKernel(char *kernelName, const char *dataPath)
Tell this interface that a SPICE kernel is no longer needed.
This function removes the kernel from the set of kernels managed by this interface. Once no users remain, the underlying kernel is also removed from SPICE so it no longer affects future queries.
- Parameters:
kernelName – File name of the kernel inside dataPath.
dataPath – Directory where the kernel is located.
- Returns:
always 0.
-
std::string getCurrentTimeString()
class method
-
void Reset(uint64_t CurrentSimNanos)
Reset the module to origina configuration values.
Reset the module to original configuration values.
-
void initTimeData()
This method is used to initialize the zero-time that will be used to calculate all system time values in the Update method. It also creates the output message for time data
-
void computeGPSData()
This method computes the GPS time data for the current elapsed time. It uses the total elapsed times at both the GPS epoch time and the current time to compute the GPS time (week, seconds, rollovers)
-
void pullSpiceData(std::vector<SpicePlanetStateMsgPayload> *spiceData, uint64_t CurrentSimNanos = 0, bool allowReconstruction = false)
This method gets the state of each spice item that has been added to the module and saves the information off into the array.
-
void writeOutputMessages(uint64_t CurrentClock)
This method takes the values computed in the model and outputs them. It packages up the internal variables into the output structure definitions and puts them out on the messaging system
- Parameters:
CurrentClock – The current simulation time (used for time stamping)
-
void addKernelPath(const std::string &kernelPath)
Add a SPICE kernel by full path (absolute or relative).
-
void addKernelPaths(const std::vector<std::string> &kernelPaths)
Convenience: add many kernels.
-
void clearKernelPaths()
Clear configured kernel paths (does not unload already loaded kernels).
-
void clearKeeper()
Resets all data loaded to SPICE.
Calls
kclear_c, which resets all loaded kernels for all simulations in this process. Avoid using this, as it can affect other simulations running in parallel. Kernels loaded withloadSpiceKernelwill be automatically cleared when all simulations that need it have closed.Deprecated, pending removal 11/20/2026.
-
void addPlanetNames(std::vector<std::string> planetNames)
take a vector of planet name strings and create the vector of planet state output messages and the vector of planet state message payloads
-
void addSpacecraftNames(std::vector<std::string> spacecraftNames)
take a vector of spacecraft name strings and create the vectors of spacecraft state output messages and the vector of spacecraft state message payloads
Public Members
-
Message<SpiceTimeMsgPayload> spiceTimeOutMsg
spice time sampling output message
-
ReadFunctor<EpochMsgPayload> epochInMsg
(optional) input epoch message
-
std::vector<Message<SpicePlanetStateMsgPayload>*> planetStateOutMsgs
vector of planet state output messages
-
std::vector<Message<SCStatesMsgPayload>*> scStateOutMsgs
vector of spacecraft state output messages
-
std::vector<Message<AttRefMsgPayload>*> attRefStateOutMsgs
vector of spacecraft attitude reference state output messages
-
std::vector<Message<TransRefMsgPayload>*> transRefStateOutMsgs
vector of spacecraft translational reference state output messages
-
std::string SPICEDataPath
— Path on file to SPICE data
-
std::string referenceBase
— Base reference frame to use
-
std::string zeroBase
— Base zero point to use for states
-
std::string timeOutPicture
— Optional parameter used to extract time strings
-
bool SPICELoaded
— Boolean indicating to reload spice
-
int charBufferSize
— avert your eyes we’re getting SPICE
-
uint8_t *spiceBuffer
— General buffer to pass down to spice
-
std::string UTCCalInit
— UTC time string for init time
-
std::vector<std::string> planetFrames
— Optional vector of planet frame names. Default values are IAU_ + planet name
-
bool timeDataInit
— Flag indicating whether time has been init
-
double J2000ETInit
s Seconds elapsed since J2000 at init
-
double J2000Current
s Current J2000 elapsed time
-
double julianDateCurrent
s Current JulianDate
-
double GPSSeconds
s Current GPS seconds
-
uint16_t GPSWeek
— Current GPS week value
-
uint64_t GPSRollovers
— Count on the number of GPS rollovers
-
BSKLogger bskLogger
— BSK Logging
Private Functions
-
SpiceReconstruction &reconState()
Return the reconstruction state, lazily creating it on first use.
-
void countSpiceQuery(const std::string &planetName, bool isPosition)
Increment this planet’s position (isPosition=true) or orientation SPICE-query tally.
Private Members
-
std::string GPSEpochTime
— String for the GPS epoch
-
double JDGPSEpoch
s Epoch for GPS time. Saved for efficiency
-
std::vector<SpicePlanetStateMsgPayload> planetData
-
std::vector<SpicePlanetStateMsgPayload> scData
-
std::vector<std::string> kernelPaths
Optional explicit kernel list. If non-empty, Reset() loads these instead.
-
std::set<std::string> configuredLoadedKernelKeys
Track which configured kernel paths have been loaded.
-
std::unordered_map<std::string, std::shared_ptr<SpiceKernel>> loadedKernels
Map of loaded kernel paths to their RAII handles.
As long as an entry is present, the corresponding kernel remains furnished in SPICE. Removing an entry allows the SpiceKernel destructor to unload the kernel when all shared_ptr copies are gone.
-
std::unique_ptr<SpiceReconstruction> recon
-
std::unordered_map<std::string, std::pair<long, long>> spiceQueryCounts
{position, orientation} SPICE-query tallies per planet (uppercase name), counting every spkezr_c/sxform_c call whether it comes from the exact path or a reconstruction knot fill. Reset to zero for the current planet set at each Reset. getPlanetSpiceQueryCount reads this.
-
static uint64_t defaultKnotStep = 60000000000