Adding Basilisk Modules

Understanding now what a Basilisk process (Task Group) and a task is, we can now move forward to adding Basilisk modules to a task. Module: cModuleTemplate and Module: cppModuleTemplate will be the basic module C and C++ BSK modules that we use in this discussion. These simple modules are used to illustrate how to make a prototypical Basilisk module. The functionality and messages used are the same across both modules. These modules are convenient for this discussion as they are set up as a tutorial module and print out the module ID value when the module is executed. This makes it simple in the simulation below to see that the desired module execution order is achieved.

../../_images/qs-bsk-2.svg

The following simulation creates a single process called dynamicsProcess and single 0.2Hz task called dynamicsTask. As illustrated above, two copies of Module: cModuleTemplate and one of Module: cppModuleTemplate are created where they are called cModule1, cModule3 and cppModule2 respectively. However, note that in this example we seek to execute modules 2 and 3 first and 1 last.

 1
 2from Basilisk.moduleTemplates import cModuleTemplate
 3from Basilisk.moduleTemplates import cppModuleTemplate
 4from Basilisk.utilities import SimulationBaseClass
 5from Basilisk.utilities import macros
 6
 7
 8def run():
 9    """
10    Illustration of adding Basilisk modules to a task
11    """
12
13    #  Create a sim module as an empty container
14    scSim = SimulationBaseClass.SimBaseClass()
15
16    #  create the simulation process
17    dynProcess = scSim.CreateNewProcess("dynamicsProcess")
18
19    # create the dynamics task and specify the integration update time
20    dynProcess.addTask(scSim.CreateNewTask("dynamicsTask", macros.sec2nano(5.)))
21
22    # create copies of the Basilisk modules
23    mod1 = cModuleTemplate.cModuleTemplate()
24    mod1.ModelTag = "cModule1"
25
26    mod2 = cppModuleTemplate.CppModuleTemplate()
27    mod2.ModelTag = "cppModule2"
28
29    mod3 = cModuleTemplate.cModuleTemplate()
30    mod3.ModelTag = "cModule3"
31
32    scSim.AddModelToTask("dynamicsTask", mod1)
33    scSim.AddModelToTask("dynamicsTask", mod2, 10)
34    scSim.AddModelToTask("dynamicsTask", mod3, 5)
35
36    #  initialize Simulation:
37    scSim.InitializeSimulation()
38    print("InitializeSimulation() completed...")
39
40    #   configure a simulation stop time and execute the simulation run
41    scSim.ConfigureStopTime(macros.sec2nano(5.0))
42    scSim.ExecuteSimulation()
43
44    return
45
46
47if __name__ == "__main__":
48    run()

The resulting demonstration code is shown above. Let us create some module someModule.someModule and give it a unique name. This is done as:

module = someModule.someModule()
module.ModelTag = "someModuleName"

With BSK C-modules the module name is repeated. With C++ modules the first variable is the module name, the second variable is the module class name which begins with a capital letter. See the above script for examples of each.

The next step is to add this module to the task list, so that they are executed during simulation:

scSim.AddModelToTask("taskName", module, priority)

The first argument is the name of the task to which you are adding the module. The 2nd argument is the module. The last argument is the optional integer priority argument.

Warning

If priority argument is not provided, then the priority defaults to -1 and the modules are executed in the order that they are added, but after modules with priority have been executed. This is the same behavior as what we saw with processes and tasks earlier.

In the above python script, the tutorial C++ Module: cppModuleTemplate is imported from Basilisk.simulation, while the C-based Module: cModuleTemplate must be imported from Basilisk.fswAlgorithm. Next, while the 1st and 3rd module are instances of the C module, the 2nd module is an instance of the equivalent C++ module.

Note

Basilisk assigns unique positive ID numbers to C/C++/Python modules upon their creation. Thus, in the above simulation code the modules 1, 2 and 3 will have the corresponding ID numbers 1, 2 and 3 because that is the order in which they are created.

Looking at the above simulation code, note that Module1 is added to the task list without any priority specified. In contrasts, Module2 and Module3 have the priorities 10 and 5 assigned. The higher the module priority, the earlier it is evaluated.

Note

The task list can contain, C, C++ and even Python based Basilisk modules at the same time. Python modules are discussed in Making Python Modules.

If you execute this python code you should see the following terminal output:

source/codeSamples % python3 bsk-2.py
BSK_INFORMATION: Variable dummy set to 0.000000 in reset.
BSK_INFORMATION: Variable dummy set to 0.000000 in reset.
BSK_INFORMATION: Variable dummy set to 0.000000 in reset.
InitializeSimulation() completed...
BSK_INFORMATION: C++ Module ID 2 ran Update at 0.000000s
BSK_INFORMATION: C Module ID 3 ran Update at 0.000000s
BSK_INFORMATION: C Module ID 1 ran Update at 0.000000s
BSK_INFORMATION: C++ Module ID 2 ran Update at 5.000000s
BSK_INFORMATION: C Module ID 3 ran Update at 5.000000s
BSK_INFORMATION: C Module ID 1 ran Update at 5.000000s

Module: cModuleTemplate and Module: cppModuleTemplate log in the Reset() method that a variable has been set to 0. As we have three such modules, notice that this reset statement is seen three times. This reset step occurs when we run scSim.InitializeSimulation().

After the initialization, Basilisk starts the time loop evaluating the modules at the specified rate. The Update() routine in both Module: cModuleTemplate and Module: cppModuleTemplate print out the module ID and the simulation time where the module is called. Note that thanks to the module evaluation priorities we set, the desired module execution order is achieved.