def set_state(self, physical_state: PhysicsState): self._stop_simthread() physical_state = _reconcile_entity_dynamics(physical_state) self._artificials = np.where( np.array([entity.artificial for entity in physical_state]) >= 1)[0] # We keep track of the PhysicalState because our simulation # only simulates things that change like position and velocity, # not things that stay constant like names and mass. # self._last_physical_state contains these constants. self._last_physical_state = physical_state.as_proto() self.R = np.array([entity.r for entity in physical_state]) self.M = np.array([entity.mass for entity in physical_state]) self._start_simthread(physical_state.timestamp, physical_state)
def test_y_vector_init(self): """Test that initializing with a y-vector uses y-vector values.""" y0 = np.concatenate(( np.array([ 10, 20, # x 30, 40, # y 50, 60, # vx 0, 0, # vy 0, 0, # heading 70, 80, # spin 90, 100, # fuel 0, 0, # throttle 1, -1, # only First is landed on Second 0, 1, # Second is broken common.SRB_EMPTY, 1 # time_acc ]), np.zeros(EngineeringState.N_ENGINEERING_FIELDS))) ps = PhysicsState(y0, self.proto_state) self.assertTrue(np.array_equal(ps.y0(), y0.astype(ps.y0().dtype))) self.assertEqual(ps['First'].landed_on, 'Second') proto_state = ps.as_proto() proto_state.timestamp = 50 self.assertEqual(proto_state.timestamp, 50) self.assertEqual(proto_state.entities[0].fuel, 90) self.assertTrue(proto_state.entities[1].broken)
def _one_request(request: Request, y0: PhysicsState) \ -> PhysicsState: """Interface to set habitat controls. Use an argument to change habitat throttle or spinning, and simulation will restart with this new information.""" log.info(f'At simtime={y0.timestamp}, ' f'Got command {MessageToString(request, as_one_line=True)}') if request.ident != Request.TIME_ACC_SET: # Reveal the type of y0.craft as str (not None). assert y0.craft is not None if request.ident == Request.HAB_SPIN_CHANGE: if y0.navmode != Navmode['Manual']: # We're in autopilot, ignore this command return y0 craft = y0.craft_entity() if not craft.landed(): craft.spin += request.spin_change elif request.ident == Request.HAB_THROTTLE_CHANGE: y0.craft_entity().throttle += request.throttle_change elif request.ident == Request.HAB_THROTTLE_SET: y0.craft_entity().throttle = request.throttle_set elif request.ident == Request.TIME_ACC_SET: assert request.time_acc_set >= 0 y0.time_acc = request.time_acc_set elif request.ident == Request.ENGINEERING_UPDATE: # Multiply this value by 100, because OrbitV considers engines at # 100% to be 100x the maximum thrust. common.craft_capabilities[HABITAT] = \ common.craft_capabilities[HABITAT]._replace( thrust=100 * request.engineering_update.max_thrust) hab = y0[HABITAT] ayse = y0[AYSE] hab.fuel = request.engineering_update.hab_fuel ayse.fuel = request.engineering_update.ayse_fuel y0[HABITAT] = hab y0[AYSE] = ayse if request.engineering_update.module_state == \ Request.DETACHED_MODULE and \ MODULE not in y0._entity_names and \ not hab.landed(): # If the Habitat is freely floating and engineering asks us to # detach the Module, spawn in the Module. module = Entity(protos.Entity( name=MODULE, mass=100, r=10, artificial=True)) module.pos = (hab.pos - (module.r + hab.r) * calc.heading_vector(hab.heading)) module.v = calc.rotational_speed(module, hab) y0_proto = y0.as_proto() y0_proto.entities.extend([module.proto]) y0 = PhysicsState(None, y0_proto) elif request.ident == Request.UNDOCK: habitat = y0[HABITAT] if habitat.landed_on == AYSE: ayse = y0[AYSE] habitat.landed_on = '' norm = habitat.pos - ayse.pos unit_norm = norm / calc.fastnorm(norm) habitat.v += unit_norm * common.UNDOCK_PUSH habitat.spin = ayse.spin y0[HABITAT] = habitat elif request.ident == Request.REFERENCE_UPDATE: y0.reference = request.reference elif request.ident == Request.TARGET_UPDATE: y0.target = request.target elif request.ident == Request.LOAD_SAVEFILE: y0 = common.load_savefile(common.savefile(request.loadfile)) elif request.ident == Request.NAVMODE_SET: y0.navmode = Navmode(request.navmode) if y0.navmode == Navmode['Manual']: y0.craft_entity().spin = 0 elif request.ident == Request.PARACHUTE: y0.parachute_deployed = request.deploy_parachute elif request.ident == Request.IGNITE_SRBS: if round(y0.srb_time) == common.SRB_FULL: y0.srb_time = common.SRB_BURNTIME elif request.ident == Request.TOGGLE_COMPONENT: component = y0.engineering.components[request.component_to_toggle] component.connected = not component.connected elif request.ident == Request.TOGGLE_RADIATOR: radiator = y0.engineering.radiators[request.radiator_to_toggle] radiator.functioning = not radiator.functioning elif request.ident == Request.CONNECT_RADIATOR_TO_LOOP: radiator = y0.engineering.radiators[request.radiator_to_loop.rad] radiator.attached_to_coolant_loop = request.radiator_to_loop.loop elif request.ident == Request.TOGGLE_COMPONENT_COOLANT: component = y0.engineering.components[request.component_to_loop.component] # See comments on _component_coolant_cnxn_transitions for more info. component.coolant_connection = ( _component_coolant_cnxn_transitions [request.component_to_loop.loop] [component.coolant_connection] ) return y0