def attFilter_dynScenario(TheDynSim): """ Executes a default scenario for stand-alone dynamic simulations :params: TheDynSim: instantiation of class DINO_DynSim :return: None """ # Log data for post-processing and plotting # Set length of simulation in nanoseconds from the simulation start. simulationTime = mc.sec2nano(100) # Set the number of data points to be logged, and therefore the sampling frequency numDataPoints = 10000 samplingTime = simulationTime / (numDataPoints - 1) log_DynOutputs(TheDynSim, samplingTime) log_DynCelestialOutputs(TheDynSim, samplingTime) log_aekfOutputs(TheDynSim, samplingTime) # Initialize Simulation TheDynSim.InitializeSimulationAndDiscover() # Set up the orbit using classical orbit elements # oe = define_default_orbit() mu = TheDynSim.DynClass.mu rN, vN = define_dino_postTMI() om.rv2elem(mu, rN, vN) # Initialize Spacecraft States within the state manager (after initialization) posRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubPosition") velRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubVelocity") sigmaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubSigma") omegaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubOmega") # Set the spacecraft initial position, velocity, attitude parameters posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] sigmaRef.setState([[0.1], [0.2], [-0.3]]) # sigma_BN_B omegaRef.setState([[0.001], [-0.01], [0.03]]) # omega_BN_B [rad/s] # Configure a simulation stop time time and execute the simulation run TheDynSim.ConfigureStopTime(simulationTime) TheDynSim.ExecuteSimulation() # Pull data for post-processing and plotting pull_DynOutputs(TheDynSim) pull_senseOutputs(TheDynSim) pull_aekfOutputs(TheDynSim) # pull_DynCelestialOutputs(TheDynSim) plt.show()
def attFilter_dynScenario(TheDynSim): """ Executes a default scenario for stand-alone dynamic simulations :params: TheDynSim: instantiation of class DINO_DynSim :return: None """ # Log data for post-processing and plotting # Set length of simulation in nanoseconds from the simulation start. simulationTime = mc.sec2nano(100) # Set the number of data points to be logged, and therefore the sampling frequency numDataPoints = 10000 samplingTime = simulationTime / (numDataPoints - 1) log_DynOutputs(TheDynSim, samplingTime) log_DynCelestialOutputs(TheDynSim, samplingTime) log_aekfOutputs(TheDynSim, samplingTime) # Initialize Simulation TheDynSim.InitializeSimulationAndDiscover() # Set up the orbit using classical orbit elements # oe = define_default_orbit() mu = TheDynSim.DynClass.mu rN, vN = define_dino_postTMI() om.rv2elem(mu, rN, vN) # Initialize Spacecraft States within the state manager (after initialization) posRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubPosition") velRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubVelocity") sigmaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubSigma") omegaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubOmega") # Set the spacecraft initial position, velocity, attitude parameters posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] sigmaRef.setState([[0.1], [0.2], [-0.3]]) # sigma_BN_B omegaRef.setState([[0.001], [-0.01], [0.03]]) # omega_BN_B [rad/s] # Configure a simulation stop time time and execute the simulation run TheDynSim.ConfigureStopTime(simulationTime) TheDynSim.ExecuteSimulation() # Pull data for post-processing and plotting pull_DynOutputs(TheDynSim) pull_senseOutputs(TheDynSim) pull_aekfOutputs(TheDynSim) # pull_DynCelestialOutputs(TheDynSim) plt.show()
def basicOrbit_dynScenario(TheDynSim): """ Executes a default scenario for stand-alone dynamic simulations :params: TheDynSim: instantiation of class DINO_DynSim :return: None """ # Initialize Simulation TheDynSim.InitializeSimulation() # Set up the orbit using classical orbit elements oe = define_default_orbit() mu = TheDynSim.DynClass.earthGravBody.mu rN, vN = om.elem2rv(mu, oe) om.rv2elem(mu, rN, vN) orbPeriod = period = 2 * np.pi * np.sqrt((oe.a**3.) / mu) # Log data for post-processing and plotting simulationTime = mc.sec2nano(10000.) numDataPoints = int(orbPeriod) samplingTime = simulationTime / (numDataPoints - 1) log_DynOutputs(TheDynSim, samplingTime) log_FSWOutputs(TheDynSim, samplingTime) # Initialize Spacecraft States within the state manager (after initialization) posRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubPosition") velRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubVelocity") sigmaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubSigma") omegaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubOmega") posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] sigmaRef.setState([[0.1], [0.2], [-0.3]]) # sigma_BN_B omegaRef.setState([[0.001], [-0.01], [0.03]]) # omega_BN_B [rad/s] # Configure a simulation stop time time and execute the simulation run TheDynSim.ConfigureStopTime(simulationTime) TheDynSim.ExecuteSimulation() # Pull data for post-processing and plotting pull_DynOutputs(TheDynSim) pull_FSWOutputs(TheDynSim) plt.show()
def basicOrbit_dynScenario(TheDynSim): """ Executes a default scenario for stand-alone dynamic simulations :params: TheDynSim: instantiation of class DINO_DynSim :return: None """ # Initialize Simulation TheDynSim.InitializeSimulation() # Set up the orbit using classical orbit elements oe = define_default_orbit() mu = TheDynSim.DynClass.earthGravBody.mu rN, vN = om.elem2rv(mu, oe) om.rv2elem(mu, rN, vN) orbPeriod = period = 2 * np.pi * np.sqrt((oe.a ** 3.) / mu) # Log data for post-processing and plotting simulationTime = mc.sec2nano(10000.) numDataPoints = int(orbPeriod) samplingTime = simulationTime / (numDataPoints - 1) log_DynOutputs(TheDynSim, samplingTime) log_FSWOutputs(TheDynSim, samplingTime) # Initialize Spacecraft States within the state manager (after initialization) posRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubPosition") velRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubVelocity") sigmaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubSigma") omegaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubOmega") posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] sigmaRef.setState([[0.1], [0.2], [-0.3]]) # sigma_BN_B omegaRef.setState([[0.001], [-0.01], [0.03]]) # omega_BN_B [rad/s] # Configure a simulation stop time time and execute the simulation run TheDynSim.ConfigureStopTime(simulationTime) TheDynSim.ExecuteSimulation() # Pull data for post-processing and plotting pull_DynOutputs(TheDynSim) pull_FSWOutputs(TheDynSim) plt.show()
def run(show_plots, orbitCase, planetCase): '''Call this routine directly to run the tutorial scenario.''' testFailCount = 0 # zero unit test result counter testMessages = [] # create empty array to store test log messages # # From here on there scenario python code is found. Above this line the code is to setup a # unitTest environment. The above code is not critical if learning how to code BSK. # # Create simulation variable names simTaskName = "simTask" simProcessName = "simProcess" # Create a sim module as an empty container scSim = SimulationBaseClass.SimBaseClass() scSim.TotalSim.terminateSimulation() # create the simulation process dynProcess = scSim.CreateNewProcess(simProcessName) # create the dynamics task and specify the integration update time simulationTimeStep = macros.sec2nano(10.) dynProcess.addTask(scSim.CreateNewTask(simTaskName, simulationTimeStep)) # Initialize new atmosphere and drag model, add them to task newAtmo = exponentialAtmosphere.ExponentialAtmosphere() atmoTaskName = "atmosphere" newAtmo.ModelTag = "ExpAtmo" dragEffector = dragDynamicEffector.DragDynamicEffector() dynProcess.addTask(scSim.CreateNewTask(atmoTaskName, simulationTimeStep)) #dynProcess.addTask(scSim.CreateNewTask(dragEffectorTaskName, simulationTimeStep)) scSim.AddModelToTask(atmoTaskName, newAtmo) #scSim.AddModelToTask(dragEffectorTaskName, dragEffector) # # setup the simulation tasks/objects # # initialize spacecraftPlus object and set properties scObject = spacecraftPlus.SpacecraftPlus() scObject.ModelTag = "spacecraftBody" scObject.hub.useTranslation = True scObject.hub.useRotation = False #scObject.addDynamicEffector(dragEffector) # add spacecraftPlus object to the simulation process scSim.AddModelToTask(simTaskName, scObject) # clear prior gravitational body and SPICE setup definitions gravFactory = simIncludeGravBody.gravBodyFactory() newAtmo.addSpacecraftToModel(scObject.scStateOutMsgName) #dragEffector.SetDensityMessage(newAtmo.atmoDensOutMsgNames[-1]) if planetCase == "Earth": planet = gravFactory.createEarth() newAtmo.setPlanet("earth") elif planetCase == "Mars": planet = gravFactory.createMars() newAtmo.setPlanet("mars") planet.isCentralBody = True # ensure this is the central gravitational body mu = planet.mu # attach gravity model to spaceCraftPlus scObject.gravField.gravBodies = spacecraftPlus.GravBodyVector(gravFactory.gravBodies.values()) # # setup orbit and simulation time oe = orbitalMotion.ClassicElements() if planetCase == "Earth": r_eq = 6371*1000.0 refBaseDens = 1.217 refScaleHeight = 8500.0 if orbitCase == "LPO": orbAltMin = 300.0*1000.0 orbAltMax = orbAltMin elif orbitCase == "LTO": orbAltMin = 300*1000.0 orbAltMax = 800.0 * 1000.0 elif planetCase == "Mars": refBaseDens = 0.020 refScaleHeight = 11100.0 r_eq = 3389.5 * 1000.0 if orbitCase == "LPO": orbAltMin = 100.0*1000.0 orbAltMax = orbAltMin elif orbitCase == "LTO": orbAltMin = 100.0*1000.0 orbAltMax = 500.0 * 1000.0 else: return 1, "Test failed- did not initialize planets." rMin = r_eq + orbAltMin rMax = r_eq + orbAltMax oe.a = (rMin+rMax)/2.0 oe.e = 1.0 - rMin/oe.a oe.i = 0.0*macros.D2R oe.Omega = 0.0*macros.D2R oe.omega = 0.0*macros.D2R oe.f = 0.0*macros.D2R rN, vN = orbitalMotion.elem2rv(mu, oe) oe = orbitalMotion.rv2elem(mu, rN, vN) # this stores consistent initial orbit elements # with circular or equatorial orbit, some angles are # arbitrary # set the simulation time n = np.sqrt(mu/oe.a/oe.a/oe.a) P = 2.*np.pi/n simulationTime = macros.sec2nano(0.5*P) # # Setup data logging before the simulation is initialized # numDataPoints = 10 samplingTime = simulationTime / (numDataPoints-1) scSim.TotalSim.logThisMessage(scObject.scStateOutMsgName, samplingTime) scSim.TotalSim.logThisMessage('atmo_dens0_data', samplingTime) scSim.AddVariableForLogging('ExpAtmo.relativePos', samplingTime, StartIndex=0, StopIndex=2) # # initialize Spacecraft States with the initialization variables # scObject.hub.r_CN_NInit = unitTestSupport.np2EigenVectorXd(rN) # m - r_CN_N scObject.hub.v_CN_NInit = unitTestSupport.np2EigenVectorXd(vN) # m - v_CN_N # # initialize Simulation # scSim.InitializeSimulation() # # configure a simulation stop time time and execute the simulation run # scSim.ConfigureStopTime(simulationTime) scSim.ExecuteSimulation() # # retrieve the logged data # posData = scSim.pullMessageLogData(scObject.scStateOutMsgName+'.r_BN_N',range(3)) velData = scSim.pullMessageLogData(scObject.scStateOutMsgName+'.v_BN_N',range(3)) densData = scSim.pullMessageLogData('atmo_dens0_data.neutralDensity') relPosData = scSim.GetLogVariableData('ExpAtmo.relativePos') np.set_printoptions(precision=16) # Compare to expected values refAtmoDensData = [] accuracy = 1e-13 for relPos in relPosData: dist = np.linalg.norm(relPos[1:]) alt = dist - r_eq refAtmoDensData.append(expAtmoComp(alt,refBaseDens,refScaleHeight)) # check a vector values for ind in range(0,len(densData)): if not unitTestSupport.isDoubleEqual(densData[ind,:], refAtmoDensData[ind],accuracy): testFailCount += 1 testMessages.append( "FAILED: ExpAtmo failed density unit test at t=" + str(densData[ind, 0] * macros.NANO2SEC) + "sec with a value difference of "+str(densData[ind,1]-refAtmoDensData[ind])) # # plot the results # if show_plots: fileNameString = filename[len(path)+6:-3] # draw the inertial position vector components plt.figure(1) fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') for idx in range(1,4): plt.plot(posData[:, 0]*macros.NANO2SEC/P, posData[:, idx]/1000., color=unitTestSupport.getLineColor(idx,3), label='$r_{BN,'+str(idx)+'}$') plt.legend(loc='lower right') plt.xlabel('Time [orbits]') plt.ylabel('Inertial Position [km]') # draw orbit in perifocal frame b = oe.a*np.sqrt(1-oe.e*oe.e) p = oe.a*(1-oe.e*oe.e) plt.figure(2,figsize=np.array((1.0, b/oe.a))*4.75,dpi=100) plt.axis(np.array([-oe.rApoap, oe.rPeriap, -b, b])/1000*1.25) # draw the planet fig = plt.gcf() ax = fig.gca() planetColor= '#008800' planetRadius = planet.radEquator/1000 ax.add_artist(plt.Circle((0, 0), planetRadius, color=planetColor)) # draw the actual orbit rData=[] fData=[] for idx in range(0,len(posData)): oeData = orbitalMotion.rv2elem(mu,posData[idx,1:4],velData[idx,1:4]) rData.append(oeData.rmag) fData.append(oeData.f + oeData.omega - oe.omega) plt.plot(rData*np.cos(fData)/1000, rData*np.sin(fData)/1000 ,color='#aa0000' ,linewidth = 3.0 ) # draw the full osculating orbit from the initial conditions fData = np.linspace(0,2*np.pi,100) rData = [] for idx in range(0,len(fData)): rData.append(p/(1+oe.e*np.cos(fData[idx]))) plt.plot(rData*np.cos(fData)/1000, rData*np.sin(fData)/1000 ,'--' , color='#555555' ) plt.xlabel('$i_e$ Cord. [km]') plt.ylabel('$i_p$ Cord. [km]') plt.grid() plt.figure() fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') smaData = [] for idx in range(0, len(posData)): oeData = orbitalMotion.rv2elem(mu, posData[idx, 1:4], velData[idx, 1:4]) smaData.append(oeData.a/1000.) plt.plot(posData[:, 0]*macros.NANO2SEC/P, smaData ,color='#aa0000', ) plt.xlabel('Time [orbits]') plt.ylabel('SMA [km]') plt.figure() fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') plt.plot(relPosData[:, 0] * macros.NANO2SEC, relPosData[:, 1:4]) plt.title('Density Data vs. Time') plt.xlabel('Time') plt.ylabel('Density in kg/m^3') plt.figure() fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') plt.plot( densData[:,0]*macros.NANO2SEC, densData[:,1]) plt.title('Density Data vs. Time') plt.xlabel('Time') plt.ylabel('Density in kg/m^3') plt.show() plt.close() return testFailCount, testMessages
def multiOrbitBeacons_dynScenario(TheDynSim): """ Executes a default scenario for stand-alone dynamic simulations :params: TheDynSim: instantiation of class DINO_DynSim :return: None """ # Log data for post-processing and plotting # Set length of simulation in nanoseconds from the simulation start. simulationTime = mc.sec2nano(10) # Set the number of data points to be logged, and therefore the sampling frequency numDataPoints = 100000 samplingTime = simulationTime / (numDataPoints - 1) log_DynOutputs(TheDynSim, samplingTime) log_DynCelestialOutputs(TheDynSim, samplingTime) # Initialize Simulation TheDynSim.InitializeSimulation() # Set up the orbit using classical orbit elements # oe = define_default_orbit() mu = TheDynSim.DynClass.mu rN, vN = define_dino_postTMI() om.rv2elem(mu, rN, vN) # Initialize Spacecraft States within the state manager (after initialization) posRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubPosition") velRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubVelocity") sigmaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubSigma") omegaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject("hubOmega") # Set the spacecraft initial position, velocity, attitude parameters posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] sigmaRef.setState([[0.1], [0.2], [-0.3]]) # sigma_BN_B omegaRef.setState([[0.001], [-0.01], [0.03]]) # omega_BN_B [rad/s] # Set up beacon orbits using COEs loaded from a file ephemFile = open("observations_log.txt", 'r') lines = ephemFile.readlines() beaconOEs = [] for ind in range(1, 1): vals = lines[ind].split(',') desVals = vals[8:] newOE = om.ClassicElements() newOE.a = float(desVals[0]) * 1000.0 newOE.e = float(desVals[1]) newOE.i = float(desVals[2]) newOE.omega = float(desVals[3]) newOE.Omega = float(desVals[4]) newOE.f = float(desVals[5]) beaconOEs.append(newOE) rN, vN = om.elem2rv(mu, newOE) print "Beacon", ind, " rN:", rN, " vN:", vN posRef = TheDynSim.DynClass.beaconList[ind - 1].dynManager.getStateObject("hubPosition") velRef = TheDynSim.DynClass.beaconList[ind - 1].dynManager.getStateObject("hubVelocity") posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] ephemFile.close() # Configure a simulation stop time time and execute the simulation run TheDynSim.ConfigureStopTime(simulationTime) TheDynSim.ExecuteSimulation() # Pull data for post-processing and plotting r_BN, v_BN, sigma_BN, omega_BN_B = pull_DynOutputs(TheDynSim) sigma_tilde_BN, omega_tilde_BN = pull_senseOutputs(TheDynSim) r_sun, r_earth, r_moon, r_mars, r_beacons = pull_DynCelestialOutputs(TheDynSim) ## Post-Process sim data using camera, image processing, batch filter DINO modules ############################################################################### # # Pull in canned QE and Transmission curves from DINO C-REx files # ############################################################################### # load tranmission curve for Canon 20D tc = np.load('../dinoModels/SimCode/opnavCamera/tc/20D.npz') # load QE curve for Hubble Space Telecope Advanced Camera for Surveys SITe CCD qe = np.load('../dinoModels/SimCode/opnavCamera/qe/ACS.npz') ############################################################################### # # Initialize camera # ############################################################################### earth = camera.beacon() earth.r_eq = 6378.137 earth.id = 'Earth' earth.albedo = 0.434 # earth.albedo = 1e30 mars = camera.beacon() mars.r_eq = 3396.2 mars.id = 'Mars' mars.albedo = 0.17 moon = camera.beacon() moon.r_eq = 1738.1 moon.id = 'Moon' # moon.albedo = 0.12 moon.albedo = .7 beacons = [earth, mars, moon] # need loop to define asteroids, too cam, ipParam, navParam = defineParameters( (512, 512), # camera resolution, width then height 0.05, # focal length in m (0.01, 0.01), # detector dimensions in m, with then height beacons, # list of beacons # transmission curve dict np.load('../dinoModels/SimCode/opnavCamera/tc/20D.npz'), # quantum efficiency curve dict np.load('../dinoModels/SimCode/opnavCamera/qe/ACS.npz'), 1, # bin size for wavelength functions (in nm) 0.01 ** 2, # effective area (m^2) 100, # dark current electrons/s/pixel 100, # read noise STD (in electrons per pixel) 100, # bin size 2 ** 32, # saturation depth 1, # Standard deviation for PSF (in Pixels) 0.01 # simulation timestep ) # this is spoofing the output of the nav exec # telling the camera when to take an image. takeImage = np.zeros(len(r_BN)) takeImage[100] = 1 takeImage[200] = 1 takeImage[300] = 1 #cam, beaconList, r_BN, r_earth, r_moon, r_mars detectorArrays, imgTimes, imgPos, imgMRP, imgBeaconPos = genCamImages(cam, beacons, r_BN, r_earth, r_moon, r_mars, takeImage) # Run the Image Processing Module beaconPLNav, beaconIDsNav, imgMRPNav, imgTimesNav, numNavInputs = genImgProc(detectorArrays, imgPos, imgMRP, imgBeaconPos, imgTimes, ipParam) print "*******Image Processing Outputs*******" print "Beacon PL:" print beaconPLNav print "beaconIDs:" print beaconIDsNav filterOutputs = genNavOutputs(beaconPLNav, beaconIDsNav, imgTimesNav, imgMRPNav, r_BN, v_BN, navParam) print "********** Filter Run Complete ************"
def run(show_plots, orbitCase, planetCase): '''Call this routine directly to run the tutorial scenario.''' testFailCount = 0 # zero unit test result counter testMessages = [] # create empty array to store test log messages # # From here on there scenario python code is found. Above this line the code is to setup a # unitTest environment. The above code is not critical if learning how to code BSK. # # Create simulation variable names simTaskName = "simTask" simProcessName = "simProcess" # Create a sim module as an empty container scSim = SimulationBaseClass.SimBaseClass() scSim.TotalSim.terminateSimulation() # create the simulation process dynProcess = scSim.CreateNewProcess(simProcessName) # create the dynamics task and specify the integration update time simulationTimeStep = macros.sec2nano(10.) dynProcess.addTask(scSim.CreateNewTask(simTaskName, simulationTimeStep)) # Initialize new atmosphere and drag model, add them to task newAtmo = exponentialAtmosphere.ExponentialAtmosphere() atmoTaskName = "atmosphere" newAtmo.ModelTag = "ExpAtmo" dragEffector = dragDynamicEffector.DragDynamicEffector() dynProcess.addTask(scSim.CreateNewTask(atmoTaskName, simulationTimeStep)) #dynProcess.addTask(scSim.CreateNewTask(dragEffectorTaskName, simulationTimeStep)) scSim.AddModelToTask(atmoTaskName, newAtmo) #scSim.AddModelToTask(dragEffectorTaskName, dragEffector) # # setup the simulation tasks/objects # # initialize spacecraftPlus object and set properties scObject = spacecraftPlus.SpacecraftPlus() scObject.ModelTag = "spacecraftBody" scObject.hub.useTranslation = True scObject.hub.useRotation = False #scObject.addDynamicEffector(dragEffector) # add spacecraftPlus object to the simulation process scSim.AddModelToTask(simTaskName, scObject) # clear prior gravitational body and SPICE setup definitions gravFactory = simIncludeGravBody.gravBodyFactory() newAtmo.addSpacecraftToModel(scObject.scStateOutMsgName) #dragEffector.SetDensityMessage(newAtmo.atmoDensOutMsgNames[-1]) if planetCase == "Earth": planet = gravFactory.createEarth() newAtmo.setPlanet("earth") elif planetCase == "Mars": planet = gravFactory.createMars() newAtmo.setPlanet("mars") planet.isCentralBody = True # ensure this is the central gravitational body mu = planet.mu # attach gravity model to spaceCraftPlus scObject.gravField.gravBodies = spacecraftPlus.GravBodyVector( gravFactory.gravBodies.values()) # # setup orbit and simulation time oe = orbitalMotion.ClassicElements() if planetCase == "Earth": r_eq = 6371 * 1000.0 refBaseDens = 1.217 refScaleHeight = 8500.0 if orbitCase == "LPO": orbAltMin = 300.0 * 1000.0 orbAltMax = orbAltMin elif orbitCase == "LTO": orbAltMin = 300 * 1000.0 orbAltMax = 800.0 * 1000.0 elif planetCase == "Mars": refBaseDens = 0.020 refScaleHeight = 11100.0 r_eq = 3389.5 * 1000.0 if orbitCase == "LPO": orbAltMin = 100.0 * 1000.0 orbAltMax = orbAltMin elif orbitCase == "LTO": orbAltMin = 100.0 * 1000.0 orbAltMax = 500.0 * 1000.0 else: return 1, "Test failed- did not initialize planets." rMin = r_eq + orbAltMin rMax = r_eq + orbAltMax oe.a = (rMin + rMax) / 2.0 oe.e = 1.0 - rMin / oe.a oe.i = 0.0 * macros.D2R oe.Omega = 0.0 * macros.D2R oe.omega = 0.0 * macros.D2R oe.f = 0.0 * macros.D2R rN, vN = orbitalMotion.elem2rv(mu, oe) oe = orbitalMotion.rv2elem( mu, rN, vN) # this stores consistent initial orbit elements # with circular or equatorial orbit, some angles are # arbitrary # set the simulation time n = np.sqrt(mu / oe.a / oe.a / oe.a) P = 2. * np.pi / n simulationTime = macros.sec2nano(0.5 * P) # # Setup data logging before the simulation is initialized # numDataPoints = 10 samplingTime = simulationTime / (numDataPoints - 1) scSim.TotalSim.logThisMessage(scObject.scStateOutMsgName, samplingTime) scSim.TotalSim.logThisMessage('atmo_dens0_data', samplingTime) scSim.AddVariableForLogging('ExpAtmo.relativePos', samplingTime, StartIndex=0, StopIndex=2) # # initialize Spacecraft States with the initialization variables # scObject.hub.r_CN_NInit = unitTestSupport.np2EigenVectorXd( rN) # m - r_CN_N scObject.hub.v_CN_NInit = unitTestSupport.np2EigenVectorXd( vN) # m - v_CN_N # # initialize Simulation # scSim.InitializeSimulation() # # configure a simulation stop time time and execute the simulation run # scSim.ConfigureStopTime(simulationTime) scSim.ExecuteSimulation() # # retrieve the logged data # posData = scSim.pullMessageLogData(scObject.scStateOutMsgName + '.r_BN_N', range(3)) velData = scSim.pullMessageLogData(scObject.scStateOutMsgName + '.v_BN_N', range(3)) densData = scSim.pullMessageLogData('atmo_dens0_data.neutralDensity') relPosData = scSim.GetLogVariableData('ExpAtmo.relativePos') np.set_printoptions(precision=16) # Compare to expected values refAtmoDensData = [] accuracy = 1e-13 for relPos in relPosData: dist = np.linalg.norm(relPos[1:]) alt = dist - r_eq refAtmoDensData.append(expAtmoComp(alt, refBaseDens, refScaleHeight)) # check a vector values for ind in range(0, len(densData)): if not unitTestSupport.isDoubleEqual(densData[ind, :], refAtmoDensData[ind], accuracy): testFailCount += 1 testMessages.append( "FAILED: ExpAtmo failed density unit test at t=" + str(densData[ind, 0] * macros.NANO2SEC) + "sec with a value difference of " + str(densData[ind, 1] - refAtmoDensData[ind])) # # plot the results # if show_plots: fileNameString = filename[len(path) + 6:-3] # draw the inertial position vector components plt.figure(1) fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') for idx in range(1, 4): plt.plot(posData[:, 0] * macros.NANO2SEC / P, posData[:, idx] / 1000., color=unitTestSupport.getLineColor(idx, 3), label='$r_{BN,' + str(idx) + '}$') plt.legend(loc='lower right') plt.xlabel('Time [orbits]') plt.ylabel('Inertial Position [km]') # draw orbit in perifocal frame b = oe.a * np.sqrt(1 - oe.e * oe.e) p = oe.a * (1 - oe.e * oe.e) plt.figure(2, figsize=np.array((1.0, b / oe.a)) * 4.75, dpi=100) plt.axis(np.array([-oe.rApoap, oe.rPeriap, -b, b]) / 1000 * 1.25) # draw the planet fig = plt.gcf() ax = fig.gca() planetColor = '#008800' planetRadius = planet.radEquator / 1000 ax.add_artist(plt.Circle((0, 0), planetRadius, color=planetColor)) # draw the actual orbit rData = [] fData = [] for idx in range(0, len(posData)): oeData = orbitalMotion.rv2elem(mu, posData[idx, 1:4], velData[idx, 1:4]) rData.append(oeData.rmag) fData.append(oeData.f + oeData.omega - oe.omega) plt.plot(rData * np.cos(fData) / 1000, rData * np.sin(fData) / 1000, color='#aa0000', linewidth=3.0) # draw the full osculating orbit from the initial conditions fData = np.linspace(0, 2 * np.pi, 100) rData = [] for idx in range(0, len(fData)): rData.append(p / (1 + oe.e * np.cos(fData[idx]))) plt.plot(rData * np.cos(fData) / 1000, rData * np.sin(fData) / 1000, '--', color='#555555') plt.xlabel('$i_e$ Cord. [km]') plt.ylabel('$i_p$ Cord. [km]') plt.grid() plt.figure() fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') smaData = [] for idx in range(0, len(posData)): oeData = orbitalMotion.rv2elem(mu, posData[idx, 1:4], velData[idx, 1:4]) smaData.append(oeData.a / 1000.) plt.plot( posData[:, 0] * macros.NANO2SEC / P, smaData, color='#aa0000', ) plt.xlabel('Time [orbits]') plt.ylabel('SMA [km]') plt.figure() fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') plt.plot(relPosData[:, 0] * macros.NANO2SEC, relPosData[:, 1:4]) plt.title('Density Data vs. Time') plt.xlabel('Time') plt.ylabel('Density in kg/m^3') plt.figure() fig = plt.gcf() ax = fig.gca() ax.ticklabel_format(useOffset=False, style='plain') plt.plot(densData[:, 0] * macros.NANO2SEC, densData[:, 1]) plt.title('Density Data vs. Time') plt.xlabel('Time') plt.ylabel('Density in kg/m^3') plt.show() plt.close() return testFailCount, testMessages
def multiOrbitBeacons_dynScenario(TheDynSim): """ Executes a default scenario for stand-alone dynamic simulations :params: TheDynSim: instantiation of class DINO_DynSim :return: None """ # Log data for post-processing and plotting # Set length of simulation in nanoseconds from the simulation start. simulationTime = mc.sec2nano(10) # Set the number of data points to be logged, and therefore the sampling frequency numDataPoints = 100000 samplingTime = simulationTime / (numDataPoints - 1) log_DynOutputs(TheDynSim, samplingTime) log_DynCelestialOutputs(TheDynSim, samplingTime) # Initialize Simulation TheDynSim.InitializeSimulation() # Set up the orbit using classical orbit elements # oe = define_default_orbit() mu = TheDynSim.DynClass.mu rN, vN = define_dino_postTMI() om.rv2elem(mu, rN, vN) # Initialize Spacecraft States within the state manager (after initialization) posRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubPosition") velRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubVelocity") sigmaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubSigma") omegaRef = TheDynSim.DynClass.scObject.dynManager.getStateObject( "hubOmega") # Set the spacecraft initial position, velocity, attitude parameters posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] sigmaRef.setState([[0.1], [0.2], [-0.3]]) # sigma_BN_B omegaRef.setState([[0.001], [-0.01], [0.03]]) # omega_BN_B [rad/s] # Set up beacon orbits using COEs loaded from a file ephemFile = open("observations_log.txt", 'r') lines = ephemFile.readlines() beaconOEs = [] for ind in range(1, 1): vals = lines[ind].split(',') desVals = vals[8:] newOE = om.ClassicElements() newOE.a = float(desVals[0]) * 1000.0 newOE.e = float(desVals[1]) newOE.i = float(desVals[2]) newOE.omega = float(desVals[3]) newOE.Omega = float(desVals[4]) newOE.f = float(desVals[5]) beaconOEs.append(newOE) rN, vN = om.elem2rv(mu, newOE) print "Beacon", ind, " rN:", rN, " vN:", vN posRef = TheDynSim.DynClass.beaconList[ ind - 1].dynManager.getStateObject("hubPosition") velRef = TheDynSim.DynClass.beaconList[ ind - 1].dynManager.getStateObject("hubVelocity") posRef.setState(sp.np2EigenVectorXd(rN)) # r_BN_N [m] velRef.setState(sp.np2EigenVectorXd(vN)) # r_BN_N [m] ephemFile.close() # Configure a simulation stop time time and execute the simulation run TheDynSim.ConfigureStopTime(simulationTime) TheDynSim.ExecuteSimulation() # Pull data for post-processing and plotting r_BN, v_BN, sigma_BN, omega_BN_B = pull_DynOutputs(TheDynSim) sigma_tilde_BN, omega_tilde_BN = pull_senseOutputs(TheDynSim) r_sun, r_earth, r_moon, r_mars, r_beacons = pull_DynCelestialOutputs( TheDynSim) ## Post-Process sim data using camera, image processing, batch filter DINO modules ############################################################################### # # Pull in canned QE and Transmission curves from DINO C-REx files # ############################################################################### # load tranmission curve for Canon 20D tc = np.load('../dinoModels/SimCode/opnavCamera/tc/20D.npz') # load QE curve for Hubble Space Telecope Advanced Camera for Surveys SITe CCD qe = np.load('../dinoModels/SimCode/opnavCamera/qe/ACS.npz') ############################################################################### # # Initialize camera # ############################################################################### earth = camera.beacon() earth.r_eq = 6378.137 earth.id = 'Earth' earth.albedo = 0.434 # earth.albedo = 1e30 mars = camera.beacon() mars.r_eq = 3396.2 mars.id = 'Mars' mars.albedo = 0.17 moon = camera.beacon() moon.r_eq = 1738.1 moon.id = 'Moon' # moon.albedo = 0.12 moon.albedo = .7 beacons = [earth, mars, moon] # need loop to define asteroids, too cam, ipParam, navParam = defineParameters( (512, 512), # camera resolution, width then height 0.05, # focal length in m (0.01, 0.01), # detector dimensions in m, with then height beacons, # list of beacons # transmission curve dict np.load('../dinoModels/SimCode/opnavCamera/tc/20D.npz'), # quantum efficiency curve dict np.load('../dinoModels/SimCode/opnavCamera/qe/ACS.npz'), 1, # bin size for wavelength functions (in nm) 0.01**2, # effective area (m^2) 100, # dark current electrons/s/pixel 100, # read noise STD (in electrons per pixel) 100, # bin size 2**32, # saturation depth 1, # Standard deviation for PSF (in Pixels) 0.01 # simulation timestep ) # this is spoofing the output of the nav exec # telling the camera when to take an image. takeImage = np.zeros(len(r_BN)) takeImage[100] = 1 takeImage[200] = 1 takeImage[300] = 1 #cam, beaconList, r_BN, r_earth, r_moon, r_mars detectorArrays, imgTimes, imgPos, imgMRP, imgBeaconPos = genCamImages( cam, beacons, r_BN, r_earth, r_moon, r_mars, takeImage) # Run the Image Processing Module beaconPLNav, beaconIDsNav, imgMRPNav, imgTimesNav, numNavInputs = genImgProc( detectorArrays, imgPos, imgMRP, imgBeaconPos, imgTimes, ipParam) print "*******Image Processing Outputs*******" print "Beacon PL:" print beaconPLNav print "beaconIDs:" print beaconIDsNav filterOutputs = genNavOutputs(beaconPLNav, beaconIDsNav, imgTimesNav, imgMRPNav, r_BN, v_BN, navParam) print "********** Filter Run Complete ************"