def __init__(self, draw_state: PhysicsState, *, title: str, running_as_mirror: bool) -> None: assert len(draw_state) >= 1 self._state = draw_state # create a vpython canvas, onto which all 3D and HTML drawing happens. self._scene = self._init_canvas(title) self._show_label: bool = True self._show_trails: bool = DEFAULT_TRAILS self._paused: bool = False self._removed_saveload_hint: bool = False self._origin: Entity self.texture_path: Path = Path('data', 'textures') self._commands: List[Request] = [] self._paused_label = vpython.label( text="Simulation paused; saving and loading enabled.\n" "When finished, unpause by setting a time acceleration.", xoffset=0, yoffset=200, line=False, height=25, border=20, opacity=1, visible=False) self._3dobjs: Dict[str, ThreeDeeObj] = {} # remove vpython ambient lighting self._scene.lights = [] # This line shouldn't be removed self._set_origin(common.DEFAULT_CENTRE) for entity in draw_state: self._3dobjs[entity.name] = self._build_threedeeobj(entity) self._orbit_projection = OrbitProjection() self._3dobjs[draw_state.reference].draw_landing_graphic( draw_state.reference_entity()) self._3dobjs[draw_state.target].draw_landing_graphic( draw_state.target_entity()) self._sidebar = Sidebar(self, running_as_mirror) self._scene.bind('keydown', self._handle_keydown) # Add an animation when launching the program to describe the solar # system and the current location while self._scene.range > 600000: vpython.rate(100) self._scene.range = self._scene.range * 0.92 self.recentre_camera(common.DEFAULT_CENTRE)
def navmode_heading(flight_state: PhysicsState) -> float: """ Returns the heading that the craft should be facing in current navmode. Don't call this with Manual navmode. If the navmode is relative to the reference, and the reference is set to the craft, this will return the craft's current heading as a sane default. """ navmode = flight_state.navmode craft = flight_state.craft_entity() ref = flight_state.reference_entity() targ = flight_state.target_entity() requested_vector: np.ndarray if navmode == Navmode['Manual']: raise ValueError('Autopilot requested for manual navmode') elif navmode.name == 'CCW Prograde': if flight_state.reference == flight_state.craft: return craft.heading normal = craft.pos - ref.pos requested_vector = np.array([-normal[1], normal[0]]) elif navmode == Navmode['CW Retrograde']: if flight_state.reference == flight_state.craft: return craft.heading normal = craft.pos - ref.pos requested_vector = np.array([normal[1], -normal[0]]) elif navmode == Navmode['Depart Reference']: if flight_state.reference == flight_state.craft: return craft.heading requested_vector = craft.pos - ref.pos elif navmode == Navmode['Approach Target']: if flight_state.target == flight_state.craft: return craft.heading requested_vector = targ.pos - craft.pos elif navmode == Navmode['Pro Targ Velocity']: if flight_state.target == flight_state.craft: return craft.heading requested_vector = craft.v - targ.v elif navmode == Navmode['Anti Targ Velocity']: if flight_state.target == flight_state.craft: return craft.heading requested_vector = targ.v - craft.v else: raise ValueError(f'Got an unexpected NAVMODE: {flight_state.navmode}') return np.arctan2(requested_vector[1], requested_vector[0])