Merge branch 'master' of https://github.com/commaai/openpilot into mqb-long

pull/23257/head
Jason Young 4 years ago
commit 39a8e96679
  1. 2
      scripts/code_stats.py
  2. 2
      scripts/count_cars.py
  3. 23
      selfdrive/athena/registration.py
  4. 11
      selfdrive/athena/tests/test_registration.py
  5. 2
      selfdrive/boardd/panda.cc
  6. 1
      selfdrive/boardd/panda.h
  7. 2
      selfdrive/camerad/snapshot/snapshot.py
  8. 4
      selfdrive/car/honda/values.py
  9. 4
      selfdrive/car/hyundai/hyundaican.py
  10. 2
      selfdrive/car/tests/test_fw_fingerprint.py
  11. 2
      selfdrive/car/toyota/carcontroller.py
  12. 1
      selfdrive/car/toyota/values.py
  13. 7
      selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py
  14. 2
      selfdrive/controls/tests/test_following_distance.py
  15. 2
      selfdrive/debug/cpu_usage_stat.py
  16. 2
      selfdrive/debug/internal/qlog_size.py
  17. 4
      selfdrive/logcatd/tests/test_logcatd_android.py
  18. 4
      selfdrive/loggerd/tests/test_loggerd.py
  19. 2
      selfdrive/manager/build.py
  20. 4
      selfdrive/manager/manager.py
  21. 2
      selfdrive/modeld/SConscript
  22. 2
      selfdrive/monitoring/test_monitoring.py
  23. 6
      selfdrive/test/process_replay/compare_logs.py
  24. 2
      selfdrive/test/process_replay/ref_commit
  25. 2
      selfdrive/test/test_onroad.py
  26. 2
      selfdrive/ui/tests/test_soundd.py
  27. 2
      tools/joystick/joystickd.py

@ -4,7 +4,7 @@ import ast
import stat
import subprocess
fouts = set([x.decode('utf-8') for x in subprocess.check_output(['git', 'ls-files']).strip().split()])
fouts = {x.decode('utf-8') for x in subprocess.check_output(['git', 'ls-files']).strip().split()}
pyf = []
for d in ["cereal", "common", "scripts", "selfdrive", "tools"]:

@ -10,6 +10,6 @@ with open(os.path.join(BASEDIR, "docs/CARS.md")) as f:
cars = [l for l in lines if l.strip().startswith("|") and l.strip().endswith("|") and
"Make" not in l and any(c.isalpha() for c in l)]
make_count = Counter([l.split('|')[1].split('|')[0].strip() for l in cars])
make_count = Counter(l.split('|')[1].split('|')[0].strip() for l in cars)
print("\n", "*"*20, len(cars), "total", "*"*20, "\n")
pprint(make_count)

@ -1,14 +1,13 @@
#!/usr/bin/env python3
import os
#/!/usr/bin/env python3
import time
import json
import jwt
from pathlib import Path
from datetime import datetime, timedelta
from common.api import api_get
from common.params import Params
from common.spinner import Spinner
from common.file_helpers import mkdirs_exists_ok
from common.basedir import PERSIST
from selfdrive.controls.lib.alertmanager import set_offroad_alert
from selfdrive.hardware import HARDWARE
@ -27,19 +26,11 @@ def register(show_spinner=False) -> str:
dongle_id = params.get("DongleId", encoding='utf8')
needs_registration = None in (IMEI, HardwareSerial, dongle_id)
# create a key for auth
# your private key is kept on your device persist partition and never sent to our servers
# do not erase your persist partition
if not os.path.isfile(PERSIST+"/comma/id_rsa.pub"):
needs_registration = True
cloudlog.warning("generating your personal RSA key")
mkdirs_exists_ok(PERSIST+"/comma")
assert os.system("openssl genrsa -out "+PERSIST+"/comma/id_rsa.tmp 2048") == 0
assert os.system("openssl rsa -in "+PERSIST+"/comma/id_rsa.tmp -pubout -out "+PERSIST+"/comma/id_rsa.tmp.pub") == 0
os.rename(PERSIST+"/comma/id_rsa.tmp", PERSIST+"/comma/id_rsa")
os.rename(PERSIST+"/comma/id_rsa.tmp.pub", PERSIST+"/comma/id_rsa.pub")
if needs_registration:
pubkey = Path(PERSIST+"/comma/id_rsa.pub")
if not pubkey.is_file():
dongle_id = UNREGISTERED_DONGLE_ID
cloudlog.warning(f"missing public key: {pubkey}")
elif needs_registration:
if show_spinner:
spinner = Spinner()
spinner.update("registering device")

@ -50,6 +50,14 @@ class TestRegistration(unittest.TestCase):
self.assertEqual(register(), dongle)
self.assertFalse(m.called)
def test_no_keys(self):
# missing pubkey
with mock.patch("selfdrive.athena.registration.api_get", autospec=True) as m:
dongle = register()
self.assertEqual(m.call_count, 0)
self.assertEqual(dongle, UNREGISTERED_DONGLE_ID)
self.assertEqual(self.params.get("DongleId", encoding='utf-8'), dongle)
def test_missing_cache(self):
# keys exist but no dongle id
self._generate_keys()
@ -65,7 +73,8 @@ class TestRegistration(unittest.TestCase):
self.assertEqual(self.params.get("DongleId", encoding='utf-8'), dongle)
def test_unregistered(self):
# no keys, no dongle id
# keys exist, but unregistered
self._generate_keys()
with mock.patch("selfdrive.athena.registration.api_get", autospec=True) as m:
m.return_value = MockResponse(None, 402)
dongle = register()

@ -352,7 +352,7 @@ void Panda::set_data_speed_kbps(uint16_t bus, uint16_t speed) {
usb_write(0xf9, bus, (speed * 10));
}
uint8_t Panda::len_to_dlc(uint8_t len) {
static uint8_t len_to_dlc(uint8_t len) {
if (len <= 8) {
return len;
}

@ -112,7 +112,6 @@ class Panda {
void send_heartbeat();
void set_can_speed_kbps(uint16_t bus, uint16_t speed);
void set_data_speed_kbps(uint16_t bus, uint16_t speed);
uint8_t len_to_dlc(uint8_t len);
void can_send(capnp::List<cereal::CanData>::Reader can_data_list);
bool can_receive(std::vector<can_frame>& out_vec);

@ -37,7 +37,7 @@ def extract_image(buf, w, h, stride):
def rois_in_focus(lapres: List[float]) -> float:
return sum([1. / len(lapres) for sharpness in lapres if sharpness >= LM_THRESH])
return sum(1. / len(lapres) for sharpness in lapres if sharpness >= LM_THRESH)
def get_snapshots(frame="roadCameraState", front_frame="driverCameraState", focus_perc_threshold=0.):

@ -1097,6 +1097,7 @@ FW_VERSIONS = {
b'36161-TG8-A830\x00\x00',
b'36161-TGS-A130\x00\x00',
b'36161-TGT-A030\x00\x00',
b'36161-TGT-A130\x00\x00',
],
(Ecu.srs, 0x18da53f1, None): [
b'77959-TG7-A210\x00\x00',
@ -1112,6 +1113,7 @@ FW_VERSIONS = {
b'78109-TG7-AP10\x00\x00',
b'78109-TG7-AP20\x00\x00',
b'78109-TG7-AS20\x00\x00',
b'78109-TG7-AT20\x00\x00',
b'78109-TG7-AU20\x00\x00',
b'78109-TG7-DJ10\x00\x00',
b'78109-TG7-YK20\x00\x00',
@ -1121,7 +1123,7 @@ FW_VERSIONS = {
b'78109-TGS-AK20\x00\x00',
b'78109-TGS-AP20\x00\x00',
b'78109-TGT-AJ20\x00\x00',
b'78109-TG7-AT20\x00\x00',
b'78109-TGT-AK30\x00\x00',
],
(Ecu.vsa, 0x18da28f1, None): [
b'57114-TG7-A630\x00\x00',

@ -102,7 +102,7 @@ def create_acc_commands(packer, enabled, accel, jerk, idx, lead_visible, set_spe
"CR_VSM_Alive": idx % 0xF,
}
scc12_dat = packer.make_can_msg("SCC12", 0, scc12_values)[2]
scc12_values["CR_VSM_ChkSum"] = 0x10 - sum([sum(divmod(i, 16)) for i in scc12_dat]) % 0x10
scc12_values["CR_VSM_ChkSum"] = 0x10 - sum(sum(divmod(i, 16)) for i in scc12_dat) % 0x10
commands.append(packer.make_can_msg("SCC12", 0, scc12_values))
@ -127,7 +127,7 @@ def create_acc_commands(packer, enabled, accel, jerk, idx, lead_visible, set_spe
"FCA_Status": 1, # AEB disabled
}
fca11_dat = packer.make_can_msg("FCA11", 0, fca11_values)[2]
fca11_values["CR_FCA_ChkSum"] = 0x10 - sum([sum(divmod(i, 16)) for i in fca11_dat]) % 0x10
fca11_values["CR_FCA_ChkSum"] = 0x10 - sum(sum(divmod(i, 16)) for i in fca11_dat) % 0x10
commands.append(packer.make_can_msg("FCA11", 0, fca11_values))
return commands

@ -35,7 +35,7 @@ class TestFwFingerprint(unittest.TestCase):
passed = True
for car_model, ecus in FW_VERSIONS.items():
for ecu, ecu_fw in ecus.items():
duplicates = set([fw for fw in ecu_fw if ecu_fw.count(fw) > 1])
duplicates = {fw for fw in ecu_fw if ecu_fw.count(fw) > 1}
if len(duplicates):
print(car_model, ECU_NAME[ecu[0]], duplicates)
passed = False

@ -28,7 +28,7 @@ class CarController():
# gas and brake
if CS.CP.enableGasInterceptor and enabled:
MAX_INTERCEPTOR_GAS = 0.5
# RAV4 has very sensitive has pedal
# RAV4 has very sensitive gas pedal
if CS.CP.carFingerprint in [CAR.RAV4, CAR.RAV4H, CAR.HIGHLANDER, CAR.HIGHLANDERH]:
PEDAL_SCALE = interp(CS.out.vEgo, [0.0, MIN_ACC_SPEED, MIN_ACC_SPEED + PEDAL_TRANSITION], [0.15, 0.3, 0.0])
elif CS.CP.carFingerprint in [CAR.COROLLA]:

@ -10,7 +10,6 @@ PEDAL_TRANSITION = 10. * CV.MPH_TO_MS
class CarControllerParams:
ACCEL_HYST_GAP = 0.06 # don't change accel command for small oscilalitons within this value
ACCEL_MAX = 1.5 # m/s2, lower than allowed 2.0 m/s2 for tuning reasons
ACCEL_MIN = -3.5 # m/s2

@ -49,16 +49,15 @@ T_IDXS_LST = [index_function(idx, max_val=MAX_T, max_idx=N+1) for idx in range(N
T_IDXS = np.array(T_IDXS_LST)
T_DIFFS = np.diff(T_IDXS, prepend=[0.])
MIN_ACCEL = -3.5
T_REACT = 0.5
T_FOLLOW = 1.45
COMFORT_BRAKE = 2.0
COMFORT_BRAKE = 2.5
STOP_DISTANCE = 6.0
def get_stopped_equivalence_factor(v_lead):
return v_lead**2 / (2 * COMFORT_BRAKE) - (T_FOLLOW - T_REACT) * v_lead
return (v_lead**2) / (2 * COMFORT_BRAKE)
def get_safe_obstacle_distance(v_ego):
return (v_ego*v_ego) / (2 * COMFORT_BRAKE) + T_REACT * v_ego + STOP_DISTANCE
return (v_ego**2) / (2 * COMFORT_BRAKE) + T_FOLLOW * v_ego + STOP_DISTANCE
def desired_follow_distance(v_ego, v_lead):
return get_safe_obstacle_distance(v_ego) - get_stopped_equivalence_factor(v_lead)

@ -29,7 +29,7 @@ class TestFollowingDistance(unittest.TestCase):
simulation_steady_state = run_following_distance_simulation(v_lead)
correct_steady_state = desired_follow_distance(v_lead, v_lead)
self.assertAlmostEqual(simulation_steady_state, correct_steady_state, delta=(correct_steady_state*.1 + 1.0))
self.assertAlmostEqual(simulation_steady_state, correct_steady_state, delta=(correct_steady_state*.1 + .5))
if __name__ == "__main__":

@ -119,5 +119,5 @@ if __name__ == "__main__":
for x in l:
print(x[2])
print('avg sum: {0:.2%} over {1} samples {2} seconds\n'.format(
sum([stat['avg']['total'] for k, stat in stats.items()]), i, i * SLEEP_INTERVAL
sum(stat['avg']['total'] for k, stat in stats.items()), i, i * SLEEP_INTERVAL
))

@ -25,7 +25,7 @@ def make_pie(msgs, typ):
print()
sizes_large = [(k, sz) for (k, sz) in sizes if sz >= total * MIN_SIZE / 100]
sizes_large += [('other', sum([sz for (_, sz) in sizes if sz < total * MIN_SIZE / 100]))]
sizes_large += [('other', sum(sz for (_, sz) in sizes if sz < total * MIN_SIZE / 100))]
labels, sizes = zip(*sizes_large)

@ -22,10 +22,10 @@ class TestLogcatdAndroid(unittest.TestCase):
# write some log messages
sent_msgs = {}
for __ in range(random.randint(5, 50)):
msg = ''.join([random.choice(string.ascii_letters) for _ in range(random.randrange(2, 50))])
msg = ''.join(random.choice(string.ascii_letters) for _ in range(random.randrange(2, 50)))
if msg in sent_msgs:
continue
sent_msgs[msg] = ''.join([random.choice(string.ascii_letters) for _ in range(random.randrange(2, 20))])
sent_msgs[msg] = ''.join(random.choice(string.ascii_letters) for _ in range(random.randrange(2, 20)))
os.system(f"log -t '{sent_msgs[msg]}' '{msg}'")
time.sleep(1)

@ -131,13 +131,13 @@ class TestLoggerd(unittest.TestCase):
route_path = str(self._get_latest_log_dir()).rsplit("--", 1)[0]
for n in range(num_segs):
p = Path(f"{route_path}--{n}")
logged = set([f.name for f in p.iterdir() if f.is_file()])
logged = {f.name for f in p.iterdir() if f.is_file()}
diff = logged ^ expected_files
self.assertEqual(len(diff), 0, f"didn't get all expected files. run={_} seg={n} {route_path=}, {diff=}\n{logged=} {expected_files=}")
def test_bootlog(self):
# generate bootlog with fake launch log
launch_log = ''.join([str(random.choice(string.printable)) for _ in range(100)])
launch_log = ''.join(str(random.choice(string.printable)) for _ in range(100))
with open("/tmp/launch_log", "w") as f:
f.write(launch_log)

@ -77,7 +77,7 @@ def build(spinner, dirty=False):
# Show TextWindow
spinner.close()
if not os.getenv("CI"):
error_s = "\n \n".join(["\n".join(textwrap.wrap(e, 65)) for e in errors])
error_s = "\n \n".join("\n".join(textwrap.wrap(e, 65)) for e in errors)
with TextWindow("openpilot failed to build\n \n" + error_s) as t:
t.wait_for_exit()
exit(1)

@ -154,8 +154,8 @@ def manager_thread():
started_prev = started
running = ' '.join(["%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
for p in managed_processes.values() if p.proc])
running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
for p in managed_processes.values() if p.proc)
print(running)
cloudlog.debug(running)

@ -65,7 +65,7 @@ if use_thneed and arch in ("aarch64", "larch64"):
compiler = lenv.Program('thneed/compile', ["thneed/compile.cc"]+common_model, LIBS=libs)
cmd = f"cd {Dir('.').abspath} && {compiler[0].abspath} ../../models/supercombo.dlc ../../models/supercombo.thneed --binary"
lib_paths = ':'.join([Dir(p).abspath for p in lenv["LIBPATH"]])
lib_paths = ':'.join(Dir(p).abspath for p in lenv["LIBPATH"])
cenv = Environment(ENV={'LD_LIBRARY_PATH': f"{lib_paths}:{lenv['ENV']['LD_LIBRARY_PATH']}"})
cenv.Command("../../models/supercombo.thneed", ["../../models/supercombo.dlc", compiler], cmd)

@ -171,7 +171,7 @@ class TestMonitoring(unittest.TestCase):
# - dm should stay quiet when not engaged
def test_pure_dashcam_user(self):
events, _ = self._run_seq(always_distracted, always_false, always_false, always_false)
self.assertTrue(np.sum([len(event) for event in events]) == 0)
self.assertTrue(sum(len(event) for event in events) == 0)
# engaged, car stops at traffic light, down to orange, no action, then car starts moving
# - should only reach green when stopped, but continues counting down on launch

@ -18,7 +18,7 @@ EPSILON = sys.float_info.epsilon
def save_log(dest, log_msgs, compress=True):
dat = b"".join([msg.as_builder().to_bytes() for msg in tqdm(log_msgs)])
dat = b"".join(msg.as_builder().to_bytes() for msg in tqdm(log_msgs))
if compress:
dat = bz2.compress(dat)
@ -61,8 +61,8 @@ def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=Non
log1, log2 = [list(filter(lambda m: m.which() not in ignore_msgs, log)) for log in (log1, log2)]
if len(log1) != len(log2):
cnt1 = Counter([m.which() for m in log1])
cnt2 = Counter([m.which() for m in log2])
cnt1 = Counter(m.which() for m in log1)
cnt2 = Counter(m.which() for m in log2)
raise Exception(f"logs are not same length: {len(log1)} VS {len(log2)}\n\t\t{cnt1}\n\t\t{cnt2}")
diff = []

@ -1 +1 @@
7ad16d3db047bbcbf91c704e8a52f91e5fc08690
7bcb9e414784d5ca8a4338680421023d07ef9e53

@ -190,7 +190,7 @@ class TestOnroad(unittest.TestCase):
total_size = sum(len(m.as_builder().to_bytes()) for m in msgs)
self.assertLess(total_size, 3.5e5)
cnt = Counter([json.loads(m.logMessage)['filename'] for m in msgs])
cnt = Counter(json.loads(m.logMessage)['filename'] for m in msgs)
big_logs = [f for f, n in cnt.most_common(3) if n / sum(cnt.values()) > 30.]
self.assertEqual(len(big_logs), 0, f"Log spam: {big_logs}")

@ -28,7 +28,7 @@ SOUNDS = {
def get_total_writes():
audio_flinger = subprocess.check_output('dumpsys media.audio_flinger', shell=True, encoding='utf-8').strip()
write_lines = [l for l in audio_flinger.split('\n') if l.strip().startswith('Total writes')]
return sum([int(l.split(':')[1]) for l in write_lines])
return sum(int(l.split(':')[1]) for l in write_lines)
class TestSoundd(unittest.TestCase):
def test_sound_card_init(self):

@ -64,7 +64,7 @@ def joystick_thread(use_keyboard):
dat.testJoystick.axes = [joystick.axes_values[a] for a in joystick.axes_values]
dat.testJoystick.buttons = [joystick.cancel]
joystick_sock.send(dat.to_bytes())
print('\n' + ', '.join([f'{name}: {round(v, 3)}' for name, v in joystick.axes_values.items()]))
print('\n' + ', '.join(f'{name}: {round(v, 3)}' for name, v in joystick.axes_values.items()))
if __name__ == '__main__':

Loading…
Cancel
Save