Skip to content

Commit

Permalink
Blinker + LDW improvements (commaai#131)
Browse files Browse the repository at this point in the history
blinker extension:
- now only triggers when tapping
- now also works when OP is not engaged
- extension configuration changed to blink count instead of seconds
other:
- implemented real blinker states (thanks BogGyver!)
- refactored blinker and blinker stalk related stuff
- ldw won't trigger while blinking by tapping anymore and numb time starts after blinking ends
- removed eon on-screen ldw messages
  • Loading branch information
neon-dev authored Nov 27, 2019
1 parent 405bf34 commit ea50af0
Show file tree
Hide file tree
Showing 9 changed files with 597 additions and 653 deletions.
36 changes: 20 additions & 16 deletions opendbc/tesla_can.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,26 @@ BO_ 532 EPB_epasControl: 3 EPB
SG_ EPB_epasEACAllow : 2|3@0+ (1,0) [4|7] "" NEO,EPAS

BO_ 792 GTW_carState: 8 GTW
SG_ BOOT_STATE : 47|2@0+ (1,0) [-1|4] "" NEO
SG_ CERRD : 7|1@0+ (1,0) [-1|2] "" NEO
SG_ DAY : 36|5@0+ (1,0) [2|31] "" NEO
SG_ DOOR_STATE_FL : 13|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_FR : 15|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_FrontTrunk : 51|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_RL : 23|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_RR : 30|2@0+ (1,0) [-1|4] "" NEO
SG_ GTW_updateInProgress : 49|2@0+ (1,0) [-1|4] "" NEO
SG_ Hour : 28|5@0+ (1,0) [0|29] "h" NEO
SG_ MCU_factoryMode : 52|1@0+ (1,0) [-1|2] "" NEO
SG_ MCU_transportModeOn : 53|1@0+ (1,0) [1|1] "" NEO
SG_ MINUTE : 45|6@0+ (1,0) [0|61] "min" NEO
SG_ MONTH : 11|4@0+ (1,0) [0|14] "Month" NEO
SG_ SECOND : 21|6@0+ (1,0) [0|61] "s" NEO
SG_ YEAR : 6|7@0+ (1,2000) [2000|2125] "Year" NEO
SG_ YEAR : 0|7@1+ (1,2000) [2000|2127] "Year" NEO
SG_ CERRD : 7|1@1+ (1,0) [0|1] "" NEO
SG_ MONTH : 8|4@1+ (1,0) [1|12] "Month" NEO
SG_ DOOR_STATE_FL : 12|2@1+ (1,0) [0|3] "" NEO
SG_ DOOR_STATE_FR : 14|2@1+ (1,0) [0|3] "" NEO
SG_ SECOND : 16|6@1+ (1,0) [0|59] "s" NEO
SG_ DOOR_STATE_RL : 22|2@1+ (1,0) [0|3] "" NEO
SG_ Hour : 24|5@1+ (1,0) [0|23] "h" NEO
SG_ DOOR_STATE_RR : 29|2@1+ (1,0) [0|3] "" NEO
SG_ DAY : 32|5@1+ (1,0) [0|31] "" NEO
SG_ MINUTE : 40|6@1+ (1,0) [0|59] "min" NEO
SG_ BOOT_STATE : 46|2@1+ (1,0) [0|3] "" NEO
SG_ GTW_updateInProgress : 48|2@1+ (1,0) [0|3] "" NEO
SG_ DOOR_STATE_FrontTrunk : 50|2@1+ (1,0) [0|3] "" NEO
SG_ MCU_factoryMode : 52|1@1+ (1,0) [0|1] "" NEO
SG_ MCU_transportModeOn : 53|1@0+ (1,0) [0|1] "" NEO
SG_ BC_headLightLStatus : 55|2@0+ (1,0) [0|3] "" NEO
SG_ BC_headLightRStatus : 57|2@0+ (1,0) [0|3] "" NEO
SG_ BC_indicatorLStatus : 59|2@0+ (1,0) [0|3] "" NEO
SG_ BC_indicatorRStatus : 61|2@0+ (1,0) [0|3] "" NEO

BO_ 872 DI_state: 8 DI
SG_ DI_systemState : 0|3@1+ (1,0) [0|0] "" NEO
Expand Down
36 changes: 20 additions & 16 deletions opendbc/tesla_can1916.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,26 @@ BO_ 532 EPB_epasControl: 3 EPB
SG_ EPB_epasEACAllow : 2|3@0+ (1,0) [4|7] "" NEO,EPAS

BO_ 792 GTW_carState: 8 GTW
SG_ BOOT_STATE : 47|2@0+ (1,0) [-1|4] "" NEO
SG_ CERRD : 7|1@0+ (1,0) [-1|2] "" NEO
SG_ DAY : 36|5@0+ (1,0) [2|31] "" NEO
SG_ DOOR_STATE_FL : 13|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_FR : 15|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_FrontTrunk : 51|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_RL : 23|2@0+ (1,0) [-1|4] "" NEO
SG_ DOOR_STATE_RR : 30|2@0+ (1,0) [-1|4] "" NEO
SG_ GTW_updateInProgress : 49|2@0+ (1,0) [-1|4] "" NEO
SG_ Hour : 28|5@0+ (1,0) [0|29] "h" NEO
SG_ MCU_factoryMode : 52|1@0+ (1,0) [-1|2] "" NEO
SG_ MCU_transportModeOn : 53|1@0+ (1,0) [1|1] "" NEO
SG_ MINUTE : 45|6@0+ (1,0) [0|61] "min" NEO
SG_ MONTH : 11|4@0+ (1,0) [0|14] "Month" NEO
SG_ SECOND : 21|6@0+ (1,0) [0|61] "s" NEO
SG_ YEAR : 6|7@0+ (1,2000) [2000|2125] "Year" NEO
SG_ YEAR : 0|7@1+ (1,2000) [2000|2127] "Year" NEO
SG_ CERRD : 7|1@1+ (1,0) [0|1] "" NEO
SG_ MONTH : 8|4@1+ (1,0) [1|12] "Month" NEO
SG_ DOOR_STATE_FL : 12|2@1+ (1,0) [0|3] "" NEO
SG_ DOOR_STATE_FR : 14|2@1+ (1,0) [0|3] "" NEO
SG_ SECOND : 16|6@1+ (1,0) [0|59] "s" NEO
SG_ DOOR_STATE_RL : 22|2@1+ (1,0) [0|3] "" NEO
SG_ Hour : 24|5@1+ (1,0) [0|23] "h" NEO
SG_ DOOR_STATE_RR : 29|2@1+ (1,0) [0|3] "" NEO
SG_ DAY : 32|5@1+ (1,0) [0|31] "" NEO
SG_ MINUTE : 40|6@1+ (1,0) [0|59] "min" NEO
SG_ BOOT_STATE : 46|2@1+ (1,0) [0|3] "" NEO
SG_ GTW_updateInProgress : 48|2@1+ (1,0) [0|3] "" NEO
SG_ DOOR_STATE_FrontTrunk : 50|2@1+ (1,0) [0|3] "" NEO
SG_ MCU_factoryMode : 52|1@1+ (1,0) [0|1] "" NEO
SG_ MCU_transportModeOn : 53|1@0+ (1,0) [0|1] "" NEO
SG_ BC_headLightLStatus : 55|2@0+ (1,0) [0|3] "" NEO
SG_ BC_headLightRStatus : 57|2@0+ (1,0) [0|3] "" NEO
SG_ BC_indicatorLStatus : 59|2@0+ (1,0) [0|3] "" NEO
SG_ BC_indicatorRStatus : 61|2@0+ (1,0) [0|3] "" NEO

BO_ 872 DI_state: 8 DI
SG_ DI_systemState : 0|3@1+ (1,0) [0|0] "" NEO
Expand Down
20 changes: 4 additions & 16 deletions selfdrive/car/modules/ALCA_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ def __init__(self,carcontroller,alcaEnabled,steerByAngle):
self.laneChange_counter = 0 # used to count frames during lane change
self.laneChange_wait = 2 # how many seconds to wait before it starts the change
self.laneChange_direction = 0 # direction of the lane change
self.prev_right_blinker_on = False # local variable for prev position
self.prev_left_blinker_on = False # local variable for prev position
self.laneChange_cancelled = False
self.laneChange_cancelled_counter = 0
self.alcaStatusSocket = messaging.pub_sock('alcaStatus')
Expand Down Expand Up @@ -148,26 +146,23 @@ def update(self,enabled,CS,actuators,alcaStateData,frame):
self.laneChange_cancelled = False

# Basic highway lane change logic
actuator_delta = 0.
turn_signal_needed = 0 # send 1 for left, 2 for right 0 for not needed

if (not CS.right_blinker_on) and (not CS.left_blinker_on) and \
if CS.turn_signal_stalk_state == 0 and \
(self.laneChange_enabled == 4):
self.debug_alca("ALCA reset: resetting 4 -> 1")
self.laneChange_enabled =1
self.laneChange_counter =0
self.laneChange_direction =0
CS.UE.custom_alert_message(-1,"",0)

if (not CS.right_blinker_on) and (not CS.left_blinker_on) and \
if CS.turn_signal_stalk_state == 0 and \
(self.laneChange_enabled > 1):
# no blinkers on but we are still changing lane, so we need to send blinker command
if self.laneChange_direction == -1:
turn_signal_needed = 1
elif self.laneChange_direction == 1:
turn_signal_needed = 2
else:
turn_signal_needed = 0

if (CS.cstm_btns.get_button_status("alca") > 0) and self.alcaEnabled and (self.laneChange_enabled == 1):
if ((CS.v_ego < cl_min_v) or (abs(actuators.steerAngle) >= cl_max_a) or \
Expand All @@ -185,14 +180,10 @@ def update(self,enabled,CS,actuators,alcaStateData,frame):
self.stop_ALCA(CS, False)
return 0, False

if self.alcaEnabled and enabled and (((not self.prev_right_blinker_on) and CS.right_blinker_on) or \
((not self.prev_left_blinker_on) and CS.left_blinker_on)) and \
if self.alcaEnabled and enabled and CS.prev_turn_signal_stalk_state == 0 and CS.turn_signal_stalk_state > 0 and \
(CS.v_ego >= cl_min_v) and (abs(actuators.steerAngle) < cl_max_a) and (self.laneChange_enabled == 1):
# start blinker, speed and angle is within limits, let's go
laneChange_direction = 1
# changing lanes
if CS.left_blinker_on:
laneChange_direction = -1
laneChange_direction = -1 if CS.turn_signal_stalk_state == 1 else 1 # left -1, right 1
self.debug_alca("ALCA blinker on detected")

CS.UE.custom_alert_message(2,"Auto Lane Change Engaged!",100)
Expand All @@ -202,9 +193,6 @@ def update(self,enabled,CS,actuators,alcaStateData,frame):
self.laneChange_direction = laneChange_direction
CS.cstm_btns.set_button_status("alca",2)

self.prev_right_blinker_on = CS.right_blinker_on
self.prev_left_blinker_on = CS.left_blinker_on

if (not self.alcaEnabled) and self.laneChange_enabled > 1:
self.debug_alca("ALCA canceled: not enabled")
self.laneChange_enabled = 1
Expand Down
105 changes: 26 additions & 79 deletions selfdrive/car/tesla/HSO_module.py
Original file line number Diff line number Diff line change
@@ -1,85 +1,32 @@
#human steer override module
import time

TIME_REMEMBER_LAST_BLINKER = 50 # in 0.01 seconds

def _current_time_millis():
return int(round(time.time() * 1000))

class HSOController():
def __init__(self,carcontroller):
self.human_control = False
self.frame_humanSteered = 0
self.turn_signal_needed = 0 # send 1 for left, 2 for right 0 for not needed
self.last_blinker_on = 0
self.blinker_on = 0
self.frame_blinker_on = 0
self.last_human_blinker_on = 0
self.frame_human_blinker_on = 0
self.HSO_frame_blinker_on = 0

def __init__(self, carcontroller):
self.human_control = False
self.frame_humanSteered = 0

def update_stat(self,CC,CS,enabled,actuators,frame):
human_control = False
self.last_blinker_on = self.blinker_on
if CS.right_blinker_on:
self.blinker_on = 2
self.frame_human_blinker_on = frame
elif CS.left_blinker_on:
self.blinker_on = 1
self.frame_human_blinker_on = frame
if (self.last_blinker_on == 0) and (self.blinker_on > 0) and (CC.ALCA.laneChange_enabled <= 1):
self.HSO_frame_blinker_on = frame
if (self.last_blinker_on == 0) and (self.blinker_on == 0):
self.HSO_frame_blinker_on = 0
if self.blinker_on > 0:
self.frame_blinker_on = frame
self.last_human_blinker_on = self.blinker_on
else:
if frame - self.frame_blinker_on < TIME_REMEMBER_LAST_BLINKER:
self.blinker_on = self.last_human_blinker_on
else:
self.last_human_blinker_on = 0
if frame - self.frame_human_blinker_on > 100 * CS.hsoBlinkerExtender:
self.blinker_on = 0
self.turn_signal_needed = 0
self.last_blinker_on = 0
def update_stat(self, CC, CS, enabled, actuators, frame):
human_control = False

if CS.enableHSO and enabled:
#if steering but not by ALCA
if (CS.right_blinker_on or CS.left_blinker_on) and (CC.ALCA.laneChange_enabled <= 1):# and (self.last_blinker_on != self.blinker_on):
if CS.enableHSO and enabled:
# if steering but not by ALCA
if CS.steer_override > 0:
self.frame_humanSteered = frame
elif CC.ALCA.laneChange_enabled <= 1:
if CS.turn_signal_stalk_state > 0 or frame <= (CC.blinker_on_frame_start + int(100 * CS.hsoNumbPeriod)): # stalk locked or blinker within numbPeriod
self.frame_humanSteered = frame
elif frame - self.frame_humanSteered < 50: # Need more human testing of handoff timing
# Find steering difference between visiond model and human (no need to do every frame if we run out of CPU):
apply_steer = int(-actuators.steerAngle)
angle_diff = abs(apply_steer - CS.angle_steers)
if angle_diff > 15.:
self.frame_humanSteered = frame
if (CS.steer_override > 0): # and (frame - self.frame_humanSteered > 50): #let's try with human touch only
self.frame_humanSteered = frame
else:
if (CC.ALCA.laneChange_enabled <= 1) and (frame - self.frame_humanSteered < 50): # Need more human testing of handoff timing
# Find steering difference between visiond model and human (no need to do every frame if we run out of CPU):
steer_current=(CS.angle_steers) # Formula to convert current steering angle to match apply_steer calculated number
apply_steer = int(-actuators.steerAngle)
angle = abs(apply_steer-steer_current)
if frame < (self.HSO_frame_blinker_on + int(100 * CS.hsoNumbPeriod)) or angle > 15.:
self.frame_humanSteered = frame
if enabled:
if CS.enableHSO:
if (frame - self.frame_humanSteered < 50):
human_control = True
CS.UE.custom_alert_message(3,"Manual Steering Enabled",51,4)
#if human control and turn signal on, and previous turn signal was not on or was different, adjust
#same direction again cancels signal
if human_control:
self.turn_signal_needed = self.blinker_on
#if no human control, no turn signal needed
if not human_control:
self.turn_signal_needed = 0
self.last_blinker_on = 0
self.blinker_on = 0
if (not human_control) and (CC.DAS_219_lcTempUnavailableSpeed == 1):
CC.DAS_219_lcTempUnavailableSpeed = 0
CC.warningNeeded = 1
self.turn_signal_needed = 0
if (CC.ALCA.laneChange_enabled > 1):
self.turn_signal_needed = 0
self.blinker_on = 0
self.last_blinker_on = 0
self.human_control = human_control
return human_control and enabled, self.turn_signal_needed
if frame - self.frame_humanSteered < 50:
human_control = True
CS.UE.custom_alert_message(3, "Manual Steering Enabled", 51, 4)

if (not human_control) and (CC.DAS_219_lcTempUnavailableSpeed == 1):
CC.DAS_219_lcTempUnavailableSpeed = 0
CC.warningNeeded = 1
self.human_control = human_control
return human_control and enabled
2 changes: 1 addition & 1 deletion selfdrive/car/tesla/PCC_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ def calc_follow_speed_ms(self, CS, alca_enabled):
# Enforce limits on speed
new_speed_kph = clip(new_speed_kph, MIN_PCC_V_KPH, MAX_PCC_V_KPH)
new_speed_kph = clip(new_speed_kph, MIN_PCC_V_KPH, self.pedal_speed_kph)
if CS.blinker_on or (abs(CS.angle_steers) > ANGLE_STOP_ACCEL) or alca_enabled:
if CS.turn_signal_blinking or (abs(CS.angle_steers) > ANGLE_STOP_ACCEL) or alca_enabled:
# Don't accelerate during manual turns, curves or ALCA.
new_speed_kph = min(new_speed_kph, self.last_speed_kph)
#BB Last safety check. Zero if below MIN_SAFE_DIST_M
Expand Down
Loading

0 comments on commit ea50af0

Please sign in to comment.