Exemplo n.º 1
0
    def __init__(self, dbc_name, CP, VM):
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.apply_steer_last = 0
        self.steer_rate_limited = False
        self.lkas11_cnt = 0
        self.scc12_cnt = -1

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.turning_indicator_alert = False

        param = Params()

        self.mad_mode_enabled = param.get_bool('MadModeEnabled')
        self.ldws_opt = param.get_bool('IsLdwsCar')
        self.stock_navi_decel_enabled = param.get_bool('StockNaviDecelEnabled')
        self.keep_steering_turn_signals = param.get_bool(
            'KeepSteeringTurnSignals')
        self.warning_over_speed_limit = param.get_bool('WarningOverSpeedLimit')

        # gas_factor, brake_factor
        # Adjust it in the range of 0.7 to 1.3
        self.scc_smoother = SccSmoother()
        self.last_blinker_frame = 0
Exemplo n.º 2
0
  def __init__(self, dbc_name, CP, VM):
    self.car_fingerprint = CP.carFingerprint
    self.packer = CANPacker(dbc_name)
    self.accel_steady = 0
    self.apply_steer_last = 0
    self.steer_rate_limited = False
    self.lkas11_cnt = 0
    self.scc12_cnt = 0

    self.resume_cnt = 0
    self.last_lead_distance = 0
    self.resume_wait_timer = 0

    self.turning_signal_timer = 0
    self.longcontrol = CP.openpilotLongitudinalControl
    self.scc_live = not CP.radarOffCan

    if CP.spasEnabled:
      self.en_cnt = 0
      self.apply_steer_ang = 0.0
      self.en_spas = 3
      self.mdps11_stat_last = 0
      self.spas_always = False

    self.scc_smoother = SccSmoother(accel_gain=1.0, decel_gain=1.0, curvature_gain=0.8)
Exemplo n.º 3
0
    def __init__(self, dbc_name, CP, VM):
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.apply_steer_last = 0
        self.accel = 0
        self.lkas11_cnt = 0
        self.scc12_cnt = -1

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.turning_indicator_alert = False

        param = Params()

        self.mad_mode_enabled = param.get_bool('MadModeEnabled')
        self.ldws_opt = param.get_bool('IsLdwsCar')
        self.stock_navi_decel_enabled = param.get_bool('StockNaviDecelEnabled')
        self.keep_steering_turn_signals = param.get_bool(
            'KeepSteeringTurnSignals')
        self.haptic_feedback_speed_camera = param.get_bool(
            'HapticFeedbackWhenSpeedCamera')

        self.scc_smoother = SccSmoother()
        self.last_blinker_frame = 0
        self.prev_active_cam = False
        self.active_cam_timer = 0
Exemplo n.º 4
0
    def __init__(self, dbc_name, CP, VM):
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.accel_steady = 0
        self.apply_steer_last = 0
        self.steer_rate_limited = False
        self.lkas11_cnt = 0
        self.scc12_cnt = -1

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.mad_mode_enabled = Params().get_bool('MadModeEnabled')
        self.ldws_opt = Params().get_bool('IsLdwsCar')
        self.stock_navi_decel_enabled = Params().get_bool(
            'StockNaviDecelEnabled')

        # gas_factor, brake_factor
        # Adjust it in the range of 0.7 to 1.3
        self.scc_smoother = SccSmoother()
Exemplo n.º 5
0
    def __init__(self, dbc_name, CP, VM):
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.accel_steady = 0
        self.apply_steer_last = 0
        self.steer_rate_limited = False
        self.lkas11_cnt = 0
        self.scc12_cnt = 0

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.mad_mode_enabled = Params().get_bool('MadModeEnabled')

        self.scc_smoother = SccSmoother(1.0)
Exemplo n.º 6
0
  def update(self, enabled, CS, frame, CC, actuators, pcm_cancel_cmd, visual_alert,
             left_lane, right_lane, left_lane_depart, right_lane_depart, set_speed, lead_visible, controls):

    # *** compute control surfaces ***

    # gas and brake
    apply_accel = actuators.gas - actuators.brake
    apply_accel, self.accel_steady = accel_hysteresis(apply_accel, self.accel_steady)
    apply_accel = clip(apply_accel * ACCEL_SCALE, ACCEL_MIN, ACCEL_MAX)

    # Steering Torque
    new_steer = actuators.steer * SteerLimitParams.STEER_MAX
    apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque,
                                                SteerLimitParams)

    self.steer_rate_limited = new_steer != apply_steer

    # SPAS limit angle extremes for safety
    if CS.spas_enabled:
      apply_steer_ang_req = clip(actuators.steerAngle, -1 * (STEER_ANG_MAX), STEER_ANG_MAX)
      # SPAS limit angle rate for safety
      if abs(self.apply_steer_ang - apply_steer_ang_req) > STEER_ANG_MAX_RATE:
        if apply_steer_ang_req > self.apply_steer_ang:
          self.apply_steer_ang += STEER_ANG_MAX_RATE
        else:
          self.apply_steer_ang -= STEER_ANG_MAX_RATE
      else:
        self.apply_steer_ang = apply_steer_ang_req
    spas_active = CS.spas_enabled and enabled and (self.spas_always or CS.out.vEgo < 7.0)  # 25km/h

    # disable if steer angle reach 90 deg, otherwise mdps fault in some models
    lkas_active = enabled and abs(CS.out.steeringAngle) < 90. and not spas_active

    # fix for Genesis hard fault at low speed
    if CS.out.vEgo < 60 * CV.KPH_TO_MS and self.car_fingerprint == CAR.GENESIS and not CS.mdps_bus:
      lkas_active = False

    # Disable steering while turning blinker on and speed below 60 kph
    if CS.out.leftBlinker or CS.out.rightBlinker:
      self.turning_signal_timer = 0.5 / DT_CTRL  # Disable for 0.5 Seconds after blinker turned off
    if self.turning_indicator_alert and CS.out.vEgo < 2 * CV.KPH_TO_MS: # set and clear by interface
      lkas_active = 0
    if self.turning_signal_timer > 0:
      self.turning_signal_timer -= 1

    if not lkas_active:
      apply_steer = 0

    self.apply_accel_last = apply_accel
    self.apply_steer_last = apply_steer

    sys_warning, sys_state, left_lane_warning, right_lane_warning = \
      process_hud_alert(lkas_active, self.car_fingerprint, visual_alert,
                        left_lane, right_lane, left_lane_depart, right_lane_depart)

    clu11_speed = CS.clu11["CF_Clu_Vanz"]
    enabled_speed = 38 if CS.is_set_speed_in_mph else 60
    if clu11_speed > enabled_speed or not lkas_active:
      enabled_speed = clu11_speed

    if not (min_set_speed < set_speed < 255 * CV.KPH_TO_MS):
      set_speed = min_set_speed
    set_speed *= CV.MS_TO_MPH if CS.is_set_speed_in_mph else CV.MS_TO_KPH

    if frame == 0:  # initialize counts from last received count signals
      self.lkas11_cnt = CS.lkas11["CF_Lkas_MsgCount"]
      self.scc12_cnt = CS.scc12["CR_VSM_Alive"] + 1 if not CS.no_radar else 0

      # TODO: fix this
      # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
      # self.scc_update_frame = frame

    # check if SCC is alive
    # if frame % 7 == 0:
    # if CS.scc11["AliveCounterACC"] == self.prev_scc_cnt:
    # if frame - self.scc_update_frame > 20 and self.scc_live:
    # self.scc_live = False
    # else:
    # self.scc_live = True
    # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
    # self.scc_update_frame = frame

    self.prev_scc_cnt = CS.scc11["AliveCounterACC"]

    self.lkas11_cnt = (self.lkas11_cnt + 1) % 0x10
    self.scc12_cnt %= 0xF

    can_sends = []
    can_sends.append(create_lkas11(self.packer, frame, self.car_fingerprint, apply_steer, lkas_active,
                                   CS.lkas11, sys_warning, sys_state, enabled, left_lane, right_lane,
                                   left_lane_warning, right_lane_warning, 0))

    if CS.mdps_bus or CS.scc_bus == 1:  # send lkas11 bus 1 if mdps or scc is on bus 1
      can_sends.append(create_lkas11(self.packer, frame, self.car_fingerprint, apply_steer, lkas_active,
                                     CS.lkas11, sys_warning, sys_state, enabled, left_lane, right_lane,
                                     left_lane_warning, right_lane_warning, 1))
    if CS.mdps_bus:  # send clu11 to mdps if it is not on bus 0
      can_sends.append(create_clu11(self.packer, frame % 0x10, CS.mdps_bus, CS.clu11, Buttons.NONE, enabled_speed))

    if pcm_cancel_cmd and self.longcontrol:
      can_sends.append(create_clu11(self.packer, frame % 0x10, CS.scc_bus, CS.clu11, Buttons.CANCEL, clu11_speed))

    # fix auto resume - by neokii
    if CS.out.cruiseState.standstill:

      if self.last_lead_distance == 0:
        self.last_lead_distance = CS.lead_distance
        self.resume_cnt = 0
        self.resume_wait_timer = 0

      # scc smoother
      elif self.scc_smoother.is_active(frame):
        pass

      elif self.resume_wait_timer > 0:
        self.resume_wait_timer -= 1

      elif CS.lead_distance != self.last_lead_distance:
        can_sends.append(create_clu11(self.packer, self.resume_cnt, CS.scc_bus, CS.clu11, Buttons.RES_ACCEL, clu11_speed))
        self.resume_cnt += 1

        if self.resume_cnt >= 8:
          self.resume_cnt = 0
          self.resume_wait_timer = SccSmoother.get_wait_count()

    # reset lead distnce after the car starts moving
    elif self.last_lead_distance != 0:
      self.last_lead_distance = 0

    # scc smoother
    if not self.longcontrol:
      self.scc_smoother.update(enabled, can_sends, self.packer, CC, CS, frame, apply_accel, controls)

    if CS.mdps_bus:  # send mdps12 to LKAS to prevent LKAS error
      can_sends.append(create_mdps12(self.packer, frame, CS.mdps12))

    # send scc to car if longcontrol enabled and SCC not on bus 0 or ont live
    if self.longcontrol and (CS.scc_bus or not self.scc_live) and frame % 2 == 0:
      can_sends.append(create_scc12(self.packer, apply_accel, enabled, self.scc12_cnt, self.scc_live, CS.scc12))
      can_sends.append(create_scc11(self.packer, frame, enabled, set_speed, lead_visible, self.scc_live, CS.scc11))
      if CS.has_scc13 and frame % 20 == 0:
        can_sends.append(create_scc13(self.packer, CS.scc13))
      if CS.has_scc14:
        can_sends.append(create_scc14(self.packer, enabled, CS.scc14))
      self.scc12_cnt += 1

    # 20 Hz LFA MFA message
    if frame % 5 == 0 and self.car_fingerprint in FEATURES["send_lfa_mfa"]:
      can_sends.append(create_lfa_mfa(self.packer, frame, lkas_active))

    if CS.spas_enabled:
      if CS.mdps_bus:
        can_sends.append(create_ems11(self.packer, CS.ems11, spas_active))

      # SPAS11 50hz
      if (frame % 2) == 0:
        if CS.mdps11_stat == 7 and not self.mdps11_stat_last == 7:
          self.en_spas = 7
          self.en_cnt = 0

        if self.en_spas == 7 and self.en_cnt >= 8:
          self.en_spas = 3
          self.en_cnt = 0

        if self.en_cnt < 8 and spas_active:
          self.en_spas = 4
        elif self.en_cnt >= 8 and spas_active:
          self.en_spas = 5

        if not spas_active:
          self.apply_steer_ang = CS.mdps11_strang
          self.en_spas = 3
          self.en_cnt = 0

        self.mdps11_stat_last = CS.mdps11_stat
        self.en_cnt += 1
        can_sends.append(create_spas11(self.packer, self.car_fingerprint, (frame // 2), self.en_spas, self.apply_steer_ang, CS.mdps_bus))

      # SPAS12 20Hz
      if (frame % 5) == 0:
        can_sends.append(create_spas12(CS.mdps_bus))

    return can_sends
Exemplo n.º 7
0
    def state_transition(self, CS):
        """Compute conditional state transitions and execute actions on state transitions"""

        self.v_cruise_kph_last = self.v_cruise_kph

        # if stock cruise is completely disabled, then we can use our own set speed logic
        self.CP.enableCruise = self.CI.CP.enableCruise

        #if not self.CP.enableCruise:
        #  self.v_cruise_kph = update_v_cruise(self.v_cruise_kph, CS.buttonEvents, self.enabled, self.is_metric)
        #elif self.CP.enableCruise and CS.cruiseState.enabled:
        #  self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH

        # scc smoother
        SccSmoother.update_cruise_buttons(self, CS)

        # decrease the soft disable timer at every step, as it's reset on
        # entrance in SOFT_DISABLING state
        self.soft_disable_timer = max(0, self.soft_disable_timer - 1)

        self.current_alert_types = [ET.PERMANENT]

        # ENABLED, PRE ENABLING, SOFT DISABLING
        if self.state != State.disabled:
            # user and immediate disable always have priority in a non-disabled state
            if self.events.any(ET.USER_DISABLE):
                self.state = State.disabled
                self.current_alert_types.append(ET.USER_DISABLE)

            elif self.events.any(ET.IMMEDIATE_DISABLE):
                self.state = State.disabled
                self.current_alert_types.append(ET.IMMEDIATE_DISABLE)

            else:
                # ENABLED
                if self.state == State.enabled:
                    if self.events.any(ET.SOFT_DISABLE):
                        self.state = State.softDisabling
                        self.soft_disable_timer = 50  # 0.5s
                        self.current_alert_types.append(ET.SOFT_DISABLE)

                # SOFT DISABLING
                elif self.state == State.softDisabling:
                    if not self.events.any(ET.SOFT_DISABLE):
                        # no more soft disabling condition, so go back to ENABLED
                        self.state = State.enabled

                    elif self.events.any(
                            ET.SOFT_DISABLE) and self.soft_disable_timer > 0:
                        self.current_alert_types.append(ET.SOFT_DISABLE)

                    elif self.soft_disable_timer <= 0:
                        self.state = State.disabled

                # PRE ENABLING
                elif self.state == State.preEnabled:
                    if not self.events.any(ET.PRE_ENABLE):
                        self.state = State.enabled
                    else:
                        self.current_alert_types.append(ET.PRE_ENABLE)

        # DISABLED
        elif self.state == State.disabled:
            if self.events.any(ET.ENABLE):
                if self.events.any(ET.NO_ENTRY):
                    self.current_alert_types.append(ET.NO_ENTRY)

                else:
                    if self.events.any(ET.PRE_ENABLE):
                        self.state = State.preEnabled
                    else:
                        self.state = State.enabled
                    self.current_alert_types.append(ET.ENABLE)
                    self.v_cruise_kph = initialize_v_cruise(
                        CS.vEgo, CS.buttonEvents, self.v_cruise_kph_last)

        # Check if actuators are enabled
        self.active = self.state == State.enabled or self.state == State.softDisabling
        if self.active:
            self.current_alert_types.append(ET.WARNING)

        # Check if openpilot is engaged
        self.enabled = self.active or self.state == State.preEnabled
Exemplo n.º 8
0
class CarController():
    def __init__(self, dbc_name, CP, VM):
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.accel_steady = 0
        self.apply_steer_last = 0
        self.steer_rate_limited = False
        self.lkas11_cnt = 0
        self.scc12_cnt = 0

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.mad_mode_enabled = Params().get('MadModeEnabled') == b'1'

        self.scc_smoother = SccSmoother(accel_gain=1.0,
                                        decel_gain=1.0,
                                        curvature_gain=1.0)

    def update(self, enabled, CS, frame, CC, actuators, pcm_cancel_cmd,
               visual_alert, left_lane, right_lane, left_lane_depart,
               right_lane_depart, set_speed, lead_visible, controls):

        # *** compute control surfaces ***

        # gas and brake
        apply_accel = actuators.gas - actuators.brake
        apply_accel, self.accel_steady = accel_hysteresis(
            apply_accel, self.accel_steady)
        apply_accel = clip(apply_accel * CarControllerParams.ACCEL_SCALE,
                           CarControllerParams.ACCEL_MIN,
                           CarControllerParams.ACCEL_MAX)

        # Steering Torque
        new_steer = int(round(actuators.steer * SteerLimitParams.STEER_MAX))
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    SteerLimitParams)

        self.steer_rate_limited = new_steer != apply_steer

        # disable if steer angle reach 90 deg, otherwise mdps fault in some models
        lkas_active = enabled and abs(CS.out.steeringAngleDeg) < 90.

        # fix for Genesis hard fault at low speed
        if CS.out.vEgo < 60 * CV.KPH_TO_MS and self.car_fingerprint == CAR.GENESIS and not CS.mdps_bus:
            lkas_active = False

        # Disable steering while turning blinker on and speed below 60 kph
        if CS.out.leftBlinker or CS.out.rightBlinker:
            self.turning_signal_timer = 0.5 / DT_CTRL  # Disable for 0.5 Seconds after blinker turned off
        if self.turning_indicator_alert and CS.out.vEgo < 2 * CV.KPH_TO_MS:  # set and clear by interface
            lkas_active = 0
        if self.turning_signal_timer > 0:
            self.turning_signal_timer -= 1

        if not lkas_active:
            apply_steer = 0

        self.apply_accel_last = apply_accel
        self.apply_steer_last = apply_steer

        sys_warning, sys_state, left_lane_warning, right_lane_warning = \
          process_hud_alert(enabled, self.car_fingerprint, visual_alert,
                            left_lane, right_lane, left_lane_depart, right_lane_depart)

        clu11_speed = CS.clu11["CF_Clu_Vanz"]
        enabled_speed = 38 if CS.is_set_speed_in_mph else 60
        if clu11_speed > enabled_speed or not lkas_active:
            enabled_speed = clu11_speed

        controls.clu_speed_ms = clu11_speed * CV.KPH_TO_MS

        if not (min_set_speed < set_speed < 255 * CV.KPH_TO_MS):
            set_speed = min_set_speed
        set_speed *= CV.MS_TO_MPH if CS.is_set_speed_in_mph else CV.MS_TO_KPH

        if frame == 0:  # initialize counts from last received count signals
            self.lkas11_cnt = CS.lkas11["CF_Lkas_MsgCount"]
            self.scc12_cnt = CS.scc12[
                "CR_VSM_Alive"] + 1 if not CS.no_radar else 0

            # TODO: fix this
            # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
            # self.scc_update_frame = frame

        # check if SCC is alive
        # if frame % 7 == 0:
        # if CS.scc11["AliveCounterACC"] == self.prev_scc_cnt:
        # if frame - self.scc_update_frame > 20 and self.scc_live:
        # self.scc_live = False
        # else:
        # self.scc_live = True
        # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
        # self.scc_update_frame = frame

        self.prev_scc_cnt = CS.scc11["AliveCounterACC"]

        self.lkas11_cnt = (self.lkas11_cnt + 1) % 0x10
        self.scc12_cnt %= 0xF

        #    apply_steer = interp(CS.out.vEgo, [0., 3.], [0., 1.])

        can_sends = []
        can_sends.append(
            create_lkas11(self.packer, frame, self.car_fingerprint,
                          apply_steer, lkas_active, CS.lkas11, sys_warning,
                          sys_state, enabled, left_lane, right_lane,
                          left_lane_warning, right_lane_warning, 0))

        if CS.mdps_bus or CS.scc_bus == 1:  # send lkas11 bus 1 if mdps or scc is on bus 1
            can_sends.append(
                create_lkas11(self.packer, frame, self.car_fingerprint,
                              apply_steer, lkas_active, CS.lkas11, sys_warning,
                              sys_state, enabled, left_lane, right_lane,
                              left_lane_warning, right_lane_warning, 1))

        if frame % 2 and CS.mdps_bus:  # send clu11 to mdps if it is not on bus 0
            can_sends.append(
                create_clu11(self.packer, frame // 2 % 0x10, CS.mdps_bus,
                             CS.clu11, Buttons.NONE, enabled_speed))

        if pcm_cancel_cmd and (self.longcontrol and not self.mad_mode_enabled):
            can_sends.append(
                create_clu11(self.packer, frame % 0x10, CS.scc_bus, CS.clu11,
                             Buttons.CANCEL, clu11_speed))

        # fix auto resume - by neokii
        if CS.out.cruiseState.standstill:

            if self.last_lead_distance == 0:
                self.last_lead_distance = CS.lead_distance
                self.resume_cnt = 0
                self.resume_wait_timer = 0

            # scc smoother
            elif self.scc_smoother.is_active(frame):
                pass

            elif self.resume_wait_timer > 0:
                self.resume_wait_timer -= 1

            elif CS.lead_distance != self.last_lead_distance:
                can_sends.append(
                    create_clu11(self.packer, self.resume_cnt, CS.scc_bus,
                                 CS.clu11, Buttons.RES_ACCEL, clu11_speed))
                self.resume_cnt += 1

                if self.resume_cnt >= 8:
                    self.resume_cnt = 0
                    self.resume_wait_timer = SccSmoother.get_wait_count()

        # reset lead distnce after the car starts moving
        elif self.last_lead_distance != 0:
            self.last_lead_distance = 0

        # scc smoother
        self.scc_smoother.update(enabled, can_sends, self.packer, CC, CS,
                                 frame, apply_accel, controls)

        if CS.mdps_bus:  # send mdps12 to LKAS to prevent LKAS error
            can_sends.append(create_mdps12(self.packer, frame, CS.mdps12))

        controls.apply_accel = apply_accel
        aReqValue = CS.scc12["aReqValue"]
        controls.aReqValue = aReqValue

        if aReqValue < controls.aReqValueMin:
            controls.aReqValueMin = controls.aReqValue

        if aReqValue > controls.aReqValueMax:
            controls.aReqValueMax = controls.aReqValue

        # send scc to car if longcontrol enabled and SCC not on bus 0 or ont live
        if self.longcontrol and CS.cruiseState_enabled and (
                CS.scc_bus or not self.scc_live) and frame % 2 == 0:

            apply_accel, lead_drel = self.scc_smoother.get_fused_accel(
                apply_accel, aReqValue, controls.sm)
            controls.fused_accel = apply_accel
            controls.lead_drel = lead_drel

            can_sends.append(
                create_scc12(self.packer, apply_accel, enabled, self.scc12_cnt,
                             self.scc_live, CS.scc12))
            can_sends.append(
                create_scc11(self.packer, frame, enabled, set_speed,
                             controls.sm['radarState'], self.scc_live,
                             CS.scc11))

            if CS.has_scc13 and frame % 20 == 0:
                can_sends.append(create_scc13(self.packer, CS.scc13))
            if CS.has_scc14:
                can_sends.append(create_scc14(self.packer, enabled, CS.scc14))
            self.scc12_cnt += 1

            # 20 Hz LFA MFA message
        if frame % 5 == 0 and self.car_fingerprint in FEATURES["send_lfa_mfa"]:
            can_sends.append(create_lfahda_mfc(self.packer, enabled))

        return can_sends
Exemplo n.º 9
0
  def state_transition(self, CS):
    """Compute conditional state transitions and execute actions on state transitions"""

    self.v_cruise_kph_last = self.v_cruise_kph

    self.CP.pcmCruise = self.CI.CP.pcmCruise

    # if stock cruise is completely disabled, then we can use our own set speed logic
    #if not self.CP.pcmCruise:
    #  self.v_cruise_kph = update_v_cruise(self.v_cruise_kph, CS.buttonEvents, self.button_timers, self.enabled, self.is_metric)
    #else:
    #  if CS.cruiseState.available:
    #    self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
    #  else:
    #    self.v_cruise_kph = 0

    SccSmoother.update_cruise_buttons(self, CS, self.CP.openpilotLongitudinalControl)

    # decrement the soft disable timer at every step, as it's reset on
    # entrance in SOFT_DISABLING state
    self.soft_disable_timer = max(0, self.soft_disable_timer - 1)

    self.current_alert_types = [ET.PERMANENT]

    # ENABLED, SOFT DISABLING, PRE ENABLING, OVERRIDING
    if self.state != State.disabled:
      # user and immediate disable always have priority in a non-disabled state
      if self.events.any(ET.USER_DISABLE):
        self.state = State.disabled
        self.current_alert_types.append(ET.USER_DISABLE)

      elif self.events.any(ET.IMMEDIATE_DISABLE):
        self.state = State.disabled
        self.current_alert_types.append(ET.IMMEDIATE_DISABLE)

      else:
        # ENABLED
        if self.state == State.enabled:
          if self.events.any(ET.SOFT_DISABLE):
            self.state = State.softDisabling
            self.soft_disable_timer = int(0.5 / DT_CTRL)
            self.current_alert_types.append(ET.SOFT_DISABLE)

          elif self.events.any(ET.OVERRIDE):
            self.state = State.overriding
            self.current_alert_types.append(ET.OVERRIDE)

        # SOFT DISABLING
        elif self.state == State.softDisabling:
          if not self.events.any(ET.SOFT_DISABLE):
            # no more soft disabling condition, so go back to ENABLED
            self.state = State.enabled

          elif self.soft_disable_timer > 0:
            self.current_alert_types.append(ET.SOFT_DISABLE)

          elif self.soft_disable_timer <= 0:
            self.state = State.disabled

        # PRE ENABLING
        elif self.state == State.preEnabled:
          if self.events.any(ET.NO_ENTRY):
            self.state = State.disabled
            self.current_alert_types.append(ET.NO_ENTRY)
          elif not self.events.any(ET.PRE_ENABLE):
            self.state = State.enabled
          else:
            self.current_alert_types.append(ET.PRE_ENABLE)

        # OVERRIDING
        elif self.state == State.overriding:
          if self.events.any(ET.SOFT_DISABLE):
            self.state = State.softDisabling
            self.soft_disable_timer = int(SOFT_DISABLE_TIME / DT_CTRL)
            self.current_alert_types.append(ET.SOFT_DISABLE)
          elif not self.events.any(ET.OVERRIDE):
            self.state = State.enabled
          else:
            self.current_alert_types.append(ET.OVERRIDE)

    # DISABLED
    elif self.state == State.disabled:
      if self.events.any(ET.ENABLE):
        if self.events.any(ET.NO_ENTRY):
          self.current_alert_types.append(ET.NO_ENTRY)

        else:
          if self.events.any(ET.PRE_ENABLE):
            self.state = State.preEnabled
          elif self.events.any(ET.OVERRIDE):
            self.state = State.overriding
          else:
            self.state = State.enabled
          self.current_alert_types.append(ET.ENABLE)
          if not self.CP.pcmCruise:
            self.v_cruise_kph = initialize_v_cruise(CS.vEgo, CS.buttonEvents, self.v_cruise_kph_last)

    # Check if openpilot is engaged and actuators are enabled
    self.enabled = self.state in ENABLED_STATES
    self.active = self.state in ACTIVE_STATES
    if self.active:
      self.current_alert_types.append(ET.WARNING)
Exemplo n.º 10
0
class CarController():
    def __init__(self, dbc_name, CP, VM):
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.apply_steer_last = 0
        self.accel = 0
        self.lkas11_cnt = 0
        self.scc12_cnt = -1

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.turning_indicator_alert = False

        param = Params()

        self.mad_mode_enabled = param.get_bool('MadModeEnabled')
        self.ldws_opt = param.get_bool('IsLdwsCar')
        self.stock_navi_decel_enabled = param.get_bool('StockNaviDecelEnabled')
        self.keep_steering_turn_signals = param.get_bool(
            'KeepSteeringTurnSignals')
        self.haptic_feedback_speed_camera = param.get_bool(
            'HapticFeedbackWhenSpeedCamera')

        self.scc_smoother = SccSmoother()
        self.last_blinker_frame = 0
        self.prev_active_cam = False
        self.active_cam_timer = 0

    def update(self, c, enabled, CS, frame, CC, actuators, pcm_cancel_cmd,
               visual_alert, left_lane, right_lane, left_lane_depart,
               right_lane_depart, set_speed, lead_visible, controls):

        # Steering Torque
        new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX))
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    CarControllerParams)

        # disable when temp fault is active, or below LKA minimum speed
        lkas_active = c.active and not CS.out.steerWarning and abs(
            CS.out.steeringAngleDeg) < CS.CP.maxSteeringAngleDeg

        # Disable steering while turning blinker on and speed below 60 kph
        if CS.out.leftBlinker or CS.out.rightBlinker:
            self.turning_signal_timer = 0.5 / DT_CTRL  # Disable for 0.5 Seconds after blinker turned off
        if self.turning_indicator_alert:  # set and clear by interface
            lkas_active = 0
        if self.turning_signal_timer > 0:
            self.turning_signal_timer -= 1

        if not lkas_active:
            apply_steer = 0

        self.apply_steer_last = apply_steer

        sys_warning, sys_state, left_lane_warning, right_lane_warning = \
          process_hud_alert(enabled, self.car_fingerprint, visual_alert,
                            left_lane, right_lane, left_lane_depart, right_lane_depart)

        if self.haptic_feedback_speed_camera:
            if self.prev_active_cam != self.scc_smoother.active_cam:
                self.prev_active_cam = self.scc_smoother.active_cam
                if self.scc_smoother.active_cam:
                    self.active_cam_timer = int(1.5 / DT_CTRL)

            if self.active_cam_timer > 0:
                self.active_cam_timer -= 1
                left_lane_warning = right_lane_warning = 1

        clu11_speed = CS.clu11["CF_Clu_Vanz"]
        enabled_speed = 38 if CS.is_set_speed_in_mph else 60
        if clu11_speed > enabled_speed or not lkas_active:
            enabled_speed = clu11_speed

        if not (min_set_speed < set_speed < 255 * CV.KPH_TO_MS):
            set_speed = min_set_speed
        set_speed *= CV.MS_TO_MPH if CS.is_set_speed_in_mph else CV.MS_TO_KPH

        if frame == 0:  # initialize counts from last received count signals
            self.lkas11_cnt = CS.lkas11["CF_Lkas_MsgCount"]

            # TODO: fix this
            # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
            # self.scc_update_frame = frame

        # check if SCC is alive
        # if frame % 7 == 0:
        # if CS.scc11["AliveCounterACC"] == self.prev_scc_cnt:
        # if frame - self.scc_update_frame > 20 and self.scc_live:
        # self.scc_live = False
        # else:
        # self.scc_live = True
        # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
        # self.scc_update_frame = frame

        self.prev_scc_cnt = CS.scc11["AliveCounterACC"]

        self.lkas11_cnt = (self.lkas11_cnt + 1) % 0x10

        can_sends = []
        can_sends.append(
            create_lkas11(self.packer, frame, self.car_fingerprint,
                          apply_steer, lkas_active, CS.lkas11, sys_warning,
                          sys_state, enabled, left_lane, right_lane,
                          left_lane_warning, right_lane_warning, 0,
                          self.ldws_opt))

        if CS.mdps_bus or CS.scc_bus == 1:  # send lkas11 bus 1 if mdps or scc is on bus 1
            can_sends.append(
                create_lkas11(self.packer, frame, self.car_fingerprint,
                              apply_steer, lkas_active, CS.lkas11, sys_warning,
                              sys_state, enabled, left_lane, right_lane,
                              left_lane_warning, right_lane_warning, 1,
                              self.ldws_opt))

        if frame % 2 and CS.mdps_bus:  # send clu11 to mdps if it is not on bus 0
            can_sends.append(
                create_clu11(self.packer, CS.mdps_bus, CS.clu11, Buttons.NONE,
                             enabled_speed))

        if pcm_cancel_cmd and (self.longcontrol and not self.mad_mode_enabled):
            can_sends.append(
                create_clu11(self.packer, CS.scc_bus, CS.clu11, Buttons.CANCEL,
                             clu11_speed))
        else:
            can_sends.append(create_mdps12(self.packer, frame, CS.mdps12))

        # fix auto resume - by neokii
        if CS.out.cruiseState.standstill and not CS.out.gasPressed:

            if self.last_lead_distance == 0:
                self.last_lead_distance = CS.lead_distance
                self.resume_cnt = 0
                self.resume_wait_timer = 0

            # scc smoother
            elif self.scc_smoother.is_active(frame):
                pass

            elif self.resume_wait_timer > 0:
                self.resume_wait_timer -= 1

            elif abs(CS.lead_distance - self.last_lead_distance) > 0.1:
                can_sends.append(
                    create_clu11(self.packer, CS.scc_bus, CS.clu11,
                                 Buttons.RES_ACCEL, clu11_speed))
                self.resume_cnt += 1

                if self.resume_cnt >= randint(6, 8):
                    self.resume_cnt = 0
                    self.resume_wait_timer = randint(30, 36)

        # reset lead distnce after the car starts moving
        elif self.last_lead_distance != 0:
            self.last_lead_distance = 0

        # scc smoother
        self.scc_smoother.update(enabled, can_sends, self.packer, CC, CS,
                                 frame, controls)

        # send scc to car if longcontrol enabled and SCC not on bus 0 or ont live
        if self.longcontrol and CS.cruiseState_enabled and (CS.scc_bus or
                                                            not self.scc_live):

            if frame % 2 == 0:

                stopping = controls.LoC.long_control_state == LongCtrlState.stopping
                apply_accel = clip(actuators.accel if c.active else 0,
                                   CarControllerParams.ACCEL_MIN,
                                   CarControllerParams.ACCEL_MAX)
                apply_accel = self.scc_smoother.get_apply_accel(
                    CS, controls.sm, apply_accel, stopping)

                self.accel = apply_accel

                controls.apply_accel = apply_accel
                aReqValue = CS.scc12["aReqValue"]
                controls.aReqValue = aReqValue

                if aReqValue < controls.aReqValueMin:
                    controls.aReqValueMin = controls.aReqValue

                if aReqValue > controls.aReqValueMax:
                    controls.aReqValueMax = controls.aReqValue

                if self.stock_navi_decel_enabled:
                    controls.sccStockCamAct = CS.scc11["Navi_SCC_Camera_Act"]
                    controls.sccStockCamStatus = CS.scc11[
                        "Navi_SCC_Camera_Status"]
                    apply_accel, stock_cam = self.scc_smoother.get_stock_cam_accel(
                        apply_accel, aReqValue, CS.scc11)
                else:
                    controls.sccStockCamAct = 0
                    controls.sccStockCamStatus = 0
                    stock_cam = False

                if self.scc12_cnt < 0:
                    self.scc12_cnt = CS.scc12[
                        "CR_VSM_Alive"] if not CS.no_radar else 0

                self.scc12_cnt += 1
                self.scc12_cnt %= 0xF

                can_sends.append(
                    create_scc12(self.packer, apply_accel, enabled,
                                 self.scc12_cnt, self.scc_live, CS.scc12,
                                 CS.out.gasPressed, CS.out.brakePressed,
                                 CS.out.cruiseState.standstill,
                                 self.car_fingerprint))

                can_sends.append(
                    create_scc11(self.packer, frame, enabled, set_speed,
                                 lead_visible, self.scc_live, CS.scc11,
                                 self.scc_smoother.active_cam, stock_cam))

                if frame % 20 == 0 and CS.has_scc13:
                    can_sends.append(create_scc13(self.packer, CS.scc13))

                if CS.has_scc14:
                    acc_standstill = stopping if CS.out.vEgo < 2. else False

                    lead = self.scc_smoother.get_lead(controls.sm)

                    if lead is not None:
                        d = lead.dRel
                        obj_gap = 1 if d < 25 else 2 if d < 40 else 3 if d < 60 else 4 if d < 80 else 5
                    else:
                        obj_gap = 0

                    can_sends.append(
                        create_scc14(self.packer, enabled, CS.out.vEgo,
                                     acc_standstill, apply_accel,
                                     CS.out.gasPressed, obj_gap, CS.scc14))
        else:
            self.scc12_cnt = -1

        # 20 Hz LFA MFA message
        if frame % 5 == 0:
            activated_hda = road_speed_limiter_get_active()
            # activated_hda: 0 - off, 1 - main road, 2 - highway
            if self.car_fingerprint in FEATURES["send_lfa_mfa"]:
                can_sends.append(
                    create_lfahda_mfc(self.packer, enabled, activated_hda))
            elif CS.has_lfa_hda:
                can_sends.append(
                    create_hda_mfc(self.packer, activated_hda, CS, left_lane,
                                   right_lane))

        new_actuators = actuators.copy()
        new_actuators.steer = apply_steer / CarControllerParams.STEER_MAX
        new_actuators.accel = self.accel

        return new_actuators, can_sends
Exemplo n.º 11
0
class CarController:
    def __init__(self, dbc_name, CP, VM):
        self.CP = CP
        self.params = CarControllerParams(CP)
        self.packer = CANPacker(dbc_name)
        self.frame = 0

        self.apply_steer_last = 0
        self.last_button_frame = 0
        self.accel = 0
        self.lkas11_cnt = 0
        self.scc12_cnt = -1

        self.resume_cnt = 0
        self.last_lead_distance = 0
        self.resume_wait_timer = 0

        self.turning_signal_timer = 0
        self.longcontrol = CP.openpilotLongitudinalControl
        self.scc_live = not CP.radarOffCan

        self.turning_indicator_alert = False

        param = Params()

        self.mad_mode_enabled = param.get_bool('MadModeEnabled')
        self.ldws_opt = param.get_bool('IsLdwsCar')
        self.stock_navi_decel_enabled = param.get_bool('StockNaviDecelEnabled')
        self.keep_steering_turn_signals = param.get_bool(
            'KeepSteeringTurnSignals')
        self.haptic_feedback_speed_camera = param.get_bool(
            'HapticFeedbackWhenSpeedCamera')

        self.scc_smoother = SccSmoother()
        self.last_blinker_frame = 0
        self.prev_active_cam = False
        self.active_cam_timer = 0
        self.last_active_cam_frame = 0

        self.angle_limit_counter = 0
        self.cut_steer_frames = 0
        self.cut_steer = False

        self.steer_fault_max_angle = CP.steerFaultMaxAngle
        self.steer_fault_max_frames = CP.steerFaultMaxFrames

    def update(self, CC, CS, controls):
        if self.CP.carFingerprint in HDA2_CAR:
            return self.update_hda2(CC, CS)

        actuators = CC.actuators
        hud_control = CC.hudControl
        pcm_cancel_cmd = CC.cruiseControl.cancel

        # Steering Torque
        new_steer = int(round(actuators.steer * self.params.STEER_MAX))
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    self.params)

        # disable when temp fault is active, or below LKA minimum speed
        lkas_active = CC.latActive

        # Disable steering while turning blinker on and speed below 60 kph
        if CS.out.leftBlinker or CS.out.rightBlinker:
            self.turning_signal_timer = 0.5 / DT_CTRL  # Disable for 0.5 Seconds after blinker turned off
        if self.turning_indicator_alert:  # set and clear by interface
            lkas_active = 0
        if self.turning_signal_timer > 0:
            self.turning_signal_timer -= 1

        if not lkas_active:
            apply_steer = 0

        self.apply_steer_last = apply_steer

        sys_warning, sys_state, left_lane_warning, right_lane_warning = process_hud_alert(
            CC.enabled, self.CP.carFingerprint, hud_control)

        if self.haptic_feedback_speed_camera:
            if self.prev_active_cam != self.scc_smoother.active_cam:
                self.prev_active_cam = self.scc_smoother.active_cam
                if self.scc_smoother.active_cam:
                    if (self.frame -
                            self.last_active_cam_frame) * DT_CTRL > 10.0:
                        self.active_cam_timer = int(1.5 / DT_CTRL)
                        self.last_active_cam_frame = self.frame

            if self.active_cam_timer > 0:
                self.active_cam_timer -= 1
                left_lane_warning = right_lane_warning = 1

        clu11_speed = CS.clu11["CF_Clu_Vanz"]
        enabled_speed = 38 if CS.is_set_speed_in_mph else 60
        if clu11_speed > enabled_speed or not lkas_active:
            enabled_speed = clu11_speed

        if self.frame == 0:  # initialize counts from last received count signals
            self.lkas11_cnt = CS.lkas11["CF_Lkas_MsgCount"]

        self.lkas11_cnt = (self.lkas11_cnt + 1) % 0x10

        cut_steer_temp = False

        if self.steer_fault_max_angle > 0:
            if lkas_active and abs(
                    CS.out.steeringAngleDeg) > self.steer_fault_max_angle:
                self.angle_limit_counter += 1
            else:
                self.angle_limit_counter = 0

            # stop requesting torque to avoid 90 degree fault and hold torque with induced temporary fault
            # two cycles avoids race conditions every few minutes
            if self.angle_limit_counter > self.steer_fault_max_frames:
                self.cut_steer = True
            elif self.cut_steer_frames > 1:
                self.cut_steer_frames = 0
                self.cut_steer = False

            if self.cut_steer:
                cut_steer_temp = True
                self.angle_limit_counter = 0
                self.cut_steer_frames += 1

        can_sends = []
        can_sends.append(
            hyundaican.create_lkas11(
                self.packer, self.frame, self.CP.carFingerprint, apply_steer,
                lkas_active, CS.lkas11, sys_warning, sys_state, CC.enabled,
                hud_control.leftLaneVisible, hud_control.rightLaneVisible,
                left_lane_warning, right_lane_warning, 0, self.ldws_opt,
                cut_steer_temp))

        if CS.mdps_bus or CS.scc_bus == 1:  # send lkas11 bus 1 if mdps or scc is on bus 1
            can_sends.append(
                hyundaican.create_lkas11(
                    self.packer, self.frame, self.CP.carFingerprint,
                    apply_steer, lkas_active, CS.lkas11, sys_warning,
                    sys_state, CC.enabled, hud_control.leftLaneVisible,
                    hud_control.rightLaneVisible, left_lane_warning,
                    right_lane_warning, 1, self.ldws_opt, cut_steer_temp))

        if self.frame % 2 and CS.mdps_bus:  # send clu11 to mdps if it is not on bus 0
            can_sends.append(
                hyundaican.create_clu11(self.packer, CS.mdps_bus, CS.clu11,
                                        Buttons.NONE, enabled_speed))

        if pcm_cancel_cmd and (self.longcontrol and not self.mad_mode_enabled):
            can_sends.append(
                hyundaican.create_clu11(self.packer, CS.scc_bus, CS.clu11,
                                        Buttons.CANCEL, clu11_speed))

        if CS.mdps_bus or self.CP.carFingerprint in FEATURES[
                "send_mdps12"]:  # send mdps12 to LKAS to prevent LKAS error
            can_sends.append(
                hyundaican.create_mdps12(self.packer, self.frame, CS.mdps12))

        self.update_auto_resume(CC, CS, clu11_speed, can_sends)
        self.update_scc(CC, CS, actuators, controls, hud_control, can_sends)

        # 20 Hz LFA MFA message
        if self.frame % 5 == 0:
            activated_hda = road_speed_limiter_get_active()
            # activated_hda: 0 - off, 1 - main road, 2 - highway
            if self.CP.carFingerprint in FEATURES["send_lfa_mfa"]:
                can_sends.append(
                    hyundaican.create_lfahda_mfc(self.packer, CC.enabled,
                                                 activated_hda))
            elif CS.has_lfa_hda:
                can_sends.append(
                    hyundaican.create_hda_mfc(self.packer, activated_hda, CS,
                                              hud_control.leftLaneVisible,
                                              hud_control.rightLaneVisible))

        new_actuators = actuators.copy()
        new_actuators.steer = apply_steer / self.params.STEER_MAX
        new_actuators.accel = self.accel

        self.frame += 1
        return new_actuators, can_sends

    def update_auto_resume(self, CC, CS, clu11_speed, can_sends):
        # fix auto resume - by neokii
        if CS.out.cruiseState.standstill and not CS.out.gasPressed:
            if self.last_lead_distance == 0:
                self.last_lead_distance = CS.lead_distance
                self.resume_cnt = 0
                self.resume_wait_timer = 0

            elif self.scc_smoother.is_active(self.frame):
                pass

            elif self.resume_wait_timer > 0:
                self.resume_wait_timer -= 1

            elif abs(CS.lead_distance - self.last_lead_distance) > 0.1:
                can_sends.append(
                    hyundaican.create_clu11(self.packer, CS.scc_bus, CS.clu11,
                                            Buttons.RES_ACCEL, clu11_speed))
                self.resume_cnt += 1

                if self.resume_cnt >= randint(6, 8):
                    self.resume_cnt = 0
                    self.resume_wait_timer = randint(30, 36)

        elif self.last_lead_distance != 0:
            self.last_lead_distance = 0

    def update_scc(self, CC, CS, actuators, controls, hud_control, can_sends):

        # scc smoother
        self.scc_smoother.update(CC.enabled, can_sends, self.packer, CC, CS,
                                 self.frame, controls)

        # send scc to car if longcontrol enabled and SCC not on bus 0 or ont live
        if self.longcontrol and CS.cruiseState_enabled and (CS.scc_bus or
                                                            not self.scc_live):

            if self.frame % 2 == 0:

                set_speed = hud_control.setSpeed
                if not (min_set_speed < set_speed < 255 * CV.KPH_TO_MS):
                    set_speed = min_set_speed
                set_speed *= CV.MS_TO_MPH if CS.is_set_speed_in_mph else CV.MS_TO_KPH

                stopping = controls.LoC.long_control_state == LongCtrlState.stopping
                apply_accel = self.scc_smoother.get_apply_accel(
                    CS, controls.sm, actuators.accel, stopping)
                apply_accel = clip(apply_accel if CC.longActive else 0,
                                   CarControllerParams.ACCEL_MIN,
                                   CarControllerParams.ACCEL_MAX)

                self.accel = apply_accel

                controls.apply_accel = apply_accel
                aReqValue = CS.scc12["aReqValue"]
                controls.aReqValue = aReqValue

                if aReqValue < controls.aReqValueMin:
                    controls.aReqValueMin = controls.aReqValue

                if aReqValue > controls.aReqValueMax:
                    controls.aReqValueMax = controls.aReqValue

                if self.stock_navi_decel_enabled:
                    controls.sccStockCamAct = CS.scc11["Navi_SCC_Camera_Act"]
                    controls.sccStockCamStatus = CS.scc11[
                        "Navi_SCC_Camera_Status"]
                    apply_accel, stock_cam = self.scc_smoother.get_stock_cam_accel(
                        apply_accel, aReqValue, CS.scc11)
                else:
                    controls.sccStockCamAct = 0
                    controls.sccStockCamStatus = 0
                    stock_cam = False

                if self.scc12_cnt < 0:
                    self.scc12_cnt = CS.scc12[
                        "CR_VSM_Alive"] if not CS.no_radar else 0

                self.scc12_cnt += 1
                self.scc12_cnt %= 0xF

                can_sends.append(
                    hyundaican.create_scc12(
                        self.packer, apply_accel, CC.enabled, self.scc12_cnt,
                        self.scc_live, CS.scc12, CS.out.gasPressed,
                        CS.out.brakePressed, CS.out.cruiseState.standstill,
                        self.CP.carFingerprint))

                can_sends.append(
                    hyundaican.create_scc11(self.packer, self.frame,
                                            CC.enabled, set_speed,
                                            hud_control.leadVisible,
                                            self.scc_live, CS.scc11,
                                            self.scc_smoother.active_cam,
                                            stock_cam))

                if self.frame % 20 == 0 and CS.has_scc13:
                    can_sends.append(
                        hyundaican.create_scc13(self.packer, CS.scc13))

                if CS.has_scc14:
                    acc_standstill = stopping if CS.out.vEgo < 2. else False

                    lead = self.scc_smoother.get_lead(controls.sm)

                    if lead is not None:
                        d = lead.dRel
                        obj_gap = 1 if d < 25 else 2 if d < 40 else 3 if d < 60 else 4 if d < 80 else 5
                    else:
                        obj_gap = 0

                    can_sends.append(
                        hyundaican.create_scc14(self.packer, CC.enabled,
                                                CS.out.vEgo, acc_standstill,
                                                apply_accel, CS.out.gasPressed,
                                                obj_gap, CS.scc14))
        else:
            self.scc12_cnt = -1

    def update_hda2(self, CC, CS):
        actuators = CC.actuators

        # Steering Torque
        new_steer = int(round(actuators.steer * self.params.STEER_MAX))
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    self.params)

        if not CC.latActive:
            apply_steer = 0

        self.apply_steer_last = apply_steer

        can_sends = []

        # steering control
        can_sends.append(
            hda2can.create_lkas(self.packer, CC.enabled, self.frame,
                                CC.latActive, apply_steer))

        # cruise cancel
        if (self.frame - self.last_button_frame) * DT_CTRL > 0.25:
            if CC.cruiseControl.cancel:
                for _ in range(20):
                    can_sends.append(
                        hda2can.create_buttons(self.packer,
                                               CS.buttons_counter + 1, True,
                                               False))
                self.last_button_frame = self.frame

            # cruise standstill resume
            elif CC.enabled and CS.out.cruiseState.standstill:
                can_sends.append(
                    hda2can.create_buttons(self.packer, CS.buttons_counter + 1,
                                           False, True))
                self.last_button_frame = self.frame

        new_actuators = actuators.copy()
        new_actuators.steer = apply_steer / self.params.STEER_MAX
        new_actuators.accel = self.accel

        self.frame += 1
        return new_actuators, can_sends
Exemplo n.º 12
0
    def update(self, enabled, CS, frame, CC, actuators, pcm_cancel_cmd,
               visual_alert, left_lane, right_lane, left_lane_depart,
               right_lane_depart, set_speed, lead_visible, controls):

        # *** compute control surfaces ***

        # gas and brake
        apply_accel = actuators.accel / CarControllerParams.ACCEL_SCALE
        apply_accel, self.accel_steady = accel_hysteresis(
            apply_accel, self.accel_steady)
        apply_accel = self.scc_smoother.get_accel(CS, controls.sm, apply_accel)
        apply_accel = clip(apply_accel * CarControllerParams.ACCEL_SCALE,
                           CarControllerParams.ACCEL_MIN,
                           CarControllerParams.ACCEL_MAX)

        # Steering Torque
        new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX))
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    CarControllerParams)

        self.steer_rate_limited = new_steer != apply_steer

        # disable if steer angle reach 90 deg, otherwise mdps fault in some models
        lkas_active = enabled and abs(
            CS.out.steeringAngleDeg) < CS.CP.maxSteeringAngleDeg

        # fix for Genesis hard fault at low speed
        if CS.out.vEgo < 60 * CV.KPH_TO_MS and self.car_fingerprint == CAR.GENESIS and not CS.mdps_bus:
            lkas_active = False

        # Disable steering while turning blinker on and speed below 60 kph
        if CS.out.leftBlinker or CS.out.rightBlinker:
            self.turning_signal_timer = 0.5 / DT_CTRL  # Disable for 0.5 Seconds after blinker turned off
        if self.turning_indicator_alert:  # set and clear by interface
            lkas_active = 0
        if self.turning_signal_timer > 0:
            self.turning_signal_timer -= 1

        if not lkas_active:
            apply_steer = 0

        self.apply_accel_last = apply_accel
        self.apply_steer_last = apply_steer

        sys_warning, sys_state, left_lane_warning, right_lane_warning = \
          process_hud_alert(enabled, self.car_fingerprint, visual_alert,
                            left_lane, right_lane, left_lane_depart, right_lane_depart)

        clu11_speed = CS.clu11["CF_Clu_Vanz"]
        enabled_speed = 38 if CS.is_set_speed_in_mph else 60
        if clu11_speed > enabled_speed or not lkas_active:
            enabled_speed = clu11_speed

        controls.clu_speed_ms = clu11_speed * CS.speed_conv_to_ms

        if not (min_set_speed < set_speed < 255 * CV.KPH_TO_MS):
            set_speed = min_set_speed
        set_speed *= CV.MS_TO_MPH if CS.is_set_speed_in_mph else CV.MS_TO_KPH

        if frame == 0:  # initialize counts from last received count signals
            self.lkas11_cnt = CS.lkas11["CF_Lkas_MsgCount"]

            # TODO: fix this
            # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
            # self.scc_update_frame = frame

        # check if SCC is alive
        # if frame % 7 == 0:
        # if CS.scc11["AliveCounterACC"] == self.prev_scc_cnt:
        # if frame - self.scc_update_frame > 20 and self.scc_live:
        # self.scc_live = False
        # else:
        # self.scc_live = True
        # self.prev_scc_cnt = CS.scc11["AliveCounterACC"]
        # self.scc_update_frame = frame

        self.prev_scc_cnt = CS.scc11["AliveCounterACC"]

        self.lkas11_cnt = (self.lkas11_cnt + 1) % 0x10

        can_sends = []
        can_sends.append(
            create_lkas11(self.packer, frame, self.car_fingerprint,
                          apply_steer, lkas_active, CS.lkas11, sys_warning,
                          sys_state, enabled, left_lane, right_lane,
                          left_lane_warning, right_lane_warning, 0,
                          self.ldws_opt))

        if CS.mdps_bus or CS.scc_bus == 1:  # send lkas11 bus 1 if mdps or scc is on bus 1
            can_sends.append(
                create_lkas11(self.packer, frame, self.car_fingerprint,
                              apply_steer, lkas_active, CS.lkas11, sys_warning,
                              sys_state, enabled, left_lane, right_lane,
                              left_lane_warning, right_lane_warning, 1,
                              self.ldws_opt))

        if frame % 2 and CS.mdps_bus:  # send clu11 to mdps if it is not on bus 0
            can_sends.append(
                create_clu11(self.packer, frame // 2 % 0x10, CS.mdps_bus,
                             CS.clu11, Buttons.NONE, enabled_speed))

        if pcm_cancel_cmd and (self.longcontrol and not self.mad_mode_enabled):
            can_sends.append(
                create_clu11(self.packer, frame % 0x10, CS.scc_bus, CS.clu11,
                             Buttons.CANCEL, clu11_speed))
        else:
            can_sends.append(create_mdps12(self.packer, frame, CS.mdps12))

        # fix auto resume - by neokii
        if CS.out.cruiseState.standstill and not CS.out.gasPressed:

            if self.last_lead_distance == 0:
                self.last_lead_distance = CS.lead_distance
                self.resume_cnt = 0
                self.resume_wait_timer = 0

            # scc smoother
            elif self.scc_smoother.is_active(frame):
                pass

            elif self.resume_wait_timer > 0:
                self.resume_wait_timer -= 1

            elif abs(CS.lead_distance - self.last_lead_distance) > 0.01:
                can_sends.append(
                    create_clu11(self.packer, self.resume_cnt, CS.scc_bus,
                                 CS.clu11, Buttons.RES_ACCEL, clu11_speed))
                self.resume_cnt += 1

                if self.resume_cnt >= 8:
                    self.resume_cnt = 0
                    self.resume_wait_timer = SccSmoother.get_wait_count() * 2

        # reset lead distnce after the car starts moving
        elif self.last_lead_distance != 0:
            self.last_lead_distance = 0

        # scc smoother
        self.scc_smoother.update(enabled, can_sends, self.packer, CC, CS,
                                 frame, apply_accel, controls)

        controls.apply_accel = apply_accel
        aReqValue = CS.scc12["aReqValue"]
        controls.aReqValue = aReqValue

        if aReqValue < controls.aReqValueMin:
            controls.aReqValueMin = controls.aReqValue

        if aReqValue > controls.aReqValueMax:
            controls.aReqValueMax = controls.aReqValue

        # send scc to car if longcontrol enabled and SCC not on bus 0 or ont live
        if self.longcontrol and CS.cruiseState_enabled and (CS.scc_bus or
                                                            not self.scc_live):

            if frame % 2 == 0:

                if self.stock_navi_decel_enabled:
                    controls.sccStockCamAct = CS.scc11["Navi_SCC_Camera_Act"]
                    controls.sccStockCamStatus = CS.scc11[
                        "Navi_SCC_Camera_Status"]
                    apply_accel, stock_cam = self.scc_smoother.get_stock_cam_accel(
                        apply_accel, aReqValue, CS.scc11)
                else:
                    controls.sccStockCamAct = 0
                    controls.sccStockCamStatus = 0
                    stock_cam = False

                if self.scc12_cnt < 0:
                    self.scc12_cnt = CS.scc12[
                        "CR_VSM_Alive"] if not CS.no_radar else 0

                self.scc12_cnt += 1
                self.scc12_cnt %= 0xF

                can_sends.append(
                    create_scc12(self.packer, apply_accel, enabled,
                                 self.scc12_cnt, self.scc_live, CS.scc12,
                                 CS.out.gasPressed, CS.out.brakePressed,
                                 CS.out.cruiseState.standstill,
                                 self.car_fingerprint))

                can_sends.append(
                    create_scc11(self.packer, frame, enabled, set_speed,
                                 lead_visible, self.scc_live, CS.scc11,
                                 self.scc_smoother.active_cam, stock_cam))

                if frame % 20 == 0 and CS.has_scc13:
                    can_sends.append(create_scc13(self.packer, CS.scc13))
                if CS.has_scc14:
                    if CS.out.vEgo < 2.:
                        long_control_state = controls.LoC.long_control_state
                        acc_standstill = True if long_control_state == LongCtrlState.stopping else False
                    else:
                        acc_standstill = False

                    lead = self.scc_smoother.get_lead(controls.sm)

                    if lead is not None:
                        d = lead.dRel
                        obj_gap = 1 if d < 25 else 2 if d < 40 else 3 if d < 60 else 4 if d < 80 else 5
                    else:
                        obj_gap = 0

                    can_sends.append(
                        create_scc14(self.packer, enabled, CS.out.vEgo,
                                     acc_standstill, apply_accel,
                                     CS.out.gasPressed, obj_gap, CS.scc14))
        else:
            self.scc12_cnt = -1

        # 20 Hz LFA MFA message
        if frame % 5 == 0:
            activated_hda = road_speed_limiter_get_active()
            # activated_hda: 0 - off, 1 - main road, 2 - highway
            if self.car_fingerprint in FEATURES["send_lfa_mfa"]:
                can_sends.append(
                    create_lfahda_mfc(self.packer, enabled, activated_hda))
            elif CS.mdps_bus == 0:
                state = 2 if self.car_fingerprint in FEATURES[
                    "send_hda_state_2"] else 1
                can_sends.append(
                    create_hda_mfc(self.packer, activated_hda, state))

        return can_sends