Skip to content

Commit

Permalink
Update docs related to logging
Browse files Browse the repository at this point in the history
  • Loading branch information
juan-g-bonilla committed Sep 12, 2023
1 parent e8eed16 commit aab15c7
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 32 deletions.
1 change: 1 addition & 0 deletions docs/source/Learn/bskPrinciples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ by writing a python script.
bskPrinciples/bskPrinciples-8
bskPrinciples/bskPrinciples-9
bskPrinciples/bskPrinciples-10
bskPrinciples/bskPrinciples-11
71 changes: 71 additions & 0 deletions docs/source/Learn/bskPrinciples/bskPrinciples-11.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.. raw:: html

<iframe width="560" height="315" src="https://www.youtube.com/embed/XuaSmG4wYlk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


.. _bskPrinciples-11:

.. warning::

This section refers to a deprecated way of logging variables. Refer to previous documentation pages for the updated way.

DEPRECATED: Setting and Recording Module Variables
==================================================

.. sidebar:: Source Code

The python code shown below can be downloaded :download:`here </../../docs/source/codeSamples/bsk-6.py>`.

Sometimes it is convenient to record a Basilisk module variable, not just the input or output message. This can be done via a python command as shown below. However, note that such module variable recording will slow down the simulation as this is done in the python layer.

The simulation setup is shown in the figure below. Both a C and C++ module are created and added to the single task. However, no messages are connected here. Rather, this sample code illustrates how to record module internal variables. The variables are either public C++ class variables, or they are variables with the C module configuration structure. Both :ref:`cModuleTemplate` and :ref:`cppModuleTemplate` have the exact same public variables for easy comparison.

.. image:: ../../_images/static/qs-bsk-6.svg
:align: center

The sample code is shown below. The C and C++ modules are set up as before. The variable ``someVariable`` of module ``someModule`` is set in python using ``someModule.someVariable = ...``.

.. literalinclude:: ../../codeSamples/bsk-6.py
:language: python
:linenos:
:lines: 18-

The :ref:`SimulationBaseClass` method to record a module variable is::

scSim.AddVariableForLogging( variableString, recordingTime, indexStart==0, indexStop==0)

Here ``variableString`` must be composed of the module tag string, a period and the variable name. The examples above illustrate how to apply this method for a C or C++ module variable.

The ``recordingTime`` variable is the minimum time that must pass, in nano-seconds again, before the module variable is recorded.

The optional integer arguments ``indexStart`` and ``indexStop`` are defaulted to zero, resulting in a single value being recorded. As this example is also recording a 3-dimensional array ``dumVector``, it is recorded by setting the start and end index to 0 and 2 respectively.

After executing the script, the recorded variables are retrieved in general using the :ref:`SimulationBaseClass` method::

scSim.GetLogVariableData(variableString)

Here ``variableString`` is again composed of the ``ModelTag`` and variable name as before. Note that the returned array has a first column that represents the time where the variable is recorded in nano-seconds. Executing the script you should thus see the following output:

.. code-block::
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: C Module ID 1 ran Update at 0.000000s
BSK_INFORMATION: C++ Module ID 2 ran Update at 0.000000s
BSK_INFORMATION: C Module ID 1 ran Update at 1.000000s
BSK_INFORMATION: C++ Module ID 2 ran Update at 1.000000s
mod1.dummy:
[[0.e+00 1.e+00]
[1.e+09 2.e+00]]
mod1.dumVector:
[[0.e+00 1.e+00 2.e+00 3.e+00]
[1.e+09 1.e+00 2.e+00 3.e+00]]
mod2.dummy:
[[0.e+00 1.e+00]
[1.e+09 2.e+00]]
mod2.dumVector:
[[0.e+00 1.e+00 2.e+00 3.e+00]
[1.e+09 1.e+00 2.e+00 3.e+00]]
Note that both the C and C++ module variables are correctly being recorded.
48 changes: 30 additions & 18 deletions docs/source/Learn/bskPrinciples/bskPrinciples-6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Setting and Recording Module Variables

The python code shown below can be downloaded :download:`here </../../docs/source/codeSamples/bsk-6.py>`.

Sometimes it is convenient to record a Basilisk module variable, not just the input or output message. This can be done via a python command as shown below. However, note that such module variable recording will slow down the simulation as this is done in the python layer.
Sometimes it is convenient to record a Basilisk module variable, not just the input or output message. This can be done via a python command as shown below. However, note that such module variable recording will slow down the simulation as this is done in the python layer.

The simulation setup is shown in the figure below. Both a C and C++ module are created and added to the single task. However, no messages are connected here. Rather, this sample code illustrates how to record module internal variables. The variables are either public C++ class variables, or they are variables with the C module configuration structure. Both :ref:`cModuleTemplate` and :ref:`cppModuleTemplate` have the exact same public variables for easy comparison.

Expand All @@ -27,21 +27,21 @@ The sample code is shown below. The C and C++ modules are set up as before. Th
:linenos:
:lines: 18-

The :ref:`SimulationBaseClass` method to record a module variable is::
Logging a variable from a module is similar to recording one from a message::

scSim.AddVariableForLogging( variableString, recordingTime, indexStart==0, indexStop==0)
moduleLogger = module.logger(variableName, recordingTime)

Here ``variableString`` must be composed of the module tag string, a period and the variable name. The examples above illustrate how to apply this method for a C or C++ module variable.
The ``variableName`` must be either a string or a list of strings. This establishes what module variables to log.

The ``recordingTime`` variable is the minimum time that must pass, in nano-seconds again, before the module variable is recorded.

The optional integer arguments ``indexStart`` and ``indexStop`` are defaulted to zero, resulting in a single value being recorded. As this example is also recording a 3-dimensional array ``dumVector``, it is recorded by setting the start and end index to 0 and 2 respectively.
After executing the script, the recorded variables are retrieved using ``moduleLogger.variableName``
where ``variableName`` is the the name of the module variable you seek to access.

After executing the script, the recorded variables are retrieved in general using the :ref:`SimulationBaseClass` method::
To access the array of time values where the module variables were recorded use ``moduleLogger.times()``.
Note that these times are given in nanoseconds.

scSim.GetLogVariableData(variableString)

Here ``variableString`` is again composed of the ``ModelTag`` and variable name as before. Note that the returned array has a first column that represents the time where the variable is recorded in nano-seconds. Executing the script you should thus see the following output:
Executing the script you should thus see the following output:

.. code-block::
Expand All @@ -52,17 +52,29 @@ Here ``variableString`` is again composed of the ``ModelTag`` and variable name
BSK_INFORMATION: C++ Module ID 2 ran Update at 0.000000s
BSK_INFORMATION: C Module ID 1 ran Update at 1.000000s
BSK_INFORMATION: C++ Module ID 2 ran Update at 1.000000s
Times: [ 0 1000000000]
mod1.dummy:
[[0.e+00 1.e+00]
[1.e+09 2.e+00]]
mod1.dumVector:
[[0.e+00 1.e+00 2.e+00 3.e+00]
[1.e+09 1.e+00 2.e+00 3.e+00]]
[1. 2.]
mod2.dummy:
[[0.e+00 1.e+00]
[1.e+09 2.e+00]]
[1. 2.]
mod2.dumVector:
[[0.e+00 1.e+00 2.e+00 3.e+00]
[1.e+09 1.e+00 2.e+00 3.e+00]]
[[1. 2. 3.]
[1. 2. 3.]]
Note that both the C and C++ module variables are correctly being recorded.

Clearing the Data Log
---------------------
Similarly to message recorders, module loggers continuously add data to their internal data vectors.
If you start and stop the simulation, pull the data, resume the simulation and so on,
this data recording process is cumulative. If you stop the simulation and want to clear the data log
so that only new data is recorded, you can clear the logger using the ``.clear()`` method.

moduleLogger.clear()

Advanced Data Logging
---------------------
The syntax ``module.logger(variableName)`` generates a simple logger for one or more module variables.
However, loggers can retrieve data from many other sources, and do arbitrary operations on this data
before it is stored. This is done using the class `Basilisk.utilities.pythonVariableLogger`.
See :ref:`scenarioFuelSlosh` for an example.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The basic swig interface file looks like this:
from Basilisk.architecture.swig_common_model import *
%}
%include "sys_model.h"
%include "sys_model.i"
%include "swig_conly_data.i"
%include "someModule.h"
Expand Down
25 changes: 12 additions & 13 deletions docs/source/codeSamples/bsk-6.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ def run():
mod2.dummy = 1
mod2.dumVector = [1., 2., 3.]

# request these module variables to be recorded
scSim.AddVariableForLogging(mod1.ModelTag + ".dummy", macros.sec2nano(1.))
scSim.AddVariableForLogging(mod1.ModelTag + ".dumVector", macros.sec2nano(1.), 0, 2)
scSim.AddVariableForLogging(mod2.ModelTag + ".dummy", macros.sec2nano(1.))
scSim.AddVariableForLogging(mod2.ModelTag + ".dumVector", macros.sec2nano(1.), 0, 2)
# request these module variables to be recorded
mod1Logger = mod1.logger("dummy", macros.sec2nano(1.))
scSim.AddModelToTask("dynamicsTask", mod1Logger)
mod2WrapLogger = mod2.logger(["dummy", "dumVector"], macros.sec2nano(1.))
scSim.AddModelToTask("dynamicsTask", mod2WrapLogger)

# initialize Simulation:
scSim.InitializeSimulation()
Expand All @@ -64,17 +64,16 @@ def run():
scSim.ConfigureStopTime(macros.sec2nano(1.0))
scSim.ExecuteSimulation()

# Print when were the variables logged (the same for every logged variable)
print("Times: ", mod1Logger.times())

# Print values logged
print("mod1.dummy:")
print(scSim.GetLogVariableData(mod1.ModelTag + ".dummy"))
print("mod1.dumVector:")
print(scSim.GetLogVariableData(mod1.ModelTag + ".dumVector"))
print(mod1Logger.dummy)
print("mod2.dummy:")
print(scSim.GetLogVariableData(mod2.ModelTag + ".dummy"))
print(mod2WrapLogger.dummy)
print("mod2.dumVector:")
print(scSim.GetLogVariableData(mod2.ModelTag + ".dumVector"))

return

print(mod2WrapLogger.dumVector)

if __name__ == "__main__":
run()

0 comments on commit aab15c7

Please sign in to comment.