WarpTwin
Documentation for WarpTwin models and classes.
Loading...
Searching...
No Matches
SpicePlanet.h
/******************************************************************************
* Copyright (c) ATTX INC 2025. All Rights Reserved.
*
* This software and associated documentation (the "Software") are the 
* proprietary and confidential information of ATTX INC. The Software is 
* furnished under a license agreement between ATTX and the user organization 
* and may be used or copied only in accordance with the terms of the agreement.
* Refer to 'license/attx_license.adoc' for standard license terms.
*
* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION 
* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or 
* transmitted in any form or by any means, for any purpose, without the express 
* written permission of ATTX INC.
******************************************************************************/
/*
SPICE Planet header file

Author: Alex Reynolds
*/
/*
Metadata for MS GUI:
imdata = {"displayname" : "SPICE Planet",
          "exclude" : False,
          "category" : "Assemblies"
}
aliases = {"enable_attitude" : "EXCLUDE",
           "self_id" : "Self",
           "inertial_frame" : "Planet Inertial Frame",
           "rotating_frame" : "Planet Rotating Frame",
           "eq_radius" : "Equatorial Radius",
           "flattening" : "Ellipse Flattening",
           "mu" : "GM",
           "J2" : "J2",
           "J3" : "J3",
           "mean_ang_vel" : "Planet Ang. Vel.",
           "self_id" : "Planet"
}
*/

#ifndef MODELS_ASSEMBLIES_SPICE_PLANET_MODEL_H
#define MODELS_ASSEMBLIES_SPICE_PLANET_MODEL_H

#include "core/CartesianVector.hpp"
#include "simulation/Model.h"
#include "frames/Frame.h"
#include "simulation/SimScheduler.h"
#include "constants/planetdefaults.h"

namespace warptwin {

    /**
     * @brief  High fidelity planet model using the JPL cspice framework under the hood for ultra accurate states
     * 
     * The SPICE planet mode uses the JPL cspice framework to
     * generate highly precise planet state. 
     * 
     * All planet states are set with the inertial state aligned
     * to the J2000 frame. The rotating frame is then set at the
     * same position. The root frame is treated as the base of the
     * J2000 frame used in SPICE, as observed from the Sun. 
     * All states are set relative to that point using the TDB 
     * time maintained by the simulation.
     * 
     * Note that output values semimajor_axis, flattening,
     * mu, J2, J3, and mean angular velocity, are not necessarily
     * loaded from SPICE. Those parameters are first searched in
     * the file clockwerk/utils/planetdefaults.h, which currently
     * defines defaults for all planets, Earth's Moon, and the Sun. 
     * If parameters are not found there, then J2, J3, flattening, mu
     * and semimajor_axis are set to zero.
     * 
     * All DISTANCE units are meters or meters/second
     * All ANGULAR RATE units are radians/second
     * 
     * Author: Alex Reynolds <alex.reynolds@attx.tech>
    */
    class SpicePlanet : public Model {
    public:
        // Model params
        //         NAME                     TYPE                    DEFAULT VALUE
        START_PARAMS
            /** This flag enables or disables outputting attitude states from the SPICE planet. True is enabled */
            SIGNAL(enable_attitude,         int,                    true) 
        END_PARAMS

        // Model inputs
        //         NAME                     TYPE                    DEFAULT VALUE
        START_INPUTS

        END_INPUTS

        // Model outputs
        //         NAME                     TYPE                    DEFAULT VALUE
        START_OUTPUTS
            /** A pointer to the spice planet object itself for easy passing to other models.
             *  Is a void pointer and must be cast in downstream model. Nullptr is set to 
             *  self in constructor. */
            SIGNAL(self_id,                 GraphTreeObject*,       nullptr)
            /** Accessor to the inertial frame of the planet. Set to point to _planet_inertial in constructor. */
            SIGNAL(inertial_frame,          Frame*,                nullptr)
            /** Accessor to the rotating frame of the planet. Set to point to _planet_inertial in constructor. */
            SIGNAL(rotating_frame,          Frame*,                nullptr)
            /** Equatorial radius of the planet, in meters. Default is Earth R per WGS84, in meters.
             *  This value is set to point to the defaults identified in clockwerk/planetdefaults. */
            SIGNAL(eq_radius,               double,                 warpos::earth_wgs84.eq_radius)
            /** Flattening for the planet. Default is WGS84 flattening.
             *  This value is set to point to the defaults identified in clockwerk/planetdefaults. */
            SIGNAL(flattening,              double,                 warpos::earth_wgs84.flattening)
            /** Gravitational parameter for planet. Default is WGS84 value, in m^3/s^2.
             *  This value is set to point to the defaults identified in clockwerk/planetdefaults. */
            SIGNAL(mu,                      double,                 warpos::earth_wgs84.mu)
            /** J2 parameter for planet. Default is derived from WGS84 but inexact.
             *  This value is set to point to the defaults identified in clockwerk/planetdefaults. */
            SIGNAL(J2,                      double,                 warpos::earth_wgs84.J2)
            /** J3 parameter for planet. Default is derived from WGS84 but inexact.
             *  This value is set to point to the defaults identified in clockwerk/planetdefaults. */
            SIGNAL(J3,                      double,                 warpos::earth_wgs84.J3)
            /** Mean angular velocity of the planet. Assumes rotation about Z axis. Default is WGS84 Earth in rad/s.
             *  This value is set to point to the defaults identified in clockwerk/planetdefaults. */
            SIGNAL(mean_ang_vel,            CartesianVector3,      CartesianVector3({0.0,0.0,warpos::earth_wgs84.mean_ang_vel}))
        END_OUTPUTS 

        // Model-specific implementations of startup and derivative
        SpicePlanet(SimulationExecutive &e, const std::string &m_name="earth");
        ~SpicePlanet();

    protected:
        int16 start() override;
        int16 execute() override;

        // The inertial frame of the planet
        Frame _planet_inertial = Frame("planet_inertial_frame");

        // The planet rotating frame
        Frame _planet_rotating = Frame("planet_rotating_frame");

        // Temporary state variables to hold calculations from spice
        clockwerk::DCM _tmp_dcm_p_pci;
        CartesianVector3 _tmp_vec;
        std::string _attitude_name;
    };

}

#endif