openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
4.3 KiB

#!/usr/bin/env python3
import os
import argparse
import time
import capnp
from typing import Union, Iterable, Optional, List, Any, Dict, Tuple
from selfdrive.test.process_replay.process_replay import CONFIGS, FAKEDATA, replay_process, get_process_config, check_openpilot_enabled, get_custom_params_from_lr
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
from tools.lib.helpers import save_log
def regen_segment(
lr: Union[LogReader, List[capnp._DynamicStructReader]], frs: Optional[Dict[str, Any]] = None,
daemons: Union[str, Iterable[str]] = "all", disable_tqdm: bool = False
) -> List[capnp._DynamicStructReader]:
if not isinstance(daemons, str) and not hasattr(daemons, "__iter__"):
raise ValueError("whitelist_proc must be a string or iterable")
all_msgs = sorted(lr, key=lambda m: m.logMonoTime)
custom_params = get_custom_params_from_lr(all_msgs)
if daemons != "all":
if isinstance(daemons, str):
raise ValueError(f"Invalid value for daemons: {daemons}")
replayed_processes = []
for d in daemons:
cfg = get_process_config(d)
replayed_processes.append(cfg)
else:
replayed_processes = CONFIGS
print("Replayed processes:", [p.proc_name for p in replayed_processes])
print("\n\n", "*"*30, "\n\n", sep="")
output_logs = replay_process(replayed_processes, all_msgs, frs, return_all_logs=True, custom_params=custom_params, disable_progress=disable_tqdm)
return output_logs
def setup_data_readers(route: str, sidx: int, use_route_meta: bool) -> Tuple[LogReader, Dict[str, Any]]:
if use_route_meta:
Live torque (#25456) * wip torqued * add basic logic * setup in manager * check sanity and publish msg * add first order filter to outputs * wire up controlsd, and update gains * rename intercept to offset * add cloudlog, live values are not updated * fix bugs, do not reset points for now * fix crashes * rename to main * fix bugs, works offline * fix float in cereal bug * add latacc filter * randomly choose points, approx for iid * add variable decay * local param to capnp instead of dict * verify works in replay * use torqued output in controlsd * use in controlsd; use points from past routes * controlsd bugfix * filter before updating gains, needs to be replaced * save all points to ensure smooth transition across routes, revert friction factor to 1.5 * add filters to prevent noisy low-speed data points; improve fit sanity * add engaged buffer * revert lat_acc thresh * use paramsd realtime process config * make latacc-to-torque generic, and overrideable * move freq to 4Hz, avoid storing in np.array, don't publish points in the message * float instead of np * remove constant while storing pts * rename slope, offset to lat_accet_factor, offset * resolve issues * use camelcase in all capnp params * use camelcase everywhere * reduce latacc threshold or sanity, add car_sane todo, save points properly * add and check tag * write param to disk at end of route * remove args * rebase op, cereal * save on exit * restore default handler * cpu usage check * add to process replay * handle reset better, reduce unnecessary computation * always publish raw values - useful for debug * regen routes * update refs * checks on cache restore * check tuning vals too * clean that up * reduce cpu usage * reduce cpu usage by 75% * cleanup * optimize further * handle reset condition better, don't put points in init, use only in corolla * bump cereal after rebasing * update refs * Update common/params.cc Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove unnecessary checks * Update RELEASES.md Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
3 years ago
r = Route(route)
lr = LogReader(r.log_paths()[sidx])
frs = {}
if len(r.camera_paths()) > sidx and r.camera_paths()[sidx] is not None:
frs['roadCameraState'] = FrameReader(r.camera_paths()[sidx])
if len(r.ecamera_paths()) > sidx and r.ecamera_paths()[sidx] is not None:
frs['wideCameraState'] = FrameReader(r.ecamera_paths()[sidx])
if len(r.dcamera_paths()) > sidx and r.dcamera_paths()[sidx] is not None:
frs['driverCameraState'] = FrameReader(r.dcamera_paths()[sidx])
else:
lr = LogReader(f"cd:/{route.replace('|', '/')}/{sidx}/rlog.bz2")
frs = {
'roadCameraState': FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/fcamera.hevc"),
'driverCameraState': FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/dcamera.hevc"),
}
if next((True for m in lr if m.which() == "wideRoadCameraState"), False):
frs['wideRoadCameraState'] = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/ecamera.hevc")
return lr, frs
def regen_and_save(
route: str, sidx: int, daemons: Union[str, Iterable[str]] = "all", outdir: str = FAKEDATA,
upload: bool = False, use_route_meta: bool = False, disable_tqdm: bool = False
) -> str:
lr, frs = setup_data_readers(route, sidx, use_route_meta)
output_logs = regen_segment(lr, frs, daemons, disable_tqdm=disable_tqdm)
log_dir = os.path.join(outdir, time.strftime("%Y-%m-%d--%H-%M-%S--0", time.gmtime()))
rel_log_dir = os.path.relpath(log_dir)
rpath = os.path.join(log_dir, "rlog.bz2")
os.makedirs(log_dir)
save_log(rpath, output_logs, compress=True)
print("\n\n", "*"*30, "\n\n", sep="")
print("New route:", rel_log_dir, "\n")
if not check_openpilot_enabled(output_logs):
raise Exception("Route did not engage for long enough")
if upload:
upload_route(rel_log_dir)
return rel_log_dir
if __name__ == "__main__":
def comma_separated_list(string):
if string == "all":
return string
return string.split(",")
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("--outdir", help="log output dir", default=FAKEDATA)
parser.add_argument("--whitelist-procs", type=comma_separated_list, default="all",
help="Comma-separated whitelist of processes to regen (e.g. controlsd). Pass 'all' to whitelist all processes.")
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()
regen_and_save(args.route, args.seg, daemons=args.whitelist_procs, upload=args.upload, outdir=args.outdir)