diff --git a/README.md b/README.md index dec4d00ae..74b90eaaa 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ Supported Cars | Acura | ILX 2016 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | | Acura | ILX 2017 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | | Acura | RDX 2018 | AcuraWatch Plus | Yes | Yes | 25mph1| 12mph | -| GM3 | Volt 2017 | Driver Confidence II | Yes | Yes | 0mph | 7mph | -| GM3 | Volt 2018 | Driver Confidence II | Yes | Yes | 0mph | 7mph | +| GM3 | Volt 2017 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| GM3 | Volt 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | | Honda | Accord 2018 | All | Yes | Stock | 0mph | 3mph | | Honda | Civic 2016 | Honda Sensing | Yes | Yes | 0mph | 12mph | | Honda | Civic 2017 | Honda Sensing | Yes | Yes | 0mph | 12mph | @@ -73,7 +73,7 @@ Supported Cars | Toyota | C-HR 20184 | All | Yes | Stock | 0mph | 0mph | | Toyota | Corolla 2017 | All | Yes | Yes2| 20mph | 0mph | | Toyota | Corolla 2018 | All | Yes | Yes2| 20mph | 0mph | -| Toyota | Highlander 2017 | All | Yes | Yes2| 20mph | 0mph | +| Toyota | Highlander 2017 | All | Yes | Yes2| 0mph | 0mph | | Toyota | Highlander Hybrid 2018| All | Yes | Yes2| 0mph | 0mph | | Toyota | Prius 2016 | TSS-P | Yes | Yes2| 0mph | 0mph | | Toyota | Prius 2017 | All | Yes | Yes2| 0mph | 0mph | diff --git a/RELEASES.md b/RELEASES.md index eae938037..0cc746f32 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2,7 +2,7 @@ Version 0.5.3 (2018-09-03) ======================== * Hyundai Santa Fe support! * Honda Pilot 2019 support thanks to energee! - * Toyota Hyghlander support thanks to daehahn! + * Toyota Highlander support thanks to daehahn! * Improve steering tuning for Honda Odyssey Version 0.5.2 (2018-08-16) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 3625a6b1d..080393230 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -55,7 +55,7 @@ def actuator_hystereses(final_pedal, pedal_steady): class CarController(object): - def __init__(self, canbus, car_fingerprint): + def __init__(self, canbus, car_fingerprint, allow_controls): self.pedal_steady = 0. self.start_time = sec_since_boot() self.chime = 0 @@ -64,6 +64,7 @@ class CarController(object): self.steer_idx = 0 self.apply_steer_last = 0 self.car_fingerprint = car_fingerprint + self.allow_controls = allow_controls # Setup detection helper. Routes commands to # an appropriate CAN bus number. @@ -77,6 +78,10 @@ class CarController(object): hud_v_cruise, hud_show_lanes, hud_show_car, chime, chime_cnt): """ Controls thread """ + # Sanity check. + if not self.allow_controls: + return + P = self.params # Send CAN commands. @@ -137,7 +142,7 @@ class CarController(object): # Send dashboard UI commands (ACC status), 25hz if (frame % 4) == 0: - can_sends.append(gmcan.create_acc_dashboard_command(canbus.powertrain, enabled, hud_v_cruise / CV.MS_TO_KPH, hud_show_car)) + can_sends.append(gmcan.create_acc_dashboard_command(self.packer_pt, canbus.powertrain, enabled, hud_v_cruise * CV.MS_TO_KPH, hud_show_car)) # Radar needs to know current speed and yaw rate (50hz), # and that ADAS is alive (10hz) diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 0c84df422..47b0d8b38 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -84,14 +84,21 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, near_stop, at_f return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values) -def create_acc_dashboard_command(bus, acc_engaged, target_speed_ms, lead_car_in_sight): - engaged = 0x90 if acc_engaged else 0 - lead_car = 0x10 if lead_car_in_sight else 0 - target_speed = int(target_speed_ms * 208) & 0xfff - speed_high = target_speed >> 8 - speed_low = target_speed & 0xff - dat = [0x01, 0x00, engaged | speed_high, speed_low, 0x01, lead_car] - return [0x370, 0, "".join(map(chr, dat)), bus] +def create_acc_dashboard_command(packer, bus, acc_engaged, target_speed_kph, lead_car_in_sight): + # Not a bit shift, dash can round up based on low 4 bits. + target_speed = int(target_speed_kph * 16) & 0xfff + + values = { + "ACCAlwaysOne" : 1, + "ACCResumeButton" : 0, + "ACCSpeedSetpoint" : target_speed, + "ACCGapLevel" : 3 * acc_engaged, # 3 "far", 0 "inactive" + "ACCCmdActive" : acc_engaged, + "ACCAlwaysOne2" : 1, + "ACCLeadCar" : lead_car_in_sight + } + + return packer.make_can_msg("ASCMActiveCruiseControlStatus", bus, values) def create_adas_time_status(bus, tt, idx): dat = [(tt >> 20) & 0xff, (tt >> 12) & 0xff, (tt >> 4) & 0xff, diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index bf39272fc..a9530d65a 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -21,12 +21,6 @@ class CM: LOW_CHIME = 0x86 HIGH_CHIME = 0x87 -# GM cars have 4 CAN buses, which creates many ways -# of how the car can be connected to. -# This ia a helper class for the interface to be setup-agnostic. -# Supports single Panda setup (connected to OBDII port), -# and a CAN forwarding setup (connected to camera module connector). - class CanBus(object): def __init__(self): self.powertrain = 0 @@ -34,6 +28,10 @@ class CanBus(object): self.chassis = 2 self.sw_gmlan = 3 +# 384 = "ASCMLKASteeringCmd" +# 715 = "ASCMGasRegenCmd" +CONTROL_MSGS = [384, 715] + class CarInterface(object): def __init__(self, CP, sendcan=None): self.CP = CP @@ -54,7 +52,7 @@ class CarInterface(object): # sending if read only is False if sendcan is not None: self.sendcan = sendcan - self.CC = CarController(canbus, CP.carFingerprint) + self.CC = CarController(canbus, CP.carFingerprint, CP.enableCamera) @staticmethod def compute_gb(accel, speed): @@ -73,8 +71,11 @@ class CarInterface(object): ret.enableCruise = False - # TODO: gate this on detection - ret.enableCamera = True + # Presence of a camera on the object bus is ok. + # Have to go passive if ASCM is online (ACC-enabled cars), + # or camera is on powertrain bus (LKA cars without ACC). + ret.enableCamera = not any(x for x in CONTROL_MSGS if x in fingerprint) + std_cargo = 136 if candidate == CAR.VOLT: @@ -325,7 +326,11 @@ class CarInterface(object): "chimeRepeated": (CM.LOW_CHIME, -1), "chimeContinuous": (CM.LOW_CHIME, -1)}[str(c.hudControl.audibleAlert)] - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, \ + # For Openpilot, "enabled" includes pre-enable. + # In GM, PCM faults out if ACC command overlaps user gas. + enabled = c.enabled and not self.CS.user_gas_pressed + + self.CC.update(self.sendcan, enabled, self.CS, self.frame, \ c.actuators, hud_v_cruise, c.hudControl.lanesVisible, \ c.hudControl.leadVisible, \ diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index cdee25186..a03235f87 100755 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -159,9 +159,9 @@ class CarInterface(object): # to a negative value, so it won't matter. # hybrid models can't do stop and go even though the stock ACC can't if candidate in [CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.CHR, - CAR.CHRH, CAR.CAMRY, CAR.CAMRYH, CAR.HIGHLANDERH]: + CAR.CHRH, CAR.CAMRY, CAR.CAMRYH, CAR.HIGHLANDERH, CAR.HIGHLANDER]: ret.minEnableSpeed = -1. - elif candidate in [CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.LEXUS_AVE30]: # TODO: hack ICE to do stop and go + elif candidate in [CAR.RAV4, CAR.COROLLA, CAR.LEXUS_AVE30]: # TODO: hack ICE to do stop and go ret.minEnableSpeed = 19. * CV.MPH_TO_MS centerToRear = ret.wheelbase - ret.centerToFront @@ -256,7 +256,7 @@ class CarInterface(object): ret.cruiseState.speed = self.CS.v_cruise_pcm * CV.KPH_TO_MS ret.cruiseState.available = bool(self.CS.main_on) ret.cruiseState.speedOffset = 0. - if self.CP.carFingerprint in [CAR.RAV4H, CAR.HIGHLANDERH]: + if self.CP.carFingerprint in [CAR.RAV4H, CAR.HIGHLANDERH, CAR.HIGHLANDER]: # ignore standstill in hybrid vehicles, since pcm allows to restart without # receiving any special command ret.cruiseState.standstill = False