segment regen (#21148)
* start seg regen
* send vipc
* fix up some paths
* set fp
* fix no entries
* engages
* seperate camera procs
* send real frames
* regen test routes
* nice argparser
* fix valgrind test
* move that
* fix that
old-commit-hash: 4a1aec27ef
commatwo_master
parent
2c3d136d32
commit
d31397b84b
13 changed files with 222 additions and 161 deletions
@ -0,0 +1 @@ |
|||||||
|
fakedata/ |
@ -1,83 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
|
|
||||||
import time |
|
||||||
|
|
||||||
from tqdm import tqdm |
|
||||||
|
|
||||||
from selfdrive.manager.process_config import managed_processes |
|
||||||
from cereal.messaging import PubMaster, recv_one, sub_sock |
|
||||||
from tools.lib.framereader import FrameReader |
|
||||||
|
|
||||||
|
|
||||||
def rreplace(s, old, new, occurrence): |
|
||||||
li = s.rsplit(old, occurrence) |
|
||||||
return new.join(li) |
|
||||||
|
|
||||||
|
|
||||||
def regen_model(msgs, pm, frame_reader, model_sock): |
|
||||||
# Send some livecalibration messages to initalize visiond |
|
||||||
for msg in msgs: |
|
||||||
if msg.which() == 'liveCalibration': |
|
||||||
pm.send('liveCalibration', msg.as_builder()) |
|
||||||
|
|
||||||
out_msgs = [] |
|
||||||
fidx = 0 |
|
||||||
for msg in tqdm(msgs): |
|
||||||
w = msg.which() |
|
||||||
|
|
||||||
if w == 'roadCameraState': |
|
||||||
msg = msg.as_builder() |
|
||||||
|
|
||||||
img = frame_reader.get(fidx, pix_fmt="rgb24")[0][:,:,::-1] |
|
||||||
|
|
||||||
msg.roadCameraState.image = img.flatten().tobytes() |
|
||||||
|
|
||||||
pm.send(w, msg) |
|
||||||
model = recv_one(model_sock) |
|
||||||
fidx += 1 |
|
||||||
out_msgs.append(model) |
|
||||||
elif w == 'liveCalibration': |
|
||||||
pm.send(w, msg.as_builder()) |
|
||||||
|
|
||||||
return out_msgs |
|
||||||
|
|
||||||
|
|
||||||
def inject_model(msgs, segment_name): |
|
||||||
if segment_name.count('--') == 2: |
|
||||||
segment_name = rreplace(segment_name, '--', '/', 1) |
|
||||||
frame_reader = FrameReader('cd:/'+segment_name.replace("|", "/") + "/fcamera.hevc") |
|
||||||
|
|
||||||
managed_processes['camerad'].start() |
|
||||||
managed_processes['modeld'].start() |
|
||||||
# TODO do better than just wait for modeld to boot |
|
||||||
time.sleep(5) |
|
||||||
|
|
||||||
pm = PubMaster(['liveCalibration', 'roadCameraState']) |
|
||||||
model_sock = sub_sock('model') |
|
||||||
try: |
|
||||||
out_msgs = regen_model(msgs, pm, frame_reader, model_sock) |
|
||||||
except (KeyboardInterrupt, SystemExit, Exception) as e: |
|
||||||
managed_processes['modeld'].stop() |
|
||||||
time.sleep(2) |
|
||||||
managed_processes['camerad'].stop() |
|
||||||
raise e |
|
||||||
managed_processes['modeld'].stop() |
|
||||||
time.sleep(2) |
|
||||||
managed_processes['camerad'].stop() |
|
||||||
|
|
||||||
new_msgs = [] |
|
||||||
midx = 0 |
|
||||||
for msg in msgs: |
|
||||||
if (msg.which() == 'model') and (midx < len(out_msgs)): |
|
||||||
model = out_msgs[midx].as_builder() |
|
||||||
model.logMonoTime = msg.logMonoTime |
|
||||||
model = model.as_reader() |
|
||||||
new_msgs.append(model) |
|
||||||
midx += 1 |
|
||||||
else: |
|
||||||
new_msgs.append(msg) |
|
||||||
|
|
||||||
print(len(new_msgs), len(list(msgs))) |
|
||||||
assert abs(len(new_msgs) - len(list(msgs))) < 2 |
|
||||||
|
|
||||||
return new_msgs |
|
@ -0,0 +1,184 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import argparse |
||||||
|
import os |
||||||
|
import time |
||||||
|
import multiprocessing |
||||||
|
from tqdm import tqdm |
||||||
|
|
||||||
|
# run DM procs |
||||||
|
os.environ["USE_WEBCAM"] = "1" |
||||||
|
|
||||||
|
import cereal.messaging as messaging |
||||||
|
from cereal.services import service_list |
||||||
|
from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error |
||||||
|
from common.params import Params |
||||||
|
from common.realtime import Ratekeeper, DT_MDL, DT_DMON |
||||||
|
from common.transformations.camera import eon_f_frame_size, eon_d_frame_size |
||||||
|
from selfdrive.car.fingerprints import FW_VERSIONS |
||||||
|
from selfdrive.manager.process import ensure_running |
||||||
|
from selfdrive.manager.process_config import managed_processes |
||||||
|
from selfdrive.test.update_ci_routes import upload_route |
||||||
|
from tools.lib.route import Route |
||||||
|
from tools.lib.framereader import FrameReader |
||||||
|
from tools.lib.logreader import LogReader |
||||||
|
|
||||||
|
|
||||||
|
process_replay_dir = os.path.dirname(os.path.abspath(__file__)) |
||||||
|
FAKEDATA = os.path.join(process_replay_dir, "fakedata/") |
||||||
|
|
||||||
|
|
||||||
|
def replay_service(s, msgs): |
||||||
|
pm = messaging.PubMaster([s, ]) |
||||||
|
rk = Ratekeeper(service_list[s].frequency, print_delay_threshold=None) |
||||||
|
smsgs = [m for m in msgs if m.which() == s] |
||||||
|
for m in smsgs: |
||||||
|
pm.send(s, m.as_builder()) |
||||||
|
rk.keep_time() |
||||||
|
|
||||||
|
vs = None |
||||||
|
def replay_cameras(lr, frs): |
||||||
|
cameras = [ |
||||||
|
("roadCameraState", DT_MDL, eon_f_frame_size, VisionStreamType.VISION_STREAM_YUV_BACK), |
||||||
|
("driverCameraState", DT_DMON, eon_d_frame_size, VisionStreamType.VISION_STREAM_YUV_FRONT), |
||||||
|
] |
||||||
|
|
||||||
|
def replay_camera(s, stream, dt, vipc_server, fr, size): |
||||||
|
pm = messaging.PubMaster([s, ]) |
||||||
|
rk = Ratekeeper(1 / dt, print_delay_threshold=None) |
||||||
|
|
||||||
|
img = b"\x00" * int(size[0]*size[1]*3/2) |
||||||
|
while True: |
||||||
|
if fr is not None and False: |
||||||
|
img = fr.get(rk.frame % fr.frame_count, pix_fmt='yuv420p')[0] |
||||||
|
img = img.flatten().tobytes() |
||||||
|
print("got img") |
||||||
|
|
||||||
|
rk.keep_time() |
||||||
|
|
||||||
|
m = messaging.new_message(s) |
||||||
|
msg = getattr(m, s) |
||||||
|
msg.frameId = rk.frame |
||||||
|
pm.send(s, m) |
||||||
|
|
||||||
|
vipc_server.send(stream, img, msg.frameId, msg.timestampSof, msg.timestampEof) |
||||||
|
|
||||||
|
# init vipc server and cameras |
||||||
|
p = [] |
||||||
|
global vs |
||||||
|
vs = VisionIpcServer("camerad") |
||||||
|
for (s, dt, size, stream) in cameras: |
||||||
|
fr = frs.get(s, None) |
||||||
|
vs.create_buffers(stream, 40, False, size[0], size[1]) |
||||||
|
p.append(multiprocessing.Process(target=replay_camera, |
||||||
|
args=(s, stream, dt, vs, fr, size))) |
||||||
|
|
||||||
|
# hack to make UI work |
||||||
|
vs.create_buffers(VisionStreamType.VISION_STREAM_RGB_BACK, 4, True, eon_f_frame_size[0], eon_f_frame_size[1]) |
||||||
|
vs.start_listener() |
||||||
|
return p |
||||||
|
|
||||||
|
|
||||||
|
def regen_segment(lr, frs=None, outdir=FAKEDATA): |
||||||
|
|
||||||
|
lr = list(lr) |
||||||
|
if frs is None: |
||||||
|
frs = dict() |
||||||
|
|
||||||
|
# setup env |
||||||
|
params = Params() |
||||||
|
params.clear_all() |
||||||
|
params.put_bool("Passive", False) |
||||||
|
params.put_bool("OpenpilotEnabledToggle", True) |
||||||
|
params.put_bool("CommunityFeaturesToggle", True) |
||||||
|
params.put_bool("CommunityFeaturesToggle", True) |
||||||
|
cal = messaging.new_message('liveCalibration') |
||||||
|
cal.liveCalibration.validBlocks = 20 |
||||||
|
cal.liveCalibration.rpyCalib = [0.0, 0.0, 0.0] |
||||||
|
params.put("CalibrationParams", cal.to_bytes()) |
||||||
|
|
||||||
|
os.environ["LOG_ROOT"] = outdir |
||||||
|
os.environ["SIMULATION"] = "1" |
||||||
|
|
||||||
|
os.environ['SKIP_FW_QUERY'] = "" |
||||||
|
os.environ['FINGERPRINT'] = "" |
||||||
|
for msg in lr: |
||||||
|
if msg.which() == 'carParams': |
||||||
|
car_fingerprint = msg.carParams.carFingerprint |
||||||
|
if len(msg.carParams.carFw) and (car_fingerprint in FW_VERSIONS): |
||||||
|
params.put("CarParamsCache", msg.carParams.as_builder().to_bytes()) |
||||||
|
else: |
||||||
|
os.environ['SKIP_FW_QUERY'] = "1" |
||||||
|
os.environ['FINGERPRINT'] = car_fingerprint |
||||||
|
|
||||||
|
fake_daemons = { |
||||||
|
'sensord': [ |
||||||
|
multiprocessing.Process(target=replay_service, args=('sensorEvents', lr)), |
||||||
|
], |
||||||
|
'pandad': [ |
||||||
|
multiprocessing.Process(target=replay_service, args=('can', lr)), |
||||||
|
multiprocessing.Process(target=replay_service, args=('pandaState', lr)), |
||||||
|
], |
||||||
|
#'managerState': [ |
||||||
|
# multiprocessing.Process(target=replay_service, args=('managerState', lr)), |
||||||
|
#], |
||||||
|
'thermald': [ |
||||||
|
multiprocessing.Process(target=replay_service, args=('deviceState', lr)), |
||||||
|
], |
||||||
|
'camerad': [ |
||||||
|
*replay_cameras(lr, frs), |
||||||
|
], |
||||||
|
|
||||||
|
# TODO: fix these and run them |
||||||
|
'paramsd': [ |
||||||
|
multiprocessing.Process(target=replay_service, args=('liveParameters', lr)), |
||||||
|
], |
||||||
|
'locationd': [ |
||||||
|
multiprocessing.Process(target=replay_service, args=('liveLocationKalman', lr)), |
||||||
|
], |
||||||
|
} |
||||||
|
|
||||||
|
try: |
||||||
|
# start procs up |
||||||
|
ignore = list(fake_daemons.keys()) + ['ui', 'manage_athenad', 'uploader'] |
||||||
|
ensure_running(managed_processes.values(), started=True, not_run=ignore) |
||||||
|
for procs in fake_daemons.values(): |
||||||
|
for p in procs: |
||||||
|
p.start() |
||||||
|
|
||||||
|
for _ in tqdm(range(60)): |
||||||
|
# ensure all procs are running |
||||||
|
for d, procs in fake_daemons.items(): |
||||||
|
for p in procs: |
||||||
|
if not p.is_alive(): |
||||||
|
raise Exception(f"{d}'s {p.name} died") |
||||||
|
time.sleep(1) |
||||||
|
finally: |
||||||
|
# kill everything |
||||||
|
for p in managed_processes.values(): |
||||||
|
p.stop() |
||||||
|
for procs in fake_daemons.values(): |
||||||
|
for p in procs: |
||||||
|
p.terminate() |
||||||
|
|
||||||
|
r = params.get("CurrentRoute", encoding='utf-8') |
||||||
|
return os.path.join(outdir, r + "--0") |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Generate new segments from old ones") |
||||||
|
parser.add_argument("--upload", action="store_true", help="Upload the new segment to the CI bucket") |
||||||
|
parser.add_argument("route", type=str, help="The source route") |
||||||
|
parser.add_argument("seg", type=int, help="Segment in source route") |
||||||
|
args = parser.parse_args() |
||||||
|
|
||||||
|
r = Route(args.route) |
||||||
|
lr = LogReader(r.log_paths()[args.seg]) |
||||||
|
fr = FrameReader(r.camera_paths()[args.seg]) |
||||||
|
rpath = regen_segment(lr, {'roadCameraState': fr}) |
||||||
|
relr = os.path.relpath(rpath) |
||||||
|
|
||||||
|
print("\n\n", "*"*30, "\n\n") |
||||||
|
print("New route:", relr, "\n") |
||||||
|
if args.upload: |
||||||
|
upload_route(relr) |
||||||
|
|
@ -1,47 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
import os |
|
||||||
import sys |
|
||||||
|
|
||||||
from selfdrive.test.openpilotci import upload_file |
|
||||||
from selfdrive.test.process_replay.compare_logs import save_log |
|
||||||
from selfdrive.test.process_replay.test_processes import segments, get_segment |
|
||||||
from selfdrive.version import get_git_commit |
|
||||||
from tools.lib.logreader import LogReader |
|
||||||
from selfdrive.test.process_replay.inject_model import inject_model |
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
|
|
||||||
no_upload = "--no-upload" in sys.argv |
|
||||||
|
|
||||||
process_replay_dir = os.path.dirname(os.path.abspath(__file__)) |
|
||||||
ref_commit_fn = os.path.join(process_replay_dir, "model_ref_commit") |
|
||||||
|
|
||||||
ref_commit = get_git_commit() |
|
||||||
if ref_commit is None: |
|
||||||
raise Exception("couldn't get ref commit") |
|
||||||
with open(ref_commit_fn, "w") as f: |
|
||||||
f.write(ref_commit) |
|
||||||
|
|
||||||
for car_brand, segment in segments: |
|
||||||
rlog_fn = get_segment(segment, original=True) |
|
||||||
|
|
||||||
if rlog_fn is None: |
|
||||||
print("failed to get segment %s" % segment) |
|
||||||
sys.exit(1) |
|
||||||
|
|
||||||
lr = LogReader(rlog_fn) |
|
||||||
print('injecting model into % s' % segment) |
|
||||||
lr = inject_model(lr, segment) |
|
||||||
|
|
||||||
route_name, segment_num = segment.rsplit("--", 1) |
|
||||||
log_fn = "%s/%s/rlog_%s.bz2" % (route_name.replace("|", "/"), segment_num, ref_commit) |
|
||||||
tmp_name = 'tmp_%s_%s' % (route_name, segment_num) |
|
||||||
save_log(tmp_name, lr) |
|
||||||
|
|
||||||
if not no_upload: |
|
||||||
upload_file(tmp_name, log_fn) |
|
||||||
print('uploaded %s', log_fn) |
|
||||||
os.remove(tmp_name) |
|
||||||
os.remove(rlog_fn) |
|
||||||
|
|
||||||
print("done") |
|
Loading…
Reference in new issue