コード例 #1
0
ファイル: engine.py プロジェクト: Arcayik/orbitx
def _reconcile_entity_dynamics(y: PhysicsState) -> PhysicsState:
    """Idempotent helper that sets velocities and spins of some entities.
    This is in its own function because it has a couple calling points."""
    # Navmode auto-rotation
    if y.navmode != Navmode['Manual']:
        craft = y.craft_entity()
        craft.spin = calc.navmode_spin(y)

    # Keep landed entities glued together
    landed_on = y.LandedOn
    for index in landed_on:
        # If we're landed on something, make sure we move in lockstep.
        lander = y[index]
        ground = y[landed_on[index]]

        if ground.name == AYSE and lander.name == HABITAT:
            # Always put the Habitat at the docking port.
            lander.pos = (
                    ground.pos
                    - calc.heading_vector(ground.heading)
                    * (lander.r + ground.r))
        else:
            norm = lander.pos - ground.pos
            unit_norm = norm / calc.fastnorm(norm)
            lander.pos = ground.pos + unit_norm * (ground.r + lander.r)

        lander.spin = ground.spin
        lander.v = calc.rotational_speed(lander, ground)

    return y
コード例 #2
0
ファイル: engine.py プロジェクト: Arcayik/orbitx
def _docking(e1, e2, e2_index):
    # e1 is an artificial object
    # if 2 artificial object to be docked on (spacespation)

    norm = e1.pos - e2.pos
    collision_angle = np.arctan2(norm[1], norm[0])
    collision_angle = collision_angle % (2 * np.pi)

    ANGLE_MIN = (e2.heading + 0.7 * np.pi) % (2 * np.pi)
    ANGLE_MAX = (e2.heading + 1.3 * np.pi) % (2 * np.pi)

    if collision_angle < ANGLE_MIN or collision_angle > ANGLE_MAX:
        # add damage ?
        _bounce(e1, e2)
        return

    log.info(f'Docking {e1.name} on {e2.name}')
    e1.landed_on = e2.name

    # Currently this flag has almost no effect.
    e1.broken = bool(
        calc.fastnorm(calc.rotational_speed(e1, e2) - e1.v) >
        common.craft_capabilities[e1.name].hull_strength
    )

    # set right heading for future takeoff
    e2_opposite = e2.heading + np.pi
    e1.pos = e2.pos + (e1.r + e2.r) * calc.heading_vector(e2_opposite)
    e1.heading = e2_opposite % (2 * np.pi)
    e1.throttle = 0
    e1.spin = e2.spin
    e1.v = e2.v
コード例 #3
0
def _land(e1, e2):
    # e1 is an artificial object
    # if 2 artificial object collide (habitat, spacespation)
    # or small astroid collision (need deletion), handle later

    log.info(f'Landing {e1.name} on {e2.name}')
    assert e2.artificial is False
    e1.landed_on = e2.name

    # Currently does nothing
    e1.broken = bool(
        calc.fastnorm(calc.rotational_speed(e1, e2) -
                      e1.v) > common.craft_capabilities[e1.name].hull_strength)

    # set right heading for future takeoff
    norm = e1.pos - e2.pos
    e1.heading = np.arctan2(norm[1], norm[0])
    e1.throttle = 0
    e1.spin = e2.spin
    e1.v = calc.rotational_speed(e1, e2)
コード例 #4
0
ファイル: engine.py プロジェクト: Arcayik/orbitx
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