mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-06-25 07:42:05 +08:00
Merge branch 'master' into dev-priv/master
# Conflicts: # selfdrive/car/hyundai/carcontroller.py # selfdrive/car/nissan/carcontroller.py # selfdrive/controls/controlsd.py
This commit is contained in:
@@ -5,6 +5,8 @@ Version 0.9.1 (2023-2-20)
|
||||
* UI updates
|
||||
* Driver monitoring icon shows driver's head pose
|
||||
* German translation thanks to Vrabetz and CzokNorris!
|
||||
* New driving model
|
||||
* 30% improved height estimation resulting in better driving performance for tall cars
|
||||
* Chevrolet Bolt EV 2022-23 support thanks to JasonJShuler!
|
||||
* Genesis GV60 2023 support thanks to sunnyhaibin!
|
||||
* Hyundai Tucson 2022-23 support
|
||||
@@ -12,6 +14,8 @@ Version 0.9.1 (2023-2-20)
|
||||
* Kia Niro Hybrid 2023 support thanks to sunnyhaibin!
|
||||
* Kia Sorento 2022-23 support thanks to sunnyhaibin!
|
||||
* Kia Sorento Plug-in Hybrid 2022 support thanks to sunnyhaibin!
|
||||
* Toyota C-HR 2021 support thanks to eFiniLan!
|
||||
* Toyota C-HR Hybrid 2022 support thanks to Korben00!
|
||||
* Volkswagen Crafter and MAN TGE 2017-23 support thanks to jyoung8607!
|
||||
|
||||
Version 0.9.0 (2022-11-21)
|
||||
|
||||
+6
-5
@@ -4,7 +4,7 @@
|
||||
|
||||
A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system.
|
||||
|
||||
# 235 Supported Cars
|
||||
# 236 Supported Cars
|
||||
|
||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video|
|
||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
@@ -17,11 +17,11 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=Q3 2019-23">J533</a>||
|
||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=RS3 2018">J533</a>||
|
||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=S3 2015-17">J533</a>||
|
||||
|Cadillac|Escalade ESV 2016[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade ESV 2016">OBD-II</a>||
|
||||
|Cadillac|Escalade ESV 2016[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade ESV 2016">OBD-II</a>||
|
||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EUV 2022-23">GM</a>|<a href="https://youtu.be/xvwzGMUA210" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Chevrolet|Bolt EV 2022-23|2LT Trim with Adaptive Cruise Control Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EV 2022-23">GM</a>||
|
||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Silverado 1500 2020-21">GM</a>||
|
||||
|Chevrolet|Volt 2017-18[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Volt 2017-18">OBD-II</a>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Chevrolet|Volt 2017-18[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Volt 2017-18">OBD-II</a>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2017-18">FCA</a>||
|
||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2019-20">FCA</a>||
|
||||
|Chrysler|Pacifica 2021|All|Stock|0 mph|39 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2021">FCA</a>||
|
||||
@@ -36,7 +36,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Genesis|GV60 (Advanced Trim) 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV60 (Advanced Trim) 2023">Hyundai A</a>||
|
||||
|Genesis|GV60 (Performance Trim) 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV60 (Performance Trim) 2023">Hyundai K</a>||
|
||||
|Genesis|GV70 2022-23[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV70 2022-23">Hyundai L</a>||
|
||||
|GMC|Acadia 2018[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Acadia 2018">OBD-II</a>|<a href="https://www.youtube.com/watch?v=0ZN6DdsBUZo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|GMC|Acadia 2018[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Acadia 2018">OBD-II</a>|<a href="https://www.youtube.com/watch?v=0ZN6DdsBUZo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Sierra 1500 2020-21">GM</a>|<a href="https://youtu.be/5HbNoBLzRwE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Accord 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Accord 2018-22">Honda Bosch A</a>|<a href="https://www.youtube.com/watch?v=mrUwlj3Mi58" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Accord Hybrid 2018-22">Honda Bosch A</a>||
|
||||
@@ -178,6 +178,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Toyota|C-HR 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2017-20">Toyota</a>||
|
||||
|Toyota|C-HR 2021|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2021">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2017-19">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2022">Toyota</a>||
|
||||
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=fkcjviZY9CM" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry 2021-22|All|openpilot|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2021-22">Toyota</a>||
|
||||
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=Q2DYY0AWKgk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
@@ -241,7 +242,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont 2018-22">J533</a>||
|
||||
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont Cross Sport 2021-22">J533</a>||
|
||||
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont X 2021-22">J533</a>||
|
||||
|Volkswagen|Tiguan 2019-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Tiguan 2019-22">J533</a>||
|
||||
|Volkswagen|Tiguan 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Tiguan 2018-23">J533</a>||
|
||||
|Volkswagen|Touran 2017|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Touran 2017">J533</a>||
|
||||
|
||||
<a id="footnotes"></a>
|
||||
|
||||
+1
-1
Submodule opendbc updated: 7f0e42faba...c354dbcdb1
@@ -35,7 +35,7 @@ class CarController:
|
||||
torque -= deadband
|
||||
return torque
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
|
||||
torque_l = 0
|
||||
torque_r = 0
|
||||
|
||||
@@ -43,5 +43,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -19,7 +19,7 @@ class CarController:
|
||||
self.packer = CANPacker(dbc_name)
|
||||
self.params = CarControllerParams(CP)
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
can_sends = []
|
||||
|
||||
lkas_active = CC.latActive and self.lkas_control_bit_prev
|
||||
|
||||
@@ -84,8 +84,9 @@ class CarState(CarStateBase):
|
||||
|
||||
if self.CP.carFingerprint in RAM_CARS:
|
||||
self.auto_high_beam = cp_cam.vl["DAS_6"]['AUTO_HIGH_BEAM_ON'] # Auto High Beam isn't Located in this message on chrysler or jeep currently located in 729 message
|
||||
ret.steerFaultTemporary = cp.vl["EPS_3"]["DASM_FAULT"] == 1
|
||||
ret.steerFaultTemporary = cp.vl["EPS_3"]["DASM_FAULT"] == 1
|
||||
else:
|
||||
ret.steerFaultTemporary = cp.vl["EPS_2"]["LKAS_TEMPORARY_FAULT"] == 1
|
||||
ret.steerFaultPermanent = cp.vl["EPS_2"]["LKAS_STATE"] == 4
|
||||
|
||||
# blindspot sensors
|
||||
@@ -139,6 +140,7 @@ class CarState(CarStateBase):
|
||||
("COUNTER", "EPS_2",),
|
||||
("COLUMN_TORQUE", "EPS_2"),
|
||||
("EPS_TORQUE_MOTOR", "EPS_2"),
|
||||
("LKAS_TEMPORARY_FAULT", "EPS_2"),
|
||||
("LKAS_STATE", "EPS_2"),
|
||||
("COUNTER", "CRUISE_BUTTONS"),
|
||||
]
|
||||
|
||||
@@ -158,5 +158,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -62,8 +62,7 @@ RAM_CARS = RAM_DT | RAM_HD
|
||||
|
||||
# the increased steer rate hasn't been verified on these cars.
|
||||
# remove from this list once it's been tested and confirmed to not fault
|
||||
CHRYSLER_OLD_TUNING_BLACKLIST = {CAR.PACIFICA_2017_HYBRID, CAR.PACIFICA_2018, CAR.PACIFICA_2018_HYBRID,
|
||||
CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE}
|
||||
CHRYSLER_OLD_TUNING_BLACKLIST = {CAR.PACIFICA_2017_HYBRID, CAR.PACIFICA_2018_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE}
|
||||
|
||||
@dataclass
|
||||
class ChryslerCarInfo(CarInfo):
|
||||
|
||||
@@ -21,7 +21,7 @@ class CarController:
|
||||
self.lkas_enabled_last = False
|
||||
self.steer_alert_last = False
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
can_sends = []
|
||||
|
||||
actuators = CC.actuators
|
||||
|
||||
@@ -78,5 +78,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -13,6 +13,8 @@ LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
|
||||
# Camera cancels up to 0.1s after brake is pressed, ECM allows 0.5s
|
||||
CAMERA_CANCEL_DELAY_FRAMES = 10
|
||||
# Enforce a minimum interval between steering messages to avoid a fault
|
||||
MIN_STEER_MSG_INTERVAL_MS = 15
|
||||
|
||||
|
||||
class CarController:
|
||||
@@ -37,7 +39,7 @@ class CarController:
|
||||
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar'])
|
||||
self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis'])
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
hud_alert = hud_control.visualAlert
|
||||
@@ -64,9 +66,10 @@ class CarController:
|
||||
self.lka_steering_cmd_counter += 1
|
||||
self.sent_lka_steering_cmd = True
|
||||
|
||||
# Avoid GM EPS faults when transmitting messages too close together: skip this transmit if we just
|
||||
# received the ASCMLKASteeringCmd loopback confirmation in the current CS frame
|
||||
if (self.frame - self.last_steer_frame) >= steer_step and not CS.loopback_lka_steering_cmd_updated:
|
||||
# Avoid GM EPS faults when transmitting messages too close together: skip this transmit if we
|
||||
# received the ASCMLKASteeringCmd loopback confirmation too recently
|
||||
last_lka_steer_msg_ms = (now_nanos - CS.loopback_lka_steering_cmd_ts_nanos) * 1e-6
|
||||
if (self.frame - self.last_steer_frame) >= steer_step and last_lka_steer_msg_ms > MIN_STEER_MSG_INTERVAL_MS:
|
||||
# Initialize ASCMLKASteeringCmd counter using the camera until we get a msg on the bus
|
||||
if not self.sent_lka_steering_cmd:
|
||||
self.lka_steering_cmd_counter = CS.pt_lka_steering_cmd_counter + 1
|
||||
|
||||
@@ -17,7 +17,11 @@ class CarState(CarStateBase):
|
||||
super().__init__(CP)
|
||||
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
|
||||
self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"]
|
||||
self.cluster_speed_hyst_gap = CV.KPH_TO_MS / 2.
|
||||
self.cluster_min_speed = CV.KPH_TO_MS / 2.
|
||||
|
||||
self.loopback_lka_steering_cmd_updated = False
|
||||
self.loopback_lka_steering_cmd_ts_nanos = 0
|
||||
self.pt_lka_steering_cmd_counter = 0
|
||||
self.cam_lka_steering_cmd_counter = 0
|
||||
self.buttons_counter = 0
|
||||
@@ -38,6 +42,7 @@ class CarState(CarStateBase):
|
||||
|
||||
# Variables used for avoiding LKAS faults
|
||||
self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0
|
||||
self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
if self.CP.networkLocation == NetworkLocation.fwdCamera:
|
||||
self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
|
||||
@@ -67,6 +67,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.pcmCruise = True
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM
|
||||
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
|
||||
ret.minSteerSpeed = 10 * CV.KPH_TO_MS
|
||||
|
||||
# Tuning for experimental long
|
||||
ret.longitudinalTuning.kpV = [2.0, 1.5]
|
||||
@@ -89,6 +90,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.pcmCruise = False # stock non-adaptive cruise control is kept off
|
||||
# supports stop and go, but initial engage must (conservatively) be above 18mph
|
||||
ret.minEnableSpeed = 18 * CV.MPH_TO_MS
|
||||
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
|
||||
|
||||
# Tuning
|
||||
ret.longitudinalTuning.kpV = [2.4, 1.5]
|
||||
@@ -100,8 +102,6 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL, CAR.EQUINOX}
|
||||
|
||||
# Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below.
|
||||
# Some GMs need some tolerance above 10 kph to avoid a fault
|
||||
ret.minSteerSpeed = 10.1 * CV.KPH_TO_MS
|
||||
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
|
||||
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]]
|
||||
ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594
|
||||
@@ -284,5 +284,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -124,7 +124,7 @@ class CarController:
|
||||
self.brake = 0.0
|
||||
self.last_steer = 0.0
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
hud_v_cruise = hud_control.setSpeed * CV.MS_TO_KPH if hud_control.speedVisible else 255
|
||||
|
||||
@@ -381,5 +381,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
# pass in a car.CarControl
|
||||
# to be called @ 100hz
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -58,7 +58,7 @@ class CarController:
|
||||
self.lat_disengage_init = False
|
||||
self.lat_active_last = False
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
|
||||
|
||||
@@ -374,5 +374,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -1559,6 +1559,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.05 99211-GI010 220614',
|
||||
b'\xf1\x00NE1 MFC AT EUR RHD 1.00 1.01 99211-GI010 211007',
|
||||
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.01 99211-GI010 211007',
|
||||
b'\xf1\x00NE1 MFC AT EUR RHD 1.00 1.02 99211-GI010 211206',
|
||||
],
|
||||
},
|
||||
CAR.TUCSON_4TH_GEN: {
|
||||
|
||||
@@ -247,7 +247,7 @@ class CarInterfaceBase(ABC):
|
||||
return reader
|
||||
|
||||
@abstractmethod
|
||||
def apply(self, c: car.CarControl) -> Tuple[car.CarControl.Actuators, List[bytes]]:
|
||||
def apply(self, c: car.CarControl, now_nanos: int) -> Tuple[car.CarControl.Actuators, List[bytes]]:
|
||||
pass
|
||||
|
||||
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True,
|
||||
|
||||
@@ -15,7 +15,7 @@ class CarController:
|
||||
self.brake_counter = 0
|
||||
self.frame = 0
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
can_sends = []
|
||||
|
||||
apply_steer = 0
|
||||
|
||||
@@ -113,5 +113,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -57,7 +57,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
def apply(self, c, now_nanos):
|
||||
# in mock no carcontrols
|
||||
actuators = car.CarControl.Actuators.new_message()
|
||||
return actuators, []
|
||||
|
||||
@@ -23,7 +23,7 @@ class CarController:
|
||||
self.lat_disengage_init = False
|
||||
self.lat_active_last = False
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
pcm_cancel_cmd = CC.cruiseControl.cancel
|
||||
|
||||
@@ -98,5 +98,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -19,7 +19,7 @@ class CarController:
|
||||
self.p = CarControllerParams(CP)
|
||||
self.packer = CANPacker(DBC[CP.carFingerprint]['pt'])
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
pcm_cancel_cmd = CC.cruiseControl.cancel
|
||||
|
||||
@@ -166,5 +166,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -253,6 +253,7 @@ FW_VERSIONS = {
|
||||
b'\xca!f@\x07',
|
||||
b'\xca!fp\x07',
|
||||
b'\xf3"f@\x07',
|
||||
b'\xe6!fp\x07',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xe6\xf5\004\000\000',
|
||||
@@ -262,6 +263,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00\xd7\x10@',
|
||||
b'\xe6\xf5D0\x00',
|
||||
b'\xe9\xf6F0\x00',
|
||||
b'\xe9\xf5B0\x00',
|
||||
],
|
||||
},
|
||||
CAR.FORESTER: {
|
||||
|
||||
@@ -14,7 +14,7 @@ class CarController:
|
||||
self.pt_packer = CANPacker(DBC[CP.carFingerprint]['pt'])
|
||||
self.tesla_can = TeslaCAN(self.packer, self.pt_packer)
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
pcm_cancel_cmd = CC.cruiseControl.cancel
|
||||
|
||||
|
||||
@@ -58,5 +58,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -182,6 +182,7 @@ routes = [
|
||||
CarTestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.CHR),
|
||||
CarTestRoute("ea8fbe72b96a185c|2023-02-08--15-11-46", TOYOTA.CHR_TSS2),
|
||||
CarTestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.CHRH),
|
||||
CarTestRoute("6719965b0e1d1737|2023-02-09--22-44-05", TOYOTA.CHRH_TSS2),
|
||||
CarTestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.PRIUS_V),
|
||||
|
||||
CarTestRoute("202c40641158a6e5|2021-09-21--09-43-24", VOLKSWAGEN.ARTEON_MK1),
|
||||
|
||||
@@ -59,15 +59,15 @@ class TestCarInterfaces(unittest.TestCase):
|
||||
CC = car.CarControl.new_message()
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC, 0)
|
||||
car_interface.apply(CC, 0)
|
||||
|
||||
CC = car.CarControl.new_message()
|
||||
CC.enabled = True
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC, 0)
|
||||
car_interface.apply(CC, 0)
|
||||
|
||||
# Test radar interface
|
||||
RadarInterface = importlib.import_module(f'selfdrive.car.{car_params.carName}.radar_interface').RadarInterface
|
||||
|
||||
@@ -149,7 +149,7 @@ class TestCarModelBase(unittest.TestCase):
|
||||
|
||||
for i, msg in enumerate(self.can_msgs):
|
||||
CS = self.CI.update(CC, (msg.as_builder().to_bytes(),))
|
||||
self.CI.apply(CC)
|
||||
self.CI.apply(CC, msg.logMonoTime)
|
||||
|
||||
if CS.canValid:
|
||||
can_valid = True
|
||||
|
||||
@@ -9,6 +9,7 @@ TOYOTA ALPHARD 2020: TOYOTA SIENNA 2018
|
||||
TOYOTA PRIUS v 2017 : TOYOTA PRIUS 2017
|
||||
TOYOTA RAV4 2022: TOYOTA RAV4 HYBRID 2022
|
||||
TOYOTA C-HR HYBRID 2018: TOYOTA C-HR 2018
|
||||
TOYOTA C-HR HYBRID 2022: TOYOTA C-HR 2021
|
||||
LEXUS IS 2018: LEXUS NX 2018
|
||||
LEXUS CT HYBRID 2018 : LEXUS NX 2018
|
||||
LEXUS ES HYBRID 2018: TOYOTA CAMRY HYBRID 2018
|
||||
|
||||
@@ -34,7 +34,7 @@ class CarController:
|
||||
self.gas = 0
|
||||
self.accel = 0
|
||||
|
||||
def update(self, CC, CS):
|
||||
def update(self, CC, CS, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
pcm_cancel_cmd = CC.cruiseControl.cancel
|
||||
|
||||
@@ -75,7 +75,7 @@ class CarInterface(CarInterfaceBase):
|
||||
tire_stiffness_factor = 0.5533
|
||||
ret.mass = 4481. * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max
|
||||
|
||||
elif candidate in (CAR.CHR, CAR.CHRH, CAR.CHR_TSS2):
|
||||
elif candidate in (CAR.CHR, CAR.CHRH, CAR.CHR_TSS2, CAR.CHRH_TSS2):
|
||||
stop_and_go = True
|
||||
ret.wheelbase = 2.63906
|
||||
ret.steerRatio = 13.6
|
||||
@@ -315,5 +315,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
# pass in a car.CarControl
|
||||
# to be called @ 100hz
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@@ -51,6 +51,7 @@ class CAR:
|
||||
CHR = "TOYOTA C-HR 2018"
|
||||
CHR_TSS2 = "TOYOTA C-HR 2021"
|
||||
CHRH = "TOYOTA C-HR HYBRID 2018"
|
||||
CHRH_TSS2 = "TOYOTA C-HR HYBRID 2022"
|
||||
COROLLA = "TOYOTA COROLLA 2017"
|
||||
COROLLA_TSS2 = "TOYOTA COROLLA TSS2 2019"
|
||||
# LSS2 Lexus UX Hybrid is same as a TSS2 Corolla Hybrid
|
||||
@@ -119,6 +120,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
|
||||
CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-20"),
|
||||
CAR.CHR_TSS2: ToyotaCarInfo("Toyota C-HR 2021"),
|
||||
CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-19"),
|
||||
CAR.CHRH_TSS2: ToyotaCarInfo("Toyota C-HR Hybrid 2022"),
|
||||
CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19"),
|
||||
CAR.COROLLA_TSS2: [
|
||||
ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"),
|
||||
@@ -233,7 +235,7 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
# FIXME: On some models, abs can sometimes be missing
|
||||
Ecu.abs: [CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_IS],
|
||||
# On some models, the engine can show on two different addresses
|
||||
Ecu.engine: [CAR.CAMRY, CAR.COROLLA_TSS2, CAR.CHR, CAR.LEXUS_IS, CAR.LEXUS_RC],
|
||||
Ecu.engine: [CAR.CAMRY, CAR.COROLLA_TSS2, CAR.CHR, CAR.CHR_TSS2, CAR.LEXUS_IS, CAR.LEXUS_RC],
|
||||
}
|
||||
)
|
||||
|
||||
@@ -637,18 +639,25 @@ FW_VERSIONS = {
|
||||
},
|
||||
CAR.CHR_TSS2: {
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'F152610260\x00\x00\x00\x00\x00\x00',
|
||||
b'F1526F4270\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'8965B10091\x00\x00\x00\x00\x00\x00',
|
||||
b'8965B10110\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x0189663F459000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\x0331014000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00895231203402\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821FF410200\x00\x00\x00\x00',
|
||||
b'\x018821FF410300\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646FF410200\x00\x00\x00\x008646GF408200\x00\x00\x00\x00',
|
||||
b'\x028646FF411100\x00\x00\x00\x008646GF409000\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
@@ -705,6 +714,23 @@ FW_VERSIONS = {
|
||||
b'8646FF407000 ',
|
||||
],
|
||||
},
|
||||
CAR.CHRH_TSS2: {
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'8965B10092\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'F152610041\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x0189663F438000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 15): [
|
||||
b'\x018821FF410500\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 109): [
|
||||
b'\x028646FF413100\x00\x00\x00\x008646GF411100\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.COROLLA: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\x0230ZC2000\x00\x00\x00\x00\x00\x00\x00\x0050212000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
@@ -2051,6 +2077,7 @@ DBC = {
|
||||
CAR.CHR: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.CHR_TSS2: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.CHRH: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.CHRH_TSS2: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.CAMRY: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.CAMRYH: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.CAMRY_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
@@ -2092,7 +2119,7 @@ EPS_SCALE = defaultdict(lambda: 73, {CAR.PRIUS: 66, CAR.COROLLA: 88, CAR.LEXUS_I
|
||||
# Toyota/Lexus Safety Sense 2.0 and 2.5
|
||||
TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022,
|
||||
CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2,
|
||||
CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2, CAR.CHR_TSS2}
|
||||
CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2, CAR.CHR_TSS2, CAR.CHRH_TSS2}
|
||||
|
||||
NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH}
|
||||
|
||||
@@ -2100,9 +2127,9 @@ NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH}
|
||||
UNSUPPORTED_DSU_CAR = {CAR.LEXUS_IS, CAR.LEXUS_RC}
|
||||
|
||||
# these cars have a radar which sends ACC messages instead of the camera
|
||||
RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022, CAR.CHR_TSS2}
|
||||
RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022, CAR.CHR_TSS2, CAR.CHRH_TSS2}
|
||||
|
||||
EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.COROLLAH_TSS2, CAR.HIGHLANDERH, CAR.HIGHLANDERH_TSS2, CAR.PRIUS,
|
||||
EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.CHRH_TSS2, CAR.COROLLAH_TSS2, CAR.HIGHLANDERH, CAR.HIGHLANDERH_TSS2, CAR.PRIUS,
|
||||
CAR.PRIUS_V, CAR.RAV4H, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.LEXUS_CTH, CAR.MIRAI, CAR.LEXUS_ESH, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_NXH, CAR.LEXUS_RXH,
|
||||
CAR.LEXUS_RXH_TSS2, CAR.LEXUS_NXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class CarController:
|
||||
self.hcaSameTorqueCount = 0
|
||||
self.hcaEnabledFrameCount = 0
|
||||
|
||||
def update(self, CC, CS, ext_bus):
|
||||
def update(self, CC, CS, ext_bus, now_nanos):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
can_sends = []
|
||||
|
||||
@@ -277,5 +277,5 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
return ret
|
||||
|
||||
def apply(self, c):
|
||||
return self.CC.update(c, self.CS, self.ext_bus)
|
||||
def apply(self, c, now_nanos):
|
||||
return self.CC.update(c, self.CS, self.ext_bus, now_nanos)
|
||||
|
||||
@@ -222,7 +222,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
|
||||
],
|
||||
CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022"),
|
||||
CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_MQB_A0]),
|
||||
CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2019-22"),
|
||||
CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2018-23"),
|
||||
CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2017"),
|
||||
CAR.TRANSPORTER_T61: [
|
||||
VWCarInfo("Volkswagen Caravelle 2020"),
|
||||
@@ -734,6 +734,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x8704L906026EJ\xf1\x893661',
|
||||
b'\xf1\x8704L906027G \xf1\x899893',
|
||||
b'\xf1\x875N0906259 \xf1\x890002',
|
||||
b'\xf1\x875NA906259H \xf1\x890002',
|
||||
b'\xf1\x875NA907115E \xf1\x890005',
|
||||
b'\xf1\x8783A907115B \xf1\x890005',
|
||||
b'\xf1\x8783A907115F \xf1\x890002',
|
||||
@@ -751,6 +752,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x870DL300013A \xf1\x893005',
|
||||
b'\xf1\x870DL300013G \xf1\x892119',
|
||||
b'\xf1\x870DL300013G \xf1\x892120',
|
||||
b'\xf1\x870DL300014C \xf1\x893703',
|
||||
],
|
||||
(Ecu.srs, 0x715, None): [
|
||||
b'\xf1\x875Q0959655AR\xf1\x890317\xf1\x82\02331310031333334313132573732379333313100',
|
||||
@@ -761,6 +763,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x1331310031333334313140013750379333423100',
|
||||
b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x1331310031333334313140573752379333423100',
|
||||
b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1316143231313500314647021750179333613100',
|
||||
b'\xf1\x875Q0959655CG\xf1\x890421\xf1\x82\x1331310031333300314240024050409333613100',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820529A6060603',
|
||||
@@ -768,6 +771,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567A6000600',
|
||||
b'\xf1\x875QF909144A \xf1\x895581\xf1\x82\x0571A60834A1',
|
||||
b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\00571A60634A1',
|
||||
b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\x0571A62A32A1',
|
||||
b'\xf1\x875QM909144B \xf1\x891081\xf1\x82\x0521A60604A1',
|
||||
b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521A60604A1',
|
||||
b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\00521A60804A1',
|
||||
|
||||
@@ -179,12 +179,12 @@ class Controls:
|
||||
self.enabled = False
|
||||
self.enabled_long = False
|
||||
self.active = False
|
||||
self.can_rcv_timeout = False
|
||||
self.soft_disable_timer = 0
|
||||
self.mismatch_counter = 0
|
||||
self.mismatch_counter_long = 0
|
||||
self.cruise_mismatch_counter = 0
|
||||
self.can_rcv_timeout_counter = 0
|
||||
self.can_rcv_timeout_counter = 0 # conseuctive timeout count
|
||||
self.can_rcv_cum_timeout_counter = 0 # cumulative timeout count
|
||||
self.last_blinker_frame = 0
|
||||
self.last_steering_pressed_frame = 0
|
||||
self.distance_traveled = 0
|
||||
@@ -196,10 +196,12 @@ class Controls:
|
||||
self.steer_limited = False
|
||||
self.desired_curvature = 0.0
|
||||
self.desired_curvature_rate = 0.0
|
||||
self.experimental_mode = False
|
||||
self.v_cruise_helper = VCruiseHelper(self.CP)
|
||||
|
||||
# TODO: no longer necessary, aside from process replay
|
||||
self.sm['liveParameters'].valid = True
|
||||
self.can_log_mono_time = 0
|
||||
|
||||
self.startup_event = get_startup_event(car_recognized, controller_available, len(self.CP.carFw) > 0)
|
||||
|
||||
@@ -370,9 +372,10 @@ class Controls:
|
||||
self.events.add(EventName.canError)
|
||||
|
||||
# generic catch-all. ideally, a more specific event should be added above instead
|
||||
can_rcv_timeout = self.can_rcv_timeout_counter >= 5
|
||||
has_disable_events = self.events.any(ET.NO_ENTRY) and (self.events.any(ET.SOFT_DISABLE) or self.events.any(ET.IMMEDIATE_DISABLE))
|
||||
no_system_errors = (not has_disable_events) or (len(self.events) == num_events)
|
||||
if (not self.sm.all_checks() or self.can_rcv_timeout) and no_system_errors:
|
||||
if (not self.sm.all_checks() or can_rcv_timeout) and no_system_errors:
|
||||
if not self.sm.all_alive():
|
||||
self.events.add(EventName.commIssue)
|
||||
elif not self.sm.all_freq_ok():
|
||||
@@ -384,7 +387,7 @@ class Controls:
|
||||
'invalid': [s for s, valid in self.sm.valid.items() if not valid],
|
||||
'not_alive': [s for s, alive in self.sm.alive.items() if not alive],
|
||||
'not_freq_ok': [s for s, freq_ok in self.sm.freq_ok.items() if not freq_ok],
|
||||
'can_rcv_timeout': self.can_rcv_timeout,
|
||||
'can_rcv_timeout': can_rcv_timeout,
|
||||
}
|
||||
if logs != self.logged_comm_issue:
|
||||
cloudlog.event("commIssue", error=True, **logs)
|
||||
@@ -447,6 +450,8 @@ class Controls:
|
||||
# Update carState from CAN
|
||||
can_strs = messaging.drain_sock_raw(self.can_sock, wait_for_one=True)
|
||||
CS = self.CI.update(self.CC, can_strs)
|
||||
if len(can_strs) and REPLAY:
|
||||
self.can_log_mono_time = messaging.log_from_bytes(can_strs[0]).logMonoTime
|
||||
|
||||
self.sm.update(0)
|
||||
|
||||
@@ -464,9 +469,9 @@ class Controls:
|
||||
# Check for CAN timeout
|
||||
if not can_strs:
|
||||
self.can_rcv_timeout_counter += 1
|
||||
self.can_rcv_timeout = True
|
||||
self.can_rcv_cum_timeout_counter += 1
|
||||
else:
|
||||
self.can_rcv_timeout = False
|
||||
self.can_rcv_timeout_counter = 0
|
||||
|
||||
# When the panda and controlsd do not agree on controls_allowed
|
||||
# we want to disengage openpilot. However the status from the panda goes through
|
||||
@@ -515,7 +520,7 @@ class Controls:
|
||||
# ENABLED
|
||||
if self.state == State.enabled:
|
||||
if CS.cruiseState.enabled and not self.CS_prev.cruiseState.enabled:
|
||||
self.v_cruise_helper.initialize_v_cruise(CS)
|
||||
self.v_cruise_helper.initialize_v_cruise(CS, self.experimental_mode)
|
||||
# Block resume if cruise never previously enabled
|
||||
resume_pressed = any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in CS.buttonEvents)
|
||||
if not self.CP.pcmCruise and not self.v_cruise_helper.v_cruise_initialized and resume_pressed:
|
||||
@@ -574,7 +579,7 @@ class Controls:
|
||||
self.state = State.enabled
|
||||
self.current_alert_types.append(ET.ENABLE)
|
||||
if CS.cruiseState.enabled:
|
||||
self.v_cruise_helper.initialize_v_cruise(CS)
|
||||
self.v_cruise_helper.initialize_v_cruise(CS, self.experimental_mode)
|
||||
|
||||
# Check if openpilot is engaged and actuators are enabled
|
||||
self.enabled = self.state in ENABLED_STATES
|
||||
@@ -769,7 +774,8 @@ class Controls:
|
||||
|
||||
if not self.read_only and self.initialized:
|
||||
# send car controls over can
|
||||
self.last_actuators, can_sends = self.CI.apply(CC)
|
||||
now_nanos = self.can_log_mono_time if REPLAY else int(sec_since_boot() * 1e9)
|
||||
self.last_actuators, can_sends = self.CI.apply(CC, now_nanos)
|
||||
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid))
|
||||
CC.actuatorsOutput = self.last_actuators
|
||||
if self.CP.steerControlType == car.CarParams.SteerControlType.angle:
|
||||
@@ -819,8 +825,8 @@ class Controls:
|
||||
controlsState.cumLagMs = -self.rk.remaining * 1000.
|
||||
controlsState.startMonoTime = int(start_time * 1e9)
|
||||
controlsState.forceDecel = bool(force_decel)
|
||||
controlsState.canErrorCounter = self.can_rcv_timeout_counter
|
||||
controlsState.experimentalMode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl
|
||||
controlsState.canErrorCounter = self.can_rcv_cum_timeout_counter
|
||||
controlsState.experimentalMode = self.experimental_mode
|
||||
|
||||
lat_tuning = self.CP.lateralTuning.which()
|
||||
if self.joystick_mode:
|
||||
@@ -871,6 +877,7 @@ class Controls:
|
||||
self.prof.checkpoint("Ratekeeper", ignore=True)
|
||||
|
||||
self.is_metric = self.params.get_bool("IsMetric")
|
||||
self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl
|
||||
|
||||
# Sample data from sockets and get a carState
|
||||
CS = self.data_sample()
|
||||
|
||||
@@ -8,10 +8,12 @@ from selfdrive.modeld.constants import T_IDXS
|
||||
|
||||
# WARNING: this value was determined based on the model's training distribution,
|
||||
# model predictions above this speed can be unpredictable
|
||||
V_CRUISE_MAX = 145 # kph
|
||||
V_CRUISE_MIN = 8 # kph
|
||||
V_CRUISE_ENABLE_MIN = 40 # kph
|
||||
V_CRUISE_INITIAL = 255 # kph
|
||||
# V_CRUISE's are in kph
|
||||
V_CRUISE_MIN = 8
|
||||
V_CRUISE_MAX = 145
|
||||
V_CRUISE_UNSET = 255
|
||||
V_CRUISE_INITIAL = 40
|
||||
V_CRUISE_INITIAL_EXPERIMENTAL_MODE = 105
|
||||
IMPERIAL_INCREMENT = 1.6 # should be CV.MPH_TO_KPH, but this causes rounding errors
|
||||
|
||||
MIN_SPEED = 1.0
|
||||
@@ -39,15 +41,15 @@ CRUISE_INTERVAL_SIGN = {
|
||||
class VCruiseHelper:
|
||||
def __init__(self, CP):
|
||||
self.CP = CP
|
||||
self.v_cruise_kph = V_CRUISE_INITIAL
|
||||
self.v_cruise_cluster_kph = V_CRUISE_INITIAL
|
||||
self.v_cruise_kph = V_CRUISE_UNSET
|
||||
self.v_cruise_cluster_kph = V_CRUISE_UNSET
|
||||
self.v_cruise_kph_last = 0
|
||||
self.button_timers = {ButtonType.decelCruise: 0, ButtonType.accelCruise: 0}
|
||||
self.button_change_states = {btn: {"standstill": False, "enabled": False} for btn in self.button_timers}
|
||||
|
||||
@property
|
||||
def v_cruise_initialized(self):
|
||||
return self.v_cruise_kph != V_CRUISE_INITIAL
|
||||
return self.v_cruise_kph != V_CRUISE_UNSET
|
||||
|
||||
def update_v_cruise(self, CS, enabled, is_metric):
|
||||
self.v_cruise_kph_last = self.v_cruise_kph
|
||||
@@ -62,8 +64,8 @@ class VCruiseHelper:
|
||||
self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
|
||||
self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH
|
||||
else:
|
||||
self.v_cruise_kph = V_CRUISE_INITIAL
|
||||
self.v_cruise_cluster_kph = V_CRUISE_INITIAL
|
||||
self.v_cruise_kph = V_CRUISE_UNSET
|
||||
self.v_cruise_cluster_kph = V_CRUISE_UNSET
|
||||
|
||||
def _update_v_cruise_non_pcm(self, CS, enabled, is_metric):
|
||||
# handle button presses. TODO: this should be in state_control, but a decelCruise press
|
||||
@@ -125,16 +127,18 @@ class VCruiseHelper:
|
||||
self.button_timers[b.type.raw] = 1 if b.pressed else 0
|
||||
self.button_change_states[b.type.raw] = {"standstill": CS.cruiseState.standstill, "enabled": enabled}
|
||||
|
||||
def initialize_v_cruise(self, CS):
|
||||
def initialize_v_cruise(self, CS, experimental_mode: bool) -> None:
|
||||
# initializing is handled by the PCM
|
||||
if self.CP.pcmCruise:
|
||||
return
|
||||
|
||||
initial = V_CRUISE_INITIAL_EXPERIMENTAL_MODE if experimental_mode else V_CRUISE_INITIAL
|
||||
|
||||
# 250kph or above probably means we never had a set speed
|
||||
if any(b.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for b in CS.buttonEvents) and self.v_cruise_kph_last < 250:
|
||||
self.v_cruise_kph = self.v_cruise_kph_last
|
||||
else:
|
||||
self.v_cruise_kph = int(round(clip(CS.vEgo * CV.MS_TO_KPH, V_CRUISE_ENABLE_MIN, V_CRUISE_MAX)))
|
||||
self.v_cruise_kph = int(round(clip(CS.vEgo * CV.MS_TO_KPH, initial, V_CRUISE_MAX)))
|
||||
|
||||
self.v_cruise_cluster_kph = self.v_cruise_kph
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import numpy as np
|
||||
from parameterized import parameterized_class
|
||||
import unittest
|
||||
|
||||
from selfdrive.controls.lib.drive_helpers import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_ENABLE_MIN, IMPERIAL_INCREMENT
|
||||
from selfdrive.controls.lib.drive_helpers import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_INITIAL, IMPERIAL_INCREMENT
|
||||
from cereal import car
|
||||
from common.conversions import Conversions as CV
|
||||
from selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver
|
||||
@@ -53,16 +53,16 @@ class TestVCruiseHelper(unittest.TestCase):
|
||||
for _ in range(2):
|
||||
self.v_cruise_helper.update_v_cruise(car.CarState(cruiseState={"available": False}), enabled=False, is_metric=False)
|
||||
|
||||
def enable(self, v_ego):
|
||||
def enable(self, v_ego, experimental_mode):
|
||||
# Simulates user pressing set with a current speed
|
||||
self.v_cruise_helper.initialize_v_cruise(car.CarState(vEgo=v_ego))
|
||||
self.v_cruise_helper.initialize_v_cruise(car.CarState(vEgo=v_ego), experimental_mode)
|
||||
|
||||
def test_adjust_speed(self):
|
||||
"""
|
||||
Asserts speed changes on falling edges of buttons.
|
||||
"""
|
||||
|
||||
self.enable(V_CRUISE_ENABLE_MIN * CV.KPH_TO_MS)
|
||||
self.enable(V_CRUISE_INITIAL * CV.KPH_TO_MS, False)
|
||||
|
||||
for btn in (ButtonType.accelCruise, ButtonType.decelCruise):
|
||||
for pressed in (True, False):
|
||||
@@ -86,7 +86,7 @@ class TestVCruiseHelper(unittest.TestCase):
|
||||
CS.buttonEvents = [ButtonEvent(type=ButtonType.decelCruise, pressed=pressed)]
|
||||
self.v_cruise_helper.update_v_cruise(CS, enabled=enabled, is_metric=False)
|
||||
if pressed:
|
||||
self.enable(V_CRUISE_ENABLE_MIN * CV.KPH_TO_MS)
|
||||
self.enable(V_CRUISE_INITIAL * CV.KPH_TO_MS, False)
|
||||
|
||||
# Expected diff on enabling. Speed should not change on falling edge of pressed
|
||||
self.assertEqual(not pressed, self.v_cruise_helper.v_cruise_kph == self.v_cruise_helper.v_cruise_kph_last)
|
||||
@@ -96,7 +96,7 @@ class TestVCruiseHelper(unittest.TestCase):
|
||||
Asserts we don't increment set speed if user presses resume/accel to exit cruise standstill.
|
||||
"""
|
||||
|
||||
self.enable(0)
|
||||
self.enable(0, False)
|
||||
|
||||
for standstill in (True, False):
|
||||
for pressed in (True, False):
|
||||
@@ -116,7 +116,7 @@ class TestVCruiseHelper(unittest.TestCase):
|
||||
|
||||
for v_ego in np.linspace(0, 100, 101):
|
||||
self.reset_cruise_speed_state()
|
||||
self.enable(V_CRUISE_ENABLE_MIN * CV.KPH_TO_MS)
|
||||
self.enable(V_CRUISE_INITIAL * CV.KPH_TO_MS, False)
|
||||
|
||||
# first decrement speed, then perform gas pressed logic
|
||||
expected_v_cruise_kph = self.v_cruise_helper.v_cruise_kph - IMPERIAL_INCREMENT
|
||||
@@ -137,13 +137,14 @@ class TestVCruiseHelper(unittest.TestCase):
|
||||
Asserts allowed cruise speeds on enabling with SET.
|
||||
"""
|
||||
|
||||
for v_ego in np.linspace(0, 100, 101):
|
||||
self.reset_cruise_speed_state()
|
||||
self.assertFalse(self.v_cruise_helper.v_cruise_initialized)
|
||||
for experimental_mode in (True, False):
|
||||
for v_ego in np.linspace(0, 100, 101):
|
||||
self.reset_cruise_speed_state()
|
||||
self.assertFalse(self.v_cruise_helper.v_cruise_initialized)
|
||||
|
||||
self.enable(float(v_ego))
|
||||
self.assertTrue(V_CRUISE_ENABLE_MIN <= self.v_cruise_helper.v_cruise_kph <= V_CRUISE_MAX)
|
||||
self.assertTrue(self.v_cruise_helper.v_cruise_initialized)
|
||||
self.enable(float(v_ego), experimental_mode)
|
||||
self.assertTrue(V_CRUISE_INITIAL <= self.v_cruise_helper.v_cruise_kph <= V_CRUISE_MAX)
|
||||
self.assertTrue(self.v_cruise_helper.v_cruise_initialized)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1 +1 @@
|
||||
a6b17ab903022b42677abe2968f3c6e50c331980
|
||||
fbf92051507b7a7585907b58baadec6b8cc475af
|
||||
|
||||
@@ -382,6 +382,10 @@ void CameraWidget::vipcThread() {
|
||||
}
|
||||
}
|
||||
emit vipcThreadFrameReceived();
|
||||
} else {
|
||||
if (!isVisible()) {
|
||||
vipc_client->connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,6 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
chart->setBackgroundVisible(false);
|
||||
axis_x = new QValueAxis(this);
|
||||
axis_y = new QValueAxis(this);
|
||||
axis_y->setLabelFormat("%.1f");
|
||||
chart->addAxis(axis_x, Qt::AlignBottom);
|
||||
chart->addAxis(axis_y, Qt::AlignLeft);
|
||||
chart->legend()->layout()->setContentsMargins(16, 0, 40, 0);
|
||||
@@ -365,7 +364,7 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
}
|
||||
|
||||
void ChartView::addSeries(const QString &msg_id, const Signal *sig) {
|
||||
QXYSeries *series = createSeries(series_type);
|
||||
QXYSeries *series = createSeries(series_type, getColor(sig));
|
||||
chart()->addSeries(series);
|
||||
series->attachAxis(axis_x);
|
||||
series->attachAxis(axis_y);
|
||||
@@ -519,8 +518,8 @@ void ChartView::updateSeries(const Signal *sig, const std::vector<Event *> *even
|
||||
s.vals.clear();
|
||||
s.vals.reserve(settings.max_cached_minutes * 60 * 100); // [n]seconds * 100hz
|
||||
s.last_value_mono_time = 0;
|
||||
s.series->setColor(getColor(s.sig));
|
||||
}
|
||||
s.series->setColor(getColor(s.sig));
|
||||
|
||||
struct Chunk {
|
||||
std::vector<Event *>::const_iterator first, second;
|
||||
@@ -777,17 +776,22 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) {
|
||||
}
|
||||
}
|
||||
|
||||
QXYSeries *ChartView::createSeries(QAbstractSeries::SeriesType type) {
|
||||
QXYSeries *ChartView::createSeries(QAbstractSeries::SeriesType type, QColor color) {
|
||||
QXYSeries *series = nullptr;
|
||||
if (type == QAbstractSeries::SeriesTypeLine) {
|
||||
series = new QLineSeries(this);
|
||||
} else {
|
||||
series = new QScatterSeries(this);
|
||||
}
|
||||
series->setColor(color);
|
||||
// TODO: Due to a bug in CameraWidget the camera frames
|
||||
// are drawn instead of the graphs on MacOS. Re-enable OpenGL when fixed
|
||||
#ifndef __APPLE__
|
||||
series->setUseOpenGL(true);
|
||||
// Qt doesn't properly apply device pixel ratio in OpenGL mode
|
||||
QPen pen = series->pen();
|
||||
pen.setWidth(2.0 * qApp->devicePixelRatio());
|
||||
series->setPen(pen);
|
||||
#endif
|
||||
return series;
|
||||
}
|
||||
@@ -802,7 +806,7 @@ void ChartView::setSeriesType(QAbstractSeries::SeriesType type) {
|
||||
s.series->deleteLater();
|
||||
}
|
||||
for (auto &s : sigs) {
|
||||
auto series = createSeries(series_type);
|
||||
auto series = createSeries(series_type, getColor(s.sig));
|
||||
chart()->addSeries(series);
|
||||
series->attachAxis(axis_x);
|
||||
series->attachAxis(axis_y);
|
||||
|
||||
@@ -76,7 +76,7 @@ private:
|
||||
void drawForeground(QPainter *painter, const QRectF &rect) override;
|
||||
std::tuple<double, double, int> getNiceAxisNumbers(qreal min, qreal max, int tick_count);
|
||||
qreal niceNumber(qreal x, bool ceiling);
|
||||
QXYSeries *createSeries(QAbstractSeries::SeriesType type);
|
||||
QXYSeries *createSeries(QAbstractSeries::SeriesType type, QColor color);
|
||||
void updateSeriesPoints();
|
||||
|
||||
int y_label_width = 0;
|
||||
|
||||
@@ -13,10 +13,16 @@ void DBCManager::open(const QString &dbc_file_name) {
|
||||
initMsgMap();
|
||||
}
|
||||
|
||||
void DBCManager::open(const QString &name, const QString &content) {
|
||||
std::istringstream stream(content.toStdString());
|
||||
dbc = const_cast<DBC *>(dbc_parse_from_stream(name.toStdString(), stream));
|
||||
initMsgMap();
|
||||
bool DBCManager::open(const QString &name, const QString &content, QString *error) {
|
||||
try {
|
||||
std::istringstream stream(content.toStdString());
|
||||
dbc = const_cast<DBC *>(dbc_parse_from_stream(name.toStdString(), stream));
|
||||
initMsgMap();
|
||||
return true;
|
||||
} catch (std::exception &e) {
|
||||
if (error) *error = e.what();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DBCManager::initMsgMap() {
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
~DBCManager();
|
||||
|
||||
void open(const QString &dbc_file_name);
|
||||
void open(const QString &name, const QString &content);
|
||||
bool open(const QString &name, const QString &content, QString *error = nullptr);
|
||||
QString generateDBC();
|
||||
void addSignal(const QString &id, const Signal &sig);
|
||||
void updateSignal(const QString &id, const QString &sig_name, const Signal &sig);
|
||||
|
||||
@@ -32,7 +32,8 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart
|
||||
time_label = new QLabel(this);
|
||||
time_label->setStyleSheet("font-weight:bold");
|
||||
toolbar->addWidget(time_label);
|
||||
name_label = new QLabel(this);
|
||||
name_label = new ElidedLabel(this);
|
||||
name_label->setContentsMargins(5, 0, 5, 0);
|
||||
name_label->setStyleSheet("font-weight:bold;");
|
||||
name_label->setAlignment(Qt::AlignCenter);
|
||||
name_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QTabWidget>
|
||||
#include <QToolBar>
|
||||
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
#include "tools/cabana/binaryview.h"
|
||||
#include "tools/cabana/chartswidget.h"
|
||||
#include "tools/cabana/historylog.h"
|
||||
@@ -40,7 +41,8 @@ private:
|
||||
void updateState(const QHash<QString, CanData> * msgs = nullptr);
|
||||
|
||||
QString msg_id;
|
||||
QLabel *name_label, *time_label, *warning_icon, *warning_label;
|
||||
QLabel *time_label, *warning_icon, *warning_label;
|
||||
ElidedLabel *name_label;
|
||||
QWidget *warning_widget;
|
||||
QTabBar *tabbar;
|
||||
QTabWidget *tab_widget;
|
||||
|
||||
+18
-6
@@ -220,9 +220,16 @@ void MainWindow::loadFile(const QString &fn) {
|
||||
QFile file(fn);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
auto dbc_name = QFileInfo(fn).baseName();
|
||||
dbc()->open(dbc_name, file.readAll());
|
||||
setCurrentFile(fn);
|
||||
statusBar()->showMessage(tr("DBC File %1 loaded").arg(fn), 2000);
|
||||
QString error;
|
||||
bool ret = dbc()->open(dbc_name, file.readAll(), &error);
|
||||
if (ret) {
|
||||
setCurrentFile(fn);
|
||||
statusBar()->showMessage(tr("DBC File %1 loaded").arg(fn), 2000);
|
||||
} else {
|
||||
QMessageBox msg_box(QMessageBox::Warning, tr("Failed to load DBC file"), tr("Failed to parse DBC file %1").arg(fn));
|
||||
msg_box.setDetailedText(error);
|
||||
msg_box.exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,11 +258,16 @@ void MainWindow::loadDBCFromOpendbc(const QString &name) {
|
||||
void MainWindow::loadDBCFromClipboard() {
|
||||
remindSaveChanges();
|
||||
QString dbc_str = QGuiApplication::clipboard()->text();
|
||||
dbc()->open("from_clipboard.dbc", dbc_str);
|
||||
if (dbc()->messages().size() > 0) {
|
||||
QString error;
|
||||
bool ret = dbc()->open("clipboard", dbc_str, &error);
|
||||
if (ret && dbc()->messages().size() > 0) {
|
||||
QMessageBox::information(this, tr("Load From Clipboard"), tr("DBC Successfully Loaded!"));
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Load From Clipboard"), tr("Failed to parse dbc from clipboard!\nMake sure that you paste the text with correct format."));
|
||||
QMessageBox msg_box(QMessageBox::Warning, tr("Failed to load DBC from clipboard"), tr("Make sure that you paste the text with correct format."));
|
||||
if (!error.isEmpty()) {
|
||||
msg_box.setDetailedText(error);
|
||||
}
|
||||
msg_box.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -182,11 +182,10 @@ void MessageListModel::sortMessages() {
|
||||
|
||||
void MessageListModel::msgsReceived(const QHash<QString, CanData> *new_msgs) {
|
||||
int prev_row_count = msgs.size();
|
||||
bool update_all = new_msgs->size() == can->can_msgs.size();
|
||||
if (update_all || (filter_str.isEmpty() && msgs.size() != can->can_msgs.size())) {
|
||||
if (filter_str.isEmpty() && msgs.size() != can->can_msgs.size()) {
|
||||
msgs = can->can_msgs.keys();
|
||||
}
|
||||
if (update_all || msgs.size() != prev_row_count) {
|
||||
if (msgs.size() != prev_row_count) {
|
||||
sortMessages();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -266,6 +266,7 @@ void SignalModel::handleSignalRemoved(const Signal *sig) {
|
||||
SignalItemDelegate::SignalItemDelegate(QObject *parent) {
|
||||
name_validator = new NameValidator(this);
|
||||
double_validator = new QDoubleValidator(this);
|
||||
small_font.setPointSize(8);
|
||||
double_validator->setLocale(QLocale::C); // Match locale of QString::toDouble() instead of system
|
||||
}
|
||||
|
||||
@@ -280,20 +281,19 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
||||
|
||||
// color label
|
||||
auto bg_color = getColor(item->sig);
|
||||
QRect rc{option.rect.left() + 3, option.rect.top(), 22, option.rect.height()};
|
||||
QRect rc{option.rect.left(), option.rect.top(), 18, option.rect.height()};
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(item->highlight ? bg_color.darker(125) : bg_color);
|
||||
painter->drawRoundedRect(rc.adjusted(0, 2, 0, -2), 5, 5);
|
||||
painter->drawRoundedRect(rc.adjusted(0, 2, 0, -2), 3, 3);
|
||||
painter->setPen(item->highlight ? Qt::white : Qt::black);
|
||||
painter->setFont(small_font);
|
||||
painter->drawText(rc, Qt::AlignCenter, QString::number(item->row() + 1));
|
||||
|
||||
// signal name
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
painter->setFont(font);
|
||||
painter->setFont(option.font);
|
||||
painter->setPen((option.state & QStyle::State_Selected ? option.palette.highlightedText() : option.palette.text()).color());
|
||||
QString text = index.data(Qt::DisplayRole).toString();
|
||||
QRect text_rect = option.rect.adjusted(rc.width() + 9, 0, 0, 0);
|
||||
QRect text_rect = option.rect.adjusted(rc.width() + 6, 0, 0, 0);
|
||||
text = painter->fontMetrics().elidedText(text, Qt::ElideRight, text_rect.width());
|
||||
painter->drawText(text_rect, option.displayAlignment, text);
|
||||
painter->restore();
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QValidator *name_validator, *double_validator;
|
||||
QFont small_font;
|
||||
};
|
||||
|
||||
class SignalView : public QWidget {
|
||||
|
||||
@@ -72,6 +72,7 @@ void AbstractStream::updateLastMsgsTo(double sec) {
|
||||
m.dat = QByteArray((char *)c.getDat().begin(), c.getDat().size());
|
||||
m.colors = QVector<QColor>(m.dat.size(), QColor(0, 0, 0, 0));
|
||||
m.last_change_t = QVector<double>(m.dat.size(), m.ts);
|
||||
m.bit_change_counts.resize(m.dat.size());
|
||||
} else {
|
||||
m.freq = m.count / std::max(1.0, m.ts);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ void ChangeTracker::compute(const QByteArray &dat, double ts, uint32_t freq) {
|
||||
void ChangeTracker::clear() {
|
||||
prev_dat.clear();
|
||||
last_change_t.clear();
|
||||
bit_change_counts.clear();
|
||||
colors.clear();
|
||||
}
|
||||
|
||||
@@ -82,6 +83,12 @@ void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
auto byte_list = opt.text.split(" ");
|
||||
if (byte_list.size() <= 1) {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((option.state & QStyle::State_Selected) && (option.state & QStyle::State_Active)) {
|
||||
painter->setPen(option.palette.color(QPalette::HighlightedText));
|
||||
} else {
|
||||
@@ -98,7 +105,7 @@ void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
|
||||
QList<QVariant> colors = index.data(Qt::UserRole).toList();
|
||||
int i = 0;
|
||||
for (auto &byte : opt.text.split(" ")) {
|
||||
for (auto &byte : byte_list) {
|
||||
if (i < colors.size()) {
|
||||
painter->fillRect(pos.marginsAdded(margins), colors[i].value<QColor>());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
|
||||
@@ -32,6 +32,7 @@ VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent) {
|
||||
// btn controls
|
||||
QHBoxLayout *control_layout = new QHBoxLayout();
|
||||
play_btn = new QPushButton();
|
||||
play_btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
control_layout->addWidget(play_btn);
|
||||
|
||||
QButtonGroup *group = new QButtonGroup(this);
|
||||
|
||||
@@ -86,6 +86,7 @@ function install_ubuntu_lts_latest_requirements() {
|
||||
install_ubuntu_common_requirements
|
||||
|
||||
$SUDO apt-get install -y --no-install-recommends \
|
||||
g++-12 \
|
||||
qtbase5-dev \
|
||||
qtchooser \
|
||||
qt5-qmake \
|
||||
|
||||
Reference in New Issue
Block a user