Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/bsk 64 read c msg #67

Merged
merged 7 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/source/Learn/bskPrinciples/bskPrinciples-4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,15 @@ After the simulation completes, the recorded data is stored inside the ``msgRec`

Clearing the Message Recorder Data Log
--------------------------------------
Note that the messager recorder will continuously add message data to its internal data vectors. If you start and stop the simulation, pull the data, resume the simulation and so on, this message data recording process is cumulative. If you stop the simulation and want to clear the message recorder data log so that only new data is recorded, you can clear the message recorder module data buffer using the ``.clear()`` method. For example, assume a message recorder ``scRec`` has been setup and needs to be cleared, this is done with::
Note that the message recorder will continuously add message data to its internal data vectors. If you start and stop the simulation, pull the data, resume the simulation and so on, this message data recording process is cumulative. If you stop the simulation and want to clear the message recorder data log so that only new data is recorded, you can clear the message recorder module data buffer using the ``.clear()`` method. For example, assume a message recorder ``scRec`` has been setup and needs to be cleared, this is done with::

scRec.clear()

Reading the Current Value of a Message
--------------------------------------
If you have a message `msg` and want to pull a current copy of the message data or payload, you can use
this method on both C and C++ wrapped message objects::

msgCopy = msg.read()


7 changes: 6 additions & 1 deletion docs/source/Learn/bskPrinciples/bskPrinciples-7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ To redirect the output of a C++ module ``someCppModule`` to this stand-alone mes
someCppModule.dataOutMsg = cppStandAloneMsg


If you want to record the output of ``someCModule`` be sure to record ``cStandAloneMsg`` instead of ``someCModule.dataOutMsg``. The later is no longer being written to. In C++ we are setting ``cppStandAloneMsg`` equal to ``someCppModule.dataOutMsg``. Here recording either will give the same result.
.. note::

If you want to record the output of ``someCModule`` be sure to record ``cStandAloneMsg``
instead of ``someCModule.dataOutMsg``. The later is no longer being written to. In C++
we are setting ``cppStandAloneMsg`` equal to ``someCppModule.dataOutMsg``. Here recording either
will give the same result.

To see the message states of both the module internal message objects and the stand-alone messages, the sample script shows how to use ``.read()`` to read the current state of the message object. This will return a copy of the message payload structure. The same method can be used to access both C and C++ wrapped messages. After executing the script you should see the following terminal output:

Expand Down
3 changes: 3 additions & 0 deletions docs/source/Support/bskReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ Version |release|
- Refactored :ref:`keplerianOrbit` to not depend on the ``gravityEffector`` class
- Updated Basilisk install documentation to discuss accessing source code from GitHub.com
- Fixed an issue where attaching a thruster to a body different than the hub when using ``zeroBase`` would yield very large offsets.
- Added documentation in :ref:`bskPrinciples-4` on how to read the current message values
- Highlighted the challege of setting up a ``recorder`` on a re-directed message in :ref:`bskPrinciples-7`
- added the ability to add a ``recorder()`` to a C-wrapped module input message


Version 2.1.5 (Dec. 13, 2022)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#
# Copyright (c) 2023, Autonomous Vehicle Systems Lab, University of Colorado at Boulder
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

#
# Purpose: Test if a C-wrapped input message can be logged with a recorder module
# Author: Hanspeter Schaub
# Creation Date: Jan. 3, 2023
#


from Basilisk.utilities import SimulationBaseClass
from Basilisk.utilities import macros
from Basilisk.moduleTemplates import cModuleTemplate
from Basilisk.architecture import messaging
from Basilisk.utilities import unitTestSupport as uts
from Basilisk.architecture import bskLogging


def test_RecordingInputMessages():
"""
testing recording a C-wrapped input message with the recorder module
"""

bskLogging.setDefaultLogLevel(bskLogging.BSK_WARNING)
testFailCount = 0 # zero unit test result counter
testMessages = [] # create empty array to store test log messages

# Create a sim module as an empty container
scSim = SimulationBaseClass.SimBaseClass()

# create the simulation process
dynProcess = scSim.CreateNewProcess("dynamicsProcess")

# create the dynamics task and specify the integration update time
dynProcess.addTask(scSim.CreateNewTask("dynamicsTask", macros.sec2nano(1.)))

# create modules
mod1 = cModuleTemplate.cModuleTemplateConfig()
mod1Wrap = scSim.setModelDataWrap(mod1)
mod1Wrap.ModelTag = "cModule1"
scSim.AddModelToTask("dynamicsTask", mod1Wrap, mod1)

# Write input data
inputData = messaging.CModuleTemplateMsgPayload()
inputData.dataVector = [1, 2, 3]
inputDataMsg = messaging.CModuleTemplateMsg().write(inputData)

# Subscribe input message to stand alone message
mod1.dataInMsg.subscribeTo(inputDataMsg)

# Create recorders tied to IO messages
dataInRec = mod1.dataInMsg.recorder()
scSim.AddModelToTask("dynamicsTask", dataInRec)

# initialize Simulation:
scSim.InitializeSimulation()

# configure a simulation stop time and execute the simulation run
scSim.ConfigureStopTime(macros.sec2nano(1.0))
scSim.ExecuteSimulation()

testFailCount, testMessages = uts.compareArray([inputData.dataVector]*2
, dataInRec.dataVector
, 0.01
, "recorded input message was not correct."
, testFailCount
, testMessages)

# each test method requires a single assert method to be called
# this check below just makes sure no sub-test failures were found
assert testFailCount < 1, testMessages


if __name__ == "__main__":
test_RecordingInputMessages()
4 changes: 4 additions & 0 deletions src/architecture/messaging/msgAutoSource/msg_C.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ void {type}_C_write({type}Payload *data, {type}_C *destination, int64_t moduleID
if (!source->header.isLinked) {{
BSK_PRINT(MSG_ERROR,"In C input msg, you are trying to read an un-connected message of type {type}.");
}}
//! ensure the current message container has a copy of a subscribed message.
//! Does nothing if the message is writing to itself
source->payload = *source->payloadPointer;

return *source->payloadPointer;
}};

Expand Down
6 changes: 3 additions & 3 deletions src/utilities/unitTestSupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def isArrayEqual(result, truth, dim, accuracy):


def isArrayEqualRelative(result, truth, dim, accuracy):
"""Compare relative accuracy of two arracy"""
"""Compare relative accuracy of two arrays"""
# the result array is of dimension dim, no time stamp
# the truth array is of dimesion dim, no time stamp
if dim < 1:
Expand Down Expand Up @@ -164,10 +164,10 @@ def compareVector(trueStates, dataStates, accuracy, msg, testFailCount, testMess

def compareArray(trueStates, dataStates, accuracy, msg, testFailCount, testMessages):
"""Compare two arrays size and values and check absolute accuracy"""
if (len(trueStates) != len(dataStates)):
if len(trueStates) != len(dataStates):
testFailCount += 1
testMessages.append("FAILED: " + msg + r" unequal data array sizes\n")
elif (len(trueStates) == 0 or len(dataStates) == 0):
elif len(trueStates) == 0 or len(dataStates) == 0:
testFailCount += 1
testMessages.append("FAILED: " + msg + r" data had empty arrays\n")
else:
Expand Down