Setting and Recording Module Variables#
In some cases, it’s useful to record internal variables from a module, not just the input or output messages. This can be done using Python, though note that recording module variables through Python can slow down the simulation since the logging happens at the scripting layer.
The simulation structure is shown in the figure below. Two modules are created and added to the same task. There are no message connections in this example. Instead, the focus is on recording internal module variables directly.
The code snippet below sets up the modules as in previous examples. The internal variable someVariable from someModule is set in Python using:
someModule.someVariable = ...
1
2from Basilisk.moduleTemplates import cppModuleTemplate
3from Basilisk.utilities import SimulationBaseClass
4from Basilisk.utilities import macros
5
6
7def run():
8 """
9 Illustration of setting and recording module variables
10 """
11
12 # Create a sim module as an empty container
13 scSim = SimulationBaseClass.SimBaseClass()
14
15 # create the simulation process
16 dynProcess = scSim.CreateNewProcess("dynamicsProcess")
17
18 # create the dynamics task and specify the integration update time
19 dynProcess.addTask(scSim.CreateNewTask("dynamicsTask", macros.sec2nano(1.)))
20
21 # create modules
22 mod1 = cppModuleTemplate.CppModuleTemplate()
23 mod1.modelTag = "module1"
24 scSim.AddModelToTask("dynamicsTask", mod1)
25
26 mod2 = cppModuleTemplate.CppModuleTemplate()
27 mod2.modelTag = "module2"
28 scSim.AddModelToTask("dynamicsTask", mod2)
29
30 # set module variables
31 mod1.dummy = 1
32 mod1.dumVector = [1., 2., 3.]
33 mod2.dummy = 1
34 mod2.dumVector = [1., 2., 3.]
35
36 # request these module variables to be recorded
37 mod1Logger = mod1.logger("dummy", macros.sec2nano(1.))
38 scSim.AddModelToTask("dynamicsTask", mod1Logger)
39 mod2WrapLogger = mod2.logger(["dummy", "dumVector"], macros.sec2nano(1.))
40 scSim.AddModelToTask("dynamicsTask", mod2WrapLogger)
41
42 # initialize Simulation:
43 scSim.InitializeSimulation()
44
45 # configure a simulation stop time and execute the simulation run
46 scSim.ConfigureStopTime(macros.sec2nano(1.0))
47 scSim.ExecuteSimulation()
48
49 # Print when were the variables logged (the same for every logged variable)
50 print("Times: ", mod1Logger.times())
51
52 # Print values logged
53 print("mod1.dummy:")
54 print(mod1Logger.dummy)
55 print("mod2.dummy:")
56 print(mod2WrapLogger.dummy)
57 print("mod2.dumVector:")
58 print(mod2WrapLogger.dumVector)
59
60if __name__ == "__main__":
61 run()
Logging a Module Variable#
To record a module variable, use the following syntax:
moduleLogger = module.logger(variableName, recordingTime)
Here, variableName can be a string (for one variable) or a list of strings (to log multiple variables). This tells the logger which internal variables to track.
The recordingTime argument is optional. It defines the minimum interval (in nanoseconds) between data recordings. If this argument is not provided, the logging occurs at the module’s update rate.
After the simulation runs, the data can be accessed using:
moduleLogger.variableName
This returns the values of the specified variable over time. To retrieve the times at which the data was recorded, use:
moduleLogger.times()
These time values are in nanoseconds.
Example Output#
Running the example script should produce output similar to the following:
source/codeSamples % python bsk-6.py
BSK_INFORMATION: Variable dummy set to 0.000000 in reset.
BSK_INFORMATION: Variable dummy set to 0.000000 in reset.
BSK_INFORMATION: Module ID 1 ran Update at 0.000000s
BSK_INFORMATION: Module ID 2 ran Update at 0.000000s
BSK_INFORMATION: Module ID 1 ran Update at 1.000000s
BSK_INFORMATION: Module ID 2 ran Update at 1.000000s
Times: [ 0 1000000000]
mod1.dummy:
[1. 2.]
mod2.dummy:
[1. 2.]
mod2.dumVector:
[[1. 2. 3.]
[1. 2. 3.]]
Clearing the Data Log#
Like message recorders, loggers accumulate data over the simulation runtime. If you stop the simulation, access the data, and then resume, the data collection continues from where it left off. To reset the log and capture only new data, use the .clear() method:
moduleLogger.clear()
Advanced Data Logging#
The module.logger(variableName) method provides a simple way to log variables. However, for more advanced needs—such as logging derived values or data from multiple sources—you can use:
Basilisk.utilities.pythonVariableLogger
This class allows for flexible logging setups with pre-processing logic before storing the data. See scenarioFuelSlosh for an example of advanced logger usage.