def __init__(self, aircraft_name="A320", init_conditions=None, jsbsim_freq=60, agent_interaction_steps=5): """ Constructor. Creates an instance of JSBSim, loads an aircraft and sets initial conditions. :param aircraft_name: name of aircraft to be loaded. JSBSim looks for file '\model_name\model_name.xml' from root dir. :param init_conditions: dict mapping properties to their initial values. Defaults to None, causing a default set of initial props to be used. :param jsbsim_freq: JSBSim integration frequency :param agent_interaction_steps: simulation steps before the agent interact """ self.jsbsim_exec = jsbsim.FGFDMExec(environ['JSBSIM_ROOT_DIR']) self.jsbsim_exec.set_debug_level(0) # requests JSBSim not to output any messages whatsoever self.jsbsim_exec.load_model(aircraft_name) # collect all jsbsim properties in Catalog Catalog.add_jsbsim_props(self.jsbsim_exec.query_property_catalog('')) # set jsbsim integration time step dt = 1 / jsbsim_freq self.jsbsim_exec.set_dt(dt) self.agent_interaction_steps = agent_interaction_steps self.initialise(init_conditions)
def __init__(self, sim_frequency_hz: float = 60.0, aircraft: Aircraft = f16, init_conditions: Dict[prp.Property, float] = None): """ Constructor. Creates an instance of JSBSim and sets initial conditions. :param sim_frequency_hz: the JSBSim integration frequency in Hz. :param aircraft: name of aircraft to be loaded. JSBSim looks for file \\model_name\\model_name.xml from root dir. :param init_conditions: dict mapping properties to their initial values. Defaults to None, causing a default set of initial props to be used. """ self.jsbsim = jsbsim.FGFDMExec(root_dir=self.JSBSIM_ROOT_DIR) self.jsbsim.set_debug_level(0) with open('config.yml', 'r') as file: configurations = yaml.safe_load(file) if configurations['general']['flightgear'] == 'true': self.jsbsim.enable_output() else: self.jsbsim.disable_output() self.sim_dt = 1.0 / sim_frequency_hz self.aircraft = aircraft self.initialise(self.sim_dt, self.aircraft.jsbsim_id, init_conditions) self.wall_clock_dt = None
def __init__(self, sim_frequency_hz: float = 60.0, aircraft: Aircraft = f16, init_conditions: Dict[prp.Property, float] = None, allow_flightgear_output: bool = True): """ Constructor. Creates an instance of JSBSim and sets initial conditions. :param sim_frequency_hz: the JSBSim integration frequency in Hz. :param aircraft_model_name: name of aircraft to be loaded. JSBSim looks for file \model_name\model_name.xml from root dir. :param init_conditions: dict mapping properties to their initial values. Defaults to None, causing a default set of initial props to be used. :param allow_flightgear_output: bool, loads a config file instructing JSBSim to connect to an output socket if True. """ self.jsbsim = jsbsim.FGFDMExec(root_dir=self.ROOT_DIR) self.jsbsim.set_debug_level(0) if allow_flightgear_output: flightgear_output_config = os.path.join( os.path.dirname(os.path.abspath(__file__)), self.OUTPUT_FILE) self.jsbsim.set_output_directive(flightgear_output_config) self.sim_dt = 1.0 / sim_frequency_hz self.aircraft = aircraft self.initialise(self.sim_dt, self.aircraft.jsbsim_id, init_conditions) self.jsbsim.disable_output() self.wall_clock_dt = None
def __init__(self, sim_frequency_hz: float = 60.0, aircraft: Aircraft = cessna172P, init_conditions: Dict['prp.Property', float] = None, allow_flightgear_output: bool = True): """ Constructor. Creates an instance of JSBSim and sets initial conditions. :param sim_frequency_hz: the JSBSim integration frequency in Hz. :param aircraft_model_name: name of aircraft to be loaded. JSBSim looks for file \model_name\model_name.xml from root dir. :param init_conditions: dict mapping properties to their initial values. Defaults to None, causing a default set of initial props to be used. :param allow_flightgear_output: bool, loads a config file instructing JSBSim to connect to an output socket if True. """ self.jsbsim = jsbsim.FGFDMExec(root_dir=self.ROOT_DIR) self.jsbsim.set_debug_level(0) if allow_flightgear_output: #TODO: if called multiple times, a file descriptor is leaked here for the output specified in the xml #on file descriptors see: https://www.cyberciti.biz/tips/linux-procfs-file-descriptors.html flightgear_output_config = os.path.join( os.path.dirname(os.path.abspath(__file__)), self.OUTPUT_FILE) self.jsbsim.set_output_directive(flightgear_output_config) self.sim_dt = 1.0 / sim_frequency_hz self.aircraft = aircraft self.initialise(self.sim_dt, self.aircraft.jsbsim_id, init_conditions) self.jsbsim.disable_output() self.wall_clock_dt = None
def CreateFDM(sandbox, pm=None): _fdm = jsbsim.FGFDMExec(os.path.join(sandbox(), ''), pm) path = sandbox.path_to_jsbsim_file() _fdm.set_aircraft_path(os.path.join(path, 'aircraft')) _fdm.set_engine_path(os.path.join(path, 'engine')) _fdm.set_systems_path(os.path.join(path, 'systems')) return _fdm
def trim(aircraft, ic, design_vector, x0, verbose, cost=None, **kwargs): root = Path('.').resolve() fdm = jsbsim.FGFDMExec( str(root) ) # The path supplied to FGFDMExec is the location of the folders "aircraft", "engines" and "systems" fdm.set_debug_level(0) fdm.load_model(aircraft) # set location set_location_purdue_airport(fdm) fdm_props = fdm.get_property_catalog('') for key in design_vector + list(ic.keys()): if key not in fdm_props.keys(): raise KeyError(key) if cost is None: def cost(fdm): # compute cost, force moment balance udot = fdm['accelerations/udot-ft_sec2'] vdot = fdm['accelerations/vdot-ft_sec2'] wdot = fdm['accelerations/wdot-ft_sec2'] pdot = fdm['accelerations/pdot-rad_sec2'] qdot = fdm['accelerations/qdot-rad_sec2'] rdot = fdm['accelerations/rdot-rad_sec2'] return udot**2 + vdot**2 + wdot**2 + pdot**2 + qdot**2 + rdot**2 # cost function for trimming def trim_cost(fdm, xd): # set initial condition for var in ic.keys(): fdm[var] = ic[var] # set design vector for i, var in enumerate(design_vector): fdm[var] = xd[i] # trim propulsion prop = fdm.get_propulsion() prop.init_running(-1) # set initial conditions fdm.run_ic() return cost(fdm) res = scipy.optimize.minimize(fun=lambda xd: trim_cost(fdm, xd), x0=x0, **kwargs) if verbose: print(res) for i, var in enumerate(design_vector): ic[var] = res['x'][i] return ic, fdm, res
def __init__(self, sim_dt): path = os.path.dirname(os.path.realpath(__file__)) self.sim = jsbsim.FGFDMExec( root_dir=os.path.join(path, self.JSBSIM_DIR)) self.sim.set_debug_level(0) self.pos = (0, 0, 0) self.time: int = 0 self.sim_dt = sim_dt self.initialise(self.sim_dt, self.AIRCRAFT, None) self.wall_clock_dt = None self.output_enabled = False self.sim.disable_output()
def __init__(self, configuration_file: str = config.DEFAULT_CONFIGURATION_FILE): self.configuration = toml.load(os.path.expanduser(configuration_file)) self.jsbsim = jsbsim.FGFDMExec( os.path.expanduser( self.configuration['simulation']['path_jsbsim'])) self.jsbsim.set_debug_level(0) self.sim_dt = 1.0 / self.configuration['simulation']['jsbsim_dt_hz'] self.wall_clock_dt = 0 aircraft = Aircraft(**self.configuration['simulation']['aircraft']) self.initialise(aircraft)
def __init__(self, model, pathJSB='.', dt=1 / 200): self.model = model self.dt = dt self.pathJSB = pathJSB self.fdm = jsb.FGFDMExec(pathJSB, None) self.fdm.load_model(self.model) self.fdm.set_dt(self.dt) self.fileLog = []
def __init__(self, sim_frequency_hz: float = 60.0, aircraft: Aircraft = x8, init_conditions: Dict[prp.Property, float] = None, debug_level: int = 0): self.fdm = jsbsim.FGFDMExec(root_dir=self.ROOT_DIR) self.fdm.set_debug_level(debug_level) self.sim_dt = 1.0 / sim_frequency_hz self.aircraft = aircraft self.initialise(self.sim_dt, self.aircraft.jsbsim_id, init_conditions) self.fdm.disable_output() self.wall_clock_dt = None self.client = self.airsim_connect()
def create_fdm(sandbox, pm=None): """ A function that starts a jsbsim flight dynamic model and provides a path to each subsystem :param sandbox: the temp directory created by the Sandbox class :param pm: adds a relative path to the default sandbox jsbsim directory :return: the flight dynamic model """ _fdm = jsbsim.FGFDMExec(os.path.join(sandbox(), ''), pm) print('FDM located at:', os.path.join(sandbox(), '')) path = sandbox.path_to_jsbsim_file() _fdm.set_aircraft_path(os.path.join(path, 'aircraft')) _fdm.set_engine_path(os.path.join(path, 'engine')) _fdm.set_systems_path(os.path.join(path, 'systems')) return _fdm
def __init__(self, aircraft_name): self.fdm = jsbsim.FGFDMExec(root_dir='../../') assert type(aircraft_name) is str self.fdm.load_model(aircraft_name) self.fdm.set_property_value("ic/lat-gc-rad", 0.761552988) self.fdm.set_property_value("ic/long-gc-rad", 0.0239284344) self.fdm.set_property_value("ic/h-agl-ft", 400) self.fdm.set_property_value("ic/vc-kts", 30) #self.fdm.set_property_value("ic/gamma-deg",0) self.fdm.set_dt(0.01) self.fdm.do_trim(1) self.state_vector = self._getstatefromsimulation_() self.trajectory = AileronRoll(self.state_vector[3], self.state_vector[5], self.state_vector[6], self.state_vector[11])
def __init__(self, aircraft, delt): self.fdm = jsbsim.FGFDMExec('.') self.fdm.set_debug_level(0) self.fdm.load_model(aircraft) self.fdm.set_dt(delt) self.fdm.set_property_value("ic/lat-gc-deg", 47.0) self.fdm.set_property_value("ic/long-gc-deg", 122.0) self.fdm.set_property_value("ic/h-sl-ft", 2000) self.fdm.set_property_value("ic/u-fps", 450) self.fdm.set_property_value("ic/v-fps", 0) self.fdm.set_property_value("ic/w-fps", 0) self.fdm.set_property_value("ic/p-rad_sec", 0) self.fdm.set_property_value("ic/q-rad_sec", 0) self.fdm.set_property_value("ic/r-rad_sec", 0) self.fdm.set_property_value("ic/phi-rad", 0) self.fdm.set_property_value("ic/theta-rad", 1) self.fdm.set_property_value("ic/psi-true-rad", 0) self.fdm.set_property_value('propulsion/set-running', -1) self.fdm.run_ic() self.ref_state = self.state() self.next_state = self.state()
def trim(aircraft, ic, design_vector, x0, verbose, cost=None, eq_constraints=None, tol=1e-6, ftol=None, show=False, **kwargs): root = Path('.').resolve() fdm = jsbsim.FGFDMExec(str(root)) # The path supplied to FGFDMExec is the location of the folders "aircraft", "engines" and "systems" if show: fdm.set_output_directive(str(root/ 'data_output' / 'flightgear.xml')) fdm.set_debug_level(0) fdm.load_model(aircraft) # set location set_location_purdue_airport(fdm) fdm_props = fdm.get_property_catalog('') for key in design_vector + list(ic.keys()): if key not in fdm_props.keys(): raise KeyError(key) if cost is None: def cost(fdm): # compute cost, force moment balance theta = fdm['attitude/theta-rad'] udot = fdm['accelerations/udot-ft_sec2'] vdot = fdm['accelerations/vdot-ft_sec2'] wdot = fdm['accelerations/wdot-ft_sec2'] pdot = fdm['accelerations/pdot-rad_sec2'] qdot = fdm['accelerations/qdot-rad_sec2'] rdot = fdm['accelerations/rdot-rad_sec2'] # (theta < 0) term prevents nose down trim return udot**2 + vdot**2 + wdot**2 + \ pdot**2 + qdot**2 + rdot**2 + + 1e-3*(theta < 0) # cost function for trimming def eval_fdm_func(xd, fdm, ic, fdm_func): # set initial condition for var in ic.keys(): fdm[var] = ic[var] # set design vector for i, var in enumerate(design_vector): fdm[var] = xd[i] # trim propulsion prop = fdm.get_propulsion() prop.init_running(-1) # set initial conditions fdm.run_ic() return fdm_func(fdm) # setup constraints constraints = [] if eq_constraints is None: eq_constraints = [] for con in eq_constraints: constraints.append({ 'type': 'eq', 'fun': eval_fdm_func, 'args': (fdm, ic, con) }) # solve res = scipy.optimize.minimize( fun=eval_fdm_func, args=(fdm, ic, cost), x0=x0, constraints=constraints, **kwargs) if verbose: print(res) # update ic for i, var in enumerate(design_vector): ic[var] = res['x'][i] if verbose: for con in constraints: print('constraint', con['type'], con['fun'](res['x'], *con['args'])) if not res['success'] or ftol is not None and abs(res['fun']) > ftol: raise RuntimeError('trim failed:\n' + str(res) + '\n' + \ str(fdm.get_property_catalog('acceleration'))) props = fdm.get_property_catalog('') del fdm return ic, props
def linearize(aircraft, states, states_deriv, inputs, outputs, ic, dx, n_round=3): assert len(states_deriv) == len(states) root = Path('.').resolve() fdm = jsbsim.FGFDMExec(str(root)) # The path supplied to FGFDMExec is the location of the folders "aircraft", "engines" and "systems" fdm.set_debug_level(0) fdm.load_model(aircraft) fdm_props = fdm.get_property_catalog('') for key in states + inputs + outputs + list( ic.keys()): if key not in fdm_props.keys(): raise KeyError(key) for key in states_deriv: if key not in fdm_props.keys() and key != 'approximate': raise KeyError(key) n = len(states) p = len(inputs) m = len(outputs) def set_ic(): set_location_purdue_airport(fdm) for key in ic.keys(): fdm[key] = ic[key] fdm.get_propulsion().init_running(-1) fdm.run_ic() A = np.zeros((n, n)) C = np.zeros((m, n)) for i, state in enumerate(states): set_ic() start = fdm.get_property_catalog('') fdm[state] = start[state] + dx fdm.resume_integration() fdm.run() for j, state_deriv in enumerate(states_deriv): if state_deriv == 'approximate': A[j, i] = (fdm[states[j]] - start[states[j]])/fdm.get_delta_t() else: A[j, i] = (fdm[state_deriv] - start[state_deriv]) / dx for j, output in enumerate(outputs): C[j, i] = (fdm[output] - start[output]) / dx set_ic() B = np.zeros((n, p)) D = np.zeros((m, p)) for i, inp in enumerate(inputs): set_ic() start = fdm.get_property_catalog('') fdm[inp] = start[inp] + dx fdm.resume_integration() fdm.run() for j, state_deriv in enumerate(states_deriv): if state_deriv == 'approximate': B[j, i] = (fdm[states[j]] - start[states[j]])/fdm.get_delta_t() else: B[j, i] = (fdm[state_deriv] - start[state_deriv]) / dx for j, output in enumerate(outputs): D[j, i] = (fdm[output] - start[output]) / dx del fdm A = np.round(A, n_round) B = np.round(B, n_round) C = np.round(C, n_round) D = np.round(D, n_round) return (A, B, C, D)
def simulate(aircraft, op_0, op_list=None, tf=50, realtime=False, verbose=False): if op_list is None: op_list = [] root = Path('.').resolve() fdm = jsbsim.FGFDMExec(str(root)) # The path supplied to FGFDMExec is the location of the folders "aircraft", "engines" and "systems" # load model fdm.load_model(aircraft) fdm.set_output_directive(str(root/ 'data_output' / 'flightgear.xml')) fdm_props = fdm.get_property_catalog('') # add a method to check that properties being set exist def set_opereating_point(props): for key in props.keys(): if key not in fdm_props.keys(): raise KeyError(key) else: fdm[key] = props[key] # set location set_location_purdue_airport(fdm) # set operating points set_opereating_point(op_0) # start engines prop = fdm.get_propulsion() prop.init_running(-1) fdm.run_ic() # start loop log = Logger() nice = True sleep_nseconds = 500 initial_seconds = time.time() frame_duration = fdm.get_delta_t() op_count = 0 result = fdm.run() low_fuel_warned = False while result and fdm.get_sim_time() < tf: t = fdm.get_sim_time() if op_count < len(op_list) and op_list[op_count][2](fdm): if verbose: print('operating point reached: ', op_list[op_count][0]) set_opereating_point(op_list[op_count][1]) op_count += 1 # rough approximation of grade of runway 28 at purdue airport if fdm['position/distance-from-start-mag-mt'] < 2000: fdm['position/terrain-elevation-asl-ft'] = 586 + 0.02*fdm['position/distance-from-start-mag-mt'] if realtime: current_seconds = time.time() actual_elapsed_time = current_seconds - initial_seconds sim_lag_time = actual_elapsed_time - fdm.get_sim_time() for _ in range(int(sim_lag_time / frame_duration)): result = fdm.run() current_seconds = time.time() else: result = fdm.run() if nice: time.sleep(sleep_nseconds / 1000000.0) if not low_fuel_warned and fdm['propulsion/total-fuel-lbs'] < 10: print('warning: LOW FUEL {:0.2f} lbs, restart simulation'.format(fdm['propulsion/total-fuel-lbs'])) low_fuel_warned = True log.new_frame(t, fdm.get_property_catalog('')) log = log.to_pandas() del fdm return log
def simulate(aircraft, op_0, op_list=None, op_times=None, tf=50, realtime=False): if op_list is None: op_list = [] if op_times is None: op_times = [] root = Path('.').resolve() fdm = jsbsim.FGFDMExec( str(root) ) # The path supplied to FGFDMExec is the location of the folders "aircraft", "engines" and "systems" # load model fdm.load_model(aircraft) fdm.set_output_directive(str(root / 'data_output' / 'flightgear.xml')) fdm_props = fdm.get_property_catalog('') # add a method to check that properties being set exist def set_opereating_point(props): for key in props.keys(): if key not in fdm_props.keys(): raise KeyError(key) else: fdm[key] = props[key] # set location set_location_purdue_airport(fdm) # set operating points set_opereating_point(op_0) # start engines prop = fdm.get_propulsion() prop.init_running(-1) fdm.run_ic() # start loop log = Logger() nice = True sleep_nseconds = 500 initial_seconds = time.time() frame_duration = fdm.get_delta_t() op_count = 0 result = fdm.run() while result and fdm.get_sim_time() < tf: t = fdm.get_sim_time() if op_count < len(op_times) and t > op_times[op_count]: set_opereating_point(op_list[op_count]) op_count += 1 if realtime: current_seconds = time.time() actual_elapsed_time = current_seconds - initial_seconds sim_lag_time = actual_elapsed_time - fdm.get_sim_time() for _ in range(int(sim_lag_time / frame_duration)): result = fdm.run() current_seconds = time.time() else: result = fdm.run() if nice: time.sleep(sleep_nseconds / 1000000.0) log.new_frame(t, fdm.get_property_catalog('')) log = log.to_pandas() return log
fuelmax = 8097.63 #prepare subplots to overlay plots fig, ax = plt.subplots(figsize=(10, 8)) #Define here the payloads to be studied payload = [1500, 15172 / 2, 15172] #Define here the mass of fuel fuel = [1000, fuelmax / 2, fuelmax] #three cases for weight weight = ["light", "mid", "heavy"] #put your path here PATH_TO_JSBSIM_FILES = "../../" fdm = jsbsim.FGFDMExec(PATH_TO_JSBSIM_FILES) #get the original CG from aircraft xml cgOrig = float(changeCG(fdm, 0, True)) #vary CG in the study cgPos = [cgOrig * 0.95, cgOrig * 1.05] #vary altitude h_ft = [8000, 30000] #run the simulation varying CG, altitude, speed and total weight #run for different CG's for j in range(2): #points to jsbsim executable and make an object fdm = jsbsim.FGFDMExec(PATH_TO_JSBSIM_FILES) fdm.load_model('global5000')
import jsbsim import numpy as np import matplotlib.pyplot as plt import keyboard # using module keyboard from funcinclude import * # ECEF reference point lat0 = 47.8303295 lon0 = 16.2562515 alt0 = 0 fdm = jsbsim.FGFDMExec('.', None) #fdm.load_script('scripts/737_cruise.xml', delta_t=0.1,initfile='cruise_init.xml') #fdm.load_script('scripts/737_custom.xml', delta_t=0.1,initfile='custom.xml') fdm.load_model("ogel") #fdm.load_model("c172p") #fdm.load_model("trogon") frame_duration = fdm.get_delta_t() fdm.set_dt(0.1) # set dt fdm.set_logging_rate(0.5) fdm.set_output_filename(0, "testOutTT.csv") fdm.enable_output() #fdm.run_ic() fdm.print_property_catalog() # list avaliable properties #atm = fdm.get_atmosphere() #aircraft = fdm.get_aircraft()
args.script = args.input if root.tag == 'output': if args.logdirectivefile: args.logdirectivefile += [args.input] else: args.logdirectivefile = [args.input] if root.tag == 'fdm_config': if args.aircraft: print('Two aircraft files are specified.') sys.exit(1) else: args.aircraft = args.input fdm = jsbsim.FGFDMExec(args.root, None) if args.script: fdm.load_script(args.script) elif args.aircraft: fdm.load_model(args.aircraft, False) if args.initfile: fdm.load_ic(args.initfile, True) if args.initfile and not args.aircraft: print("You must specify an initilization file with the aircraft name") sys.exit(1) if args.logdirectivefile: for f in args.logdirectivefile: if not fdm.set_output_directive(f):
Created on Wed May 6 15:04:25 2020 @author: rega0051 """ from os import path import time import jsbsim as jsb #%% # Launch FGFS #./fgfs_JSBSim.sh UltraStick25e pathJSB = '.' fdm = jsb.FGFDMExec(pathJSB, None) model = 'UltraStick25e' #%% Setup fdm.load_model(model) fdm.set_dt(1 / 200) # Load IC file #fileIC = path.join(fdm.get_aircraft_path(), model, 'initCruise.xml') fdm.load_ic('initCruise.xml', True) # Setup JSBSim to FlightGear fdm.set_output_directive(path.join('scripts', 'OutputFgfs.xml')) # Setup JSBSim Logging
import os import toml import jsbsim configuration = toml.load( '../config/default_configuration.toml' ) # included: '/Users/######/Programme/jsbsim-code' #an System anpassen. sim = jsbsim.FGFDMExec( os.path.expanduser(configuration["simulation"]["path_jsbsim"])) sim.load_model('c172p') print(sim.print_property_catalog())