* format card
* standalone process
* no class member CS, there's no point
also can be confusing; what else could be using this?
* rename CoS
* Update selfdrive/controls/controlsd.py
* never works first time :D
* canRcvTimeout is bool
* hack
* add cpu
* see what testing closet comes up with
* first
* some clean up
* support passable CI, fix test models
* fix startup alert
* process replay changes
* test_fuzzy
* gate carOutput valid on carControl valid
* we should publish after we update carOutput
* controlsd was using actuatorsOutput from 2 frames ago for torque, not the most up to date
* check all checks for carControl in case controlsd dies
* log more timestamps
* more generic latency logger; needs some clean up
latency_logger.py was difficult to understand and modify
* card polls on can and carControl to get latest carControl possible
* temp try to send earlier
* add log
* remove latencylogger
* no mpld3!
* old loop
* detect first event
* normal send
* revert "card polls on can and carControl to get latest carControl possible"
how it was is best
* sheesh! update should be first
* first timestamp
* temp comment ( timestamp is slow :( )
* more final ordering, and make polling on/off test repeatable
* Received can
* new plot timestamps
* clean up
* no poll
* add controllers (draft)
* Revert "add controllers (draft)"
This reverts commit e2c3f01b2fadcff74347bac90c8a5cc1ef4e27b3.
* fix that
* conventions
* just use CS
* consider controlsd state machine in card: not fully done
* hmm it's just becoming controlsd
* rm debugging
* Revert "hmm it's just becoming controlsd"
This reverts commit 534a357ee95bec4ed070667186af55d59421bbc7.
* Revert "just use CS"
This reverts commit 9fa7406f30c86200f20457f7b9ff95e731201bf9.
* add vCruise
* migrate car state
* Revert "migrate car state"
This reverts commit 4ae86ca163c6920070f410f608f7644ab632850b.
* Revert "add vCruise"
This reverts commit af247a8da41c3626ada4231b98042da1a1ae4633.
* simple state machine in card (doesn't work as is)
* Revert "simple state machine in card (doesn't work as is)"
This reverts commit b4af8a9b0a2e17fdfc89d344c64678ef51305c24.
* poll carState without conflate
* bump
* remove state transition
* fix
* update refs
* ignore cumLagMs and don't ignore valid
* fix controls mismatch; controlsd used to set alt exp
* controlsd_config_callback not needed for card
* revert ref temp
* update refs
* no poll
* not builder!
* test fix
* need to migrate initialized
* CC will be a reader
* more as_reader!
* fix None
* init after publish like before - no real difference
* controlsd clean up
* remove redundant check and check passive for init
* stash
* flip
* migrate missing carOutput for controlsd
* Update ref_commit
* bump cereal
* comment
* no class params
* no class
* Revert "no class"
This reverts commit 5499b83c2dcb5462070626f8523e3aec6f4c209d.
* add todo
* regen and update refs
* fix
* update refs
* and fix that
* should be controlsstate
* remove controlsState migration
CoS.initialized isn't needed yet
* fix
* flip!
* bump
* fix that
* update refs
* fix
* if canValid goes false, controlsd would still send
* bump
* rm diff
* need to be very careful with initializing
* update refs
old-commit-hash: 71f5c441fe
Process replay
Process replay is a regression test designed to identify any changes in the output of a process. This test replays a segment through individual processes and compares the output to a known good replay. Each make is represented in the test with a segment.
If the test fails, make sure that you didn't unintentionally change anything. If there are intentional changes, the reference logs will be updated.
Use test_processes.py to run the test locally.
Use FILEREADER_CACHE='1' test_processes.py to cache log files.
Currently the following processes are tested:
- controlsd
- radard
- plannerd
- calibrationd
- dmonitoringd
- locationd
- paramsd
- ubloxd
- torqued
Usage
Usage: test_processes.py [-h] [--whitelist-procs PROCS] [--whitelist-cars CARS] [--blacklist-procs PROCS]
[--blacklist-cars CARS] [--ignore-fields FIELDS] [--ignore-msgs MSGS] [--update-refs] [--upload-only]
Regression test to identify changes in a process's output
optional arguments:
-h, --help show this help message and exit
--whitelist-procs PROCS Whitelist given processes from the test (e.g. controlsd)
--whitelist-cars WHITELIST_CARS Whitelist given cars from the test (e.g. HONDA)
--blacklist-procs BLACKLIST_PROCS Blacklist given processes from the test (e.g. controlsd)
--blacklist-cars BLACKLIST_CARS Blacklist given cars from the test (e.g. HONDA)
--ignore-fields IGNORE_FIELDS Extra fields or msgs to ignore (e.g. carState.events)
--ignore-msgs IGNORE_MSGS Msgs to ignore (e.g. onroadEvents)
--update-refs Updates reference logs using current commit
--upload-only Skips testing processes and uploads logs from previous test run
Forks
openpilot forks can use this test with their own reference logs, by default test_proccess.py saves logs locally.
To generate new logs:
./test_processes.py
Then, check in the new logs using git-lfs. Make sure to also update the ref_commit file to the current commit.
API
Process replay test suite exposes programmatic APIs for simultaneously running processes or groups of processes on provided logs.
def replay_process_with_name(name: Union[str, Iterable[str]], lr: LogIterable, *args, **kwargs) -> List[capnp._DynamicStructReader]:
def replay_process(
cfg: Union[ProcessConfig, Iterable[ProcessConfig]], lr: LogIterable, frs: Optional[Dict[str, Any]] = None,
fingerprint: Optional[str] = None, return_all_logs: bool = False, custom_params: Optional[Dict[str, Any]] = None, disable_progress: bool = False
) -> List[capnp._DynamicStructReader]:
Example usage:
from openpilot.selfdrive.test.process_replay import replay_process_with_name
from openpilot.tools.lib.logreader import LogReader
lr = LogReader(...)
# provide a name of the process to replay
output_logs = replay_process_with_name('locationd', lr)
# or list of names
output_logs = replay_process_with_name(['ubloxd', 'locationd'], lr)
Supported processes:
- controlsd
- radard
- plannerd
- calibrationd
- dmonitoringd
- locationd
- paramsd
- ubloxd
- torqued
- modeld
- dmonitoringmodeld
Certain processes may require an initial state, which is usually supplied within Params and persisting from segment to segment (e.g CalibrationParams, LiveParameters). The custom_params is dictionary used to prepopulate Params with arbitrary values. The get_custom_params_from_lr helper is provided to fetch meaningful values from log files.
from openpilot.selfdrive.test.process_replay import get_custom_params_from_lr
previous_segment_lr = LogReader(...)
current_segment_lr = LogReader(...)
custom_params = get_custom_params_from_lr(previous_segment_lr, 'last')
output_logs = replay_process_with_name('calibrationd', lr, custom_params=custom_params)
Replaying processes that use VisionIPC (e.g. modeld, dmonitoringmodeld) require additional frs dictionary with camera states as keys and FrameReader objects as values.
from openpilot.tools.lib.framereader import FrameReader
frs = {
'roadCameraState': FrameReader(...),
'wideRoadCameraState': FrameReader(...),
'driverCameraState': FrameReader(...),
}
output_logs = replay_process_with_name(['modeld', 'dmonitoringmodeld'], lr, frs=frs)
To capture stdout/stderr of the replayed process, captured_output_store can be provided.
output_store = dict()
# pass dictionary by reference, it will be filled with standard outputs - even if process replay fails
output_logs = replay_process_with_name(['radard', 'plannerd'], lr, captured_output_store=output_store)
# entries with captured output in format { 'out': '...', 'err': '...' } will be added to provided dictionary for each replayed process
print(output_store['radard']['out']) # radard stdout
print(output_store['radard']['err']) # radard stderr