diff --git a/docs/source/Learn/bskPrinciples/bskPrinciples-10.rst b/docs/source/Learn/bskPrinciples/bskPrinciples-10.rst index f2afd1119..8bf0d9fbe 100644 --- a/docs/source/Learn/bskPrinciples/bskPrinciples-10.rst +++ b/docs/source/Learn/bskPrinciples/bskPrinciples-10.rst @@ -1,6 +1,6 @@ .. _bskPrinciples-10: -.. warning:: +.. warning:: This section refers to a deprecated way of operating with C modules. Refer to previous documentation pages for the updated way. @@ -8,7 +8,7 @@ Deprecated: Using old-style C modules ===================================== In more recent Basilisk scripts, whether a module is implemented in C++ or C should not make any difference on how this module is used in Python scripts. However, this has not always been -the case, and you might encounter some code that uses the older syntax. This documentation +the case, and you might encounter some code that uses the older syntax. This documentation summarizes how to use this older syntax. Previous documentation pages have taught us that C++ modules (and new-syntax C modules) are @@ -27,13 +27,13 @@ In order to perform the same operations on an old-syntax C module, one would do: moduleWrap.modelTag = "someModuleName" scSim.AddModelToTask("taskName", moduleWrap, moduleConfig, priority) -Note that in this case, we created a "Config" object ``someModule.someModuleConfig``. Connecting +Note that in this case, we created a "Config" object ``someModule.someModuleConfig``. Connecting messages and setting parameters of the module is done through this object. Then, the ``setModelDataWrap`` method of the simulation object is called on the "Config" object, which generates the "Wrap" object. The unique name must be set on the "Wrap" object. Finally, the module is added to the simulation by using both the "Wrap" and "Config" objects in the ``scSim.AddModelToTask`` method. -The need for separate "Config" and "Wrap" objects arises from the lack of classes in the C programming language. +The need for separate "Config" and "Wrap" objects arises from the lack of classes in the C programming language. The "Config" objects, as well as the relevant ``updateState``, ``Reset``, and ``SelfInit`` methods, are written in pure C for C modules. However, the simulation framework is written in C++ and it expects the modules to be C++ classes. The "Wrap" object is this C++ class, which holds references to diff --git a/docs/source/Learn/bskPrinciples/bskPrinciples-11.rst b/docs/source/Learn/bskPrinciples/bskPrinciples-11.rst index f03909020..ddcfb31df 100644 --- a/docs/source/Learn/bskPrinciples/bskPrinciples-11.rst +++ b/docs/source/Learn/bskPrinciples/bskPrinciples-11.rst @@ -2,7 +2,7 @@ .. _bskPrinciples-11: -.. warning:: +.. warning:: This section refers to a deprecated way of logging variables. Refer to previous documentation pages for the updated way. diff --git a/docs/source/Learn/bskPrinciples/bskPrinciples-2a.rst b/docs/source/Learn/bskPrinciples/bskPrinciples-2a.rst index 90d0f43dd..c113c21ce 100644 --- a/docs/source/Learn/bskPrinciples/bskPrinciples-2a.rst +++ b/docs/source/Learn/bskPrinciples/bskPrinciples-2a.rst @@ -44,5 +44,3 @@ If you execute this python code you should see the following terminal output: 0.0 BSK_INFORMATION: C Module ID 1 ran Update at 0.000000s 1.0 - - diff --git a/docs/source/Learn/bskPrinciples/bskPrinciples-8.rst b/docs/source/Learn/bskPrinciples/bskPrinciples-8.rst index 46a883db4..67fd96813 100644 --- a/docs/source/Learn/bskPrinciples/bskPrinciples-8.rst +++ b/docs/source/Learn/bskPrinciples/bskPrinciples-8.rst @@ -45,5 +45,3 @@ To disable a single task, this is done with the :ref:`SimulationBaseClass` metho BSK executed a single simulation step BSK_INFORMATION: C Module ID 1 ran Update at 4.000000s BSK executed a single simulation step - - diff --git a/docs/source/Learn/bskPrinciples/bskPrinciples-9.rst b/docs/source/Learn/bskPrinciples/bskPrinciples-9.rst index 7cb640139..1a0a35790 100644 --- a/docs/source/Learn/bskPrinciples/bskPrinciples-9.rst +++ b/docs/source/Learn/bskPrinciples/bskPrinciples-9.rst @@ -32,4 +32,4 @@ at 1Hz as this method is called at the task update period. The integration type is determined by the integrator assigned to the primary ``DynamicObject`` to which the other ``DynamicObject`` integrations is synchronized. By default this is the ``RK4`` integrator. It doesn't matter what integrator is assigned to the secondary ``DynamicObject`` instances, -the integrator of the primary object is used. \ No newline at end of file +the integrator of the primary object is used. diff --git a/docs/source/Learn/makingModules/advancedTopics/creatingDynObject.rst b/docs/source/Learn/makingModules/advancedTopics/creatingDynObject.rst index 9b08b6d71..83901e9ca 100644 --- a/docs/source/Learn/makingModules/advancedTopics/creatingDynObject.rst +++ b/docs/source/Learn/makingModules/advancedTopics/creatingDynObject.rst @@ -35,4 +35,3 @@ scenarios as with the spacecraft example. See the discussion in :ref:`bskPrinci Basilisk modules that inherit from the ``DynamicObject`` class can be linked. If linked, then the associated module ordinate differential equations (ODEs) are integrated simultaneously. - diff --git a/docs/source/Learn/makingModules/cModules/cModules-1.rst b/docs/source/Learn/makingModules/cModules/cModules-1.rst index eabe2c65c..635b8b7d5 100644 --- a/docs/source/Learn/makingModules/cModules/cModules-1.rst +++ b/docs/source/Learn/makingModules/cModules/cModules-1.rst @@ -83,4 +83,3 @@ For example, assume the module needs an array of input messages of type ``SomeMs The module needs to implement separate logic to determine how many messages have been set. For example, the reset function could loop over this array and up to what slot the associate message object has been linked. As the C wrapped message object can act as either input or output messages, the above example can readily be converted to an outpout message example by renaming the array variable ``moreOutMsgs``. - diff --git a/docs/source/Learn/makingModules/cModules/cModules-3.rst b/docs/source/Learn/makingModules/cModules/cModules-3.rst index 95699d236..73046073f 100644 --- a/docs/source/Learn/makingModules/cModules/cModules-3.rst +++ b/docs/source/Learn/makingModules/cModules/cModules-3.rst @@ -101,4 +101,3 @@ Assume the module has an array called ``moreInMsgs`` which contain input message .. code:: cpp inMsgBuffer = SomeMsg_C_read(&configData->moreInMsgs[3]); - diff --git a/docs/source/Learn/makingModules/cppModules/cppModules-1.rst b/docs/source/Learn/makingModules/cppModules/cppModules-1.rst index d4ccaad8a..f4a304c48 100644 --- a/docs/source/Learn/makingModules/cppModules/cppModules-1.rst +++ b/docs/source/Learn/makingModules/cppModules/cppModules-1.rst @@ -105,4 +105,3 @@ To define a vector of output messages, we define a vector of message pointer usi public: std::vector*> moreOutMsgs; //!< variable description - diff --git a/docs/source/Learn/makingModules/cppModules/cppModules-3.rst b/docs/source/Learn/makingModules/cppModules/cppModules-3.rst index 8ce040a2a..f7a4bffa9 100644 --- a/docs/source/Learn/makingModules/cppModules/cppModules-3.rst +++ b/docs/source/Learn/makingModules/cppModules/cppModules-3.rst @@ -110,4 +110,3 @@ Note that with the ``new`` call above the memory associated with this output mes delete this->moreOutMsgs.at(c); } } - diff --git a/docs/source/Learn/makingModules/pyModules.rst b/docs/source/Learn/makingModules/pyModules.rst index 9c871c6ee..342516733 100644 --- a/docs/source/Learn/makingModules/pyModules.rst +++ b/docs/source/Learn/makingModules/pyModules.rst @@ -9,10 +9,10 @@ Making Python Modules Python modules are a good alternative to C and C++ modules for quick prototyping. They are defined entirely in a Python script, which means that there is no need -for a header (``.h``), definition (``.cpp``), or SWIG interface file (``.i``). However, they +for a header (``.h``), definition (``.cpp``), or SWIG interface file (``.i``). However, they are much slower than C or C++ modules, which will significantly slow down your simulation. -Python modules are implemented by subclassing ``SysModel`` from ``Basilisk.architecture.sysModel``. +Python modules are implemented by subclassing ``SysModel`` from ``Basilisk.architecture.sysModel``. Then, one can implement the ``__init__``, ``Reset``, and ``updateState`` methods in the same way that one would implement these methods in C++. Remember to always call ``__init__`` of diff --git a/docs/source/Support/bskReleaseNotes.rst b/docs/source/Support/bskReleaseNotes.rst index 622cf0836..d09b0eaab 100644 --- a/docs/source/Support/bskReleaseNotes.rst +++ b/docs/source/Support/bskReleaseNotes.rst @@ -43,8 +43,8 @@ Version 2.3.0 (April 5, 2024) - Fixed a python version checking bug that prevented Basilisk from compiling on Windows - Created a new example scenario :ref:`scenarioHaloOrbit` demonstrating a near-Halo orbit simulation - Updated versioning to better follow the `semantic versioning `_ standard, in the format - ``MAJOR.MINOR.PATCH``. Releases will increment the minor version number, while pull requests into develop will - automatically increment the patch number. This allows users to reference/require specific versions of Basilisk + ``MAJOR.MINOR.PATCH``. Releases will increment the minor version number, while pull requests into develop will + automatically increment the patch number. This allows users to reference/require specific versions of Basilisk outside of the release cycle. Online documentation is only built for the ``MAJOR.MINOR.0`` releases - updated plotting of ``opNav`` example scenarios to work again with latest version of ``matplotlib`` @@ -164,7 +164,7 @@ Version 2.2.1 (Dec. 22, 2023) - Added a new method ``setDataBuffer()`` to :ref:`simpleStorageUnit` and :ref:`partitionedStorageUnit` to add or remove data from specified partitions. - Refactored ``simIncludeGravBody``. The most notable change for users is that the commonly used line ``scObject.gravField.gravBodies = spacecraft.GravBodyVector(list(gravFactory.gravBodies.values()))`` - can be replaced by ``gravFactory.addBodiesTo(scObject)`` (where ``scObject`` is a ``spacecraft.Spacecraft`` + can be replaced by ``gravFactory.addBodiesTo(scObject)`` (where ``scObject`` is a ``spacecraft.Spacecraft`` or ``spacecraftSystem.SpacecraftSystem``, and ``gravFactory`` is a ``simIncludeGravBody.gravBodyFactory``) - Added condition in :ref:`thrustCMEstimation` to avoid measurement updates when input ``attGuidInMsg`` has not been written. - Added :ref:`scenarioSepMomentumManagement` to show how to use a dual-gimbaled electric thruster to perform contunuous @@ -218,7 +218,7 @@ Version 2.2.0 (June 28, 2023) - Refactored the :ref:`prescribedMotionStateEffector` dynamics module to vary the prescribed states across the dynamics integration time step. - The encryption build option for the project's conan zmq dependency is disabled because it is uneeded. -- Added an optional ``controllerStatus`` variable and ``deviceStatusInMsg`` message to the :ref:`simpleInstrumentController` to +- Added an optional ``controllerStatus`` variable and ``deviceStatusInMsg`` message to the :ref:`simpleInstrumentController` to match the functionality of the corresponding data and power modules - Corrected tasks priorities in several scenarios and added checks in two modules to ensure that C MSG read errors are not thrown - Reworked how integrators are implemented. New Runge-Kutta integrators may @@ -376,7 +376,7 @@ Version 2.1.4 (Oct. 1, 2022) - added new attitude pointing scenario :ref:`scenarioAttitudeFeedback2T_stateEffTH` that uses the new :ref:`thrusterStateEffector` - added ability to simulate faults within :ref:`coarseSunSensor` module -- created a 1-DoF rotating rigid body class ``SpinningBodyStateEffector``. It is built in a general way to simulate +- created a 1-DoF rotating rigid body class ``SpinningBodyStateEffector``. It is built in a general way to simulate any effector with a single spinning axis. @@ -456,7 +456,7 @@ Version 2.1.1 (Dec. 15, 2021) Version 2.1.0 (Nov. 13, 2021) ----------------------------- -- added BSpline function to ``utilities`` and related UnitTest. +- added BSpline function to ``utilities`` and related UnitTest. - added kinematic relations between angular accelerations and second derivative of MRP set to :ref:`rigidBodyKinematicsutilities` library - updated the installation script to function with the latest ``conan`` program and the recent @@ -473,7 +473,7 @@ Version 2.1.0 (Nov. 13, 2021) - added new scenario :ref:`scenarioVariableTimeStepIntegrators` - updated :ref:`scenarioIntegrators` to include the ``rkf45`` and ``rkf78`` options - changed the way :ref:`spacecraftReconfig` gets the deputy's mass properties. It now receives that information - through a message of the type ``VehicleConfigMsgPayload`` instead of an internal variable. Relevant example + through a message of the type ``VehicleConfigMsgPayload`` instead of an internal variable. Relevant example scripts have been updated. - new tutorial example scenario script :ref:`scenarioTAMcomparison` - new mass sensor that converts a ``simulation`` mass properties message to a ``FSW`` vehicle configuration message :ref:`simpleMassProps` @@ -518,13 +518,13 @@ Version 2.0.6 using the above new MTB related modules to change the momentum, as well as drive the nominal momentum to a desired value using :ref:`rwNullSpace`. - created a new architecture based on ``BskSim`` called ``MultiSatBskSim``. It exploits the new messaging system to create a simulation - with any number of spacecraft in a highly modular way. It allows for the addition of homogeneous or heterogeneous satellites without + with any number of spacecraft in a highly modular way. It allows for the addition of homogeneous or heterogeneous satellites without having to hard code their properties into a single dynamics or FSW script. It will be a foundation to test the upcoming multithreading capabilities of Basilisk. -- added three example scenarios that showcase this new architecture. See :ref:`scenario_BasicOrbitMultiSat`, :ref:`scenario_AttGuidMultiSat` +- added three example scenarios that showcase this new architecture. See :ref:`scenario_BasicOrbitMultiSat`, :ref:`scenario_AttGuidMultiSat` and :ref:`scenario_StationKeepingMultiSat`. - added a new FSW module :ref:`formationBarycenter`. It computes the barycenter's position and velocity of a swarm of satellites. This barycenter - can be either computed with cartesian coordinates (usual mass-weighted average), or using orbital elements weighted average. Will be useful + can be either computed with cartesian coordinates (usual mass-weighted average), or using orbital elements weighted average. Will be useful for spacecraft formations defined around the barycenter of the swarm and not a chief spacecraft. - enhanced :ref:`locationPointing` to support the target input msg being either a location message or an ephemeris message @@ -558,7 +558,7 @@ Version 2.0.5 two modules are connected - updated :ref:`gravityEffector` documentation to properly pull in the RST documentation and link to the PDF describing the gravity models -- updated ``setAllButCurrentEventActivity`` method in :ref:`SimulationBaseClass` to work with multiple satellites. We can now add an index at the +- updated ``setAllButCurrentEventActivity`` method in :ref:`SimulationBaseClass` to work with multiple satellites. We can now add an index at the end of each event name that guarantees only events with the same index are affected. The ``useIndex`` flag must be set to ``True``. - added new magnetic torque bar effector in :ref:`MtbEffector` - added new FSW module to control the RW momentum using MTBs in :ref:`mtbMomentumManagement` @@ -764,7 +764,7 @@ Version 2.0.0 - updated ``spacecraftPlus`` to allow the attitude motion to be prescribed through an optional input message of type ``attRefMsg``. - fixed sign issue in :ref:`simpleSolarPanel` -- support Vizard 1.6.0 scripting +- support Vizard 1.6.0 scripting @@ -862,7 +862,7 @@ Version 2.0.0 BSK messages. For example, this allows :ref:`vizInterface` store the simulation data into a Vizard compatible manner. - Updated :ref:`spiceInterface` to allow for optional overriding the IAU planet frame with custom values - Updated :ref:`vizInterface` to allow setting ``show24hrClock`` and ``showDataRateDisplay`` flags for Vizard files - supported in Vizard v1.3.0 + supported in Vizard v1.3.0 Version 1.7.4 @@ -1143,7 +1143,7 @@ simple and robust solution. - added new tutorial on calling Python Spice functions within a Monte Carlo BSK simulation - Added Keplerian Orbit utility class which is swig'd. This first implementation takes in elliptical orbit elements and can produce a range of related outputs like position, velocity, orbital period, etc. This makes it easier to create Keplerian orbits within python. -- Added a LimbFinding module for OpNav: limbFinding. This module performs a Canny transform to find the end of the planet and saves away the non-zero pixels for pose-estimation. +- Added a LimbFinding module for OpNav: limbFinding. This module performs a Canny transform to find the end of the planet and saves away the non-zero pixels for pose-estimation. - made BSK compatible with both swig version 3 and 4 .. raw:: html diff --git a/docs/source/Vizard/vizardAdvanced/vizardSettings.rst b/docs/source/Vizard/vizardAdvanced/vizardSettings.rst index ad65ffac4..e2024cd96 100644 --- a/docs/source/Vizard/vizardAdvanced/vizardSettings.rst +++ b/docs/source/Vizard/vizardAdvanced/vizardSettings.rst @@ -416,14 +416,14 @@ cones can be setup in Vizard, but can also be scripted from Basilisk using the helper function ``createConeInOut``: .. code-block:: - + viz = vizSupport.enableUnityVisualization(scSim, simTaskName, scObject, saveFile=fileName) vizSupport.createConeInOut(viz, toBodyName='earth', coneColor='teal', normalVector_B=[1, 0, 0], incidenceAngle=30\ macros.D2R, isKeepIn=True, coneHeight=5.0, coneName=‘sensorCone’) vizSupport.createConeInOut(viz,toBodyName='earth', coneColor='blue', normalVector_B=[0, 1, 0], incidenceAngle=30\ macros.D2R, isKeepIn=False, coneHeight=5.0, coneName=‘comCone’)] - + The following table illustrates the arguments for the ``createConeInOut`` method: @@ -1829,5 +1829,3 @@ the MSM radii are stored in the list ``rListDebris``. The sample code is:: , saveFile=fileName , msmInfoList=[msmInfoDebris] ) - - diff --git a/examples/BskSim/models/BSK_FormationDynamics.py b/examples/BskSim/models/BSK_FormationDynamics.py index a535ee8fa..438097eda 100644 --- a/examples/BskSim/models/BSK_FormationDynamics.py +++ b/examples/BskSim/models/BSK_FormationDynamics.py @@ -140,4 +140,3 @@ def InitAllDynObjects(self): self.SetSimpleNavObject() self.SetReactionWheelDynEffector() self.SetExternalForceTorqueObject() - diff --git a/examples/BskSim/models/BSK_SEPDynamics.py b/examples/BskSim/models/BSK_SEPDynamics.py index 1fa13d90f..82eae9dd1 100644 --- a/examples/BskSim/models/BSK_SEPDynamics.py +++ b/examples/BskSim/models/BSK_SEPDynamics.py @@ -19,7 +19,7 @@ import numpy as np from Basilisk.utilities import (macros as mc, unitTestSupport as sp, RigidBodyKinematics as rbk, simIncludeRW) from Basilisk.simulation import (spacecraft, simpleNav, simpleMassProps, reactionWheelStateEffector, - ReactionWheelPower, boreAngCalc, spinningBodyOneDOFStateEffector, + ReactionWheelPower, boreAngCalc, spinningBodyOneDOFStateEffector, spinningBodyTwoDOFStateEffector, thrusterStateEffector, facetSRPDynamicEffector) from Basilisk.architecture import messaging @@ -168,8 +168,8 @@ def SetRotatingSolarArrays(self): self.RSAList[0].r_SB_B = [0.5 * 1.53, 0.0, 0.44] self.RSAList[0].r_ScS_S = [-0.036, 2.827, -0.469] self.RSAList[0].sHat_S = [0, 1, 0] - self.RSAList[0].dcm_S0B = [[0, 0, -1], - [1, 0, 0], + self.RSAList[0].dcm_S0B = [[0, 0, -1], + [1, 0, 0], [0, -1, 0]] self.RSAList[0].IPntSc_S = [[319.0, 0.0, 0.0], [0.0, 185.0, 0.0], @@ -310,7 +310,7 @@ def SetSEPTrusterStateEffectors(self): self.SEPThruster1.kappaInit = messaging.DoubleVector([0.0]) self.SEPThruster1.modelTag = "SEPThruster1" self.scObject.addStateEffector(self.SEPThruster1) - + self.SEPThruster2.addThruster(thruster, self.platform2.spinningBodyConfigLogOutMsgs[1]) self.SEPThruster2.kappaInit = messaging.DoubleVector([0.0]) self.SEPThruster2.modelTag = "SEPThruster2" @@ -387,4 +387,3 @@ def InitAllDynObjects(self, SimBase): self.SetInertialBoresight2(SimBase) self.SetSEPTrusterStateEffectors() self.SetFacetSRPDynamicEffector(SimBase) - diff --git a/examples/BskSim/scenarios/scenario_SEPPoint.py b/examples/BskSim/scenarios/scenario_SEPPoint.py index 244c40d05..814c7cbe4 100644 --- a/examples/BskSim/scenarios/scenario_SEPPoint.py +++ b/examples/BskSim/scenarios/scenario_SEPPoint.py @@ -102,7 +102,7 @@ def __init__(self, numberSpacecraft, prescribed): else: scBodyList.append([self.DynModels[i].platform1.modelTag, self.DynModels[i].platform1.spinningBodyConfigLogOutMsgs[1]]) for j in range(self.DynModels[i].numRSA): - scBodyList.append([self.DynModels[i].RSAList[j].modelTag, self.DynModels[i].RSAList[j].spinningBodyConfigLogOutMsg]) + scBodyList.append([self.DynModels[i].RSAList[j].modelTag, self.DynModels[i].RSAList[j].spinningBodyConfigLogOutMsg]) # Enable Vizard viz = vizSupport.enableUnityVisualization(self, self.DynModels[0].taskName, scBodyList, saveFile=__file__) @@ -267,7 +267,7 @@ def log_outputs(self): self.AddModelToTask(DynModels[sc].taskName, self.platformRefAngleLogs[0]) self.platformRefAngleLogs.append(FswModels[sc].platform2ReferenceData.hingedRigidBodyRef2OutMsg.recorder(self.samplingTime)) self.AddModelToTask(DynModels[sc].taskName, self.platformRefAngleLogs[1]) - + if thrusterFlag == 1: # log platform torques if not self.prescribed: @@ -395,7 +395,7 @@ def pull_outputs(self, show_plots, spacecraftIndex): T_F = [0, 0, 0.1] for i in range(len(dataCMLocation)): r_CM_B = r_BM_B + dataCMLocation[i] - + if not self.prescribed: theta1 = dataPlatformAngle[0][i] theta2 = dataPlatformAngle[1][i] diff --git a/examples/MultiSatBskSim/modelsMultiSat/BSK_MultiSatDynamics.py b/examples/MultiSatBskSim/modelsMultiSat/BSK_MultiSatDynamics.py index 10bdfdfdc..99065ae9e 100644 --- a/examples/MultiSatBskSim/modelsMultiSat/BSK_MultiSatDynamics.py +++ b/examples/MultiSatBskSim/modelsMultiSat/BSK_MultiSatDynamics.py @@ -183,7 +183,7 @@ def SetFuelTank(self): self.fuelTankStateEffector.r_TB_B = [[0.0], [0.0], [0.0]] self.tankModel.radiusTankInit = 1 self.tankModel.lengthTank = 1 - + # Add the tank and connect the thrusters self.scObject.addStateEffector(self.fuelTankStateEffector) self.fuelTankStateEffector.addThrusterSet(self.thrusterDynamicEffector) diff --git a/examples/OpNavScenarios/modelsOpNav/BSK_OpNavDynamics.py b/examples/OpNavScenarios/modelsOpNav/BSK_OpNavDynamics.py index 8b2569aba..2d3ac9933 100644 --- a/examples/OpNavScenarios/modelsOpNav/BSK_OpNavDynamics.py +++ b/examples/OpNavScenarios/modelsOpNav/BSK_OpNavDynamics.py @@ -369,7 +369,7 @@ def SetEphemConvert(self): def SetSimpleGrav(self): planet = self.gravFactory.createMarsBarycenter() planet.isCentralBody = True - + self.gravFactory.addBodiesTo(self.scObject) # Global call to initialize every module @@ -387,5 +387,3 @@ def InitAllDynObjects(self, SimBase): self.SetEphemConvert() self.SetCamera() self.SetCamera2() - - diff --git a/examples/scenarioAerocapture.py b/examples/scenarioAerocapture.py index d26221879..e5296d0fa 100644 --- a/examples/scenarioAerocapture.py +++ b/examples/scenarioAerocapture.py @@ -115,14 +115,14 @@ def sph2rv(xxsph): NOTE: this function assumes inertial and planet-fixed frames are aligned at this time """ - + r = xxsph[0] lon = xxsph[1] lat = xxsph[2] u = xxsph[3] gam = xxsph[4] hda = xxsph[5] - + NI = np.eye(3) IE = np.array([[np.cos(lat) * np.cos(lon), -np.sin(lon), -np.sin(lat) * np.cos(lon)], [np.cos(lat) * np.sin(lon), np.cos(lon), -np.sin(lat) * np.sin(lon)], @@ -130,13 +130,13 @@ def sph2rv(xxsph): ES = np.array([[np.cos(gam), 0, np.sin(gam)], [-np.sin(gam) * np.sin(hda), np.cos(hda), np.cos(gam) * np.sin(hda)], [-np.sin(gam) * np.cos(hda), -np.sin(hda), np.cos(gam) * np.cos(hda)]]) - + e1_E = np.array([1,0,0]) rvec_N = (r * NI @ IE) @ e1_E - + s3_S = np.array([0,0,1]) uvec_N = u * ( NI @ IE @ ES) @ s3_S - + return rvec_N, uvec_N @@ -171,7 +171,7 @@ def run(show_plots, planetCase): tabAtmo = tabularAtmosphere.TabularAtmosphere() # update with current values tabAtmo.modelTag = "tabularAtmosphere" # update python name of test module atmoTaskName = "atmosphere" - + # define constants & load data if planetCase == 'Earth': r_eq = 6378136.6 @@ -181,10 +181,10 @@ def run(show_plots, planetCase): r_eq = 3397.2 * 1000 dataFileName = bskPath + '/supportData/AtmosphereData/MarsGRAMNominal.txt' altList, rhoList, tempList = readAtmTable(dataFileName, 'MarsGRAM') - + # assign constants & ref. data to module tabAtmo.planetRadius = r_eq - tabAtmo.altList = tabularAtmosphere.DoubleVector(altList) + tabAtmo.altList = tabularAtmosphere.DoubleVector(altList) tabAtmo.rhoList = tabularAtmosphere.DoubleVector(rhoList) tabAtmo.tempList = tabularAtmosphere.DoubleVector(tempList) @@ -217,7 +217,7 @@ def run(show_plots, planetCase): scObject.modelTag = "spacecraftBody" scObject.hub.mHub = m_sc tabAtmo.addSpacecraftToModel(scObject.scStateOutMsg) - + simpleNavObj = simpleNav.SimpleNav() scSim.AddModelToTask(simTaskName, simpleNavObj) simpleNavObj.scStateInMsg.subscribeTo(scObject.scStateOutMsg) @@ -253,7 +253,7 @@ def run(show_plots, planetCase): hda = np.pi/2 xxsph = [r,lon,lat,u,gam,hda] rN, vN = sph2rv(xxsph) - + scObject.hub.r_CN_NInit = rN # m - r_CN_N scObject.hub.v_CN_NInit = vN # m - v_CN_N @@ -378,5 +378,3 @@ def run(show_plots, planetCase): # close the plots being saved off to avoid over-writing old and new figures if __name__ == '__main__': run(True, 'Mars') # planet arrival case, can be Earth or Mars - - diff --git a/examples/scenarioDataDemo.py b/examples/scenarioDataDemo.py index 73b236fe8..e35827365 100644 --- a/examples/scenarioDataDemo.py +++ b/examples/scenarioDataDemo.py @@ -18,7 +18,7 @@ Overview -------- -This is an illustration of how to use onboard data management modules to perform analysis of onboard data generated +This is an illustration of how to use onboard data management modules to perform analysis of onboard data generated by instruments, stored by computers, and downlinked by transmittters. This scenario is intended to provide both an overview and a concrete demonstration of the features and interface of the diff --git a/examples/scenarioDeployingPanel.py b/examples/scenarioDeployingPanel.py index 9e0196b2f..afa1651b0 100644 --- a/examples/scenarioDeployingPanel.py +++ b/examples/scenarioDeployingPanel.py @@ -30,7 +30,7 @@ python3 scenarioDeployingPanel.py -The simulation includes two deploying panels that start undeployed. The first panel deploys fully, +The simulation includes two deploying panels that start undeployed. The first panel deploys fully, but the second panel deploys off-nominally (to 80%), leading to a reduced power output. @@ -163,9 +163,9 @@ def run(show_plots): panel1.modelTag = "panel1" panel1.mass = 100.0 panel1.IPntS_S = [[100.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 50.0]] - panel1.d = 1.5 + panel1.d = 1.5 panel1.k = 200. - panel1.c = 20. + panel1.c = 20. panel1.r_HB_B = [[-.5], [0.0], [-1.0]] panel1.dcm_HB = [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]] panel1.thetaInit = -np.pi @@ -175,9 +175,9 @@ def run(show_plots): panel2.modelTag = "panel2" panel2.mass = 100.0 panel2.IPntS_S = [[100.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 50.0]] - panel2.d = 1.5 + panel2.d = 1.5 panel2.k = 200. - panel2.c = 20. + panel2.c = 20. panel2.r_HB_B = [[.5], [0.0], [-1.0]] panel2.dcm_HB = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] panel2.thetaInit = -np.pi @@ -228,7 +228,7 @@ def run(show_plots): solarPanel1 = simpleSolarPanel.SimpleSolarPanel() solarPanel1.modelTag = "pwr1" - solarPanel1.nHat_B = [0, 0, 1] + solarPanel1.nHat_B = [0, 0, 1] solarPanel1.panelArea = 2.0 # m^2 solarPanel1.panelEfficiency = 0.9 # 90% efficiency in power generation solarPanel1.stateInMsg.subscribeTo(panel1.hingedRigidBodyConfigLogOutMsg) @@ -236,7 +236,7 @@ def run(show_plots): solarPanel2 = simpleSolarPanel.SimpleSolarPanel() solarPanel2.modelTag = "pwr2" - solarPanel2.nHat_B = [0, 0, 1] + solarPanel2.nHat_B = [0, 0, 1] solarPanel2.panelArea = 2.0 # m^2 solarPanel2.panelEfficiency = 0.9 # 90% efficiency in power generation solarPanel2.stateInMsg.subscribeTo(panel2.hingedRigidBodyConfigLogOutMsg) @@ -316,9 +316,9 @@ def run(show_plots): np.set_printoptions(precision=16) - figureList = plotOrbits(dataLog.times(), dataSigmaBN, dataOmegaBN_B, + figureList = plotOrbits(dataLog.times(), dataSigmaBN, dataOmegaBN_B, panel1thetaLog, panel1thetaDotLog, - panel2thetaLog, panel2thetaDotLog, + panel2thetaLog, panel2thetaDotLog, pwrLog1, pwrLog2) if show_plots: diff --git a/examples/scenarioDeployingSolarArrays.py b/examples/scenarioDeployingSolarArrays.py index 321fc03a8..078e0c7b5 100644 --- a/examples/scenarioDeployingSolarArrays.py +++ b/examples/scenarioDeployingSolarArrays.py @@ -190,7 +190,7 @@ def run(show_plots): r_M1S1_B = [0.0, 0.0, 0.0] # [m] r_M2S2_B = [0.0, 0.0, 0.0] # [m] - # Position vector of solar array frame origin points with respect to hub frame origin point B + # Position vector of solar array frame origin points with respect to hub frame origin point B # expressed in B frame components rArray1SB_B = np.array([2.0, 0.0, 0.0]) # [m] rArray2SB_B = np.array([-2.0, 0.0, 0.0]) # [m] @@ -216,7 +216,7 @@ def run(show_plots): IElement_PntFc_F = [[I_element_11, 0.0, 0.0], [0.0, I_element_22, 0.0], [0.0, 0.0, I_element_33]] # [kg m^2] (Elements approximated as rectangular prisms) - + # Deployment temporal information ramp_duration = 2.0 # [s] init_deploy_duration = 5.0 * 60.0 # [s] @@ -346,7 +346,7 @@ def run(show_plots): array2RotProfilerList[i].setThetaDDotMax(array2MaxRotAccelList1[i]) # [rad/s^2] array1RotProfilerList[i].setThetaInit(array1ThetaInit1) # [rad] array2RotProfilerList[i].setThetaInit(array2ThetaInit1) # [rad] - + scSim.AddModelToTask(fswTaskName, array1RotProfilerList[i]) scSim.AddModelToTask(fswTaskName, array2RotProfilerList[i]) array1RotProfilerList[i].spinningBodyInMsg.subscribeTo(array1ElementRefMsgList1[i]) @@ -378,7 +378,7 @@ def run(show_plots): array2Element8PrescribedDataLog = array2RotProfilerList[7].spinningBodyOutMsg.recorder(dataRecRate) array2Element9PrescribedDataLog = array2RotProfilerList[8].spinningBodyOutMsg.recorder(dataRecRate) array2Element10PrescribedDataLog = array2RotProfilerList[9].spinningBodyOutMsg.recorder(dataRecRate) - + scSim.AddModelToTask(fswTaskName, scStateData) scSim.AddModelToTask(fswTaskName, array1Element1PrescribedDataLog) scSim.AddModelToTask(fswTaskName, array1Element2PrescribedDataLog) @@ -493,7 +493,7 @@ def run(show_plots): array2ElementRefMsgList2.append(messaging.HingedRigidBodyMsg().write(array2ElementMessageData)) array2RotProfilerList[i].spinningBodyInMsg.subscribeTo(array2ElementRefMsgList2[i]) - + simTime3 = init_deploy_duration + 10 # [s] scSim.ConfigureStopTime(macros.sec2nano(simTime1 + simTime2 + simTime3)) scSim.ExecuteSimulation() @@ -733,4 +733,3 @@ def run(show_plots): run( True, # show_plots ) - \ No newline at end of file diff --git a/examples/scenarioFuelSlosh.py b/examples/scenarioFuelSlosh.py index d6cf743fc..613554480 100755 --- a/examples/scenarioFuelSlosh.py +++ b/examples/scenarioFuelSlosh.py @@ -321,7 +321,7 @@ def run(show_plots, damping_parameter, timeStep): scSim.AddModelToTask(simTaskName, dataLog) scLog = scObject.logger( - ["totOrbEnergy", "totOrbAngMomPntN_N", "totRotAngMomPntC_N", "totRotEnergy"], + ["totOrbEnergy", "totOrbAngMomPntN_N", "totRotAngMomPntC_N", "totRotEnergy"], simulationTimeStep) scSim.AddModelToTask(simTaskName, scLog) @@ -330,13 +330,13 @@ def run(show_plots, damping_parameter, timeStep): def get_rho(currentSimNanos, i): stateName = f'linearSpringMassDamperRho{i}' return scObject.dynManager.getStateObject(stateName).getState()[0][0] - + damperRhoLog = pythonVariableLogger.PythonVariableLogger({ "damperRho1": lambda currentSimNanos: get_rho(currentSimNanos, 1), "damperRho2": lambda currentSimNanos: get_rho(currentSimNanos, 2), "damperRho3": lambda currentSimNanos: get_rho(currentSimNanos, 3), }, simulationTimeStep) - + scSim.AddModelToTask(simTaskName, damperRhoLog) # @@ -436,7 +436,7 @@ def get_rho(currentSimNanos, i): plt.figure(6, figsize=(5, 4)) for rhojOut in rhojOuts: plt.plot(time, rhojOut) - + plt.legend(['Particle 1', 'Particle 2', 'Particle 3'], loc='lower right') plt.xlabel('Time (s)') plt.ylabel('Displacement (m)') diff --git a/examples/scenarioGroundDownlink.py b/examples/scenarioGroundDownlink.py index 599a17341..785bc4d2e 100644 --- a/examples/scenarioGroundDownlink.py +++ b/examples/scenarioGroundDownlink.py @@ -44,7 +44,7 @@ .. image:: /_images/Scenarios/scenarioGroundPassPolar.svg :align: center - + .. image:: /_images/Scenarios/scenarioGroundPassRange.svg :align: center diff --git a/examples/scenarioHaloOrbit.py b/examples/scenarioHaloOrbit.py index 59e0a93c4..b2201c6d2 100644 --- a/examples/scenarioHaloOrbit.py +++ b/examples/scenarioHaloOrbit.py @@ -316,5 +316,3 @@ def run(showPlots=True): run( True # Show plots ) - - diff --git a/examples/scenarioHelioTransSpice.py b/examples/scenarioHelioTransSpice.py index b3433a6ce..065f4aa84 100644 --- a/examples/scenarioHelioTransSpice.py +++ b/examples/scenarioHelioTransSpice.py @@ -199,4 +199,4 @@ def run(): if __name__ == "__main__": - run() \ No newline at end of file + run() diff --git a/examples/scenarioIntegratorsComparison.py b/examples/scenarioIntegratorsComparison.py index f7d8fc3f9..7c1591de2 100644 --- a/examples/scenarioIntegratorsComparison.py +++ b/examples/scenarioIntegratorsComparison.py @@ -26,12 +26,12 @@ python3 scenarioIntegratorsComparison.py -For information on how to setup different integrators, see :ref:`scenarioIntegrators` and :ref:`scenarioVariableTimeStepIntegrators`. +For information on how to setup different integrators, see :ref:`scenarioIntegrators` and :ref:`scenarioVariableTimeStepIntegrators`. Currently, Basilisk only supports explicit Runge-Kutta integrators, both of the regular and adaptive variations. Non-adaptive Runge-Kutta integrators can be controlled solely by the step size: larger step -sizes means that faster computation, but less accurate results. +sizes means that faster computation, but less accurate results. In contrast, adaptive Runge-Kutta methods are affected both by the step size and absolute and relative tolerance. These integrators will try @@ -39,10 +39,10 @@ smaller time step is used internally for greater accuracy. When using an adaptive integrator, the Basilisk dynamics task time step -can be increased without risk of increasing the integration error. However, +can be increased without risk of increasing the integration error. However, this also means that other modules in the task are updated less often, which might be undesirable. Additionally, spacecraft state messages will -also be updated less frequently. +also be updated less frequently. Finally, each integrator is associated with an order. Greater order integrators are more accurate, but more computationally @@ -54,11 +54,11 @@ These are the Euler method (order 1), Heun's method (order 2), the Runge-Kutta 4 (order 4), the Runge-Kutta-Fehlberg 4(5) (adaptive with order 5), and the Runge-Kutta-Fehlberg 7(8) (adaptive with order 8). -The adaptive integrators are used with two different absolute +The adaptive integrators are used with two different absolute tolerances: 0.1 and 10. Each integrator is used to propagate a two-body orbit around the -Earth. The final position of each propagation is compared to +Earth. The final position of each propagation is compared to the analytical solution, and a final position error is obtained. Moreover, the time that it takes to propagate each orbit is recorded. @@ -93,12 +93,12 @@ for the larger time steps in which time adaption takes place. Here, a tighter tolerance would translate into higher computational costs. However, this is hard to see in the plot given the inherent -noisiness of performance measuring. +noisiness of performance measuring. -Fixed-timestep integrators are helpful when you want your simulation runtime -to be consistent as you vary simulation parameters. Since there is no adaptation, -runtime will be similar even if the parameters change the stiffness of the system's -dynamic equations. Of course, this comes at the cost of accuracy, but can it be +Fixed-timestep integrators are helpful when you want your simulation runtime +to be consistent as you vary simulation parameters. Since there is no adaptation, +runtime will be similar even if the parameters change the stiffness of the system's +dynamic equations. Of course, this comes at the cost of accuracy, but can it be very useful for hardware-in-the-loop simulations. One should note that adaptive RK methods are inherently slower than diff --git a/examples/scenarioJupiterArrival.py b/examples/scenarioJupiterArrival.py index ecc1f8f14..3dfdac321 100644 --- a/examples/scenarioJupiterArrival.py +++ b/examples/scenarioJupiterArrival.py @@ -36,7 +36,7 @@ .. math:: N = \sqrt{\frac{\mu}{(-a)^{3}}}(t-t_p) = e \tan(\zeta)-\ln \left[ \tan \left( \frac{\zeta}{2} + \frac{\pi}{4} \right) \right] - + where the orbit equation in terms of :math:`\zeta` is :math:`r = a(1-e \sec(\zeta))` and :math:`\zeta = \cos^{-1}\left( \frac{ea}{a-r}\right)`. @@ -101,7 +101,7 @@ def run(show_plots): Args: show_plots (bool): Determines if the script should display plots """ - + # Create simulation variable names simTaskName = "simTask" simProcessName = "simProcess" @@ -153,14 +153,14 @@ def run(show_plots): r_J_2_S = 778298361. * 1000 # [m] Distance from Jupiter to Sun r_E_2_S = 149598023. * 1000 # [m] Distance from Earth to Sun r_SC_J_park = 800000. * 1000 # [m] Desired circular parking orbit radius - + V_J_C_S = np.sqrt(sunmu/r_J_2_S) # [m/s] (1) "J"upiter "C"ircular speed relative to the "S"un V_SC_C_J = np.sqrt(jupiter.mu/r_SC_J_park) # [m/s] (2) "S"pace"C"raft "C"ircular parking speed relative to "J"upiter. V_SC_A_S = np.sqrt( sunmu*r_E_2_S / ((r_J_2_S + r_E_2_S)*r_J_2_S) ) # [m/s] (3) "S"pace"C"raft speed at "A"poapsis of Hohmann transfer ellipse relative to the "S"un V_SC_A_J = V_SC_A_S - V_J_C_S # [m/s] (4) "S"pace"C"raft speed at "A"poapsis of Hohmann transfer ellipse relative to "J"upiter - + a_H = - ( jupiter.mu / ( V_SC_A_J*V_SC_A_J) ) # [m] Semimajor axis (-) of arrival hyperbola. - + V_SC_P_H = np.sqrt( (V_SC_A_J*V_SC_A_J) + (2*jupiter.mu / r_SC_J_park) ) # [m/s] (5) "S"pace"C"raft speed at "P"eriapsis of "H"ohmann transfer ellipse (Before delta V performed) Delta_V_Parking_Orbit = V_SC_C_J - V_SC_P_H e_H = 1 + ((r_SC_J_park*V_SC_A_J*V_SC_A_J) / jupiter.mu) @@ -170,7 +170,7 @@ def run(show_plots): oe.Omega = 48.2 * macros.D2R oe.omega = 347.8 * macros.D2R oe.f = 280.0 * macros.D2R - + # Determine required simulation time (time of flight) from SC initial position on hyperbola to periapsis. (Time until delta V must be performed) # Method: Use hyperbolic time equation to find TOF: (t-tp) zeta = 2*np.arctan( np.tan(oe.f / 2) * np.sqrt( (oe.e - 1) / (oe.e + 1) ) ) @@ -182,7 +182,7 @@ def run(show_plots): # Define other parking orbit parameters a_park = r_SC_J_park e_park = 0 - + # Initialize Spacecraft States with the initialization variables scObject.hub.r_CN_NInit = r_N # [m] = r_BN_N scObject.hub.v_CN_NInit = v_N # [m/s] = v_BN_N @@ -208,14 +208,14 @@ def run(show_plots): viz = vizSupport.enableUnityVisualization(scSim, simTaskName, scObject, # saveFile=__file__ ) - + # Initialize and execute simulation for the first section (stops at periapsis of hyperbola before delta V) scSim.InitializeSimulation() scSim.ConfigureStopTime(simulationTime) scSim.ExecuteSimulation() - + np.set_printoptions(precision=16) - + # Get current spacecraft states velRef = scObject.dynManager.getStateObject("hubVelocity") vN = dataRec.v_BN_N[-1] @@ -224,12 +224,12 @@ def run(show_plots): vHat = vN / np.linalg.norm(vN) vN = vN + Delta_V_Parking_Orbit*vHat velRef.setState(vN) - + # Run the simulation for 2nd chunk scSim.ConfigureStopTime(simulationTime + macros.sec2nano(300000)) - + scSim.ExecuteSimulation() - + # Pull recorded data for the entire simulation posData = dataRec.r_BN_N @@ -247,7 +247,7 @@ def run(show_plots): def plotOrbits(timeAxis, posData, jupiter, a_park, e_park): fileName = os.path.basename(os.path.splitext(__file__)[0]) - + # Figure 1: Draw the inertial position vector components plt.close("all") # Clears out plots from earlier test runs plt.figure(1) @@ -265,7 +265,7 @@ def plotOrbits(timeAxis, posData, jupiter, a_park, e_park): figureList = {} pltName = fileName + "1" figureList[pltName] = plt.figure(1) - + # Figure 2: Plot arrival to Jupiter plt.figure(2,figsize=(5,5)) plt.axis([-16, 16, -16, 16]) @@ -279,7 +279,7 @@ def plotOrbits(timeAxis, posData, jupiter, a_park, e_park): planetColor = '#008800' planetRadius = 1.0 ax.add_artist(plt.Circle((0, 0), planetRadius, color=planetColor)) - + # Draw the actual orbit from pulled data (DataRec) plt.plot(posData[:,0] / jupiter.radEquator, posData[:,1] / jupiter.radEquator, color='orangered', label='Simulated Flight') plt.xlabel('Jupiter Velocity Direction [DU]') @@ -297,8 +297,8 @@ def plotOrbits(timeAxis, posData, jupiter, a_park, e_park): figureList[pltName] = plt.figure(2) return figureList - - + + if __name__ == "__main__": run( True # show_plots diff --git a/examples/scenarioLagrangePointOrbit.py b/examples/scenarioLagrangePointOrbit.py index d358ab458..803677d37 100644 --- a/examples/scenarioLagrangePointOrbit.py +++ b/examples/scenarioLagrangePointOrbit.py @@ -387,5 +387,3 @@ def run(lagrangePoint, nOrbits, timestep, showPlots=True): 300, # Timestep (seconds) True # Show plots ) - - diff --git a/examples/scenarioSolarArrayDeployment.py b/examples/scenarioSolarArrayDeployment.py index 30f7b1922..608492cd9 100644 --- a/examples/scenarioSolarArrayDeployment.py +++ b/examples/scenarioSolarArrayDeployment.py @@ -75,7 +75,7 @@ def run(show_plots): # B frame is the hub body frame # S1 and S2 frames are the solar array body frames # M1 and M2 frames are the mount frames - + # DCMs representing the attitude of the hub frame with respect to the solar array frames dcm_BS1 = np.array([[0, 1, 0], [0, 0, -1], @@ -84,16 +84,16 @@ def run(show_plots): [0, 0, -1], [1, 0, 0]]) - # Position vector of solar array frame origin points with respect to hub frame origin point B + # Position vector of solar array frame origin points with respect to hub frame origin point B # expressed in B frame components rArray1SB_B = np.array([0.5 * 1.53, 0.0, 0.44]) # [m] rArray2SB_B = np.array([-0.5 * 1.53, 0.0, 0.44]) # [m] - # Position vector of mount frame origin points with respect to solar array frame origin points + # Position vector of mount frame origin points with respect to solar array frame origin points # expressed in solar array frame components r_M1S1_S1 = [0.0, 0.0, 0.0] # [m] r_M2S2_S2 = [0.0, 0.0, 0.0] # [m] - + # Position vector of mount frame with respect to solar array frame in hub frame components r_M1S1_B = dcm_BS1 @ r_M1S1_S1 # [m] r_M2S2_B = dcm_BS2 @ r_M2S2_S2 # [m] @@ -119,7 +119,7 @@ def run(show_plots): IElement_PntFc_F = [[I_element_11, 0.0, 0.0], [0.0, I_element_22, 0.0], [0.0, 0.0, I_element_33]] # [kg m^2] (approximate as rectangular prisms) - + # Deployment temporal information ramp_duration = 1.0 # [s] init_deploy_duration = 5.0 * 60.0 # [s] @@ -249,7 +249,7 @@ def run(show_plots): array2RotProfilerList[i].setThetaDDotMax(array2MaxRotAccelList1[i]) # [rad/s^2] array1RotProfilerList[i].setThetaInit(array1ThetaInit1) # [rad] array2RotProfilerList[i].setThetaInit(array2ThetaInit1) # [rad] - + scSim.AddModelToTask(fswTaskName, array1RotProfilerList[i]) scSim.AddModelToTask(fswTaskName, array2RotProfilerList[i]) array1RotProfilerList[i].spinningBodyInMsg.subscribeTo(array1ElementRefMsgList1[i]) @@ -361,7 +361,7 @@ def run(show_plots): array2ElementRefMsgList2.append(messaging.HingedRigidBodyMsg().write(array2ElementMessageData)) array2RotProfilerList[i].spinningBodyInMsg.subscribeTo(array2ElementRefMsgList2[i]) - + simTime3 = init_deploy_duration + 10 # [s] scSim.ConfigureStopTime(macros.sec2nano(simTime1 + simTime2 + simTime3)) scSim.ExecuteSimulation() @@ -539,4 +539,3 @@ def run(show_plots): run( True, # show_plots ) - \ No newline at end of file diff --git a/examples/scenarioTAMcomparison.py b/examples/scenarioTAMcomparison.py index e25e78d73..438d12bd9 100644 --- a/examples/scenarioTAMcomparison.py +++ b/examples/scenarioTAMcomparison.py @@ -140,7 +140,7 @@ def run(show_plots, orbitCase, useBias1, useBias2, useBounds1, useBounds2): """ The scenarios can be run with the following setups parameters: - + Args: show_plots (bool): Determines if the script should display plots orbitCase (str): Specify the type of orbit to be simulated {'elliptical','circular'} @@ -148,7 +148,7 @@ def run(show_plots, orbitCase, useBias1, useBias2, useBounds1, useBounds2): useBias2 (bool): Flag to use a sensor bias on TAM 2 useBounds1 (bool): Flag to use TAM 1 sensor bounds useBounds2 (bool): Flag to use TAM 2 sensor bounds - + """ # Create simulation variable names @@ -466,4 +466,3 @@ def run(show_plots, orbitCase, useBias1, useBias2, useBounds1, useBounds2): True, #Use sensor bounds 1 (True,False) False #Use sensor bounds 2 (True,False) ) - diff --git a/examples/scenarioTwoChargedSC.py b/examples/scenarioTwoChargedSC.py index 71ff0a941..6b269c84b 100644 --- a/examples/scenarioTwoChargedSC.py +++ b/examples/scenarioTwoChargedSC.py @@ -174,8 +174,8 @@ def run(show_plots): rListLeader = radii # radius of each sphere in the leader spacecraft spPosListFollower_H = spherelocation # The location of each sphere for the follower spacecraft rListFollower = radii # radius of each sphere in the follower spacecraft - - + + # If you would like to simulate each spacecraft by a single sphere, uncomment this section (line186 - line189) of # code and comment out the previous section lines (162-181) # create a list of sphere body-fixed locations and associated radii using one sphere for each spacecraft @@ -242,7 +242,7 @@ def run(show_plots): samplingTime = simulationTime // (numDataPoints - 1) dataRecL = scObjectLeader.scStateOutMsg.recorder() dataRecF = scObjectFollower.scStateOutMsg.recorder() - + # Add recorders to the Task scSim.AddModelToTask(dynTaskName, dataRecL) scSim.AddModelToTask(dynTaskName, dataRecF) @@ -276,7 +276,7 @@ def run(show_plots): attDataL_N = dataRecL.sigma_BN attDataF_N = dataRecF.sigma_BN - + # Calculate relative position vector and magnitude in the inertial frame relPosData_N = posDataL_N[:, 0:3] - posDataF_N[:, 0:3] relPosMagn = np.linalg.norm(relPosData_N, axis=1) @@ -317,7 +317,7 @@ def run(show_plots): plt.close("all") return figureList - + def plotOrbits(timeData, posDataL_N, posDataF_N, relPosMagn, attDataL_N, attDataF_N, P, spPosListLeader_H, rListLeader, LeaderSpCharges, spPosListFollower_H, rListFollower, FollowerSpCharges, relXPosData_H, relYPosData_H, diff --git a/src/architecture/utilities/_Documentation/BasiliskCorruptions.tex b/src/architecture/utilities/_Documentation/BasiliskCorruptions.tex index 4919ad351..2d220b66b 100644 --- a/src/architecture/utilities/_Documentation/BasiliskCorruptions.tex +++ b/src/architecture/utilities/_Documentation/BasiliskCorruptions.tex @@ -122,7 +122,7 @@ \section{Desired Corruptions} \begin{enumerate} \item Max \item Min - \end{enumerate} + \end{enumerate} \item Discretization \begin{enumerate} \item Max/min only = 2 bit @@ -286,7 +286,7 @@ \subsubsection{General for IMU} \item attach .noise, .discrete, and .sat to the corruption groups. \end{enumerate} -I am not sure of the "best practice" for building these types of things. Please provide whatever critiques you see fit. +I am not sure of the "best practice" for building these types of things. Please provide whatever critiques you see fit. diff --git a/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.cpp b/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.cpp index 946629397..95ae62663 100755 --- a/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.cpp +++ b/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.cpp @@ -75,10 +75,10 @@ void MrpProportionalDerivative::updateState(uint64_t callTime) // Compute P*delta_omega Eigen::Vector3d v3_temp2 = this->P * omega_BR_B; - + // Compute omega_r x [I]omega Eigen::Vector3d v3_temp3 = omega_RN_B.cross(this->ISCPntB_B * omega_BN_B); - + // Compute [I](d(omega_r)/dt - omega x omega_r) Eigen::Vector3d domega_RN_B = cArray2EigenVector3d(guidanceMsgPayload.domega_RN_B); Eigen::Vector3d v3_temp4 = this->ISCPntB_B * (domega_RN_B - omega_BN_B.cross(omega_RN_B)); diff --git a/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.h b/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.h index 85c40387a..7319c714b 100755 --- a/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.h +++ b/src/fswAlgorithms/attControl/mrpProportionalDerivative/mrpProportionalDerivative.h @@ -48,7 +48,7 @@ class MrpProportionalDerivative: public SysModel { ReadFunctor guidInMsg; //!< Attitude guidance input message ReadFunctor vehConfigInMsg; //!< Vehicle configuration input message Message cmdTorqueOutMsg; //!< Commanded torque output message - + BSKLogger *bskLogger; //!< BSK Logging private: diff --git a/src/fswAlgorithms/attControl/rateServoFullNonlinear/_Documentation/AVS-Sim-nonlinRateServo-2019-0327.tex b/src/fswAlgorithms/attControl/rateServoFullNonlinear/_Documentation/AVS-Sim-nonlinRateServo-2019-0327.tex index 3a98f574f..8571dc315 100755 --- a/src/fswAlgorithms/attControl/rateServoFullNonlinear/_Documentation/AVS-Sim-nonlinRateServo-2019-0327.tex +++ b/src/fswAlgorithms/attControl/rateServoFullNonlinear/_Documentation/AVS-Sim-nonlinRateServo-2019-0327.tex @@ -52,29 +52,29 @@ \section{Overview} This module computes a commanded control torque vector $\bm L_r$ using a rate based steering law that drives a body frame \frameDefinition{B} towards a time varying reference frame \frameDefinition{R}, based on a desired reference frame \frameDefinition{B*} (the desired body frame from the kinematic steering law). The module input messages and output message are illustrated in Figure~\ref{fig:moduleImg}. The output message is a body-frame control torque vector that is outlined in section 3, with $\bm L_r$ specifically computed in equation \ref{eq:MS:39}. - The required attitude guidance message contains both attitude tracking error rates as well as reference frame rates. This message is read in with every update cycle. The vehicle configuration message is only read in on reset and contains the spacecraft inertia tensor about the vehicle's center of mass location. The commanded body rates are read in from the steering module output message. - - The reaction wheel (RW) configuration message is optional. If the message name is specified, then the RW message is read in. If the optional RW availability message is present, then the control will only use the RWs that are marked available. + The required attitude guidance message contains both attitude tracking error rates as well as reference frame rates. This message is read in with every update cycle. The vehicle configuration message is only read in on reset and contains the spacecraft inertia tensor about the vehicle's center of mass location. The commanded body rates are read in from the steering module output message. + + The reaction wheel (RW) configuration message is optional. If the message name is specified, then the RW message is read in. If the optional RW availability message is present, then the control will only use the RWs that are marked available. The servo rate feedback control can compensate for Reaction Wheel (RW) gyroscopic effects as well. This is an optional input message where the RW configuration array message contains the RW spin axis $\hat{g}_{s,i}$ information and the RW polar inertia about the spin axis IWs,i . This is only read in on reset. The RW speed message contains the RW speed $\Omega_i$ and is read in every time step. The optional RW availability message can be used to include or not include RWs in the MRP feedback. This allows the module to selectively turn off some RWs. The default is that all RWs are operational and are included. \section{Initialization} -Simply call the module reset function prior to using this control module. This will reset the prior function call time variable, and reset the rotational rate error integral measure. The control update period $\Delta t$ is evaluated automatically. +Simply call the module reset function prior to using this control module. This will reset the prior function call time variable, and reset the rotational rate error integral measure. The control update period $\Delta t$ is evaluated automatically. \section{Steering Law Goals} -This technical note develops a rate based steering law that drives a body frame \frameDefinition{B} towards a time varying reference frame \frameDefinition{R}. The inertial frame is given by \frameDefinition{N}. The RW coordinate frame is given by $\mathcal{W_{i}}:\{ \hat{\bm g}_{s_{i}}, \hat{\bm g}_{t_{i}}, \hat{\bm g}_{g_{i}} \}$. Using MRPs, the overall control goal is +This technical note develops a rate based steering law that drives a body frame \frameDefinition{B} towards a time varying reference frame \frameDefinition{R}. The inertial frame is given by \frameDefinition{N}. The RW coordinate frame is given by $\mathcal{W_{i}}:\{ \hat{\bm g}_{s_{i}}, \hat{\bm g}_{t_{i}}, \hat{\bm g}_{g_{i}} \}$. Using MRPs, the overall control goal is \begin{equation} \label{eq:MS:1} \bm\sigma_{\mathcal{B}/\mathcal{R}} \rightarrow 0 \end{equation} -The reference frame orientation $\bm \sigma_{\mathcal{R}/\mathcal{N}}$, angular velocity $\bm\omega_{\mathcal{R}/\mathcal{N}}$ and inertial angular acceleration $\dot{\bm \omega}_{\mathcal{R}/\mathcal{N}}$ are assumed to be known. +The reference frame orientation $\bm \sigma_{\mathcal{R}/\mathcal{N}}$, angular velocity $\bm\omega_{\mathcal{R}/\mathcal{N}}$ and inertial angular acceleration $\dot{\bm \omega}_{\mathcal{R}/\mathcal{N}}$ are assumed to be known. The rotational equations of motion of a rigid spacecraft with $N$ Reaction Wheels (RWs) attached are given by\cite{schaub} \begin{equation} \label{eq:MS:2} - [I_{RW}] \dot{\bm \omega} = - [\tilde{\bm \omega}] \left( - [I_{RW}] \bm\omega + [G_{s}] \bm h_{s} + [I_{RW}] \dot{\bm \omega} = - [\tilde{\bm \omega}] \left( + [I_{RW}] \bm\omega + [G_{s}] \bm h_{s} \right) - [G_{s}] \bm u_{s} + \bm L \end{equation} where the inertia tensor $[I_{RW}]$ is defined as @@ -128,7 +128,7 @@ \section{Angular Velocity Servo Sub-System} \bm z = \int_{t_{0}}^{t_{f}} \leftexp{B}{ \delta\bm\omega}\ \D t \end{equation} -The rate servo Lyapunov function is defined as +The rate servo Lyapunov function is defined as \begin{equation} \label{eq:MS:35} V_{\bm\omega}(\delta\bm\omega, \bm z) = \frac{1}{2} \delta\bm\omega ^{T} [I_{\text{RW}}] \delta\bm\omega + \frac{1}{2} \bm z ^{T} [K_{I}] \bm z @@ -149,8 +149,8 @@ \section{Angular Velocity Servo Sub-System} \begin{multline} \label{eq:MS:38} \dot V_{\bm\omega} = \delta\bm\omega^{T} \Big( - - [\tilde{\bm \omega}_{\mathcal{B}/\mathcal{N}}] \left( - [I_{RW}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} + - [\tilde{\bm \omega}_{\mathcal{B}/\mathcal{N}}] \left( + [I_{RW}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} \right) - [G_{s}] \bm u_{s} + \bm L + [K_{I}] \bm z \\ - [I_{\text{RW}}](\bm\omega_{\mathcal{B}^{\ast}/\mathcal{R}} ' + \dot{\bm\omega}_{\mathcal{R}/\mathcal{N}} - {\bm\omega}_{\mathcal{B}/\mathcal{N}} \times \bm\omega_{\mathcal{R}/\mathcal{N}}) @@ -164,7 +164,7 @@ \section{Angular Velocity Servo Sub-System} Let $[P]^{T} = [P]>$ be a symmetric positive definite rate feedback gain matrix. The servo rate feedback control is defined as \begin{multline} \label{eq:MS:39} - [G_{s}]\bm u_{s} = [P]\delta\bm\omega + [K_{I}]\bm z - [\tilde{\bm\omega}_{\mathcal{B}^{\ast}/\mathcal{N}}] + [G_{s}]\bm u_{s} = [P]\delta\bm\omega + [K_{I}]\bm z - [\tilde{\bm\omega}_{\mathcal{B}^{\ast}/\mathcal{N}}] \left( [I_{\text{RW}}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} \right) \\ - [I_{\text{RW}}](\bm\omega_{\mathcal{B}^{\ast}/\mathcal{R}} ' + \dot{\bm\omega}_{\mathcal{R}/\mathcal{N}} - {\bm\omega}_{\mathcal{B}/\mathcal{N}} \times \bm\omega_{\mathcal{R}/\mathcal{N}}) + \bm L @@ -183,22 +183,22 @@ \section{Angular Velocity Servo Sub-System} \begin{align} \label{eq:MS:42} \dot V_{\omega} &= \delta\bm\omega^{T} \Big( - - [P]\delta\bm\omega - [\tilde{\bm \omega}_{\mathcal{B}/\mathcal{N}}] \left( - [I_{RW}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} - \right) - + [\tilde{\bm\omega}_{\mathcal{B}^{\ast}/\mathcal{N}}] + - [P]\delta\bm\omega - [\tilde{\bm \omega}_{\mathcal{B}/\mathcal{N}}] \left( + [I_{RW}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} + \right) + + [\tilde{\bm\omega}_{\mathcal{B}^{\ast}/\mathcal{N}}] \left( [I_{\text{RW}}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} \right) - \Big ) + \Big ) \nonumber \\ &= \delta\bm\omega^{T} \Big( - [P]\delta\bm\omega - - [\widetilde{\delta\bm \omega}] \left( - [I_{RW}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} - \right) + - [\widetilde{\delta\bm \omega}] \left( + [I_{RW}] \bm\omega_{\mathcal{B}/\mathcal{N}} + [G_{s}] \bm h_{s} + \right) \Big ) \nonumber \\ &= - \delta\bm\omega ^{T} [P] \delta\bm\omega < 0 \end{align} -Thus, in the absence of unmodeled torques, the servo control in Eq.~\eqref{eq:MS:39} is asymptotically stabilizing in rate tracking error $\delta\bm\omega$. +Thus, in the absence of unmodeled torques, the servo control in Eq.~\eqref{eq:MS:39} is asymptotically stabilizing in rate tracking error $\delta\bm\omega$. Next, the servo robustness to unmodeled external torques is investigated. Let us assume that the external torque vector $\bm L$ in Eq.~\eqref{eq:MS:2} only approximates the true external torque, and the unmodeled component is given by $\Delta \bm L$. Substituting the true equations of motion and the same servo control in Eq.~\eqref{eq:MS:39} into the Lyapunov rate expression in Eq.~\eqref{eq:MS:36} leads to \begin{equation} @@ -213,15 +213,15 @@ \section{Angular Velocity Servo Sub-System} Assuming that $\Delta\bm L$ is either constant as seen by the body frame, or at least varies slowly, then taking a body-frame time derivative of Eq.~\eqref{eq:MS:44} is \begin{equation} \label{eq:MS:45} - [I_{\text{RW}}]\delta\bm\omega'' + [P]\delta\bm\omega' + [K_{I}]\delta \bm \omega = \Delta\bm L' \approx 0 + [I_{\text{RW}}]\delta\bm\omega'' + [P]\delta\bm\omega' + [K_{I}]\delta \bm \omega = \Delta\bm L' \approx 0 \end{equation} -As $[I_{\text{RW}}]$, $[P]$ and $[K_{I}]$ are all symmetric positive definite matrices, these linear differential equations are stable, and $\delta\bm\omega\rightarrow0$ given that assumption that $\Delta\bm L' \approx 0$. +As $[I_{\text{RW}}]$, $[P]$ and $[K_{I}]$ are all symmetric positive definite matrices, these linear differential equations are stable, and $\delta\bm\omega\rightarrow0$ given that assumption that $\Delta\bm L' \approx 0$. \section{Unit Test} The unit test for this module \verb|test_MRP_feedback| tests a set of gains $K,K_i,P$ on a rigid body with no external torques, and with a fixed input reference attitude message. The torque requested by the controller is evaluated against python computed torques at 0s, 0.5s, 1s, 1.5s and 2s to within a tolerance of $10^{-8}$. After 1s the simulation is stopped and the reset() function is called to check that integral feedback related variables are properly reset. The following permutations are run: \begin{itemize} - \item The test is run for a case with error integration feedback ($k_i=0.01$) and one case where $k_i$ is set to a negative value, resulting in a case with no integrator. + \item The test is run for a case with error integration feedback ($k_i=0.01$) and one case where $k_i$ is set to a negative value, resulting in a case with no integrator. \item The RW array number is configured either to 4 or 0 \item The integral limit term is set to either 0 or 20 \item The RW availability message is tested in 3 manners. Either the availability message is not written where all wheels should default to being available. If the availability message is written, then the RWs are either zero to available or not available. @@ -238,8 +238,8 @@ \section{User Guide} \item $^B\dot{\mathbf{\omega}}_{RN}$ as \verb|guidCmdData.domega_RN_B| \item $[I]$, the inertia matrix of the body as \verb|vehicleConfigOut.ISCPntB_B| \item $\Omega_i$, speed of each reaction wheel in \verb|rwSpeedMessage.wheelSpeeds| -\item Gains $k,P$ in \verb|moduleConfig|. -\item The integral gain $K_i$ in \verb|moduleConfig|. Setting this variable to a negative number disables the error integration for the controller, leaving just PI terms. +\item Gains $k,P$ in \verb|moduleConfig|. +\item The integral gain $K_i$ in \verb|moduleConfig|. Setting this variable to a negative number disables the error integration for the controller, leaving just PI terms. \item The value of \verb|integralLimit|, used to limit the degree of integrator windup and reduce the chance of controller saturation. The integrator is required to maintain asymptotic tracking in the presence of an external disturbing torque. For this module, the integration limit is applied to each element of the integrated error vector $z$, and any elements greater than the limit are set to the limit instead. \item Commanded body rates omegap\_BastR\_B and omega\_BastR\_B diff --git a/src/fswAlgorithms/attControl/thrMomentumManagement/_Documentation/Basilisk-thrMomentumManagement-20160817.tex b/src/fswAlgorithms/attControl/thrMomentumManagement/_Documentation/Basilisk-thrMomentumManagement-20160817.tex index 066e2f542..64418cd7f 100755 --- a/src/fswAlgorithms/attControl/thrMomentumManagement/_Documentation/Basilisk-thrMomentumManagement-20160817.tex +++ b/src/fswAlgorithms/attControl/thrMomentumManagement/_Documentation/Basilisk-thrMomentumManagement-20160817.tex @@ -53,16 +53,16 @@ \section{Module Description} \subsection{Overall RW Momentum Management Outline} -To manage the Reaction Wheel (RW) angular momentum build-up over time, a thruster-based momentum dumping strategy is used. Figure~\ref{fig:Fig1} illustrates how the momentum dumping will occur simultaneously with an inertial pointing control solution. The output of {\tt thrMomentumManagement} module is a $\Delta \bm H$ vector. This output is then mapped into a thruster impulse request using the {\tt thrForceMapping} module. Note that this latter module is designed to map a control torque vector into thruster forces. If the input torque and output force sets are multiplied by time, the same module also functions to map a desired angular momentum changes vector $\Delta H$ into a set of thruster impulse requests. The final module {\tt thrMomentumDumping} in the series takes the thruster impulse requests and determines a thruster firing sequence to achieve this desired momentum change. The spacecraft attitude is held constant by simultaneously having a RW control module holding an inertial attitude. The process of holding the desired attitude leads to the RWs despinning to the desired level due the external thruster disturbances. +To manage the Reaction Wheel (RW) angular momentum build-up over time, a thruster-based momentum dumping strategy is used. Figure~\ref{fig:Fig1} illustrates how the momentum dumping will occur simultaneously with an inertial pointing control solution. The output of {\tt thrMomentumManagement} module is a $\Delta \bm H$ vector. This output is then mapped into a thruster impulse request using the {\tt thrForceMapping} module. Note that this latter module is designed to map a control torque vector into thruster forces. If the input torque and output force sets are multiplied by time, the same module also functions to map a desired angular momentum changes vector $\Delta H$ into a set of thruster impulse requests. The final module {\tt thrMomentumDumping} in the series takes the thruster impulse requests and determines a thruster firing sequence to achieve this desired momentum change. The spacecraft attitude is held constant by simultaneously having a RW control module holding an inertial attitude. The process of holding the desired attitude leads to the RWs despinning to the desired level due the external thruster disturbances. \subsection{Momentum Management Algorithm} Assume the spacecraft contains $N_{\text{RW}}$ RWs. The net RW angular momentum is given by \begin{equation} \bm h_{s} = \sum_{i=1}^{N_{\text{RW}}} \hat{\bm g}_{s_{i}} J_{s_{i}} \Omega_{i} -\end{equation} -where $\hat{\bm g}_{s_{i}}$ is the RW spin axis, $J_{s_{i}}$ is the spin axis RW inertia and $\Omega_{i}$ is the RW speed rate about this axis. -Because the inertial attitude of the spacecraft is assumed to be held nominally steady the body-relative RW cluster angular momentum rate can be approximated as +\end{equation} +where $\hat{\bm g}_{s_{i}}$ is the RW spin axis, $J_{s_{i}}$ is the spin axis RW inertia and $\Omega_{i}$ is the RW speed rate about this axis. +Because the inertial attitude of the spacecraft is assumed to be held nominally steady the body-relative RW cluster angular momentum rate can be approximated as \begin{equation} \dot{\bm h}_{s} = \frac{\leftexp{B}{\D}\bm h_{s}}{\D t} + \bm\omega_{B/N} \times \bm h_{s} \approx \frac{\leftexp{B}{\D}\bm h_{s}}{\D t} \end{equation} @@ -84,7 +84,7 @@ \subsection{Momentum Management Algorithm} \begin{equation} \leftexp{B}{\Delta}\bm H = -\leftexp{B}{\bm h}_{s} \frac{ |\bm h_{s}| - h_{s,\text{min}} - }{|\bm h_{s}|} + }{|\bm h_{s}|} \end{equation} This strategy requires a thruster firing solution which creates this desired $\leftexp{B}{\Delta}\bm H$ over the duration of the momentum dumping. The goal of the RW momentum management module is to simply compute if a $\leftexp{B}{\Delta}\bm H$ is required, or set it equal to zero if the RW momentum is too small. Not that this module will only compute $\leftexp{B}{\Delta}\bm H$ once. Either it is zero or non-zero. To reuse this momentum management module, the reset() function must be called. @@ -103,7 +103,7 @@ \subsection{Momentum Management Algorithm} \subsection{Module Messages} -The module input and output messages are illustrated in Figure~\ref{fig:moduleImg}. The module has a single output message of type {\tt CmdTorqueBodyIntMsg} which contains the desired momentum change $\leftexp{B}{\Delta}\bm H$. +The module input and output messages are illustrated in Figure~\ref{fig:moduleImg}. The module has a single output message of type {\tt CmdTorqueBodyIntMsg} which contains the desired momentum change $\leftexp{B}{\Delta}\bm H$. There are 2 required input messages. The message of type {\tt RWArrayConfigMsg} is read in during the {\tt reset()} method and provides the RW configuration states. The message of type {\tt RWSpeedMsg} provides the current RW speeds and is read in during the {\tt Update()} method. @@ -121,7 +121,7 @@ \subsection{{\tt reset()} Method} \section{Module Functions} \begin{itemize} \item \textbf{Perform a single angular momentum check after reset}: The module should only do this momentum check once after the {\tt reset()} method is called. - \item \textbf{Create an output message with the desired RWA momentum change}: The output is used by a separate module to determine a momentum dumping actuation implementation. + \item \textbf{Create an output message with the desired RWA momentum change}: The output is used by a separate module to determine a momentum dumping actuation implementation. \end{itemize} \section{Module Assumptions and Limitations} @@ -141,17 +141,17 @@ \section{Test Description and Success Criteria} \section{Test Parameters} -The simulation is setup with 4 RWs with identical $J_{s}$ values. +The simulation is setup with 4 RWs with identical $J_{s}$ values. The unit test verifies that the module output message vector matches expected values. \begin{table}[htbp] \caption{Error tolerance for each test.} \label{tab:errortol} \centering \fontsize{10}{10}\selectfont - \begin{tabular}{ c | c } % Column formatting, + \begin{tabular}{ c | c } % Column formatting, \hline\hline - \textbf{Output Value Tested} & \textbf{Tolerated Error} \\ + \textbf{Output Value Tested} & \textbf{Tolerated Error} \\ \hline - {\tt torqueRequestBody} & \input{AutoTeX/toleranceValue} \\ + {\tt torqueRequestBody} & \input{AutoTeX/toleranceValue} \\ \hline\hline \end{tabular} \end{table} @@ -165,12 +165,12 @@ \section{Test Results} \caption{Test results} \label{tab:results} \centering \fontsize{10}{10}\selectfont - \begin{tabular}{c | c } % Column formatting, + \begin{tabular}{c | c } % Column formatting, \hline\hline - \textbf{hsMinCheck} &\textbf{Pass/Fail} \\ + \textbf{hsMinCheck} &\textbf{Pass/Fail} \\ \hline - 0 & \input{AutoTeX/passFail0} \\ - 1 & \input{AutoTeX/passFail1} \\ + 0 & \input{AutoTeX/passFail0} \\ + 1 & \input{AutoTeX/passFail1} \\ \hline\hline \end{tabular} \end{table} @@ -190,7 +190,7 @@ \section{User Guide} The module configurable parameters include: \begin{itemize} \item {{\tt hs\_min} Parameter}: -This parameter dictates the desired lower ceiling of the RW cluster angular momentum. It must be set prior to calling the routine. +This parameter dictates the desired lower ceiling of the RW cluster angular momentum. It must be set prior to calling the routine. \end{itemize} diff --git a/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst b/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst index 1fb78d4e4..51d047113 100644 --- a/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst +++ b/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst @@ -49,7 +49,7 @@ At this stage of development, constraint compliance is only guaranteed for the a reference trajectory (see Detailed Module Description below). It may happen that portions of the reference trajectory between waypoints still violate the rotational constraints. Ensuring that this does not happen will be subject of further refinements of this module. For the time being, it is possible to circumvent this problem changing the grid refinement level ``N``. This changes the coordinates of the grid points, thus yielding a different reference trajectory for every ``N``. A small ``N`` -results in a coarser grid, which is more likely to yield a trajectory that violates some constraints, but is generally smoother. Viceversa, a higher ``N`` gives a +results in a coarser grid, which is more likely to yield a trajectory that violates some constraints, but is generally smoother. Viceversa, a higher ``N`` gives a finer grid where the chance of obtaining a constraint-incompliant grid is reduced. However, the trajectory in this case is less regular due to the fact that the interpolating curve is forced to pass through a larger number of waypoints. A higher ``N`` is also associated with a higher computational cost. @@ -63,10 +63,10 @@ parameter ``N``. Each grid node corresponds to an attitude. An undirected graph - ``startNode`` whose coordinates :math:`\sigma_{BN,S}` correspond to the attitude of the spacecraft contained in the ``vehicleConfigInMsg``; - ``goalNode`` whose coordinates :math:`\sigma_{BN,G}` correspond to the desired target attitude at the end of the maneuver. -Two different cost functions are used by the :math:`A^*` algorithm to search a valid path. The first is based on the total cartesian length of the path in MRP space. +Two different cost functions are used by the :math:`A^*` algorithm to search a valid path. The first is based on the total cartesian length of the path in MRP space. The second is the effort-based cost function computed integrating the control torque norm over the interpolated trajectory obtained from a path., as explained in `R. Calaon and H. Schaub `__. In both cases, the final reference passed to the Attitude Reference Message -consists in the interpolated curve obtained from the optimal path computed by :math:`A^*`, based on the chosen cost function. Interpolation is performed using the +consists in the interpolated curve obtained from the optimal path computed by :math:`A^*`, based on the chosen cost function. Interpolation is performed using the routine in :ref:`BSpline`. Note that this module does not implement the constant angular rate norm routine described in `R. Calaon and H. Schaub `__. @@ -87,7 +87,7 @@ The required module configuration is:: CAM.appendKeepOutDirection([1,0,0], keepOutFov) CAM.appendKeepInDirection([0,1,0], keepInFov) scSim.AddModelToTask(simTaskName, CAM) - + The module is configurable with the following parameters: .. list-table:: Module Parameters @@ -105,4 +105,4 @@ The module is configurable with the following parameters: * - ``BSplineType`` - desired type of BSpline: 0 for precise interpolation, 1 for least-squares approximation * - ``costFcnType`` - - desired cost function for the graph search algorithm: 0 for total MRP distance, 1 for effort-based cost. \ No newline at end of file + - desired cost function for the graph search algorithm: 0 for total MRP distance, 1 for effort-based cost. diff --git a/src/fswAlgorithms/attGuidance/sepPoint/sepPoint.rst b/src/fswAlgorithms/attGuidance/sepPoint/sepPoint.rst index f07a26877..2bdb42a4f 100644 --- a/src/fswAlgorithms/attGuidance/sepPoint/sepPoint.rst +++ b/src/fswAlgorithms/attGuidance/sepPoint/sepPoint.rst @@ -59,7 +59,7 @@ The required module configuration is:: attGuid.beta = beta attGuid.alignmentPriority = alignmentPriority attGuid.modelTag = "sepPoint" - + The module is configurable with the following parameters: .. list-table:: Module Parameters @@ -80,4 +80,4 @@ The module is configurable with the following parameters: - half-cone angle of the keep-in Sun constraint * - ``alignmentPriority`` - 0 - - 0 to prioritize incidence on the arrays, 1 to prioritize Sun-constrained direction. \ No newline at end of file + - 0 to prioritize incidence on the arrays, 1 to prioritize Sun-constrained direction. diff --git a/src/fswAlgorithms/attGuidance/waypointReference/_UnitTest/test_WaypointReference.py b/src/fswAlgorithms/attGuidance/waypointReference/_UnitTest/test_WaypointReference.py index ca8359715..c68a626e1 100644 --- a/src/fswAlgorithms/attGuidance/waypointReference/_UnitTest/test_WaypointReference.py +++ b/src/fswAlgorithms/attGuidance/waypointReference/_UnitTest/test_WaypointReference.py @@ -52,17 +52,17 @@ def test_waypointReference(show_plots, attType, MRPswitching, useReferenceFrame, **Validation Test Description** This unit test script tests the capability of the WaypointReference module to correctly read time-tagged - attitude parameters, angular rates and angular accelerations from a text file. - First a text file is generated that contains a sequence of time-tagged attitude parameters, angular rates + attitude parameters, angular rates and angular accelerations from a text file. + First a text file is generated that contains a sequence of time-tagged attitude parameters, angular rates and angular accelerations; subsequently, the same file is fed to the waypointReference module. The module is tested against all the attitude types that it supports: - MRPs - Euler Parameters (quaternion) [q0, q1, q2, q3] - Euler Parameters (quaternion) [q1, q2, q3, qs] - and with angular rates and accelerations that can be expressed either in the inertial frame N or in the + and with angular rates and accelerations that can be expressed either in the inertial frame N or in the reference frame R. - This unit test writes 5 time-tagged attitudes at times t = [1.0, 2.0, 3.0, 4.0, 5.0]s. Real values of - attitude parameters, angular rates and angular accelerations in inertial frames are stored in + This unit test writes 5 time-tagged attitudes at times t = [1.0, 2.0, 3.0, 4.0, 5.0]s. Real values of + attitude parameters, angular rates and angular accelerations in inertial frames are stored in ``attReal_RN``, ``omegaReal_RN_N`` and ``omegaDotReal_RN_N`` respectively. **Test Parameters** @@ -75,21 +75,21 @@ def test_waypointReference(show_plots, attType, MRPswitching, useReferenceFrame, **Description of Variables Being Tested** - This unit test checks the correctness of the output attitude reference message + This unit test checks the correctness of the output attitude reference message - ``attRefMsg`` compared to the real values stored in the data file ``attReal_RN``, ``omegaReal_RN_N`` and ``omegaDotReal_RN_N``. The simulation is run with a sampling frequency of 0.25 s, which is higher than the frequency with which the attitude - waypoints are saved in the data file (1.0 s), starting at t = 0. + waypoints are saved in the data file (1.0 s), starting at t = 0. - For t < 1.0 s we check that the attitude in ``attRefMsg`` coincides with ``attReal_RN`` at time t = 1.0 s, + For t < 1.0 s we check that the attitude in ``attRefMsg`` coincides with ``attReal_RN`` at time t = 1.0 s, while rates and accelerations in ``attRefMsg`` are zero. - For t > 5.0 s we check that the attitude in ``attRefMsg`` coincides with ``attReal_RN`` at time t = 5.0 s, + For t > 5.0 s we check that the attitude in ``attRefMsg`` coincides with ``attReal_RN`` at time t = 5.0 s, while rates and accelerations in ``attRefMsg`` are zero. - For 1.0 s <= t <= 5.0 s we check that the attitude, rates and accelerations in ``attRefMsg`` coincide with + For 1.0 s <= t <= 5.0 s we check that the attitude, rates and accelerations in ``attRefMsg`` coincide with the linear interpolation of ``attReal_RN``, ``omegaReal_RN_N`` and ``omegaDotReal_RN_N``. """ @@ -132,7 +132,7 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu dataFileName = os.path.join(path, dataFileName) delimiter = "," fDataFile = open(dataFileName, "w+") - + # create the datafile and store the real attitude, rate and acceleration values t = [] attReal_RN = [] @@ -166,7 +166,7 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu else: print("Invalid attitude type") return - + if not useReferenceFrame: lineString += str(omegaReal_RN_N[-1].tolist())[1:-1] + delimiter + str(omegaDotReal_RN_N[-1].tolist())[1:-1] + '\n' else: @@ -174,7 +174,7 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu omegaReal_RN_R = np.matmul(RN, omegaReal_RN_N[-1]) omegaDotReal_RN_R = np.matmul(RN, omegaDotReal_RN_N[-1]) lineString += str(omegaReal_RN_R.tolist())[1:-1] + delimiter + str(omegaDotReal_RN_R.tolist())[1:-1] + '\n' - + # write line on file fDataFile.write(lineString) @@ -201,17 +201,17 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu # Need to call the self-init and cross-init methods unitTestSim.InitializeSimulation() - unitTestSim.ConfigureStopTime(simulationTime) + unitTestSim.ConfigureStopTime(simulationTime) # Begin the simulation time run set above unitTestSim.ExecuteSimulation() # This pulls the sampling times from the simulation run. timeData = dataLog.times() * macros.NANO2SEC - + # Check if logged data matches the real attitude, rates and accelerations j = 0 - + sigma_RN = [[], [], []] # checking attitude msg for t < t_min for i in range(len(timeData)-1): @@ -229,7 +229,7 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu if not unitTestSupport.isVectorEqual(dataLog.domega_RN_N[i], np.array([0.0, 0.0, 0.0]), accuracy): testFailCount += 1 testMessages.append("FAILED: " + testModule.modelTag + " Module failed angular acceleration check at time t = {}".format(timeData[i])) - + # checking attitude msg for t_min <= t <= t_max elif timeData[i] >= t[0] and timeData[i] <= t[-1]: while (timeData[i] >= t[j] and timeData[i] <= t[j+1]) == False: @@ -256,7 +256,7 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu if not unitTestSupport.isVectorEqual(dataLog.domega_RN_N[i], omegaDot_RN_N_int, accuracy): testFailCount += 1 testMessages.append("FAILED: " + testModule.modelTag + " Module failed angular acceleration check at time t = {}".format(timeData[i])) - + # checking attitude msg for t < t_max else: if not unitTestSupport.isVectorEqual(dataLog.sigma_RN[i], attReal_RN[-1], accuracy): @@ -290,4 +290,3 @@ def waypointReferenceTestFunction(attType, MRPswitching, useReferenceFrame, accu 1e-12) if os.path.exists(dataFileName): os.remove(dataFileName) - \ No newline at end of file diff --git a/src/fswAlgorithms/attGuidance/waypointReference/waypointReference.rst b/src/fswAlgorithms/attGuidance/waypointReference/waypointReference.rst index 64663eb84..422baad9b 100644 --- a/src/fswAlgorithms/attGuidance/waypointReference/waypointReference.rst +++ b/src/fswAlgorithms/attGuidance/waypointReference/waypointReference.rst @@ -1,9 +1,9 @@ Executive Summary ----------------- -Module that reads the reorientation maneuver of a spacecraft from a text file, likely created outside of Basilisk, and outputs an +Module that reads the reorientation maneuver of a spacecraft from a text file, likely created outside of Basilisk, and outputs an Attitude Reference Message. This module makes it possible to reproduce on Basilisk attitude orientation maneuvers computed externally. The module outputs an Attitude -Reference Message that follows the sequence of waypoints contained in the text file. The text file must be formatted appropriately for the module to be able to read +Reference Message that follows the sequence of waypoints contained in the text file. The text file must be formatted appropriately for the module to be able to read the information correctly: see Module Assumptions and Limitaions for a detailed explanation on how to do this. @@ -28,18 +28,18 @@ provides information on what this message is used for. Module Assumptions and Limitations ---------------------------------- The module assumes that the text file is written in a compatible form, which means that each piece of information must be provided in the correct order. -Each line of text should contain information relative to one and only one waypoint along the maneuver: such information must be in the following order: time, -attitude parameters, angular rates, angular acceleration. There must be a ``delimiter`` between each piece of information and the next one, as well al between +Each line of text should contain information relative to one and only one waypoint along the maneuver: such information must be in the following order: time, +attitude parameters, angular rates, angular acceleration. There must be a ``delimiter`` between each piece of information and the next one, as well al between different elements of the same piece of information (for example between consecutive entries of the 3-dimensional angular rate vector). Using MRP to represent -the attitude :math:`\sigma_{\mathcal{R/N}}=[\sigma_1, \sigma_2, \sigma_3]`, expressing angular rates :math:`{}^{\mathcal{N}}\omega_{\mathcal{R/N}}=[\omega_1, \omega_2, \omega_3]` -and accelerations :math:`{}^{\mathcal{N}}\dot{\omega}_{\mathcal{R/N}}=[\dot{\omega}_1, \dot{\omega}_2, \dot{\omega}_3]` in the inertial frame, and using the comma as a delimiter, +the attitude :math:`\sigma_{\mathcal{R/N}}=[\sigma_1, \sigma_2, \sigma_3]`, expressing angular rates :math:`{}^{\mathcal{N}}\omega_{\mathcal{R/N}}=[\omega_1, \omega_2, \omega_3]` +and accelerations :math:`{}^{\mathcal{N}}\dot{\omega}_{\mathcal{R/N}}=[\dot{\omega}_1, \dot{\omega}_2, \dot{\omega}_3]` in the inertial frame, and using the comma as a delimiter, one waypoint is correctly read if presented as a line like the following .. math:: t, \sigma_1, \sigma_2, \sigma_3, \omega_1, \omega_2, \omega_3, \dot{\omega}_1, \dot{\omega}_2, \dot{\omega}_3 - + The module is conceptually very simple and makes no further assumptions. However, the user might want to use a sampling frequency in the -Basilisk simulation that is equal or higher than the frequency of the waypoints. For lower sampling frequencies, the module output does not give a +Basilisk simulation that is equal or higher than the frequency of the waypoints. For lower sampling frequencies, the module output does not give a trustworthy representation of the maneuver. @@ -53,11 +53,11 @@ The module reads a sequence of time-tagged waypoints. Defining :math:`t=[t_0,... - for :math:`t_{sim} > t_N`: the attitude is held constant and equal to the attitude of the last waypoint; angular rates and acceleration are kept at zero. When reading from the data file, the module always maps the attitude to the short rotation MRP set, regardless of the attitude type. This means that, for a data file that -describes large attitude rotations (larger than 180 deg), the ``attRefOutMsg.sigma_RN`` will present a discontinuity. When two subsequent waypoints are mapped into different +describes large attitude rotations (larger than 180 deg), the ``attRefOutMsg.sigma_RN`` will present a discontinuity. When two subsequent waypoints are mapped into different MRP sets, the interpolation is carried out in that time interval between the first waypoint and the shadow set of the second waypoint. This allows for a non-singular attitude description. - - + + User Guide ---------- The module assumes the data file is in plain text form and the following format: @@ -77,7 +77,7 @@ The required module configuration is:: waypointReferenceModule.dataFileName = dataFileName waypointReferenceModule.attitudeType = 0 unitTestSim.AddModelToTask(unitTaskName, waypointReferenceModule) - + Note that for ``attitudeType``, a valid input must be provided by the user: 0 - MRP, 1 - EP or quaternions (q0, q1, q2, q3), 2 - EP or quaternions (q1, q2, q3, qs). No default attitude type is used by the module, therefore faliure to specify this parameter results in breaking the simulation. diff --git a/src/fswAlgorithms/effectorInterfaces/forceTorqueThrForceMapping/forceTorqueThrForceMapping.rst b/src/fswAlgorithms/effectorInterfaces/forceTorqueThrForceMapping/forceTorqueThrForceMapping.rst index 84b41f040..16ea65c73 100644 --- a/src/fswAlgorithms/effectorInterfaces/forceTorqueThrForceMapping/forceTorqueThrForceMapping.rst +++ b/src/fswAlgorithms/effectorInterfaces/forceTorqueThrForceMapping/forceTorqueThrForceMapping.rst @@ -12,9 +12,9 @@ onto a set of thrusters. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. Both the `cmdTorqueInMsg` and `cmdForceInMsg` are optional. diff --git a/src/fswAlgorithms/effectorInterfaces/hingedRigidBodyPIDMotor/hingedRigidBodyPIDMotor.rst b/src/fswAlgorithms/effectorInterfaces/hingedRigidBodyPIDMotor/hingedRigidBodyPIDMotor.rst index f09227f12..233b48b67 100644 --- a/src/fswAlgorithms/effectorInterfaces/hingedRigidBodyPIDMotor/hingedRigidBodyPIDMotor.rst +++ b/src/fswAlgorithms/effectorInterfaces/hingedRigidBodyPIDMotor/hingedRigidBodyPIDMotor.rst @@ -26,12 +26,12 @@ provides information on what this message is used for. - Input Spinning Body Message Message. * - hingedRigidBodyRefInMsg - :ref:`HingedRigidBodyMsgPayload` - - Input Spinning Body Reference Message Message. + - Input Spinning Body Reference Message Message. Module Assumptions and Limitations ---------------------------------- -This module is very simple and does not make any assumptions. The only limitations are those inherent to a PID type of control law, here implemented. The type of response (underdamped, +This module is very simple and does not make any assumptions. The only limitations are those inherent to a PID type of control law, here implemented. The type of response (underdamped, overdamped, or critically damped) depends on the choice of gains provided as inputs to the module. @@ -54,7 +54,7 @@ The required module configuration is:: motor.P = P motor.P = I unitTestSim.AddModelToTask(unitTaskName, motor) - + The module is configurable with the following parameters: .. list-table:: Module Parameters diff --git a/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst b/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst index 7cda18045..c7d3a9afb 100644 --- a/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst +++ b/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst @@ -25,9 +25,9 @@ The corresponding angle the prescribed body moves through during the rotation is Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages @@ -53,12 +53,12 @@ Detailed Module Description --------------------------- This 1 DOF rotational motion kinematic profiler module is written to profile spinning body motion with respect to a body-fixed mount frame. The inputs to the profiler are the scalar maximum angular acceleration for the rotation -:math:`\alpha_{\text{max}}`, the prescribed body's initial attitude with respect to the mount frame as the Principal +:math:`\alpha_{\text{max}}`, the prescribed body's initial attitude with respect to the mount frame as the Principal Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's reference attitude with respect to the mount frame as the Principal Rotation Vector ``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. The prescribed body is assumed to be non-rotating at the beginning of the rotation. - -Subtracting the initial principal rotation vector from the reference principal rotation vector gives the required + +Subtracting the initial principal rotation vector from the reference principal rotation vector gives the required rotation angle and axis for the rotation: .. math:: @@ -68,23 +68,23 @@ rotation angle and axis for the rotation: \hat{\textbf{{e}}} = \frac{\cos \frac{\Phi_0}{2} \sin \frac{\Phi_1}{2} \hat{\textbf{{e}}}_1 - \cos \frac{\Phi_1}{2} \sin \frac{\Phi_0}{2} \hat{\textbf{{e}}}_0 + \sin \frac{\Phi_1}{2} \sin \frac{\Phi_0}{2} \hat{\textbf{{e}}}_1 \times \hat{\textbf{{e}}}_0 }{\sin \frac{\Phi_{\text{ref}}}{2}} During the first half of the rotation, the prescribed body is constantly accelerated with the given maximum -angular acceleration. The prescribed body's angular velocity increases linearly during the acceleration phase and +angular acceleration. The prescribed body's angular velocity increases linearly during the acceleration phase and reaches a maximum magnitude halfway through the rotation. The switch time :math:`t_s` is the simulation time halfway through the rotation: - + .. math:: t_s = t_0 + \frac{\Delta t}{2} where the time required for the rotation :math:`\Delta t` is determined using the inputs to the profiler: - + .. math:: \Delta t = t_f - t_0 = 2 \sqrt{ \Phi_{\text{ref}} / \ddot{\Phi}_{\text{max}}} The resulting trajectory of the angle :math:`\Phi` swept during the first half of the rotation is parabolic. The profiled -motion is concave upwards if the reference angle :math:`\Phi_{\text{ref}}` is greater than zero. If the converse is true, +motion is concave upwards if the reference angle :math:`\Phi_{\text{ref}}` is greater than zero. If the converse is true, the profiled motion is instead concave downwards. The described motion during the first half of the rotation is characterized by the expressions: - + .. math:: \omega_{\mathcal{F} / \mathcal{M}}(t) = \alpha_{\text{max}} @@ -94,17 +94,17 @@ is characterized by the expressions: .. math:: \Phi(t) = c_1 (t - t_0)^2 -where +where .. math:: c_1 = \frac{\Phi_{\text{ref}}}{2(t_s - t_0)^2} Similarly, the second half of the rotation decelerates the prescribed body constantly until it reaches a -non-rotating state. The prescribed body angular velocity decreases linearly from its maximum magnitude back to zero. +non-rotating state. The prescribed body angular velocity decreases linearly from its maximum magnitude back to zero. The trajectory swept during the second half of the rotation is quadratic and concave downwards if the reference angle :math:`\Phi_{\text{ref}}` is positive. If :math:`\Phi_{\text{ref}}` is negative, the profiled motion is instead concave upwards. The described motion during the second half of the rotation is characterized by the expressions: - + .. math:: \ddot{\Phi}(t) = -\alpha_{\text{max}} @@ -114,7 +114,7 @@ concave upwards. The described motion during the second half of the rotation is .. math:: \Phi(t) = c_2 (t - t_f)^2 + \Phi_{\text{ref}} - where + where .. math:: c_2 = \frac{\Phi_{\text{ref}}}{2(t_s - t_f)^2} @@ -169,4 +169,3 @@ The user is required to set the above configuration data parameters, as they are #. Add the module to the task list:: unitTestSim.AddModelToTask(unitTaskName, PrescribedRot1DOF) - diff --git a/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst b/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst index 4b38827a4..2e0764dc7 100644 --- a/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst +++ b/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst @@ -27,9 +27,9 @@ The corresponding angle the prescribed body moves through during the rotation is Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages @@ -189,4 +189,3 @@ The user is required to set the above configuration data parameters, as they are #. Add the module to the task list:: unitTestSim.AddModelToTask(unitTaskName, PrescribedRot2DOF) - diff --git a/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst b/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst index 91aefda66..4eba6d156 100644 --- a/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst +++ b/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst @@ -24,9 +24,9 @@ The corresponding translational trajectory the prescribed body moves through dur Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages @@ -161,4 +161,3 @@ The user is required to set the above configuration data parameters, as they are #. Add the module to the task list:: unitTestSim.AddModelToTask(unitTaskName, PrescribedTrans) - diff --git a/src/fswAlgorithms/effectorInterfaces/solarArrayReference/solarArrayReference.rst b/src/fswAlgorithms/effectorInterfaces/solarArrayReference/solarArrayReference.rst index c8a46d229..36653bbc0 100644 --- a/src/fswAlgorithms/effectorInterfaces/solarArrayReference/solarArrayReference.rst +++ b/src/fswAlgorithms/effectorInterfaces/solarArrayReference/solarArrayReference.rst @@ -44,7 +44,7 @@ For this module to operate, the user needs to provide two unit directions as inp - :math:`{}^\mathcal{B}\boldsymbol{\hat{a}}_1`: direction of the solar array drive, about which the rotation happens; - :math:`{}^\mathcal{B}\boldsymbol{\hat{a}}_2`: direction perpendicular to the solar array surface, with the array at a zero rotation. -To compute the reference rotation :math:`\theta_R`, the module computes the unit vector :math:`{}^\mathcal{R}\boldsymbol{\hat{a}}_2`, which is coplanar with +To compute the reference rotation :math:`\theta_R`, the module computes the unit vector :math:`{}^\mathcal{R}\boldsymbol{\hat{a}}_2`, which is coplanar with :math:`{}^\mathcal{B}\boldsymbol{\hat{a}}_1` and the Sun direction :math:`{}^\mathcal{R}\boldsymbol{\hat{r}}_S`. This is obtained as: .. math:: @@ -72,7 +72,7 @@ The required module configuration is:: solarArray.a2Hat_B = [0, 0, 1] solarArray.attitudeFrame = 0 unitTestSim.AddModelToTask(unitTaskName, solarArray) - + The module is configurable with the following parameters: .. list-table:: Module Parameters diff --git a/src/fswAlgorithms/effectorInterfaces/thrFiringRemainder/_Documentation/secModuleDescription.tex b/src/fswAlgorithms/effectorInterfaces/thrFiringRemainder/_Documentation/secModuleDescription.tex index 12ef87fa4..8dddf866d 100644 --- a/src/fswAlgorithms/effectorInterfaces/thrFiringRemainder/_Documentation/secModuleDescription.tex +++ b/src/fswAlgorithms/effectorInterfaces/thrFiringRemainder/_Documentation/secModuleDescription.tex @@ -3,31 +3,31 @@ \section{Module Description} -This module implements a remainder tracking thruster firing logic. More details can be found in Reference~\citenum{Alcorn:2016rz}. +This module implements a remainder tracking thruster firing logic. More details can be found in Reference~\citenum{Alcorn:2016rz}. \subsection{Module Input and Output Messages} As illustrated in Figure~\ref{fig:moduleImg}, the module reads in two messages. One message contains the thruster configuration message from which the maximum thrust force value for each thruster is extracted and stored in the module. This message is only read in on {\tt reset()}. -The second message reads in an array of requested thruster force values with every {\tt Update()} function call. These force values $F_{i}$ can be positive if on-pulsing is requested, or negative if off-pulsing is required. On-pulsing is used to achieve an attitude control torque onto the spacecraft by turning on a thruster. Off-pulsing assumes a thruster is nominally on, such as with doing an extended orbit correction maneuver, and the attitude control is achieved by doing periodic off-pulsing. +The second message reads in an array of requested thruster force values with every {\tt Update()} function call. These force values $F_{i}$ can be positive if on-pulsing is requested, or negative if off-pulsing is required. On-pulsing is used to achieve an attitude control torque onto the spacecraft by turning on a thruster. Off-pulsing assumes a thruster is nominally on, such as with doing an extended orbit correction maneuver, and the attitude control is achieved by doing periodic off-pulsing. -The output of the module is a message containing an array of thruster on-time requests. If these on-times are larger than the control period, then the thruster remains on only for the control period upon which the on-criteria is reevaluated. +The output of the module is a message containing an array of thruster on-time requests. If these on-times are larger than the control period, then the thruster remains on only for the control period upon which the on-criteria is reevaluated. \subsection{reset() Functionality} \begin{itemize} - \item The control period is dynamically evaluated in the module by comparing the current time with the prior call time. In {\tt reset()} the {\tt prevCallTime} variable is reset to 0. + \item The control period is dynamically evaluated in the module by comparing the current time with the prior call time. In {\tt reset()} the {\tt prevCallTime} variable is reset to 0. \item The thruster configuration message is read in and the number of thrusters is stored in the module variable {\tt numThrusters}. The maximum force per thruster is stored in {\tt maxThrust}. \item The on-time pulse remainder variable is reset for each thruster back to 0.0. \end{itemize} \subsection{Update() Functionality} -The goal of the {\tt update()} method is to read in the current attitude control thruster force message and map these into a thruster on-time output message. Let $\Delta t_{\text{min}}$ be the minimum on-time that can be implemented with a thruster. If the requested on-time is less than $\Delta t_{\text{min}}$, then the requested thruster on-time is clipped to zero. In the following algorithm unimplemented fractional on-times less than $\Delta t_{\text{min}}$ are tracked and accumulated, providing additional pointing accuracy. For example, if the minimum on-time is 20 milli-seconds, an on-time algorithm without remainder calculation would create a deadband about the 20 milli-second control request. With the remainder logic, if 5 milli-second on-time requests are computed, these are accumulated such that every 4$^{\text{th}}$ control step a 20 milli-second burn is requested. This reduces the deadband behavior of the thruster and achieves better pointing. In this example the 5 milli-second un-implemented on-times are accumulated in the variable $\Delta t_{\text{partial}}$. +The goal of the {\tt update()} method is to read in the current attitude control thruster force message and map these into a thruster on-time output message. Let $\Delta t_{\text{min}}$ be the minimum on-time that can be implemented with a thruster. If the requested on-time is less than $\Delta t_{\text{min}}$, then the requested thruster on-time is clipped to zero. In the following algorithm unimplemented fractional on-times less than $\Delta t_{\text{min}}$ are tracked and accumulated, providing additional pointing accuracy. For example, if the minimum on-time is 20 milli-seconds, an on-time algorithm without remainder calculation would create a deadband about the 20 milli-second control request. With the remainder logic, if 5 milli-second on-time requests are computed, these are accumulated such that every 4$^{\text{th}}$ control step a 20 milli-second burn is requested. This reduces the deadband behavior of the thruster and achieves better pointing. In this example the 5 milli-second un-implemented on-times are accumulated in the variable $\Delta t_{\text{partial}}$. -If the {\tt update()} method is called for the first time after reset, then there is no knowledge of the control period $\Delta t$. In this case the control period is set to 2 seconds, unless the module parameter \texttt{defaultControlPeiod} is set to a different value. If this is a repeated call of the {\tt update()} method then the control period $\Delta t$ is evaluated by differencing the current time with the prior call time. Next a loop goes over each installed thruster to map the requested force $F_{i}$ into an on-time $t_{i}$. The following logic is used. +If the {\tt update()} method is called for the first time after reset, then there is no knowledge of the control period $\Delta t$. In this case the control period is set to 2 seconds, unless the module parameter \texttt{defaultControlPeiod} is set to a different value. If this is a repeated call of the {\tt update()} method then the control period $\Delta t$ is evaluated by differencing the current time with the prior call time. Next a loop goes over each installed thruster to map the requested force $F_{i}$ into an on-time $t_{i}$. The following logic is used. \begin{itemize} - \item If off-pulsing is used then $F_{i}\le 0$ and we set $$F_{i} += F_{\text{max}}$$ to a reduced thrust to achieve the negative $F_{i}$ force. - \item Next, if $F_{i} < 0$ then it set to be equal to zero. This can occur if an off-pulsing request is larger than the maximum thruster force magnitude $F_{\text{max}}$. - \item The nominal thruster on-time is computed using $$t_{i} = \dfrac{F_{i}}{F_{\text{max}}} \Delta t$$. + \item If off-pulsing is used then $F_{i}\le 0$ and we set $$F_{i} += F_{\text{max}}$$ to a reduced thrust to achieve the negative $F_{i}$ force. + \item Next, if $F_{i} < 0$ then it set to be equal to zero. This can occur if an off-pulsing request is larger than the maximum thruster force magnitude $F_{\text{max}}$. + \item The nominal thruster on-time is computed using $$t_{i} = \dfrac{F_{i}}{F_{\text{max}}} \Delta t$$. \item If there un-implemented on-time requested $\Delta t_{\text{partial}}$ from earlier {\tt update()} method calls, these are added to the current on-time request using $$t_{i} += \Delta t_{\text{partial}}$$ After this step the variable $\Delta t_{\text{partial}}$ is reset to 0 as the remainder calculation is stored in the on-time variable $t_{i}$. \item If $t_{i} < \Delta t_{\text{partial}}$ then on-time request is set to zero and the remained is set to $\Delta t_{\text{partial}} = t_{i}$ \item If $t_{i} > \Delta $ then the requested force is larger than $F_{\text{max}}$ and the control is saturated. In this case the on-time is set to 1.1$\Delta t$ such that the thruster remains on through the control period. diff --git a/src/fswAlgorithms/effectorInterfaces/thrFiringSchmitt/_Documentation/secModuleDescription.tex b/src/fswAlgorithms/effectorInterfaces/thrFiringSchmitt/_Documentation/secModuleDescription.tex index 81fe86048..67e7bbacb 100644 --- a/src/fswAlgorithms/effectorInterfaces/thrFiringSchmitt/_Documentation/secModuleDescription.tex +++ b/src/fswAlgorithms/effectorInterfaces/thrFiringSchmitt/_Documentation/secModuleDescription.tex @@ -7,20 +7,20 @@ \section{Model Description} $$ l = \frac{t_{i}}{t_{\text{min}}} $$ -If $l$ is larger than a threshold $l_{\text{on}}$ then the thruster control time is set to $t_{i} = t_{\text{min}}$. Once on, the thruster level must drop below a lower threshold $l_{\text{off}}$ to turn off again. The benefit of this logic is that it provides a good balance between fuel efficiency and pointing accuracy. +If $l$ is larger than a threshold $l_{\text{on}}$ then the thruster control time is set to $t_{i} = t_{\text{min}}$. Once on, the thruster level must drop below a lower threshold $l_{\text{off}}$ to turn off again. The benefit of this logic is that it provides a good balance between fuel efficiency and pointing accuracy. \subsection{Module Input and Output Messages} As illustrated in Figure~\ref{fig:moduleImg}, the module reads in two messages. One message contains the thruster configuration message from which the maximum thrust force value for each thruster is extracted and stored in the module. This message is only read in on {\tt reset()}. -The second message reads in an array of requested thruster force values with every {\tt Update()} function call. These force values $F_{i}$ can be positive if on-pulsing is requested, or negative if off-pulsing is required. On-pulsing is used to achieve an attitude control torque onto the spacecraft by turning on a thruster. Off-pulsing assumes a thruster is nominally on, such as with doing an extended orbit correction maneuver, and the attitude control is achieved by doing periodic off-pulsing. +The second message reads in an array of requested thruster force values with every {\tt Update()} function call. These force values $F_{i}$ can be positive if on-pulsing is requested, or negative if off-pulsing is required. On-pulsing is used to achieve an attitude control torque onto the spacecraft by turning on a thruster. Off-pulsing assumes a thruster is nominally on, such as with doing an extended orbit correction maneuver, and the attitude control is achieved by doing periodic off-pulsing. -The output of the module is a message containing an array of thruster on-time requests. If these on-times are larger than the control period, then the thruster remains on only for the control period upon which the on-criteria is reevaluated. +The output of the module is a message containing an array of thruster on-time requests. If these on-times are larger than the control period, then the thruster remains on only for the control period upon which the on-criteria is reevaluated. \subsection{reset() Functionality} \begin{itemize} - \item The control period is dynamically evaluated in the module by comparing the current time with the prior call time. In {\tt reset()} the {\tt prevCallTime} variable is reset to 0. + \item The control period is dynamically evaluated in the module by comparing the current time with the prior call time. In {\tt reset()} the {\tt prevCallTime} variable is reset to 0. \item The thruster configuration message is read in and the number of thrusters is stored in the module variable {\tt numThrusters}. The maximum force per thruster is stored in {\tt maxThrust}. \item The last thruster state variable {\tt lastThrustState} is set to off (i.e. false) \end{itemize} @@ -29,17 +29,15 @@ \subsection{Update() Functionality} The goal of the {\tt update()} method is to read in the current attitude control thruster force message and map these into a thruster on-time output message using the Schmitt trigger logic.\cite{Alcorn:2016rz} The module sets a desired minimum thruster on time $t_{\text{min}}$. This is typically not set to the lower limit of the thruster resolution, but rather to a value that provides a good duty cycle and avoids excessive short on-off switching. The cost naturally is a reduced pointing capability. Let the duty cycle $l$ be defined as the ratio between the commanded on time $t_{i}$ and $t_{\text{min}}$. The thruster is turned on for a period $t_{i} = t_{\text{min}}$ if $l$ is larger than $l_{\text{on}}$. The thruster then remains on until $l$ drops below a lower threshold $l_{\text{off}}$. The benefit of this method is that it provides a good balance between fuel usage and pointing accuracy.\cite{Alcorn:2016rz} -If the {\tt update()} method is called for the first time after reset, then there is no knowledge of the control period $\Delta t$. In this case the thruster on-time values are set either to 0 (on-pulsing case) or 2 seconds (off-pulsing case). After writing out this message the module is exited. This logic is essence turns off the thruster-based attitude control for one control period. +If the {\tt update()} method is called for the first time after reset, then there is no knowledge of the control period $\Delta t$. In this case the thruster on-time values are set either to 0 (on-pulsing case) or 2 seconds (off-pulsing case). After writing out this message the module is exited. This logic is essence turns off the thruster-based attitude control for one control period. -If this is a repeated call of the {\tt update()} method then the control period $\Delta t$ is evaluated by differencing the current time with the prior call time. Next a loop goes over each installed thruster to map the requested force $F_{i}$ into an on-time $t_{i}$. The following logic is used. +If this is a repeated call of the {\tt update()} method then the control period $\Delta t$ is evaluated by differencing the current time with the prior call time. Next a loop goes over each installed thruster to map the requested force $F_{i}$ into an on-time $t_{i}$. The following logic is used. \begin{itemize} - \item If off-pulsing is used then $F_{i}\le 0$ and we set $$F_{i} += F_{\text{max}}$$ to a reduced thrust to achieve the negative $F_{i}$ force. - \item Next, if $F_{i} < 0$ then it set to be equal to zero. This can occur if an off-pulsing request is larger than the maximum thruster force magnitude $F_{\text{max}}$. - \item The nominal thruster on-time is computed using $$t_{i} = \dfrac{F_{i}}{F_{\text{max}}} \Delta t$$ + \item If off-pulsing is used then $F_{i}\le 0$ and we set $$F_{i} += F_{\text{max}}$$ to a reduced thrust to achieve the negative $F_{i}$ force. + \item Next, if $F_{i} < 0$ then it set to be equal to zero. This can occur if an off-pulsing request is larger than the maximum thruster force magnitude $F_{\text{max}}$. + \item The nominal thruster on-time is computed using $$t_{i} = \dfrac{F_{i}}{F_{\text{max}}} \Delta t$$ \item If $\Delta t > t_{i} \ge t_{\text{min}}$ the thruster on time is set to $t_{i}$ \item If $t_{i} > \Delta t$ then the thruster is saturated. In this case the on-time is set to $t_{i} = 1.1\Delta t$ such that the thruster remains on through the control period. \item The Schmitt trigger logic occurs if $t_{i} < t_{\text{min}}$. If $l>l_{\text{on}}$ then $t_{i} = t_{\text{min}}$. This command of $t_{i} = t_{\text{min}}$ remains on as long as $l > l_{\text{off}}$. If $lmeasurementModel(); - + /*! - Compute the value for the yBar parameter (note that this is equation 23 in the time update section of the reference document*/ Eigen::VectorXd yBar; @@ -265,7 +265,7 @@ void PositionODuKF::measurementUpdate() { yBar += this->wM(i) * this->yMeas.col(i); } - + /*! - Populate the matrix that we perform the QR decomposition on in the measurement update section of the code. This is based on the difference between the yBar parameter and the calculated measurement models. Equation 24. */ diff --git a/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.h b/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.h index 7683962c2..359d2b601 100644 --- a/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.h +++ b/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.h @@ -1,12 +1,12 @@ /* ISC License - + Copyright (c) 2024, 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 @@ -14,7 +14,7 @@ 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. - + */ diff --git a/src/fswAlgorithms/opticalNavigation/visualOdometry/_UnitTest/test_visualOdometry.py b/src/fswAlgorithms/opticalNavigation/visualOdometry/_UnitTest/test_visualOdometry.py index a4c463acc..53827063f 100644 --- a/src/fswAlgorithms/opticalNavigation/visualOdometry/_UnitTest/test_visualOdometry.py +++ b/src/fswAlgorithms/opticalNavigation/visualOdometry/_UnitTest/test_visualOdometry.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2023, Laboratory for Atmospheric Space Physics, University of Colorado 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 @@ -14,7 +14,7 @@ # 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. -# +# # import copy import itertools diff --git a/src/fswAlgorithms/orbitControl/lambertPlanner/_UnitTest/test_lambertPlanner.py b/src/fswAlgorithms/orbitControl/lambertPlanner/_UnitTest/test_lambertPlanner.py index 5314d1039..6c94556b4 100644 --- a/src/fswAlgorithms/orbitControl/lambertPlanner/_UnitTest/test_lambertPlanner.py +++ b/src/fswAlgorithms/orbitControl/lambertPlanner/_UnitTest/test_lambertPlanner.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,7 +14,7 @@ # 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. -# +# # import copy import itertools diff --git a/src/fswAlgorithms/orbitControl/lambertSecondDV/_UnitTest/test_lambertSecondDV.py b/src/fswAlgorithms/orbitControl/lambertSecondDV/_UnitTest/test_lambertSecondDV.py index 57c0ea134..7d52aa39d 100644 --- a/src/fswAlgorithms/orbitControl/lambertSecondDV/_UnitTest/test_lambertSecondDV.py +++ b/src/fswAlgorithms/orbitControl/lambertSecondDV/_UnitTest/test_lambertSecondDV.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2023, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,7 +14,7 @@ # 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. -# +# # import itertools diff --git a/src/fswAlgorithms/orbitControl/lambertSolver/_UnitTest/test_lambertSolver.py b/src/fswAlgorithms/orbitControl/lambertSolver/_UnitTest/test_lambertSolver.py index 3e1188c14..b99e5f135 100644 --- a/src/fswAlgorithms/orbitControl/lambertSolver/_UnitTest/test_lambertSolver.py +++ b/src/fswAlgorithms/orbitControl/lambertSolver/_UnitTest/test_lambertSolver.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,7 +14,7 @@ # 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. -# +# # import copy import itertools diff --git a/src/fswAlgorithms/orbitControl/lambertSurfaceRelativeVelocity/_UnitTest/test_lambertSurfaceRelativeVelocity.py b/src/fswAlgorithms/orbitControl/lambertSurfaceRelativeVelocity/_UnitTest/test_lambertSurfaceRelativeVelocity.py index ebbb8f1de..7321a9b2c 100644 --- a/src/fswAlgorithms/orbitControl/lambertSurfaceRelativeVelocity/_UnitTest/test_lambertSurfaceRelativeVelocity.py +++ b/src/fswAlgorithms/orbitControl/lambertSurfaceRelativeVelocity/_UnitTest/test_lambertSurfaceRelativeVelocity.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,7 +14,7 @@ # 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. -# +# # import itertools diff --git a/src/fswAlgorithms/pointCloudProcessing/cameraTriangulation/_UnitTest/test_cameraTriangulation.py b/src/fswAlgorithms/pointCloudProcessing/cameraTriangulation/_UnitTest/test_cameraTriangulation.py index 79aa93609..18798c978 100644 --- a/src/fswAlgorithms/pointCloudProcessing/cameraTriangulation/_UnitTest/test_cameraTriangulation.py +++ b/src/fswAlgorithms/pointCloudProcessing/cameraTriangulation/_UnitTest/test_cameraTriangulation.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2023, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,7 +14,7 @@ # 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. -# +# # import itertools diff --git a/src/fswAlgorithms/stateEstimation/thrustCMEstimation/_UnitTest/test_thrustCMEstimation.py b/src/fswAlgorithms/stateEstimation/thrustCMEstimation/_UnitTest/test_thrustCMEstimation.py index d506dd8f1..cb41833c8 100755 --- a/src/fswAlgorithms/stateEstimation/thrustCMEstimation/_UnitTest/test_thrustCMEstimation.py +++ b/src/fswAlgorithms/stateEstimation/thrustCMEstimation/_UnitTest/test_thrustCMEstimation.py @@ -152,7 +152,7 @@ def thrustCMEstimationTestFunction(show_plots, dT, accuracy): sigma = cmEstimateLog.covariance preFit = cmEstimateLog.preFitRes postFit = cmEstimateLog.postFitRes - + # check that post-fit residuals are smaller in magnitude that pre-fit residuals at each measurement for i in range(len(r_TB_B)): np.testing.assert_array_less(np.linalg.norm(postFit[i]), np.linalg.norm(preFit[i]) + accuracy, verbose=True) diff --git a/src/fswAlgorithms/stateEstimation/thrustCMEstimation/thrustCMEstimation.rst b/src/fswAlgorithms/stateEstimation/thrustCMEstimation/thrustCMEstimation.rst index 184e97970..cc779ce14 100644 --- a/src/fswAlgorithms/stateEstimation/thrustCMEstimation/thrustCMEstimation.rst +++ b/src/fswAlgorithms/stateEstimation/thrustCMEstimation/thrustCMEstimation.rst @@ -83,7 +83,7 @@ The required module configuration is:: cmEstimation.P0 = [0.0025, 0.0025, 0.0025] cmEstimation.R0 = [1e-9, 1e-9, 1e-9] unitTestSim.AddModelToTask(unitTaskName, cmEstimation) - + The module is configurable with the following parameters: .. list-table:: Module Parameters @@ -105,4 +105,3 @@ The module is configurable with the following parameters: * - ``R0`` - [0, 0, 0] - diagonal elements of the measurement noise covariance - diff --git a/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleDescription.tex b/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleDescription.tex index cfd1f478e..8c2c93320 100644 --- a/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleDescription.tex +++ b/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleDescription.tex @@ -9,7 +9,7 @@ \subsection{General Formulation} \subsection{reset() Functionality} -The reset function has a few critical behaviors. +The reset function has a few critical behaviors. \begin{itemize} \item The vector containing the net $\Delta \bm v$ is zero on reset. \item The prior time tag $t_{n-1}$ is zero to zero on default. @@ -19,10 +19,10 @@ \subsection{reset() Functionality} \subsection{Update() Functionality} -The update function reads in the latest accelerometer data input message and must process all the new measurements since the last update function call. +The update function reads in the latest accelerometer data input message and must process all the new measurements since the last update function call. \begin{itemize} \item The accelerometer input message is read in and sorted by the time tags. \item If the initialization flag is not true, then the integration is occurring for the first time. To avoid large $\Delta t$ evaluations because of an old prior time $t_{n-1}$, the input data is looped over from the end of the array (i.e. from the newest to oldest) to find the first data time tag $t_{i}$ which is newer then the prior data time tag $t_{n-1}$. Once found we set $t_{n-1} = t_{i}$, set the initialization flag to true and break the loop. As a result the first new data set is not included in the $\Delta\bm v$ evaluation. \item The next step is to loop over all data sets and see if $t_{i}>t_{n-1}$. If yes, the associate data set has not been processed and it is integrated using $$\leftexp{B}{\Delta\bm v} += \leftexp{B}{\bm a_{i}} \Delta t$$ where $\Delta t = t_{i} - t_{n-1}$. The prior time is set to the $t_{i}$ current data time and the loop is repeated. \item The final step before writing the output message is to zero all output message data and then set the {\tt timeTag} to the latest accelerometer measurement time tag, and copy over the $\Delta\bm v$ vector. -\end{itemize} \ No newline at end of file +\end{itemize} diff --git a/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleFunctions.tex b/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleFunctions.tex index 4e86d6cdd..579dfae6a 100644 --- a/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleFunctions.tex +++ b/src/fswAlgorithms/transDetermination/dvAccumulation/_Documentation/secModuleFunctions.tex @@ -8,4 +8,4 @@ \section{Module Functions} \end{itemize} \section{Module Assumptions and Limitations} -The module assumes all accelerometer vector measurements have their components taken with respect to the body frame $\cal B$. \ No newline at end of file +The module assumes all accelerometer vector measurements have their components taken with respect to the body frame $\cal B$. diff --git a/src/moduleTemplates/_doc.rst b/src/moduleTemplates/_doc.rst index d116e5d9a..3dacc0813 100644 --- a/src/moduleTemplates/_doc.rst +++ b/src/moduleTemplates/_doc.rst @@ -74,5 +74,3 @@ already checks if the input messages are connected (assuming they are all requir provides sample code the creates buffer variables for the input and output messages, reads in the input messages, and write to the output messages. The unit test already loads up the module, creates blank input message copies that are subscribed to the module, creates recorder modules for each output message, etc. - - diff --git a/src/simulation/deviceInterface/encoder/encoder.rst b/src/simulation/deviceInterface/encoder/encoder.rst index 483aeae8e..12a4c7920 100644 --- a/src/simulation/deviceInterface/encoder/encoder.rst +++ b/src/simulation/deviceInterface/encoder/encoder.rst @@ -35,7 +35,7 @@ for the first iteration the time step is set at 0, the wheel speeds will not be Discretization ~~~~~~~~~~~~~~ -Under normal operating conditions, the discretizer works by setting the wheel speed as a multiple of the resolution of the sensor. This resolution is calculated through the number of +Under normal operating conditions, the discretizer works by setting the wheel speed as a multiple of the resolution of the sensor. This resolution is calculated through the number of clicks per rotation that the sensor can handle. Let :math:`N` be the number of clicks measured during a time step: .. math:: diff --git a/src/simulation/deviceInterface/hingedBodyLinearProfiler/_UnitTest/test_hingedBodyLinearProfiler.py b/src/simulation/deviceInterface/hingedBodyLinearProfiler/_UnitTest/test_hingedBodyLinearProfiler.py index 7ecd63663..772fff574 100644 --- a/src/simulation/deviceInterface/hingedBodyLinearProfiler/_UnitTest/test_hingedBodyLinearProfiler.py +++ b/src/simulation/deviceInterface/hingedBodyLinearProfiler/_UnitTest/test_hingedBodyLinearProfiler.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2022, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# from math import pi @@ -48,9 +48,9 @@ def test_hingedBodyLinearProfiler(show_plots, startTime, endTime, startTheta, en endTheta (double): ending angle of deployment in radians **Description of Variables Being Tested** - + For a deployment from 0 to 1 degree, starting at 1 second and ending at 2 seconds into the simulation, checks that the angle and angle rates are as expected before, during, and after deployment. - + Before deployment, theta should be 0 and ``thetaDot`` 0. During deployment, ``thetaDot`` should be 1 degree per second, with theta varying linearly. After deployment, theta should be 1 degree and ``thetaDot`` 0. """ @@ -64,7 +64,7 @@ def hingedBodyLinearProfilerTestFunction(show_plots, startTime, endTime, startTh testMessages = [] unitTaskName = "unitTask" unitProcessName = "TestProcess" - + # accuracy to which double values compared accuracy = 1e-12 @@ -93,7 +93,7 @@ def hingedBodyLinearProfilerTestFunction(show_plots, startTime, endTime, startTh # pull module data and make sure it is correct trueTheta = np.array([0, 0, 0, pi/360, pi/180, pi/180, pi/180]); trueThetaDot = np.array([0, 0, pi/180, pi/180, pi/180, 0, 0]) - + testFailCount, testMessages = unitTestSupport.compareVector(trueTheta, dataLog.theta, accuracy, "theta", testFailCount, testMessages) testFailCount, testMessages = unitTestSupport.compareVector(trueThetaDot, dataLog.thetaDot, accuracy, "thetaDot", testFailCount, testMessages) @@ -107,5 +107,3 @@ def hingedBodyLinearProfilerTestFunction(show_plots, startTime, endTime, startTh if __name__ == "__main__": test_hingedBodyLinearProfiler(False, macros.sec2nano(1), macros.sec2nano(2), 0, pi/180) - - diff --git a/src/simulation/deviceInterface/hingedBodyLinearProfiler/hingedBodyLinearProfiler.rst b/src/simulation/deviceInterface/hingedBodyLinearProfiler/hingedBodyLinearProfiler.rst index 3d0f77683..cf35bb1f8 100644 --- a/src/simulation/deviceInterface/hingedBodyLinearProfiler/hingedBodyLinearProfiler.rst +++ b/src/simulation/deviceInterface/hingedBodyLinearProfiler/hingedBodyLinearProfiler.rst @@ -53,4 +53,3 @@ A sample setup is done using: testModule.endTime = macros.sec2nano(330) # [ns] continue deploying for 300 seconds testModule.startTheta = 0 # [rad] starting angle in radians testModule.endTheta = 10*pi/180 # [rad] ending angle is 10 degrees in the positive direction as defined by hinged rigid body frame - diff --git a/src/simulation/deviceInterface/motorVoltageInterface/motorVoltageInterface.h b/src/simulation/deviceInterface/motorVoltageInterface/motorVoltageInterface.h index 43d065a28..5b600b9f4 100644 --- a/src/simulation/deviceInterface/motorVoltageInterface/motorVoltageInterface.h +++ b/src/simulation/deviceInterface/motorVoltageInterface/motorVoltageInterface.h @@ -36,7 +36,7 @@ class MotorVoltageInterface: public SysModel { public: MotorVoltageInterface(); ~MotorVoltageInterface(); - + void computeMotorTorque(); void reset(uint64_t currentSimNanos); void updateState(uint64_t currentSimNanos); @@ -45,7 +45,7 @@ class MotorVoltageInterface: public SysModel { void setGains(Eigen::VectorXd gains); //!< -- Takes in an array of gains to set for rws and sets them, leaving blanks up to MAX_EFF_COUNT void setScaleFactors(Eigen::VectorXd scaleFactors); //!< -- Takes in an array of scale factors to set for rws and sets them, leaving blanks up to MAX_EFF_COUNT void setBiases(Eigen::VectorXd biases); //!< -- Takes in an array of biases to set for rws and sets them, leaving blanks up to MAX_EFF_COUNT - + public: ReadFunctor motorVoltageInMsg; //!< -- Message that contains motor voltage input states Message motorTorqueOutMsg;//!< -- Output Message for motor torques diff --git a/src/simulation/deviceInterface/prescribedLinearTranslation/_UnitTest/test_prescribedLinearTranslation.py b/src/simulation/deviceInterface/prescribedLinearTranslation/_UnitTest/test_prescribedLinearTranslation.py index 82da9e5de..10cdcd4ef 100644 --- a/src/simulation/deviceInterface/prescribedLinearTranslation/_UnitTest/test_prescribedLinearTranslation.py +++ b/src/simulation/deviceInterface/prescribedLinearTranslation/_UnitTest/test_prescribedLinearTranslation.py @@ -287,4 +287,3 @@ def test_prescribedLinearTranslation(show_plots, 0.01, # [m/s^2] transAccelMax 1e-8 # accuracy ) - \ No newline at end of file diff --git a/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst b/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst index a8dcdcede..3b2c40c9e 100644 --- a/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst +++ b/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst @@ -36,9 +36,9 @@ set to nonzero values, the smoothed bang-coast-bang profiler is selected. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages @@ -64,11 +64,11 @@ Detailed Module Description Non-Smoothed Bang-Bang Profiler ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The first option to profile the linear translation is a pure bang-bang acceleration profile. If the given reference +The first option to profile the linear translation is a pure bang-bang acceleration profile. If the given reference position is greater than the given initial position, the user-specified maximum acceleration value is applied positively to the first half of the translation and negatively to the second half of the translation. However, if the reference position is less than the initial position, the acceleration is instead applied -negatively during the first half of the translation and positively during the second half of the translation. As a +negatively during the first half of the translation and positively during the second half of the translation. As a result of this acceleration profile, the translational body's hub-relative velocity changes linearly with time and reaches a maximum in magnitude halfway through the translation. Note that the velocity is assumed to both start and end at zero in this module. The resulting translational position profile is parabolic in time. @@ -471,4 +471,3 @@ This section is to outline the steps needed to setup the prescribed linear trans #. Add the module to the task list:: unitTestSim.AddModelToTask(unitTaskName, prescribedLinearTrans) - diff --git a/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst b/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst index aab6a30d1..7a31bd76c 100644 --- a/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst +++ b/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst @@ -36,9 +36,9 @@ set to nonzero values, the smoothed bang-coast-bang profiler is selected. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what the message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/deviceInterface/singleAxisProfiler/_UnitTest/test_singleAxisProfiler.py b/src/simulation/deviceInterface/singleAxisProfiler/_UnitTest/test_singleAxisProfiler.py index 811034491..07bc88e7c 100644 --- a/src/simulation/deviceInterface/singleAxisProfiler/_UnitTest/test_singleAxisProfiler.py +++ b/src/simulation/deviceInterface/singleAxisProfiler/_UnitTest/test_singleAxisProfiler.py @@ -147,4 +147,3 @@ def test_singleAxisProfiler(show_plots, theta, thetaDot, thetaDDot, rotAxis_MAng -10.0 * macros.D2R, # [rad] rotAxis_MAngle 1e-12 # accuracy ) - \ No newline at end of file diff --git a/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst b/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst index d43033143..c5bf9a090 100644 --- a/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst +++ b/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst @@ -16,9 +16,9 @@ the spinning body rotation axis expressed as a unit vector in Mount frame compon Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what the message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/deviceInterface/tempMeasurement/_UnitTest/test_tempMeasurement.py b/src/simulation/deviceInterface/tempMeasurement/_UnitTest/test_tempMeasurement.py index 28c3c4d8e..e15784e01 100644 --- a/src/simulation/deviceInterface/tempMeasurement/_UnitTest/test_tempMeasurement.py +++ b/src/simulation/deviceInterface/tempMeasurement/_UnitTest/test_tempMeasurement.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2023, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# # # Thermal Sensor Faults Test @@ -44,11 +44,11 @@ @pytest.mark.parametrize( "tempFault", [ - "TEMP_FAULT_NOMINAL", - "TEMP_FAULT_STUCK_CURRENT", - "TEMP_FAULT_STUCK_VALUE", - "TEMP_FAULT_SPIKING", - "BIASED" + "TEMP_FAULT_NOMINAL", + "TEMP_FAULT_STUCK_CURRENT", + "TEMP_FAULT_STUCK_VALUE", + "TEMP_FAULT_SPIKING", + "BIASED" ]) # provide a unique test method name, starting with test_ def test_sensorThermalFault(tempFault): @@ -170,26 +170,26 @@ def run(tempFault): unitTestSim.InitializeSimulation() unitTestSim.ConfigureStopTime(simulationTime) unitTestSim.ExecuteSimulation() - nominals = np.array([ 0., -0.04439869, -0.08875756, -0.13307667, - -0.17735608, -0.22159584, -0.265796, -0.30995662, -0.35407775, - -0.39815946, -0.44220178, -0.48620479, -0.53016852, -0.57409304, - -0.6179784, -0.66182465, -0.70563184, -0.74940004, -0.79312929, - -0.83681965, -0.88047117, -0.9240839, -0.9676579, -1.01119321, - -1.0546899, -1.09814802, -1.14156761, -1.18494873, -1.22829144, - -1.27159578, -1.31486181, -1.35808958, -1.40127914, -1.44443055, - -1.48754385, -1.5306191, -1.57365634, -1.61665564, -1.65961704, - -1.7025406, -1.74542636, -1.78827437, -1.83108469, -1.87385737, - -1.91659246, -1.95929001, -2.00195007, -2.04457269, -2.08715792, - -2.12970582, -2.17221642, -2.21468979, -2.25712597, -2.29952502, - -2.34188697, -2.38421189, -2.42649982, -2.46875082, -2.51096492, - -2.55314219, -2.59528266, -2.6373864, -2.67945344, -2.72148384, - -2.76347765, -2.80543491, -2.84735568, -2.88924, -2.93108792, - -2.9728995 , -3.01467477, -3.05641378, -3.0981166, -3.13978325, - -3.1814138, -3.22300829, -3.26456677, -3.30608928, -3.34757587, - -3.38902659, -3.43044149, -3.47182062, -3.51316402, -3.55447174, - -3.59574383, -3.63698033, -3.67818129, -3.71934677, -3.76047679, - -3.80157142, -3.8426307, -3.88365467, -3.92464338, -3.96559689, - -4.00651522, -4.04739844, -4.08824658, -4.1290597, -4.16983783, + nominals = np.array([ 0., -0.04439869, -0.08875756, -0.13307667, + -0.17735608, -0.22159584, -0.265796, -0.30995662, -0.35407775, + -0.39815946, -0.44220178, -0.48620479, -0.53016852, -0.57409304, + -0.6179784, -0.66182465, -0.70563184, -0.74940004, -0.79312929, + -0.83681965, -0.88047117, -0.9240839, -0.9676579, -1.01119321, + -1.0546899, -1.09814802, -1.14156761, -1.18494873, -1.22829144, + -1.27159578, -1.31486181, -1.35808958, -1.40127914, -1.44443055, + -1.48754385, -1.5306191, -1.57365634, -1.61665564, -1.65961704, + -1.7025406, -1.74542636, -1.78827437, -1.83108469, -1.87385737, + -1.91659246, -1.95929001, -2.00195007, -2.04457269, -2.08715792, + -2.12970582, -2.17221642, -2.21468979, -2.25712597, -2.29952502, + -2.34188697, -2.38421189, -2.42649982, -2.46875082, -2.51096492, + -2.55314219, -2.59528266, -2.6373864, -2.67945344, -2.72148384, + -2.76347765, -2.80543491, -2.84735568, -2.88924, -2.93108792, + -2.9728995 , -3.01467477, -3.05641378, -3.0981166, -3.13978325, + -3.1814138, -3.22300829, -3.26456677, -3.30608928, -3.34757587, + -3.38902659, -3.43044149, -3.47182062, -3.51316402, -3.55447174, + -3.59574383, -3.63698033, -3.67818129, -3.71934677, -3.76047679, + -3.80157142, -3.8426307, -3.88365467, -3.92464338, -3.96559689, + -4.00651522, -4.04739844, -4.08824658, -4.1290597, -4.16983783, -4.21058103, -4.25128934]) testValue = 0 @@ -234,4 +234,4 @@ def run(tempFault): if __name__ == "__main__": - run("TEMP_FAULT_NOMINAL") \ No newline at end of file + run("TEMP_FAULT_NOMINAL") diff --git a/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.cpp b/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.cpp index 18f776fcb..57d234a38 100644 --- a/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.cpp +++ b/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.cpp @@ -82,12 +82,12 @@ void TempMeasurement::applySensorErrors() sensorError = this->senBias + sensorNoise; } this->sensedTemperature = this->trueTemperature + sensorError; - + // apply fault conditions if(this->faultState == TEMP_FAULT_STUCK_VALUE){ // stuck at specified value this->sensedTemperature = this->stuckValue; } else if (this->faultState == TEMP_FAULT_STUCK_CURRENT){ // stuck at last value before flag turned on - this->sensedTemperature = this->pastValue; + this->sensedTemperature = this->pastValue; } else if (this->faultState == TEMP_FAULT_SPIKING){ // spiking periodically with specified probability // have to make a new distribution every time because SWIG can't parse putting this in the H file....? std::uniform_real_distribution spikeProbabilityDistribution(0.0,1.0); @@ -96,7 +96,7 @@ void TempMeasurement::applySensorErrors() this->sensedTemperature = this->sensedTemperature*this->spikeAmount; } } - + this->pastValue = this->sensedTemperature; // update past value } @@ -122,4 +122,3 @@ void TempMeasurement::updateState(uint64_t currentSimNanos) // write to the output messages this->tempOutMsg.write(&tempOutMsgBuffer, this->moduleID, currentSimNanos); } - diff --git a/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.rst b/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.rst index 350e4e5e2..5049e7a10 100644 --- a/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.rst +++ b/src/simulation/deviceInterface/tempMeasurement/tempMeasurement.rst @@ -4,8 +4,8 @@ Models the addition of noise, bias, and faults to temperature measurements. Message Connection Descriptions ------------------------------- -The following table lists all module input and output messages. The module msg connection -is set by the user from python. The msg type contains a link to the message structure definition, +The following table lists all module input and output messages. The module msg connection +is set by the user from python. The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages @@ -30,7 +30,7 @@ bias, and three faults: - ``TEMP_FAULT_STUCK_VALUE`` is faulty behavior where the measurement sticks to a specific value - ``TEMP_FAULT_STUCK_CURRENT`` fixes the measurement to the value -- ``TEMP_FAULT_SPIKING`` is faulty behavior where the measurement spikes +- ``TEMP_FAULT_SPIKING`` is faulty behavior where the measurement spikes to a specified multiplier times the actual value, with a given probability - ``TEMP_FAULT_NOMINAL`` has no faulty behavior but may still have noise and bias @@ -90,7 +90,7 @@ A sample setup is done using: tempMeasurementModel.senBias = 1.0 # [C] bias amount tempMeasurementModel.senNoiseStd = 5.0 # [C] noise standard devation - tempMeasurementModel.walkBounds = 2.0 # + tempMeasurementModel.walkBounds = 2.0 # tempMeasurementModel.stuckValue = 10.0 # [C] if the sensor gets stuck, stuck at 10 degrees C tempMeasurementModel.spikeProbability = 0.3 # [-] 30% chance of spiking at each time step tempMeasurementModel.spikeAmount = 10.0 # [-] 10x the actual sensed value if the spike happens diff --git a/src/simulation/dynamics/DynOutput/orbElemConvert/_Documentation/secUserGuide.tex b/src/simulation/dynamics/DynOutput/orbElemConvert/_Documentation/secUserGuide.tex index 696a6bfd4..766ef6555 100644 --- a/src/simulation/dynamics/DynOutput/orbElemConvert/_Documentation/secUserGuide.tex +++ b/src/simulation/dynamics/DynOutput/orbElemConvert/_Documentation/secUserGuide.tex @@ -5,7 +5,7 @@ \section{User Guide} \item {\tt spiceStateInMsg}: spice state input message \item {\tt elemInMsg}: classical orbit elements input message \end{itemize} -Note that only one can be connected to. +Note that only one can be connected to. The three output messages are: \begin{itemize} @@ -28,4 +28,4 @@ \section{User Guide} Vallado, D. A., and McClain, W. D., \textit{Fundamentals of Astrodynamics and Applications, 4th ed}. Hawthorne, CA: Published by Microcosm Press, 2013. \bibitem{bib:2} Schaub, H., and Junkins, J. L., \textit{Analytical Mechanics of Space Systems, 3rd ed.}. Reston, VA: American Institute of Aeronautics and Astronautics. -\end{thebibliography} \ No newline at end of file +\end{thebibliography} diff --git a/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.h b/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.h index 2570b61f1..267a35b6a 100644 --- a/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.h +++ b/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.h @@ -49,7 +49,7 @@ class GravityGradientEffector: public SysModel, public DynamicEffector { public: - Message gravityGradientOutMsg; //!< output message containing the gravity gradient + Message gravityGradientOutMsg; //!< output message containing the gravity gradient StateData *hubSigma; //!< Hub/Inertial attitude represented by MRP StateData *r_BN_N; //!< Hub/Inertial position vector in inertial frame components Eigen::MatrixXd *ISCPntB_B; //!< [kg m^2] current spacecraft inertia about point B, B-frame components diff --git a/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.rst b/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.rst index 834c7d96b..2f5a7383f 100644 --- a/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.rst +++ b/src/simulation/dynamics/GravityGradientEffector/GravityGradientEffector.rst @@ -97,4 +97,3 @@ Module Output Message Name ^^^^^^^^^^^^^^^^^^^^^^^^^^ The effector write an output message with the current gravity gradient torque information at each ``update`` cycle. The output message is ``gravityGradientOutMsg``. - diff --git a/src/simulation/dynamics/HingedRigidBodies/_UnitTest/test_hingedRigidBodyStateEffector.py b/src/simulation/dynamics/HingedRigidBodies/_UnitTest/test_hingedRigidBodyStateEffector.py index a64cc7ef4..f3319c4a8 100644 --- a/src/simulation/dynamics/HingedRigidBodies/_UnitTest/test_hingedRigidBodyStateEffector.py +++ b/src/simulation/dynamics/HingedRigidBodies/_UnitTest/test_hingedRigidBodyStateEffector.py @@ -296,18 +296,18 @@ def hingedRigidBodyNoGravity(show_plots): # --fulltrace command line option is specified. __tracebackhide__ = True - testFailCount = 0 # zero unit test result counter + testFailCount = 0 # zero unit test result counter testMessages = [] # create empty list to store test log messages - + scObject = spacecraftSystem.SpacecraftSystem() scObject.modelTag = "spacecraftBody" - + unitTaskName = "unitTask" # arbitrary name (don't change) unitProcessName = "TestProcess" # arbitrary name (don't change) - + # Create a sim module as an empty container unitTestSim = SimulationBaseClass.SimBaseClass() - + # Create test thread testProcessRate = macros.sec2nano(0.001) # update process rate update time testProc = unitTestSim.CreateNewProcess(unitProcessName) @@ -360,7 +360,7 @@ def hingedRigidBodyNoGravity(show_plots): dataLog = scObject.primaryCentralSpacecraft.scStateOutMsg.recorder() unitTestSim.AddModelToTask(unitTaskName, dataLog) - + scLog = pythonVariableLogger.PythonVariableLogger({ "totOrbEnergy": lambda _: scObject.primaryCentralSpacecraft.totOrbEnergy, "totOrbAngMomPntN_N": lambda _: scObject.primaryCentralSpacecraft.totOrbAngMomPntN_N, @@ -878,7 +878,7 @@ def hingedRigidBodyThetaSS(show_plots): PlotTitle = "BOE Calculation for Steady State Theta 2 Deflection vs Simulation" format = r"width=0.8\textwidth" unitTestSupport.writeFigureLaTeX(PlotName, PlotTitle, plt, format, path) - + if show_plots: plt.show() plt.close("all") @@ -1878,4 +1878,4 @@ class boxAndWingParameters: # test_hingedRigidBodyThetaSS(True) # test_hingedRigidBodyFrequencyAmp(True) # test_hingedRigidBodyMotorTorque(True, True) - hingedRigidBodyLagrangVsBasilisk(True) \ No newline at end of file + hingedRigidBodyLagrangVsBasilisk(True) diff --git a/src/simulation/dynamics/LinearSpringMassDamper/_UnitTest/test_linearSpringMassDamper.py b/src/simulation/dynamics/LinearSpringMassDamper/_UnitTest/test_linearSpringMassDamper.py index b604f8d7f..ed622f02d 100644 --- a/src/simulation/dynamics/LinearSpringMassDamper/_UnitTest/test_linearSpringMassDamper.py +++ b/src/simulation/dynamics/LinearSpringMassDamper/_UnitTest/test_linearSpringMassDamper.py @@ -63,16 +63,16 @@ def fuelSloshTest(show_plots,useFlag,testCase): testFailCount = 0 # zero unit test result counter testMessages = [] # create empty list to store test log messages - + scObject = spacecraft.Spacecraft() scObject.modelTag = "spacecraftBody" - + unitTaskName = "unitTask" # arbitrary name (don't change) unitProcessName = "TestProcess" # arbitrary name (don't change) - + # Create a sim module as an empty container unitTestSim = SimulationBaseClass.SimBaseClass() - + # Create test thread testProcessRate = macros.sec2nano(0.001) # update process rate update time testProc = unitTestSim.CreateNewProcess(unitProcessName) @@ -162,7 +162,7 @@ def fuelSloshTest(show_plots,useFlag,testCase): unitTestSim.particle1.c = 15.0 unitTestSim.particle2.c = 17.0 unitTestSim.particle3.c = 11.0 - + # Add test module to runtime call list unitTestSim.AddModelToTask(unitTaskName, scObject) diff --git a/src/simulation/dynamics/MtbEffector/MtbEffector.h b/src/simulation/dynamics/MtbEffector/MtbEffector.h index d12a3b9f5..2259f0d69 100644 --- a/src/simulation/dynamics/MtbEffector/MtbEffector.h +++ b/src/simulation/dynamics/MtbEffector/MtbEffector.h @@ -32,11 +32,11 @@ #include "architecture/utilities/bskLogging.h" #include "architecture/messaging/messaging.h" - + /*! @brief This module converts magnetic torque bar dipoles to body torques. */ class MtbEffector: public SysModel, public DynamicEffector { - + public: MtbEffector(); ~MtbEffector(); @@ -45,7 +45,7 @@ class MtbEffector: public SysModel, public DynamicEffector { void linkInStates(DynParamManager& states); void computeForceTorque(double integTime, double timeStep); void WriteOutputMessages(uint64_t CurrentClock); - + public: Message mtbOutMsg; //!< output message containing net torque produced by the torque bars in Body components StateData *hubSigma; //!< Hub/Inertial attitude represented by MRP @@ -53,7 +53,7 @@ class MtbEffector: public SysModel, public DynamicEffector { ReadFunctor magInMsg; //!< input msg for magnetic field data in inertial frame N ReadFunctor mtbParamsInMsg; //!< input msg for layout of magnetic torque bars BSKLogger bskLogger; //!< -- BSK Logging - + private: MTBCmdMsgPayload mtbCmdInMsgBuffer; //!< msg buffer or commanded mtb dipole array in the magnetic torque bar frame T MagneticFieldMsgPayload magInMsgBuffer; //!< msg buffer for magnetic field data in inertial frame N diff --git a/src/simulation/dynamics/MtbEffector/_UnitTest/test_MtbEffector.py b/src/simulation/dynamics/MtbEffector/_UnitTest/test_MtbEffector.py index 97a3ea04d..74c21d778 100644 --- a/src/simulation/dynamics/MtbEffector/_UnitTest/test_MtbEffector.py +++ b/src/simulation/dynamics/MtbEffector/_UnitTest/test_MtbEffector.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import os @@ -37,7 +37,7 @@ def truthMagneticTorque(bField_N, sigmaBN, mtbCmds, GtMatrix, numMTB, maxDipole): - + temp = np.asarray(GtMatrix[0:3*numMTB]) GtMatrix = np.reshape(temp, (3, numMTB)) bField_N = np.asarray(bField_N) @@ -74,7 +74,7 @@ def test_MtbEffector(show_plots, accuracy, maxDipole): **Description of Variables Being Tested** - Here discuss what variables and states are being checked. + Here discuss what variables and states are being checked. """ [testResults, testMessage] = MtbEffectorTestFunction(show_plots, accuracy, maxDipole) assert testResults < 1, testMessage @@ -84,7 +84,7 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): """Call this routine directly to run the unit test.""" testFailCount = 0 # zero unit test result counter testMessages = [] # create empty array to store test log messages - + # create simulation variable names simTaskName = "simTask" simProcessName = "simProcess" @@ -108,8 +108,8 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): earth = gravFactory.createEarth() earth.isCentralBody = True # ensure this is the central gravitational body mu = earth.mu - - + + # initialize spacecraft object and set properties scObject = spacecraft.Spacecraft() scObject.modelTag = "bskTestSat" @@ -120,7 +120,7 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): scObject.hub.mHub = 10.0 # kg - spacecraft mass (arbitrary) scObject.hub.r_BcB_B = [[0.0], [0.0], [0.0]] # m - position vector of body-fixed point B relative to CM scObject.hub.IHubPntBc_B = unitTestSupport.np2EigenMatrix3d(I) - + oe = orbitalMotion.ClassicElements() oe.a = 6778.14 * 1000. # meters oe.e = 0.0 @@ -137,8 +137,8 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): # add spacecraft object scSim.AddModelToTask(simTaskName, scObject) scObject.gravField.gravBodies = spacecraft.GravBodyVector(list(gravFactory.gravBodies.values())) - - + + # add magnetic field module magModule = magneticFieldWMM.MagneticFieldWMM() magModule.modelTag = "WMM" @@ -147,15 +147,15 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): magModule.epochInMsg.subscribeTo(epochMsg) magModule.addSpacecraftToModel(scObject.scStateOutMsg) # this command can be repeated if multiple scSim.AddModelToTask(simTaskName, magModule) - - + + # add magnetic torque bar effector mtbEff = MtbEffector.MtbEffector() mtbEff.modelTag = "MtbEff" scObject.addDynamicEffector(mtbEff) scSim.AddModelToTask(simTaskName, mtbEff) - - + + # mtbConfigData message mtbConfigParams = messaging.MTBArrayConfigMsgPayload() mtbConfigParams.numMTB = 3 @@ -167,30 +167,30 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): ] mtbConfigParams.maxMtbDipoles = [maxDipole]*4 mtbParamsInMsg = messaging.MTBArrayConfigMsg().write(mtbConfigParams) - - + + # MTBCmdMsgPayload, mtbCmdInMsg mtbCmdInMsgContainer = messaging.MTBCmdMsgPayload() mtbCmdInMsgContainer.mtbDipoleCmds = [0.2, 0.2, 0.2] mtbCmdInMsg = messaging.MTBCmdMsg().write(mtbCmdInMsgContainer) - - # subscribe to mesaages + + # subscribe to mesaages mtbEff.mtbCmdInMsg.subscribeTo(mtbCmdInMsg) mtbEff.mtbParamsInMsg.subscribeTo(mtbParamsInMsg) mtbEff.magInMsg.subscribeTo(magModule.envOutMsgs[0]) - - + + # Setup data logging before the simulation is initialized numDataPoints = 3600 samplingTime = unitTestSupport.samplingTime(simulationTime, simulationTimeStep, numDataPoints) dataLog = scObject.scStateOutMsg.recorder(samplingTime) dataLogMag = magModule.envOutMsgs[0].recorder(samplingTime) dataLogMTB = mtbEff.mtbOutMsg.recorder(samplingTime) - + scSim.AddModelToTask(simTaskName, dataLogMTB) scSim.AddModelToTask(simTaskName, dataLogMag) scSim.AddModelToTask(simTaskName, dataLog) - + # initialize Simulation scSim.InitializeSimulation() @@ -204,7 +204,7 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): mtbData = dataLogMTB.mtbNetTorque_B dataMagField = dataLogMag.magField_N np.set_printoptions(precision=16) - + # plot net mtb torque if show_plots: plt.close("all") # clears out plots from earlier test runs @@ -248,13 +248,13 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): mtbConfigParams.numMTB, maxDipole ) - + testFailCount, testMessages = unitTestSupport.compareVector(mtbTauV, mtbTauTruth, accuracy, "mtbTorque_B", testFailCount, testMessages) - + if testFailCount == 0: print("PASSED: Mtb Effector") else: @@ -267,5 +267,3 @@ def MtbEffectorTestFunction(show_plots, accuracy, maxDipole): 1e-12, 0.1 ) - - diff --git a/src/simulation/dynamics/NHingedRigidBodies/nHingedRigidBodyStateEffector.cpp b/src/simulation/dynamics/NHingedRigidBodies/nHingedRigidBodyStateEffector.cpp index 23b15dbf4..be0ac2a2c 100755 --- a/src/simulation/dynamics/NHingedRigidBodies/nHingedRigidBodyStateEffector.cpp +++ b/src/simulation/dynamics/NHingedRigidBodies/nHingedRigidBodyStateEffector.cpp @@ -35,7 +35,7 @@ NHingedRigidBodyStateEffector::NHingedRigidBodyStateEffector() this->nameOfThetaState ="nHingedRigidBody" + std::to_string(this->effectorID) + "Theta"; this->nameOfThetaDotState = "nHingedRigidBody" + std::to_string(this->effectorID) + "ThetaDot"; this->effectorID++; - + return; } @@ -80,7 +80,7 @@ void NHingedRigidBodyStateEffector::linkInStates(DynParamManager& statesIn) /*! This method allows the HRB state effector to register its states: theta and thetaDot with the dyn param manager */ void NHingedRigidBodyStateEffector::registerStates(DynParamManager& states) { - + // - Register the states associated with hinged rigid bodies - theta and thetaDot Eigen::MatrixXd thetaInitMatrix(this->PanelVec.size(),1); Eigen::MatrixXd thetaDotInitMatrix(this->PanelVec.size(),1); @@ -122,7 +122,7 @@ void NHingedRigidBodyStateEffector::updateEffectorMassProps(double integTime) sum_rH.setZero(); Eigen::Vector3d sum_rPrimeH; sum_rPrimeH.setZero(); - + std::vector::iterator PanelIt; int it = 0; for(PanelIt=this->PanelVec.begin(); PanelIt!=this->PanelVec.end(); PanelIt++){ @@ -138,61 +138,61 @@ void NHingedRigidBodyStateEffector::updateEffectorMassProps(double integTime) PanelIt->sHat1_B = PanelIt->dcm_SB.row(0); PanelIt->sHat2_B = PanelIt->dcm_SB.row(1); PanelIt->sHat3_B = PanelIt->dcm_SB.row(2); - + PanelIt->r_SB_B = this->r_HB_B - PanelIt->d*PanelIt->sHat1_B + sum_rH; sum_rH += -2*PanelIt->d*PanelIt->sHat1_B; // - Define rTilde_SB_B PanelIt->rTilde_SB_B = eigenTilde(PanelIt->r_SB_B); - + // - Find rPrime_SB_B sum_ThetaDot += PanelIt->thetaDot; PanelIt->rPrime_SB_B = PanelIt->d*(sum_ThetaDot*PanelIt->sHat3_B + sum_rPrimeH); sum_rPrimeH += 2*PanelIt->sHat3_B*sum_ThetaDot; - + PanelIt->omega_SB_B = sum_ThetaDot*PanelIt->sHat2_B; - + // - Next find the body time derivative of the inertia about point B // - Define tilde matrix of rPrime_SB_B PanelIt->rPrimeTilde_SB_B = eigenTilde(PanelIt->rPrime_SB_B); - + // - Find body time derivative of IPntS_B PanelIt->ISPrimePntS_B = sum_ThetaDot*(PanelIt->IPntS_S(2,2) - PanelIt->IPntS_S(0,0)) *(PanelIt->sHat1_B*PanelIt->sHat3_B.transpose() + PanelIt->sHat3_B*PanelIt->sHat1_B.transpose()); - + // - Mass summation sum_mass += PanelIt->mass; - + // - Inertia of the panels summation term sum_PanelInertia += PanelIt->dcm_SB.transpose()*PanelIt->IPntS_S*PanelIt->dcm_SB + PanelIt->mass*PanelIt->rTilde_SB_B*PanelIt->rTilde_SB_B.transpose(); - + // - COM position summation terms sum_COM += PanelIt->mass*PanelIt->r_SB_B; - + sum_COMprime += PanelIt->mass*PanelIt->rPrime_SB_B; - + // - Inertia Prime of the effector summation terms sum_EffInertia += PanelIt->ISPrimePntS_B - PanelIt->mass*(PanelIt->rPrimeTilde_SB_B*PanelIt->rTilde_SB_B + PanelIt->rTilde_SB_B*PanelIt->rPrimeTilde_SB_B); - + it += 1; } - + // - update effector mass properties this->effProps.mEff = sum_mass; - + // - update effector COM location this->effProps.rEff_CB_B = 1.0/this->effProps.mEff*sum_COM; - + this->effProps.rEffPrime_CB_B = 1.0/this->effProps.mEff*sum_COMprime; - + // - Find the inertia of the hinged rigid body about point B this->effProps.IEffPntB_B = sum_PanelInertia; - + // - Find body time derivative of IPntB_B this->effProps.IEffPrimePntB_B = sum_EffInertia; - + return; } @@ -205,7 +205,7 @@ double NHingedRigidBodyStateEffector::HeaviFunc(double cond) return ans; } -/*! This method allows the HRB state effector to give its contributions to the matrices needed for the back-sub +/*! This method allows the HRB state effector to give its contributions to the matrices needed for the back-sub method */ void NHingedRigidBodyStateEffector::updateContributions(double integTime, BackSubMatrices & backSubContr, Eigen::Vector3d sigma_BN, Eigen::Vector3d omega_BN_B, Eigen::Vector3d g_N) { @@ -364,7 +364,7 @@ void NHingedRigidBodyStateEffector::updateContributions(double integTime, BackSu // - Start defining them good old contributions - start with translation // - For documentation on contributions see Allard, Diaz, Schaub flex/slosh paper - + // - translational contributions backSubContr.matrixA.setZero(); backSubContr.matrixB.setZero(); @@ -382,7 +382,7 @@ void NHingedRigidBodyStateEffector::updateContributions(double integTime, BackSu sumTerm1 += (2*((int) this->PanelVec.size() - k)+1)*PanelIt2->mass*PanelIt2->d*PanelIt2->sHat3_B; std::advance(PanelIt2, 1); } - + sumTerm2 = pow(sumThetaDot,2)*(2*((int) this->PanelVec.size() - j)+1)*PanelIt->mass*PanelIt->d*PanelIt->sHat1_B; backSubContr.matrixA += sumTerm1*this->matrixEDHRB.row(j-1)*this->matrixFDHRB; backSubContr.matrixB += sumTerm1*this->matrixEDHRB.row(j-1)*this->matrixGDHRB; @@ -391,10 +391,10 @@ void NHingedRigidBodyStateEffector::updateContributions(double integTime, BackSu } Eigen::Vector3d aTheta; Eigen::Vector3d bTheta; - + aTheta = this->matrixEDHRB.row(0)*this->matrixFDHRB; bTheta = this->matrixEDHRB.row(0)*this->matrixGDHRB; - + // - Rotational contributions backSubContr.matrixC.setZero(); backSubContr.matrixD.setZero(); @@ -440,7 +440,7 @@ void NHingedRigidBodyStateEffector::updateContributions(double integTime, BackSu j += 1; } - + return; } @@ -474,7 +474,7 @@ void NHingedRigidBodyStateEffector::computeDerivatives(double integTime, Eigen:: this->thetaState->setDerivative(this->thetaDotState->getState()); // - Second, a little more involved this->thetaDotState->setDerivative(thetaDDot); - + return; } @@ -501,7 +501,7 @@ void NHingedRigidBodyStateEffector::updateEnergyMomContributions(double integTim rotEnergyContr_Sum += 0.5*omega_SN_B.dot(IPntS_B*omega_SN_B) + 1.0/2.0*PanelIt->mass*rDot_SB_B.dot(rDot_SB_B) + 1.0/2.0*PanelIt->k*(PanelIt->theta-PanelIt->theta_0)*(PanelIt->theta-PanelIt->theta_0); } - + // - Find rotational angular momentum contribution from hub rotAngMomPntCContr_B = rotAngMomPntCContr_B_Sum; diff --git a/src/simulation/dynamics/RadiationPressure/radiationPressure.h b/src/simulation/dynamics/RadiationPressure/radiationPressure.h index 184430ba4..d190fbecf 100755 --- a/src/simulation/dynamics/RadiationPressure/radiationPressure.h +++ b/src/simulation/dynamics/RadiationPressure/radiationPressure.h @@ -60,7 +60,7 @@ class RadiationPressure: public SysModel, public DynamicEffector{ void addForceLookupBEntry(Eigen::Vector3d vec); void addTorqueLookupBEntry(Eigen::Vector3d vec); void addSHatLookupBEntry(Eigen::Vector3d vec); - + private: void computeCannonballModel(Eigen::Vector3d rSunB_B); void computeLookupModel(Eigen::Vector3d rSunB_B); diff --git a/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.h b/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.h index 4ff0cf5fb..e8bc72766 100644 --- a/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.h +++ b/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.h @@ -33,7 +33,7 @@ #include "architecture/utilities/avsEigenSupport.h" /** Container for gravitational body data - * + * * This class is designed to hold all of the information for a gravity * body. The nominal use-case has it initialized at the python level and * attached to dynamics using the AddGravityBody method. @@ -67,13 +67,13 @@ class GravBodyData void loadEphemeris(); /** Creates the following properies in the given statesIn object. - * + * * - [planetName].r_PN_N * - [planetName].v_PN_N * - [planetName].mu * - [planetName].J20002Pfix * - [planetName].J20002Pfix_dot - * + * * vr_PN_N`, `v_PN_N`, and `mu` are initialized to zero, while `J20002Pfix` and `J20002Pfix_dot` * are initialized to the values stored in `this->localPlanet`. This usually means that * `J20002Pfix` is initialized to the identity matrix and `J20002Pfix_dot` to zero. @@ -127,7 +127,7 @@ class GravityEffector : public SysModel void registerProperties(DynParamManager &statesIn); /** Calculate gravitational acceleration of s/c wrt inertial (no central body) or wrt central body - * + * * @param r_cF_N is position of center of mass of s/c wrt frame * @param rDot_cF_N is the derivative of above */ @@ -145,8 +145,8 @@ class GravityEffector : public SysModel /** Adds a `GravBodyData` associated with this effector */ void addGravBody(std::shared_ptr gravBody); - /** Called to modify property names to prepend them by the string stored in nameOfSpacecraftAttachedTo - * + /** Called to modify property names to prepend them by the string stored in nameOfSpacecraftAttachedTo + * * This can be used to make property names unique between different `GravityEffector` in a simulation * with multiple dynamic objects. */ diff --git a/src/simulation/dynamics/dualHingedRigidBodies/_UnitTest/test_dualhingedRigidBodyStateEffector.py b/src/simulation/dynamics/dualHingedRigidBodies/_UnitTest/test_dualhingedRigidBodyStateEffector.py index 9bf44cd74..590746fc6 100644 --- a/src/simulation/dynamics/dualHingedRigidBodies/_UnitTest/test_dualhingedRigidBodyStateEffector.py +++ b/src/simulation/dynamics/dualHingedRigidBodies/_UnitTest/test_dualhingedRigidBodyStateEffector.py @@ -60,16 +60,16 @@ def dualHingedRigidBodyTest(show_plots, useFlag, testCase): testFailCount = 0 # zero unit test result counter testMessages = [] # create empty list to store test log messages - + scObject = spacecraft.Spacecraft() scObject.modelTag = "spacecraftBody" - + unitTaskName = "unitTask" # arbitrary name (don't change) unitProcessName = "TestProcess" # arbitrary name (don't change) - + # Create a sim module as an empty container unitTestSim = SimulationBaseClass.SimBaseClass() - + # Create test thread testProcessRate = macros.sec2nano(0.0001) # update process rate update time testProc = unitTestSim.CreateNewProcess(unitProcessName) diff --git a/src/simulation/dynamics/dualHingedRigidBodies/dualHingedRigidBodyStateEffector.h b/src/simulation/dynamics/dualHingedRigidBodies/dualHingedRigidBodyStateEffector.h index 5a505fbb8..113f06e66 100755 --- a/src/simulation/dynamics/dualHingedRigidBodies/dualHingedRigidBodyStateEffector.h +++ b/src/simulation/dynamics/dualHingedRigidBodies/dualHingedRigidBodyStateEffector.h @@ -137,7 +137,7 @@ class DualHingedRigidBodyStateEffector : public StateEffector, public SysModel { Eigen::MatrixXd *inertialPositionProperty; //!< [m] r_N inertial position relative to system spice zeroBase/refBase Eigen::MatrixXd *inertialVelocityProperty; //!< [m] v_N inertial velocity relative to system spice zeroBase/refBase Eigen::MatrixXd *g_N; //!< [m/s^2] Gravitational acceleration in N frame components - + }; diff --git a/src/simulation/dynamics/extForceTorque/extForceTorque.cpp b/src/simulation/dynamics/extForceTorque/extForceTorque.cpp index 3e5cdcfe6..e5f9cff4b 100755 --- a/src/simulation/dynamics/extForceTorque/extForceTorque.cpp +++ b/src/simulation/dynamics/extForceTorque/extForceTorque.cpp @@ -41,7 +41,7 @@ ExtForceTorque::~ExtForceTorque() } -/*! This method is used to reset the module. +/*! This method is used to reset the module. @return void */ void ExtForceTorque::reset(uint64_t currentSimNanos) diff --git a/src/simulation/dynamics/facetDragEffector/_Documentation/secUserGuide.tex b/src/simulation/dynamics/facetDragEffector/_Documentation/secUserGuide.tex index 60fc01c08..c4012fd5b 100644 --- a/src/simulation/dynamics/facetDragEffector/_Documentation/secUserGuide.tex +++ b/src/simulation/dynamics/facetDragEffector/_Documentation/secUserGuide.tex @@ -35,4 +35,3 @@ \subsection{General Module Setup} scObject.modelTag = "spacecraftBody" scObject.addDynamicEffector(newDrag) \end{verbatim} - diff --git a/src/simulation/dynamics/facetDragEffector/facetDragDynamicEffector.h b/src/simulation/dynamics/facetDragEffector/facetDragDynamicEffector.h index e1b5268c9..411902151 100644 --- a/src/simulation/dynamics/facetDragEffector/facetDragDynamicEffector.h +++ b/src/simulation/dynamics/facetDragEffector/facetDragDynamicEffector.h @@ -80,4 +80,4 @@ class FacetDragDynamicEffector: public SysModel, public DynamicEffector { }; -#endif +#endif diff --git a/src/simulation/dynamics/facetSRPDynamicEffector/_UnitTest/test_unitFacetSRPDynamicEffector.py b/src/simulation/dynamics/facetSRPDynamicEffector/_UnitTest/test_unitFacetSRPDynamicEffector.py index 6e8f8ca8d..dbef170d7 100644 --- a/src/simulation/dynamics/facetSRPDynamicEffector/_UnitTest/test_unitFacetSRPDynamicEffector.py +++ b/src/simulation/dynamics/facetSRPDynamicEffector/_UnitTest/test_unitFacetSRPDynamicEffector.py @@ -66,7 +66,7 @@ def test_facetSRPTestFunction(show_plots, facetRotAngle1, facetRotAngle2): facetRotAngle1 (double): [rad] Articulation angle for facets 7 and 8 (solar panel 1) facetRotAngle2 (double): [rad] Articulation angle for facets 9 and 10 (solar panel 2) """ - + [testResults, testMessage] = facetSRPTestFunction(show_plots, facetRotAngle1, facetRotAngle2) assert testResults < 1, testMessage @@ -121,7 +121,7 @@ def facetSRPTestFunction(show_plots, facetRotAngle1, facetRotAngle2): facetRotAngle1MessageData.theta = facetRotAngle1 facetRotAngle1MessageData.thetaDot = 0.0 facetRotAngle1Message = messaging.HingedRigidBodyMsg().write(facetRotAngle1MessageData) - + facetRotAngle2MessageData = messaging.HingedRigidBodyMsgPayload() facetRotAngle2MessageData.theta = facetRotAngle2 facetRotAngle2MessageData.thetaDot = 0.0 diff --git a/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.h b/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.h index 73499fcb1..e21b217a8 100644 --- a/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.h +++ b/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.h @@ -73,4 +73,4 @@ class FacetSRPDynamicEffector: public SysModel, public DynamicEffector { bool facetAngleMsgRead; //!< Boolean variable signaling that the facet articulation messages are read }; -#endif +#endif diff --git a/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst b/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst index 339484135..c0c016564 100644 --- a/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst +++ b/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst @@ -8,9 +8,9 @@ articulating facets. The unit test for this module shows how to set up this part Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/dynamics/gravityEffector/_Documentation/secUserGuide.tex b/src/simulation/dynamics/gravityEffector/_Documentation/secUserGuide.tex index c2a9f1ee5..9ab1be620 100755 --- a/src/simulation/dynamics/gravityEffector/_Documentation/secUserGuide.tex +++ b/src/simulation/dynamics/gravityEffector/_Documentation/secUserGuide.tex @@ -4,8 +4,8 @@ \section{User Guide} \subsection{Using Central Bodies and Relative Dynamics} \subsubsection{Using Central Bodies} In simulations with multiple planetary bodies, using dynamics relative to a central body can improve accuracy. Generally, this is the right thing to do rather than using an absolute coordinate set. If a user has a gravBody called \verb|earth|, the central body flag should be set to True. -\verb|earth.isCentralBody = True| -The dynamics will then take care of themselves, but the user needs to be careful to input initial position and velocity values as \textit{relative to} the central body. This can be input from a set of Keplerian orbital elements using \verb|orbitalMotion.elem2rv| as in\\ \verb|Basilisk/tests/scenarios/scenarioBasicOrbit.py|. +\verb|earth.isCentralBody = True| +The dynamics will then take care of themselves, but the user needs to be careful to input initial position and velocity values as \textit{relative to} the central body. This can be input from a set of Keplerian orbital elements using \verb|orbitalMotion.elem2rv| as in\\ \verb|Basilisk/tests/scenarios/scenarioBasicOrbit.py|. The user should be aware that if spacecraft position and velocity are read back from a message log or plotted that the absolute position and velocity will be returned. It will take additional work to convert the outputs back to a relative form by subtracting out the central body positions and velocities. No rotation will be needed, though. It is critical that the relative position and velocities are given in a frame which is linearly translated but \textbf{not rotated} from the simulation inertial frame. There is no handling of rotated relative frames within the dynamics. The orbital element to position and velocity conversion in the section below can be used for relative dynamics inputs, as well. diff --git a/src/simulation/dynamics/gravityEffector/_UnitTest/test_gravityDynEffector.py b/src/simulation/dynamics/gravityEffector/_UnitTest/test_gravityDynEffector.py index 97f917362..ad994a77f 100644 --- a/src/simulation/dynamics/gravityEffector/_UnitTest/test_gravityDynEffector.py +++ b/src/simulation/dynamics/gravityEffector/_UnitTest/test_gravityDynEffector.py @@ -580,4 +580,4 @@ def multiBodyGravity(show_plots): # independentSphericalHarmonics(False) # sphericalHarmonics(False) # singleGravityBody(True) - multiBodyGravity(True) \ No newline at end of file + multiBodyGravity(True) diff --git a/src/simulation/dynamics/hingedRigidBodyMotor/_UnitTest/test_hingedRigidBodyMotor.py b/src/simulation/dynamics/hingedRigidBodyMotor/_UnitTest/test_hingedRigidBodyMotor.py index 79494be41..fa887e0b8 100644 --- a/src/simulation/dynamics/hingedRigidBodyMotor/_UnitTest/test_hingedRigidBodyMotor.py +++ b/src/simulation/dynamics/hingedRigidBodyMotor/_UnitTest/test_hingedRigidBodyMotor.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2022, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import pytest from Basilisk.architecture import messaging @@ -50,7 +50,7 @@ def test_hingedRigidBodyMotor(show_plots, K, P, sensedTheta, sensedThetaDot, ref accuracy (double): unit text accuracy **Description of Variables Being Tested** - + K and P are varied (note both must be set to positive values). The sensed hinged rigid body state is held constant while the reference is also varied to check positive and negative deltas. """ @@ -89,7 +89,7 @@ def hingedRigidBodyMotorTestFunction(show_plots, K, P, sensedTheta, sensedThetaD # subscribe input messages to module module.hingedBodyStateSensedInMsg.subscribeTo(hingedBodyStateSensedInMsg) module.hingedBodyStateReferenceInMsg.subscribeTo(hingedBodyStateReferenceInMsg) - + module.K = K module.P = P @@ -117,5 +117,3 @@ def hingedRigidBodyMotorTestFunction(show_plots, K, P, sensedTheta, sensedThetaD if __name__ == "__main__": test_hingedRigidBodyMotor(False, 5, 1, 1, .1, 1.2, .2, 1e-12) # first test case above - - diff --git a/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.h b/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.h index b2c318bbc..15902699d 100644 --- a/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.h +++ b/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.h @@ -39,7 +39,7 @@ class HingedRigidBodyMotor: public SysModel { void updateState(uint64_t currentSimNanos); public: - + double K; //!< gain on theta double P; //!< gain on theta dot diff --git a/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.rst b/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.rst index b14900263..9cd5dd358 100644 --- a/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.rst +++ b/src/simulation/dynamics/hingedRigidBodyMotor/hingedRigidBodyMotor.rst @@ -4,9 +4,9 @@ Calculates a motor torque given a sensed and reference hinged rigid body state u Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.cpp b/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.cpp index 6407c8084..6ec36d754 100644 --- a/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.cpp +++ b/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.cpp @@ -127,7 +127,7 @@ void linearTranslationOneDOFStateEffector::writeOutputStateMessages(uint64_t cur translatingBodyBuffer.rhoDot = this->rhoDot; this->translatingBodyOutMsg.write(&translatingBodyBuffer, this->moduleID, currentSimNanos); } - + if (this->translatingBodyConfigLogOutMsg.isLinked()) { SCStatesMsgPayload configLogMsg; configLogMsg = this->translatingBodyConfigLogOutMsg.zeroMsgPayload; @@ -194,10 +194,10 @@ void linearTranslationOneDOFStateEffector::computeBackSubContributions(BackSubMa this->aRho.setZero(); this->bRho.setZero(); this->cRho = 0.0; - + return; } - + this->aRho = - this->fHat_B.transpose(); this->bRho = this->fHat_B.transpose() * this->rTilde_FcB_B; this->cRho = 1.0 / this->mass * (this->motorForce - this->k * (this->rho - this->rhoRef) diff --git a/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.h b/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.h index 40fdefaad..2760f61ea 100644 --- a/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.h +++ b/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.h @@ -51,7 +51,7 @@ class linearTranslationOneDOFStateEffector : /** setter for `k` property */ void setK(double k); /** setter for `c` property */ - void setC(double c); + void setC(double c); /** setter for `rhoInit` property */ void setRhoInit(double rhoInit) {this->rhoInit = rhoInit;}; /** setter for `rhoDotInit` property */ diff --git a/src/simulation/dynamics/msmForceTorque/_UnitTest/test_msmForceTorque.py b/src/simulation/dynamics/msmForceTorque/_UnitTest/test_msmForceTorque.py index 9d675c969..6edb0d316 100644 --- a/src/simulation/dynamics/msmForceTorque/_UnitTest/test_msmForceTorque.py +++ b/src/simulation/dynamics/msmForceTorque/_UnitTest/test_msmForceTorque.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import pytest from Basilisk.architecture import messaging @@ -168,5 +168,3 @@ def msmForceTorqueTestFunction(show_plots, accuracy): if __name__ == "__main__": test_msmForceTorque(False, 1e-4) - - diff --git a/src/simulation/dynamics/msmForceTorque/msmForceTorque.h b/src/simulation/dynamics/msmForceTorque/msmForceTorque.h index b997f3319..1aa038022 100644 --- a/src/simulation/dynamics/msmForceTorque/msmForceTorque.h +++ b/src/simulation/dynamics/msmForceTorque/msmForceTorque.h @@ -46,7 +46,7 @@ class MsmForceTorque: public SysModel { private: void readMessages(); - + public: std::vector> scStateInMsgs; //!< vector of spacecraft state input messages std::vector> voltInMsgs; //!< vector of voltage input messages diff --git a/src/simulation/dynamics/msmForceTorque/msmForceTorque.rst b/src/simulation/dynamics/msmForceTorque/msmForceTorque.rst index 214147648..aa0f6b9b0 100644 --- a/src/simulation/dynamics/msmForceTorque/msmForceTorque.rst +++ b/src/simulation/dynamics/msmForceTorque/msmForceTorque.rst @@ -4,9 +4,9 @@ This module uses the Multi-Sphere-Method (MSM) to evaluate the mutual electrosta Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. _ModuleIO_MSM_FORCE_TORQUE: diff --git a/src/simulation/dynamics/reactionWheels/_UnitTest/test_reactionWheelStateEffector_RWUpdate.py b/src/simulation/dynamics/reactionWheels/_UnitTest/test_reactionWheelStateEffector_RWUpdate.py index a4e0b63fa..68b608ea2 100644 --- a/src/simulation/dynamics/reactionWheels/_UnitTest/test_reactionWheelStateEffector_RWUpdate.py +++ b/src/simulation/dynamics/reactionWheels/_UnitTest/test_reactionWheelStateEffector_RWUpdate.py @@ -55,8 +55,8 @@ def test_RWUpdate(show_plots, accuracy): The objective of this script is to test the functionality of changing the reaction wheel (RW) characteristics while the simulation is running. It starts by testing the initial setup, and then does four additional tests: the first - two change the maximum allowed torque, the third one changes the maximum power limit, and the final one changes the - current wheel speeds and maximum allowed wheel speeds. All these tests rely on the fact that, when a maximum or + two change the maximum allowed torque, the third one changes the maximum power limit, and the final one changes the + current wheel speeds and maximum allowed wheel speeds. All these tests rely on the fact that, when a maximum or minimum value is surpassed, the applied torque is capped accordingly. As this test script is not parameterized, only one version of this script will run. diff --git a/src/simulation/dynamics/reactionWheels/reactionWheelStateEffector.h b/src/simulation/dynamics/reactionWheels/reactionWheelStateEffector.h index 7725f6898..19ed5d568 100755 --- a/src/simulation/dynamics/reactionWheels/reactionWheelStateEffector.h +++ b/src/simulation/dynamics/reactionWheels/reactionWheelStateEffector.h @@ -62,7 +62,7 @@ class ReactionWheelStateEffector: public SysModel, public StateEffector { void WriteOutputMessages(uint64_t CurrentClock); void ReadInputs(); void ConfigureRWRequests(double CurrentTime); - + public: std::vector ReactionWheelData; //!< -- RW information diff --git a/src/simulation/dynamics/spacecraft/spacecraft.h b/src/simulation/dynamics/spacecraft/spacecraft.h index 7d6d1e14b..30a5432ac 100755 --- a/src/simulation/dynamics/spacecraft/spacecraft.h +++ b/src/simulation/dynamics/spacecraft/spacecraft.h @@ -58,7 +58,7 @@ class Spacecraft : public DynamicObject{ Eigen::Vector3d sumForceExternal_N; //!< [N] Sum of forces given in the inertial frame Eigen::Vector3d sumForceExternal_B; //!< [N] Sum of forces given in the body frame Eigen::Vector3d sumTorquePntB_B; //!< [N-m] Total torque about point B in B frame components - + Eigen::Vector3d dvAccum_CN_B; //!< [m/s] Accumulated delta-v of center of mass relative to inertial frame in body frame coordinates Eigen::Vector3d dvAccum_BN_B; //!< [m/s] accumulated delta-v of body frame relative to inertial frame in body frame coordinates Eigen::Vector3d dvAccum_CN_N; //!< [m/s] accumulated delta-v of center of mass relative to inertial frame in inertial frame coordinates diff --git a/src/simulation/dynamics/spacecraftSystem/_UnitTest/test_multiSpacecraft.py b/src/simulation/dynamics/spacecraftSystem/_UnitTest/test_multiSpacecraft.py index 6c913fbbe..f3a0f4fd3 100644 --- a/src/simulation/dynamics/spacecraftSystem/_UnitTest/test_multiSpacecraft.py +++ b/src/simulation/dynamics/spacecraftSystem/_UnitTest/test_multiSpacecraft.py @@ -748,4 +748,4 @@ def SCConnectedAndUnconnected(show_plots): if __name__ == "__main__": # SCConnected(True) - SCConnectedAndUnconnected(True) \ No newline at end of file + SCConnectedAndUnconnected(True) diff --git a/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.cpp b/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.cpp index 4fbf49805..ddfd4746e 100755 --- a/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.cpp +++ b/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.cpp @@ -619,9 +619,9 @@ void SpacecraftSystem::initializeSCPosVelocity(SpacecraftUnit &spacecraft) return; } -/*! This method is solving Xdot = F(X,t) for the system. The hub needs to calculate its derivatives, along with all of - the stateEffectors. The hub also has gravity and dynamicEffectors acting on it and these relationships are controlled - in this method. At the end of this method all of the states will have their corresponding state derivatives set in the +/*! This method is solving Xdot = F(X,t) for the system. The hub needs to calculate its derivatives, along with all of + the stateEffectors. The hub also has gravity and dynamicEffectors acting on it and these relationships are controlled + in this method. At the end of this method all of the states will have their corresponding state derivatives set in the dynParam Manager thus solving for Xdot*/ void SpacecraftSystem::equationsOfMotion(double integTimeSeconds, double timeStep) { @@ -1012,7 +1012,7 @@ void SpacecraftSystem::calculateDeltaVandAcceleration(SpacecraftUnit &spacecraft } /*! This method is used to find the total energy and momentum of the spacecraft. It finds the total orbital energy, - total orbital angular momentum, total rotational energy and total rotational angular momentum. These values are used + total orbital angular momentum, total rotational energy and total rotational angular momentum. These values are used for validation purposes. */ void SpacecraftSystem::computeEnergyMomentum(double time) { @@ -1206,7 +1206,7 @@ void SpacecraftSystem::computeEnergyMomentumSystem(double time) // - Find rotational angular momentum for the spacecraft totRotAngMomPntC_B += -(*this->primaryCentralSpacecraft.m_SC)(0,0)*(Eigen::Vector3d (*this->primaryCentralSpacecraft.c_B)).cross(cDotLocal_B); this->primaryCentralSpacecraft.totRotAngMomPntC_N = dcmLocal_NB*totRotAngMomPntC_B; - + return; } @@ -1308,4 +1308,3 @@ void SpacecraftSystem::postIntegration(double integrateToThisTime) { this->computeEnergyMomentum(integrateToThisTime); } - diff --git a/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.h b/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.h index de944e1a8..80e9da964 100755 --- a/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.h +++ b/src/simulation/dynamics/spacecraftSystem/spacecraftSystem.h @@ -66,7 +66,7 @@ class SpacecraftUnit { Message scStateOutMsg; //!< -- Name of the state output message Message scMassStateOutMsg; //!< -- Name of the state output message Message scEnergyMomentumOutMsg; //!< -- Name of the state output message - + double totOrbEnergy; //!< [J] Total orbital kinetic energy double totRotEnergy; //!< [J] Total rotational energy @@ -91,7 +91,7 @@ class SpacecraftUnit { Eigen::Vector3d nonConservativeAccelpntB_B;//!< [m/s/s] Current spacecraft body acceleration in the B frame Eigen::Vector3d omegaDot_BN_B; //!< [rad/s/s] angular acceleration of body wrt to N in body frame - + HubEffector hub; //!< class variable GravityEffector gravField; //!< -- Gravity effector for gravitational field experienced by spacecraft @@ -99,7 +99,7 @@ class SpacecraftUnit { std::vector dynEffectors; //!< -- Vector of dynamic effectors attached to dynObject std::vector dockingPoints; //!< class variable - + Eigen::MatrixXd *inertialPositionProperty; //!< [m] r_N inertial position relative to system spice zeroBase/refBase Eigen::MatrixXd *inertialVelocityProperty; //!< [m] v_N inertial velocity relative to system spice zeroBase/refBase @@ -152,7 +152,7 @@ class SpacecraftSystem : public DynamicObject{ SpacecraftUnit primaryCentralSpacecraft; //!< -- Primary spacecraft in which other spacecraft can attach/detach to/from std::vector spacecraftDockedToPrimary; //!< -- vector of spacecraft currently docked with primary spacecraft std::vector unDockedSpacecraft; //!< -- vector of spacecraft currently detached from all other spacecraft - int numberOfSCAttachedToPrimary; //!< class variable + int numberOfSCAttachedToPrimary; //!< class variable BSKLogger bskLogger; //!< -- BSK Logging public: @@ -181,7 +181,7 @@ class SpacecraftSystem : public DynamicObject{ private: Eigen::MatrixXd *sysTime; //!< [s] System time - + }; diff --git a/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/_UnitTest/test_spinningBodyOneDOFStateEffector.py b/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/_UnitTest/test_spinningBodyOneDOFStateEffector.py index 90d55a659..bd49f7ab6 100644 --- a/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/_UnitTest/test_spinningBodyOneDOFStateEffector.py +++ b/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/_UnitTest/test_spinningBodyOneDOFStateEffector.py @@ -166,7 +166,7 @@ def spinningBody(show_plots, cmdTorque, lock, thetaRef): # Add energy and momentum variables to log scObjectLog = scObject.logger(["totOrbAngMomPntN_N", "totRotAngMomPntC_N", "totOrbEnergy", "totRotEnergy"]) unitTestSim.AddModelToTask(unitTaskName, scObjectLog) - + # Initialize the simulation unitTestSim.InitializeSimulation() diff --git a/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.cpp b/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.cpp index cb58eb2c1..949a82d52 100644 --- a/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.cpp +++ b/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.cpp @@ -180,7 +180,7 @@ void SpinningBodyOneDOFStateEffector::updateEffectorMassProps(double integTime) - this->mass * (rPrimeTilde_ScB_B * this->rTilde_ScB_B + this->rTilde_ScB_B * rPrimeTilde_ScB_B); } -/*! This method allows the SB state effector to give its contributions to the matrices needed for the back-sub +/*! This method allows the SB state effector to give its contributions to the matrices needed for the back-sub method */ void SpinningBodyOneDOFStateEffector::updateContributions(double integTime, BackSubMatrices & backSubContr, @@ -233,7 +233,7 @@ void SpinningBodyOneDOFStateEffector::updateContributions(double integTime, - IPntS_B * this->omegaTilde_BN_B * this->omega_SB_B - this->mass * rTilde_ScS_B * this->omegaTilde_BN_B * rDot_SB_B)) / this->mTheta; } - + // For documentation on contributions see Vaz Carneiro, Allard, Schaub spinning body paper // Translation contributions backSubContr.matrixA = -this->mass * rTilde_ScS_B * this->sHat_B * this->aTheta.transpose(); @@ -262,7 +262,7 @@ void SpinningBodyOneDOFStateEffector::computeDerivatives(double integTime, this->sigma_BN = sigma_BN; this->dcm_BN = (this->sigma_BN.toRotationMatrix()).transpose(); - // Grab omegaDot_BN_B + // Grab omegaDot_BN_B Eigen::Vector3d omegaDotLocal_BN_B; omegaDotLocal_BN_B = omegaDot_BN_B; diff --git a/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/_UnitTest/test_spinningBodyTwoDOFStateEffector.py b/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/_UnitTest/test_spinningBodyTwoDOFStateEffector.py index d83d0c52e..a95611029 100644 --- a/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/_UnitTest/test_spinningBodyTwoDOFStateEffector.py +++ b/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/_UnitTest/test_spinningBodyTwoDOFStateEffector.py @@ -192,7 +192,7 @@ def spinningBody(show_plots, cmdTorque1, lock1, theta1Ref, cmdTorque2, lock2, th # Add energy and momentum variables to log scObjectLog = scObject.logger(["totOrbAngMomPntN_N", "totRotAngMomPntC_N", "totOrbEnergy", "totRotEnergy"]) unitTestSim.AddModelToTask(unitTaskName, scObjectLog) - + # Initialize the simulation unitTestSim.InitializeSimulation() diff --git a/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.cpp b/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.cpp index 3cdff76f3..2e4b54142 100644 --- a/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.cpp +++ b/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.cpp @@ -51,7 +51,7 @@ SpinningBodyTwoDOFStateEffector::SpinningBodyTwoDOFStateEffector() this->IS2PntSc2_B.setIdentity(); this->IPrimeS1PntSc1_B.setZero(); this->IPrimeS2PntSc2_B.setZero(); - + this->nameOfTheta1State = "spinningBodyTheta1" + std::to_string(SpinningBodyTwoDOFStateEffector::effectorID); this->nameOfTheta1DotState = "spinningBodyTheta1Dot" + std::to_string(SpinningBodyTwoDOFStateEffector::effectorID); this->nameOfTheta2State = "spinningBodyTheta2" + std::to_string(SpinningBodyTwoDOFStateEffector::effectorID); @@ -257,7 +257,7 @@ void SpinningBodyTwoDOFStateEffector::updateEffectorMassProps(double integTime) - this->mass2 * (rPrimeTilde_Sc2B_B * this->rTilde_Sc2B_B + this->rTilde_Sc2B_B * rPrimeTilde_Sc2B_B); } -/*! This method allows the SB state effector to give its contributions to the matrices needed for the back-sub +/*! This method allows the SB state effector to give its contributions to the matrices needed for the back-sub method */ void SpinningBodyTwoDOFStateEffector::updateContributions(double integTime, BackSubMatrices & backSubContr, Eigen::Vector3d sigma_BN, Eigen::Vector3d omega_BN_B, Eigen::Vector3d g_N) { @@ -327,18 +327,18 @@ void SpinningBodyTwoDOFStateEffector::updateContributions(double integTime, Back Eigen::Vector2d CThetaStar; CThetaStar(0,0) = this->u1 - this->k1 * (this->theta1 - this->theta1Ref) - this->c1 * (this->theta1Dot - this->theta1DotRef) + this->s1Hat_B.transpose() * gravityTorquePntS1_B - - this->s1Hat_B.transpose() * ((IPrimeSPntS1_B + this->omegaTilde_BN_B * ISPntS1_B) * this->omega_BN_B - + (this->IPrimeS1PntSc1_B + this->omegaTilde_BN_B * this->IS1PntSc1_B) * this->omega_S1B_B - + (this->IPrimeS2PntSc2_B + this->omegaTilde_BN_B * this->IS2PntSc2_B) * this->omega_S2B_B + - this->s1Hat_B.transpose() * ((IPrimeSPntS1_B + this->omegaTilde_BN_B * ISPntS1_B) * this->omega_BN_B + + (this->IPrimeS1PntSc1_B + this->omegaTilde_BN_B * this->IS1PntSc1_B) * this->omega_S1B_B + + (this->IPrimeS2PntSc2_B + this->omegaTilde_BN_B * this->IS2PntSc2_B) * this->omega_S2B_B + (this->IS2PntSc2_B - this->mass2 * rTilde_Sc2S1_B * rTilde_Sc2S2_B) * this->omegaTilde_S1B_B * this->omega_S2S1_B + this->mass1 * (rTilde_Sc1S1_B * this->omegaTilde_S1B_B + this->omegaTilde_BN_B * rTilde_Sc1S1_B) * this->rPrime_Sc1S1_B - + this->mass2 * (rTilde_Sc2S1_B * this->omegaTilde_S1B_B + this->omegaTilde_BN_B * rTilde_Sc2S1_B) * this->rPrime_Sc2S1_B + + this->mass2 * (rTilde_Sc2S1_B * this->omegaTilde_S1B_B + this->omegaTilde_BN_B * rTilde_Sc2S1_B) * this->rPrime_Sc2S1_B + this->mass2 * rTilde_Sc2S1_B * omegaTilde_S2S1_B * this->rPrime_Sc2S2_B + this->mass * rTilde_ScS1_B * this->omegaTilde_BN_B * rDot_S1B_B); CThetaStar(1, 0) = this->u2 - this->k2 * (this->theta2 - this->theta2Ref) - this->c2 * (this->theta2Dot - this->theta2DotRef) + this->s2Hat_B.transpose() * gravityTorquePntS2_B - this->s2Hat_B.transpose() * ((IPrimeS2PntS2_B + this->omegaTilde_BN_B * IS2PntS2_B) * this->omega_S2N_B - + IS2PntS2_B * this->omegaTilde_S1B_B * this->omega_S2S1_B + this->mass2 * rTilde_Sc2S2_B * omegaTilde_S1N_B * this->rPrime_S2S1_B + + IS2PntS2_B * this->omegaTilde_S1B_B * this->omega_S2S1_B + this->mass2 * rTilde_Sc2S2_B * omegaTilde_S1N_B * this->rPrime_S2S1_B + this->mass2 * rTilde_Sc2S2_B * this->omegaTilde_BN_B * (rDot_S2S1_B + rDot_S1B_B)); // Check if any of the axis are locked and change dynamics accordingly @@ -353,7 +353,7 @@ void SpinningBodyTwoDOFStateEffector::updateContributions(double integTime, Back AThetaStar.row(0).setZero(); BThetaStar.row(0).setZero(); CThetaStar.row(0).setZero(); - + } if (this->lockFlag2 == 1) { @@ -383,16 +383,16 @@ void SpinningBodyTwoDOFStateEffector::updateContributions(double integTime, Back backSubContr.vecRot = - (this->IPrimeS1PntSc1_B + this->omegaTilde_BN_B * this->IS1PntSc1_B) * this->omega_S1B_B - (this->IPrimeS2PntSc2_B + this->omegaTilde_BN_B * this->IS2PntSc2_B) * this->omega_S2B_B - (this->IS2PntSc2_B - this->mass2 * this->rTilde_Sc2B_B * rTilde_Sc2S2_B) * this->omegaTilde_S1B_B * this->omega_S2S1_B - this->mass1 * (this->rTilde_Sc1B_B * this->omegaTilde_S1B_B + this->omegaTilde_BN_B * this->rTilde_Sc1B_B) * this->rPrime_Sc1B_B - - this->mass2 * (this->rTilde_Sc2B_B * this->omegaTilde_S1B_B + this->omegaTilde_BN_B * this->rTilde_Sc2B_B) * this->rPrime_Sc2B_B + - this->mass2 * (this->rTilde_Sc2B_B * this->omegaTilde_S1B_B + this->omegaTilde_BN_B * this->rTilde_Sc2B_B) * this->rPrime_Sc2B_B - this->mass2 * this->rTilde_Sc2B_B * omegaTilde_S2S1_B * this->rPrime_Sc2S2_B - (this->IS1PntSc1_B + this->IS2PntSc2_B - this->mass1 * this->rTilde_Sc1B_B * rTilde_Sc1S1_B - this->mass2 * this->rTilde_Sc2B_B * rTilde_Sc2S1_B) * this->s1Hat_B * this->CTheta.row(0) - - (this->IS2PntSc2_B - this->mass2 * this->rTilde_Sc2B_B * rTilde_Sc2S2_B) * this->s2Hat_B * this->CTheta.row(1); + - (this->IS2PntSc2_B - this->mass2 * this->rTilde_Sc2B_B * rTilde_Sc2S2_B) * this->s2Hat_B * this->CTheta.row(1); } /*! This method is used to find the derivatives for the SB stateEffector: thetaDDot and the kinematic derivative */ void SpinningBodyTwoDOFStateEffector::computeDerivatives(double integTime, Eigen::Vector3d rDDot_BN_N, Eigen::Vector3d omegaDot_BN_B, Eigen::Vector3d sigma_BN) -{ - // Grab omegaDot_BN_B +{ + // Grab omegaDot_BN_B Eigen::Vector3d omegaDotLocal_BN_B; omegaDotLocal_BN_B = omegaDot_BN_B; @@ -465,7 +465,7 @@ void SpinningBodyTwoDOFStateEffector::updateState(uint64_t currentSimNanos) this->u1 = incomingCmdBuffer.motorTorque[0]; this->u2 = incomingCmdBuffer.motorTorque[1]; } - + //! - Zero the command buffer and read the incoming command array if (this->motorLockInMsg.isLinked() && this->motorLockInMsg.isWritten()) { ArrayEffectorLockMsgPayload incomingLockBuffer; @@ -490,7 +490,7 @@ void SpinningBodyTwoDOFStateEffector::updateState(uint64_t currentSimNanos) /* Compute spinning body inertial states */ this->computeSpinningBodyInertialStates(); - + /* Write output messages*/ this->writeOutputStateMessages(currentSimNanos); } diff --git a/src/simulation/environment/ExponentialAtmosphere/_Documentation/secUserGuide.tex b/src/simulation/environment/ExponentialAtmosphere/_Documentation/secUserGuide.tex index 11219145f..0f3000676 100644 --- a/src/simulation/environment/ExponentialAtmosphere/_Documentation/secUserGuide.tex +++ b/src/simulation/environment/ExponentialAtmosphere/_Documentation/secUserGuide.tex @@ -38,4 +38,3 @@ \subsection{Planet Ephemeris Information} \subsection{Setting the Model Reach} By default the model doesn't perform any checks on the altitude to see if the specified atmosphere model should be used. This is set through the parameters {\tt envMinReach} and {\tt envMaxReach}. Their default values are -1. If these are set to positive values, then if the altitude is smaller than {\tt envMinReach} or larger than {\tt envMaxReach}, the density is set to zero. - diff --git a/src/simulation/environment/MsisAtmosphere/_Documentation/secUserGuide.tex b/src/simulation/environment/MsisAtmosphere/_Documentation/secUserGuide.tex index c973678fa..2c02328d1 100644 --- a/src/simulation/environment/MsisAtmosphere/_Documentation/secUserGuide.tex +++ b/src/simulation/environment/MsisAtmosphere/_Documentation/secUserGuide.tex @@ -22,7 +22,7 @@ \subsection{General Module Setup} \item {\bfseries Direct Setting:} The module variable {\tt epochDoy} can be set directly as well. However, note that if the input message is specified, the {\tt epochDoy} value is not used. \begin{verbatim} newAtmo.epochDoy = 1 - \end{verbatim} + \end{verbatim} \end{enumerate} The model can then be added to a task like other simModels. Each Atmosphere calculates atmospheric parameters based on the output state messages for a set of spacecraft. @@ -56,4 +56,4 @@ \subsection{NRLMSISE-00 atmosphere user guide} "ap_3_-42", "ap_3_-45", "ap_3_-48","ap_3_-51","ap_3_-54", "ap_3_-57","f107_1944_0","f107_24_-24" ] -\end{verbatim} \ No newline at end of file +\end{verbatim} diff --git a/src/simulation/environment/TabularAtmosphere/_UnitTest/test_unitTestTabularAtmosphere.py b/src/simulation/environment/TabularAtmosphere/_UnitTest/test_unitTestTabularAtmosphere.py index 5698e8e68..a60cec4d4 100644 --- a/src/simulation/environment/TabularAtmosphere/_UnitTest/test_unitTestTabularAtmosphere.py +++ b/src/simulation/environment/TabularAtmosphere/_UnitTest/test_unitTestTabularAtmosphere.py @@ -50,7 +50,7 @@ def test_tabularAtmosphere(altitude, accuracy, useMinReach, useMaxReach): r""" **Validation Test Description** - + TabularAtmosphere interpolates from user-provided data to compute density and temperature at the current s/c altitude. The unit test checks altitudes at, between, above, and below the values included in the table. This test uses a python helper function to provide data from EarthGRAM (see supportData\AtmosphereData\support). @@ -80,7 +80,7 @@ def test_tabularAtmosphere(altitude, accuracy, useMinReach, useMaxReach): - ``densData[0]`` - ``tempData[0]`` """ - + # each test method requires a single assert method to be called [testResults, testMessage] = tabularAtmosphereTestFunction(altitude, accuracy, useMinReach, useMaxReach) assert testResults < 1, testMessage @@ -102,21 +102,21 @@ def tabularAtmosphereTestFunction(altitude, accuracy, useMinReach, useMaxReach): # Construct algorithm and associated C++ container module = tabularAtmosphere.TabularAtmosphere() # update with current values module.modelTag = "tabularAtmosphere" # update python name of test module - + # define constants & load data r_eq = 6378136.6 filename = bskPath + '/../../supportData/AtmosphereData/EarthGRAMNominal.txt' altList, rhoList, tempList = readAtmTable(filename,'EarthGRAM') - + # assign constants & ref. data to module module.planetRadius = r_eq - module.altList = tabularAtmosphere.DoubleVector(altList) + module.altList = tabularAtmosphere.DoubleVector(altList) module.rhoList = tabularAtmosphere.DoubleVector(rhoList) module.tempList = tabularAtmosphere.DoubleVector(tempList) # Add test module to runtime call list unitTestSim.AddModelToTask(unitTaskName, module) - + # CHECK - env min and max if useMinReach: minReach = 50.0 * 1000 @@ -128,7 +128,7 @@ def tabularAtmosphereTestFunction(altitude, accuracy, useMinReach, useMaxReach): module.envMaxReach = maxReach else: maxReach = 5000.0 * 1000 - + # setup orbit and simulation time r0 = r_eq + (altitude * 1000.0) # meters oe = orbitalMotion.ClassicElements() @@ -145,7 +145,7 @@ def tabularAtmosphereTestFunction(altitude, accuracy, useMinReach, useMaxReach): scStateMsg = messaging.SCStatesMsgPayload() # Create a structure for the input message scStateMsg.r_BN_N = np.array(r0N) scInMsg = messaging.SCStatesMsg().write(scStateMsg) - + # add spacecraft to environment model module.addSpacecraftToModel(scInMsg) @@ -164,11 +164,11 @@ def tabularAtmosphereTestFunction(altitude, accuracy, useMinReach, useMaxReach): # Begin the simulation time run set above unitTestSim.ExecuteSimulation() - + # This pulls the actual data log from the simulation run. densData = dataLog.neutralDensity tempData = dataLog.localTemp - + # define python function to compute truth values def tabAtmoComp(val, xList, yList): if (val < xList[0]) or (val <= minReach): @@ -186,16 +186,16 @@ def tabAtmoComp(val, xList, yList): m = (y1 - y0)/(x - x0) out = y0 + (val - x0) * m return out - + # compute truth values trueDensity = tabAtmoComp(altitude * 1000, altList, rhoList) print('\nmodule density: {0:.6e}'.format(densData[0])) print('true density: {0:.6e}'.format(trueDensity)) - + trueTemp = tabAtmoComp(altitude * 1000, altList, tempList) print('\nmodule temperature: {0:.6e}'.format(tempData[0])) print('true temperature: {0:.6e}\n'.format(trueTemp)) - + # compare truth values to module results if trueDensity != 0: testFailCount = not unitTestSupport.isDoubleEqualRelative(densData[0], trueDensity, accuracy) @@ -205,7 +205,7 @@ def tabAtmoComp(val, xList, yList): testMessage = "density computed correctly" else: testMessage = "density computed incorrectly" - + # compare truth values to module results for temperature if trueTemp != 0 : # needs checking testFailCount = not unitTestSupport.isDoubleEqualRelative(tempData[0], trueTemp, accuracy) @@ -220,7 +220,7 @@ def tabAtmoComp(val, xList, yList): if testFailCount == 0: print("PASSED: " + module.modelTag) - return [testFailCount, testMessage] + return [testFailCount, testMessage] # diff --git a/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.cpp b/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.cpp index 548d2e38b..1e5a3552d 100644 --- a/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.cpp +++ b/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.cpp @@ -49,12 +49,12 @@ void TabularAtmosphere::customreset(uint64_t CurrentClock) this->altList_length = (int) this->altList.size(); this->rhoList_length = (int) this->rhoList.size(); this->tempList_length = (int) this->tempList.size(); - + if((this->altList_length != this->rhoList_length) || (this->altList_length != this->tempList_length)){ bskLogger.bskLog(BSK_ERROR, "Input arrays not of equal length."); } - + if(this->altList_length == 0){ bskLogger.bskLog(BSK_ERROR, "No data in altitude list."); } else if(this->rhoList_length == 0){ @@ -62,7 +62,7 @@ void TabularAtmosphere::customreset(uint64_t CurrentClock) } else if(this->tempList_length == 0){ bskLogger.bskLog(BSK_ERROR, "No data in temperature list."); } - + return; } diff --git a/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.h b/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.h index fe6c03853..10a44b941 100644 --- a/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.h +++ b/src/simulation/environment/TabularAtmosphere/tabularAtmosphere.h @@ -33,10 +33,10 @@ class TabularAtmosphere: public AtmosphereBase { private: - + // pulls density and temperature from atmospheric table at requested altitude, performs linear interpolation if necessary void evaluateAtmosphereModel(AtmoPropsMsgPayload *msg, double currentTime); - + int altList_length; // length of list of altitude values extracted from the atmosphere table int rhoList_length; // length of list of density values extracted from the atmosphere table int tempList_length; // length of list of temperature values extracted from the atmosphere table diff --git a/src/simulation/environment/albedo/_UnitTest/test_albedo.py b/src/simulation/environment/albedo/_UnitTest/test_albedo.py index 23a17c671..d242f5cff 100644 --- a/src/simulation/environment/albedo/_UnitTest/test_albedo.py +++ b/src/simulation/environment/albedo/_UnitTest/test_albedo.py @@ -214,7 +214,7 @@ def unitAlbedo(show_plots, planetCase, modelType, useEclipse): def test_albedo_invalid_file(tmp_path): """Verify that Albedo model returns gracefully when file cannot be loaded. - + Regression test for BSK-428 where model would segfault when invalid file was specified. @@ -242,7 +242,7 @@ def test_albedo_invalid_file(tmp_path): albModule.spacecraftStateInMsg.subscribeTo(scInMsg) albModule.addPlanetandAlbedoDataModel(planetInMsg, str(tmp_path), "does_not_exit.file") - + # this call would previously segfault albModule.reset(0) diff --git a/src/simulation/environment/albedo/albedo.cpp b/src/simulation/environment/albedo/albedo.cpp index 4cd95b902..2c643afa6 100644 --- a/src/simulation/environment/albedo/albedo.cpp +++ b/src/simulation/environment/albedo/albedo.cpp @@ -76,7 +76,7 @@ Config::Config() { this->nHat_B.fill(0.0); this->r_IB_B.fill(0.0); return; -} +} Config::~Config() { return; @@ -95,7 +95,7 @@ void Albedo::addInstrumentConfig(instConfig_t configMsg) { if (configMsg.fov < 0.0) { this->fovs.push_back(this->fov_default); bskLogger.bskLog(BSK_WARNING, "Albedo Module (addInstrumentConfig): For the instrument (%lu)'s half field of view angle (fov), the default value is used.", (int) this->albOutMsgs.size()-1); - } + } else { this->fovs.push_back(configMsg.fov); } @@ -143,7 +143,7 @@ void Albedo::addInstrumentConfig(double fov, Eigen::Vector3d nHat_B, Eigen::Vect this->nHat_Bs.push_back(nHat_B_default); bskLogger.bskLog(BSK_WARNING, "Albedo Module (addInstrumentConfig): Instrument (%lu)'s unit normal vector (nHat_B) cannot be composed of all zeros, the default vector is used instead.", this->albOutMsgs.size()-1); } - + return; } @@ -407,7 +407,7 @@ void Albedo::evaluateAlbedoModel(int idx) auto dataPath = this->dataPaths.at(idx); auto numLat = this->numLats.at(idx); auto numLon = this->numLons.at(idx); - //! - Obtain the parameters of the specified model + //! - Obtain the parameters of the specified model if (modelName == "ALBEDO_AVG") { //! - Albedo model based on an average value if (numLat < 0.0) { numLat = this->defaultNumLat; } @@ -507,7 +507,7 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan //! - B: spacecraft body frame //! - N: inertial frame //! - S: sun (helio) frame - //! - I: instrument body frame + //! - I: instrument body frame auto fov = this->fovs[instIdx]; //! - [rad] instrument's field of view half angle auto nHat_B = this->nHat_Bs[instIdx]; //! - [-] unit normal vector of the instrument (spacecraft body) auto r_IB_B = this->r_IB_Bs[instIdx]; //! - [m] instrument's misalignment vector wrt spacecraft's body frame @@ -585,7 +585,7 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan r_dAP_N = LLA2PCI(gdlla, planetMsg.J20002Pfix, RA_planet); //! - Assumes that the planet is a sphere. r_SdA_N = r_SP_N - r_dAP_N; //! - [m] position vector from dA to Sun (inertial) r_IdA_N = r_IP_N - r_dAP_N; //! - [m] position vector from dA to instrument (inertial) - rHat_dAP_N = r_dAP_N / r_dAP_N.norm(); //! - [-] -assuming- dA normal vector (inertial) + rHat_dAP_N = r_dAP_N / r_dAP_N.norm(); //! - [-] -assuming- dA normal vector (inertial) sHat_SdA_N = r_SdA_N / r_SdA_N.norm(); //! - [-] sun direction vector from dA (inertial) rHat_IdA_N = r_IdA_N / r_IdA_N.norm(); //! - [-] dA to instrument direction vector (inertial) //! - Portions of the planet diff --git a/src/simulation/environment/albedo/albedo.h b/src/simulation/environment/albedo/albedo.h index 651cfd3a8..fe13e96bd 100644 --- a/src/simulation/environment/albedo/albedo.h +++ b/src/simulation/environment/albedo/albedo.h @@ -84,7 +84,7 @@ class Albedo : public SysModel { ReadFunctor spacecraftStateInMsg; //!< input message name for spacecraft data std::vector> planetInMsgs; //!< vector of planet data input data - BSKLogger bskLogger; //!< BSK Logging + BSKLogger bskLogger; //!< BSK Logging int defaultNumLat; //!< [-] default number of latitude grid points int defaultNumLon; //!< [-] default number of longitude grid points Eigen::Vector3d nHat_B_default; //!< [-] default value for unit normal of the instrument (spacecraft body) diff --git a/src/simulation/environment/dentonFluxModel/dentonFluxModel.rst b/src/simulation/environment/dentonFluxModel/dentonFluxModel.rst index 869fe8c22..055130383 100644 --- a/src/simulation/environment/dentonFluxModel/dentonFluxModel.rst +++ b/src/simulation/environment/dentonFluxModel/dentonFluxModel.rst @@ -9,9 +9,9 @@ flux data. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. _ModuleIO_Denton_Flux_Model: diff --git a/src/simulation/environment/eclipse/eclipse.cpp b/src/simulation/environment/eclipse/eclipse.cpp index 54ea92db2..041bc1dc8 100755 --- a/src/simulation/environment/eclipse/eclipse.cpp +++ b/src/simulation/environment/eclipse/eclipse.cpp @@ -96,7 +96,7 @@ void Eclipse::writeOutputMessages(uint64_t CurrentClock) void Eclipse::updateState(uint64_t currentSimNanos) { this->readInputMessages(); - + // A lot of different vectors here. The below letters denote frames // P: planet frame // B: spacecraft body frame @@ -111,18 +111,18 @@ void Eclipse::updateState(uint64_t currentSimNanos) std::vector::iterator scIt; std::vector::iterator planetIt; - + // Index to assign the shadowFactor for each body position (S/C) // being tracked int scIdx = 0; - + for(scIt = this->scStateBuffer.begin(); scIt != this->scStateBuffer.end(); scIt++) { double tmpShadowFactor = 1.0; // 1.0 means 100% illumination (no eclipse) double eclipsePlanetDistance = 0.0; int64_t eclipsePlanetKey = -1; r_BN_N = cArray2EigenVector3d(scIt->r_BN_N); - + // Find the closest planet if there is one int idx = 0; for(planetIt = this->planetBuffer.begin(); planetIt != this->planetBuffer.end(); planetIt++) @@ -137,7 +137,7 @@ void Eclipse::updateState(uint64_t currentSimNanos) if (r_HB_N.norm() < s_HP_N.norm()) { idx++; continue; - } + } else{ // Find the closest planet and save its distance and vector index slot if (s_BP_N.norm() < eclipsePlanetDistance || eclipsePlanetKey < 0) { @@ -147,7 +147,7 @@ void Eclipse::updateState(uint64_t currentSimNanos) idx++; } } - + // If planetkey is not -1 then we have a planet for which // we compute the eclipse conditions if (eclipsePlanetKey >= 0) { @@ -155,7 +155,7 @@ void Eclipse::updateState(uint64_t currentSimNanos) s_BP_N = r_BN_N - r_PN_N; r_HB_N = r_HN_N - r_BN_N; s_HP_N = r_HN_N - r_PN_N; - + double s = s_BP_N.norm(); std::string plName(this->planetBuffer[eclipsePlanetKey].PlanetName); double planetRadius = this->getPlanetEquatorialRadius(plName); @@ -167,7 +167,7 @@ void Eclipse::updateState(uint64_t currentSimNanos) double l = safeSqrt(s*s - s_0*s_0); double l_1 = c_1*tan(f_1); double l_2 = c_2*tan(f_2); - + if (fabs(l) < fabs(l_2)) { if (c_2 < 0) { // total eclipse tmpShadowFactor = this->computePercentShadow(planetRadius, r_HB_N, s_BP_N); @@ -199,7 +199,7 @@ double Eclipse::computePercentShadow(double planetRadius, Eigen::Vector3d r_HB_N double a = safeAsin(REQ_SUN*1000/normR_HB_N); // apparent radius of sun double b = safeAsin(planetRadius/normS_BP_N); // apparent radius of occulting body double c = safeAcos((-s_BP_N.dot(r_HB_N))/(normS_BP_N*normR_HB_N)); - + // The order of these conditionals is important. // In particular (c < a + b) must check last to avoid testing // with implausible a, b and c values diff --git a/src/simulation/environment/eclipse/eclipse.h b/src/simulation/environment/eclipse/eclipse.h index daef00ade..0cbf1a7b7 100755 --- a/src/simulation/environment/eclipse/eclipse.h +++ b/src/simulation/environment/eclipse/eclipse.h @@ -38,13 +38,13 @@ class Eclipse: public SysModel { public: Eclipse(); ~Eclipse(); - + void reset(uint64_t CurrenSimNanos); void updateState(uint64_t currentSimNanos); void writeOutputMessages(uint64_t CurrentClock); void addSpacecraftToModel(Message *tmpScMsg); void addPlanetToModel(Message *tmpSpMsg); - + public: ReadFunctor sunInMsg; //!< sun ephemeris input message name std::vector> planetInMsgs; //!< A vector of planet incoming state message names ordered by the sequence in which planet are added to the module diff --git a/src/simulation/environment/ephemerisConverter/_Documentation/secUserGuide.tex b/src/simulation/environment/ephemerisConverter/_Documentation/secUserGuide.tex index 43f8f38b3..0417cf87d 100644 --- a/src/simulation/environment/ephemerisConverter/_Documentation/secUserGuide.tex +++ b/src/simulation/environment/ephemerisConverter/_Documentation/secUserGuide.tex @@ -7,4 +7,4 @@ \section{User Guide} \item[-] \texttt{EphemObject.modelTag = 'EphemData'} \item[-] \texttt{EphemObject.addSpiceInputMsg(spiceInMsg)} \end{itemize} -The output messages are then stored in the vector of output messages called {\tt ephemOutMsgs}. \ No newline at end of file +The output messages are then stored in the vector of output messages called {\tt ephemOutMsgs}. diff --git a/src/simulation/environment/groundLocation/groundLocation.h b/src/simulation/environment/groundLocation/groundLocation.h index 3e2a63ad9..d99548084 100644 --- a/src/simulation/environment/groundLocation/groundLocation.h +++ b/src/simulation/environment/groundLocation/groundLocation.h @@ -48,7 +48,7 @@ class GroundLocation: public SysModel { void addSpacecraftToModel(Message *tmpScMsg); void specifyLocation(double lat, double longitude, double alt); void specifyLocationPCPF(Eigen::Vector3d& r_LP_P_Loc); - + private: void updateInertialPositions(); void computeAccess(); diff --git a/src/simulation/environment/groundMapping/_UnitTest/test_groundMapping.py b/src/simulation/environment/groundMapping/_UnitTest/test_groundMapping.py index 8d9e65ae2..3b42cfa16 100644 --- a/src/simulation/environment/groundMapping/_UnitTest/test_groundMapping.py +++ b/src/simulation/environment/groundMapping/_UnitTest/test_groundMapping.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2022, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import math diff --git a/src/simulation/environment/groundMapping/groundMapping.rst b/src/simulation/environment/groundMapping/groundMapping.rst index a47863e04..13b90eab0 100644 --- a/src/simulation/environment/groundMapping/groundMapping.rst +++ b/src/simulation/environment/groundMapping/groundMapping.rst @@ -11,9 +11,9 @@ also assumes the spacecraft instrument has a spherical field-of-view (FOV). Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/environment/magneticFieldCenteredDipole/_Documentation/secUserGuide.tex b/src/simulation/environment/magneticFieldCenteredDipole/_Documentation/secUserGuide.tex index 87b1b7a85..ec3ff2715 100644 --- a/src/simulation/environment/magneticFieldCenteredDipole/_Documentation/secUserGuide.tex +++ b/src/simulation/environment/magneticFieldCenteredDipole/_Documentation/secUserGuide.tex @@ -10,9 +10,9 @@ \subsection{General Module Setup} magModule = magneticFieldCenteredDipole.MagneticFieldCenteredDipole() magModule = "CenteredDipole" \end{verbatim} -By default the model the dipole parameters are zeroed, resulting in a zeroed magnetic field message. +By default the model the dipole parameters are zeroed, resulting in a zeroed magnetic field message. -The model can be added to a task like other simModels. +The model can be added to a task like other simModels. \begin{verbatim} unitTestSim.AddModelToTask(unitTaskName, testModule) \end{verbatim} @@ -46,13 +46,12 @@ \subsection{Centered Dipole Magnetic Parameters} \end{verbatim} where $g_{1}^{0}$, $g_{1}^{1}$ and $h_{1}^{1}$ are the first three expansion terms of the IGRF spherical harmonics model.\footnote{\url{https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html}} -The python support file {\tt simSetPlanetEnvironment.py} contains a helper function called +The python support file {\tt simSetPlanetEnvironment.py} contains a helper function called \begin{verbatim} centeredDipoleMagField() -\end{verbatim} +\end{verbatim} which helps setup common NASA centered dipole models for a range of planets that contain global magnetic fields. This possible planet names includes mercury, earth, jupiter, saturn, uranus and neptune. The function is then called with \begin{verbatim} simSetPlanetEnvironment.centeredDipoleMagField(testModule, "jupiter") \end{verbatim} to setup the named planets dipole model. - diff --git a/src/simulation/environment/magneticFieldWMM/_Documentation/secUserGuide.tex b/src/simulation/environment/magneticFieldWMM/_Documentation/secUserGuide.tex index cda7d9839..5d65a257c 100644 --- a/src/simulation/environment/magneticFieldWMM/_Documentation/secUserGuide.tex +++ b/src/simulation/environment/magneticFieldWMM/_Documentation/secUserGuide.tex @@ -24,13 +24,13 @@ \subsection{General Module Setup} epMsg = messaging.EpochMsg().write(epochMsgData) magModule.epochInMsg.subscribeTo(epMsg) \end{verbatim} -If the user wants to set the WMM epoch directly, this is done by defining the {\tt epochDate} variable in terms of a decimal year format required by WMM. +If the user wants to set the WMM epoch directly, this is done by defining the {\tt epochDate} variable in terms of a decimal year format required by WMM. \begin{verbatim} magModule.epochDate = decimalYear \end{verbatim} -Not that the epoch message, if available, over-writes the information of setting {\tt epochDate}. +Not that the epoch message, if available, over-writes the information of setting {\tt epochDate}. -The model can be added to a task like other simModels. +The model can be added to a task like other simModels. \begin{verbatim} unitTestSim.AddModelToTask(unitTaskName, testModule) \end{verbatim} @@ -52,5 +52,3 @@ \subsection{Planet Ephemeris Information} \subsection{Setting the Model Reach} By default the model doesn't perform any checks on the altitude to see if the specified magnetic field model should be used. This is set through the parameters {\tt envMinReach} and {\tt envMaxReach}. Their default values are -1. If these are set to positive values, then if the spacecraft orbit radius is smaller than {\tt envMinReach} or larger than {\tt envMaxReach}, the magnetic field vector is set to zero. - - diff --git a/src/simulation/environment/spacecraftLocation/spacecraftLocation.h b/src/simulation/environment/spacecraftLocation/spacecraftLocation.h index 864599a20..87fbcc56b 100644 --- a/src/simulation/environment/spacecraftLocation/spacecraftLocation.h +++ b/src/simulation/environment/spacecraftLocation/spacecraftLocation.h @@ -43,7 +43,7 @@ class SpacecraftLocation: public SysModel { bool ReadMessages(); void WriteMessages(uint64_t CurrentClock); void addSpacecraftToModel(Message *tmpScMsg); - + private: void computeAccess(); @@ -59,7 +59,7 @@ class SpacecraftLocation: public SysModel { std::vector*> accessOutMsgs; //!< vector of ground location access messages std::vector> scStateInMsgs; //!< vector of other sc state input messages Eigen::Vector3d r_LB_B; //!< [m] position of the location relative to the spacecraft frame origin B, in B frame components - + BSKLogger bskLogger; //!< -- BSK Logging private: diff --git a/src/simulation/navigation/pinholeCamera/pinholeCamera.h b/src/simulation/navigation/pinholeCamera/pinholeCamera.h index 4e2420535..f99f95d8b 100755 --- a/src/simulation/navigation/pinholeCamera/pinholeCamera.h +++ b/src/simulation/navigation/pinholeCamera/pinholeCamera.h @@ -41,10 +41,10 @@ class PinholeCamera: public SysModel { void reset(uint64_t currentSimNanos); void readInputMessages(); void writeOutputMessages(uint64_t CurrentClock); - + void addLandmark(Eigen::Vector3d& pos, Eigen::Vector3d& normal); void processBatch(Eigen::MatrixXd rBatch_BP_P, Eigen::MatrixXd mrpBatch_BP, Eigen::MatrixXd eBatch_SP_P, bool show_progress); - + private: void processInputs(); void loopLandmarks(); @@ -61,43 +61,43 @@ class PinholeCamera: public SysModel { double nyPixel; //!< [-] number of vertical pixels double wPixel; //!< [m] pixel width Eigen::Matrix3d dcm_CB; //!< [-] dcm from body to camera - + /* Module outputs */ Eigen::VectorXi isvisibleLmk; //!< [-] flag telling if a landmark is visible Eigen::MatrixXi pixelLmk; //!< [-] pixels for landmarks - + /* Landmark distribution */ std::vector r_LP_P; //!< [m] landmark positions in planet frame std::vector nL_P; //!< [-] landmark normals in planet frame - + double maskSun; //!< [-] minimum slant range for Sun lighting /* Messages definition */ ReadFunctor ephemerisInMsg; //!< planet ephemeris input message ReadFunctor scStateInMsg; //!< spacecraft state input msg - + SCStatesMsgPayload spacecraftState; //!< input spacecraft state EphemerisMsgPayload ephemerisPlanet; //!< input planet ephemeris std::vector*> landmarkOutMsgs; //!< vector of landmark messages std::vector landmarkMsgBuffer; //!< buffer of landmark output data BSKLogger bskLogger; //!< -- BSK Logging - + /* Batch variables */ Eigen::MatrixXi pixelBatchLmk; //!< [-] batch of landmark pixels Eigen::MatrixXi isvisibleBatchLmk; //!< [-] batch of landmark visibility stauts private: int n; //!< [-] number of landmarks - + /* Positions */ Eigen::Vector3d r_PN_N; //!< [m] current planet position in inertial frame Eigen::Vector3d r_BP_P; //!< [m] current spacecraft position w.r.t. planet in planet frame - + /* Direction cosine matrices */ Eigen::Matrix3d dcm_BP; //!< [-] current direction cosine matrix from planet to spacecraft body frame Eigen::Matrix3d dcm_PN; //!< [-] current direction cosine matrix from inertial to planet frame - + /* Unit-vectors */ Eigen::Vector3d e_SP_P; //!< [-] current unit-vector pointing from planet to Sun in planet frame Eigen::Vector3d eC_C; //!< [-] focal direction unit-vector in camera frame diff --git a/src/simulation/navigation/pinholeCamera/pinholeCamera.rst b/src/simulation/navigation/pinholeCamera/pinholeCamera.rst index ce2fc7eb0..955aad937 100755 --- a/src/simulation/navigation/pinholeCamera/pinholeCamera.rst +++ b/src/simulation/navigation/pinholeCamera/pinholeCamera.rst @@ -4,7 +4,7 @@ Executive Summary This module simulates a camera pinhole model that computes landmark pixels as seen by a spacecraft. It reads the planet's ephemeris and spacecraft state messages as inputs. It outputs a vector of landmark messages. -The module can also account for Sun's lighting constraint by setting a mask angle. +The module can also account for Sun's lighting constraint by setting a mask angle. diff --git a/src/simulation/navigation/planetNav/_UnitTest/test_planetNav.py b/src/simulation/navigation/planetNav/_UnitTest/test_planetNav.py index 5b1b509ef..fd3f7689f 100644 --- a/src/simulation/navigation/planetNav/_UnitTest/test_planetNav.py +++ b/src/simulation/navigation/planetNav/_UnitTest/test_planetNav.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import math @@ -280,5 +280,3 @@ def planetNavTestFunction(show_plots): if __name__ == "__main__": test_planetNav(True) - - diff --git a/src/simulation/navigation/planetNav/planetNav.cpp b/src/simulation/navigation/planetNav/planetNav.cpp index 82ead644d..b3e2b2d7f 100644 --- a/src/simulation/navigation/planetNav/planetNav.cpp +++ b/src/simulation/navigation/planetNav/planetNav.cpp @@ -150,4 +150,3 @@ void PlanetNav::updateState(uint64_t currentSimNanos) this->writeOutputMessages(currentSimNanos); this->prevTime = currentSimNanos; } - diff --git a/src/simulation/navigation/planetNav/planetNav.rst b/src/simulation/navigation/planetNav/planetNav.rst index 4a95efb95..dc84ffe4a 100644 --- a/src/simulation/navigation/planetNav/planetNav.rst +++ b/src/simulation/navigation/planetNav/planetNav.rst @@ -23,9 +23,9 @@ The user can set the noise levels of each of these parameters independently. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages @@ -56,4 +56,4 @@ depend on velocity or attitude error should depend on angular velocity. planetNavigation.PMatrix = pMatrix planetNavigation.crossTrans = True planetNavigation.crossAtt = False - scSim.AddModelToTask(simTaskName, planetNavigation) \ No newline at end of file + scSim.AddModelToTask(simTaskName, planetNavigation) diff --git a/src/simulation/navigation/simpleNav/_Documentation/secTest.tex b/src/simulation/navigation/simpleNav/_Documentation/secTest.tex index 512742805..923a89f52 100644 --- a/src/simulation/navigation/simpleNav/_Documentation/secTest.tex +++ b/src/simulation/navigation/simpleNav/_Documentation/secTest.tex @@ -11,19 +11,19 @@ \subsection{Test location} \subsection{Subtests} -\noindent This unit test is designed to functionally test the simulation model -outputs as well as get complete code path coverage. The test design is broken +\noindent This unit test is designed to functionally test the simulation model +outputs as well as get complete code path coverage. The test design is broken up into three main parts:\\ \begin{enumerate} -\item{\underline{Error Bound Enforcement}: The simulation is run for 2.4 hours and the +\item{\underline{Error Bound Enforcement}: The simulation is run for 2.4 hours and the error bounds for all of the signals are tested. This test length is long enough to see both the walk in the signal and the noise, all the while not being so long as to slow down the test. The test ensures that the bounds are crossed no more than 30\% of the time.} -\item{\underline{Error Bound Usage}: The error signals are checked for all of the model - parameters over the course of the simulation to ensure that the error gets +\item{\underline{Error Bound Usage}: The error signals are checked for all of the model + parameters over the course of the simulation to ensure that the error gets to at least 80\% of its maximum error bound at least once, ensuring that noise is indeed properly introduced.} -\item{\underline{Corner Case Check}: The simulation is intentionally given bad inputs to +\item{\underline{Corner Case Check}: The simulation is intentionally given bad inputs to ensure that it alerts the user and does not crash.} \end{enumerate} @@ -47,7 +47,7 @@ \subsection{Test success criteria} \begin{tabular}{|c||c|c|c|c|c|c|} \hline Variable & Position & Velocity & Attitude & Rates & $\Delta$ V & Sun Position \\ \hline \hline -Associated $\sigma$ & 5 (m)& 0.035 (m/s)& $\frac{1}{360}$ (deg) & 0.05 (deg/s) & 1 (deg) & 0.1 (deg) \\ \hline +Associated $\sigma$ & 5 (m)& 0.035 (m/s)& $\frac{1}{360}$ (deg) & 0.05 (deg/s) & 1 (deg) & 0.1 (deg) \\ \hline \end{tabular} \end{table} @@ -58,7 +58,7 @@ \subsection{Test success criteria} \begin{tabular}{|c||c|c|c|c|c|c|} \hline Variable & Position & Velocity & Attitude & Rates & $\Delta$ V & Sun Position \\ \hline \hline -Associated bounds & 1000 (m)& 1 (m/s)& 0.29 (deg) & 1.15 (deg/s) & 5 (deg) & 3.03 (deg) \\ \hline +Associated bounds & 1000 (m)& 1 (m/s)& 0.29 (deg) & 1.15 (deg/s) & 5 (deg) & 3.03 (deg) \\ \hline \end{tabular} \end{table} @@ -81,20 +81,20 @@ \subsection{Pass/Fail} The test results are explained below and summarized in Table~\ref{tab:results}. \begin{enumerate} - \item{Error Bound Enforcement: We only want to violate the error bound a - statistically small number of times as most bounds are specified 3-sigma. + \item{Error Bound Enforcement: We only want to violate the error bound a + statistically small number of times as most bounds are specified 3-sigma. All signals remained inside their bounds more than 1-sigma (~70\%) of the time. } - \item{Error Bound Usage: As stated above, we want to ensure that the random - walk process is effectively utilizing the error bound that it has been - given and not remaining mired near zero. All error signals cross up above + \item{Error Bound Usage: As stated above, we want to ensure that the random + walk process is effectively utilizing the error bound that it has been + given and not remaining mired near zero. All error signals cross up above 80\% of their error bound at least once.} \end{enumerate} -\subsection{Corner case test} +\subsection{Corner case test} Corner Case Usage: All errors/warnings were stimulated and the simulation still ran without incident. The expected error message is not automatically validated within pytest, but the test can not pass -if the corner case test did break the simulation. In that way it is a partially automated test. +if the corner case test did break the simulation. In that way it is a partially automated test. \subsection{Summary of Test Results} @@ -118,14 +118,14 @@ \subsection{Summary of Test Results} \subsection{Test Coverage} -The method coverage for all of the methods included in the simple\_nav +The method coverage for all of the methods included in the simple\_nav module are tabulated in Tables~\ref{tab:cov_met} and \ref{tab:cov_met2}. \begin{table}[htbp] \caption{Simple Navigation Test Analysis Results} \label{tab:cov_met} \centering \fontsize{10}{10}\selectfont - \begin{tabular}{c | r | r | r} % Column formatting, + \begin{tabular}{c | r | r | r} % Column formatting, \hline Method Name & Unit Test Coverage (\%) & Runtime Self (\%) & Runtime Children (\%) \\ \hline @@ -140,7 +140,7 @@ \subsection{Test Coverage} \caption{GaussMarkov Test Analysis Results} \label{tab:cov_met2} \centering \fontsize{10}{10}\selectfont - \begin{tabular}{c | r | r | r} % Column formatting, + \begin{tabular}{c | r | r | r} % Column formatting, \hline Method Name & Unit Test Coverage (\%) & Runtime Self (\%) & Runtime Children (\%) \\ \hline @@ -154,20 +154,18 @@ \subsection{Test Coverage} \hline \end{tabular} \end{table} -For all of the code this test was designed for, the coverage percentage is -100\%. The CPU usage of the model is higher than would be ideal although this -might just be a symptom of the level of simplicity present in the overall -simulation. The majority of the computations are coming from two pieces of the -GaussMarkov code. - -The first is the random number generator. The model is using -one of the simplest random number generators in the standard template library. -That is still a relatively expensive operation as random numbers are costly and -we generate a new random number for each state. The second factor is in the -state and noise propagation. Those are being performed with a matrix -multiplication that is an $n^2$ operation. We could save some computations -here in the future if we took away the cross-correlation capability from some -of the states which would definitely be easy and accurate. It would just take +For all of the code this test was designed for, the coverage percentage is +100\%. The CPU usage of the model is higher than would be ideal although this +might just be a symptom of the level of simplicity present in the overall +simulation. The majority of the computations are coming from two pieces of the +GaussMarkov code. + +The first is the random number generator. The model is using +one of the simplest random number generators in the standard template library. +That is still a relatively expensive operation as random numbers are costly and +we generate a new random number for each state. The second factor is in the +state and noise propagation. Those are being performed with a matrix +multiplication that is an $n^2$ operation. We could save some computations +here in the future if we took away the cross-correlation capability from some +of the states which would definitely be easy and accurate. It would just take some more code. - - diff --git a/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataNodeBase.cpp b/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataNodeBase.cpp index af8206ba4..621a15afa 100644 --- a/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataNodeBase.cpp +++ b/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataNodeBase.cpp @@ -148,5 +148,3 @@ bool DataNodeBase::customReadMessages() { return true; } - - diff --git a/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataStorageUnitBase.cpp b/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataStorageUnitBase.cpp index bfd0b6511..687d7b90f 100644 --- a/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataStorageUnitBase.cpp +++ b/src/simulation/onboardDataHandling/_GeneralModuleFiles/dataStorageUnitBase.cpp @@ -272,7 +272,7 @@ void DataStorageUnitBase::setDataBuffer(std::string partitionName, int64_t data) if ((this->storedData[(size_t) index].dataInstanceSum + data) >= 0) { this->storedData[(size_t) index].dataInstanceSum += data; } - + } //! - if a dataNode does not exist in storedData, add it to storedData, and add amount else if (strcmp(partitionName.c_str(), "") != 0) { diff --git a/src/simulation/onboardDataHandling/instrument/mappingInstrument/_UnitTest/test_mappingInstrument.py b/src/simulation/onboardDataHandling/instrument/mappingInstrument/_UnitTest/test_mappingInstrument.py index d264f814d..175e430f1 100644 --- a/src/simulation/onboardDataHandling/instrument/mappingInstrument/_UnitTest/test_mappingInstrument.py +++ b/src/simulation/onboardDataHandling/instrument/mappingInstrument/_UnitTest/test_mappingInstrument.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2022, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import numpy as np from Basilisk.architecture import messaging @@ -111,5 +111,3 @@ def mappingInstrumentTestFunction(): if __name__ == "__main__": test_mappingInstrument() - - diff --git a/src/simulation/onboardDataHandling/instrument/mappingInstrument/mappingInstrument.rst b/src/simulation/onboardDataHandling/instrument/mappingInstrument/mappingInstrument.rst index 44492d262..7ef2a6feb 100644 --- a/src/simulation/onboardDataHandling/instrument/mappingInstrument/mappingInstrument.rst +++ b/src/simulation/onboardDataHandling/instrument/mappingInstrument/mappingInstrument.rst @@ -11,9 +11,9 @@ are not accessible. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/onboardDataHandling/instrument/simpleInstrument/_UnitTest/test_simpleInstrument.py b/src/simulation/onboardDataHandling/instrument/simpleInstrument/_UnitTest/test_simpleInstrument.py index 9feffd187..da2833804 100644 --- a/src/simulation/onboardDataHandling/instrument/simpleInstrument/_UnitTest/test_simpleInstrument.py +++ b/src/simulation/onboardDataHandling/instrument/simpleInstrument/_UnitTest/test_simpleInstrument.py @@ -172,4 +172,4 @@ def checkStatus(): # if __name__ == "__main__": # checkDefault() - checkStatus() \ No newline at end of file + checkStatus() diff --git a/src/simulation/onboardDataHandling/spaceToGroundTransmitter/_UnitTest/test_spaceToGroundTransmitter.py b/src/simulation/onboardDataHandling/spaceToGroundTransmitter/_UnitTest/test_spaceToGroundTransmitter.py index fdc73eee4..856cba685 100644 --- a/src/simulation/onboardDataHandling/spaceToGroundTransmitter/_UnitTest/test_spaceToGroundTransmitter.py +++ b/src/simulation/onboardDataHandling/spaceToGroundTransmitter/_UnitTest/test_spaceToGroundTransmitter.py @@ -144,4 +144,4 @@ def run(deviceStatus, accessStatus): # stand-alone python script # if __name__ == "__main__": - test_module(False, 1, 1) \ No newline at end of file + test_module(False, 1, 1) diff --git a/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.h b/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.h index c4c1f152c..a036c5595 100644 --- a/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.h +++ b/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.h @@ -39,5 +39,3 @@ class SimpleStorageUnit: public DataStorageUnitBase { }; #endif //BASILISK_SIMPLESTORAGEUNIT_H - - diff --git a/src/simulation/onboardDataHandling/transmitter/_UnitTest/test_simpleTransmitter.py b/src/simulation/onboardDataHandling/transmitter/_UnitTest/test_simpleTransmitter.py index a283df9b7..ee67b2c9c 100644 --- a/src/simulation/onboardDataHandling/transmitter/_UnitTest/test_simpleTransmitter.py +++ b/src/simulation/onboardDataHandling/transmitter/_UnitTest/test_simpleTransmitter.py @@ -209,4 +209,4 @@ def checkStatus(): # if __name__ == "__main__": checkDefault() - checkStatus() \ No newline at end of file + checkStatus() diff --git a/src/simulation/power/_GeneralModuleFiles/powerNodeBase.h b/src/simulation/power/_GeneralModuleFiles/powerNodeBase.h index bbd71a68f..99870e302 100644 --- a/src/simulation/power/_GeneralModuleFiles/powerNodeBase.h +++ b/src/simulation/power/_GeneralModuleFiles/powerNodeBase.h @@ -45,7 +45,7 @@ class PowerNodeBase: public SysModel { protected: void writeMessages(uint64_t CurrentClock); - bool readMessages(); + bool readMessages(); virtual void evaluatePowerModel(PowerNodeUsageMsgPayload *powerUsageMsg)=0; //!< Virtual void method used to compute module-wise power usage/generation. virtual void customreset(uint64_t CurrentClock); //!< Custom Reset method, similar to customSelfInit. virtual void customWriteMessages(uint64_t CurrentClock);//!< custom Write method, similar to customSelfInit. diff --git a/src/simulation/sensors/coarseSunSensor/_Documentation/secUserGuide.tex b/src/simulation/sensors/coarseSunSensor/_Documentation/secUserGuide.tex index 1ef8daa24..eb414f68f 100644 --- a/src/simulation/sensors/coarseSunSensor/_Documentation/secUserGuide.tex +++ b/src/simulation/sensors/coarseSunSensor/_Documentation/secUserGuide.tex @@ -8,27 +8,27 @@ \subsubsection{Direct Method} \begin{equation} {\tt nHat\_B} \equiv \leftexp{B}{\hat{\bm n}} \end{equation} -It is possible to set these vectors directly. However, there are some convenience functions that make this process easier. +It is possible to set these vectors directly. However, there are some convenience functions that make this process easier. \subsubsection{Via a Common Sensor Platform} Multiple CSS devices are often arranged together on a single CSS platform. The orientation of the body-fixed platform frame $\frameDefinition{P}$ relative to the body frame $\frameDefinition{B}$ is given through $[PB]$. In the CSS module, the DCM is specified through the variable {\tt dcm\_PB}. Assume the DCM {\tt dcm\_PB} is set directly via Python. Two angles then define the orientation of the sensor normal axis $\hat{\bm n}$. The elevation angle is $\phi$ and the azimuth angle is $\theta$. These are an Euler angle sequence with the order 3-(-2). The elevation angle is a positive 3-axis rotation, while the azimuth is a minus 2-axis rotation. The helper function $$ -{\tt setUnitDirectionVectorWithPerturbation}(\theta_{p}, \phi_{p}) +{\tt setUnitDirectionVectorWithPerturbation}(\theta_{p}, \phi_{p}) $$ where $\theta_{p}$ and $\phi_{p}$ are CSS heading perturbation can can be specified. The Euler angles implemented are then \begin{align} \phi_{\text{actual}} &= \phi_{\text{true}} + \phi_{p} \\ - \theta_{\text{actual}} &= \theta_{\text{true}} + \theta_{p} + \theta_{\text{actual}} &= \theta_{\text{true}} + \theta_{p} \end{align} -To setup un-perturbed CSS sensor axes simple set these perturbation angles to zero. +To setup un-perturbed CSS sensor axes simple set these perturbation angles to zero. Instead of setting the DCM {\tt dcm\_PB} variable directly, this can also be set via the helper function $$ {\tt setBodyToPlatformDCM}(\psi, \theta, \phi) $$ -where $(\psi, \theta, \phi)$ are classical $3-2-1$ Euler angles that map from the body frame $\cal B$ to the platform frame $\cal P$. +where $(\psi, \theta, \phi)$ are classical $3-2-1$ Euler angles that map from the body frame $\cal B$ to the platform frame $\cal P$. @@ -38,7 +38,7 @@ \subsection{CSS Field-of-View} $$ {\tt fov} $$ -This angle is the angle from the bore-sight axis to the edge of the field of view, and is expressed in terms of radians. +This angle is the angle from the bore-sight axis to the edge of the field of view, and is expressed in terms of radians. It defaults to a value of 60 degrees. @@ -50,14 +50,14 @@ \subsection{CSS Output Scale} $$ {\tt scaleFactor} $$ -is the scale factor $\alpha$ which scales the output to the desired range of values, as well as the desired units. For example, if the maximum sun signal ($\hat{\bm n}$ points directly at sun) should yield 1 mA, then the scale factor is set to this value. +is the scale factor $\alpha$ which scales the output to the desired range of values, as well as the desired units. For example, if the maximum sun signal ($\hat{\bm n}$ points directly at sun) should yield 1 mA, then the scale factor is set to this value. If not set by the user, this parameter has a default value of 1.0. \subsection{Specifying CSS Sensor Noise} -Three types of CSS signal corruptions can be simulated. If not specified, all these corruptions are zeroed. +Three types of CSS signal corruptions can be simulated. If not specified, all these corruptions are zeroed. The Kelly corruption parameter $\kappa$ is set by specifying the variable $$ @@ -68,13 +68,13 @@ \subsection{Specifying CSS Sensor Noise} $$ {\tt SenNoiseStd} $$ -is set to a non-zero value. This is the standard deviation of normalized gaussian noise. Note that this noise magnitude is in terms of normalized units as it is added to the 0-1 nominal signal. +is set to a non-zero value. This is the standard deviation of normalized gaussian noise. Note that this noise magnitude is in terms of normalized units as it is added to the 0-1 nominal signal. Next, to simulate a signal bias, the variable $$ {\tt SenBias} $$ -is set to a non-zero value. This constant bias of the normalized gaussian noise. +is set to a non-zero value. This constant bias of the normalized gaussian noise. Finally, to set saturation values, the variables $$ @@ -86,12 +86,12 @@ \subsection{Specifying CSS Sensor Noise} are used. minOutput is 0 by default and maxOutput is 1,000,000 by default. \subsection{Connecting Messages} -If the {\tt EclipseSimMsg} is connected, then the solar eclipse information is taking into account. The eclipse info provides 0 if the spacecraft is fully in a planet's shadow, 1 if in free space fully exposed to the, and a value between (0,1) if in the penumbra region. The cosine sensor value $\hat\gamma$ is scaled by this eclipse value. If the message is not connected, then this value default to 1, thus simulating a spacecraft that is fully exposed to the sun. +If the {\tt EclipseSimMsg} is connected, then the solar eclipse information is taking into account. The eclipse info provides 0 if the spacecraft is fully in a planet's shadow, 1 if in free space fully exposed to the, and a value between (0,1) if in the penumbra region. The cosine sensor value $\hat\gamma$ is scaled by this eclipse value. If the message is not connected, then this value default to 1, thus simulating a spacecraft that is fully exposed to the sun. If the optional albedo message is connected, then its information is included in the CSS sensor data evaluation. \subsection{Auxiliary Parameters} -The following module variables can be set, but they are not currently used by the CSS module itself. These are used however in the Vizard visualization. +The following module variables can be set, but they are not currently used by the CSS module itself. These are used however in the Vizard visualization. \begin{itemize} \item {\tt r\_B} -- position vector of the sensor relative to the body frame $\cal B$. If not set, this defaults to a zero vector. \item {\tt CSSGroupID} -- positive integer ID number if the CSS unit belongs to a group of CSS units. If not set, this defaults to group 0. @@ -105,9 +105,8 @@ \subsubsection{Individual CSS Units} This setup is convenient if only 1-2 CSS units have to be modeled, but can be cumbersome if a larger cluster of CSS units must be administered. When setup this way, each CSS unit will output an individual CSS output message. \subsubsection{Array or Constellation of CSS Units} -An alternate method to setup a series of CSS units is to use the {\tt CSSConstellation()} class. This class is able to store a series of CSS {\tt CoarseSunSensor} objects, and engage the update routine on all of them at once. This way only the {\tt CSSConstellation} module needs to be added to the BSK update stack. In this method the +An alternate method to setup a series of CSS units is to use the {\tt CSSConstellation()} class. This class is able to store a series of CSS {\tt CoarseSunSensor} objects, and engage the update routine on all of them at once. This way only the {\tt CSSConstellation} module needs to be added to the BSK update stack. In this method the {\tt CSSConstellation} module outputs a single CSS sensor message which contains an array of doubles with the CSS sensor signal. Here the individual CSS units {\tt CSS1}, {\tt CSS2}, etc. are setup and configured first. Next, they are added to the {\tt CSSConstellation} through the python command $$ {\tt cssConstellation.sensorList = coarse\_sun\_sensor.CSSVector([CSS1, CSS2, ..., CSS8])} $$ - diff --git a/src/simulation/sensors/coarseSunSensor/_UnitTest/test_CSSConfig.py b/src/simulation/sensors/coarseSunSensor/_UnitTest/test_CSSConfig.py index 8aedfed6b..5a844a517 100644 --- a/src/simulation/sensors/coarseSunSensor/_UnitTest/test_CSSConfig.py +++ b/src/simulation/sensors/coarseSunSensor/_UnitTest/test_CSSConfig.py @@ -187,4 +187,3 @@ def run(show_plots, accuracy): False, # show_plots 1e-12 # accuracy ) - diff --git a/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensorFaults.py b/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensorFaults.py index 2088ae456..30726b0ca 100644 --- a/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensorFaults.py +++ b/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensorFaults.py @@ -46,11 +46,11 @@ @pytest.mark.parametrize( "cssFault", [ - "CSSFAULT_OFF", - "CSSFAULT_STUCK_CURRENT", - "CSSFAULT_STUCK_MAX", - "CSSFAULT_STUCK_RAND", - "CSSFAULT_RAND", + "CSSFAULT_OFF", + "CSSFAULT_STUCK_CURRENT", + "CSSFAULT_STUCK_MAX", + "CSSFAULT_STUCK_RAND", + "CSSFAULT_RAND", ]) # provide a unique test method name, starting with test_ def test_coarseSunSensor(cssFault): @@ -73,7 +73,7 @@ def run(cssFault): # Create a simulation container unitTestSim = SimulationBaseClass.SimBaseClass() # unitTestSim.RNGSeed = 10 - + # Ensure simulation is empty testProc = unitTestSim.CreateNewProcess(testProcessName) testProc.addTask(unitTestSim.CreateNewTask(testTaskName, testTaskRate)) @@ -138,7 +138,7 @@ def run(cssFault): cssOutput = cssRecoder.OutputData[-1] print(cssOutput) print(truthValue) - + if cssFault == "CSSFAULT_OFF": if not truthValue == cssOutput: testFailCount += 1 diff --git a/src/simulation/sensors/hingedRigidBodyMotorSensor/_UnitTest/test_hingedRigidBodyMotorSensor.py b/src/simulation/sensors/hingedRigidBodyMotorSensor/_UnitTest/test_hingedRigidBodyMotorSensor.py index 525cceddc..0368352d6 100644 --- a/src/simulation/sensors/hingedRigidBodyMotorSensor/_UnitTest/test_hingedRigidBodyMotorSensor.py +++ b/src/simulation/sensors/hingedRigidBodyMotorSensor/_UnitTest/test_hingedRigidBodyMotorSensor.py @@ -1,12 +1,12 @@ -# +# # ISC License -# +# # Copyright (c) 2022, Autonomous Vehicle Systems Lab, University of Colorado 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 @@ -14,8 +14,8 @@ # 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. -# -# +# +# import matplotlib.pyplot as plt import numpy as np @@ -52,7 +52,7 @@ def test_hingedRigidBodyMotorSensor(show_plots, thetaNoiseStd, thetaDotNoiseStd, accuracy (double): absolute accuracy value used in the validation tests **Description of Variables Being Tested** - + The python evaluated sensed value is compared against the module output. """ @@ -66,7 +66,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo testMessages = [] unitTaskName = "unitTask" unitProcessName = "TestProcess" - + timeStep = 0.5 totalTime = 10.0 @@ -82,7 +82,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo # Configure blank module input messages hingedRigidBodyMotorSensorInMsgData = messaging.HingedRigidBodyMsgPayload() - + # set up fake input message hingedRigidBodyMotorSensorInMsgData.theta = trueTheta; hingedRigidBodyMotorSensorInMsgData.thetaDot = trueThetaDot; @@ -95,7 +95,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo # set up output message recorder objects dataLog = module.hingedRigidBodyMotorSensorOutMsg.recorder() unitTestSim.AddModelToTask(unitTaskName, dataLog) - + # set up variables in sensor module.thetaNoiseStd = thetaNoiseStd module.thetaDotNoiseStd = thetaDotNoiseStd @@ -113,11 +113,11 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo # pull module data and make sure it is correct sensedTheta = dataLog.theta[-1] sensedThetaDot = dataLog.thetaDot[-1] - + # add bias to test values biasTheta = trueTheta+thetaBias biasThetaDot = trueThetaDot+thetaDotBias - + # discretize test values if thetaLSB > 0: discTheta = round(biasTheta/thetaLSB)*thetaLSB @@ -127,7 +127,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo discThetaDot = round(biasThetaDot/thetaDotLSB)*thetaDotLSB else: discThetaDot = biasThetaDot - + print(sensedTheta) print(sensedThetaDot) print(trueTheta) @@ -141,7 +141,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo if not unitTestSupport.isDoubleEqual(sensedThetaDot, discThetaDot, accuracy): testMessages.append("Failed thetaDot bias.") testFailCount += 1 - + # check discretization if abs(thetaLSB) > accuracy: if not unitTestSupport.isDoubleEqual(sensedTheta, discTheta, accuracy): @@ -155,7 +155,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo print("PASSED: " + module.modelTag) else: print(testMessages) - + if show_plots: thetaVals = trueTheta*np.ones(int(totalTime/timeStep)+1) thetaDotVals = trueThetaDot*np.ones(int(totalTime/timeStep)+1) @@ -181,7 +181,7 @@ def hingedRigidBodyMotorSensorTestFunction(show_plots, thetaNoiseStd, thetaDotNo plt.close("all") return [testFailCount, "".join(testMessages)] - + if __name__ == "__main__": test_hingedRigidBodyMotorSensor( diff --git a/src/simulation/sensors/hingedRigidBodyMotorSensor/hingedRigidBodyMotorSensor.rst b/src/simulation/sensors/hingedRigidBodyMotorSensor/hingedRigidBodyMotorSensor.rst index 6d9a2ab57..a73ec54e2 100644 --- a/src/simulation/sensors/hingedRigidBodyMotorSensor/hingedRigidBodyMotorSensor.rst +++ b/src/simulation/sensors/hingedRigidBodyMotorSensor/hingedRigidBodyMotorSensor.rst @@ -6,9 +6,9 @@ measured state. Message Connection Descriptions ------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description provides information on what this message is used for. .. list-table:: Module I/O Messages diff --git a/src/simulation/sensors/imuSensor/_Documentation/BasiliskCorruptions.tex b/src/simulation/sensors/imuSensor/_Documentation/BasiliskCorruptions.tex index ca5a586bb..9c819682a 100644 --- a/src/simulation/sensors/imuSensor/_Documentation/BasiliskCorruptions.tex +++ b/src/simulation/sensors/imuSensor/_Documentation/BasiliskCorruptions.tex @@ -122,7 +122,7 @@ \section{Desired Corruptions} \begin{enumerate} \item Max \item Min - \end{enumerate} + \end{enumerate} \item Discretization \begin{enumerate} \item Max/min only = 2 bit diff --git a/src/simulation/sensors/simpleMassProps/simpleMassProps.h b/src/simulation/sensors/simpleMassProps/simpleMassProps.h index 1b98aad9f..39e5b4273 100644 --- a/src/simulation/sensors/simpleMassProps/simpleMassProps.h +++ b/src/simulation/sensors/simpleMassProps/simpleMassProps.h @@ -43,7 +43,7 @@ class SimpleMassProps: public SysModel { ReadFunctor scMassPropsInMsg; //!< sc mass properties input msg Message vehicleConfigOutMsg; //!< vehicle configuration output msg - + BSKLogger bskLogger; //!< -- BSK Logging diff --git a/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.h b/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.h index f44a8c749..46b7988bc 100755 --- a/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.h +++ b/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.h @@ -49,7 +49,7 @@ class SimpleVoltEstimator: public SysModel { VoltMsgPayload trueVoltState; //!< -- voltage state without errors VoltMsgPayload estVoltState; //!< -- voltage state including errors BSKLogger bskLogger; //!< -- BSK Logging - + ReadFunctor voltInMsg; //!< voltage input msg private: diff --git a/src/simulation/simSynch/simSynch.cpp b/src/simulation/simSynch/simSynch.cpp index 4c9e3633e..1056354c4 100644 --- a/src/simulation/simSynch/simSynch.cpp +++ b/src/simulation/simSynch/simSynch.cpp @@ -54,9 +54,9 @@ void ClockSynch::reset(uint64_t currentSimNanos) /*! This method performs all of the runtime behavior for the clock synch model. - It initializes the timers present in the model on the first pass and then - ensures that the model stays stuck on the synchronization pulse. Note that we - do the init on the first pass instead of the init routines so that we don't + It initializes the timers present in the model on the first pass and then + ensures that the model stays stuck on the synchronization pulse. Note that we + do the init on the first pass instead of the init routines so that we don't have a big lag between initialization and runtime which messes up our clocking. @return void @param currentSimNanos The clock time associated with the model call @@ -76,23 +76,23 @@ void ClockSynch::updateState(uint64_t currentSimNanos) this->startSimTimeNano = currentSimNanos; this->timeInitialized = true; } - + //! - Compute the number of nanoseconds that have elapsed in the simulation simTimeNano = (int64_t) ((currentSimNanos - this->startSimTimeNano)/this->accelFactor); - + //! - Compute the current time and get the actually elapsed nanoseconds since init time currentTime = std::chrono::high_resolution_clock::now(); realTimeNano = (int64_t) (std::chrono::duration_cast(currentTime - this->startTime)).count(); - + //! - Save off the observed time-delta for analysis and flag any unexpected overruns initTimeDeltaNano = simTimeNano - realTimeNano; - + if(initTimeDeltaNano < -this->accuracyNanos) { this->outputData.overrunCounter++; } this->outputData.initTimeDelta = initTimeDeltaNano * NANO2SEC; - + /*! - Loop behavior is fairly straightforward. While we haven't reached the specified accuracy: -# Compute the current time -# Determine how many nanoseconds are left in our synch frame @@ -108,11 +108,11 @@ void ClockSynch::updateState(uint64_t currentSimNanos) sleepAmountNano = (simTimeNano - realTimeNano) / (2); std::this_thread::sleep_for(std::chrono::nanoseconds(sleepAmountNano)); } - + //! - Save off the output message information for analysis this->outputData.finalTimeDelta = (double) (simTimeNano - realTimeNano - sleepAmountNano); this->outputData.finalTimeDelta *= NANO2SEC; - + //! - Write the composite information into the output synch message. this->clockOutMsg.write(&this->outputData, this->moduleID, currentSimNanos); diff --git a/src/simulation/simSynch/simSynch.h b/src/simulation/simSynch/simSynch.h index 05d942a57..81cc07a42 100755 --- a/src/simulation/simSynch/simSynch.h +++ b/src/simulation/simSynch/simSynch.h @@ -35,10 +35,10 @@ class ClockSynch: public SysModel { public: ClockSynch(); ~ClockSynch(); - + void reset(uint64_t currentSimNanos); void updateState(uint64_t currentSimNanos); - + public: double accelFactor; //!< [-] Factor used to accelerate sim-time relative to clock SynchClockMsgPayload outputData; //!< [-] Output data for the synch module @@ -50,7 +50,7 @@ class ClockSynch: public SysModel { private: bool timeInitialized; //!< [-] Flag that the module has been reset std::chrono::high_resolution_clock::time_point startTime; //! [-] first time stamp of pass through data - uint64_t startSimTimeNano; //!< [ns] Previous simulation time observed + uint64_t startSimTimeNano; //!< [ns] Previous simulation time observed }; diff --git a/src/simulation/thermal/motorThermal/motorThermal.rst b/src/simulation/thermal/motorThermal/motorThermal.rst index 67bd03ec1..efe8f1b17 100644 --- a/src/simulation/thermal/motorThermal/motorThermal.rst +++ b/src/simulation/thermal/motorThermal/motorThermal.rst @@ -1,7 +1,7 @@ Executive Summary ----------------- -Module that computes the motor temperature. It takes into account mechanical power efficiency, as well as friction, +Module that computes the motor temperature. It takes into account mechanical power efficiency, as well as friction, as sources of heat. There is also a dissipative term due to the temperature gradient between the motor and the air surrounding it. @@ -36,7 +36,7 @@ power :math:`P_{mec}` is given by: .. math:: P_{mec}=\Omega \times u_s -where :math:`\Omega` is the motor angular velocity and :math:`u_s` represents the applied torque. Given the mechanical efficiency :math:`\eta`, we can convert +where :math:`\Omega` is the motor angular velocity and :math:`u_s` represents the applied torque. Given the mechanical efficiency :math:`\eta`, we can convert mechanical power into thermal power as follows: .. math:: @@ -48,7 +48,7 @@ Similarly to the mechanical power, the friction dissipation is given by: P_{f}=\Omega \times \tau_f where :math:`\tau_f` represents the friction torque. The absolute value of these two terms added together represents the thermal power generation. As for the power -dissipation, we assume a temperature gradient between the motor and the surrounding environment. For simplicity, a constant ambient temperature is considered. The +dissipation, we assume a temperature gradient between the motor and the surrounding environment. For simplicity, a constant ambient temperature is considered. The thermal power dissipation is calculated using the temperature difference between the motor and the environment, scaled by the ambient's thermal resistance :math:`R_{ambient}`: .. math:: @@ -128,4 +128,4 @@ A sample setup is done using: thermalModel.ambientTemperature = 20 # [Celsius] thermalModel.efficiency = 0.7 thermalModel.ambientThermalResistance = 5 # Air Thermal Resistance - thermalModel.motorHeatCapacity = 50 # Motor Heat Capacity \ No newline at end of file + thermalModel.motorHeatCapacity = 50 # Motor Heat Capacity diff --git a/src/simulation/thermal/sensorThermal/sensorThermal.rst b/src/simulation/thermal/sensorThermal/sensorThermal.rst index 1fcfd2eec..ef6096a93 100644 --- a/src/simulation/thermal/sensorThermal/sensorThermal.rst +++ b/src/simulation/thermal/sensorThermal/sensorThermal.rst @@ -160,4 +160,4 @@ The relevant messages are then connected to the module: sensorThermalModel.sunInMsg.subscribeTo(sunMsg) sensorThermalModel.stateInMsg.subscribeTo(scStateMsg) sensorThermalModel.sensorStatusInMsg.subscribeTo(sensorStatusMsg) - unitTestSim.AddModelToTask(unitTaskName, sensorThermalModel) \ No newline at end of file + unitTestSim.AddModelToTask(unitTaskName, sensorThermalModel) diff --git a/src/simulation/vizard/_GeneralModuleFiles/vizStructures.h b/src/simulation/vizard/_GeneralModuleFiles/vizStructures.h index 151c2b09e..3d7478d7b 100644 --- a/src/simulation/vizard/_GeneralModuleFiles/vizStructures.h +++ b/src/simulation/vizard/_GeneralModuleFiles/vizStructures.h @@ -324,9 +324,9 @@ VizSpacecraftData std::vector genericSensorList; //!< [-] (Optional) Vector of generic sensor configuration info std::vector transceiverList; //!< [-] (Optional) Vector of transceiver configuration info - + std::vector genericStorageList; //!< [-] (Optional) Vector of generic storage configuration info - + std::vector lightList; //!<[-] (Optional) Vector of spacecraft light devices std::string spacecraftSprite = ""; //!< Set sprite for this spacecraft only through shape name and optional int RGB color values [0,255] Possible settings: "CIRCLE","SQUARE", "STAR", "TRIANGLE" or "bskSat" for a 2D spacecraft sprite of the bskSat shape diff --git a/src/simulation/vizard/dataFileToViz/_UnitTest/test_dataFileToViz.py b/src/simulation/vizard/dataFileToViz/_UnitTest/test_dataFileToViz.py index 9c599f290..f92e84042 100644 --- a/src/simulation/vizard/dataFileToViz/_UnitTest/test_dataFileToViz.py +++ b/src/simulation/vizard/dataFileToViz/_UnitTest/test_dataFileToViz.py @@ -347,7 +347,7 @@ def run(show_plots, convertPosUnits, attType, checkThruster, checkRW, verbose): # Need to call the self-init and cross-init methods unitTestSim.InitializeSimulation() - unitTestSim.ConfigureStopTime(simulationTime) + unitTestSim.ConfigureStopTime(simulationTime) # Begin the simulation time run set above unitTestSim.ExecuteSimulation() @@ -458,4 +458,3 @@ def run(show_plots, convertPosUnits, attType, checkThruster, checkRW, verbose): ) if os.path.exists(dataFileName): os.remove(dataFileName) - diff --git a/src/simulation/vizard/dataFileToViz/dataFileToViz.h b/src/simulation/vizard/dataFileToViz/dataFileToViz.h index 83fa1917e..a5b999484 100755 --- a/src/simulation/vizard/dataFileToViz/dataFileToViz.h +++ b/src/simulation/vizard/dataFileToViz/dataFileToViz.h @@ -1,10 +1,10 @@ /* Copyright (c) 2016, Autonomous Vehicle Systems Lab, Univeristy 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 @@ -12,7 +12,7 @@ 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. - + */ diff --git a/src/simulation/vizard/dataFileToViz/dataFileToViz.rst b/src/simulation/vizard/dataFileToViz/dataFileToViz.rst index fb7f7512c..14a204b4f 100644 --- a/src/simulation/vizard/dataFileToViz/dataFileToViz.rst +++ b/src/simulation/vizard/dataFileToViz/dataFileToViz.rst @@ -134,4 +134,3 @@ Next, the RW position, spin axis direction, the wheel speed and the maximum moto testModule.appendUMax(0.5) Repeat the above steps for each wheel. - diff --git a/src/simulation/vizard/vizInterface/vizInterface.h b/src/simulation/vizard/vizInterface/vizInterface.h index d073dab62..686e56109 100755 --- a/src/simulation/vizard/vizInterface/vizInterface.h +++ b/src/simulation/vizard/vizInterface/vizInterface.h @@ -1,10 +1,10 @@ /* Copyright (c) 2016, Autonomous Vehicle Systems Lab, Univeristy 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 @@ -12,7 +12,7 @@ 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. - + */ @@ -70,7 +70,7 @@ class VizInterface : public SysModel { std::vector> cameraConfInMsgs; //!< [-] vector of incoming camera data messages std::vector cameraConfMsgStatus; //!< [-] vector of msg status of incoming camera data std::vector cameraConfigBuffers; //!< [-] vector of Camera config buffers - + int64_t FrameNumber; //!< Number of frames that have been updated for TimeStamp message std::string protoFilename; //!< Filename for where to save the protobuff message VizSettings settings; //!< [-] container for the Viz settings that can be specified from BSK @@ -79,7 +79,7 @@ class VizInterface : public SysModel { std::string comProtocol; //!< Communication protocol to use when connecting to Vizard std::string comAddress; //!< Communication address to use when connecting to Vizard std::string comPortNumber; //!< Communication port number to use when connecting to Vizard - + ReadFunctor epochInMsg; //!< [-] simulation epoch date/time input msg MsgCurrStatus epochMsgStatus; //!< [-] ID of the epoch msg EpochMsgPayload epochMsgBuffer; //!< [-] epoch msg data diff --git a/src/utilities/simIncludeGravBody.py b/src/utilities/simIncludeGravBody.py index e5d3fce22..6753e08f0 100644 --- a/src/utilities/simIncludeGravBody.py +++ b/src/utilities/simIncludeGravBody.py @@ -441,7 +441,7 @@ def createSpiceInterface( raise ValueError( "'time' argument must be provided and a valid SPICE time string" ) - + if spiceKernalFileNames is not None: spiceKernelFileNames = spiceKernalFileNames deprecationWarn(