From 193ed0fba14c567c02f827ad99c68d94cec58677 Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 18:40:48 +0200 Subject: [PATCH 01/21] jamezz-comma devel-pro --- selfdrive/car/gm/carcontroller.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index be0ca64ccb1996..aad3d219dc012f 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -24,9 +24,12 @@ def __init__(self, car_fingerprint): self.STEER_DRIVER_ALLOWANCE = 50 # allowed driver torque before start limiting self.STEER_DRIVER_MULTIPLIER = 4 # weight driver torque heavily self.STEER_DRIVER_FACTOR = 100 # from dbc - self.NEAR_STOP_BRAKE_PHASE = 0.5 # m/s, more aggressive braking near full stop + self.NEAR_STOP_BRAKE_PHASE = 1.5 # m/s, more aggressive braking near full stop - self.ADAS_KEEPALIVE_STEP = 10 + # Takes case of "Service Adaptive Cruise" and "Service Front Camera" + # dashboard messages. + self.ADAS_KEEPALIVE_STEP = 100 + self.CAMERA_KEEPALIVE_STEP = 100 # pedal lookups, only for Volt MAX_GAS = 3072 # Only a safety limit ZERO_GAS = 2048 @@ -59,12 +62,11 @@ def __init__(self, canbus, car_fingerprint, allow_controls): self.pedal_steady = 0. self.start_time = sec_since_boot() self.chime = 0 - self.lkas_active = False - self.inhibit_steer_for = 0 self.steer_idx = 0 self.apply_steer_last = 0 self.car_fingerprint = car_fingerprint self.allow_controls = allow_controls + self.lka_icon_status_last = 0 # Setup detection helper. Routes commands to # an appropriate CAN bus number. @@ -161,6 +163,18 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ # Send ADAS keepalive, 10hz if frame % P.ADAS_KEEPALIVE_STEP == 0: can_sends += gmcan.create_adas_keepalive(canbus.powertrain) + + # Show green icon when LKA torque is applied, and + # alarming orange icon when approaching torque limit. + # If not sent periodically, LKA icon disappears in about 5 seconds. + # Conveniently, sending camera message periodically also works as a keepalive. + lka_active = CS.lkas_status == 1 + lka_critical = abs(actuators.steer) > 0.9 + lka_icon_status = lka_active + (int(lka_critical) << 1) + if frame % P.CAMERA_KEEPALIVE_STEP == 0 \ + or lka_icon_status != self.lka_icon_status_last: + can_sends.append(gmcan.create_lka_icon_command(canbus.sw_gmlan, lka_active, lka_critical)) + self.lka_icon_status_last = lka_icon_status # Send chimes if self.chime != chime: From 879b0f04dc1cd8eedcebc185f1c72e9d6a33312f Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 18:41:55 +0200 Subject: [PATCH 02/21] jamezz-comma devel-pro --- selfdrive/car/gm/gmcan.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 47b0d8b38dfad4..910cb1d95604ce 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -134,6 +134,16 @@ def create_chime_command(bus, chime_type, duration, repeat_cnt): dat = [chime_type, duration, repeat_cnt, 0xff, 0] return [0x10400060, 0, "".join(map(chr, dat)), bus] +def create_lka_icon_command(bus, active, critical): + if active: + if critical: + dat = "\x40\xc0\x14" + else: + dat = "\x40\x40\x18" + else: + dat = "\x00\x00\x00" + return [0x104c006c, 0, dat, bus] + # TODO: WIP ''' def create_friction_brake_command_ct6(packer, bus, apply_brake, idx, near_stop, at_full_stop): From c15bccbe2e2d4268259fedf54d08289b18caed14 Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 18:45:18 +0200 Subject: [PATCH 03/21] jamezz-comma devel-pro --- selfdrive/car/gm/interface.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 27d94b885b4af7..a37b51a8cced98 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -52,7 +52,13 @@ def __init__(self, CP, sendcan=None): @staticmethod def compute_gb(accel, speed): - return float(accel) / 4.0 + # Ripped from compute_gb_honda in Honda's interface.py. Works well off shelf but may need more tuning + creep_brake = 0.0 + creep_speed = 2.68 + creep_brake_value = 0.10 + if speed < creep_speed: + creep_brake = (creep_speed - speed) / creep_speed * creep_brake_value + return float(accel) / 4.8 - creep_brake @staticmethod def calc_accel_override(a_ego, a_target, v_ego, v_target): @@ -76,7 +82,7 @@ def get_params(candidate, fingerprint): if candidate == CAR.VOLT: # supports stop and go, but initial engage must be above 18mph (which include conservatism) - ret.minEnableSpeed = 18 * CV.MPH_TO_MS + ret.minEnableSpeed = 7 * CV.MPH_TO_MS # kg of standard extra cargo to count for drive, gas, etc... ret.mass = 1607 + std_cargo ret.safetyModel = car.CarParams.SafetyModels.gm @@ -137,15 +143,15 @@ def get_params(candidate, fingerprint): ret.longPidDeadzoneBP = [0.] ret.longPidDeadzoneV = [0.] - ret.longitudinalKpBP = [5., 35.] - ret.longitudinalKpV = [2.4, 1.5] - ret.longitudinalKiBP = [0.] - ret.longitudinalKiV = [0.36] + ret.longitudinalKpBP = [0., 5., 35.] + ret.longitudinalKpV = [1.8, 2.425, 2.2] + ret.longitudinalKiBP = [0., 35.] + ret.longitudinalKiV = [0.26, 0.36] ret.steerLimitAlert = True ret.stoppingControl = True - ret.startAccel = 0.8 + ret.startAccel = 0.5 ret.steerActuatorDelay = 0.1 # Default delay, not measured yet ret.steerRateCost = 1.0 From 32e01a652799a3f8ff448f10d2915bef21ef7826 Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 18:57:08 +0200 Subject: [PATCH 04/21] Make car specific longitudinalKpV and longitudinalKiV --- selfdrive/car/toyota/interface.py | 66 +++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 3e465c649a0e28..a8a2fb0335993d 100755 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -83,6 +83,14 @@ def get_params(candidate, fingerprint): ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 # TODO: Prius seem to have very laggy actuators. Understand if it is lag or hysteresis ret.steerActuatorDelay = 0.25 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [3.6, 2.4, 1.5] + ret.longitudinalKiV = [0.54, 0.36] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 2.4, 1.5] + ret.longitudinalKiV = [0.54, 0.36] elif candidate in [CAR.RAV4, CAR.RAV4H]: stop_and_go = True if (candidate in CAR.RAV4H) else False @@ -94,6 +102,15 @@ def get_params(candidate, fingerprint): ret.wheelbase = 2.65 tire_stiffness_factor = 0.5533 ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiV = [0.18, 0.12] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 1.1, 1.0] + ret.longitudinalKiV = [0.5, 0.24] + elif candidate == CAR.COROLLA: stop_and_go = False ret.safetyParam = 100 # see conversion factor for STEER_TORQUE_EPS in dbc file @@ -103,6 +120,14 @@ def get_params(candidate, fingerprint): ret.mass = 2860 * CV.LB_TO_KG + std_cargo # mean between normal and hybrid ret.steerKpV, ret.steerKiV = [[0.2], [0.05]] ret.steerKf = 0.00003 # full torque for 20 deg at 80mph means 0.00007818594 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiV = [0.18, 0.12] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 1.1, 1.0] + ret.longitudinalKiV = [0.5, 0.24] elif candidate == CAR.LEXUS_RXH: stop_and_go = True @@ -113,6 +138,14 @@ def get_params(candidate, fingerprint): ret.mass = 4481 * CV.LB_TO_KG + std_cargo # mean between min and max ret.steerKpV, ret.steerKiV = [[0.6], [0.1]] ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiV = [0.18, 0.12] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 1.1, 1.0] + ret.longitudinalKiV = [0.5, 0.24] elif candidate in [CAR.CHR, CAR.CHRH]: stop_and_go = True @@ -123,6 +156,14 @@ def get_params(candidate, fingerprint): ret.mass = 3300. * CV.LB_TO_KG + std_cargo ret.steerKpV, ret.steerKiV = [[0.723], [0.0428]] ret.steerKf = 0.00006 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiV = [0.18, 0.12] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 1.1, 1.0] + ret.longitudinalKiV = [0.5, 0.24] elif candidate in [CAR.CAMRY, CAR.CAMRYH]: stop_and_go = True @@ -133,6 +174,14 @@ def get_params(candidate, fingerprint): ret.mass = 3400 * CV.LB_TO_KG + std_cargo #mean between normal and hybrid ret.steerKpV, ret.steerKiV = [[0.6], [0.1]] ret.steerKf = 0.00006 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiV = [0.18, 0.12] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 1.1, 1.0] + ret.longitudinalKiV = [0.5, 0.24] elif candidate in [CAR.HIGHLANDER, CAR.HIGHLANDERH]: stop_and_go = True @@ -143,6 +192,14 @@ def get_params(candidate, fingerprint): ret.mass = 4607 * CV.LB_TO_KG + std_cargo #mean between normal and hybrid limited ret.steerKpV, ret.steerKiV = [[0.6], [0.05]] ret.steerKf = 0.00006 + if ret.enableGasInterceptor: + ret.gasMaxV = [0.7] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiV = [0.18, 0.12] + else: + ret.gasMaxV = [0.2] + ret.longitudinalKpV = [3.6, 1.1, 1.0] + ret.longitudinalKiV = [0.5, 0.24] ret.steerRateCost = 1. ret.centerToFront = ret.wheelbase * 0.44 @@ -203,14 +260,7 @@ def get_params(candidate, fingerprint): ret.stoppingControl = False - if ret.enableGasInterceptor: - ret.gasMaxV = [0.7] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiV = [0.18, 0.12] - else: - ret.gasMaxV = [0.2] - ret.longitudinalKpV = [3.6, 1.1, 1.0] - ret.longitudinalKiV = [0.5, 0.24] + return ret # returns a car.CarState From 9d75053ec2b50b812f70aa5bede418d5b9045408 Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 19:20:51 +0200 Subject: [PATCH 05/21] Update carcontroller.py --- selfdrive/car/gm/carcontroller.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index aad3d219dc012f..ebe33689c64d1d 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -4,7 +4,7 @@ from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car.gm import gmcan -from selfdrive.car.gm.values import CAR, DBC +from selfdrive.car.gm.values import CAR, DBC, AccState from selfdrive.can.packer import CANPacker @@ -30,13 +30,14 @@ def __init__(self, car_fingerprint): # dashboard messages. self.ADAS_KEEPALIVE_STEP = 100 self.CAMERA_KEEPALIVE_STEP = 100 + # pedal lookups, only for Volt MAX_GAS = 3072 # Only a safety limit - ZERO_GAS = 2048 + self.ZERO_GAS = 2048 MAX_BRAKE = 350 # Should be around 3.5m/s^2, including regen self.MAX_ACC_REGEN = 1404 # ACC Regen braking is slightly less powerful than max regen paddle self.GAS_LOOKUP_BP = [-0.25, 0., 0.5] - self.GAS_LOOKUP_V = [self.MAX_ACC_REGEN, ZERO_GAS, MAX_GAS] + self.GAS_LOOKUP_V = [self.MAX_ACC_REGEN, self.ZERO_GAS, MAX_GAS] self.BRAKE_LOOKUP_BP = [-1., -0.25] self.BRAKE_LOOKUP_V = [MAX_BRAKE, 0] @@ -85,7 +86,6 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ return P = self.params - # Send CAN commands. can_sends = [] canbus = self.canbus @@ -133,12 +133,18 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ if (frame % 4) == 0: idx = (frame / 4) % 4 - at_full_stop = enabled and CS.standstill - near_stop = enabled and (CS.v_ego < P.NEAR_STOP_BRAKE_PHASE) + car_stopping = apply_gas < P.ZERO_GAS + standstill = CS.pcm_acc_status == AccState.STANDSTILL + at_full_stop = enabled and standstill and car_stopping + near_stop = enabled and (CS.v_ego < P.NEAR_STOP_BRAKE_PHASE) and car_stopping can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, canbus.chassis, apply_brake, idx, near_stop, at_full_stop)) - at_full_stop = enabled and CS.standstill - can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, canbus.powertrain, apply_gas, idx, enabled, at_full_stop)) + # Auto-resume from full stop by resetting ACC control + acc_enabled = enabled + if standstill and not car_stopping: + acc_enabled = False + + can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, canbus.powertrain, apply_gas, idx, acc_enabled, at_full_stop)) # Send dashboard UI commands (ACC status), 25hz if (frame % 4) == 0: @@ -160,10 +166,9 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ can_sends.append(gmcan.create_adas_steering_status(canbus.obstacle, idx)) can_sends.append(gmcan.create_adas_accelerometer_speed_status(canbus.obstacle, CS.v_ego, idx)) - # Send ADAS keepalive, 10hz if frame % P.ADAS_KEEPALIVE_STEP == 0: can_sends += gmcan.create_adas_keepalive(canbus.powertrain) - + # Show green icon when LKA torque is applied, and # alarming orange icon when approaching torque limit. # If not sent periodically, LKA icon disappears in about 5 seconds. From dc43b9cb37ff53a45f747c7898c270603151042b Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 19:21:33 +0200 Subject: [PATCH 06/21] Update gmcan.py --- selfdrive/car/gm/gmcan.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 910cb1d95604ce..1aedd7603e49d9 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -59,19 +59,16 @@ def create_gas_regen_command(packer, bus, throttle, idx, acc_engaged, at_full_st return packer.make_can_msg("ASCMGasRegenCmd", bus, values) def create_friction_brake_command(packer, bus, apply_brake, idx, near_stop, at_full_stop): - - if apply_brake == 0: - mode = 0x1 - else: + mode = 0x1 + if apply_brake > 0: mode = 0xa - if at_full_stop: - mode = 0xd - # TODO: this is to have GM bringing the car to complete stop, - # but currently it conflicts with OP controls, so turned off. - #elif near_stop: - # mode = 0xb + if near_stop: + mode = 0xb + if at_full_stop: + mode = 0xd + brake = (0x1000 - apply_brake) & 0xfff checksum = (0x10000 - (mode << 12) - brake - idx) & 0xffff From a2ef537812a838a366729cb505ac23452eb405aa Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 19:22:10 +0200 Subject: [PATCH 07/21] Update interface.py --- selfdrive/car/gm/interface.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index a37b51a8cced98..9386d40461ed78 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -52,7 +52,7 @@ def __init__(self, CP, sendcan=None): @staticmethod def compute_gb(accel, speed): - # Ripped from compute_gb_honda in Honda's interface.py. Works well off shelf but may need more tuning + # Ripped from compute_gb_honda in Honda's interface.py. Works well off shelf but may need more tuning creep_brake = 0.0 creep_speed = 2.68 creep_brake_value = 0.10 @@ -199,7 +199,7 @@ def update(self, c): ret.cruiseState.available = bool(self.CS.main_on) cruiseEnabled = self.CS.pcm_acc_status != 0 ret.cruiseState.enabled = cruiseEnabled - ret.cruiseState.standstill = self.CS.pcm_acc_status == 4 + ret.cruiseState.standstill = False ret.leftBlinker = self.CS.left_blinker_on ret.rightBlinker = self.CS.right_blinker_on @@ -282,8 +282,6 @@ def update(self, c): events.append(create_event('pedalPressed', [ET.NO_ENTRY, ET.USER_DISABLE])) if ret.gasPressed: events.append(create_event('pedalPressed', [ET.PRE_ENABLE])) - if ret.cruiseState.standstill: - events.append(create_event('resumeRequired', [ET.WARNING])) # handle button presses for b in ret.buttonEvents: From 4630add3783f9970234b9f6b27798897ea04364e Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 19:22:50 +0200 Subject: [PATCH 08/21] Update values.py --- selfdrive/car/gm/values.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 8e93b677c8ae66..62529ed6d73578 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -12,6 +12,12 @@ class CruiseButtons: MAIN = 5 CANCEL = 6 +class AccState: + OFF = 0 + ACTIVE = 1 + FAULTED = 3 + STANDSTILL = 4 + def is_eps_status_ok(eps_status, car_fingerprint): valid_eps_status = [] if car_fingerprint == CAR.VOLT: @@ -49,6 +55,7 @@ def parse_gear_shifter(can_gear): STEER_THRESHOLD = 1.0 + STOCK_CONTROL_MSGS = { CAR.VOLT: [384, 715], # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" CAR.CADILLAC_CT6: [], # Cadillac does not require ASCMs to be disconnected From 1ef7bc26012ed7682b8d564b77ff4bc42dc57e20 Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 20:35:04 +0200 Subject: [PATCH 09/21] Create .gitignore --- selfdrive/car/gm/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 selfdrive/car/gm/.gitignore diff --git a/selfdrive/car/gm/.gitignore b/selfdrive/car/gm/.gitignore new file mode 100644 index 00000000000000..89fa7bc7daf83e --- /dev/null +++ b/selfdrive/car/gm/.gitignore @@ -0,0 +1,2 @@ +buttons.msg +buttons.cc.msg From fc46e263ea91ad515c18aaae605805eeeb64234c Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 20:39:52 +0200 Subject: [PATCH 10/21] Add Buttons --- selfdrive/car/gm/carstate.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 7c0c63f54631ce..5f1b548d895c8e 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -3,6 +3,8 @@ from common.kalman.simple_kalman import KF1D from selfdrive.config import Conversions as CV from selfdrive.can.parser import CANParser +from selfdrive.car.modules.UIBT_module import UIButtons,UIButton +from selfdrive.car.modules.UIEV_module import UIEvents from selfdrive.car.gm.values import DBC, CAR, parse_gear_shifter, \ CruiseButtons, is_eps_status_ok, \ STEER_THRESHOLD @@ -56,7 +58,19 @@ def __init__(self, CP, canbus): self.prev_left_blinker_on = False self.right_blinker_on = False self.prev_right_blinker_on = False - + + #BB UIEvents + self.UE = UIEvents(self) + + #BB variable for custom buttons + self.cstm_btns = UIButtons(self,"Gm","gm") + + #BB pid holder for ALCA + self.pid = None + + #BB custom message counter + self.custom_alert_counter = -1 #set to 100 for 1 second display; carcontroller will take down to zero + # vEgo kalman filter dt = 0.01 self.v_ego_kf = KF1D(x0=np.matrix([[0.], [0.]]), @@ -64,7 +78,17 @@ def __init__(self, CP, canbus): C=np.matrix([1., 0.]), K=np.matrix([[0.12287673], [0.29666309]])) self.v_ego = 0. - + #BB init ui buttons + def init_ui_buttons(self): + btns = [] + btns.append(UIButton("","",0,"",0)) + btns.append(UIButton("","",0,"",1)) + btns.append(UIButton("","",0,"",2)) + btns.append(UIButton("","",0,"",3)) + btns.append(UIButton("","",0,"",4)) + btns.append(UIButton("lka","LKA",0,"",5)) + return btns + def update(self, pt_cp): self.can_valid = pt_cp.can_valid From d8f4cca06fc8380620a14c2017362fcdb40f3a3a Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 21:41:37 +0200 Subject: [PATCH 11/21] Update carstate.py --- selfdrive/car/gm/carstate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 5f1b548d895c8e..4878d897511373 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -81,12 +81,12 @@ def __init__(self, CP, canbus): #BB init ui buttons def init_ui_buttons(self): btns = [] - btns.append(UIButton("","",0,"",0)) + btns.append(UIButton("lka","LKA",0,"",0)) btns.append(UIButton("","",0,"",1)) btns.append(UIButton("","",0,"",2)) btns.append(UIButton("","",0,"",3)) btns.append(UIButton("","",0,"",4)) - btns.append(UIButton("lka","LKA",0,"",5)) + btns.append(UIButton("","",0,"",5)) return btns def update(self, pt_cp): From 7a90f0e0c66a001fef5e981852af177e94bc38f7 Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 21:46:42 +0200 Subject: [PATCH 12/21] Add update_ui_buttons --- selfdrive/car/gm/carstate.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 4878d897511373..e9b7f90772ec41 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -81,13 +81,19 @@ def __init__(self, CP, canbus): #BB init ui buttons def init_ui_buttons(self): btns = [] - btns.append(UIButton("lka","LKA",0,"",0)) + btns.append(UIButton("","",0,"",0)) btns.append(UIButton("","",0,"",1)) btns.append(UIButton("","",0,"",2)) btns.append(UIButton("","",0,"",3)) btns.append(UIButton("","",0,"",4)) - btns.append(UIButton("","",0,"",5)) + btns.append(UIButton("lka","LKA",0,"",5)) return btns + #BB update ui buttons + def update_ui_buttons(self,id,btn_status): + if self.cstm_btns.btns[id].btn_status > 0: + self.cstm_btns.btns[id].btn_status = btn_status * self.cstm_btns.btns[id].btn_status + else: + self.cstm_btns.btns[id].btn_status = btn_status def update(self, pt_cp): From c332f2083523c373a386462ef77365afe41fdfca Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 21:53:07 +0200 Subject: [PATCH 13/21] Add cstm_btns.send_button_info --- selfdrive/car/gm/carcontroller.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index ebe33689c64d1d..fdf2f2a86e53bd 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -80,7 +80,12 @@ def __init__(self, canbus, car_fingerprint, allow_controls): def update(self, sendcan, enabled, CS, frame, actuators, \ hud_v_cruise, hud_show_lanes, hud_show_car, chime, chime_cnt): """ Controls thread """ - +#update custom UI buttons and alerts + CS.UE.update_custom_ui() + if (frame % 1000 == 0): + CS.cstm_btns.send_button_info() + CS.UE.uiSetCarEvent(CS.cstm_btns.car_folder,CS.cstm_btns.car_name) + # Sanity check. if not self.allow_controls: return From ba58ec4a2e8c55652b825220ffabf744379bdb8c Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 22:05:21 +0200 Subject: [PATCH 14/21] Add gas button --- selfdrive/car/gm/carstate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index e9b7f90772ec41..fdc58eac422542 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -85,7 +85,7 @@ def init_ui_buttons(self): btns.append(UIButton("","",0,"",1)) btns.append(UIButton("","",0,"",2)) btns.append(UIButton("","",0,"",3)) - btns.append(UIButton("","",0,"",4)) + btns.append(UIButton("gas","GAS",0,"",4)) btns.append(UIButton("lka","LKA",0,"",5)) return btns #BB update ui buttons From a7bff8ca695e7b75152c48ec9a236fd64ecca57c Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 22:08:15 +0200 Subject: [PATCH 15/21] Add lka button code --- selfdrive/car/gm/carcontroller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index fdf2f2a86e53bd..6739da8f424c4b 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -107,7 +107,8 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ self.apply_steer_last = apply_steer idx = (frame / P.STEER_STEP) % 4 - + if CS.cstm_btns.get_button_status("lka") == 0: + apply_steer = 0 if self.car_fingerprint == CAR.VOLT: can_sends.append(gmcan.create_steering_control(self.packer_pt, canbus.powertrain, apply_steer, idx, lkas_enabled)) From c41bb1337d48536fedfdb4ad10bd53dcf3e6cfaf Mon Sep 17 00:00:00 2001 From: arne182 Date: Sun, 14 Oct 2018 22:10:36 +0200 Subject: [PATCH 16/21] add gasbuttonstatus --- selfdrive/car/gm/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 9386d40461ed78..88d1e0fb45ba3f 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -243,7 +243,7 @@ def update(self, c): buttonEvents.append(be) ret.buttonEvents = buttonEvents - + ret.gasbuttonstatus = self.CS.cstm_btns.get_button_status("gas") events = [] if not self.CS.can_valid: self.can_invalid_count += 1 From 9490808d0227f2efe6aee8ebd3617e5d8065ba23 Mon Sep 17 00:00:00 2001 From: arne182 Date: Mon, 15 Oct 2018 18:31:15 +0200 Subject: [PATCH 17/21] add gasbuttonstatus --- selfdrive/car/honda/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 2bff2e74601b6d..d72f49887d57a1 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -472,7 +472,7 @@ def update(self, c): # TODO: more buttons? buttonEvents.append(be) ret.buttonEvents = buttonEvents - + ret.gasbuttonstatus = self.CS.cstm_btns.get_button_status("gas") # events # TODO: I don't like the way capnp does enums # These strings aren't checked at compile time From da3fe4baa208d09e666374f025244b596390ecff Mon Sep 17 00:00:00 2001 From: arne182 Date: Mon, 15 Oct 2018 18:32:00 +0200 Subject: [PATCH 18/21] Add Gas button --- selfdrive/car/honda/carstate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 7e04435802f370..0d51dbcee65b1b 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -183,7 +183,7 @@ def init_ui_buttons(self): btns.append(UIButton("","",0,"",2)) btns.append(UIButton("sound","SND",1,"",3)) btns.append(UIButton("","",0,"",4)) - btns.append(UIButton("","",0,"",5)) + btns.append(UIButton("gas","Gas",0,"",5)) return btns #BB update ui buttons From e33393650e86758e0b42fb387f3a73f2c19a8ae3 Mon Sep 17 00:00:00 2001 From: arne182 Date: Mon, 15 Oct 2018 19:30:48 +0200 Subject: [PATCH 19/21] Create dashcam.h --- selfdrive/ui/dashcam.h | 164 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 selfdrive/ui/dashcam.h diff --git a/selfdrive/ui/dashcam.h b/selfdrive/ui/dashcam.h new file mode 100644 index 00000000000000..4f503a48980db8 --- /dev/null +++ b/selfdrive/ui/dashcam.h @@ -0,0 +1,164 @@ +#include + +#define CAPTURE_STATE_NONE 0 +#define CAPTURE_STATE_CAPTURING 1 +#define CAPTURE_STATE_NOT_CAPTURING 2 +#define RECORD_INTERVAL 60 // Time in seconds to rotate recordings +#define RECORD_FILES 3 // Number of files to create before looping over + +int captureState = CAPTURE_STATE_NOT_CAPTURING; +int captureNum = 1; +int start_time = 0; +int elapsed_time = 0; // Time of current recording + +//TBD - need to implement locking current video +bool lock_current_video = false; // If true save the current video before rotating + +void stop_capture() { + if (captureState == CAPTURE_STATE_CAPTURING) { + //printf("Stop capturing screen\n"); + system("killall -SIGINT screenrecord"); + captureState = CAPTURE_STATE_NOT_CAPTURING; + } +} + +int get_time() { + // Get current time (in seconds) + + int iRet; + struct timeval tv; + int seconds = 0; + + iRet = gettimeofday(&tv,NULL); + if (iRet == 0) { + seconds = (int)tv.tv_sec; + } + return seconds; +} + +void start_capture() { + char cmd[50] = ""; + ////////////////////////////////// + // NOTE: make sure /sdcard/videos/ folder exists on the device! + ////////////////////////////////// + snprintf(cmd,sizeof(cmd),"screenrecord /sdcard/videos/video%d.mp4&",captureNum); + //printf("Capturing to file: %s\n",cmd); + start_time = get_time(); + system(cmd); + + if (captureNum >= RECORD_FILES) { + captureNum = 1; + } + else { + captureNum++; + } +} + +bool screen_button_clicked(int touch_x, int touch_y) { + if (touch_x >= 1660 && touch_x <= 1810) { + if (touch_y >= 885 && touch_y <= 1035) { + return true; + } + } + return false; +} + +void draw_date_time(UIState *s) { + // Draw the current date/time + + int rect_w = 465; + int rect_h = 80; + int rect_x = (1920-rect_w)/2; + int rect_y = (1080-rect_h-10); + + // Get local time to display + time_t t = time(NULL); + struct tm tm = *localtime(&t); + char now[50] = ""; + snprintf(now,sizeof(now),"%04d/%02d/%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, rect_x, rect_y, rect_w, rect_h, 15); + nvgStrokeColor(s->vg, nvgRGBA(255,255,255,80)); + nvgStrokeWidth(s->vg, 6); + nvgStroke(s->vg); + + nvgFontSize(s->vg, 60); + nvgFontFace(s->vg, "sans-semibold"); + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); + nvgText(s->vg,rect_x+17,rect_y+55,now,NULL); +} + +static void rotate_video() { + // Overwrite the existing video (if needed) + elapsed_time = 0; + stop_capture(); + captureState = CAPTURE_STATE_CAPTURING; + start_capture(); +} + +static void screen_draw_button(UIState *s, int touch_x, int touch_y) { + // Set button to bottom left of screen + if (s->vision_connected && s->plus_state == 0) { + + int btn_w = 150; + int btn_h = 150; + int btn_x = 1920 - btn_w; + int btn_y = 1080 - btn_h; + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, btn_x-110, btn_y-45, btn_w, btn_h, 100); + nvgStrokeColor(s->vg, nvgRGBA(255,255,255,80)); + nvgStrokeWidth(s->vg, 6); + nvgStroke(s->vg); + + nvgFontSize(s->vg, 70); + + if (captureState == CAPTURE_STATE_CAPTURING) { + NVGcolor fillColor = nvgRGBA(255,0,0,150); + nvgFillColor(s->vg, fillColor); + nvgFill(s->vg); + nvgFillColor(s->vg, nvgRGBA(255,255,255,200)); + } + else { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); + } + nvgText(s->vg,btn_x-88,btn_y+50,"REC",NULL); + } + + if (captureState == CAPTURE_STATE_CAPTURING) { + draw_date_time(s); + + elapsed_time = get_time() - start_time; + + if (elapsed_time >= RECORD_INTERVAL) { + rotate_video(); + } + } +} + +void screen_toggle_record_state() { + if (captureState == CAPTURE_STATE_CAPTURING) { + captureState = CAPTURE_STATE_NOT_CAPTURING; + } + else { + captureState = CAPTURE_STATE_CAPTURING; + } +} + +void screen_capture( UIState *s, int touch_x, int touch_y ) { + screen_draw_button(s, touch_x, touch_y); + if (screen_button_clicked(touch_x,touch_y)) { + screen_toggle_record_state(); + + if (captureState == CAPTURE_STATE_CAPTURING) { + start_capture(); + } + else if (captureState == CAPTURE_STATE_NOT_CAPTURING) { + stop_capture(); + } + } + else if (!s->vision_connected) { + // Assume car is not in drive so stop recording + stop_capture(); + } +} From e030913a48192d4120a065067601ea75576985ea Mon Sep 17 00:00:00 2001 From: arne182 Date: Mon, 15 Oct 2018 19:34:35 +0200 Subject: [PATCH 20/21] add dashcam.h --- selfdrive/ui/ui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/ui.c b/selfdrive/ui/ui.c index c5f3b540378c55..9a316e077b7c16 100644 --- a/selfdrive/ui/ui.c +++ b/selfdrive/ui/ui.c @@ -240,7 +240,7 @@ typedef struct UIState { float light_sensor; } UIState; - +#include "dashcam.h" #include "bbui.h" static int last_brightness = -1; From b725c056e8f80623077d977666c2efe237069a7b Mon Sep 17 00:00:00 2001 From: arne182 Date: Mon, 15 Oct 2018 19:51:06 +0200 Subject: [PATCH 21/21] Make video directory into a variable --- selfdrive/ui/dashcam.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/selfdrive/ui/dashcam.h b/selfdrive/ui/dashcam.h index 4f503a48980db8..9041c73f1e56f1 100644 --- a/selfdrive/ui/dashcam.h +++ b/selfdrive/ui/dashcam.h @@ -37,11 +37,19 @@ int get_time() { } void start_capture() { + captureState = CAPTURE_STATE_CAPTURING; char cmd[50] = ""; + char videos_dir[50] = "/sdcard/videos"; + ////////////////////////////////// - // NOTE: make sure /sdcard/videos/ folder exists on the device! + // NOTE: make sure videos_dir folder exists on the device! ////////////////////////////////// - snprintf(cmd,sizeof(cmd),"screenrecord /sdcard/videos/video%d.mp4&",captureNum); + struct stat st = {0}; + if (stat(videos_dir, &st) == -1) { + mkdir(videos_dir,0700); + } + + snprintf(cmd,sizeof(cmd),"screenrecord %s/video%d.mp4&",videos_dir,captureNum); //printf("Capturing to file: %s\n",cmd); start_time = get_time(); system(cmd); @@ -138,10 +146,11 @@ static void screen_draw_button(UIState *s, int touch_x, int touch_y) { void screen_toggle_record_state() { if (captureState == CAPTURE_STATE_CAPTURING) { - captureState = CAPTURE_STATE_NOT_CAPTURING; + stop_capture(); } else { - captureState = CAPTURE_STATE_CAPTURING; + //captureState = CAPTURE_STATE_CAPTURING; + start_capture(); } } @@ -150,12 +159,14 @@ void screen_capture( UIState *s, int touch_x, int touch_y ) { if (screen_button_clicked(touch_x,touch_y)) { screen_toggle_record_state(); +/* if (captureState == CAPTURE_STATE_CAPTURING) { start_capture(); } else if (captureState == CAPTURE_STATE_NOT_CAPTURING) { stop_capture(); } +*/ } else if (!s->vision_connected) { // Assume car is not in drive so stop recording