parent
6f5f8e7746
commit
bab1254a02
1 changed files with 89 additions and 0 deletions
@ -0,0 +1,89 @@ |
||||
import numpy as np |
||||
|
||||
|
||||
def flatten_type_dict(d, sep="/", prefix=None): |
||||
res = {} |
||||
if isinstance(d, dict): |
||||
for key, val in d.items(): |
||||
if prefix is None: |
||||
res.update(flatten_type_dict(val, prefix=key)) |
||||
else: |
||||
res.update(flatten_type_dict(val, prefix=prefix + sep + key)) |
||||
return res |
||||
elif isinstance(d, list): |
||||
return {prefix: np.array(d)} |
||||
else: |
||||
return {prefix: d} |
||||
|
||||
|
||||
def get_message_dict(message, typ): |
||||
valid = message.valid |
||||
message = message._get(typ) |
||||
if not hasattr(message, 'to_dict'): |
||||
# TODO: support these |
||||
#print("skipping", typ) |
||||
return |
||||
|
||||
msg_dict = message.to_dict(verbose=True) |
||||
msg_dict = flatten_type_dict(msg_dict) |
||||
msg_dict['_valid'] = valid |
||||
return msg_dict |
||||
|
||||
|
||||
def append_dict(path, t, d, values, arrays=False): |
||||
if path not in values: |
||||
group = {} |
||||
group["t"] = [] |
||||
for k in d: |
||||
group[k] = [] |
||||
values[path] = group |
||||
else: |
||||
group = values[path] |
||||
|
||||
if arrays: |
||||
group["t"] += t.tolist() |
||||
for k, v in d.items(): |
||||
group[k] += v.tolist() |
||||
else: |
||||
group["t"].append(t) |
||||
for k, v in d.items(): |
||||
group[k].append(v) |
||||
|
||||
|
||||
def potentially_ragged_array(arr, dtype=None, **kwargs): |
||||
# TODO: is there a better way to detect inhomogeneous shapes? |
||||
try: |
||||
return np.array(arr, dtype=dtype, **kwargs) |
||||
except ValueError: |
||||
return np.array(arr, dtype=object, **kwargs) |
||||
|
||||
def msgs_to_time_series(msgs): |
||||
""" |
||||
Convert an iterable of canonical capnp messages into a dictionary of time series. |
||||
Each time series has a value with key "t" which consists of monotonically increasing timestamps |
||||
in seconds. |
||||
""" |
||||
values = {} |
||||
for msg in msgs: |
||||
typ = msg.which() |
||||
|
||||
tm = msg.logMonoTime / 1.0e9 |
||||
msg_dict = get_message_dict(msg, typ) |
||||
if msg_dict is not None: |
||||
append_dict(typ, tm, msg_dict, values) |
||||
|
||||
# Sort values by time. |
||||
for group in values.values(): |
||||
order = np.argsort(group["t"]) |
||||
for name, group_values in group.items(): |
||||
group[name] = potentially_ragged_array(group_values)[order] |
||||
|
||||
return values |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
import sys |
||||
from openpilot.tools.lib.logreader import LogReader |
||||
m = msgs_to_time_series(LogReader(sys.argv[1])) |
||||
print(m['driverCameraState']['t']) |
||||
print(np.diff(m['driverCameraState']['timestampSof'])) |
Loading…
Reference in new issue