Exemplo n.º 1
0
    def step(self,
             v_lead=0.0,
             cruise_buttons=None,
             grade=0.0,
             publish_model=True):
        gen_signals, gen_checks = get_can_signals(CP)
        sgs = [s[0] for s in gen_signals]
        msgs = [s[1] for s in gen_signals]
        cks_msgs = set(check[0] for check in gen_checks)
        cks_msgs.add(0x18F)
        cks_msgs.add(0x30C)

        # ******** get messages sent to the car ********
        can_strings = messaging.drain_sock_raw(Plant.sendcan,
                                               wait_for_one=self.response_seen)

        # After the first response the car is done fingerprinting, so we can run in lockstep with controlsd
        if can_strings:
            self.response_seen = True

        self.cp.update_strings(can_strings, sendcan=True)

        # ******** get controlsState messages for plotting ***
        controls_state_msgs = []
        for a in messaging.drain_sock(Plant.controls_state,
                                      wait_for_one=self.response_seen):
            controls_state_msgs.append(a.controlsState)

        fcw = None
        for a in messaging.drain_sock(Plant.plan):
            if a.longitudinalPlan.fcw:
                fcw = True

        if self.cp.vl[0x1fa]['COMPUTER_BRAKE_REQUEST']:
            brake = self.cp.vl[0x1fa]['COMPUTER_BRAKE'] * 0.003906248
        else:
            brake = 0.0

        if self.cp.vl[0x200]['GAS_COMMAND'] > 0:
            gas = self.cp.vl[0x200]['GAS_COMMAND'] / 256.0
        else:
            gas = 0.0

        if self.cp.vl[0xe4]['STEER_TORQUE_REQUEST']:
            steer_torque = self.cp.vl[0xe4]['STEER_TORQUE'] * 1.0 / 0xf00
        else:
            steer_torque = 0.0

        distance_lead = self.distance_lead_prev + v_lead * self.ts

        # ******** run the car ********
        speed, acceleration = car_plant(self.distance_prev, self.speed_prev,
                                        grade, gas, brake)
        distance = self.distance_prev + speed * self.ts
        speed = self.speed_prev + self.ts * acceleration
        if speed <= 0:
            speed = 0
            acceleration = 0

        # ******** lateral ********
        self.angle_steer -= (steer_torque / 10.0) * self.ts

        # *** radar model ***
        if self.lead_relevancy:
            d_rel = np.maximum(0., distance_lead - distance)
            v_rel = v_lead - speed
        else:
            d_rel = 200.
            v_rel = 0.
        lateral_pos_rel = 0.

        # print at 5hz
        if (self.frame % (self.rate // 5)) == 0:
            print(
                "%6.2f m  %6.2f m/s  %6.2f m/s2   %.2f ang   gas: %.2f  brake: %.2f  steer: %5.2f     lead_rel: %6.2f m  %6.2f m/s"
                % (distance, speed, acceleration, self.angle_steer, gas, brake,
                   steer_torque, d_rel, v_rel))

        # ******** publish the car ********
        vls_tuple = namedtuple('vls', [
            'XMISSION_SPEED',
            'WHEEL_SPEED_FL',
            'WHEEL_SPEED_FR',
            'WHEEL_SPEED_RL',
            'WHEEL_SPEED_RR',
            'STEER_ANGLE',
            'STEER_ANGLE_RATE',
            'STEER_TORQUE_SENSOR',
            'STEER_TORQUE_MOTOR',
            'LEFT_BLINKER',
            'RIGHT_BLINKER',
            'GEAR',
            'WHEELS_MOVING',
            'BRAKE_ERROR_1',
            'BRAKE_ERROR_2',
            'SEATBELT_DRIVER_LAMP',
            'SEATBELT_DRIVER_LATCHED',
            'BRAKE_PRESSED',
            'BRAKE_SWITCH',
            'CRUISE_BUTTONS',
            'ESP_DISABLED',
            'HUD_LEAD',
            'USER_BRAKE',
            'STEER_STATUS',
            'GEAR_SHIFTER',
            'PEDAL_GAS',
            'CRUISE_SETTING',
            'ACC_STATUS',
            'CRUISE_SPEED_PCM',
            'CRUISE_SPEED_OFFSET',
            'DOOR_OPEN_FL',
            'DOOR_OPEN_FR',
            'DOOR_OPEN_RL',
            'DOOR_OPEN_RR',
            'CAR_GAS',
            'MAIN_ON',
            'EPB_STATE',
            'BRAKE_HOLD_ACTIVE',
            'INTERCEPTOR_GAS',
            'INTERCEPTOR_GAS2',
            'IMPERIAL_UNIT',
            'MOTOR_TORQUE',
        ])
        vls = vls_tuple(
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.angle_steer,
            self.angle_steer_rate,
            0,
            0,  # Steer torque sensor
            0,
            0,  # Blinkers
            self.gear_choice,
            speed != 0,
            self.brake_error,
            self.brake_error,
            not self.seatbelt,
            self.seatbelt,  # Seatbelt
            self.brake_pressed,
            0.,  # Brake pressed, Brake switch
            cruise_buttons,
            self.esp_disabled,
            0,  # HUD lead
            self.user_brake,
            self.steer_error,
            self.gear_shifter,
            self.pedal_gas,
            self.cruise_setting,
            self.acc_status,
            self.v_cruise,
            0,  # Cruise speed offset
            0,
            0,
            0,
            0,  # Doors
            self.user_gas,
            self.main_on,
            0,  # EPB State
            0,  # Brake hold
            0,  # Interceptor feedback
            0,  # Interceptor 2 feedback
            False,
            0,
        )

        # TODO: publish each message at proper frequency
        can_msgs = []
        for msg in set(msgs):
            msg_struct = {}
            indxs = [i for i, x in enumerate(msgs) if msg == msgs[i]]
            for i in indxs:
                msg_struct[sgs[i]] = getattr(vls, sgs[i])

            if "COUNTER" in honda.get_signals(msg):
                msg_struct["COUNTER"] = self.frame % 4

            if "COUNTER_PEDAL" in honda.get_signals(msg):
                msg_struct["COUNTER_PEDAL"] = self.frame % 0xf

            msg = honda.lookup_msg_id(msg)
            msg_data = honda.encode(msg, msg_struct)

            if "CHECKSUM" in honda.get_signals(msg):
                msg_data = fix(msg_data, msg)

            if "CHECKSUM_PEDAL" in honda.get_signals(msg):
                msg_struct["CHECKSUM_PEDAL"] = crc8_pedal(msg_data[:-1])
                msg_data = honda.encode(msg, msg_struct)

            can_msgs.append([msg, 0, msg_data, 0])

        # add the radar message
        # TODO: use the DBC
        if self.frame % 5 == 0:
            radar_state_msg = b'\x79\x00\x00\x00\x00\x00\x00\x00'
            radar_msg = to_3_byte(d_rel * 16.0) + \
                        to_3_byte(int(lateral_pos_rel * 16.0) & 0x3ff) + \
                        to_3s_byte(int(v_rel * 32.0)) + \
                        b"0f00000"

            radar_msg = binascii.unhexlify(radar_msg)
            can_msgs.append([0x400, 0, radar_state_msg, 1])
            can_msgs.append([0x445, 0, radar_msg, 1])

        # add camera msg so controlsd thinks it's alive
        msg_struct["COUNTER"] = self.frame % 4
        msg = honda.lookup_msg_id(0xe4)
        msg_data = honda.encode(msg, msg_struct)
        msg_data = fix(msg_data, 0xe4)
        can_msgs.append([0xe4, 0, msg_data, 2])

        # Fake sockets that controlsd subscribes to
        live_parameters = messaging.new_message('liveParameters')
        live_parameters.liveParameters.valid = True
        live_parameters.liveParameters.sensorValid = True
        live_parameters.liveParameters.posenetValid = True
        live_parameters.liveParameters.steerRatio = CP.steerRatio
        live_parameters.liveParameters.stiffnessFactor = 1.0
        Plant.live_params.send(live_parameters.to_bytes())

        dmon_state = messaging.new_message('driverMonitoringState')
        dmon_state.driverMonitoringState.isDistracted = False
        Plant.driverMonitoringState.send(dmon_state.to_bytes())

        pandaState = messaging.new_message('pandaState')
        pandaState.pandaState.safetyModel = car.CarParams.SafetyModel.hondaNidec
        pandaState.pandaState.controlsAllowed = True
        Plant.pandaState.send(pandaState.to_bytes())

        deviceState = messaging.new_message('deviceState')
        deviceState.deviceState.freeSpacePercent = 100
        deviceState.deviceState.batteryPercent = 100
        Plant.deviceState.send(deviceState.to_bytes())

        live_location_kalman = messaging.new_message('liveLocationKalman')
        live_location_kalman.liveLocationKalman.inputsOK = True
        live_location_kalman.liveLocationKalman.gpsOK = True
        Plant.live_location_kalman.send(live_location_kalman.to_bytes())

        # ******** publish a fake model going straight and fake calibration ********
        # note that this is worst case for MPC, since model will delay long mpc by one time step
        if publish_model and self.frame % 5 == 0:
            md = messaging.new_message('modelV2')
            cal = messaging.new_message('liveCalibration')
            md.modelV2.frameId = 0

            if self.lead_relevancy:
                d_rel = np.maximum(0., distance_lead - distance)
                v_rel = v_lead - speed
                prob = 1.0
            else:
                d_rel = 200.
                v_rel = 0.
                prob = 0.0

            lead = log.ModelDataV2.LeadDataV2.new_message()
            lead.xyva = [float(d_rel), 0.0, float(v_rel), 0.0]
            lead.xyvaStd = [1.0, 1.0, 1.0, 1.0]
            lead.prob = prob
            md.modelV2.leads = [lead, lead]

            cal.liveCalibration.calStatus = 1
            cal.liveCalibration.calPerc = 100
            cal.liveCalibration.rpyCalib = [0.] * 3
            # fake values?
            Plant.model.send(md.to_bytes())
            Plant.cal.send(cal.to_bytes())
            for s in Plant.pm.sock.keys():
                try:
                    Plant.pm.send(s, messaging.new_message(s))
                except Exception:
                    Plant.pm.send(s, messaging.new_message(s, 1))

        Plant.logcan.send(can_list_to_can_capnp(can_msgs))

        # ******** update prevs ********
        self.frame += 1

        if self.response_seen:
            self.rk.monitor_time()

            self.speed = speed
            self.distance = distance
            self.distance_lead = distance_lead

            self.speed_prev = speed
            self.distance_prev = distance
            self.distance_lead_prev = distance_lead

        else:
            # Don't advance time when controlsd is not yet ready
            self.rk.keep_time()
            self.rk._frame = 0

        return {
            "distance": distance,
            "speed": speed,
            "acceleration": acceleration,
            "distance_lead": distance_lead,
            "brake": brake,
            "gas": gas,
            "steer_torque": steer_torque,
            "fcw": fcw,
            "controls_state_msgs": controls_state_msgs,
        }
Exemplo n.º 2
0
    def step(self,
             v_lead=0.0,
             cruise_buttons=None,
             grade=0.0,
             publish_model=True):
        gen_signals, gen_checks = get_can_signals(CP)
        sgs = [s[0] for s in gen_signals]
        msgs = [s[1] for s in gen_signals]
        cks_msgs = set(check[0] for check in gen_checks)
        cks_msgs.add(0x18F)
        cks_msgs.add(0x30C)

        # ******** get messages sent to the car ********
        can_msgs = []
        for a in messaging.drain_sock(Plant.sendcan):
            can_msgs.extend(can_capnp_to_can_list(a.sendcan, [0, 2]))
        self.cp.update_can(can_msgs)

        # ******** get live100 messages for plotting ***
        live100_msgs = []
        for a in messaging.drain_sock(Plant.live100):
            live100_msgs.append(a.live100)

        fcw = None
        for a in messaging.drain_sock(Plant.plan):
            if a.plan.fcw:
                fcw = True

        if self.cp.vl[0x1fa]['COMPUTER_BRAKE_REQUEST']:
            brake = self.cp.vl[0x1fa]['COMPUTER_BRAKE'] * 0.003906248
        else:
            brake = 0.0

        if self.cp.vl[0x200]['GAS_COMMAND'] > 0:
            gas = self.cp.vl[0x200]['GAS_COMMAND'] / 256.0
        else:
            gas = 0.0

        if self.cp.vl[0xe4]['STEER_TORQUE_REQUEST']:
            steer_torque = self.cp.vl[0xe4]['STEER_TORQUE'] * 1.0 / 0xf00
        else:
            steer_torque = 0.0

        distance_lead = self.distance_lead_prev + v_lead * self.ts

        # ******** run the car ********
        speed, acceleration = car_plant(self.distance_prev, self.speed_prev,
                                        grade, gas, brake)
        distance = self.distance_prev + speed * self.ts
        speed = self.speed_prev + self.ts * acceleration
        if speed <= 0:
            speed = 0
            acceleration = 0

        # ******** lateral ********
        self.angle_steer -= (steer_torque / 10.0) * self.ts

        # *** radar model ***
        if self.lead_relevancy:
            d_rel = np.maximum(0., distance_lead - distance)
            v_rel = v_lead - speed
        else:
            d_rel = 200.
            v_rel = 0.
        lateral_pos_rel = 0.

        # print at 5hz
        if (self.rk.frame % (self.rate // 5)) == 0:
            print(
                "%6.2f m  %6.2f m/s  %6.2f m/s2   %.2f ang   gas: %.2f  brake: %.2f  steer: %5.2f     lead_rel: %6.2f m  %6.2f m/s"
                % (distance, speed, acceleration, self.angle_steer, gas, brake,
                   steer_torque, d_rel, v_rel))

        # ******** publish the car ********
        vls_tuple = namedtuple('vls', [
            'XMISSION_SPEED',
            'WHEEL_SPEED_FL',
            'WHEEL_SPEED_FR',
            'WHEEL_SPEED_RL',
            'WHEEL_SPEED_RR',
            'STEER_ANGLE',
            'STEER_ANGLE_RATE',
            'STEER_TORQUE_SENSOR',
            'LEFT_BLINKER',
            'RIGHT_BLINKER',
            'GEAR',
            'WHEELS_MOVING',
            'BRAKE_ERROR_1',
            'BRAKE_ERROR_2',
            'SEATBELT_DRIVER_LAMP',
            'SEATBELT_DRIVER_LATCHED',
            'BRAKE_PRESSED',
            'BRAKE_SWITCH',
            'CRUISE_BUTTONS',
            'ESP_DISABLED',
            'HUD_LEAD',
            'USER_BRAKE',
            'STEER_STATUS',
            'GEAR_SHIFTER',
            'PEDAL_GAS',
            'CRUISE_SETTING',
            'ACC_STATUS',
            'CRUISE_SPEED_PCM',
            'CRUISE_SPEED_OFFSET',
            'DOOR_OPEN_FL',
            'DOOR_OPEN_FR',
            'DOOR_OPEN_RL',
            'DOOR_OPEN_RR',
            'CAR_GAS',
            'MAIN_ON',
            'EPB_STATE',
            'BRAKE_HOLD_ACTIVE',
            'INTERCEPTOR_GAS',
        ])
        vls = vls_tuple(
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.speed_sensor(speed),
            self.angle_steer,
            self.angle_steer_rate,
            0,  #Steer torque sensor
            0,
            0,  # Blinkers
            self.gear_choice,
            speed != 0,
            self.brake_error,
            self.brake_error,
            not self.seatbelt,
            self.seatbelt,  # Seatbelt
            self.brake_pressed,
            0.,  #Brake pressed, Brake switch
            cruise_buttons,
            self.esp_disabled,
            0,  # HUD lead
            self.user_brake,
            self.steer_error,
            self.gear_shifter,
            self.pedal_gas,
            self.cruise_setting,
            self.acc_status,
            self.v_cruise,
            0,  # Cruise speed offset
            0,
            0,
            0,
            0,  # Doors
            self.user_gas,
            self.main_on,
            0,  # EPB State
            0,  # Brake hold
            0  # Interceptor feedback
        )

        # TODO: publish each message at proper frequency
        can_msgs = []
        for msg in set(msgs):
            msg_struct = {}
            indxs = [i for i, x in enumerate(msgs) if msg == msgs[i]]
            for i in indxs:
                msg_struct[sgs[i]] = getattr(vls, sgs[i])

            if "COUNTER" in honda.get_signals(msg):
                msg_struct["COUNTER"] = self.rk.frame % 4

            if "COUNTER_PEDAL" in honda.get_signals(msg):
                msg_struct["COUNTER_PEDAL"] = self.rk.frame % 0xf

            msg = honda.lookup_msg_id(msg)
            msg_data = honda.encode(msg, msg_struct)

            if "CHECKSUM" in honda.get_signals(msg):
                msg_data = fix(msg_data, msg)

            if "CHECKSUM_PEDAL" in honda.get_signals(msg):
                msg_struct["CHECKSUM_PEDAL"] = crc8_pedal(
                    [ord(i) for i in msg_data][:-1])
                msg_data = honda.encode(msg, msg_struct)

            can_msgs.append([msg, 0, msg_data, 0])

        # add the radar message
        # TODO: use the DBC
        if self.rk.frame % 5 == 0:
            radar_state_msg = '\x79\x00\x00\x00\x00\x00\x00\x00'
            radar_msg = to_3_byte(d_rel*16.0) + \
                        to_3_byte(int(lateral_pos_rel*16.0)&0x3ff) + \
                        to_3s_byte(int(v_rel*32.0)) + \
                        "0f00000"
            can_msgs.append([0x400, 0, radar_state_msg, 1])
            can_msgs.append([0x445, 0, radar_msg.decode("hex"), 1])

        # add camera msg so controlsd thinks it's alive
        msg_struct["COUNTER"] = self.rk.frame % 4
        msg = honda.lookup_msg_id(0xe4)
        msg_data = honda.encode(msg, msg_struct)
        msg_data = fix(msg_data, 0xe4)
        can_msgs.append([0xe4, 0, msg_data, 2])

        Plant.logcan.send(can_list_to_can_capnp(can_msgs))

        # ******** publish a fake model going straight and fake calibration ********
        # note that this is worst case for MPC, since model will delay long mpc by one time step
        if publish_model and self.rk.frame % 5 == 0:
            md = messaging.new_message()
            cal = messaging.new_message()
            md.init('model')
            cal.init('liveCalibration')
            md.model.frameId = 0
            for x in [md.model.path, md.model.leftLane, md.model.rightLane]:
                x.points = [0.0] * 50
                x.prob = 1.0
                x.std = 1.0
            md.model.lead.dist = float(d_rel)
            md.model.lead.prob = 1.
            md.model.lead.std = 0.1
            cal.liveCalibration.calStatus = 1
            cal.liveCalibration.calPerc = 100
            # fake values?
            Plant.model.send(md.to_bytes())
            Plant.cal.send(cal.to_bytes())

        # ******** update prevs ********
        self.speed = speed
        self.distance = distance
        self.distance_lead = distance_lead

        self.speed_prev = speed
        self.distance_prev = distance
        self.distance_lead_prev = distance_lead

        self.rk.keep_time()
        return (distance, speed, acceleration, distance_lead, brake, gas,
                steer_torque, fcw, live100_msgs)