Source code for test_smallBodyWaypointFeedback

# 
#  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
#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# 
# 

import numpy as np
from Basilisk.architecture import messaging
from Basilisk.fswAlgorithms import smallBodyWaypointFeedback
from Basilisk.simulation import planetEphemeris
from Basilisk.utilities import SimulationBaseClass
from Basilisk.utilities import macros
from Basilisk.utilities import orbitalMotion
from Basilisk.utilities import unitTestSupport


# @pytest.mark.parametrize("accuracy", [1e-12])
# @pytest.mark.parametrize("param1, param2", [
#      (1, 1)
#     ,(1, 3)
# ])

[docs]def test_smallBodyWaypointFeedback(show_plots): r""" **Validation Test Description** This test checks two things: a large force output when the spacecraft is far from the waypoint, and a small force output when the spacecraft is at the waypoint. **Test Parameters** Args: :param show_plots: flag if plots should be shown. **Description of Variables Being Tested** In this test, the ``forceRequestBody`` variable in the :ref:`CmdForceBodyMsgPayload` output by the module is tested. When far away from the waypoint, the force request should be larger than 1 N. When close to the waypoint, the force request should only account for third body perturbations and SRP. """ [testResults1, testMessages1] = smallBodyWaypointFeedbackTestFunction1() [testResults2, testMessages2] = smallBodyWaypointFeedbackTestFunction2() assert (testResults1 + testResults2) < 1, [testMessages1, testMessages2]
[docs]def smallBodyWaypointFeedbackTestFunction1(): """This test checks for a large force return when far away from the waypoint""" testFailCount = 0 testMessages = [] unitTaskName = "unitTask" unitProcessName = "TestProcess" unitTestSim = SimulationBaseClass.SimBaseClass() testProcessRate = macros.sec2nano(0.5) testProc = unitTestSim.CreateNewProcess(unitProcessName) testProc.addTask(unitTestSim.CreateNewTask(unitTaskName, testProcessRate)) # setup module to be tested module = smallBodyWaypointFeedback.SmallBodyWaypointFeedback() module.ModelTag = "smallBodyWaypointFeedback1" unitTestSim.AddModelToTask(unitTaskName, module) module.A_sc = 1. # Surface area of the spacecraft, m^2 module.M_sc = 300 # Mass of the spacecraft, kg module.IHubPntC_B = unitTestSupport.np2EigenMatrix3d([82.12, 0.0, 0.0, 0.0, 98.40, 0.0, 0.0, 0.0, 121.0]) # sc inertia module.mu_ast = 4.892 # Gravitational constant of the asteroid module.x1_ref = [-2000., 0., 0.] module.x2_ref = [0.0, 0.0, 0.0] module.K1 = unitTestSupport.np2EigenMatrix3d([5e-4, 0e-5, 0e-5, 0e-5, 5e-4, 0e-5, 0e-5, 0e-5, 5e-4]) module.K2 = unitTestSupport.np2EigenMatrix3d([1., 0., 0., 0., 1., 0., 0., 0., 1.]) # Set the orbital parameters of the asteroid oeAsteroid = planetEphemeris.ClassicElementsMsgPayload() oeAsteroid.a = 1.1259 * orbitalMotion.AU * 1000 # meters oeAsteroid.e = 0.20373 oeAsteroid.i = 6.0343 * macros.D2R oeAsteroid.Omega = 2.01820 * macros.D2R oeAsteroid.omega = 66.304 * macros.D2R oeAsteroid.f = 346.32 * macros.D2R r_ON_N, v_ON_N = orbitalMotion.elem2rv(orbitalMotion.MU_SUN*(1000.**3), oeAsteroid) # Create the position and velocity of states of the s/c wrt the small body hill frame origin r_BO_N = np.array([-2000., 1500., 1000.]) # Position of the spacecraft relative to the body v_BO_N = np.array([0., 0., 0.]) # Velocity of the spacecraft relative to the body # Create the inertial position and velocity of the s/c r_BN_N = np.add(r_BO_N, r_ON_N) v_BN_N = np.add(v_BO_N, v_ON_N) # Configure blank module input messages asteroidEphemerisInMsgData = messaging.EphemerisMsgPayload() asteroidEphemerisInMsgData.r_BdyZero_N = r_ON_N asteroidEphemerisInMsgData.v_BdyZero_N = v_ON_N asteroidEphemerisInMsg = messaging.EphemerisMsg().write(asteroidEphemerisInMsgData) navTransInMsgData = messaging.NavTransMsgPayload() navTransInMsgData.r_BN_N = r_BN_N navTransInMsgData.v_BN_N = v_BN_N navTransInMsg = messaging.NavTransMsg().write(navTransInMsgData) navAttInMsgData = messaging.NavAttMsgPayload() navAttInMsgData.sigma_BN = np.array([0.1, 0.0, 0.0]) navAttInMsg = messaging.NavAttMsg().write(navAttInMsgData) sunEphemerisInMsgData = messaging.EphemerisMsgPayload() sunEphemerisInMsg = messaging.EphemerisMsg().write(sunEphemerisInMsgData) # subscribe input messages to module module.navTransInMsg.subscribeTo(navTransInMsg) module.navAttInMsg.subscribeTo(navAttInMsg) module.asteroidEphemerisInMsg.subscribeTo(asteroidEphemerisInMsg) module.sunEphemerisInMsg.subscribeTo(sunEphemerisInMsg) # setup output message recorder objects forceOutMsgRec = module.forceOutMsg.recorder() unitTestSim.AddModelToTask(unitTaskName, forceOutMsgRec) unitTestSim.InitializeSimulation() unitTestSim.ConfigureStopTime(macros.sec2nano(0.)) unitTestSim.ExecuteSimulation() if np.linalg.norm(forceOutMsgRec.forceRequestBody) <= 1: testFailCount += 1 testMessages.append("FAILED: " + module.ModelTag + " Module failed " + "force output" + " unit test") if testFailCount == 0: print("PASSED: " + module.ModelTag) else: print(testMessages) return [testFailCount, "".join(testMessages)]
[docs]def smallBodyWaypointFeedbackTestFunction2(): """This test checks that the force output is near zero when at the waypoint""" testFailCount = 0 testMessages = [] unitTaskName = "unitTask" unitProcessName = "TestProcess" unitTestSim = SimulationBaseClass.SimBaseClass() testProcessRate = macros.sec2nano(0.5) testProc = unitTestSim.CreateNewProcess(unitProcessName) testProc.addTask(unitTestSim.CreateNewTask(unitTaskName, testProcessRate)) # setup module to be tested module = smallBodyWaypointFeedback.SmallBodyWaypointFeedback() module.ModelTag = "smallBodyWaypointFeedback2" unitTestSim.AddModelToTask(unitTaskName, module) module.A_sc = 1. # Surface area of the spacecraft, m^2 module.M_sc = 300 # Mass of the spacecraft, kg module.IHubPntC_B = unitTestSupport.np2EigenMatrix3d([82.12, 0.0, 0.0, 0.0, 98.40, 0.0, 0.0, 0.0, 121.0]) # sc inertia module.mu_ast = 4.892 # Gravitational constant of the asteroid module.x1_ref = [-2000., 0., 0.] module.x2_ref = [0.0, 0.0, 0.0] module.K1 = unitTestSupport.np2EigenMatrix3d([5e-4, 0e-5, 0e-5, 0e-5, 5e-4, 0e-5, 0e-5, 0e-5, 5e-4]) module.K2 = unitTestSupport.np2EigenMatrix3d([1., 0., 0., 0., 1., 0., 0., 0., 1.]) # Set the orbital parameters of the asteroid oeAsteroid = planetEphemeris.ClassicElementsMsgPayload() oeAsteroid.a = 1.1259 * orbitalMotion.AU * 1000 # meters oeAsteroid.e = 0.20373 oeAsteroid.i = 6.0343 * macros.D2R oeAsteroid.Omega = 2.01820 * macros.D2R oeAsteroid.omega = 66.304 * macros.D2R oeAsteroid.f = 346.32 * macros.D2R r_ON_N, v_ON_N = orbitalMotion.elem2rv(orbitalMotion.MU_SUN*(1000.**3), oeAsteroid) # Create the position and velocity of states of the s/c wrt the small body hill frame r_BO_H = np.array([-2000., 0., 0.]) # Position of the spacecraft relative to the body v_BO_H = np.array([0., 0., 0.]) # Velocity of the spacecraft relative to the body r_BN_N, v_BN_N = orbitalMotion.hill2rv(r_ON_N, v_ON_N, r_BO_H, v_BO_H) # Configure blank module input messages asteroidEphemerisInMsgData = messaging.EphemerisMsgPayload() asteroidEphemerisInMsgData.r_BdyZero_N = r_ON_N asteroidEphemerisInMsgData.v_BdyZero_N = v_ON_N asteroidEphemerisInMsg = messaging.EphemerisMsg().write(asteroidEphemerisInMsgData) navTransInMsgData = messaging.NavTransMsgPayload() navTransInMsgData.r_BN_N = r_BN_N navTransInMsgData.v_BN_N = v_BN_N navTransInMsg = messaging.NavTransMsg().write(navTransInMsgData) navAttInMsgData = messaging.NavAttMsgPayload() navAttInMsgData.sigma_BN = np.array([0.1, 0.0, 0.0]) navAttInMsg = messaging.NavAttMsg().write(navAttInMsgData) sunEphemerisInMsgData = messaging.EphemerisMsgPayload() sunEphemerisInMsg = messaging.EphemerisMsg().write(sunEphemerisInMsgData) # subscribe input messages to module module.navTransInMsg.subscribeTo(navTransInMsg) module.navAttInMsg.subscribeTo(navAttInMsg) module.asteroidEphemerisInMsg.subscribeTo(asteroidEphemerisInMsg) module.sunEphemerisInMsg.subscribeTo(sunEphemerisInMsg) # setup output message recorder objects forceOutMsgRec = module.forceOutMsg.recorder() unitTestSim.AddModelToTask(unitTaskName, forceOutMsgRec) unitTestSim.InitializeSimulation() unitTestSim.ConfigureStopTime(macros.sec2nano(0.)) unitTestSim.ExecuteSimulation() if np.linalg.norm(forceOutMsgRec.forceRequestBody) >= 1e-8: testFailCount += 1 testMessages.append("FAILED: " + module.ModelTag + " Module failed " + "force output" + " unit test") if testFailCount == 0: print("PASSED: " + module.ModelTag) else: print(testMessages) return [testFailCount, "".join(testMessages)]
if __name__ == "__main__": test_smallBodyWaypointFeedback(False)