def testAircrafts(self): aircraft_path = self.sandbox.path_to_jsbsim_file('aircraft') for d in os.listdir(aircraft_path): fullpath = os.path.join(aircraft_path, d) # Is d a directory ? if not os.path.isdir(fullpath): continue f = os.path.join(aircraft_path, d, d + '.xml') # Is f an aircraft definition file ? if not CheckXMLFile(f, 'fdm_config'): continue if d in ('blank'): continue fdm = CreateFDM(self.sandbox) self.assertTrue(fdm.load_model(d), msg='Failed to load aircraft %s' % (d, )) for f in os.listdir(fullpath): f = os.path.join(aircraft_path, d, f) if CheckXMLFile(f, 'initialize'): self.assertTrue( fdm.load_ic(f, False), msg='Failed to load IC %s for aircraft %s' % (f, d)) try: fdm.run_ic() except RuntimeError: self.fail('Failed to run IC %s for aircraft %s' % (f, d)) del fdm
def testScripts(self): script_path = self.sandbox.path_to_jsbsim_file('scripts') for f in os.listdir(self.sandbox.elude(script_path)): fullpath = os.path.join(self.sandbox.elude(script_path), f) # Does f contains a JSBSim script ? if not CheckXMLFile(fullpath, 'runscript'): continue fdm = CreateFDM(self.sandbox) self.assertTrue(fdm.load_script(os.path.join(script_path, f)), msg="Failed to load script %s" % (fullpath, )) fdm.run_ic() self.scripts += 1 del fdm
def test_initial_conditions(self): prop_output_to_CSV = ['velocities/vc-kts'] # A dictionary that contains the XML tags to extract from the IC file # along with the name of the properties that contain the values # extracted from the IC file. vars = [{'tag': 'vt', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/vt-fps', 'prop': 'velocities/vt-fps', 'CSV_header': 'V_{Total} (ft/s)'}, {'tag': 'vc', 'unit': convtokts, 'default_unit': 'KTS', 'ic_prop': 'ic/vc-kts', 'prop': 'velocities/vc-kts', 'CSV_header': '/fdm/jsbsim/velocities/vc-kts'}, {'tag': 'ubody', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/u-fps', 'prop': 'velocities/u-fps', 'CSV_header': 'UBody'}, {'tag': 'vbody', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/v-fps', 'prop': 'velocities/v-fps', 'CSV_header': 'VBody'}, {'tag': 'wbody', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/w-fps', 'prop': 'velocities/w-fps', 'CSV_header': 'WBody'}, {'tag': 'vnorth', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/vn-fps', 'prop': 'velocities/v-north-fps', 'CSV_header': 'V_{North} (ft/s)'}, {'tag': 'veast', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/ve-fps', 'prop': 'velocities/v-east-fps', 'CSV_header': 'V_{East} (ft/s)'}, {'tag': 'vdown', 'unit': convtofps, 'default_unit': 'FT/SEC', 'ic_prop': 'ic/vd-fps', 'prop': 'velocities/v-down-fps', 'CSV_header': 'V_{Down} (ft/s)'}, {'tag': 'latitude', 'unit': convtodeg, 'default_unit': 'RAD', 'ic_prop': 'ic/lat-gc-deg', 'prop': 'position/lat-gc-deg', 'CSV_header': 'Latitude (deg)'}, {'tag': 'longitude', 'unit': convtodeg, 'default_unit': 'RAD', 'ic_prop': 'ic/long-gc-deg', 'prop': 'position/long-gc-deg', 'CSV_header': 'Longitude (deg)'}, {'tag': 'altitude', 'unit': convtoft, 'default_unit': 'FT', 'ic_prop': 'ic/h-agl-ft', 'prop': 'position/h-agl-ft', 'CSV_header': 'Altitude AGL (ft)'}, {'tag': 'altitudeAGL', 'unit': convtoft, 'default_unit': 'FT', 'ic_prop': 'ic/h-agl-ft', 'prop': 'position/h-agl-ft', 'CSV_header': 'Altitude AGL (ft)'}, {'tag': 'altitudeMSL', 'unit': convtoft, 'default_unit': 'FT', 'ic_prop': 'ic/h-sl-ft', 'prop': 'position/h-sl-ft', 'CSV_header': 'Altitude ASL (ft)'}, {'tag': 'phi', 'unit': convtodeg, 'default_unit': 'RAD', 'ic_prop': 'ic/phi-deg', 'prop': 'attitude/phi-deg', 'CSV_header': 'Phi (deg)'}, {'tag': 'theta', 'unit': convtodeg, 'default_unit': 'RAD', 'ic_prop': 'ic/theta-deg', 'prop': 'attitude/theta-deg', 'CSV_header': 'Theta (deg)'}, {'tag': 'psi', 'unit': convtodeg, 'default_unit': 'RAD', 'ic_prop': 'ic/psi-true-deg', 'prop': 'attitude/psi-deg', 'CSV_header': 'Psi (deg)'}, {'tag': 'elevation', 'unit': convtoft, 'default_unit': 'FT', 'ic_prop': 'ic/terrain-elevation-ft', 'prop': 'position/terrain-elevation-asl-ft', 'CSV_header': 'Terrain Elevation (ft)'}] script_path = self.sandbox.path_to_jsbsim_file('scripts') for f in os.listdir(self.sandbox.elude(script_path)): # TODO These scripts need some further investigation if f in ('ZLT-NT-moored-1.xml', '737_cruise_steady_turn_simplex.xml'): continue fullpath = os.path.join(self.sandbox.elude(script_path), f) # Does f contains a JSBSim script ? if not CheckXMLFile(fullpath, 'runscript'): continue # Read the IC file name from the script tree = et.parse(fullpath) root = tree.getroot() use_tag = root.find('use') aircraft_name = use_tag.attrib['aircraft'] aircraft_path = os.path.join('aircraft', aircraft_name) path_to_jsbsim_aircrafts = self.sandbox.elude(self.sandbox.path_to_jsbsim_file(aircraft_path)) IC_file = append_xml(use_tag.attrib['initialize']) IC_tree = et.parse(os.path.join(path_to_jsbsim_aircrafts, IC_file)) IC_root = IC_tree.getroot() # Only testing version 1.0 of init files if 'version' in IC_root.attrib: if float(IC_root.attrib['version']) == 2.0: continue # Extract the IC values from XML for var in vars: var_tag = IC_root.find('./'+var['tag']) var['specified'] = var_tag is not None if not var['specified']: var['value'] = 0.0 continue var['value'] = float(var_tag.text) if 'unit' in var_tag.attrib: conv = var['unit'][var_tag.attrib['unit']] else: conv = var['unit'][var['default_unit']] var['value'] *= conv # Generate a CSV file to check that it is correctly initialized # with the initial values output_tag = et.SubElement(root, 'output') output_tag.attrib['name'] = 'check_csv_values.csv' output_tag.attrib['type'] = 'CSV' output_tag.attrib['rate'] = '10' position_tag = et.SubElement(output_tag, 'position') position_tag.text = 'ON' velocities_tag = et.SubElement(output_tag, 'velocities') velocities_tag.text = 'ON' for props in prop_output_to_CSV: property_tag = et.SubElement(output_tag, 'property') property_tag.text = props tree.write(self.sandbox(f)) # Initialize the script fdm = CreateFDM(self.sandbox) fdm.load_script(f) fdm.run_ic() # Sanity check, we just initialized JSBSim with the ICs, the time # must be set to 0.0 self.assertEqual(fdm.get_property_value('simulation/sim-time-sec'), 0.0) # Check that the properties (including in 'ic/') have been # correctly initialized (i.e. that they contain the value read from # the XML file). for var in vars: if not var['specified']: continue value = var['value'] prop = fdm.get_property_value(var['ic_prop']) if var['tag'] == 'psi': if abs(prop - 360.0) <= 1E-8: prop = 0.0 self.assertAlmostEqual(value, prop, delta=1E-7, msg="In script %s: %s should be %f but found %f" % (f, var['tag'], value, prop)) prop = fdm.get_property_value(var['prop']) if var['tag'] == 'psi': if abs(prop - 360.0) <= 1E-8: prop = 0.0 self.assertAlmostEqual(value, prop, delta=1E-7, msg="In script %s: %s should be %f but found %f" % (f, var['tag'], value, prop)) # Execute the first second of the script. This is to make sure that # the CSV file is open and the ICs have been written in it. try: ExecuteUntil(fdm, 1.0) except RuntimeError as e: if e.args[0] == 'Trim Failed': self.fail("Trim failed in script %s" % (f,)) else: raise # Copies the CSV file content in a table ref = pd.read_csv(self.sandbox('check_csv_values.csv')) # Sanity check: make sure that the time step 0.0 has been copied in # the CSV file. self.assertEqual(ref['Time'][0], 0.0) # Check that the value in the CSV file equals the value read from # the IC file. for var in vars: if not var['specified']: continue value = var['value'] csv_value = ref[var['CSV_header']][0] if var['tag'] == 'psi': if abs(csv_value - 360.0) <= 1E-8: csv_value = 0.0 self.assertAlmostEqual(value, csv_value, delta=1E-7, msg="In script %s: %s should be %f but found %f" % (f, var['tag'], value, csv_value)) del fdm