From 50a38074004f0c98115506b8ddccfd465e54248f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Vaz=20Carneiro?= Date: Tue, 31 Oct 2023 13:03:51 -0600 Subject: [PATCH 1/4] Introduce new field to scStatesMsgPayload The new field corresponds to the accumulated delta-v of the center of mass of the spacecraft in the inertial frame. --- src/architecture/msgPayloadDefC/SCStatesMsgPayload.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/architecture/msgPayloadDefC/SCStatesMsgPayload.h b/src/architecture/msgPayloadDefC/SCStatesMsgPayload.h index bc2eb6b788..4d4005b274 100755 --- a/src/architecture/msgPayloadDefC/SCStatesMsgPayload.h +++ b/src/architecture/msgPayloadDefC/SCStatesMsgPayload.h @@ -33,6 +33,7 @@ typedef struct { double omegaDot_BN_B[3]; //!< r/s/s Current angular acceleration double TotalAccumDVBdy[3]; //!< m/s Accumulated DV of center of mass in body frame coordinates double TotalAccumDV_BN_B[3]; //!< m/s Accumulated DV of body frame in body frame coordinates + double TotalAccumDV_CN_N[3]; //!< m/s Accumulated DV of center of mass in inertial frame coordinates double nonConservativeAccelpntB_B[3];//!< m/s/s Current Spacecraft non-conservative body frame accel uint64_t MRPSwitchCount; //!< -- Number of times that MRPs have switched }SCStatesMsgPayload; From 05251a8c426ae656cef6398c9ccc3c6e8113291e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Vaz=20Carneiro?= Date: Tue, 31 Oct 2023 13:04:51 -0600 Subject: [PATCH 2/4] Add the new field to the spacecraft module --- src/simulation/dynamics/spacecraft/spacecraft.cpp | 5 +++++ src/simulation/dynamics/spacecraft/spacecraft.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/simulation/dynamics/spacecraft/spacecraft.cpp b/src/simulation/dynamics/spacecraft/spacecraft.cpp index 39149fb95a..fd9f905cce 100755 --- a/src/simulation/dynamics/spacecraft/spacecraft.cpp +++ b/src/simulation/dynamics/spacecraft/spacecraft.cpp @@ -37,6 +37,7 @@ Spacecraft::Spacecraft() this->simTimePrevious = 0; this->dvAccum_CN_B.setZero(); this->dvAccum_BN_B.setZero(); + this->dvAccum_CN_N.setZero(); // - Set integrator as RK4 by default this->integrator = new svIntegratorRK4(this); @@ -101,6 +102,7 @@ void Spacecraft::writeOutputStateMessages(uint64_t clockTime) eigenMatrixXd2CArray(this->dvAccum_CN_B, stateOut.TotalAccumDVBdy); stateOut.MRPSwitchCount = this->hub.MRPSwitchCount; eigenMatrixXd2CArray(this->dvAccum_BN_B, stateOut.TotalAccumDV_BN_B); + eigenMatrixXd2CArray(this->dvAccum_CN_N, stateOut.TotalAccumDV_CN_N); eigenVector3d2CArray(this->nonConservativeAccelpntB_B, stateOut.nonConservativeAccelpntB_B); eigenVector3d2CArray(this->omegaDot_BN_B, stateOut.omegaDot_BN_B); this->scStateOutMsg.write(&stateOut, this->moduleID, clockTime); @@ -487,6 +489,9 @@ void Spacecraft::postIntegration(double integrateToThisTime) { this->dvAccum_BN_B += newDcm_NB.transpose()*(newV_BN_N - this->hubGravVelocity->getState()); + // - Find the accumulated DV of the center of mass in the inertial frame + this->dvAccum_CN_N += newV_CN_N - this->BcGravVelocity->getState(); + // - non-conservative acceleration of the body frame in the body frame this->nonConservativeAccelpntB_B = (newDcm_NB.transpose()*(newV_BN_N - this->hubGravVelocity->getState()))/this->timeStep; diff --git a/src/simulation/dynamics/spacecraft/spacecraft.h b/src/simulation/dynamics/spacecraft/spacecraft.h index 647c03e179..453312486c 100755 --- a/src/simulation/dynamics/spacecraft/spacecraft.h +++ b/src/simulation/dynamics/spacecraft/spacecraft.h @@ -61,6 +61,7 @@ class Spacecraft : public DynamicObject{ 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 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 Eigen::Vector3d totOrbAngMomPntN_N; //!< [kg m^2/s] Total orbital angular momentum about N in N frame compenents From e69fd61443fd18fa7a01aa2c000facd0b9a99b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Vaz=20Carneiro?= Date: Tue, 31 Oct 2023 13:05:02 -0600 Subject: [PATCH 3/4] Add an external force test to make sure accumulated dv is correct --- .../spacecraft/_UnitTest/test_spacecraft.py | 79 ++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/src/simulation/dynamics/spacecraft/_UnitTest/test_spacecraft.py b/src/simulation/dynamics/spacecraft/_UnitTest/test_spacecraft.py index 7133861398..11e97169ea 100644 --- a/src/simulation/dynamics/spacecraft/_UnitTest/test_spacecraft.py +++ b/src/simulation/dynamics/spacecraft/_UnitTest/test_spacecraft.py @@ -21,6 +21,7 @@ import numpy import pytest +from random import random filename = inspect.getframeinfo(inspect.currentframe()).filename path = os.path.dirname(os.path.abspath(filename)) @@ -54,12 +55,13 @@ def addTimeColumn(time, data): , "SCPointBVsPointC" , "scOptionalRef" , "scAccumDV" + , "scAccumDVExtForce" ]) def test_spacecraftAllTest(show_plots, function): """Module Unit Test""" if function == "scOptionalRef": [testResults, testMessage] = eval(function + '(show_plots, 1e-3)') - elif function == "scAccumDV": + elif function == "scAccumDV" or function == "scAccumDVExtForce": [testResults, testMessage] = eval(function + '()') else: [testResults, testMessage] = eval(function + '(show_plots)') @@ -1073,9 +1075,11 @@ def scAccumDV(): dataAccumDV_CN_B = dataLog.TotalAccumDVBdy dataAccumDV_BN_B = dataLog.TotalAccumDV_BN_B + dataAccumDV_CN_N = dataLog.TotalAccumDV_CN_N accuracy = 1e-10 truth_dataAccumDV_CN_B = [0.0, 0.0, 0.0] + truth_dataAccumDV_CN_N = [0.0, 0.0, 0.0] v_r = numpy.cross(numpy.array(scObject.hub.omega_BN_BInit).T, -numpy.array(scObject.hub.r_BcB_B).T)[0] truth_dataAccumDV_BN_B = numpy.zeros(3) for i in range(len(dataLog.times())-1): @@ -1090,11 +1094,80 @@ def scAccumDV(): testFailCount += 1 testMessages.append("FAILED: Spacecraft Point B Accumulated DV test failed pos unit test") + if not unitTestSupport.isArrayEqual(dataAccumDV_CN_N[i+1],truth_dataAccumDV_CN_N,3,accuracy): + testFailCount += 1 + testMessages.append("FAILED: Spacecraft Point C Accumulated DV in inertial frame test failed pos unit test") + + if testFailCount == 0: + print("PASSED: Spacecraft Accumulated DV tests with offset CoM") + + return [testFailCount, ''.join(testMessages)] + + +def scAccumDVExtForce(): + """Module Unit Test""" + # The __tracebackhide__ setting influences pytest showing of tracebacks: + # the mrp_steering_tracking() function will not be shown unless the + # --fulltrace command line option is specified. + __tracebackhide__ = True + + 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 + timeStep = 0.1 + testProcessRate = macros.sec2nano(timeStep) # update process rate update time + testProc = unitTestSim.CreateNewProcess(unitProcessName) + testProc.addTask(unitTestSim.CreateNewTask(unitTaskName, testProcessRate)) + + # Add test module to runtime call list + unitTestSim.AddModelToTask(unitTaskName, scObject) + + # Add external force and torque + extFTObject = extForceTorque.ExtForceTorque() + extFTObject.ModelTag = "externalDisturbance" + extFTObject.extTorquePntB_B = [[0], [0], [0]] + extForce = numpy.array([random() for _ in range(3)]) + extFTObject.extForce_B = [[item] for item in extForce] + scObject.addDynamicEffector(extFTObject) + unitTestSim.AddModelToTask(unitTaskName, extFTObject) + + # Define initial conditions of the spacecraft + scObject.hub.mHub = 100 + + dataLog = scObject.scStateOutMsg.recorder() + unitTestSim.AddModelToTask(unitTaskName, dataLog) + + unitTestSim.InitializeSimulation() + stopTime = 0.5 + unitTestSim.ConfigureStopTime(macros.sec2nano(stopTime)) + unitTestSim.ExecuteSimulation() + + dataAccumDV_CN_N = dataLog.TotalAccumDV_CN_N + timeArraySec = dataLog.times() * macros.NANO2SEC + + accuracy = 1e-10 + for i in range(len(dataLog.times())): + truth_dataAccumDV_CN_N = extForce * timeArraySec[i] / scObject.hub.mHub + if not unitTestSupport.isArrayEqual(dataAccumDV_CN_N[i], truth_dataAccumDV_CN_N, 3, accuracy): + testFailCount += 1 + testMessages.append("FAILED: Spacecraft Point C Accumulated DV with external force test failed unit test") + if testFailCount == 0: print("PASSED: Spacecraft Accumulated DV tests with offset CoM") return [testFailCount, ''.join(testMessages)] + if __name__ == "__main__": # scAttRef(True, 1e-3) # SCTranslation(True) @@ -1102,4 +1175,6 @@ def scAccumDV(): # SCRotation(True) # SCTransBOE(True) # SCPointBVsPointC(True) - scOptionalRef(True, 0.001) \ No newline at end of file + # scOptionalRef(True, 0.001) + # scAccumDV() + scAccumDVExtForce() From 25859107be12c3a8c92a3afe2bea8d31017a903b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Vaz=20Carneiro?= Date: Wed, 29 Nov 2023 10:01:31 -0700 Subject: [PATCH 4/4] Update release notes --- docs/source/Support/bskReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/Support/bskReleaseNotes.rst b/docs/source/Support/bskReleaseNotes.rst index a7b02165d1..e82cf0b57e 100644 --- a/docs/source/Support/bskReleaseNotes.rst +++ b/docs/source/Support/bskReleaseNotes.rst @@ -55,6 +55,8 @@ Version |release| - Implemented new syntax for variable logging. See :ref:`bskPrinciples-6`. - Basilisk minimum Python version is now formally 3.8.x (checked by build files). Previously, it was indicated to be 3.7.x yet in practice it was 3.8.x. +- Added a ``TotalAccumDV_CN_N`` field in :ref:`SCStatesMsgPayload` that saves the total accumulated velocity of the + spacecraft's center of mass in the inertial frame. .. warning::