Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. First, determine scripting of the new component
  2. Next, modify/add the minimal set of code for the new resource until the script parses
  3. Then, add validation of the input data
  4. Next, incrementally add and validate new functionality until the resource is complete

 

Adding a New Resource Subtype of an Existing Type (Type 1)

Initial Steps

 

  1. Decide on the scripting needed to create and access your new resource, as best as you can.
  2. Determine the public properties needed, their valid values, and how the class will be used in GMAT.

Base Code modifications

 

  1. Decide which GMAT resource base class will be the parent of your new class. For example, if you are adding a new type of Thruster, you will need to derive your class from the base Thruster class, located in src/base/hardware.
  2. Determine whether or not you can copy-and-paste portions of your new class from an existing class. If not, you will need to start from scratch, deriving your class from the base class you selected in the previous step. In either case, make sure the standard header information is present and correct, and your new code follows the GMAT C++ Style Guide.
  3. Add additional data or methods to the new class as needed. If you add additional user-settable parameters, you will need to create an enumeration listing those new data, as well as static string and Gmat::ParameterType arrays to hold the strings and data types for those new parameters (see Appendix A example).
  4. Implement the pure virtual methods of the parent class (or inherited by the base class), and other public methods whose base/default implementation are not correct or sufficient for your new class. For example, if you need to add some validation to the Initialize() method, you would include new code in your Initialize() method and (almost certainly) call the parent Initialize() from your method as well.
  5. If your class is a leaf class, implement the Clone (and potentially, Copy) methods.
  6. If you do not have any reference objects, use "DEFAULT_TO_NO_REFOBJECTS" in the public part of your header file.
  7. If you do not have any owned clone members, use "DEFAULT_TO_NO_CLONES" in the public part of your header file.
  8. Add your new type to the appropriate Factory subclass in /src/base/factory.
  9. Add your new resource name to the ObjectType enum in include/gmatdefs.hpp.
  10. Add to OBJECT_TYPE_STRING and AUTOMATIC_GLOBAL_FLAGS in GmatBase.cpp, being careful to add your new entries in the correct spot in each.
  11. Implement validation of your added class data, following the style of other classes (e.g. using errorMessageFormat, etc.)
  12. Implement the functionality of the new class.
  13. Add your new class(es) to the MakeBase.eclipse file to make sure it is compiled.
  14. Add your new resource class to the Microsoft Visual C++ 2010 Express libGmatBase project if you are building using MS Visual Studio.

 

GUI Code modifications

 

  1. Add your new type to GuiTreeItemData::ItemType if appropriate.
  2. Check the CreateNewResource() method in the GmatMainFrame class to see if you need to add or modify the list (e.g. in the switch statement), to match the modifications to GmatTreeItemData.
  3. Decide whether you can use the GmatBaseSetupPanel, or if you will need a custom GUI panel for your new resource. See How to Create GMAT Panels for further instructions on creating a new GUI panel. NOTE that if you use the GmatBaseSetupPanel, you will also need to implement these methods in your new base class: GetPropertyObjectType and GetTypesForList (if you have a parameter of OBJECT_ARRAY type)
  4. In the ResourceTree class, you may need to modify or add methods for your new type, e.g. the OnAdd* methods. Also, add item(s) to the POPUP enum for your class, or modify existing items as needed.
  5. You will need to add (or modify) methods in GuiItemManager that keep a list of configured objects of your new type and update that list when necessary, and create/unregister GUI widgets (e.g. combo boxes or lists) that may be needed
  6. Add your new class(es) to the MakeGui.eclipse file to make sure it is compiled
  7. Add your new resource class to the Microsoft Visual C++ 2010 Express GMAT_wxGui project if you are building using MS Visual Studio.

...

  1. You need to make an entry in the gmatdefs.hpp Gmat::ObjectType for your new Resource. For example, if I were to add an ErrorModel class, I would add an ERROR_MODEL entry to ObjectType. Your new entry should be in a location in the list that makes sense (for example, near similar items, or at the end immediately before the UNKNOWN_OBJECT entry).
  2. There are two places in GmatBase.cpp that you will need to modify.  You must make sure these additions are each inserted into the correct position in the array, corresponding to the position where you added your entry into Gmat::OBJECT_TYPE.
    1. First, you will need to add your class/Resource name to OBJECT_TYPE_STRING.
    2. Also, you will need to add to the AUTOMATIC_GLOBAL_FLAGS array.
  3. Create your new class, making sure to derive it from GmatBase. You will implement it as described above for Type 1, adding methods and data as needed, and implementing applicable methods inherited from GmatBase.
  4. You need to create a factory that will know how to create objects of your new Resource type. To do this, create the new Factory class, e.g. ErrorModelFactory.hpp and ErrorModelFactory.cpp (see other Factory classes for examples). You will want to make sure that it includes the CreateObject generic method – this is needed for compatibility with recent Interpreter/Moderator modifications.
  5. Because objects are generally configured, you need to tell the ConfigManager class about your new Resource. You will need an Add method and a Get method for your new Resource, e.g. AddErrorModel and GetErrorModel.
  6. The Moderator also needs to know about your new Resource, so you will need to modify Moderator.cpp to register your new factory.
  7. To ensure that the Interpretercode can handle your new type:
  8. Add a string array to Interpreter.hpp, e.g. errorModelList
  9. In Interpreter::BuildCreatableObjectMaps, add a section for your new list.
  10. In Interpreter::GetCreatableList, add a section for you new type
  11. To make sure that objects of your new class are written out correctly to a script, you will need to add to ScriptInterpreter::WriteScript. Add code there, similar to that for other types, to write objects of your new type.
  12. You may need to modify ObjectInitializer code if you need objects of your type to be initialized before or after another specific type of object, or if you need to build references between your Resource type and objects of another type.

 

GUI Code

The steps for adding a panel and incorporating your new Resource into the other GUI code are identical to steps taken for Type 1.

...

  1. Run unit-tests with the new code – these unit-tests must be thorough and should use input test data obtained from GMAT engineers when available
  2. Coordinate with GMAT team members to deliver code modifications

 

Appendix A: Example (Type 1)

...

Code Block
languagecpp
GMAT NuclearPowerSystem1.AnnualDecayRate = 5.123;
GMAT NuclearPowerSystem1.Margin = 4.998;

Base Code

 

  • Decide on the new class structure. Since we may need or want to add other Power Systems at a later time, we will derive a PowerSystem class from Hardware and then derive a NuclearPowerSystem class from that.

  •  Create the new resource class from scratch, or start from a similar class (derived from the same base type) and modify as needed. In this example, we can start from a similar Hardware class and modify. Edit the header to make sure all the author, date, and descriptive information is correct:

...

  • Since the PowerSystem will be 'attached' to a Spacecraft, we also need to create a panel to be used as a tab on the SpacecraftPanel. See the PowerSystemPanel header in Appendix B. The implementation of this panel is very similar to that of existing 'tabs' used for the SpacecraftPanel.
  • Now, we need to add the PowerSystemPanel and PowerSystemConfigPanel classes to the list in MakeBase.eclipse file to make sure they are compiled. If you developing on a Windows platform, you should also add the classes to the project file for Microsoft Visual C++ 2010 Express.

.

Back to Base Code

 

  • Now we need to create the subclass, NuclearPowerSystem. We will derive it from the PowerSystem class so that it inherits all of the methods and data we defined earlier.
  • In this case, recall that we have a pure virtual method, GetPowerGenerated, in the PowerSystem class. Since NuclearPowerSystem is a leaf class, we must implement this method here.
  • Also, we must implement the Clone() method since this is a leaf class.
  • Each class must set its  parameterCount based on its own enumeration:

    Code Block
    languagecpp
    parameterCount = NuclearPowerSystemParamCount;
  • Add "DEFAULT_TO_NO_REFOBJECTS" to the leaf class.
  • The class needs to tell the system what type of resource it is:

 


Code Block
languagecpp
objectTypes.push_back(Gmat::NUCLEAR_POWER_SYSTEM); ** only needed if we add this type to GMAT::ObjectType
objectTypeNames.push_back("NuclearPowerSystem");

...

Code Block
languagecpp
//$Id$
//------------------------------------------------------------------------------
//                            PowerSystemPanel
//------------------------------------------------------------------------------
// GMAT: General Mission Analysis Tool
//
//
// Copyright (c) 2002-2014 United States Government as represented by the
// Administrator of The National Aeronautics and Space Administration.
// All Other Rights Reserved.
//
// Author: Wendy Shoan
// Created: 2014.05.07
/**
 * This class contains information needed to setup users spacecraft power
 * system through GUI
 *
 */
//------------------------------------------------------------------------------
#ifndef PowerSystemPanel_hpp
#define PowerSystemPanel_hpp
#include "gmatwxdefs.hpp"
#include "Spacecraft.hpp"
#include "GmatPanel.hpp"
#include "GuiItemManager.hpp"
#include "GmatAppData.hpp"

class PowerSystemPanel: public wxPanel
{
public:
   PowerSystemPanel(GmatPanel *scPanel, wxWindow *parent, Spacecraft *spacecraft);
   ~PowerSystemPanel();
   void SaveData();
   void LoadData();
   bool IsDataChanged() { return dataChanged; }
   bool CanClosePanel() { return canClose; }
private:
   bool dataChanged;
   bool canClose;
   bool powerSystemChanged;
   void Create();
   // Event Handling
   DECLARE_EVENT_TABLE();
   void OnComboBoxChange(wxCommandEvent& event);
   Spacecraft     *theSpacecraft;
   GuiItemManager *theGuiManager;
   GuiInterpreter *theGuiInterpreter;
   GmatPanel      *theScPanel;
   wxComboBox     *powerSystemComboBox;
   std::string    thePowerSystem;
   // IDs for the controls and the menu commands
   enum
   {
      ID_TEXT = 30220,
      ID_COMBOBOX
   };
};
#endif

 

Appendix C: Example (Type 2)


This appendix shows a brief example, illustrating the extra steps needed in order to add an ErrorModel class. After these steps are completed, the remaining work would be similar to Type 1 (see Appendix A).
   Base Code

  • We add an entry in the gmatdefs.hpp Gmat::ObjectType:

...

  • Next we modify Moderator.cpp to register the new ErrorModelFactory. We add an errorModelList to Interpreter. Then we edit Interpreter::BuildCreatableObjectMaps, to add a section for this new list: 

     

    Code Block
    languagecpp
    errorModelList.clear(); 
    StringArray erm = theModerator->GetListOfFactoryItems(Gmat::ERROR_MODEL); 
    copy(erm.begin(), erm.end(), back_inserter(errorModelList)); 
    copy(erm.begin(), erm.end(), back_inserter(allObjectTypeList)); 
    for (UnsignedInt i = 0; i < errorModelList.size(); i++) 
       objectTypeMap.insert(std::make_pair(errorModelList[i], Gmat::ERROR_MODEL));

     

     

  • In Interpreter::GetCreatableList, we add a section to the switch statement for this type as well:

...

  • We do not need to modify ObjectInitializer at this time.

GUI Code

The steps for adding a panel and incorporating your new Resource into the other GUI code are identical to steps taken for Type 1 (see Appendix A).

...