예제 #1
0
    def testOutputRate(self):
        self.fdm.load_script(self.script_path)

        # Check that the output is enabled by default
        self.assertEqual(self.fdm.get_property_value("simulation/output/enabled"), 1.0)

        # Check that the rate is consistent with the values extracted from the
        # script and the aircraft definition
        self.assertAlmostEqual(self.fdm.get_property_value("simulation/output/log_rate_hz"), self.rateHz, delta=1e-5)

        self.fdm.run_ic()

        for i in xrange(self.rate):
            self.fdm.run()

        output = Table()
        output.ReadCSV(self.output_file)

        # According to the settings, the output file must contain 2 lines in
        # addition to the headers :
        # 1. The initial conditions
        # 2. The output after 'rate' iterations
        self.assertEqual(output.get_column(0)[1], 0.0)
        self.assertEqual(output.get_column(0)[2], self.rate * self.dt)
        self.assertEqual(output.get_column(0)[2], self.fdm.get_property_value("simulation/sim-time-sec"))
예제 #2
0
    def testDebugLvl(self):
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(
            self.sandbox.path_to_jsbsim_file('scripts', 'ball_orbit.xml'))
        fdm.run_ic()

        ExecuteUntil(fdm, 1000.)

        ref, current = Table(), Table()
        ref.ReadCSV(self.sandbox('BallOut.csv'))
        del fdm

        os.environ["JSBSIM_DEBUG"] = str(0)
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(
            self.sandbox.path_to_jsbsim_file('scripts', 'ball_orbit.xml'))
        fdm.run_ic()

        ExecuteUntil(fdm, 1000.)

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

        diff = ref.compare(current)
        self.longMessage = True
        self.assertTrue(diff.empty(), msg='\n' + repr(diff))
예제 #3
0
    def testTrimRestoresOutputSettings(self):
        self.fdm.load_script(self.script_path)

        # Disables the output during the initialization
        self.fdm.set_property_value("simulation/output/enabled", 0.0)
        self.fdm.run_ic()

        # Check that the output remains disabled even after the trim is
        # executed
        while self.fdm.get_property_value("simulation/sim-time-sec") < self.trim_date + 2.0 * self.dt:
            self.fdm.run()
            self.assertEqual(self.fdm.get_property_value("simulation/output/enabled"), 0.0)

        # Re-enable the output and check that the output rate is unaffected by
        # the previous operations
        self.fdm.set_property_value("simulation/output/enabled", 1.0)
        frame = int(self.fdm.get_property_value("simulation/frame"))

        for i in xrange(self.rate):
            self.fdm.run()

        output = Table()
        output.ReadCSV(self.output_file)

        # The frame at which the data is logged must be the next multiple of
        # the output rate
        self.assertEqual(int(output.get_column(0)[1] / self.dt), (1 + frame / self.rate) * self.rate)
예제 #4
0
    def test_model_loading(self):
        self.longMessage = True

        self.BuildReference('c1724.xml')
        output_ref = Table()
        output_ref.ReadCSV(self.sandbox('JSBout172B.csv'))

        self.ProcessAndCompare('aerodynamics')
        self.ProcessAndCompare('autopilot')
        self.ProcessAndCompare('flight_control')
        self.ProcessAndCompare('ground_reactions')
        self.ProcessAndCompare('mass_balance')
        self.ProcessAndCompare('metrics')
        self.ProcessAndCompare('propulsion')
        self.ProcessAndCompare('system')

        # The <output> section needs special handling. In addition to the check
        # conducted by ProcessAndCompare with a directive file, we need to
        # verify that the <output> tag has been correctly executed by JSBSim.
        # In the case of the script c1724.xml, this means that the data output
        # in JSBout172B.csv is the same between the reference 'output_ref' and
        # the result 'mod' below where the <output> tag was moved in a separate
        # file.
        self.ProcessAndCompare('output')
        mod = Table()
        mod.ReadCSV(self.sandbox('JSBout172B.csv'))
        diff = output_ref.compare(mod, 0.0)
        self.assertTrue(diff.empty(),
                        msg='\nTesting section "output"\n'+repr(diff))

        self.BuildReference('weather-balloon.xml')
        self.ProcessAndCompare('buoyant_forces')

        self.BuildReference('Concorde_runway_test.xml')
        self.ProcessAndCompare('external_reactions')
예제 #5
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.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))
예제 #6
0
    def testOrbitCheckCase(self):
        os.environ['JSBSIM_DEBUG'] = str(0)
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(self.sandbox.path_to_jsbsim_file('scripts', 'ball_orbit.xml'))
        fdm.run_ic()

        while fdm.run():
            pass

        ref, current = Table(), Table()
        ref.ReadCSV(self.sandbox.elude(self.sandbox.path_to_jsbsim_file('logged_data', 'BallOut.csv')))
        current.ReadCSV(self.sandbox('BallOut.csv'))

        diff = ref.compare(current)
        self.longMessage = True
        self.assertTrue(diff.empty(), msg='\n'+repr(diff))
예제 #7
0
    def test_model_loading(self):
        self.longMessage = True

        self.BuildReference('c1724.xml')
        output_ref = Table()
        output_ref.ReadCSV(self.sandbox('JSBout172B.csv'))

        self.ProcessAndCompare('aerodynamics')
        self.ProcessAndCompare('autopilot')
        self.ProcessAndCompare('flight_control')
        self.ProcessAndCompare('ground_reactions')
        self.ProcessAndCompare('mass_balance')
        self.ProcessAndCompare('metrics')
        self.ProcessAndCompare('propulsion')
        self.ProcessAndCompare('system')

        # The <output> section needs special handling. In addition to the check
        # conducted by ProcessAndCompare with a directive file, we need to
        # verify that the <output> tag has been correctly executed by JSBSim.
        # In the case of the script c1724.xml, this means that the data output
        # in JSBout172B.csv is the same between the reference 'output_ref' and
        # the result 'mod' below where the <output> tag was moved in a separate
        # file.
        self.ProcessAndCompare('output')
        mod = Table()
        mod.ReadCSV(self.sandbox('JSBout172B.csv'))
        diff = output_ref.compare(mod, 0.0)
        self.assertTrue(diff.empty(),
                        msg='\nTesting section "output"\n' + repr(diff))

        self.BuildReference('weather-balloon.xml')
        self.ProcessAndCompare('buoyant_forces')

        self.BuildReference('Concorde_runway_test.xml')
        self.ProcessAndCompare('external_reactions')
예제 #8
0
    def testDisablingOutput(self):
        self.fdm.load_script(self.script_path)

        # Disables the output during the initialization
        self.fdm.set_property_value("simulation/output/enabled", 0.0)
        self.fdm.run_ic()
        self.fdm.set_property_value("simulation/output/enabled", 1.0)

        for i in xrange(self.rate):
            self.fdm.run()

        output = Table()
        output.ReadCSV(self.output_file)

        # According to the settings, the output file must contain 1 line in
        # addition to the headers :
        # 1. The output after 'rate' iterations
        self.assertEqual(output.get_column(0)[1], self.fdm.get_property_value("simulation/sim-time-sec"))
예제 #9
0
    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))
예제 #10
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))
예제 #11
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))
예제 #12
0
    def testDebugLvl(self):
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(self.sandbox.path_to_jsbsim_file('scripts', 'ball_orbit.xml'))
        fdm.run_ic()

        ExecuteUntil(fdm, 1000.)

        ref, current = Table(), Table()
        ref.ReadCSV(self.sandbox('BallOut.csv'))
        del fdm

        os.environ["JSBSIM_DEBUG"]=str(0)
        fdm = CreateFDM(self.sandbox)
        fdm.load_script(self.sandbox.path_to_jsbsim_file('scripts', 'ball_orbit.xml'))
        fdm.run_ic()

        ExecuteUntil(fdm, 1000.)

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

        diff = ref.compare(current)
        self.longMessage = True
        self.assertTrue(diff.empty(), msg='\n'+repr(diff))
예제 #13
0
    def BuildReference(self, script_name):
        # Run the script
        self.script = self.sandbox.path_to_jsbsim_file(
            os.path.join('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.set_property_value('simulation/randomseed', 0.0)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

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

        # 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 = self.sandbox('aircraft', self.aircraft_name)
예제 #14
0
    def testDisablingOutputInScript(self):
        property = et.SubElement(self.run_tag, "property")
        property.text = "simulation/output/enabled"
        property.attrib["value"] = "0.0"
        self.tree.write(self.sandbox("c1722_0.xml"))

        self.fdm.load_script("c1722_0.xml")

        # Check that the output is disabled
        self.assertEqual(self.fdm.get_property_value("simulation/output/enabled"), 0.0)

        self.fdm.run_ic()
        self.fdm.set_property_value("simulation/output/enabled", 1.0)

        for i in xrange(self.rate):
            self.fdm.run()

        output = Table()
        output.ReadCSV(self.output_file)

        # According to the settings, the output file must contain 1 line in
        # addition to the headers :
        # 1. The output after 'rate' iterations
        self.assertEqual(output.get_column(0)[1], self.fdm.get_property_value("simulation/sim-time-sec"))
예제 #15
0
    def BuildReference(self, script_name):
        # Run the script
        self.script = self.sandbox.path_to_jsbsim_file(os.path.join('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.set_property_value('simulation/randomseed', 0.0)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

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

        # 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 = self.sandbox('aircraft', self.aircraft_name)
예제 #16
0
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>
#

import sys
from JSBSim_utils import CreateFDM, Table, SandBox

sandbox = SandBox("check_cases", "orbit")

fdm = CreateFDM(sandbox)
fdm.load_script(sandbox.path_to_jsbsim_file("scripts", "ball_orbit.xml"))
fdm.run_ic()

while fdm.run():
    pass

ref, current = Table(), Table()
ref.ReadCSV(sandbox.elude(sandbox.path_to_jsbsim_file("logged_data", "BallOut.csv")))
current.ReadCSV(sandbox("BallOut.csv"))

diff = ref.compare(current)
if not diff.empty():
    print diff
    sys.exit(-1)  # Needed for 'make test' to report the test passed.

sandbox.erase()
예제 #17
0
class TestModelLoading(unittest.TestCase):
    def setUp(self):
        self.sandbox = SandBox()

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

    def BuildReference(self, script_name):
        # Run the script
        self.script = self.sandbox.path_to_jsbsim_file(
            os.path.join('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.set_property_value('simulation/randomseed', 0.0)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

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

        # 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 = self.sandbox('aircraft', self.aircraft_name)

    def ProcessAndCompare(self, section):
        # Here we determine if the original aircraft definition <section> is
        # inline or read from an external file.
        tree = et.parse(
            os.path.join(self.path_to_jsbsim_aircrafts,
                         self.aircraft_name + '.xml'))
        root = tree.getroot()

        # Iterate over all the tags named <section>
        for section_element in root.findall(section):
            if 'file' in section_element.keys():
                self.InsertAndCompare(section_element, tree)
            else:
                self.DetachAndCompare(section_element, tree)

    def DetachAndCompare(self, section_element, tree):
        # Extract <section> from the original aircraft definition file and copy
        # it in a separate XML file 'section.xml'
        section_tree = et.ElementTree(element=section_element)
        if 'name' in section_element.keys():
            section = section_element.attrib['name']
        else:
            section = section_element.tag

        section_tree.write(os.path.join(self.aircraft_path, section + '.xml'),
                           xml_declaration=True)

        # Now, we need to clean up the aircraft definition file from all
        # references to <section>. We just need a single <section> tag that
        # points to the file 'section.xml'
        for element in list(section_element):
            section_element.remove(element)

        section_element.attrib = {'file': section + '.xml'}
        tree.write(os.path.join(self.aircraft_path,
                                self.aircraft_name + '.xml'),
                   xml_declaration=True)

        self.Compare(section)

    def InsertAndCompare(self, section_element, tree):
        file_name = append_xml(section_element.attrib['file'])
        section_file = os.path.join(self.path_to_jsbsim_aircrafts, file_name)

        # If <section> is actually <system>, we need to iterate over all the
        # directories in which the file is allowed to be stored until the file
        # is located.
        if not os.path.exists(
                section_file) and section_element.tag == 'system':
            section_file = os.path.join(self.path_to_jsbsim_aircrafts,
                                        "systems", file_name)
            if not os.path.exists(section_file):
                section_file = self.sandbox.elude(
                    self.sandbox.path_to_jsbsim_file("systems", file_name))

        # The original <section> tag is dropped and replaced by the content of
        # the file.
        section_root = et.parse(section_file).getroot()

        del section_element.attrib['file']
        section_element.attrib.update(section_root.attrib)
        section_element.extend(section_root)

        tree.write(
            os.path.join(self.aircraft_path, self.aircraft_name + '.xml'))

        self.Compare(section_element.tag + " file:" + section_file)

    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))

    def test_model_loading(self):
        self.longMessage = True

        self.BuildReference('c1724.xml')
        output_ref = Table()
        output_ref.ReadCSV(self.sandbox('JSBout172B.csv'))

        self.ProcessAndCompare('aerodynamics')
        self.ProcessAndCompare('autopilot')
        self.ProcessAndCompare('flight_control')
        self.ProcessAndCompare('ground_reactions')
        self.ProcessAndCompare('mass_balance')
        self.ProcessAndCompare('metrics')
        self.ProcessAndCompare('propulsion')
        self.ProcessAndCompare('system')

        # The <output> section needs special handling. In addition to the check
        # conducted by ProcessAndCompare with a directive file, we need to
        # verify that the <output> tag has been correctly executed by JSBSim.
        # In the case of the script c1724.xml, this means that the data output
        # in JSBout172B.csv is the same between the reference 'output_ref' and
        # the result 'mod' below where the <output> tag was moved in a separate
        # file.
        self.ProcessAndCompare('output')
        mod = Table()
        mod.ReadCSV(self.sandbox('JSBout172B.csv'))
        diff = output_ref.compare(mod, 0.0)
        self.assertTrue(diff.empty(),
                        msg='\nTesting section "output"\n' + repr(diff))

        self.BuildReference('weather-balloon.xml')
        self.ProcessAndCompare('buoyant_forces')

        self.BuildReference('Concorde_runway_test.xml')
        self.ProcessAndCompare('external_reactions')
예제 #18
0
class TestModelLoading(unittest.TestCase):
    def setUp(self):
        self.sandbox = SandBox()

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

    def BuildReference(self, script_name):
        # Run the script
        self.script = self.sandbox.path_to_jsbsim_file(os.path.join('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.set_property_value('simulation/randomseed', 0.0)

        fdm.run_ic()
        ExecuteUntil(fdm, 50.0)

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

        # 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 = self.sandbox('aircraft', self.aircraft_name)

    def ProcessAndCompare(self, section):
        # Here we determine if the original aircraft definition <section> is
        # inline or read from an external file.
        tree = et.parse(os.path.join(self.path_to_jsbsim_aircrafts,
                                     self.aircraft_name + '.xml'))
        root = tree.getroot()

        # Iterate over all the tags named <section>
        for section_element in root.findall(section):
            if 'file' in section_element.keys():
                self.InsertAndCompare(section_element, tree)
            else:
                self.DetachAndCompare(section_element, tree)

    def DetachAndCompare(self, section_element, tree):
        # Extract <section> from the original aircraft definition file and copy
        # it in a separate XML file 'section.xml'
        section_tree = et.ElementTree(element=section_element)
        if 'name' in section_element.keys():
            section = section_element.attrib['name']
        else:
            section = section_element.tag

        section_tree.write(os.path.join(self.aircraft_path, section+'.xml'),
                           xml_declaration=True)

        # Now, we need to clean up the aircraft definition file from all
        # references to <section>. We just need a single <section> tag that
        # points to the file 'section.xml'
        for element in list(section_element):
            section_element.remove(element)

        section_element.attrib = {'file': section+'.xml'}
        tree.write(os.path.join(self.aircraft_path, self.aircraft_name+'.xml'),
                   xml_declaration=True)

        self.Compare(section)

    def InsertAndCompare(self, section_element, tree):
        file_name = append_xml(section_element.attrib['file'])
        section_file = os.path.join(self.path_to_jsbsim_aircrafts, file_name)

        # If <section> is actually <system>, we need to iterate over all the
        # directories in which the file is allowed to be stored until the file
        # is located.
        if not os.path.exists(section_file) and section_element.tag == 'system':
            section_file = os.path.join(self.path_to_jsbsim_aircrafts, "systems", file_name)
            if not os.path.exists(section_file):
                section_file = self.sandbox.elude(self.sandbox.path_to_jsbsim_file("systems", file_name))

        # The original <section> tag is dropped and replaced by the content of
        # the file.
        section_root = et.parse(section_file).getroot()

        del section_element.attrib['file']
        section_element.attrib.update(section_root.attrib)
        section_element.extend(section_root)

        tree.write(os.path.join(self.aircraft_path, self.aircraft_name+'.xml'))

        self.Compare(section_element.tag+" file:"+section_file)

    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))

    def test_model_loading(self):
        self.longMessage = True

        self.BuildReference('c1724.xml')
        output_ref = Table()
        output_ref.ReadCSV(self.sandbox('JSBout172B.csv'))

        self.ProcessAndCompare('aerodynamics')
        self.ProcessAndCompare('autopilot')
        self.ProcessAndCompare('flight_control')
        self.ProcessAndCompare('ground_reactions')
        self.ProcessAndCompare('mass_balance')
        self.ProcessAndCompare('metrics')
        self.ProcessAndCompare('propulsion')
        self.ProcessAndCompare('system')

        # The <output> section needs special handling. In addition to the check
        # conducted by ProcessAndCompare with a directive file, we need to
        # verify that the <output> tag has been correctly executed by JSBSim.
        # In the case of the script c1724.xml, this means that the data output
        # in JSBout172B.csv is the same between the reference 'output_ref' and
        # the result 'mod' below where the <output> tag was moved in a separate
        # file.
        self.ProcessAndCompare('output')
        mod = Table()
        mod.ReadCSV(self.sandbox('JSBout172B.csv'))
        diff = output_ref.compare(mod, 0.0)
        self.assertTrue(diff.empty(),
                        msg='\nTesting section "output"\n'+repr(diff))

        self.BuildReference('weather-balloon.xml')
        self.ProcessAndCompare('buoyant_forces')

        self.BuildReference('Concorde_runway_test.xml')
        self.ProcessAndCompare('external_reactions')
예제 #19
0
    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))
예제 #20
0
    def test_IC_override(self):
        # Run the script c1724.xml
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'c1724.xml')

        fdm = CreateFDM(self.sandbox)
        fdm.load_script(script_path)

        vt0 = fdm.get_property_value('ic/vt-kts')

        fdm.run_ic()
        self.assertEqual(fdm.get_property_value('simulation/sim-time-sec'), 0.0)
        self.assertAlmostEqual(fdm.get_property_value('velocities/vt-fps'),
                               vt0 / fpstokts, delta=1E-7)

        ExecuteUntil(fdm, 1.0)

        # Check that the total velocity exported in the output file matches the
        # IC defined in the initialization file
        ref = Table()
        ref.ReadCSV(self.sandbox('JSBout172B.csv'))
        self.assertEqual(ref.get_column('Time')[1], 0.0)
        self.assertAlmostEqual(ref.get_column('V_{Total} (ft/s)')[1],
                               vt0 / fpstokts, delta=1E-7)

        # Now, we will re-run the same test but the IC will be overridden in the
        # script. The initial total velocity is increased by 1 ft/s
        vt0 += 1.0

        # The script c1724.xml is loaded and the following line is added in it:
        #    <property value="..."> ic/vt-kts </property>
        # The modified script is then saved with the named 'c1724_0.xml'
        tree = et.parse(self.sandbox.elude(script_path))
        run_tag = tree.getroot().find("./run")
        property = et.SubElement(run_tag, 'property')
        property.text = 'ic/vt-kts'
        property.attrib['value'] = str(vt0)
        tree.write(self.sandbox('c1724_0.xml'))

        # Re-run the same check than above. This time we are making sure than
        # the total initial velocity is increased by 1 ft/s
        self.sandbox.delete_csv_files()

        # 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.load_script('c1724_0.xml')

        self.assertAlmostEqual(fdm.get_property_value('ic/vt-kts'), vt0,
                               delta=1E-6)

        fdm.run_ic()
        self.assertEqual(fdm.get_property_value('simulation/sim-time-sec'), 0.0)
        self.assertAlmostEqual(fdm.get_property_value('velocities/vt-fps'),
                               vt0 / fpstokts, delta=1E-6)

        ExecuteUntil(fdm, 1.0)

        mod = Table()
        mod.ReadCSV(self.sandbox('JSBout172B.csv'))
        self.assertAlmostEqual(mod.get_column('V_{Total} (ft/s)')[1],
                               vt0 / fpstokts, delta=1E-6)
예제 #21
0
    def test_IC_override(self):
        # Run the script c1724.xml
        script_path = self.sandbox.path_to_jsbsim_file('scripts', 'c1724.xml')

        fdm = CreateFDM(self.sandbox)
        fdm.load_script(script_path)

        vt0 = fdm.get_property_value('ic/vt-kts')

        fdm.run_ic()
        ExecuteUntil(fdm, 1.0)

        # Check that the total velocity exported in the output file matches the IC
        # defined in the initialization file
        ref = Table()
        ref.ReadCSV(self.sandbox('JSBout172B.csv'))

        for col, title in enumerate(ref._lines[0]):
            if title == 'V_{Total} (ft/s)':
                self.assertTrue(
                    abs(ref._lines[1][col] - (vt0 / fpstokts)) < 1E-5,
                    msg=
                    "Original script %s\nThe total velocity is %f. The value %f was expected"
                    % (script_path, ref._lines[1][col], vt0 / fpstokts))
                break
        else:
            self.fail("The total velocity is not exported in %s" %
                      (script_path, ))

        # Now, we will re-run the same test but the IC will be overridden in the scripts
        # The initial total velocity is increased by 1 ft/s
        vt0 += 1.0

        # The script c1724.xml is loaded and the following line is added in it:
        #    <property value="..."> ic/vt-kts </property>
        # The modified script is then saved with the named 'c1724_0.xml'
        tree = et.parse(self.sandbox.elude(script_path))
        run_tag = tree.getroot().find("./run")
        property = et.SubElement(run_tag, 'property')
        property.text = 'ic/vt-kts'
        property.attrib['value'] = str(vt0)
        tree.write(self.sandbox('c1724_0.xml'))

        # Re-run the same check than above. This time we are making sure than the total
        # initial velocity is increased by 1 ft/s
        self.sandbox.delete_csv_files()

        # 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.load_script('c1724_0.xml')

        self.assertTrue(
            abs(fdm.get_property_value('ic/vt-kts') - vt0) < 1E-5,
            msg=
            "Modified script %s\nThe total velocity in the IC (%f) is different from %f"
            % (self.sandbox('JSBout172B.csv'),
               fdm.get_property_value('ic/vt-kts'), vt0))

        fdm.run_ic()
        ExecuteUntil(fdm, 1.0)

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

        for col, title in enumerate(mod._lines[0]):
            if title == 'V_{Total} (ft/s)':
                self.assertTrue(
                    abs(mod._lines[1][col] - (vt0 / fpstokts)) < 1E-5,
                    msg=
                    "Modified script %s\nThe total velocity is %f. The value %f was expected"
                    % (self.sandbox('JSBout172B.csv'), mod._lines[1][col],
                       vt0 / fpstokts))
                break
        else:
            self.fail("The total velocity is not exported in %s" %
                      (sandbox('JSBout172B.csv'), ))