Source code for test_unitFacetDrag


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



#
#
#
# Purpose:  Test the facetDrag module.
# Author:   Andrew Harris
# Creation Date:  May 16 2019
#


import inspect
import os

import numpy as np

filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
bskName = 'Basilisk'
splitPath = path.split(bskName)


# import general simulation support files
from Basilisk.utilities import SimulationBaseClass
from Basilisk.utilities import macros
from Basilisk.utilities import orbitalMotion
from Basilisk.utilities import RigidBodyKinematics as rbk

# import simulation related support
from Basilisk.simulation import spacecraft
from Basilisk.simulation import exponentialAtmosphere
from Basilisk.simulation import facetDragDynamicEffector
from Basilisk.simulation import simpleNav
from Basilisk.utilities import unitTestSupport
from Basilisk.utilities import simIncludeGravBody


#print dir(exponentialAtmosphere)


[docs]def test_unitFacetDrag(): """This function is called by the py.test environment.""" # each test method requires a single assert method to be called testResults = [] testMessage = [] dragRes, dragMsg = TestDragCalculation() testMessage.append(dragMsg) testResults.append(dragRes) shadowRes, shadowMsg = TestShadowCalculation() testMessage.append(shadowMsg) testResults.append(shadowRes) testSum = sum(testResults) snippetName = "unitTestPassFail" if testSum == 0: colorText = 'ForestGreen' print("PASSED") passedText = r'\textcolor{' + colorText + '}{' + "PASSED" + '}' else: colorText = 'Red' print("Failed") passedText = r'\textcolor{' + colorText + '}{' + "Failed" + '}' unitTestSupport.writeTeXSnippet(snippetName, passedText, path) assert testSum < 1, testMessage
def TestDragCalculation(): # Init test support variables testFailCount = 0 testMessages = [] ## Simulation initialization simTaskName = "simTask" simProcessName = "simProcess" scSim = SimulationBaseClass.SimBaseClass() dynProcess = scSim.CreateNewProcess(simProcessName) simulationTimeStep = macros.sec2nano(5.) dynProcess.addTask(scSim.CreateNewTask(simTaskName, simulationTimeStep)) # initialize spacecraft object and set properties scObject = spacecraft.Spacecraft() scObject.ModelTag = "spacecraftBody" ## Initialize new atmosphere and drag model, add them to task newAtmo = exponentialAtmosphere.ExponentialAtmosphere() newAtmo.ModelTag = "ExpAtmo" newAtmo.addSpacecraftToModel(scObject.scStateOutMsg) newDrag = facetDragDynamicEffector.FacetDragDynamicEffector() newDrag.ModelTag = "FacetDrag" newDrag.atmoDensInMsg.subscribeTo(newAtmo.envOutMsgs[0]) scObject.addDynamicEffector(newDrag) try: scAreas = [1.0, 1.0] scCoeff = np.array([2.0, 2.0]) B_normals = [np.array([1, 0, 0]), np.array([0, 1, 0])] B_locations = [np.array([0.1,0,0]), np.array([0,0.1,0])] for i in range(0,len(scAreas)): newDrag.addFacet(scAreas[i], scCoeff[i], B_normals[i], B_locations[i]) except: testFailCount += 1 testMessages.append("ERROR: FacetDrag unit test failed while setting facet parameters.") return testFailCount, testMessages # clear prior gravitational body and SPICE setup definitions gravFactory = simIncludeGravBody.gravBodyFactory() planet = gravFactory.createEarth() planet.isCentralBody = True # ensure this is the central gravitational body mu = planet.mu # attach gravity model to spacecraft scObject.gravField.gravBodies = spacecraft.GravBodyVector(list(gravFactory.gravBodies.values())) # # setup orbit and simulation time oe = orbitalMotion.ClassicElements() r_eq = 6371*1000.0 refBaseDens = 1.217 refScaleHeight = 8500.0 # Set base density, equitorial radius, scale height in Atmosphere newAtmo.baseDensity = refBaseDens newAtmo.scaleHeight = refScaleHeight newAtmo.planetRadius = r_eq rN = np.array([r_eq+200.0e3,0,0]) vN = np.array([0,7.788e3,0]) sig_BN = np.array([0,0,0]) # initialize Spacecraft States with the initialization variables scObject.hub.r_CN_NInit = rN # m - r_CN_N scObject.hub.v_CN_NInit = vN # m - v_CN_N scObject.hub.sigma_BNInit = sig_BN simulationTime = macros.sec2nano(5.) # # Setup data logging before the simulation is initialized # numDataPoints = 10 # add BSK objects to the simulation process scSim.AddModelToTask(simTaskName, scObject) scSim.AddModelToTask(simTaskName, newAtmo) scSim.AddModelToTask(simTaskName, newDrag) # setup logging dataLog = scObject.scStateOutMsg.recorder() scSim.AddModelToTask(simTaskName, dataLog) atmoLog = newAtmo.envOutMsgs[0].recorder() scSim.AddModelToTask(simTaskName, atmoLog) # # initialize Simulation # scSim.InitializeSimulation() scSim.AddVariableForLogging(newDrag.ModelTag + ".forceExternal_B", simulationTimeStep, 0, 2, 'double') scSim.AddVariableForLogging(newDrag.ModelTag + ".torqueExternalPntB_B", simulationTimeStep, 0, 2, 'double') # configure a simulation stop time and execute the simulation run # scSim.ConfigureStopTime(simulationTime) scSim.ExecuteSimulation() # Retrieve logged data dragDataForce_B = scSim.GetLogVariableData(newDrag.ModelTag + ".forceExternal_B") dragTorqueData = scSim.GetLogVariableData(newDrag.ModelTag + ".torqueExternalPntB_B") posData = dataLog.r_BN_N velData = dataLog.v_BN_N attData = dataLog.sigma_BN densData = atmoLog.neutralDensity np.set_printoptions(precision=16) def checkFacetDragForce(dens, area, coeff, facet_dir, sigma_BN, inertial_vel): dcm = rbk.MRP2C(sigma_BN) vMag = np.linalg.norm(inertial_vel) v_hat_B = dcm.dot(inertial_vel) / vMag projArea = area * (facet_dir.dot(v_hat_B)) if projArea > 0: drag_force = -0.5 * dens * projArea * coeff * vMag**2.0 * v_hat_B else: drag_force = np.zeros([3,]) return drag_force # Compare to expected values accuracy = 1e-3 unitTestSupport.writeTeXSnippet("toleranceValue", str(accuracy), path) test_val = np.zeros([3,]) for i in range(len(scAreas)): test_val += checkFacetDragForce(densData[i], scAreas[i], scCoeff[i], B_normals[i], attData[1], velData[1]) if len(densData) > 0: if not unitTestSupport.isArrayEqualRelative(dragDataForce_B[1,1:4], test_val, 3,accuracy): testFailCount += 1 testMessages.append( "FAILED: FacetDragEffector failed force unit test at t=" + str(dragDataForce_B[1,0]* macros.NANO2SEC) + "sec with a value difference of "+str(dragDataForce_B[1,1:]-test_val)) else: testFailCount += 1 testMessages.append("FAILED: ExpAtmo failed to pull any logged data") if testFailCount: print(testMessages) else: print("PASSED") return testFailCount, testMessages def TestShadowCalculation(): # Init test support variables testFailCount = 0 testMessages = [] ## Simulation initialization simTaskName = "simTask" simProcessName = "simProcess" scSim = SimulationBaseClass.SimBaseClass() dynProcess = scSim.CreateNewProcess(simProcessName) simulationTimeStep = macros.sec2nano(10.) dynProcess.addTask(scSim.CreateNewTask(simTaskName, simulationTimeStep)) # initialize spacecraft object and set properties scObject = spacecraft.Spacecraft() scObject.ModelTag = "spacecraftBody" simpleNavObj = simpleNav.SimpleNav() simpleNavObj.scStateInMsg.subscribeTo(scObject.scStateOutMsg) ## Initialize new atmosphere and drag model, add them to task newAtmo = exponentialAtmosphere.ExponentialAtmosphere() newAtmo.ModelTag = "ExpAtmo" newAtmo.addSpacecraftToModel(scObject.scStateOutMsg) newDrag = facetDragDynamicEffector.FacetDragDynamicEffector() newDrag.ModelTag = "FacetDrag" newDrag.atmoDensInMsg.subscribeTo(newAtmo.envOutMsgs[0]) scObject.addDynamicEffector(newDrag) try: scAreas = [1.0, 1.0] scCoeff = np.array([2.0, 2.0]) B_normals = [np.array([0, 0, -1]), np.array([0, -1, 0])] B_locations = [np.array([0,0,0.1]), np.array([0,0.1,0])] for ind in range(0,len(scAreas)): newDrag.addFacet(scAreas[ind], scCoeff[ind], B_normals[ind], B_locations[ind]) except: testFailCount += 1 testMessages.append("ERROR: FacetDrag unit test failed while setting facet parameters.") return testFailCount, testMessages # clear prior gravitational body and SPICE setup definitions gravFactory = simIncludeGravBody.gravBodyFactory() planet = gravFactory.createEarth() planet.isCentralBody = True # ensure this is the central gravitational body mu = planet.mu # attach gravity model to spacecraft scObject.gravField.gravBodies = spacecraft.GravBodyVector(list(gravFactory.gravBodies.values())) # # setup orbit and simulation time oe = orbitalMotion.ClassicElements() r_eq = 6371*1000.0 refBaseDens = 1.217 refScaleHeight = 8500.0 # Set base density, equitorial radius, scale height in Atmosphere newAtmo.baseDensity = refBaseDens newAtmo.scaleHeight = refScaleHeight newAtmo.planetRadius = r_eq rN = np.array([r_eq+200.0e3,0,0]) vN = np.array([0,7.788e3,0]) sig_BN = np.array([0,0,0]) # initialize Spacecraft States with the initialization variables scObject.hub.r_CN_NInit = rN # m - r_CN_N scObject.hub.v_CN_NInit = vN # m - v_CN_N scObject.hub.sigma_BNInit = sig_BN simulationTime = macros.sec2nano(10.) # # Setup data logging before the simulation is initialized # numDataPoints = 10 # add BSK objects to the simulation process scSim.AddModelToTask(simTaskName, scObject) scSim.AddModelToTask(simTaskName, newAtmo) scSim.AddModelToTask(simTaskName, newDrag) # setup logging dataLog = scObject.scStateOutMsg.recorder() scSim.AddModelToTask(simTaskName, dataLog) atmoLog = newAtmo.envOutMsgs[0].recorder() scSim.AddModelToTask(simTaskName, atmoLog) # # initialize Simulation # scSim.InitializeSimulation() scSim.AddVariableForLogging(newDrag.ModelTag + ".forceExternal_B", simulationTimeStep, 0, 2, 'double') scSim.AddVariableForLogging(newDrag.ModelTag + ".torqueExternalPntB_B", simulationTimeStep, 0, 2, 'double') # configure a simulation stop time and execute the simulation run # scSim.ConfigureStopTime(simulationTime) scSim.ExecuteSimulation() # Retrieve logged data #dragDataForce_B = scSim.GetLogVariableData(newDrag.ModelTag + ".forceExternal_B") dragDataForce_B = scSim.GetLogVariableData(newDrag.ModelTag + ".forceExternal_B") dragTorqueData = scSim.GetLogVariableData(newDrag.ModelTag + ".torqueExternalPntB_B") posData = dataLog.r_BN_N velData = dataLog.v_BN_N attData = dataLog.sigma_BN densData = atmoLog.neutralDensity np.set_printoptions(precision=16) # Compare to expected values accuracy = 1e-9 #unitTestSupport.writeTeXSnippet("toleranceValue", str(accuracy), path) if len(densData) > 0: for ind in range(1,len(densData)): if not unitTestSupport.isArrayZero(dragDataForce_B[ind, 1:], 3,accuracy): testFailCount += 1 testMessages.append( "FAILED: FacetDragEffector failed shadow unit test with a value difference of " + str(dragDataForce_B[ind,1:])) else: testFailCount += 1 testMessages.append("FAILED: ExpAtmo failed to pull any logged data") if testFailCount: print(testMessages) else: print("PASSED") return testFailCount, testMessages if __name__=="__main__": # test_unitFacetDrag() TestShadowCalculation() # TestDragCalculation()