-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kia and Hyundai Port #309
Kia and Hyundai Port #309
Changes from all commits
0fba33b
b111277
cd25fac
606c21b
577608b
5864323
5ae7119
c2e120c
675d9fe
10cb834
89605ed
e343c95
affc00d
640ab12
f550656
3e49143
88d1dd2
afdda0e
30b72e4
7a62bf0
6f2431e
af723bd
f623414
306db9e
9770e53
14c2d1f
6120df1
2b4b7e4
ca9cae5
d9ae140
04ef0eb
f58f679
d340f87
4830d72
c1a46bb
ee827cf
27c7425
4b0cd28
a874cf4
50ef912
306f0d5
460d821
00f435f
b027e72
a24b151
541a9af
fd73f48
7e427f8
f42d56d
70f7615
9498649
de3b4af
920d532
4ca3e04
8a3c827
71a38b7
cd73d25
17ee07f
9888743
ee81e1c
0ea21f3
e247e93
924a29a
335a56f
3a4da2b
08deeda
c3fcf11
cabe873
0a5e384
0eae9e5
3524c8b
6f6a902
8d4f98f
282e1c1
ad05aab
bcd083a
721ca90
0e42e0c
6faf87c
d85e5d9
69d3ca5
9578c2c
7e9eefe
342121d
8867ba3
9d8af80
6348878
71f3744
a7ac59d
da5c204
ed3fe0c
6a77630
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Kia Hyundai Safety | ||
|
||
static int hyundai_ign_hook() { | ||
return true; | ||
} | ||
static void hyundai_init(int16_t param) { | ||
controls_allowed = 1; | ||
} | ||
|
||
static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { | ||
// Steering Value Safety Check | ||
|
||
return true; | ||
} | ||
|
||
static int hyundai_tx_lin_hook(int lin_num, uint8_t *data, int len) { | ||
return true; | ||
} | ||
|
||
static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { | ||
return -1; | ||
} | ||
|
||
const safety_hooks hyundai_hooks = { | ||
.init = hyundai_init, | ||
.rx = default_rx_hook, | ||
.tx = hyundai_tx_hook, | ||
.tx_lin = hyundai_tx_lin_hook, | ||
.ignition = hyundai_ign_hook, | ||
.fwd = hyundai_fwd_hook, | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#/bin/sh | ||
PYTHONPATH=/data/openpilot PREPAREONLY=1 /data/openpilot/selfdrive/controls/controlsd.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from selfdrive.car.hyundai.values import CAR, DBC | ||
from selfdrive.can.parser import CANParser | ||
from selfdrive.config import Conversions as CV | ||
|
||
def get_can_parser2(CP): | ||
|
||
signals = [ | ||
("Byte0", "LKAS11", 0), | ||
("Byte1", "LKAS11", 0), | ||
("Byte2", "LKAS11", 0), | ||
("Byte3", "LKAS11", 0), | ||
("Byte4", "LKAS11", 0), | ||
("Byte5", "LKAS11", 0), | ||
("Byte6", "LKAS11", 0), # Checksum | ||
("Byte7", "LKAS11", 0), | ||
|
||
("Byte0", "LKAS12", 0), | ||
("Byte1", "LKAS12", 0), | ||
("Byte2", "LKAS12", 0), | ||
("Byte3", "LKAS12", 0), | ||
("Byte4", "LKAS12", 0), | ||
("Byte5", "LKAS12", 0) | ||
] | ||
|
||
checks = [ | ||
("LKAS11", 100), # LKAS11 = 100Hz | ||
("LKAS12", 10) # LKAS12 = 10Hz | ||
] | ||
|
||
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 1) | ||
|
||
|
||
class CamState(object): | ||
def __init__(self, CP): | ||
self.CP = CP | ||
|
||
# initialize can parser | ||
self.car_fingerprint = CP.carFingerprint | ||
|
||
|
||
def update(self, cp): | ||
# copy can_valid | ||
self.can_valid = cp.can_valid | ||
|
||
# LKAS11 From Camera | ||
self.lkas11_b0 = int(cp.vl["LKAS11"]['Byte0']) | ||
self.lkas11_b1 = int(cp.vl["LKAS11"]['Byte1']) | ||
self.lkas11_b2 = int(cp.vl["LKAS11"]['Byte2']) | ||
self.lkas11_b3 = int(cp.vl["LKAS11"]['Byte3']) | ||
self.lkas11_b4 = int(cp.vl["LKAS11"]['Byte4']) | ||
self.lkas11_b5 = int(cp.vl["LKAS11"]['Byte5']) | ||
self.lkas11_b6 = int(cp.vl["LKAS11"]['Byte6']) | ||
self.lkas11_b7 = int(cp.vl["LKAS11"]['Byte7']) | ||
|
||
# LKAS10 From Camera | ||
self.lkas12_b0 = int(cp.vl["LKAS12"]['Byte0']) | ||
self.lkas12_b1 = int(cp.vl["LKAS12"]['Byte1']) | ||
self.lkas12_b2 = int(cp.vl["LKAS12"]['Byte2']) | ||
self.lkas12_b3 = int(cp.vl["LKAS12"]['Byte3']) | ||
self.lkas12_b4 = int(cp.vl["LKAS12"]['Byte4']) | ||
self.lkas12_b5 = int(cp.vl["LKAS12"]['Byte5']) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
from common.numpy_fast import clip, interp | ||
from selfdrive.boardd.boardd import can_list_to_can_capnp | ||
from selfdrive.car.hyundai.hyundaican import make_can_msg, create_lkas11, create_lkas12b | ||
from selfdrive.car.hyundai.values import ECU, STATIC_MSGS, CAR | ||
from selfdrive.can.packer import CANPacker | ||
|
||
|
||
# Steer torque limits | ||
STEER_MAX = 200 # Actual limit is about 1023, but not tested, and not needed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so, I assume 1023 is absurdly high? would be nice to add the 200 limit so the safety_hyundai.h in panda as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be safe to push it to 250, but it is VERY strong, any more would be unsafe. The large amount of power it has is why I later reduce the output torque when the driver starts steering. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then I definitely recommend to add the 200 limit panda safety. |
||
STEER_DELTA = 5 # We have no Panda Safety, don't be silly here! Good idea, YOU add Panda Safety! | ||
|
||
|
||
TARGET_IDS = [0x340] | ||
|
||
|
||
class CarController(object): | ||
def __init__(self, dbc_name, car_fingerprint, enable_camera): | ||
self.braking = False | ||
self.controls_allowed = True | ||
self.last_steer = 0 | ||
self.car_fingerprint = car_fingerprint | ||
self.angle_control = False | ||
self.idx = 0 | ||
self.lkas_request = 0 | ||
self.lanes = 0 | ||
self.steer_angle_enabled = False | ||
self.ipas_reset_counter = 0 | ||
self.turning_inhibit = 0 | ||
self.limited_steer = 0 | ||
self.hide_lkas_fault = 100 | ||
print self.car_fingerprint | ||
|
||
self.fake_ecus = set() | ||
if enable_camera: self.fake_ecus.add(ECU.CAM) | ||
self.packer = CANPacker(dbc_name) | ||
|
||
def update(self, sendcan, enabled, CS, frame, actuators, CamS): | ||
# When the driver starts inputting torque, reduce the requested torque | ||
# We do not want to remove torque because we want to know if OP is still steering | ||
# And how we do it, meh, who cares, this might do. | ||
if abs(CS.steer_torque_driver) > 1: | ||
self.limited_steer = actuators.steer / (abs(CS.steer_torque_driver) * 2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mmm... this causes a torque jump as soon as Maybe you can have a look how this is done for GM. You can see how the driver torque is taken into account to limit the commanded torque. Would be nice to re-use the same logic, just different parameters, which will make writing safety code in panda a lot easier. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GM looks nice, I will implement that. This never used to have * 2, so there was no jump, but later... hack.. |
||
else: | ||
self.limited_steer = actuators.steer | ||
|
||
# Steering Torque Scaling is to STEER_MAX, + 1024 for center | ||
apply_steer = int(round((self.limited_steer * STEER_MAX) + 1024)) | ||
|
||
# This is redundant clipping code, kept in case it needs to be advanced | ||
max_lim = 1024 + STEER_MAX | ||
min_lim = 1024 - STEER_MAX | ||
apply_steer = clip(apply_steer, min_lim, max_lim) | ||
|
||
# Very basic Rate Limiting | ||
# TODO: Revisit this | ||
if (apply_steer - self.last_steer) > STEER_DELTA: | ||
apply_steer = self.last_steer + STEER_DELTA | ||
elif (self.last_steer - apply_steer) > STEER_DELTA: | ||
apply_steer = self.last_steer - STEER_DELTA | ||
|
||
|
||
# Inhibits *outside of* alerts | ||
# Because the Turning Indicator Status is based on Lights and not Stalk, latching is | ||
# needed for the disable to work. | ||
if CS.left_blinker_on == 1 or CS.right_blinker_on == 1: | ||
self.turning_inhibit = 180 # Disable for 1.8 Seconds after blinker turned off | ||
|
||
if self.turning_inhibit > 0: | ||
self.turning_inhibit = self.turning_inhibit - 1 | ||
|
||
if not enabled or self.turning_inhibit > 0: | ||
apply_steer = 1024 # 1024 is midpoint (no steer) | ||
self.last_steer = 1024 # Reset Last Steer | ||
else: | ||
self.lanes = 3 * 4 # bit 0 = Right Lane, bit 1 = Left Lane, Offset by 2 bits in byte. | ||
|
||
self.last_steer = apply_steer | ||
|
||
can_sends = [] | ||
|
||
# Index is 4 bits long, this is the counter | ||
self.idx = self.idx + 1 | ||
if self.idx >= 16: | ||
self.idx = 0 | ||
|
||
# Byte 4 is used for Index and HBA | ||
# We generate the Index, but pass through HBA | ||
lkas11_byte4 = self.idx * 16 | ||
|
||
# Split apply steer Word into 2 Bytes | ||
apply_steer_a = apply_steer & 0xFF | ||
apply_steer_b = (apply_steer >> 8) & 0xFF | ||
|
||
|
||
# If Request to Steer is anything but 0 torque, turn on ActToi | ||
if apply_steer != 1024: | ||
apply_steer_b = apply_steer_b + 0x08 | ||
|
||
|
||
if enabled: | ||
# When we send Torque signals that the camera does not expet, it faults. | ||
# This masks the fault for 750ms after bringing stock back on. | ||
# This does NOT mean that the factory system will be enabled, it will still be off. | ||
# This was tested at 500ms, and 1 in 10 disables, a fault was still seen. | ||
self.hide_lkas_fault = 75 | ||
|
||
# Generate the 7 bytes as needed for OP Control. | ||
# Anything we don't generate, pass through from camera | ||
lkas11_byte0 = int(self.lanes) + (CamS.lkas11_b0 & 0xC3) | ||
lkas11_byte1 = CamS.lkas11_b1 | ||
lkas11_byte2 = apply_steer_a | ||
lkas11_byte3 = apply_steer_b + (CamS.lkas11_b3 & 0xE0) # ToiFlt always comes on, don't pass it | ||
lkas11_byte4 = lkas11_byte4 + (CamS.lkas11_b4 & 0x0F) # Always use our counter | ||
lkas11_byte5 = CamS.lkas11_b5 | ||
lkas11_byte7 = CamS.lkas11_b7 | ||
else: | ||
# Pass Through the 7 bytes so that Factory LKAS is in control | ||
# We still use our counter, because otherwise duplicates and missed messages from the camera | ||
# is possible due to the implementation method. As such, we recreate the checksum as well | ||
# Byte 0 defined below due to Fault Masking | ||
lkas11_byte1 = CamS.lkas11_b1 | ||
lkas11_byte2 = CamS.lkas11_b2 | ||
# Byte 3 defined below due to Fault Masking | ||
lkas11_byte4 = lkas11_byte4 + (CamS.lkas11_b4 & 0x0F) # Always use our counter | ||
lkas11_byte5 = CamS.lkas11_b5 | ||
lkas11_byte7 = CamS.lkas11_b7 | ||
# This is the Fault Masking needed in byte 0 and byte 3 | ||
if self.hide_lkas_fault > 0: | ||
lkas11_byte0 = int(self.lanes) + (CamS.lkas11_b0 & 0xC3) | ||
lkas11_byte3 = CamS.lkas11_b3 & 0xE7 | ||
self.hide_lkas_fault = self.hide_lkas_fault - 1 | ||
else: | ||
lkas11_byte0 = CamS.lkas11_b0 | ||
lkas11_byte3 = CamS.lkas11_b3 | ||
|
||
|
||
|
||
# Create Checksum | ||
# Sorento checksum is Byte 0 to 5 | ||
# Other models appear to be Byte 0 to Byte 5 as well as Byte 7 | ||
if CS.car_fingerprint == CAR.SORENTO: | ||
# 6 Byte Checksum | ||
checksum = (lkas11_byte0 + lkas11_byte1 + lkas11_byte2 + lkas11_byte3 + \ | ||
lkas11_byte4 + lkas11_byte5) % 256 | ||
else: | ||
# 7 Byte Checksum | ||
checksum = (lkas11_byte0 + lkas11_byte1 + lkas11_byte2 + lkas11_byte3 + \ | ||
lkas11_byte4 + lkas11_byte5 + lkas11_byte7) % 256 | ||
|
||
|
||
|
||
# Create LKAS11 Message at 100Hz | ||
can_sends.append(create_lkas11(self.packer, lkas11_byte0, \ | ||
lkas11_byte1, lkas11_byte2, lkas11_byte3, lkas11_byte4, \ | ||
lkas11_byte5, checksum, lkas11_byte7)) | ||
|
||
|
||
|
||
# Create LKAS12 Message at 10Hz | ||
if (frame % 10) == 0: | ||
can_sends.append(create_lkas12b(self.packer, CamS.lkas12_b0, CamS.lkas12_b1, \ | ||
CamS.lkas12_b2, CamS.lkas12_b3, CamS.lkas12_b4, CamS.lkas12_b5)) | ||
|
||
|
||
|
||
# Limit Terminal Debugging to 5Hz | ||
if (frame % 20) == 0: | ||
print "controlsdDebug steer", actuators.steer, "strToq", CS.steer_torque_driver, "lim steer", self.limited_steer, "v_ego", \ | ||
CS.v_ego, "strAng", CS.angle_steers | ||
|
||
|
||
|
||
# Send messages to canbus | ||
sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is only because Toyota Camera takes a while to start sending msgs. Is this really needed for hyundai?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most likely not, an artefact because this was based off Toyota.
I will kill it and update it if all okay.