Skip to content

Commit c49f997

Browse files
authored
Add laikadOffline subtest to process replay. (#24995)
* Add subtests to process replay. Adds laikadOffline subtest * Update cpp. * Update ref * Update ref again * Update ref again * update ref * Fix disabling fetching orbits * Add proc name to event exception * update ref * Update setup_env * Fix offline test and update refs
1 parent ca800da commit c49f997

File tree

4 files changed

+47
-15
lines changed

4 files changed

+47
-15
lines changed

selfdrive/locationd/laikad.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22
import json
3+
import math
34
import os
45
import time
56
from collections import defaultdict
@@ -29,18 +30,20 @@
2930

3031

3132
class Laikad:
32-
def __init__(self, valid_const=("GPS", "GLONASS"), auto_update=False, valid_ephem_types=(EphemerisType.ULTRA_RAPID_ORBIT, EphemerisType.NAV),
33+
def __init__(self, valid_const=("GPS", "GLONASS"), auto_fetch_orbits=True, auto_update=False, valid_ephem_types=(EphemerisType.ULTRA_RAPID_ORBIT, EphemerisType.NAV),
3334
save_ephemeris=False, last_known_position=None):
3435
self.astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types, clear_old_ephemeris=True)
3536
self.gnss_kf = GNSSKalman(GENERATED_DIR, cython=True)
3637

38+
self.auto_fetch_orbits = auto_fetch_orbits
3739
self.orbit_fetch_executor: Optional[ProcessPoolExecutor] = None
3840
self.orbit_fetch_future: Optional[Future] = None
3941

4042
self.last_fetch_orbits_t = None
4143
self.last_cached_t = None
4244
self.save_ephemeris = save_ephemeris
4345
self.load_cache()
46+
4447
self.posfix_functions = {constellation: get_posfix_sympy_fun(constellation) for constellation in (ConstellationId.GPS, ConstellationId.GLONASS)}
4548
self.last_pos_fix = last_known_position if last_known_position is not None else []
4649
self.last_pos_residual = []
@@ -85,7 +88,8 @@ def process_ublox_msg(self, ublox_msg, ublox_mono_time: int, block=False):
8588
report = ublox_msg.measurementReport
8689
if report.gpsWeek > 0:
8790
latest_msg_t = GPSTime(report.gpsWeek, report.rcvTow)
88-
self.fetch_orbits(latest_msg_t + SECS_IN_MIN, block)
91+
if self.auto_fetch_orbits:
92+
self.fetch_orbits(latest_msg_t + SECS_IN_MIN, block)
8993

9094
new_meas = read_raw_ublox(report)
9195
processed_measurements = process_measurements(new_meas, self.astro_dog)
@@ -146,8 +150,8 @@ def update_localizer(self, est_pos, t: float, measurements: List[GNSSMeasurement
146150

147151
def kf_valid(self, t: float) -> List[bool]:
148152
filter_time = self.gnss_kf.filter.get_filter_time()
149-
return [filter_time is not None,
150-
filter_time is not None and abs(t - filter_time) < MAX_TIME_GAP,
153+
return [not math.isnan(filter_time),
154+
abs(t - filter_time) < MAX_TIME_GAP,
151155
all(np.isfinite(self.gnss_kf.x[GStates.ECEF_POS]))]
152156

153157
def init_gnss_localizer(self, est_pos):
@@ -275,7 +279,8 @@ def main(sm=None, pm=None):
275279

276280
replay = "REPLAY" in os.environ
277281
# todo get last_known_position
278-
laikad = Laikad(save_ephemeris=not replay)
282+
use_internet = "LAIKAD_NO_INTERNET" not in os.environ
283+
laikad = Laikad(save_ephemeris=not replay, auto_fetch_orbits=use_internet)
279284
while True:
280285
sm.update()
281286

selfdrive/test/process_replay/process_replay.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
PROC_REPLAY_DIR = os.path.dirname(os.path.abspath(__file__))
2828
FAKEDATA = os.path.join(PROC_REPLAY_DIR, "fakedata/")
2929

30-
ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback', 'tolerance', 'fake_pubsubmaster', 'submaster_config'], defaults=({},))
30+
ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback', 'tolerance', 'fake_pubsubmaster', 'submaster_config', 'environ', 'subtest_name'], defaults=({}, {}, ""))
3131

3232

3333
def wait_for_event(evt):
3434
if not evt.wait(TIMEOUT):
3535
if threading.currentThread().getName() == "MainThread":
3636
# tested process likely died. don't let test just hang
37-
raise Exception("Timeout reached. Tested process likely crashed.")
37+
raise Exception(f"Timeout reached. Tested process {os.environ['PROC_NAME']} likely crashed.")
3838
else:
3939
# done testing this process, let it die
4040
sys.exit(0)
@@ -190,6 +190,7 @@ def get_car_params(msgs, fsm, can_sock, fingerprint):
190190
_, CP = get_car(can, sendcan)
191191
Params().put("CarParams", CP.to_bytes())
192192

193+
193194
def controlsd_rcv_callback(msg, CP, cfg, fsm):
194195
# no sendcan until controlsd is initialized
195196
socks = [s for s in cfg.pub_sub[msg.which()] if
@@ -198,6 +199,7 @@ def controlsd_rcv_callback(msg, CP, cfg, fsm):
198199
socks.remove("sendcan")
199200
return socks, len(socks) > 0
200201

202+
201203
def radar_rcv_callback(msg, CP, cfg, fsm):
202204
if msg.which() != "can":
203205
return [], False
@@ -240,7 +242,7 @@ def laika_rcv_callback(msg, CP, cfg, fsm):
240242
if msg.ubloxGnss.which() == "measurementReport":
241243
return ["gnssMeasurements"], True
242244
else:
243-
return [], False
245+
return [], True
244246

245247

246248
CONFIGS = [
@@ -345,6 +347,19 @@ def laika_rcv_callback(msg, CP, cfg, fsm):
345347
tolerance=None,
346348
fake_pubsubmaster=False,
347349
),
350+
ProcessConfig(
351+
proc_name="laikad",
352+
subtest_name="Offline",
353+
pub_sub={
354+
"ubloxGnss": ["gnssMeasurements"],
355+
},
356+
ignore=["logMonoTime"],
357+
init_callback=get_car_params,
358+
should_recv_callback=laika_rcv_callback,
359+
tolerance=NUMPY_TOLERANCE,
360+
fake_pubsubmaster=True,
361+
environ={"LAIKAD_NO_INTERNET": "1"},
362+
),
348363
ProcessConfig(
349364
proc_name="laikad",
350365
pub_sub={
@@ -366,7 +381,8 @@ def replay_process(cfg, lr, fingerprint=None):
366381
else:
367382
return cpp_replay_process(cfg, lr, fingerprint)
368383

369-
def setup_env(simulation=False, CP=None):
384+
385+
def setup_env(simulation=False, CP=None, cfg=None):
370386
params = Params()
371387
params.clear_all()
372388
params.put_bool("OpenpilotEnabledToggle", True)
@@ -380,6 +396,16 @@ def setup_env(simulation=False, CP=None):
380396
os.environ['SKIP_FW_QUERY'] = ""
381397
os.environ['FINGERPRINT'] = ""
382398

399+
if cfg is not None:
400+
# Clear all custom processConfig environment variables
401+
for cfg in CONFIGS:
402+
for k, _ in cfg.environ.items():
403+
if k in os.environ:
404+
del os.environ[k]
405+
406+
os.environ.update(cfg.environ)
407+
os.environ['PROC_NAME'] = cfg.proc_name
408+
383409
if simulation:
384410
os.environ["SIMULATION"] = "1"
385411
elif "SIMULATION" in os.environ:
@@ -396,6 +422,7 @@ def setup_env(simulation=False, CP=None):
396422
os.environ['SKIP_FW_QUERY'] = "1"
397423
os.environ['FINGERPRINT'] = CP.carFingerprint
398424

425+
399426
def python_replay_process(cfg, lr, fingerprint=None):
400427
sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub]
401428
pub_sockets = [s for s in cfg.pub_sub.keys() if s != 'can']
@@ -413,10 +440,10 @@ def python_replay_process(cfg, lr, fingerprint=None):
413440
if fingerprint is not None:
414441
os.environ['SKIP_FW_QUERY'] = "1"
415442
os.environ['FINGERPRINT'] = fingerprint
416-
setup_env()
443+
setup_env(cfg=cfg)
417444
else:
418445
CP = [m for m in lr if m.which() == 'carParams'][0].carParams
419-
setup_env(CP=CP)
446+
setup_env(CP=CP, cfg=cfg)
420447

421448
assert(type(managed_processes[cfg.proc_name]) is PythonProcess)
422449
managed_processes[cfg.proc_name].prepare()
@@ -477,7 +504,7 @@ def cpp_replay_process(cfg, lr, fingerprint=None):
477504
log_msgs = []
478505

479506
# We need to fake SubMaster alive since we can't inject a fake clock
480-
setup_env(simulation=True)
507+
setup_env(simulation=True, cfg=cfg)
481508

482509
managed_processes[cfg.proc_name].prepare()
483510
managed_processes[cfg.proc_name].start()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a0b5ce7b2e0b9c073e51ac8908402d53e1d99722
1+
a9adebff7ce27d6233d443217a30337b761898ee

selfdrive/test/process_replay/test_processes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,11 @@ def format_diff(results, ref_commit):
200200
if cfg.proc_name not in tested_procs:
201201
continue
202202

203-
cur_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}_{cur_commit}.bz2")
203+
cur_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}{cfg.subtest_name}_{cur_commit}.bz2")
204204
if args.update_refs: # reference logs will not exist if routes were just regenerated
205205
ref_log_path = get_url(*segment.rsplit("--", 1))
206206
else:
207-
ref_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}_{ref_commit}.bz2")
207+
ref_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}{cfg.subtest_name}_{ref_commit}.bz2")
208208
ref_log_path = ref_log_fn if os.path.exists(ref_log_fn) else BASE_URL + os.path.basename(ref_log_fn)
209209

210210
dat = None if args.upload_only else log_data[segment]

0 commit comments

Comments
 (0)