Program Listing for File FrameContainer.h#
↰ Return to documentation for file (include/Karana/Frame/FrameContainer.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 FrameContainer class.
*/
#pragma once
#include <memory>
#include <string>
#include "Karana/Frame/OrientedChainedFrameToFrame.h"
#include "Karana/KCore/LockingBase.h"
#include "Karana/KCore/UsageTrackingMap.h"
#include "Karana/Frame/EdgeFrameToFrame.h"
#include "Karana/Frame/Frame.h"
#include "Karana/KCore/Tree.h"
namespace Karana::Frame {
class Frame;
class SpiceFrameToFrame;
namespace kc = Karana::Core;
/**
* @class FrameContainer
* @brief A container class for managing frames and their relationships.
*
* This class provides functionality to create, register, and manage frames,
* as well as establish relationships between frames.
*
* See \sref{frames_layer_sec} for more discussion on
* the frames layer.
*/
class FrameContainer : public kc::LockingBase {
// for access to _edgeOrientation
friend class FrameToFrame;
// For access to container elements for discard
friend class Frame;
friend class EdgeFrameToFrame;
friend class ChainedFrameToFrame;
friend class OrientedChainedFrameToFrame;
// for access to _spce_f2fs_list
friend class SpiceFrameToFrame;
friend class SpiceFrame;
// for access to trackUsage methods
friend class PrescribedFrameToFrame;
public:
/**
* @brief Constructs a FrameContainer with a root frame.
*/
FrameContainer();
/**
* @brief FrameContainer destructor.
*/
virtual ~FrameContainer();
/**
* @brief Create a FrameContainer.
* @param root_frame_name Name for the root frame
* @return The frame container.
*/
static kc::ks_ptr<FrameContainer> create(std::string_view root_frame_name);
/** options struct for dumpString */
struct DumpOptions : LockingBase::DumpOptions {
bool frames = false; ///< frames usage map
bool edges = false; ///< edge usage map
bool oriented = false; ///< oriented f2fs usage map
bool chains = false; ///< regular chains usage map
/**
* @brief Copy assignment operator.
*
* @param p DumpOptions to copy from.
* @return A reference to the assigned DumpOptions.
*/
DumpOptions &operator=(const DumpOptions &p) {
if (this != &p) {
LockingBase::DumpOptions::operator=(p); // Call base class assignment operator
// Assign Derived-specific members here
frames = p.frames;
edges = p.edges;
oriented = p.oriented;
chains = p.chains;
}
return *this;
}
};
/**
* @brief Return a formatted string containing information about this object.
*
* @param prefix String prefix to use for formatting.
* @param options Dump options (if null, defaults will be used).
* @return A string representation of the object.
*/
std::string dumpString(std::string_view prefix = "",
const Base::DumpOptions *options = nullptr) const override;
/**
* @brief Returns the root frame of the tree.
* @return The root frame.
*/
const kc::ks_ptr<Frame> &root() const;
/**
* @brief Return a vector of all Frames with the given name.
* @param name name of the Frame instances to look up
* @return A vector of all the Frames with the given name.
*/
std::vector<kc::ks_ptr<Frame>> lookupFrame(std::string_view name);
/**
* @brief Checks if one frame is an ancestor of another.
* @param oframe The potential ancestor frame.
* @param pframe The potential descendant frame.
* @param strict If false, a frame can be its own ancestor
* @return True if oframe is an ancestor of pframe, false otherwise.
*/
bool isAncestorOf(const Frame &oframe, const Frame &pframe, bool strict);
/**
* @brief Gets the common ancestor of two frames.
* @param frame1 The first frame.
* @param frame2 The second frame.
* @return The common ancestor frame.
*/
const kc::ks_ptr<Frame> &getAncestor(const Frame &frame1, const Frame &frame2);
public:
/* these are public for use by SOADyn */
/**
* @brief Method to track usage of a Frame instance.
*
* These methods need to be public to allow specialized classes
* (e.g., multibody) ones to call them
*
* @param frame the new Frame to track
*/
void trackUsageFrame(const kc::ks_ptr<Frame> &frame);
/**
* @brief Method to track usage of an EdgeFrameToFrame instance.
*
* These methods need to be public to allow specialized classes
* (e.g., multibody) ones to call them
*
* @param f2f the new EdgeFrameToFrame to track
*/
void trackUsageEdgeFrameToFrame(const kc::ks_ptr<EdgeFrameToFrame> &f2f);
/**
* @brief Method to track usage of an OrientedChainedFrameToFrame instance.
*
* These methods need to be public to allow specialized classes
* (e.g., multibody) ones to call them
*
* @param of2f the new Frame to track
*/
void
trackUsageOrientedChainedFrameToFrame(const kc::ks_ptr<OrientedChainedFrameToFrame> &of2f);
/**
* @brief Method to track usage of an ChainedFrameToFrame instance.
*
* These methods need to be public to allow specialized classes
* (e.g., multibody) ones to call them
*
* @param cf2f the new Frame to track
*/
void trackUsageChainedFrameToFrame(const kc::ks_ptr<ChainedFrameToFrame> &cf2f);
/** @brief Return a vector of all the ChainedFrameToFrames in the FrameContainer.
*
* @return List of all the chain elements.
*/
std::vector<kc::ks_ptr<ChainedFrameToFrame>> chainedFrameToFrames();
public:
/** @brief Return a vector of all the frames in the FrameContainer.
*
* @return List of all the frame elements.
*/
std::vector<kc::ks_ptr<Frame>> frames();
/** @brief Return a vector of all the EdgeFrameToFrames in the FrameContainer.
*
* @return List of all the edge elements.
*/
std::vector<kc::ks_ptr<EdgeFrameToFrame>> edgeFrameToFrames();
/** @brief Freeze the OrientedChainedFrameToFrame that connects this frame to the root.
* This will effectively freeze all edges in the path.
*
* @param frame the downstream terminal frame
*/
void freezeUpstream(const kc::ks_ptr<Frame> &frame);
/** @brief Unfreeze the OrientedChainedFrameToFrame that connects this frame to the root.
* This will effectively unfreeze all edges in the path.
*
* @param frame the downstream terminal frame
*/
void unfreezeUpstream(const kc::ks_ptr<Frame> &frame);
/**
* @brief Set the ephemeris time
*
* The ephemeris time is needed by Spice frames
*
* @param ephemeris_time the ephemeris time
*/
void setEphemerisTime(double ephemeris_time);
/**
* @brief Return the current ephemeris time
*
* The ephemeris time is needed by Spice frames
*
* @return the current ephemeris time
*/
double getEphemerisTime();
/**
* @brief Return true if this FrameContainer is using spice frames, false otherwise.
*
* @return true if this FrameContainer is using spice frames, false otherwise.
*/
bool isUsingSpice();
/**
* @brief Display the frame tree hierarchy starting from a specific frame
*
* @param prefix the string prefix for each line of the displayed output
* @param f the root Frame for the start of the tree display
* @param callback the function to generate each frame's display string
*/
void dumpFrameTree(std::string_view prefix,
const Frame &f,
const std::function<std::string(const Frame &)> &callback) const;
/**
* @brief Return the frame ids tracking their hierarchy
*
* @returns the ids tree
*/
const std::unique_ptr<const kc::Tree<kc::id_t>> &tree() { return _tree; }
protected:
/**
* @brief - Discard the FrameContainer.
* @param base - Pointer to the FrameContainer.
*/
void _discard(kc::ks_ptr<Base> &base) override;
// void _ensureTree();
void _makeNotHealthy() override;
void _makeHealthy() override;
/**
* @brief Return true if the sub_f2f path is contained within the
* f2f's oframe/pframe path and oriented with the path, false
* if it has opposed orientation, and nullopt if it is not full
* contained on the path at all.
*
* @param f2f The frame to frame we want to check if sub_f2f is contained within.
* @param sub_f2f The sub-frame this method checks is contained within f2f.
* @returns true if the sub_f2f path is contained within the f2f's oframe/pframe path,
* false if it has opposed orientation, and nullopt if it is not contained
* in the path.
*/
std::optional<bool> _subchainOrientation(const FrameToFrame &f2f,
const FrameToFrame &sub_f2f) const;
/** List of all SpiceFrameToFrame instances */
kc::RegistryList<FrameToFrame> _spice_f2fs_list;
private:
kc::UsageTrackingMap<kc::id_t, Frame> _frame_usage_map;
kc::UsageTrackingMap<kc::id_t, EdgeFrameToFrame> _edge_usage_map;
kc::UsageTrackingMap<std::pair<kc::id_t, kc::id_t>, ChainedFrameToFrame> _chain_usage_map;
kc::UsageTrackingMap<std::pair<kc::id_t, kc::id_t>, OrientedChainedFrameToFrame>
_oriented_chain_usage_map;
mutable std::unique_ptr<const kc::Tree<kc::id_t>> _tree;
kc::ks_ptr<Frame> _root_frame;
double _ephemeris_time = km::notReadyNaN;
};
} // namespace Karana::Frame