Source code for test_spacecraftReconfig

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


#
#   Unit Test Script
#   Module Name:        spacecraftReconfig
#   Author:             Hirotaka Kondo
#   Creation Date:      March 27, 2020
#

import pytest
import itertools
# Import all of the modules that we are going to be called in this simulation
from Basilisk.utilities import SimulationBaseClass
from Basilisk.utilities import unitTestSupport  # general support file with common unit test functions
from Basilisk.utilities import orbitalMotion
from Basilisk.utilities import macros
from Basilisk.utilities import simIncludeThruster
from Basilisk.utilities import fswSetupThrusters
from Basilisk.fswAlgorithms.spacecraftReconfig import spacecraftReconfig  # import the module that is to be tested


# uncomment this line is this test is to be skipped in the global unit test run, adjust message as needed
# @pytest.mark.skipif(conditionstring)
# uncomment this line if this test has an expected failure, adjust message as needed
# @pytest.mark.xfail(conditionstring)
# provide a unique test method name, starting with test_

[docs]@pytest.mark.parametrize("useRefAttitude", [True, False]) @pytest.mark.parametrize("accuracy", [1e-9]) def test_spacecraftReconfig(show_plots, useRefAttitude, accuracy): """Module Unit Test""" # each test method requires a single assert method to be called [testResults, testMessage] = spacecraftReconfigTestFunction(show_plots, useRefAttitude, accuracy) assert testResults < 1, testMessage
def spacecraftReconfigTestFunction(show_plots, useRefAttitude, accuracy): testFailCount = 0 # zero unit test result counter testMessages = [] # create empty array to store test log messages unitTaskName = "unitTask" # arbitrary name (don't change) unitProcessName = "TestProcess" # arbitrary name (don't change) # Create a sim spacecraftReconfig as an empty container unitTestSim = SimulationBaseClass.SimBaseClass() # Create test thread testProcessRate = macros.sec2nano(0.1) # process rate testProc = unitTestSim.CreateNewProcess(unitProcessName) # create new process testProc.addTask(unitTestSim.CreateNewTask(unitTaskName, testProcessRate)) # create new task # Construct algorithm and associated C++ container moduleConfig = spacecraftReconfig.spacecraftReconfigConfig() # update with current values moduleWrap = unitTestSim.setModelDataWrap(moduleConfig) moduleWrap.ModelTag = "spacecraftReconfig" # update python name of test spacecraftReconfig moduleConfig.chiefTransInMsgName = "chiefInputMsg" moduleConfig.deputyTransInMsgName = "deputyInputMsg" moduleConfig.thrustConfigInMsgName = "thrustConfigInputMsg" if(useRefAttitude): moduleConfig.attRefInMsgName = "attRefInputMsg" moduleConfig.onTimeOutMsgName = "onTImeOutputMsg" moduleConfig.attRefOutMsgName = "attRefOutputMsg" moduleConfig.targetClassicOED = [0.0000, 0.0000, 0.0000, 0.0001, 0.0002, 0.0003] moduleConfig.scMassDeputy = 500 # [kg] moduleConfig.attControlTime = 400 # [s] moduleConfig.mu = orbitalMotion.MU_EARTH * 1e9 # [m^3/s^2] # Add test spacecraftReconfig to runtime call list unitTestSim.AddModelToTask(unitTaskName, moduleWrap, moduleConfig) # Create input message and size it because the regular creator of that message # is not part of the test. # # Chief Navigation Message # oe = orbitalMotion.ClassicElements() oe.a = 20000e3 # [m] oe.e = 0.1 oe.i = 0.2 oe.Omega = 0.3 oe.omega = 0.4 oe.f = 0.5 (r_BN_N, v_BN_N) = orbitalMotion.elem2rv(orbitalMotion.MU_EARTH*1e9, oe) chiefNavStateOutData = spacecraftReconfig.NavTransIntMsg() # Create a structure for the input message chiefNavStateOutData.timeTag = 0 chiefNavStateOutData.r_BN_N = r_BN_N chiefNavStateOutData.v_BN_N = v_BN_N chiefNavStateOutData.vehAccumDV = [0, 0, 0] unitTestSupport.setMessage(unitTestSim.TotalSim, unitProcessName, moduleConfig.chiefTransInMsgName, chiefNavStateOutData) # # Deputy Navigation Message # oe2 = orbitalMotion.ClassicElements() oe2.a = (1 + 0.0006) * 7000e3 # [m] oe2.e = 0.2 + 0.0005 oe2.i = 0.0 + 0.0004 oe2.Omega = 0.0 + 0.0003 oe2.omega = 0.0 + 0.0002 oe2.f = 0.0001 (r_BN_N2, v_BN_N2) = orbitalMotion.elem2rv(orbitalMotion.MU_EARTH*1e9, oe2) deputyNavStateOutData = spacecraftReconfig.NavTransIntMsg() # Create a structure for the input message deputyNavStateOutData.timeTag = 0 deputyNavStateOutData.r_BN_N = r_BN_N2 deputyNavStateOutData.v_BN_N = v_BN_N2 deputyNavStateOutData.vehAccumDV = [0, 0, 0] unitTestSupport.setMessage(unitTestSim.TotalSim, unitProcessName, moduleConfig.deputyTransInMsgName, deputyNavStateOutData) # # reference attitude message # if(useRefAttitude): attRefInData = spacecraftReconfig.AttRefFswMsg() attRefInData.sigma_RN = [1.0, 0.0, 0.0] attRefInData.omega_RN_N = [0.0, 0.0, 0.0] attRefInData.domega_RN_N = [0.0, 0.0, 0.0] unitTestSupport.setMessage(unitTestSim.TotalSim, unitProcessName, moduleConfig.attRefInMsgName, attRefInData) # # thruster configuration message # location = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] direction = [[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]] # get thrust in +z direction fswSetupThrusters.clearSetup() for i in range(len(location)): fswSetupThrusters.create(location[i], direction[i], 22.6) fswSetupThrusters.writeConfigMessage(moduleConfig.thrustConfigInMsgName, unitTestSim.TotalSim, unitProcessName) # Setup logging on the test spacecraftReconfig output message so that we get all the writes to it unitTestSim.TotalSim.logThisMessage(moduleConfig.attRefOutMsgName, testProcessRate) unitTestSim.AddVariableForLogging(moduleWrap.ModelTag + ".resetPeriod", testProcessRate) # Need to call the self-init and cross-init methods unitTestSim.InitializeSimulation() # Set the simulation time. # NOTE: the total simulation time may be longer than this value. The # simulation is stopped at the next logging event on or after the # simulation end time. unitTestSim.ConfigureStopTime(testProcessRate) # seconds to stop simulation # Begin the simulation time run set above unitTestSim.ExecuteSimulation() # This pulls the actual data log from the simulation run. # Note that range(3) will provide [0, 1, 2] Those are the elements you get from the vector (all of them) attOutput = unitTestSim.pullMessageLogData( moduleConfig.attRefOutMsgName + ".sigma_RN", list(range(3))) resetPeriod = unitTestSim.GetLogVariableData(moduleWrap.ModelTag + ".resetPeriod") # set the filtered output truth states if useRefAttitude: trueVector = [[1.0,0.0,0.0]] else: trueVector = [[0.38532697209248595, -0.7016349090839732, -0.4026194572440069]] trueResetPeriod = 28148.5466910579925752244889736 # compare the spacecraftReconfig results to the truth values for i in range(0, len(trueVector)): # check a vector values if not unitTestSupport.isArrayEqual(attOutput[i], trueVector[i], 3, accuracy): testFailCount += 1 testMessages.append("FAILED: " + moduleWrap.ModelTag + " Module failed " + moduleConfig.attRefOutMsgName + ".sigma_RN" + " unit test at t=" + str(attOutput[i, 0]*macros.NANO2SEC) + "sec\n") if (not unitTestSupport.isDoubleEqualRelative(resetPeriod[0,1], trueResetPeriod, accuracy)): testFailCount += 1 testMessages.append("FAILED: " + moduleWrap.ModelTag + " Module failed " + "resetPeriod") # print out success message if no error were found if testFailCount == 0: print("PASSED: " + moduleWrap.ModelTag) print("This test uses an accuracy value of " + str(accuracy)) # each test method requires a single assert method to be called # this check below just makes sure no sub-test failures were found return [testFailCount, ''.join(testMessages)] # # This statement below ensures that the unitTestScript can be run as a # stand-along python script # if __name__ == "__main__": test_spacecraftReconfig( False, # show_plots True, # useRefAttitude 1e-9 # accuracy )