How to create a new Orbit Parameter
The following procedure describes how to add a new orbit Parameter and use in the GMAT.
I will make the new Parameter type named "NewOrbitSMA" and type of Gmat::REAL_TYPE (See gmatdefs.hpp for available types used in GMAT). I'll make the owner type of this new Parameter to be a Spacecraft. So Spacecraft code needs to be modified to handle the new Parameter. For Parameter subsystem, OrbitData needs to be modified for the new orbit Parameter and add a new class called NewOrbitSMA in KeplerianParameters. KeplerianParameters file declares and implements keplerian related Prameters such as "SMA" and "ECC". I'll add a new Parameter class for NewOrbitSMA in KeplerianParameters file since I'm going to return first element of Keplerian state as an example.
Here are files that should be modified for a new Parameter.
- Spacecraft - To provide acces method for a new spacecraft field. If Parameter return type is REAL, implement Get/SetRealParameter(). If you can use some existing field to compute a new Parameter value, you can skip this.
- OrbitData - To provide call through method for accessing Spacecraft data for a new Parameter. For some Parameters, it computes new value after getting required value from the spacecraft.
- KeplerianParameters - To add a new Parameter class and implement Evaluate() method.
- ParameterFactory - To handle creating a new Parameter through factory so that it can be used in scripting and GUI.
- Moderator - To show a new Parameter in the GUI ParameterSelectDialog.
Â
Here are detailed step by step procedure and example code to add a new Parameter.
Â
A. In base/spacecraft/Spacecraft.hpp:
  1. Add NEW_ORBIT_SMA to the SC_Param_ID enumeration list. I inserted after ORBIT_A_MATRIX.
        ...
        ORBIT_A_MATRIX,
                NEW_ORBIT_SMA,
        CARTESIAN_X,
        ...
    Â
  2. Add a new data member to store value of the new parameter.
        Real newOrbitSMA;
Â
B. In base/spacecraft/Spacecraft.cpp:
  1. Define the type of NEW_ORBIT_SMA in the PARAMETER_TYPE.
     Do this by inserting the type at the same postion as NEW_ORBIT_SMA was inserted in the header.
        ...
        Gmat::RMATRIX_TYPE,    // OrbitAMatrix
        Gmat::REAL_TYPE,       // NewOrbitSMA
        Gmat::REAL_TYPE,       // CartesianX
        ...
Â
  2. Define the label of NEW_ORBIT_SMA in the PARAMETER_LABEL.
     Do this by inserting the label at the same postion as NEW_ORBIT_SMA was inserted in the header.
       ...
        "OrbitAMatrix",
        "NewOrbitSMA",
        "CartesianX",
        ...
Â
  3. Modify GetParameterID(const std::string &str) const to return proper parameter ID
        ...
        if (str == "NewOrbitSMA")
           return NEW_ORBIT_SMA;
        ...
       Â
  4. Initialize newOrbitSMA in the constructor, copy constructor, and assignment operator.
Â
  5. Update GetRealParameter(const Integer id) to return new parameter value.
     Assuming newOrbitSMA is already computed.
        ...
        if (id == NEW_ORBIT_SMA)  return newOrbitSMA;
        ...
Â
  6. Update SetRealParameter(const Integer id, const Real value) to set new value to new Spacecraft member data.
        ...
        if (id == NEW_ORBIT_SMA)
        {
           parmsChanged = true;
           // Do range checking on input value
           // Do any computation needed
           // Or you can just set value
           newOrbitSMA = value;
           return value;
        }
        ...
  Â
C. In base/parameter/OrbitData.hpp:
  1. Add a new enumeration name for new Parameter item ID.
This item ID is is not the same ID used in the Spacecraft.hpp, so it can be given different id name. Using item ID avoids string comparison which will increase performance.
        ...
        // New orbit items
        enum {NEW_ORBIT_SMA_ID = Item8Count, Item9Count};
        ...
  2. Add a new method Real GetNewOrbitReal(Integer item);
Â
D. In base/parameter/OrbitData.cpp
  1. Update SetReal(Integer item, Real rval) to set value of new parameter.
This method makes call through owner object of the new Parameter. In this case owner object is Spacecraft.
        ...
        // New orbit Parameter
        case NEW_ORBIT_SMA_ID:
           mSpacecraft->SetRealParameter(mSpacecraft->GetParameterID("NewOrbitSMA"), rval);
           break;
        ...
Â
  2. Implement a new method Real GetNewOrbitReal(Integer item) to return value.
     For example:
 Â
       //------------------------------------------------------------------------------
       // Real GetNewOrbitReal(Integer item)
       //------------------------------------------------------------------------------
       Real OrbitData::GetNewOrbitReal(Integer item)
       {
          Rvector6 state = GetKepState();
          switch (item)
          {
          case NEW_ORBIT_SMA_ID:
             // Compute new orbit parameter value here and return.
             // I'm returning first element of keplerian state as an example.
             return state[0];
          defualt:
             throw ParameterException("OrbitData::GetNewOrbitReal() Unknown parameter id: " +
                                      GmatRealUtil::ToString(item));
          }
       }
Â
E. In base/parameter/KeplerianParameters.hpp:
  1. Declare class called NewOrbitSMA.
        ...
        class GMAT_API NewOrbitSMA : public OrbitReal
        {
        public:
Â
           NewOrbitSMA(const std::string &name = "", GmatBase *obj = NULL);
           NewOrbitSMA(const NewOrbitSMA ¶m);
           const NewOrbitSMA& operator=(const NewOrbitSMA &right);
           virtual ~NewOrbitSMA();
Â
           // methods inherited from Parameter
           virtual bool Evaluate();
Â
           // methods inherited from GmatBase
           virtual GmatBase* Clone(void) const;
        };
        ...
      Â
Â
F. In base/parameter/KeplerianParameter.cpp:
  1. Implement class NewOrbitSMA. You can copy KepSMA class and modify it.
I'm assuming KepSMA was copied and renamed to NewOrbitSMA.
Â
     a. Modify NewOrbitSMA::NewOrbitSMA() constructor to give new Parameter name and description, etc,. If you look at OrbitReal constructor, the second argment is the Parameter type name, so this name will be used in the GMAT.
        ...
        NewOrbitSMA::NewOrbitSMA(const std::string &name, GmatBase *obj)
           : OrbitReal(name, "NewOrbitSMA", obj, "New Orbit Semi-Major Axis", "Km", GmatParam::ORIGIN, NEW_ORBIT_SMA_ID, true)
        {
           mDepObjectName = "Earth";
           SetRefObjectName(Gmat::SPACE_POINT, "Earth");
           SetRefObjectName(Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
        }
        ...
      Â
     b. Modify NewOrbitSMA::Evaluate() method to pass NEW_ORBIT_SMA_ID to retrieve value. This method will just set the member data called mRealValue. When OrbitReal::EvaluateReal() is called it will call Evaluate() and return the value. So retriving is done by the parent class.
        ...
        mRealValue = OrbitData::GetKepReal(NEW_ORBIT_SMA_ID);
Â
        if (mRealValue == GmatOrbitConstants::ORBIT_REAL_UNDEFINED)
           return false;
        else
           return true;
        ...
      Â
G. In base/factory/ParameterFactory.cpp
  1. Modify ParameterFactory::CreateParameter() method to create a new Parameter called "NewOrbitSMA"
        ...
        // New Orbit Parameters
        if (ofType == "NewOrbitSMA")
           return new NewOrbitSMA(withName);
        ...
Â
  2. Modify ParameterFactory::ParameterFactory() constructor to add a new Parameter called "NewOrbitSMA" to creatables list.
        ...
        // New Orbit Parameters
        creatables.push_back("NewOrbitSMA");
        ...
Â
  At this point, the new Parameter called "NewOrbitSMA" is available for script and GUI ParameterSelectDialog for you to use. For example;
        Create Spacecraft sat;
        Create ReportFile rf;
       Â
        BeginMissionSequence;
        Report rf sat.NewOrbitSMA;
Â
H. If you want to see this new Parameter in the ParameterSelectDialog, you need to modify the Moderator to create this Parameter in the default mission.
  1. Modify Moderator::CreateDefaultParameters() to create the new Parameter using default settings, ie, using DefaultSpacecraft and Earth as origin.
        ...
        // New orbital Parameter
        CreateParameter("NewOrbitSMA", "DefaultSC.Earth.NewOrbitSMA");
        ...
Â
  2. If you want to see list of Parameters in the GmatLog.txt, just turn on DEBUG_PARAMETERS in the gmat_startup_file.
        DEBUG_PARAMETERS      = ON
Â
     Then you will see something like this in the GmatLog.txt.
Â
        ==========================================================================================
        =================================== GMAT Parameter List ==================================
        ==========================================================================================
        (R = Reportable, P = Plottable, S = Settable)
        No  ParameterType      ObjectType    DependencyType             R P S Description
        --- ----------------   ------------- ----------------------     - - - -----------
        ...
         29 EA                 Spacecraft    Origin                     Y Y N Eccentric Anomaly
         30 HA                 Spacecraft    Origin                     Y Y N Hyperbolic Anomaly
         31 MM                 Spacecraft    Origin                     Y Y N Mean Motion
         32 NewOrbitSMA        Spacecraft    Origin                     Y Y Y New Orbit Semi-Major Axis
         33 VelApoapsis        Spacecraft    Origin                     Y Y N Velocity at Apoapsis
         34 VelPeriapsis       Spacecraft    Origin                     Y Y N Velocity at Periapsis
        ...
Â
Â