def test_initialise_conditions_basic_config(self):
        plane = aircraft.f15

        # manually reset JSBSim instance with new initial conditions
        if self.sim:
            self.sim.close()
        sim_frequency = 2
        self.sim = Simulation(sim_frequency_hz=sim_frequency,
                              aircraft=plane,
                              init_conditions=None)

        self.assertEqual(self.sim.get_loaded_model_name(),
                         plane.jsbsim_id,
                         msg='JSBSim did not load expected aircraft model: ' +
                         self.sim.get_loaded_model_name())

        # check that properties are as we expected them to be
        expected_values = {
            prp.initial_u_fps: 328.0,
            prp.initial_v_fps: 0.0,
            prp.initial_w_fps: 0.0,
            prp.u_fps: 328.0,
            prp.v_fps: 0.0,
            prp.w_fps: 0.0,
            prp.BoundedProperty('simulation/dt', '', None, None):
            1 / sim_frequency
        }

        for prop, expected in expected_values.items():
            actual = self.sim[prop]
            self.assertAlmostEqual(expected, actual)
Exemple #2
0
    def task_step(self, sim: Simulation, action: Sequence[float], env) \
            -> Tuple[NamedTuple, float, bool, Dict]:
        # input actions
        for prop, command in zip(self.action_variables, action):
            sim[prop] = command

        # run simulation
        #for _ in range(sim_steps):
        #    sim.run()
        while self.observation_timer > 0:
            sim.run()
            self.controller_timer -= self.simulation_dt
            self.observation_timer -= self.simulation_dt
            if self.controller_timer <= 0:
                self._run_pid_controls(self.pid_controls, sim)
                self.controller_timer += self.controller_dt
        self.observation_timer += self.observation_dt
        self._update_custom_properties(sim)
        state = self.State(*(sim[prop] for prop in self.state_variables))
        done = self._is_terminal(sim, env)
        reward = self._calculate_reward(state, self.last_state, done, sim, env)
        if done:
            reward = self._reward_terminal_override(reward, sim, env)
        if self.debug:
            self._validate_state(state, done, action, reward)
        self._store_reward(reward, sim)
        self.last_state = state
        info = {'reward': reward}

        #return state, reward.agent_reward(), done, info
        return state, reward, done, info
    def test_load_bad_aircraft_id(self):
        bad_name = 'qwertyuiop'
        bad_aircraft = aircraft.Aircraft(bad_name, '', '', 100.)

        with self.assertRaises(RuntimeError):
            self.sim = None
            self.sim = Simulation(aircraft=bad_aircraft)
    def test_load_model(self):
        plane = aircraft.a320
        self.sim = None
        self.sim = Simulation(aircraft=plane)
        actual_name = self.sim.get_loaded_model_name()

        self.assertEqual(plane.jsbsim_id,
                         actual_name,
                         msg=f'Unexpected aircraft model name after loading.')
def basic_task():
    """ A simple task involving initing a JSBSimInstance to test multiprocessing. """
    model = aircraft.cessna172P
    time.sleep(0.05)
    fdm = Simulation(aircraft=model)
    fdm.run()
    time.sleep(0.05)

    return 0
Exemple #6
0
 def _init_new_sim(self, dt: float, aircraft: Aircraft,
                   initial_conditions: Dict):
     return Simulation(sim_frequency_hz=dt,
                       jsbsim_dir=self.jsbsim_dir,
                       aircraft=aircraft,
                       init_conditions=initial_conditions,
                       allow_flightgear_output=False)
Exemple #7
0
 def _init_new_sim(self, dt, aircraft, initial_conditions):
     vis = self.cfg.get('visualiser') or {}
     allow_fg = vis.get('flightgear') is not None
     return Simulation(jsbsim_dir=self.jsbsim_dir,
                       sim_dt=dt,
                       aircraft=aircraft,
                       init_conditions=initial_conditions,
                       allow_flightgear_output=allow_fg)
    def test_initialise_conditions_custom_config(self):
        """ Test JSBSimInstance initialisation with custom initial conditions. """

        plane = aircraft.f15
        init_conditions = {
            prp.initial_u_fps: 1000.0,
            prp.initial_v_fps: 0.0,
            prp.initial_w_fps: 1.0,
            prp.initial_altitude_ft: 5000,
            prp.initial_heading_deg: 12,
            prp.initial_r_radps: -0.1,
        }
        # map JSBSim initial condition properties to sim properties
        init_to_sim_conditions = {
            prp.initial_u_fps: prp.u_fps,
            prp.initial_v_fps: prp.v_fps,
            prp.initial_w_fps: prp.w_fps,
            prp.initial_altitude_ft: prp.altitude_sl_ft,
            prp.initial_heading_deg: prp.heading_deg,
            prp.initial_r_radps: prp.r_radps,
        }
        sim_frequency = 10

        # manually reset JSBSim instance
        if self.sim:
            self.sim.close()
        self.sim = Simulation(sim_frequency, plane, init_conditions)

        # check JSBSim initial condition and simulation properties
        for init_prop, expected in init_conditions.items():
            sim_prop = init_to_sim_conditions[init_prop]

            init_actual = self.sim[init_prop]
            sim_actual = self.sim[sim_prop]
            self.assertAlmostEqual(expected,
                                   init_actual,
                                   msg=f'wrong value for property {init_prop}')
            self.assertAlmostEqual(expected,
                                   sim_actual,
                                   msg=f'wrong value for property {sim_prop}')

        self.assertAlmostEqual(1.0 / sim_frequency, self.sim[prp.sim_dt])
class TestSimulation(unittest.TestCase):
    sim: Simulation = None

    def setUp(self):
        if self.sim:
            self.sim.close()
        self.sim = Simulation()

    def tearDown(self):
        self.sim = None

    def test_init_jsbsim(self):
        self.assertIsInstance(self.sim.jsbsim,
                              jsbsim.FGFDMExec,
                              msg=f'Expected Simulation.jsbsim to hold an '
                              'instance of JSBSim.')

    def test_load_model(self):
        plane = aircraft.a320
        self.sim = None
        self.sim = Simulation(aircraft=plane)
        actual_name = self.sim.get_loaded_model_name()

        self.assertEqual(plane.jsbsim_id,
                         actual_name,
                         msg=f'Unexpected aircraft model name after loading.')

    def test_load_bad_aircraft_id(self):
        bad_name = 'qwertyuiop'
        bad_aircraft = aircraft.Aircraft(bad_name, '', '', 100.)

        with self.assertRaises(RuntimeError):
            self.sim = None
            self.sim = Simulation(aircraft=bad_aircraft)

    def test_get_property(self):
        self.setUp()
        # we expect certain values specified in the IC config XML file
        expected_values = {
            prp.initial_u_fps: 328.0,
            prp.initial_v_fps: 0.0,
            prp.initial_w_fps: 0.0,
            prp.u_fps: 328.0,
            prp.v_fps: 0.0,
            prp.w_fps: 0.0,
        }

        for prop, expected in expected_values.items():
            actual = self.sim[prop]
            self.assertAlmostEqual(expected, actual)

    def test_get_bad_property(self):
        self.setUp()
        bad_prop = prp.BoundedProperty("bad_prop_name", "", 0, 0)
        with self.assertRaises(KeyError):
            _ = self.sim[bad_prop]

    def test_set_property(self):
        self.setUp()
        set_values = {
            prp.altitude_sl_ft: 1000,
            prp.aileron_cmd: 0.2,
            prp.elevator_cmd: 0.2,
            prp.rudder_cmd: 0.2,
            prp.throttle_cmd: 0.2,
        }

        for prop, value in set_values.items():
            self.sim[prop] = value

        for prop, expected in set_values.items():
            actual = self.sim[prop]
            self.assertAlmostEqual(expected, actual)

    def test_initialise_conditions_basic_config(self):
        plane = aircraft.f15

        # manually reset JSBSim instance with new initial conditions
        if self.sim:
            self.sim.close()
        sim_frequency = 2
        self.sim = Simulation(sim_frequency_hz=sim_frequency,
                              aircraft=plane,
                              init_conditions=None)

        self.assertEqual(self.sim.get_loaded_model_name(),
                         plane.jsbsim_id,
                         msg='JSBSim did not load expected aircraft model: ' +
                         self.sim.get_loaded_model_name())

        # check that properties are as we expected them to be
        expected_values = {
            prp.initial_u_fps: 328.0,
            prp.initial_v_fps: 0.0,
            prp.initial_w_fps: 0.0,
            prp.u_fps: 328.0,
            prp.v_fps: 0.0,
            prp.w_fps: 0.0,
            prp.BoundedProperty('simulation/dt', '', None, None):
            1 / sim_frequency
        }

        for prop, expected in expected_values.items():
            actual = self.sim[prop]
            self.assertAlmostEqual(expected, actual)

    def test_initialise_conditions_custom_config(self):
        """ Test JSBSimInstance initialisation with custom initial conditions. """

        plane = aircraft.f15
        init_conditions = {
            prp.initial_u_fps: 1000.0,
            prp.initial_v_fps: 0.0,
            prp.initial_w_fps: 1.0,
            prp.initial_altitude_ft: 5000,
            prp.initial_heading_deg: 12,
            prp.initial_r_radps: -0.1,
        }
        # map JSBSim initial condition properties to sim properties
        init_to_sim_conditions = {
            prp.initial_u_fps: prp.u_fps,
            prp.initial_v_fps: prp.v_fps,
            prp.initial_w_fps: prp.w_fps,
            prp.initial_altitude_ft: prp.altitude_sl_ft,
            prp.initial_heading_deg: prp.heading_deg,
            prp.initial_r_radps: prp.r_radps,
        }
        sim_frequency = 10

        # manually reset JSBSim instance
        if self.sim:
            self.sim.close()
        self.sim = Simulation(sim_frequency, plane, init_conditions)

        # check JSBSim initial condition and simulation properties
        for init_prop, expected in init_conditions.items():
            sim_prop = init_to_sim_conditions[init_prop]

            init_actual = self.sim[init_prop]
            sim_actual = self.sim[sim_prop]
            self.assertAlmostEqual(expected,
                                   init_actual,
                                   msg=f'wrong value for property {init_prop}')
            self.assertAlmostEqual(expected,
                                   sim_actual,
                                   msg=f'wrong value for property {sim_prop}')

        self.assertAlmostEqual(1.0 / sim_frequency, self.sim[prp.sim_dt])

    def test_multiprocess_simulations(self):
        """
        JSBSim segfaults when multiple instances are run on one process.

        Let's confirm that we can launch multiple processes each with 1 instance.
        """
        processes = 4
        with multiprocessing.Pool(processes) as pool:
            # N.B. basic_task is a top level function that inits JSBSim
            future_results = [
                pool.apply_async(basic_task) for _ in range(processes)
            ]
            results = [f.get() for f in future_results]

        good_exit_code = 0
        expected = [good_exit_code] * processes
        self.assertListEqual(results,
                             expected,
                             msg="multiprocess execution of JSBSim failed")
 def setUp(self):
     if self.sim:
         self.sim.close()
     self.sim = Simulation()
Exemple #11
0
 def _new_episode_init(self, sim: Simulation) -> None:
     super()._new_episode_init(sim)
     sim.set_throttle_mixture_controls(self.THROTTLE_CMD, self.MIXTURE_CMD)
     sim[self.steps_left] = self.steps_left.max
     sim[self.target_track_deg] = self._get_target_track()