Exemple #1
0
    def Compare(self, section):
        # Rerun the script with the modified aircraft definition
        self.sandbox.delete_csv_files()
        fdm = CreateFDM(self.sandbox)
        # We need to tell JSBSim that the aircraft definition is located in the
        # directory build/.../aircraft
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.load_script(self.script)
        fdm['simulation/randomseed'] = 0.0

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = pd.read_csv('output.csv', index_col=0)

        # Check the data are matching i.e. the time steps are the same between
        # the two data sets and that the output data are also the same.
        self.assertTrue(isDataMatching(self.ref, mod))

        # Whether the data is read from the aircraft definition file or from an
        # external file, the results shall be exactly identical. Hence the
        # precision set to 0.0.
        diff = FindDifferences(self.ref, mod, 0.0)
        self.assertEqual(len(diff), 0,
                         msg='\nTesting section "'+section+'"\n'+diff.to_string())
Exemple #2
0
    def test_gust_reset(self):
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(self.sandbox.path_to_jsbsim_file('scripts',
                                                         'c172_cruise_8K.xml'))
        fdm['simulation/randomseed'] = 0.0
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))

        fdm.run_ic()
        ExecuteUntil(fdm, 15.5)

        ref = pd.read_csv('output.csv', index_col=0)

        fdm['simulation/randomseed'] = 0.0
        fdm.reset_to_initial_conditions(1)
        ExecuteUntil(fdm, 15.5)

        current = pd.read_csv('output_0.csv', index_col=0)

        # Check the data are matching i.e. the time steps are the same between
        # the two data sets and that the output data are also the same.
        self.assertTrue(isDataMatching(ref, current))

        # Find all the data that are differing by more than 1E-8 between the
        # two data sets.
        diff = FindDifferences(ref, current, 1E-8)
        self.longMessage = True
        self.assertEqual(len(diff), 0, msg='\n'+diff.to_string())
Exemple #3
0
    def Compare(self, section):
        # Rerun the script with the modified aircraft definition
        self.sandbox.delete_csv_files()
        fdm = CreateFDM(self.sandbox)
        # We need to tell JSBSim that the aircraft definition is located in the
        # directory build/.../aircraft
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        fdm.load_script(self.script)
        fdm['simulation/randomseed'] = 0.0

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = pd.read_csv('output.csv', index_col=0)

        # Check the data are matching i.e. the time steps are the same between
        # the two data sets and that the output data are also the same.
        self.assertTrue(isDataMatching(self.ref, mod))

        # Whether the data is read from the aircraft definition file or from an
        # external file, the results shall be exactly identical. Hence the
        # precision set to 0.0.
        diff = FindDifferences(self.ref, mod, 0.0)
        self.assertEqual(len(diff),
                         0,
                         msg='\nTesting section "' + section + '"\n' +
                         diff.to_string())
    def Compare(self, section):
        # Rerun the script with the modified aircraft definition
        self.sandbox.delete_csv_files()
        fdm = CreateFDM(self.sandbox)
        # We need to tell JSBSim that the aircraft definition is located in the
        # directory build/.../aircraft
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        fdm.load_script(self.script)
        fdm.set_property_value('simulation/randomseed', 0.0)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = Table()
        mod.ReadCSV(self.sandbox('output.csv'))

        # Whether the data is read from the aircraft definition file or from an
        # external file, the results shall be exactly identical. Hence the
        # precision set to 0.0.
        diff = self.ref.compare(mod, 0.0)
        self.assertTrue(diff.empty(),
                        msg='\nTesting section "' + section + '"\n' +
                        repr(diff))
Exemple #5
0
    def test_initial_latitude(self):
        Output_file = self.sandbox.path_to_jsbsim_file('tests', 'output.xml')
        GEODETIC, ELEVATION, ALTITUDE = (1, 2, 4)

        for v in ('', '_v2'):
            IC_file = self.sandbox.path_to_jsbsim_file('aircraft', 'ball',
                                                       'reset00' + v + '.xml')

            for i in xrange(8):
                for latitude_pos in xrange(4):
                    IC_tree = et.parse(IC_file)
                    IC_root = IC_tree.getroot()
                    if v:
                        position_tag = IC_root.find('position')
                        latitude_tag = et.SubElement(position_tag, 'latitude')
                        latitude_tag.attrib['unit'] = 'DEG'
                    else:
                        position_tag = IC_root
                        latitude_tag = IC_root.find('latitude')

                    latitude_tag.text = str(latitude_pos * 30.)

                    if i & GEODETIC:
                        latitude_tag.attrib['type'] = 'geod'

                    if i & ELEVATION:
                        elevation_tag = et.SubElement(IC_root, 'elevation')
                        elevation_tag.text = '1000.'

                    if i & ALTITUDE:
                        if v:
                            altitude_tag = position_tag.find('altitudeMSL')
                            altitude_tag.tag = 'altitudeAGL'
                        else:
                            altitude_tag = position_tag.find('altitude')
                            altitude_tag.tag = 'altitudeMSL'

                    IC_tree.write('IC.xml')

                    fdm = CreateFDM(self.sandbox)
                    fdm.load_model('ball')
                    fdm.set_output_directive(Output_file)
                    fdm.set_output_filename(1, 'check_csv_values.csv')
                    fdm.load_ic('IC.xml', False)
                    fdm.run_ic()

                    self.CheckICValues(self.GetVariables(latitude_tag),
                                       'IC%d' % (i, ), fdm, position_tag)

                    del fdm
    def test_initial_latitude(self):
        Output_file = self.sandbox.path_to_jsbsim_file('tests', 'output.xml')
        GEODETIC, ELEVATION, ALTITUDE = (1, 2, 4)

        for v in ('', '_v2'):
            IC_file = self.sandbox.path_to_jsbsim_file('aircraft', 'ball',
                                                       'reset00'+v+'.xml')

            for i in xrange(8):
                for latitude_pos in xrange(4):
                    IC_tree = et.parse(IC_file)
                    IC_root = IC_tree.getroot()
                    if v:
                        position_tag = IC_root.find('position')
                        latitude_tag = et.SubElement(position_tag, 'latitude')
                        latitude_tag.attrib['unit'] = 'DEG'
                    else:
                        position_tag = IC_root
                        latitude_tag = IC_root.find('latitude')

                    latitude_tag.text = str(latitude_pos*30.)

                    if i & GEODETIC:
                        latitude_tag.attrib['type'] = 'geod'

                    if i & ELEVATION:
                        elevation_tag = et.SubElement(IC_root, 'elevation')
                        elevation_tag.text = '1000.'

                    if i & ALTITUDE:
                        if v:
                            altitude_tag = position_tag.find('altitudeMSL')
                            altitude_tag.tag = 'altitudeAGL'
                        else:
                            altitude_tag = position_tag.find('altitude')
                            altitude_tag.tag = 'altitudeMSL'

                    IC_tree.write('IC.xml')

                    fdm = CreateFDM(self.sandbox)
                    fdm.load_model('ball')
                    fdm.set_output_directive(Output_file)
                    fdm.set_output_filename(1, 'check_csv_values.csv')
                    fdm.load_ic('IC.xml', False)
                    fdm.run_ic()

                    self.CheckICValues(self.GetVariables(latitude_tag),
                                       'IC%d' % (i,), fdm, position_tag)

                    del fdm
    def testUnitConversion(self):
        shutil.copy(self.sandbox.path_to_jsbsim_file('tests',
                                                     'output2.xml'),'.')
        shutil.copy(self.sandbox.path_to_jsbsim_file('tests',
                                                     'unitconversion.xml'),'.')
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'c1723.xml')
        fdm = CreateFDM(self.sandbox)
        fdm.set_output_directive('output2.xml')
        fdm.load_script(script_path)
        fdm.run_ic()
        ExecuteUntil(fdm, 10.)

        ref = pd.read_csv("output2.csv", index_col=0)
        self.assertAlmostEqual(np.abs(ref['/fdm/jsbsim/aero/alpha-deg']-
                                      ref['template/alpha-deg']).max(), 0.0)
        self.assertAlmostEqual(np.abs(ref['pre/p-aero-deg_sec']-
                                      ref['template/p-aero-deg_sec']).max(), 0.0)
Exemple #8
0
    def testDragFunctions(self):
        fdm = CreateFDM(self.sandbox)
        self.script_path = self.sandbox.path_to_jsbsim_file('scripts',
                                                            'x153.xml')
        fdm.load_script(self.script_path)
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.run_ic()

        while fdm.run():
            pass

        results = pd.read_csv('output.csv', index_col=0)
        Fdrag = results['F_{Drag} (lbs)']
        CDmin = results['aero/coefficient/CDmin']
        CDi = results['aero/coefficient/CDi']
        self.assertAlmostEqual(abs(Fdrag/(CDmin+CDi)).max(), 1.0, delta=1E-5)
Exemple #9
0
    def test_gust_reset(self):
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(self.sandbox.path_to_jsbsim_file('scripts', 'c172_cruise_8K.xml'))
        fdm.set_property_value('simulation/randomseed', 0.0)
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))

        fdm.run_ic()
        ExecuteUntil(fdm, 15.5)

        ref, current = Table(), Table()
        ref.ReadCSV(self.sandbox('output.csv'))

        fdm.set_property_value('simulation/randomseed', 0.0)
        fdm.reset_to_initial_conditions(1)
        ExecuteUntil(fdm, 15.5)

        current.ReadCSV(self.sandbox('output_0.csv'))

        diff = ref.compare(current)
        self.longMessage = True
        self.assertTrue(diff.empty(), msg='\n'+repr(diff))
Exemple #10
0
    def BuildReference(self, script_name):
        # Run the script
        self.script = self.sandbox.path_to_jsbsim_file('scripts', script_name)
        self.sandbox.delete_csv_files()
        fdm = CreateFDM(self.sandbox)
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.load_script(self.script)
        fdm['simulation/randomseed'] = 0.0

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        self.ref = pd.read_csv("output.csv", index_col=0)

        # Since the script will work with modified versions of the aircraft XML
        # definition file, we need to make a copy of the directory that
        # contains all the input data of that aircraft

        tree, self.aircraft_name, self.path_to_jsbsim_aircrafts = CopyAircraftDef(self.script, self.sandbox)
        self.aircraft_path = os.path.join('aircraft', self.aircraft_name)
Exemple #11
0
    def BuildReference(self, script_name):
        # Run the script
        self.script = self.sandbox.path_to_jsbsim_file('scripts', script_name)
        self.sandbox.delete_csv_files()
        fdm = CreateFDM(self.sandbox)
        fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        fdm.load_script(self.script)
        fdm['simulation/randomseed'] = 0.0

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        self.ref = pd.read_csv("output.csv", index_col=0)

        # Since the script will work with modified versions of the aircraft XML
        # definition file, we need to make a copy of the directory that
        # contains all the input data of that aircraft

        tree, self.aircraft_name, self.path_to_jsbsim_aircrafts = CopyAircraftDef(
            self.script, self.sandbox)
        self.aircraft_path = os.path.join('aircraft', self.aircraft_name)
    def test_set_initial_geodetic_latitude(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts',
                                                       '737_cruise.xml')
        output_file = self.sandbox.path_to_jsbsim_file('tests', 'output.xml')
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(script_path)
        fdm.set_output_directive(output_file)

        alt = fdm['ic/h-sl-ft']
        glat = fdm['ic/lat-geod-deg'] - 30.
        fdm['ic/lat-geod-deg'] = glat
        fdm.run_ic()

        self.assertAlmostEqual(fdm['ic/h-sl-ft'], alt)
        self.assertAlmostEqual(fdm['ic/lat-geod-deg'], glat)
        self.assertAlmostEqual(fdm['ic/lat-geod-rad'], glat*math.pi/180.)
        self.assertAlmostEqual(fdm['position/lat-geod-deg'], glat)

        # Sanity check: make sure that the time step 0.0 has been copied in the
        # CSV file.
        ref = pd.read_csv('output.csv')
        self.assertEqual(ref['Time'][0], 0.0)
        self.assertAlmostEqual(ref['Latitude Geodetic (deg)'][0], glat)
Exemple #13
0
    def test_gust_reset(self):
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(
            self.sandbox.path_to_jsbsim_file('scripts', 'c172_cruise_8K.xml'))
        fdm.set_property_value('simulation/randomseed', 0.0)
        fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))

        fdm.run_ic()
        ExecuteUntil(fdm, 15.5)

        ref, current = Table(), Table()
        ref.ReadCSV(self.sandbox('output.csv'))

        fdm.set_property_value('simulation/randomseed', 0.0)
        fdm.reset_to_initial_conditions(1)
        ExecuteUntil(fdm, 15.5)

        current.ReadCSV(self.sandbox('output_0.csv'))

        diff = ref.compare(current)
        self.longMessage = True
        self.assertTrue(diff.empty(), msg='\n' + repr(diff))
    def Compare(self, section):
        # Rerun the script with the modified aircraft definition
        self.sandbox.delete_csv_files()
        fdm = CreateFDM(self.sandbox)
        # We need to tell JSBSim that the aircraft definition is located in the
        # directory build/.../aircraft
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        fdm.load_script(self.script)
        fdm.set_property_value('simulation/randomseed', 0.0)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = Table()
        mod.ReadCSV(self.sandbox('output.csv'))

        # Whether the data is read from the aircraft definition file or from an
        # external file, the results shall be exactly identical. Hence the
        # precision set to 0.0.
        diff = self.ref.compare(mod, 0.0)
        self.assertTrue(diff.empty(),
                        msg='\nTesting section "'+section+'"\n'+repr(diff))
Exemple #15
0
    def test_set_initial_geodetic_latitude(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts',
                                                       '737_cruise.xml')
        output_file = self.sandbox.path_to_jsbsim_file('tests', 'output.xml')
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(script_path)
        fdm.set_output_directive(output_file)

        alt = fdm['ic/h-sl-ft']
        glat = fdm['ic/lat-geod-deg'] - 30.
        fdm['ic/lat-geod-deg'] = glat
        fdm.run_ic()

        self.assertAlmostEqual(fdm['ic/h-sl-ft'], alt)
        self.assertAlmostEqual(fdm['ic/lat-geod-deg'], glat)
        self.assertAlmostEqual(fdm['ic/lat-geod-rad'], glat * math.pi / 180.)
        self.assertAlmostEqual(fdm['position/lat-geod-deg'], glat)

        # Sanity check: make sure that the time step 0.0 has been copied in the
        # CSV file.
        ref = pd.read_csv('output.csv')
        self.assertEqual(ref['Time'][0], 0.0)
        self.assertAlmostEqual(ref['Latitude Geodetic (deg)'][0], glat)
    def test_point_mass_inertia(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'J2460.xml')
        fdm = CreateFDM(self.sandbox)
        fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        fdm.load_script(script_path)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        ref = pd.read_csv("output.csv", index_col=0)

        tree, aircraft_name, path_to_jsbsim_aircrafts = CopyAircraftDef(
            script_path, self.sandbox)

        pointmass_element = tree.getroot().find(
            'mass_balance/pointmass//form/..')
        weight_element = pointmass_element.find('weight')
        weight = float(weight_element.text)
        form_element = pointmass_element.find('form')
        radius_element = form_element.find('radius')
        radius, length = (0.0, 0.0)
        if radius_element is not None:
            radius = float(radius_element.text)
        length_element = form_element.find('length')
        if length_element is not None:
            length = float(length_element.text)
        shape = form_element.attrib['shape']
        pointmass_element.remove(form_element)

        inertia = np.zeros((3, 3))
        if string.strip(shape) == 'tube':
            inertia[0, 0] = radius * radius
            inertia[1, 1] = (6.0 * inertia[0, 0] + length * length) / 12.0
            inertia[2, 2] = inertia[1, 1]

        inertia = inertia * weight / 32.174049  # converting slugs to lbs

        ixx_element = et.SubElement(pointmass_element, 'ixx')
        ixx_element.text = str(inertia[0, 0])
        iyy_element = et.SubElement(pointmass_element, 'iyy')
        iyy_element.text = str(inertia[1, 1])
        izz_element = et.SubElement(pointmass_element, 'izz')
        izz_element.text = str(inertia[2, 2])

        tree.write(
            self.sandbox('aircraft', aircraft_name, aircraft_name + '.xml'))

        # Because JSBSim internals use static pointers, we cannot rely on
        # Python garbage collector to decide when the FDM is destroyed
        # otherwise we can get dangling pointers.
        del fdm

        fdm = CreateFDM(self.sandbox)
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        fdm.load_script(script_path)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = pd.read_csv("output.csv", index_col=0)

        # Check the data are matching i.e. the time steps are the same between
        # the two data sets and that the output data are also the same.
        self.assertTrue(isDataMatching(ref, mod))

        # Find all the data that are differing by more than 1E-8 between the
        # two data sets.
        diff = FindDifferences(ref, mod, 1E-8)
        self.longMessage = True
        self.assertEqual(len(diff), 0, msg='\n' + diff.to_string())
    def test_point_mass_inertia(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'J2460.xml')
        fdm = CreateFDM(self.sandbox)
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.load_script(script_path)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        ref = pd.read_csv("output.csv", index_col=0)

        tree, aircraft_name, path_to_jsbsim_aircrafts = CopyAircraftDef(script_path, self.sandbox)

        pointmass_element = tree.getroot().find('mass_balance/pointmass//form/..')
        weight_element = pointmass_element.find('weight')
        weight = float(weight_element.text)
        form_element = pointmass_element.find('form')
        radius_element = form_element.find('radius')
        radius, length = (0.0, 0.0)
        if radius_element is not None:
            radius = float(radius_element.text)
        length_element = form_element.find('length')
        if length_element is not None:
            length = float(length_element.text)
        shape = form_element.attrib['shape']
        pointmass_element.remove(form_element)

        inertia = np.zeros((3, 3))
        if string.strip(shape) == 'tube':
            inertia[0, 0] = radius * radius
            inertia[1, 1] = (6.0 * inertia[0, 0] + length * length) / 12.0
            inertia[2, 2] = inertia[1, 1]

        inertia = inertia * weight / 32.174049  # converting slugs to lbs

        ixx_element = et.SubElement(pointmass_element, 'ixx')
        ixx_element.text = str(inertia[0, 0])
        iyy_element = et.SubElement(pointmass_element, 'iyy')
        iyy_element.text = str(inertia[1, 1])
        izz_element = et.SubElement(pointmass_element, 'izz')
        izz_element.text = str(inertia[2, 2])

        tree.write(self.sandbox('aircraft', aircraft_name,
                                aircraft_name+'.xml'))

        # Because JSBSim internals use static pointers, we cannot rely on
        # Python garbage collector to decide when the FDM is destroyed
        # otherwise we can get dangling pointers.
        del fdm

        fdm = CreateFDM(self.sandbox)
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.load_script(script_path)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = pd.read_csv("output.csv", index_col=0)

        # Check the data are matching i.e. the time steps are the same between
        # the two data sets and that the output data are also the same.
        self.assertTrue(isDataMatching(ref, mod))

        # Find all the data that are differing by more than 1E-8 between the
        # two data sets.
        diff = FindDifferences(ref, mod, 1E-8)
        self.longMessage = True
        self.assertEqual(len(diff), 0, msg='\n'+diff.to_string())
class CheckMomentsUpdate(JSBSimTestCase):
    def CheckCGPosition(self):
        weight = self.fdm['inertia/weight-lbs']
        empty_weight = self.fdm['inertia/empty-weight-lbs']
        contents = self.fdm['buoyant_forces/gas-cell/contents-mol']
        radiosonde_weight = weight - empty_weight - contents * mol2lbs

        CGx = self.fdm['inertia/cg-x-in']
        CGy = self.fdm['inertia/cg-y-in']
        CGz = self.fdm['inertia/cg-z-in']
        X = self.fdm['inertia/pointmass-location-X-inches']
        Y = self.fdm['inertia/pointmass-location-Y-inches']
        Z = self.fdm['inertia/pointmass-location-Z-inches']

        self.assertAlmostEqual(CGx, X * radiosonde_weight / weight, delta=1E-7)
        self.assertAlmostEqual(CGy, Y * radiosonde_weight / weight, delta=1E-7)
        self.assertAlmostEqual(CGz, Z * radiosonde_weight / weight, delta=1E-7)

    def test_moments_update(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts',
                                                       'weather-balloon.xml')
        self.fdm = CreateFDM(self.sandbox)

        self.fdm.load_script(script_path)
        self.fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        self.fdm.run_ic()

        self.CheckCGPosition()

        dt = self.fdm['simulation/dt']
        ExecuteUntil(self.fdm, 1.0-2.0*dt)

        self.CheckCGPosition()

        # Moves the radio sonde to modify the CG location
        self.fdm['inertia/pointmass-location-X-inches'] = 5.0

        # Check that the moment is immediately updated accordingly
        self.fdm.run()
        self.CheckCGPosition()

        Fbx = self.fdm['forces/fbx-buoyancy-lbs']
        Fbz = self.fdm['forces/fbz-buoyancy-lbs']
        CGx = self.fdm['inertia/cg-x-in'] / 12.0  # Converts from in to ft
        CGz = self.fdm['inertia/cg-z-in'] / 12.0
        Mby = self.fdm['moments/m-buoyancy-lbsft']

        self.assertAlmostEqual(Fbx * CGz - Fbz * CGx, Mby, delta=1E-7,
                               msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" % (Fbx*CGz-Fbz*CGx, Mby))

        # One further step to log the same results in the output file
        self.fdm.run()
        self.CheckCGPosition()

        csv = pd.read_csv('output.csv')
        Mby = csv['M_{Buoyant} (ft-lbs)'].iget(-1)
        Fbx = csv['F_{Buoyant x} (lbs)'].iget(-1)
        Fbz = csv['F_{Buoyant z} (lbs)'].iget(-1)

        self.assertAlmostEqual(Fbx * CGz - Fbz * CGx, Mby, delta=1E-7,
                               msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" % (Fbx*CGz-Fbz*CGx, Mby))
class CheckMomentsUpdate(unittest.TestCase):
    def setUp(self):
        self.sandbox = SandBox()

    def tearDown(self):
        self.sandbox.erase()

    def CheckCGPosition(self):
        weight = self.fdm.get_property_value('inertia/weight-lbs')
        empty_weight = self.fdm.get_property_value('inertia/empty-weight-lbs')
        contents = self.fdm.get_property_value('buoyant_forces/gas-cell/contents-mol')
        radiosonde_weight = weight - empty_weight - contents * mol2lbs

        CGx = self.fdm.get_property_value('inertia/cg-x-in')
        CGy = self.fdm.get_property_value('inertia/cg-y-in')
        CGz = self.fdm.get_property_value('inertia/cg-z-in')
        X = self.fdm.get_property_value('inertia/pointmass-location-X-inches')
        Y = self.fdm.get_property_value('inertia/pointmass-location-Y-inches')
        Z = self.fdm.get_property_value('inertia/pointmass-location-Z-inches')

        self.assertAlmostEqual(CGx, X * radiosonde_weight / weight, delta = 1E-7)
        self.assertAlmostEqual(CGy, Y * radiosonde_weight / weight, delta = 1E-7)
        self.assertAlmostEqual(CGz, Z * radiosonde_weight / weight, delta = 1E-7)

    def test_moments_update(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'weather-balloon.xml')
        self.fdm = CreateFDM(self.sandbox)

        self.fdm.load_script(script_path)
        self.fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        self.fdm.run_ic()

        self.CheckCGPosition()

        dt = self.fdm.get_property_value('simulation/dt')
        ExecuteUntil(self.fdm, 1.0-2.0*dt)

        self.CheckCGPosition()

        # Moves the radio sonde to modify the CG location
        self.fdm.set_property_value('inertia/pointmass-location-X-inches', 5.0)

        # Check that the moment is immediately updated accordingly
        self.fdm.run()
        self.CheckCGPosition()

        Fbx = self.fdm.get_property_value('forces/fbx-buoyancy-lbs')
        Fbz = self.fdm.get_property_value('forces/fbz-buoyancy-lbs')
        CGx = self.fdm.get_property_value('inertia/cg-x-in') / 12.0 # Converts from in to ft
        CGz = self.fdm.get_property_value('inertia/cg-z-in') / 12.0
        Mby = self.fdm.get_property_value('moments/m-buoyancy-lbsft')

        self.assertAlmostEqual(Fbx * CGz - Fbz * CGx, Mby, delta=1E-7,
                               msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" % (Fbx*CGz-Fbz*CGx, Mby))

        # One further step to log the same results in the output file
        self.fdm.run()
        self.CheckCGPosition()

        csv = Table()
        csv.ReadCSV(self.sandbox('output.csv'))
        Mby = csv.get_column('M_{Buoyant} (ft-lbs)')[-1]
        Fbx = csv.get_column('F_{Buoyant x} (lbs)')[-1]
        Fbz = csv.get_column('F_{Buoyant z} (lbs)')[-1]

        self.assertAlmostEqual(Fbx * CGz - Fbz * CGx, Mby, delta=1E-7,
                               msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" % (Fbx*CGz-Fbz*CGx, Mby))
class CheckMomentsUpdate(JSBSimTestCase):
    def CheckCGPosition(self):
        weight = self.fdm['inertia/weight-lbs']
        empty_weight = self.fdm['inertia/empty-weight-lbs']
        contents = self.fdm['buoyant_forces/gas-cell/contents-mol']
        radiosonde_weight = weight - empty_weight - contents * mol2lbs

        CGx = self.fdm['inertia/cg-x-in']
        CGy = self.fdm['inertia/cg-y-in']
        CGz = self.fdm['inertia/cg-z-in']
        X = self.fdm['inertia/pointmass-location-X-inches']
        Y = self.fdm['inertia/pointmass-location-Y-inches']
        Z = self.fdm['inertia/pointmass-location-Z-inches']

        self.assertAlmostEqual(CGx, X * radiosonde_weight / weight, delta=1E-7)
        self.assertAlmostEqual(CGy, Y * radiosonde_weight / weight, delta=1E-7)
        self.assertAlmostEqual(CGz, Z * radiosonde_weight / weight, delta=1E-7)

    def test_moments_update(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts',
                                                       'weather-balloon.xml')
        self.fdm = CreateFDM(self.sandbox)

        self.fdm.load_script(script_path)
        self.fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        self.fdm.run_ic()

        self.CheckCGPosition()

        dt = self.fdm['simulation/dt']
        ExecuteUntil(self.fdm, 1.0 - 2.0 * dt)

        self.CheckCGPosition()

        # Moves the radio sonde to modify the CG location
        self.fdm['inertia/pointmass-location-X-inches'] = 5.0

        # Check that the moment is immediately updated accordingly
        self.fdm.run()
        self.CheckCGPosition()

        Fbx = self.fdm['forces/fbx-buoyancy-lbs']
        Fbz = self.fdm['forces/fbz-buoyancy-lbs']
        CGx = self.fdm['inertia/cg-x-in'] / 12.0  # Converts from in to ft
        CGz = self.fdm['inertia/cg-z-in'] / 12.0
        Mby = self.fdm['moments/m-buoyancy-lbsft']

        self.assertAlmostEqual(
            Fbx * CGz - Fbz * CGx,
            Mby,
            delta=1E-7,
            msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" %
            (Fbx * CGz - Fbz * CGx, Mby))

        # One further step to log the same results in the output file
        self.fdm.run()
        self.CheckCGPosition()

        csv = pd.read_csv('output.csv')
        Mby = csv['M_{Buoyant} (ft-lbs)'].iget(-1)
        Fbx = csv['F_{Buoyant x} (lbs)'].iget(-1)
        Fbz = csv['F_{Buoyant z} (lbs)'].iget(-1)

        self.assertAlmostEqual(
            Fbx * CGz - Fbz * CGx,
            Mby,
            delta=1E-7,
            msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" %
            (Fbx * CGz - Fbz * CGx, Mby))
    def test_point_mass_inertia(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'J2460.xml')
        fdm = CreateFDM(self.sandbox)
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.load_script(script_path)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        ref = Table()
        ref.ReadCSV(self.sandbox("output.csv"))

        tree, aircraft_name, path_to_jsbsim_aircrafts = CopyAircraftDef(script_path, self.sandbox)

        pointmass_element = tree.getroot().find('mass_balance/pointmass//form/..')
        weight_element = pointmass_element.find('weight')
        weight = float(weight_element.text)
        form_element = pointmass_element.find('form')
        radius_element = form_element.find('radius')
        radius, length = (0.0, 0.0)
        if radius_element is not None:
            radius = float(radius_element.text)
        length_element = form_element.find('length')
        if length_element is not None:
            length = float(length_element.text)
        shape = form_element.attrib['shape']
        pointmass_element.remove(form_element)

        inertia = numpy.zeros((3,3))
        if string.strip(shape) == 'tube':
            inertia[0,0] = radius * radius
            inertia[1,1] = (6.0 * inertia[0,0] + length * length) / 12.0
            inertia[2,2] = inertia[1,1]

        inertia = inertia * weight / 32.174049 # conversion between slug and lb

        ixx_element = et.SubElement(pointmass_element, 'ixx')
        ixx_element.text = str(inertia[0,0])
        iyy_element = et.SubElement(pointmass_element, 'iyy')
        iyy_element.text = str(inertia[1,1])
        izz_element = et.SubElement(pointmass_element, 'izz')
        izz_element.text = str(inertia[2,2])

        tree.write(self.sandbox('aircraft', aircraft_name, aircraft_name+'.xml'))

        fdm = CreateFDM(self.sandbox)
        fdm.set_aircraft_path('aircraft')
        fdm.set_output_directive(self.sandbox.path_to_jsbsim_file('tests',
                                                                  'output.xml'))
        fdm.load_script(script_path)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

        mod = Table()
        mod.ReadCSV(self.sandbox("output.csv"))

        diff = ref.compare(mod)
        self.assertTrue(diff.empty(),
                        msg='\n'+repr(diff))
Exemple #22
0
class CheckMomentsUpdate(unittest.TestCase):
    def setUp(self):
        self.sandbox = SandBox()

    def tearDown(self):
        self.sandbox.erase()

    def CheckCGPosition(self):
        weight = self.fdm.get_property_value('inertia/weight-lbs')
        empty_weight = self.fdm.get_property_value('inertia/empty-weight-lbs')
        contents = self.fdm.get_property_value(
            'buoyant_forces/gas-cell/contents-mol')
        radiosonde_weight = weight - empty_weight - contents * mol2lbs

        CGx = self.fdm.get_property_value('inertia/cg-x-in')
        CGy = self.fdm.get_property_value('inertia/cg-y-in')
        CGz = self.fdm.get_property_value('inertia/cg-z-in')
        X = self.fdm.get_property_value('inertia/pointmass-location-X-inches')
        Y = self.fdm.get_property_value('inertia/pointmass-location-Y-inches')
        Z = self.fdm.get_property_value('inertia/pointmass-location-Z-inches')

        self.assertAlmostEqual(CGx, X * radiosonde_weight / weight, delta=1E-7)
        self.assertAlmostEqual(CGy, Y * radiosonde_weight / weight, delta=1E-7)
        self.assertAlmostEqual(CGz, Z * radiosonde_weight / weight, delta=1E-7)

    def test_moments_update(self):
        script_path = self.sandbox.path_to_jsbsim_file('scripts',
                                                       'weather-balloon.xml')
        self.fdm = CreateFDM(self.sandbox)

        self.fdm.load_script(script_path)
        self.fdm.set_output_directive(
            self.sandbox.path_to_jsbsim_file('tests', 'output.xml'))
        self.fdm.run_ic()

        self.CheckCGPosition()

        dt = self.fdm.get_property_value('simulation/dt')
        ExecuteUntil(self.fdm, 1.0 - 2.0 * dt)

        self.CheckCGPosition()

        # Moves the radio sonde to modify the CG location
        self.fdm.set_property_value('inertia/pointmass-location-X-inches', 5.0)

        # Check that the moment is immediately updated accordingly
        self.fdm.run()
        self.CheckCGPosition()

        Fbx = self.fdm.get_property_value('forces/fbx-buoyancy-lbs')
        Fbz = self.fdm.get_property_value('forces/fbz-buoyancy-lbs')
        CGx = self.fdm.get_property_value(
            'inertia/cg-x-in') / 12.0  # Converts from in to ft
        CGz = self.fdm.get_property_value('inertia/cg-z-in') / 12.0
        Mby = self.fdm.get_property_value('moments/m-buoyancy-lbsft')

        self.assertAlmostEqual(
            Fbx * CGz - Fbz * CGx,
            Mby,
            delta=1E-7,
            msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" %
            (Fbx * CGz - Fbz * CGx, Mby))

        # One further step to log the same results in the output file
        self.fdm.run()
        self.CheckCGPosition()

        csv = Table()
        csv.ReadCSV(self.sandbox('output.csv'))
        Mby = csv.get_column('M_{Buoyant} (ft-lbs)')[-1]
        Fbx = csv.get_column('F_{Buoyant x} (lbs)')[-1]
        Fbz = csv.get_column('F_{Buoyant z} (lbs)')[-1]

        self.assertAlmostEqual(
            Fbx * CGz - Fbz * CGx,
            Mby,
            delta=1E-7,
            msg="Fbx*CGz-Fbz*CGx = %f and Mby = %f do not match" %
            (Fbx * CGz - Fbz * CGx, Mby))