How to Add a New Command

How to Add a New Command

Introduction

A Command represents a member of the set of instruction(s) that perform a task in GMAT.  Each Command is associated with one or more Resources and describes how the associated Resources will be used and evolve over time. Commands are sequential and they run in scripted order.  That scripted list of commands  is called the Mission Control Sequence. Commands in GMAT are created in order, via script or GUI, to run a mission.
The following text shows sample scripting for a mission sequence:

BeginMissionSequence; Propagate 'Prop To Periapsis' DefaultProp(DefaultSC) {DefaultSC.Earth.Periapsis}; Target 'Hohmann Transfer' DC1 {SolveMode = Solve, ExitMode = SaveAndContinue}; Vary 'Vary TOI' DC1(TOI.Element1 = 1, {Perturbation = 0.0001, Lower = 0.0, Upper = 3.14159, MaxStep = 0.5}); Maneuver 'Perform TOI' TOI(DefaultSC); Propagate 'Prop To Apoapsis' DefaultProp(DefaultSC) {DefaultSC.Earth.Apoapsis}; Achieve 'Achieve RMAG = 42165' DC1(DefaultSC.Earth.RMAG = 42164.169, {Tolerance = 0.1}); Vary 'Vary GOI' DC1(GOI.Element1 = 1, {Perturbation = 0.0001, Lower = 0.0, Upper = 3.14159, MaxStep = 0.2}); Maneuver 'Perform GOI' GOI(DefaultSC); Achieve 'Achieve ECC = 0.005' DC1(DefaultSC.Earth.ECC = 0.005, {Tolerance = 0.0001}); EndTarget; % For targeter DC1 Propagate 'Prop One Day' DefaultProp(DefaultSC) {DefaultSC.ElapsedSecs = 86400};


The following snapshot shows the mission sequence of this scripting as it is presented in GMAT's GUI.


There are many types of built-in Commands used in spacecraft missions. New Commands can be created to extend GMAT to perform a new task. This document will describe a general procedure to add a new Command to the baseline GMAT code. If you would prefer to add your new Command as a plugin, please see instead the document "."

Overview

All configurable Command types must be derived from GmatCommand. The GmatCommand class is derived from the base GMAT class, GmatBase. Often there are intermediate classes that encapsulate common data and methods for the Command type. For example, there is a PlotCommand class, derived from GmatCommand, from which ClearPlot, MarkPoint, PenDown, and PenUp Commands are derived. Data and method implementations that are common to all of these subclasses are placed in the PlotCommand class, and only those that need specific modifications are added or overridden in the subclasses. Only leaf Commands can be created and used in the GMAT mission sequence.


Most Commands have one or more associated Resources and options. Though not shown in the above diagram, the associated Resource type of the PlotCommand is the Subscriber/XYPlot, and there are no command options. Sample script syntax of one of the PlotCommand leaf classes is

ClearPlot DefaultXYPlot;

A more complicated command is the Propagate command, shown below.

Propagate DefaultProp(DefaultSC) {DefaultSC.ElapsedSecs = 12000.0};

The associated Resource type for this command is a Propagator type named "DefaultProp" and a Spacecraft type named "DefaultSC." The command option in this example is "DefaultSC.ElapsedSecs = 12000.0." This script tells the Propagate command to propagate the Spacecraft object "DefaultSC" for 12000 seconds using the Propagator object "DefaultProp."

A maneuver command example is shown below.

Maneuver DefaultIB(DefaultSC);

The associated Resource type is an object of the ImpulsiveBurn type named "DefaultIB" and a Spacecraft type named "DefaultSC." This script snippet tells the Maneuver Command to apply a maneuver to the Spacecraft object "DefaultSC" using the ImpulsiveBurn object "DefaultIB."


Commands in GMAT are executed in order, whether created via script or GUI, when running a mission. When a Command is created via the GUI, it is set to use its default Resource(s) and option(s). When a Command is created via script, the associated Resource must be created before the Commands are created, otherwise errors will occur during script parsing. 

GMAT uses a late binding scheme to provide interconnection between Resource objects and Commands. Commands store names of associated Resource objects during script parsing. Actual object instances are connected before the execution of Commands when the Sandbox is initialized. See the "" for more details on GMAT's late binding scheme.

Required First Steps

In order to add a new Command to GMAT, some preliminary steps must be taken to set up your build environment:

  1. Download the configured GMAT source

  2. Download, or refer to, the GMAT C++ Code Style Guide from the GMAT Wiki.  Code used in GMAT follows the standard GMAT coding style as defined in this guide.

  3. Build GMAT on your platform with no code changes (see instructions on building the source on the GMAT Wiki) [NOTE: to maintain cross-platform compatibility, code must build successfully using the GCC compiler and Visual Studio in order to be considered for inclusion in GMAT.]

  4. Run the Sample Missions (or SmokeTests and possibly a subset of relevant system tests, if you have access to the GMAT test system) before code modification, to

    1. Confirm successful execution of the unmodified GMAT, and

    2. Obtain an initial set of 'truth' data for later testing

Once these steps have been completed and GMAT runs successfully from this clean build, you can start the work to create a new Command.

General Requirements

Though GMAT is a modular system, adding a new Command is not as simple as just compiling and linking a new class. There are requirements that must be met regarding, among other things:

  • Deriving the new class from a base class (either an existing Command class, or GmatCommand)

  • Implementing, at a minimum, several specific methods

  • Adding the new command to the appropriate factory (or creating a new factory)

  • Updating base type lists and related enumerated types

  • Modification of types and addition of methods in GUI management classes

  • Optionally, creating GUI components to edit your new Command

Required Methods

Among other generic methods provided by the GmatBase class, the following list details methods that should usually be implemented for a new Command. Note that InterpretAction() and Execute() methods are specific to the Command class and must be implemented.

  • InterpretAction(): Parses the command string and builds the corresponding command structures. During script interpretation, this method is called to parse the string and to set Resource object names and options.

  • GetWrapperObjectNameArray(), SetElementWrapper(), ClearWrappers(): If a Command accesses configured Parameters or other Resource properties, these methods should be implemented.

  • RenameRefObject(): If a Command accesses one or more configured Resource, this method should be implemented.

  • Initialize(): Initializes the internal command data. During the Sandbox initialization, this method is called to set Resource object pointers to the objects in the Sandbox.

  • Execute(): Performs actions on associated Resource objects or just performs actions without associated Resource objects. During the Sandbox execution, this method is called to perform actions.

  • TakeAction(): Performs an action specific to the Command. This method is usually called from other Commands.

  • GetGeneratingString(): Generates the command string as it appears in the script. This method is called when saving GUI resources and commands to a script file, or when showing scripts from the individual resource panel.

Recommended Practices

There are practices and/or strategies that may be helpful to a developer in creating a new Command. It is often helpful to:

  • First, determine scripting of the new component

  • Next, modify/add the minimal set of code for the new Command until the associated script parses

  • Then, add validation of the input data

  • Then, begin to add the functionality necessary to make the Command work (may be done in steps)

Procedures for Adding a New Command

Base Code modifications:

  1. Decide which GMAT Command base class will be the parent of your new class. Most Commands derive from the GmatCommand class located in src/base/command.

  2. Create the new class by making NewCommand.cpp and NewCommand.hpp files for the class, where NewCommand is the name of the command (usually identical to the command name used in GMAT scripts).

  3. Add additional data or methods to the new class as needed.

  4. Implement the pure virtual methods of the parent class, and other public methods whose base/default implementation are not correct or sufficient for your new class. The only pure virtual method required for Commands is the Execute() method, which must be implemented. In addition, you may need to add some validation to the Initialize() method, so you would override the Initialize() method and include new code there, and (almost certainly) call the parent Initialize() method as well.

  5. If your class is a leaf class, implement the Clone() and Copy() methods. Implement the RenameRefobjects() method to handle renaming Resource names from the GUI. If your command does not reference any objects, add the macro "DEFAULT_TO_NO_REFOBJECTS" in the public part of your header file. This macro is replaced by a RenameRefobjects() implementation, set to return true, during compilation.

  6. If your class has cloned objects, implement the cloning of objects in the copy constructor and the assignment operator as needed. The assignment operator should delete owned cloned objects before creating new owned cloned objects. If your class does not own any cloned objects, add the macro "DEFAULT_TO_NO_CLONES" in the public part of your header file. This macro is replaced by an implementation of HasLocalClones() that returns false.

  7. Update /src/base/factory/CommandFactory.cpp to add your new Command type. Add a new Command type to the data member "creatables" list in the CommandFactory constructor so that the new Command type is recognized in the Interpreter. Update the CreateCommand() method to return an instance of your new Command type when a new Command instance with the new type name is requested.

  8. Add your new class(es) to the /src/base/MakeBase.eclipse file to make sure it is compiled using GCC.

  9. Add new Command class to Microsoft Visual C++ 2010 Express libGmatBase project to build the new command into GMAT builds created using Visual Studio.