def __init__(self, dbc_name, CP, VM):
        self.CP = CP
        self.apply_steer_last = 0
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.steer_rate_limited = False

        # resume
        self.resume_cnt = 0
        self.last_resume_frame = 0
        self.last_lead_distance = 0

        self.lkas11_cnt = 0

        # hud
        self.hud_timer_left = 0
        self.hud_timer_right = 0

        self.enable_time = 0
        self.steer_torque_over_timer = 0
        self.steer_torque_ratio = 1

        self.timer1 = tm.CTime1000("time")

        self.SC = SpdctrlSlow()
        self.model_speed = 0
        self.model_sum = 0
Exemple #2
0
    def param_load(self):
        self.command_cnt += 1
        if self.command_cnt > 100:
            self.command_cnt = 0

        if self.command_cnt % 10:
            return

        self.command_load += 1
        if self.command_load == 1:
            self.param_OpkrAccelProfile = int(
                self.params.get('OpkrAccelProfile'))
        elif self.command_load == 2:
            self.param_OpkrAutoResume = int(self.params.get('OpkrAutoResume'))
        elif self.command_load == 3:
            self.param_OpkrWhoisDriver = int(
                self.params.get('OpkrWhoisDriver'))
        else:
            self.command_load = 0

        # speed controller
        if self.param_preOpkrAccelProfile != self.param_OpkrAccelProfile:
            self.param_preOpkrAccelProfile = self.param_OpkrAccelProfile
            if self.param_OpkrAccelProfile == 1:
                self.SC = SpdctrlSlow()
            elif self.param_OpkrAccelProfile == 2:
                self.SC = SpdctrlNormal()
            else:
                self.SC = SpdctrlNormal()
    def __init__(self, dbc_name, CP, VM):
        self.CP = CP
        self.apply_steer_last = 0
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.steer_rate_limited = False
        self.resume_cnt = 0
        self.last_resume_frame = 0
        self.last_lead_distance = 0
        self.lanechange_manual_timer = 0
        self.emergency_manual_timer = 0
        self.driver_steering_torque_above_timer = 0
        self.mode_change_timer = 0

        self.steer_mode = ""
        self.mdps_status = ""
        self.lkas_switch = ""

        self.lkas11_cnt = 0

        self.nBlinker = 0

        self.dRel = 0
        self.yRel = 0
        self.vRel = 0

        self.timer1 = tm.CTime1000("time")
        self.model_speed = 0
        self.model_sum = 0

        # hud
        self.hud_timer_left = 0
        self.hud_timer_right = 0

        self.traceCC = trace1.Loger("CarController")

        self.cruise_gap = 0
        self.cruise_gap_prev = 0
        self.cruise_gap_set_init = 0
        self.cruise_gap_switch_timer = 0

        self.params = Params()
        self.mode_change_switch = int(
            self.params.get('CruiseStatemodeSelInit'))
        self.param_OpkrAccelProfile = int(self.params.get('OpkrAccelProfile'))
        self.param_OpkrAutoResume = int(self.params.get('OpkrAutoResume'))

        if self.param_OpkrAccelProfile == 1:
            self.SC = SpdctrlSlow()
        elif self.param_OpkrAccelProfile == 2:
            self.SC = SpdctrlNormal()
        else:
            self.SC = SpdctrlFast()
Exemple #4
0
    def __init__(self, dbc_name, CP, VM):
        self.CP = CP
        self.p = SteerLimitParams(CP)
        self.packer = CANPacker(dbc_name)

        self.apply_steer_last = 0
        self.car_fingerprint = CP.carFingerprint
        self.steer_rate_limited = False
        self.last_resume_frame = 0
        self.last_lead_distance = 0

        self.resume_cnt = 0
        self.lkas11_cnt = 0

        self.nBlinker = 0
        self.lane_change_torque_lower = 0
        self.steer_torque_over_timer = 0
        self.steer_torque_ratio = 1
        self.steer_torque_ratio_dir = 1

        self.dRel = 0
        self.yRel = 0
        self.vRel = 0

        self.timer1 = tm.CTime1000("time")
        self.model_speed = 0
        self.model_sum = 0

        # hud
        self.hud_timer_left = 0
        self.hud_timer_right = 0
        self.hud_sys_state = 0

        self.command_cnt = 0
        self.command_load = 0
        self.params = Params()

        self.SC = SpdctrlSlow()
        self.traceCC = trace1.Loger("CarController")
class CarController():
    def __init__(self, dbc_name, CP, VM):
        self.CP = CP
        self.apply_steer_last = 0
        self.car_fingerprint = CP.carFingerprint
        self.packer = CANPacker(dbc_name)
        self.steer_rate_limited = False

        # resume
        self.resume_cnt = 0
        self.last_resume_frame = 0
        self.last_lead_distance = 0

        self.lkas11_cnt = 0

        # hud
        self.hud_timer_left = 0
        self.hud_timer_right = 0

        self.enable_time = 0
        self.steer_torque_over_timer = 0
        self.steer_torque_ratio = 1

        self.timer1 = tm.CTime1000("time")

        self.SC = SpdctrlSlow()
        self.model_speed = 0
        self.model_sum = 0

    def limit_ctrl(self, value, limit, offset):
        p_limit = offset + limit
        m_limit = offset - limit
        if value > p_limit:
            value = p_limit
        elif value < m_limit:
            value = m_limit
        return value

    def process_hud_alert(self, enabled, c):
        visual_alert = c.hudControl.visualAlert
        left_lane = c.hudControl.leftLaneVisible
        right_lane = c.hudControl.rightLaneVisible

        sys_warning = (visual_alert == VisualAlert.steerRequired)

        if left_lane:
            self.hud_timer_left = 100

        if right_lane:
            self.hud_timer_right = 100

        if self.hud_timer_left:
            self.hud_timer_left -= 1

        if self.hud_timer_right:
            self.hud_timer_right -= 1

        # initialize to no line visible
        sys_state = 1
        if self.hud_timer_left and self.hud_timer_right or sys_warning:  # HUD alert only display when LKAS status is active
            if (self.steer_torque_ratio > 0.8) and (enabled or sys_warning):
                sys_state = 3
            else:
                sys_state = 4
        elif self.hud_timer_left:
            sys_state = 5
        elif self.hud_timer_right:
            sys_state = 6

        return sys_warning, sys_state

    def atom_tune(self, v_ego, cv_value):  # cV(곡률에 의한 변화)
        self.cvBPV = self.CP.atomTuning.cvBPV
        self.cvV = self.CP.atomTuning.cvV
        self.cvSteerMAXV = self.CP.atomTuning.cvSteerMaxV
        self.cvSteerdUPV = self.CP.atomTuning.cvSteerdUpV
        self.cvSteerdDNV = self.CP.atomTuning.cvSteerdDnV

        self.steerMAX = []
        self.steerdUP = []
        self.steerdDN = []

        # Max
        nPos = 0
        for sCV in self.cvV:  # speed
            self.steerMAX.append(interp(cv_value, sCV, self.cvSteerMAXV[nPos]))
            self.steerdUP.append(interp(cv_value, sCV, self.cvSteerdUPV[nPos]))
            self.steerdDN.append(interp(cv_value, sCV, self.cvSteerdDNV[nPos]))
            nPos += 1
            if nPos > 10:
                break

        MAX = interp(v_ego, self.cvBPV, self.steerMAX)
        UP = interp(v_ego, self.cvBPV, self.steerdUP)
        DN = interp(v_ego, self.cvBPV, self.steerdDN)

        #str_log1 = 'ego={:.1f} /{:.1f}/{:.1f}/{:.1f} {}'.format(v_ego,  MAX, UP, DN, self.steerMAX )
        #trace1.printf2( '{}'.format( str_log1 ) )
        return MAX, UP, DN

    def steerParams_torque(self, CS, abs_angle_steers, path_plan):
        param = SteerLimitParams()
        v_ego_kph = CS.out.vEgo * CV.MS_TO_KPH

        self.enable_time = self.timer1.sampleTime()
        if self.enable_time < 50:
            self.steer_torque_over_timer = 0
            self.steer_torque_ratio = 1
            return param

        nMAX, nUP, nDN = self.atom_tune(CS.out.vEgo, self.model_speed)
        param.STEER_MAX = min(param.STEER_MAX, nMAX)
        param.STEER_DELTA_UP = min(param.STEER_DELTA_UP, nUP)
        param.STEER_DELTA_DOWN = min(param.STEER_DELTA_DOWN, nDN)

        sec_pval = 0.5  # 0.5 sec 운전자 => 오파  (sec)
        sec_mval = 30.0  # 오파 => 운전자.  (sec)
        # streer over check
        if path_plan.laneChangeState != LaneChangeState.off:
            self.steer_torque_over_timer = 0
        elif CS.out.leftBlinker or CS.out.rightBlinker:
            sec_mval = 0.2  # 오파 => 운전자.
            sec_pval = 10

        if v_ego_kph > 5 and CS.out.steeringPressed:  #사용자 핸들 토크
            self.steer_torque_over_timer = 50
        elif self.steer_torque_over_timer:
            self.steer_torque_over_timer -= 1

        ratio_pval = 1 / (100 * sec_pval)
        ratio_mval = 1 / (100 * sec_mval)

        if self.steer_torque_over_timer:
            self.steer_torque_ratio -= ratio_mval
        else:
            self.steer_torque_ratio += ratio_pval

        if self.steer_torque_ratio < 0:
            self.steer_torque_ratio = 0
        elif self.steer_torque_ratio > 1:
            self.steer_torque_ratio = 1

        return param

    def update(self, c, CS, frame, sm):
        enabled = c.enabled
        actuators = c.actuators
        pcm_cancel_cmd = c.cruiseControl.cancel
        abs_angle_steers = abs(actuators.steerAngle)

        self.model_speed, self.model_sum = self.SC.calc_va(sm, CS.out.vEgo)

        # Steering Torque
        path_plan = sm['pathPlan']
        param = self.steerParams_torque(CS, abs_angle_steers, path_plan)
        new_steer = actuators.steer * param.STEER_MAX
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    param)
        self.steer_rate_limited = new_steer != apply_steer

        apply_steer_limit = param.STEER_MAX
        if self.steer_torque_ratio < 1:
            apply_steer_limit = int(self.steer_torque_ratio * param.STEER_MAX)
            apply_steer = self.limit_ctrl(apply_steer, apply_steer_limit, 0)

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

        # fix for Genesis hard fault at low speed
        if CS.out.vEgo < 16.7 and self.car_fingerprint == CAR.HYUNDAI_GENESIS:
            lkas_active = False

        if not lkas_active:
            apply_steer = 0

        steer_req = 1 if apply_steer else 0

        self.apply_steer_last = apply_steer

        sys_warning, sys_state = self.process_hud_alert(lkas_active, c)

        if 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

        can_sends = []
        can_sends.append(
            create_lkas11(self.packer, self.lkas11_cnt, self.car_fingerprint,
                          apply_steer, steer_req, CS.lkas11, sys_warning,
                          sys_state, c))

        can_sends.append(create_mdps12(self.packer, frame, CS.mdps12))

        str_log1 = 'torg:{:>4.0f}/{:>4.0f} CV:{:>5.0f}'.format(
            apply_steer, new_steer, self.model_speed)
        str_log2 = 'max={:>4.0f} tm={:>5.1f} '.format(apply_steer_limit,
                                                      self.timer1.sampleTime())
        trace1.printf('{} {}'.format(str_log1, str_log2))

        lfa_usm = CS.lfahda["LFA_USM"]
        lfa_warn = CS.lfahda["LFA_SysWarning"]
        lfa_active = CS.lfahda["ACTIVE2"]

        hda_usm = CS.lfahda["HDA_USM"]
        hda_active = CS.lfahda["ACTIVE"]
        str_log1 = 'hda={:.0f},{:.0f}'.format(hda_usm, hda_active)
        str_log2 = 'lfa={:.0f},{:.0f},{:.0f}'.format(lfa_usm, lfa_warn,
                                                     lfa_active)
        trace1.printf2('{} {}'.format(str_log1, str_log2))

        if pcm_cancel_cmd and self.CP.openpilotLongitudinalControl:
            can_sends.append(
                create_clu11(self.packer, frame, CS.clu11, Buttons.CANCEL))
        elif CS.out.cruiseState.standstill:
            # run only first time when the car stopped
            if self.last_lead_distance == 0:
                # get the lead distance from the Radar
                self.last_lead_distance = CS.lead_distance
                self.resume_cnt = 0
            # when lead car starts moving, create 6 RES msgs
            elif CS.lead_distance != self.last_lead_distance and (
                    frame - self.last_resume_frame) > 5:
                can_sends.append(
                    create_clu11(self.packer, self.resume_cnt, CS.clu11,
                                 Buttons.RES_ACCEL))
                self.resume_cnt += 1
                # interval after 6 msgs
                if self.resume_cnt > 5:
                    self.last_resume_frame = frame
        # reset lead distnce after the car starts moving
        elif self.last_lead_distance != 0:
            self.last_lead_distance = 0

        # 20 Hz LFA MFA message
        if frame % 5 == 0 and self.car_fingerprint in [
                CAR.SONATA, CAR.PALISADE, CAR.IONIQ
        ]:
            can_sends.append(create_lfa_mfa(self.packer, frame, enabled))

        return can_sends
Exemple #6
0
class CarController():
    def __init__(self, dbc_name, CP, VM):
        self.CP = CP
        self.p = SteerLimitParams(CP)
        self.packer = CANPacker(dbc_name)

        self.apply_steer_last = 0
        self.car_fingerprint = CP.carFingerprint
        self.steer_rate_limited = False
        self.last_resume_frame = 0
        self.last_lead_distance = 0

        self.resume_cnt = 0
        self.lkas11_cnt = 0

        self.nBlinker = 0
        self.lane_change_torque_lower = 0
        self.steer_torque_over_timer = 0
        self.steer_torque_ratio = 1
        self.steer_torque_ratio_dir = 1

        self.dRel = 0
        self.yRel = 0
        self.vRel = 0

        self.timer1 = tm.CTime1000("time")
        self.model_speed = 0
        self.model_sum = 0

        # hud
        self.hud_timer_left = 0
        self.hud_timer_right = 0
        self.hud_sys_state = 0

        self.command_cnt = 0
        self.command_load = 0
        self.params = Params()

        self.SC = SpdctrlSlow()
        self.traceCC = trace1.Loger("CarController")

    def limit_ctrl(self, value, limit, offset):
        p_limit = offset + limit
        m_limit = offset - limit
        if value > p_limit:
            value = p_limit
        elif value < m_limit:
            value = m_limit
        return value

    def process_hud_alert(self, enabled, c):
        visual_alert = c.hudControl.visualAlert
        left_lane = c.hudControl.leftLaneVisible
        right_lane = c.hudControl.rightLaneVisible

        sys_warning = (visual_alert == VisualAlert.steerRequired)

        if left_lane:
            self.hud_timer_left = 100

        if right_lane:
            self.hud_timer_right = 100

        if self.hud_timer_left:
            self.hud_timer_left -= 1

        if self.hud_timer_right:
            self.hud_timer_right -= 1

        # initialize to no line visible
        sys_state = 1
        if self.hud_timer_left and self.hud_timer_right or sys_warning:  # HUD alert only display when LKAS status is active
            if (self.steer_torque_ratio > 0.7) and (enabled or sys_warning):
                sys_state = 3
            else:
                sys_state = 4
        elif self.hud_timer_left:
            sys_state = 5
        elif self.hud_timer_right:
            sys_state = 6

        return sys_warning, sys_state

    def atom_tune(self, v_ego_kph, cv_value):  # cV(곡률에 의한 변화)
        self.cv_KPH = self.CP.atomTuning.cvKPH
        self.cv_BPV = self.CP.atomTuning.cvBPV
        self.cv_sMaxV = self.CP.atomTuning.cvsMaxV
        self.cv_sdUpV = self.CP.atomTuning.cvsdUpV
        self.cv_sdDnV = self.CP.atomTuning.cvsdDnV

        self.steerMAX = []
        self.steerdUP = []
        self.steerdDN = []

        # Max
        nPos = 0
        for sCV in self.cv_BPV:
            self.steerMAX.append(interp(cv_value, sCV, self.cv_sMaxV[nPos]))
            self.steerdUP.append(interp(cv_value, sCV, self.cv_sdUpV[nPos]))
            self.steerdDN.append(interp(cv_value, sCV, self.cv_sdDnV[nPos]))
            nPos += 1
            if nPos > 20:
                break

        MAX = interp(v_ego_kph, self.cv_KPH, self.steerMAX)
        UP = interp(v_ego_kph, self.cv_KPH, self.steerdUP)
        DN = interp(v_ego_kph, self.cv_KPH, self.steerdDN)

        #str_log1 = 'ego={:.1f} /{:.1f}/{:.1f}/{:.1f} {}'.format(v_ego_kph,  MAX, UP, DN, self.steerMAX )
        #trace1.printf2( '{}'.format( str_log1 ) )
        return MAX, UP, DN

    def steerParams_torque(self, CS, actuators, path_plan):
        param = copy.copy(self.p)
        v_ego_kph = CS.out.vEgo * CV.MS_TO_KPH
        dst_steer = actuators.steer * param.STEER_MAX
        abs_angle_steers = abs(actuators.steerAngle)

        self.enable_time = self.timer1.sampleTime()
        if self.enable_time < 50:
            self.steer_torque_over_timer = 0
            self.steer_torque_ratio = 1
            return param, dst_steer

        nMAX, nUP, nDN = self.atom_tune(v_ego_kph, self.model_speed)
        param.STEER_MAX = min(param.STEER_MAX, nMAX)
        param.STEER_DELTA_UP = min(param.STEER_DELTA_UP, nUP)
        param.STEER_DELTA_DOWN = min(param.STEER_DELTA_DOWN, nDN)

        sec_mval = 10.0  # 오파 => 운전자.  (sec)
        sec_pval = 3  #  운전자 => 오파  (sec)
        # streer over check
        if path_plan.laneChangeState != LaneChangeState.off:
            self.steer_torque_over_timer = 0
        elif CS.out.leftBlinker or CS.out.rightBlinker:
            sec_mval = 0.5  # 오파 => 운전자.
            sec_pval = 10  # 운전자 => 오파  (sec)

        if v_ego_kph > 5 and CS.out.steeringPressed:  #사용자 핸들 토크
            if abs_angle_steers > 5 and CS.out.steeringTorque < -10:  #right
                if dst_steer < 0:
                    self.steer_torque_over_timer = 0
                else:
                    #sec_mval = 1
                    self.steer_torque_over_timer = 50
            elif abs_angle_steers > 5 and CS.out.steeringTorque > 10:  #left
                if dst_steer > 0:
                    self.steer_torque_over_timer = 0
                else:
                    #sec_mval = 1
                    self.steer_torque_over_timer = 50
            else:
                self.steer_torque_over_timer = 50

        elif self.steer_torque_over_timer:
            self.steer_torque_over_timer -= 1

        ratio_pval = 1 / (100 * sec_pval)
        ratio_mval = 1 / (100 * sec_mval)

        if self.steer_torque_over_timer:
            self.steer_torque_ratio -= ratio_mval
        else:
            self.steer_torque_ratio += ratio_pval

        if self.steer_torque_ratio < 0:
            self.steer_torque_ratio = 0
        elif self.steer_torque_ratio > 1:
            self.steer_torque_ratio = 1

        return param, dst_steer

    #def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, visual_alert,
    #           left_lane, right_lane, left_lane_depart, right_lane_depart):

    def update(self, c, CS, frame, sm, CP):
        if self.CP != CP:
            self.CP = CP

        enabled = c.enabled
        actuators = c.actuators
        pcm_cancel_cmd = c.cruiseControl.cancel

        path_plan = sm['pathPlan']
        self.dRel, self.yRel, self.vRel = SpdController.get_lead(sm)
        if self.SC is not None:
            self.model_speed, self.model_sum = self.SC.calc_va(sm, CS.out.vEgo)
        else:
            self.model_speed = self.model_sum = 0

        # Steering Torque
        param, dst_steer = self.steerParams_torque(CS, c.actuators, path_plan)
        new_steer = actuators.steer * param.STEER_MAX
        apply_steer = apply_std_steer_torque_limits(new_steer,
                                                    self.apply_steer_last,
                                                    CS.out.steeringTorque,
                                                    param)
        self.steer_rate_limited = new_steer != apply_steer

        apply_steer_limit = param.STEER_MAX
        if self.steer_torque_ratio < 1:
            apply_steer_limit = int(self.steer_torque_ratio * param.STEER_MAX)
            apply_steer = self.limit_ctrl(apply_steer, apply_steer_limit, 0)

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

        if not lkas_active:
            apply_steer = 0

        steer_req = 1 if apply_steer else 0
        self.apply_steer_last = apply_steer

        sys_warning, self.hud_sys_state = self.process_hud_alert(
            lkas_active, c)

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

        can_sends = []
        can_sends.append(
            create_lkas11(self.packer, self.lkas11_cnt, self.car_fingerprint,
                          apply_steer, steer_req, CS.lkas11, sys_warning,
                          self.hud_sys_state, c))

        if steer_req:
            can_sends.append(create_mdps12(self.packer, frame, CS.mdps12))

        str_log1 = 'torg:{:5.0f}/{:5.0f}  CV={:5.1f}/{:5.1f}'.format(
            apply_steer, new_steer, self.model_speed, self.model_sum)
        str_log2 = 'limit={:.0f} tm={:.1f} gap={:.0f}'.format(
            apply_steer_limit, self.timer1.sampleTime(), CS.cruiseGapSet)
        trace1.printf('{} {}'.format(str_log1, str_log2))

        run_speed_ctrl = CS.acc_active and self.SC != None
        if not run_speed_ctrl:
            str_log2 = 'LKAS={:.0f}  steer={:5.0f} '.format(
                CS.lkas_button_on, CS.out.steeringTorque)
            trace1.printf2('{}'.format(str_log2))

        if pcm_cancel_cmd:
            can_sends.append(
                create_clu11(self.packer, frame, CS.clu11, Buttons.CANCEL))
        if CS.out.cruiseState.standstill:
            # run only first time when the car stopped
            if self.last_lead_distance == 0 or not CP.lateralsRatom.opkrAutoResume:
                # get the lead distance from the Radar
                self.last_lead_distance = CS.lead_distance
                self.resume_cnt = 0
            # when lead car starts moving, create 6 RES msgs
            elif CS.lead_distance != self.last_lead_distance and (
                    frame - self.last_resume_frame) > 5:
                can_sends.append(
                    create_clu11(self.packer, self.resume_cnt, CS.clu11,
                                 Buttons.RES_ACCEL))
                self.resume_cnt += 1
                # interval after 6 msgs
                if self.resume_cnt > 5:
                    self.last_resume_frame = frame
                    self.resume_cnt = 0
        # reset lead distnce after the car starts moving
        elif self.last_lead_distance != 0:
            self.last_lead_distance = 0
        elif run_speed_ctrl and self.SC != None:
            is_sc_run = self.SC.update(CS, sm, self)
            if is_sc_run:
                can_sends.append(
                    create_clu11(self.packer, self.resume_cnt, CS.clu11,
                                 self.SC.btn_type, self.SC.sc_clu_speed))
                self.resume_cnt += 1
            else:
                self.resume_cnt = 0

        # 20 Hz LFA MFA message
        if frame % 5 == 0 and self.car_fingerprint in [
                CAR.SONATA, CAR.PALISADE, CAR.IONIQ, CAR.KIA_NIRO_EV
        ]:
            can_sends.append(create_lfa_mfa(self.packer, frame, enabled))

    # counter inc
        self.lkas11_cnt += 1
        return can_sends