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.
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.