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