Exemple #1
0
    def test_engines(self):
        """Test that engines use fuel and accelerate at the expected."""
        with PhysicsEngine('tests/habitat.json') as physics_engine:
            # In this test case, there is a single entity that has 300 kg fuel.
            # heading, velocity, and position are all 0.
            throttle = 1
            t_delta = 5

            physics_engine.handle_requests([
                network.Request(ident=network.Request.HAB_THROTTLE_SET,
                                throttle_set=throttle)
            ],
                                           requested_t=0)

            initial = physics_engine.get_state(0)
            moved = physics_engine.get_state(t_delta)

            self.assertAlmostEqual(initial[0].heading, 0)

            self.assertAlmostEqual(
                moved[0].fuel, (initial[0].fuel - t_delta * throttle *
                                common.craft_capabilities[HABITAT].fuel_cons))
            self.assertTrue(
                moved[0].vx < (t_delta * calc.engine_acceleration(moved)))

            t_no_fuel = (
                initial[0].fuel /
                (throttle * common.craft_capabilities[HABITAT].fuel_cons))
            empty_fuel = physics_engine.get_state(t_no_fuel)
            after_empty_fuel = physics_engine.get_state(t_no_fuel + t_delta)

            self.assertEqual(round(empty_fuel[0].fuel), 0)
            self.assertEqual(round(after_empty_fuel[0].vx),
                             round(empty_fuel[0].vx))
Exemple #2
0
    def test_srbs(self):
        """Test that SRBs move the craft, and run out of fuel."""
        with PhysicsEngine('tests/habitat.json') as physics_engine:
            t_delta = 5

            physics_engine.handle_requests(
                [network.Request(ident=network.Request.IGNITE_SRBS)],
                requested_t=0)

            initial = physics_engine.get_state(0)
            moved = physics_engine.get_state(t_delta)

            self.assertAlmostEqual(initial[0].heading, 0)
            self.assertAlmostEqual(initial[0].vx, 0)
            self.assertAlmostEqual(moved[0].vx,
                                   t_delta * calc.engine_acceleration(moved))

            srb_empty = physics_engine.get_state(common.SRB_BURNTIME)
            after_srb_empty = physics_engine.get_state(common.SRB_BURNTIME + 5)

            self.assertAlmostEqual(srb_empty[0].vx, after_srb_empty[0].vx)
Exemple #3
0
    def _create_wtexts(self):
        vpython.canvas.get_selected().caption += "<table>\n"
        self._wtexts: List[TableText] = []

        self._wtexts.append(
            TableText("Simulation time",
                      lambda state: datetime.fromtimestamp(
                          state.timestamp, common.TIMEZONE).strftime('%x %X'),
                      "Current time in simulation",
                      new_section=False))
        self._wtexts.append(
            TableText("Orbit speed",
                      lambda state: common.format_num(
                          calc.orb_speed(state.craft_entity(),
                                         state.reference_entity()), " m/s"),
                      "Speed required for circular orbit at current altitude",
                      new_section=False))

        self._wtexts.append(
            TableText(
                "Periapsis",
                lambda state: common.format_num(calc.periapsis(
                    state.craft_entity(), state.reference_entity()) / 1000,
                                                " km",
                                                decimals=3),
                "Lowest altitude in naïve orbit around reference",
                new_section=False))

        self._wtexts.append(
            TableText(
                "Apoapsis",
                lambda state: common.format_num(calc.apoapsis(
                    state.craft_entity(), state.reference_entity()) / 1000,
                                                " km",
                                                decimals=3),
                "Highest altitude in naïve orbit around reference",
                new_section=False))

        self._wtexts.append(
            TableText(
                # The H in HRT stands for Habitat, even though craft is more
                # general and covers Ayse, but HRT is the familiar triple name and
                # the Hawking III says trans rights.
                "HRT phase θ",
                lambda state: common.format_num(
                    calc.phase_angle(
                        state.craft_entity(), state.reference_entity(),
                        state.target_entity()), "°") or "Same ref and targ",
                "Angle between Habitat, Reference, and Target",
                new_section=False))

        self._wtexts.append(
            TableText(
                "Throttle",
                lambda state: "{:.1%}".format(state.craft_entity().throttle),
                "Percentage of habitat's maximum rated engines",
                new_section=True))

        self._wtexts.append(
            TableText("Engine Acceleration",
                      lambda state: common.format_num(
                          calc.engine_acceleration(state), " m/s/s") +
                      (' [SRB]' if state.srb_time > 0 else ''),
                      "Acceleration due to craft's engine thrust",
                      new_section=False))

        self._wtexts.append(
            TableText("Drag",
                      lambda state: common.format_num(
                          calc.fastnorm(calc.drag(state)), " m/s/s"),
                      "Atmospheric drag acting on the craft",
                      new_section=False))

        self._wtexts.append(
            TableText("Fuel",
                      lambda state: common.format_num(
                          state.craft_entity().fuel, " kg"),
                      "Remaining fuel of craft",
                      new_section=False))

        def rotation_formatter(state: PhysicsState) -> str:
            deg_spin = round(np.degrees(state.craft_entity().spin), ndigits=1)
            if deg_spin < 0:
                return f"{-deg_spin} °/s cw"
            elif deg_spin > 0:
                return f"{deg_spin} °/s ccw"
            else:
                return f"{deg_spin} °/s"

        self._wtexts.append(
            TableText("Rotation",
                      rotation_formatter,
                      "Rotation speed of craft",
                      new_section=False))

        self._wtexts.append(
            TableText(
                "Ref altitude",
                lambda state: common.format_num(calc.altitude(
                    state.craft_entity(), state.reference_entity()) / 1000,
                                                " km",
                                                decimals=3),
                "Altitude of habitat above reference surface",
                new_section=True))

        self._wtexts.append(
            TableText("Ref speed",
                      lambda state: common.format_num(
                          calc.speed(state.craft_entity(),
                                     state.reference_entity()), " m/s"),
                      "Speed of habitat above reference surface",
                      new_section=False))

        self._wtexts.append(
            TableText(
                "Vertical speed",
                lambda state: common.format_num(
                    calc.v_speed(state.craft_entity(), state.reference_entity(
                    )), " m/s "),
                "Vertical speed of habitat towards/away reference surface",
                new_section=False))

        self._wtexts.append(
            TableText("Horizontal speed",
                      lambda state: common.format_num(
                          calc.h_speed(state.craft_entity(),
                                       state.reference_entity()), " m/s "),
                      "Horizontal speed of habitat across reference surface",
                      new_section=False))

        self._wtexts.append(
            TableText("Pitch θ",
                      lambda state: common.format_num(
                          np.degrees(
                              calc.pitch(state.craft_entity(
                              ), state.reference_entity())) % 360, "°"),
                      "Horizontal speed of habitat across reference surface",
                      new_section=False))

        self._wtexts.append(
            TableText("Targ altitude",
                      lambda state: common.format_num(calc.altitude(
                          state.craft_entity(), state.target_entity()) / 1000,
                                                      " km",
                                                      decimals=3),
                      "Altitude of habitat above reference surface",
                      new_section=True))

        self._wtexts.append(
            TableText("Targ speed",
                      lambda state: common.format_num(
                          calc.speed(state.craft_entity(), state.target_entity(
                          )), " m/s"),
                      "Speed of habitat above target surface",
                      new_section=False))

        self._wtexts.append(
            TableText(
                "Landing acc",
                lambda state: common.format_num(
                    calc.landing_acceleration(state.craft_entity(),
                                              state.target_entity()), " m/s/s"
                ) or "no vertical landing",
                "Constant engine acc to land during vertical descent to target",
                new_section=False))

        vpython.canvas.get_selected().caption += "</table>"