pull/1407/head
parent
ba0d92de52
commit
abad49110e
9 changed files with 0 additions and 993 deletions
@ -1,284 +0,0 @@ |
|||||||
import os |
|
||||||
import struct |
|
||||||
import bisect |
|
||||||
import numpy as np |
|
||||||
import _io |
|
||||||
|
|
||||||
import capnp |
|
||||||
from cereal import log as capnp_log |
|
||||||
|
|
||||||
class RawData(): |
|
||||||
def __init__(self, f): |
|
||||||
self.f = _io.FileIO(f, 'rb') |
|
||||||
self.lenn = struct.unpack("I", self.f.read(4))[0] |
|
||||||
self.count = os.path.getsize(f) / (self.lenn+4) |
|
||||||
|
|
||||||
def read(self, i): |
|
||||||
self.f.seek((self.lenn+4)*i + 4) |
|
||||||
return self.f.read(self.lenn) |
|
||||||
|
|
||||||
def yuv420_to_rgb(raw, image_dim=None, swizzled=False): |
|
||||||
def expand(x): |
|
||||||
x = np.repeat(x, 2, axis=0) |
|
||||||
return np.repeat(x, 2, axis=1) |
|
||||||
|
|
||||||
if image_dim is None: |
|
||||||
image_dim = (raw.shape[1]*2, raw.shape[2]*2) |
|
||||||
swizzled = True |
|
||||||
|
|
||||||
if not swizzled: |
|
||||||
img_data = np.array(raw, copy=False, dtype=np.uint8) |
|
||||||
uv_len = (image_dim[0]/2)*(image_dim[1]/2) |
|
||||||
img_data_u = expand(img_data[image_dim[0]*image_dim[1]: \ |
|
||||||
image_dim[0]*image_dim[1]+uv_len]. \ |
|
||||||
reshape(image_dim[0]/2, image_dim[1]/2)) |
|
||||||
|
|
||||||
img_data_v = expand(img_data[image_dim[0]*image_dim[1]+uv_len: \ |
|
||||||
image_dim[0]*image_dim[1]+2*uv_len]. \ |
|
||||||
reshape(image_dim[0]/2, image_dim[1]/2)) |
|
||||||
img_data_y = img_data[0:image_dim[0]*image_dim[1]].reshape(image_dim) |
|
||||||
else: |
|
||||||
img_data_y = np.zeros(image_dim, dtype=np.uint8) |
|
||||||
img_data_y[0::2, 0::2] = raw[0] |
|
||||||
img_data_y[1::2, 0::2] = raw[1] |
|
||||||
img_data_y[0::2, 1::2] = raw[2] |
|
||||||
img_data_y[1::2, 1::2] = raw[3] |
|
||||||
img_data_u = expand(raw[4]) |
|
||||||
img_data_v = expand(raw[5]) |
|
||||||
|
|
||||||
yuv = np.stack((img_data_y, img_data_u, img_data_v)).swapaxes(0,2).swapaxes(0,1) |
|
||||||
yuv = yuv.astype(np.int16) |
|
||||||
|
|
||||||
# http://maxsharabayko.blogspot.com/2016/01/fast-yuv-to-rgb-conversion-in-python-3.html |
|
||||||
# according to ITU-R BT.709 |
|
||||||
yuv[:,:, 0] = yuv[:,:, 0].clip(16, 235).astype(yuv.dtype) - 16 |
|
||||||
yuv[:,:,1:] = yuv[:,:,1:].clip(16, 240).astype(yuv.dtype) - 128 |
|
||||||
|
|
||||||
A = np.array([[1.164, 0.000, 1.793], |
|
||||||
[1.164, -0.213, -0.533], |
|
||||||
[1.164, 2.112, 0.000]]) |
|
||||||
|
|
||||||
# our result |
|
||||||
img = np.dot(yuv, A.T).clip(0, 255).astype('uint8') |
|
||||||
return img |
|
||||||
|
|
||||||
|
|
||||||
class YuvData(): |
|
||||||
def __init__(self, f, dim=(160,320)): |
|
||||||
self.f = _io.FileIO(f, 'rb') |
|
||||||
self.image_dim = dim |
|
||||||
self.image_size = self.image_dim[0]/2 * self.image_dim[1]/2 * 6 |
|
||||||
self.count = os.path.getsize(f) / self.image_size |
|
||||||
|
|
||||||
def read_frame(self, frame): |
|
||||||
self.f.seek(self.image_size*frame) |
|
||||||
raw = self.f.read(self.image_size) |
|
||||||
return raw |
|
||||||
|
|
||||||
def read_frames(self, range_start, range_len): |
|
||||||
self.f.seek(self.image_size*range_start) |
|
||||||
raw = self.f.read(self.image_size*range_len) |
|
||||||
return raw |
|
||||||
|
|
||||||
def read_frames_into(self, range_start, buf): |
|
||||||
self.f.seek(self.image_size*range_start) |
|
||||||
return self.f.readinto(buf) |
|
||||||
|
|
||||||
def read(self, frame): |
|
||||||
return yuv420_to_rgb(self.read_frame(frame), self.image_dim) |
|
||||||
|
|
||||||
def close(self): |
|
||||||
self.f.close() |
|
||||||
|
|
||||||
def __enter__(self): |
|
||||||
return self |
|
||||||
|
|
||||||
def __exit__(self, type, value, traceback): |
|
||||||
self.close() |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class OneReader(): |
|
||||||
def __init__(self, base_path, goofy=False, segment_range=None): |
|
||||||
self.base_path = base_path |
|
||||||
|
|
||||||
route_name = os.path.basename(base_path) |
|
||||||
|
|
||||||
self.rcamera_size = (304, 560) |
|
||||||
|
|
||||||
if segment_range is None: |
|
||||||
parent_path = os.path.dirname(base_path) |
|
||||||
self.segment_nums = [] |
|
||||||
for p in os.listdir(parent_path): |
|
||||||
if not p.startswith(route_name+"--"): |
|
||||||
continue |
|
||||||
self.segment_nums.append(int(p.rsplit("--", 1)[-1])) |
|
||||||
if not self.segment_nums: |
|
||||||
raise Exception("no route segments found") |
|
||||||
self.segment_nums.sort() |
|
||||||
self.segment_range = (self.segment_nums[0], self.segment_nums[-1]) |
|
||||||
else: |
|
||||||
self.segment_range = segment_range |
|
||||||
self.segment_nums = range(segment_range[0], segment_range[1]+1) |
|
||||||
for i in self.segment_nums: |
|
||||||
if not os.path.exists(base_path+"--"+str(i)): |
|
||||||
raise Exception("missing segment in provided range") |
|
||||||
|
|
||||||
# goofy data is broken with discontinuous logs |
|
||||||
if goofy and (self.segment_range[0] != 0 |
|
||||||
or self.segment_nums != range(self.segment_range[0], self.segment_range[1]+1)): |
|
||||||
raise Exception("goofy data needs all the segments for a route") |
|
||||||
|
|
||||||
self.cur_seg = None |
|
||||||
self.cur_seg_f = None |
|
||||||
|
|
||||||
# index the frames |
|
||||||
print("indexing frames {}...".format(self.segment_nums)) |
|
||||||
|
|
||||||
self.rcamera_encode_map = {} # frame_id -> (segment num, segment id, frame_time) |
|
||||||
last_frame_id = -1 |
|
||||||
|
|
||||||
if goofy: |
|
||||||
# goofy is goofy |
|
||||||
|
|
||||||
frame_size = self.rcamera_size[0]*self.rcamera_size[1]*3/2 |
|
||||||
|
|
||||||
# find the encode id ranges for each segment by using the rcamera file size |
|
||||||
segment_encode_ids = [] |
|
||||||
cur_encode_id = 0 |
|
||||||
for n in self.segment_nums: |
|
||||||
camera_path = os.path.join(self.seg_path(n), "rcamera") |
|
||||||
if not os.path.exists(camera_path): |
|
||||||
# for goofy, missing camera files means a bad route |
|
||||||
raise Exception("Missing camera file {}".format(camera_path)) |
|
||||||
camera_size = os.path.getsize(camera_path) |
|
||||||
assert (camera_size % frame_size) == 0 |
|
||||||
|
|
||||||
num_frames = camera_size / frame_size |
|
||||||
segment_encode_ids.append(cur_encode_id) |
|
||||||
cur_encode_id += num_frames |
|
||||||
|
|
||||||
last_encode_id = -1 |
|
||||||
# use the segment encode id map and frame events to build the frame index |
|
||||||
for n in self.segment_nums: |
|
||||||
log_path = os.path.join(self.seg_path(n), "rlog") |
|
||||||
if os.path.exists(log_path): |
|
||||||
with open(log_path, "rb") as f: |
|
||||||
for evt in capnp_log.Event.read_multiple(f): |
|
||||||
if evt.which() == 'frame': |
|
||||||
|
|
||||||
if evt.frame.frameId < last_frame_id: |
|
||||||
# a non-increasing frame id is bad route (eg visiond was restarted) |
|
||||||
raise Exception("non-increasing frame id") |
|
||||||
last_frame_id = evt.frame.frameId |
|
||||||
|
|
||||||
seg_i = bisect.bisect_right(segment_encode_ids, evt.frame.encodeId)-1 |
|
||||||
assert seg_i >= 0 |
|
||||||
seg_num = self.segment_nums[seg_i] |
|
||||||
seg_id = evt.frame.encodeId-segment_encode_ids[seg_i] |
|
||||||
frame_time = evt.logMonoTime / 1.0e9 |
|
||||||
|
|
||||||
self.rcamera_encode_map[evt.frame.frameId] = (seg_num, seg_id, |
|
||||||
frame_time) |
|
||||||
|
|
||||||
last_encode_id = evt.frame.encodeId |
|
||||||
|
|
||||||
if last_encode_id-cur_encode_id > 10: |
|
||||||
# too many missing frames is a bad route (eg route from before encoder rotating worked) |
|
||||||
raise Exception("goofy route is missing frames: {}, {}".format( |
|
||||||
last_encode_id, cur_encode_id)) |
|
||||||
|
|
||||||
else: |
|
||||||
# for harry data, build the index from encodeIdx events |
|
||||||
for n in self.segment_nums: |
|
||||||
log_path = os.path.join(self.seg_path(n), "rlog") |
|
||||||
if os.path.exists(log_path): |
|
||||||
with open(log_path, "rb") as f: |
|
||||||
for evt in capnp_log.Event.read_multiple(f): |
|
||||||
if evt.which() == 'encodeIdx' and evt.encodeIdx.type == 'bigBoxLossless': |
|
||||||
frame_time = evt.logMonoTime / 1.0e9 |
|
||||||
self.rcamera_encode_map[evt.encodeIdx.frameId] = ( |
|
||||||
evt.encodeIdx.segmentNum, evt.encodeIdx.segmentId, |
|
||||||
frame_time) |
|
||||||
|
|
||||||
print("done") |
|
||||||
|
|
||||||
# read the first event to find the start time |
|
||||||
self.reset_to_seg(self.segment_range[0]) |
|
||||||
for evt in self.events(): |
|
||||||
if evt.which() != 'initData': |
|
||||||
self.start_mono = evt.logMonoTime |
|
||||||
break |
|
||||||
self.reset_to_seg(self.segment_range[0]) |
|
||||||
|
|
||||||
|
|
||||||
def seg_path(self, num): |
|
||||||
return self.base_path+"--"+str(num) |
|
||||||
|
|
||||||
def reset_to_seg(self, seg): |
|
||||||
self.cur_seg = seg |
|
||||||
if self.cur_seg_f: |
|
||||||
self.cur_seg_f.close() |
|
||||||
self.cur_seg_f = None |
|
||||||
|
|
||||||
def seek_ts(self, ts): |
|
||||||
seek_seg = int(ts/60) |
|
||||||
if seek_seg < self.segment_range[0] or seek_seg > self.segment_range[1]: |
|
||||||
raise ValueError |
|
||||||
|
|
||||||
self.reset_to_seg(seek_seg) |
|
||||||
target_mono = self.start_mono + int(ts*1e9) |
|
||||||
for evt in self.events(): |
|
||||||
if evt.logMonoTime >= target_mono: |
|
||||||
break |
|
||||||
|
|
||||||
def read_event(self): |
|
||||||
while True: |
|
||||||
if self.cur_seg > self.segment_range[1]: |
|
||||||
return None |
|
||||||
if self.cur_seg_f is None: |
|
||||||
log_path = os.path.join(self.seg_path(self.cur_seg), "rlog") |
|
||||||
if not os.path.exists(log_path): |
|
||||||
print("missing log file!", log_path) |
|
||||||
self.cur_seg += 1 |
|
||||||
continue |
|
||||||
self.cur_seg_f = open(log_path, "rb") |
|
||||||
|
|
||||||
try: |
|
||||||
return capnp_log.Event.read(self.cur_seg_f) |
|
||||||
except capnp.lib.capnp.KjException as e: |
|
||||||
if 'EOF' in str(e): # dumb, but pycapnp does this too |
|
||||||
self.cur_seg_f.close() |
|
||||||
self.cur_seg_f = None |
|
||||||
self.cur_seg += 1 |
|
||||||
else: |
|
||||||
raise |
|
||||||
|
|
||||||
def events(self): |
|
||||||
while True: |
|
||||||
r = self.read_event() |
|
||||||
if r is None: |
|
||||||
break |
|
||||||
yield r |
|
||||||
|
|
||||||
def read_frame(self, frame_id): |
|
||||||
encode_idx = self.rcamera_encode_map.get(frame_id) |
|
||||||
if encode_idx is None: |
|
||||||
return None |
|
||||||
|
|
||||||
seg_num, seg_id, _ = encode_idx |
|
||||||
camera_path = os.path.join(self.seg_path(seg_num), "rcamera") |
|
||||||
if not os.path.exists(camera_path): |
|
||||||
return None |
|
||||||
with YuvData(camera_path, self.rcamera_size) as data: |
|
||||||
return data.read_frame(seg_id) |
|
||||||
|
|
||||||
def close(self): |
|
||||||
if self.cur_seg_f is not None: |
|
||||||
self.cur_seg_f.close() |
|
||||||
|
|
||||||
def __enter__(self): |
|
||||||
return self |
|
||||||
|
|
||||||
def __exit__(self, type, value, traceback): |
|
||||||
self.close() |
|
@ -1,66 +0,0 @@ |
|||||||
import bisect |
|
||||||
import numpy as np |
|
||||||
from scipy.interpolate import interp1d |
|
||||||
|
|
||||||
|
|
||||||
def deep_interp_0_fast(dx, x, y): |
|
||||||
FIX = False |
|
||||||
if len(y.shape) == 1: |
|
||||||
y = y[:, None] |
|
||||||
FIX = True |
|
||||||
ret = np.zeros((dx.shape[0], y.shape[1])) |
|
||||||
index = list(x) |
|
||||||
for i in range(dx.shape[0]): |
|
||||||
idx = bisect.bisect_left(index, dx[i]) |
|
||||||
if idx == x.shape[0]: |
|
||||||
idx = x.shape[0] - 1 |
|
||||||
ret[i] = y[idx] |
|
||||||
|
|
||||||
if FIX: |
|
||||||
return ret[:, 0] |
|
||||||
else: |
|
||||||
return ret |
|
||||||
|
|
||||||
|
|
||||||
def running_mean(x, N): |
|
||||||
cumsum = np.cumsum(np.insert(x, [0]*(int(N/2)) + [-1]*(N-int(N/2)), [x[0]]*int(N/2) + [x[-1]]*(N-int(N/2)))) |
|
||||||
return (cumsum[N:] - cumsum[:-N]) / N |
|
||||||
|
|
||||||
|
|
||||||
def deep_interp_np(x, xp, fp): |
|
||||||
x = np.atleast_1d(x) |
|
||||||
xp = np.array(xp) |
|
||||||
if len(xp) < 2: |
|
||||||
return np.repeat(fp, len(x), axis=0) |
|
||||||
if min(np.diff(xp)) < 0: |
|
||||||
raise RuntimeError('Bad x array for interpolation') |
|
||||||
j = np.searchsorted(xp, x) - 1 |
|
||||||
j = np.clip(j, 0, len(xp)-2) |
|
||||||
d = np.divide(x - xp[j], xp[j + 1] - xp[j], out=np.ones_like(x, dtype=np.float64), where=xp[j + 1] - xp[j] != 0) |
|
||||||
vals_interp = (fp[j].T*(1 - d)).T + (fp[j + 1].T*d).T |
|
||||||
if len(vals_interp) == 1: |
|
||||||
return vals_interp[0] |
|
||||||
else: |
|
||||||
return vals_interp |
|
||||||
|
|
||||||
|
|
||||||
def clipping_deep_interp(x, xp, fp): |
|
||||||
if len(xp) < 2: |
|
||||||
return deep_interp_np(x, xp, fp) |
|
||||||
bad_idx = np.where(np.diff(xp) < 0)[0] |
|
||||||
if len(bad_idx) > 0: |
|
||||||
if bad_idx[0] ==1: |
|
||||||
return np.zeros([] + list(fp.shape[1:])) |
|
||||||
return deep_interp_np(x, xp[:bad_idx[0]], fp[:bad_idx[0]]) |
|
||||||
else: |
|
||||||
return deep_interp_np(x, xp, fp) |
|
||||||
|
|
||||||
|
|
||||||
def deep_interp(dx, x, y, kind="slinear"): |
|
||||||
return interp1d( |
|
||||||
x, y, |
|
||||||
axis=0, |
|
||||||
kind=kind, |
|
||||||
bounds_error=False, |
|
||||||
fill_value="extrapolate", |
|
||||||
assume_sorted=True)(dx) |
|
@ -1,78 +0,0 @@ |
|||||||
import os |
|
||||||
import numpy as np |
|
||||||
import random |
|
||||||
|
|
||||||
class SamplingBuffer(): |
|
||||||
def __init__(self, fn, size, write=False): |
|
||||||
self._fn = fn |
|
||||||
self._write = write |
|
||||||
if self._write: |
|
||||||
self._f = open(self._fn, "ab") |
|
||||||
else: |
|
||||||
self._f = open(self._fn, "rb") |
|
||||||
self._size = size |
|
||||||
self._refresh() |
|
||||||
|
|
||||||
def _refresh(self): |
|
||||||
self.cnt = os.path.getsize(self._fn) / self._size |
|
||||||
|
|
||||||
@property |
|
||||||
def count(self): |
|
||||||
self._refresh() |
|
||||||
return self.cnt |
|
||||||
|
|
||||||
def _fetch_one(self, x): |
|
||||||
assert self._write == False |
|
||||||
self._f.seek(x*self._size) |
|
||||||
return self._f.read(self._size) |
|
||||||
|
|
||||||
def sample(self, count, indices = None): |
|
||||||
if indices == None: |
|
||||||
cnt = self.count |
|
||||||
assert cnt != 0 |
|
||||||
indices = map(lambda x: random.randint(0, cnt-1), range(count)) |
|
||||||
return map(self._fetch_one, indices) |
|
||||||
|
|
||||||
def write(self, dat): |
|
||||||
assert self._write == True |
|
||||||
assert (len(dat) % self._size) == 0 |
|
||||||
self._f.write(dat) |
|
||||||
self._f.flush() |
|
||||||
|
|
||||||
class NumpySamplingBuffer(): |
|
||||||
def __init__(self, fn, size, dtype, write=False): |
|
||||||
self._size = size |
|
||||||
self._dtype = dtype |
|
||||||
self._buf = SamplingBuffer(fn, len(np.zeros(size, dtype=dtype).tobytes()), write) |
|
||||||
|
|
||||||
@property |
|
||||||
def count(self): |
|
||||||
return self._buf.count |
|
||||||
|
|
||||||
def write(self, dat): |
|
||||||
self._buf.write(dat.tobytes()) |
|
||||||
|
|
||||||
def sample(self, count, indices = None): |
|
||||||
return np.fromstring(''.join(self._buf.sample(count, indices)), dtype=self._dtype).reshape([count]+list(self._size)) |
|
||||||
|
|
||||||
# TODO: n IOPS needed where n is the Multi |
|
||||||
class MultiNumpySamplingBuffer(): |
|
||||||
def __init__(self, fn, npa, write=False): |
|
||||||
self._bufs = [] |
|
||||||
for i,n in enumerate(npa): |
|
||||||
self._bufs.append(NumpySamplingBuffer(fn + ("_%d" % i), n[0], n[1], write)) |
|
||||||
|
|
||||||
def write(self, dat): |
|
||||||
for b,x in zip(self._bufs, dat): |
|
||||||
b.write(x) |
|
||||||
|
|
||||||
@property |
|
||||||
def count(self): |
|
||||||
return min(map(lambda x: x.count, self._bufs)) |
|
||||||
|
|
||||||
def sample(self, count): |
|
||||||
cnt = self.count |
|
||||||
assert cnt != 0 |
|
||||||
indices = map(lambda x: random.randint(0, cnt-1), range(count)) |
|
||||||
return map(lambda x: x.sample(count, indices), self._bufs) |
|
||||||
|
|
@ -1,94 +0,0 @@ |
|||||||
import numpy as np |
|
||||||
|
|
||||||
_DESC_FMT = """ |
|
||||||
{} (n={}): |
|
||||||
MEAN={} |
|
||||||
VAR={} |
|
||||||
MIN={} |
|
||||||
MAX={} |
|
||||||
""" |
|
||||||
|
|
||||||
class StatTracker(): |
|
||||||
def __init__(self, name): |
|
||||||
self._name = name |
|
||||||
self._mean = 0. |
|
||||||
self._var = 0. |
|
||||||
self._n = 0 |
|
||||||
self._min = -float("-inf") |
|
||||||
self._max = -float("inf") |
|
||||||
|
|
||||||
@property |
|
||||||
def mean(self): |
|
||||||
return self._mean |
|
||||||
|
|
||||||
@property |
|
||||||
def var(self): |
|
||||||
return (self._n * self._var) / (self._n - 1.) |
|
||||||
|
|
||||||
@property |
|
||||||
def min(self): |
|
||||||
return self._min |
|
||||||
|
|
||||||
@property |
|
||||||
def max(self): |
|
||||||
return self._max |
|
||||||
|
|
||||||
def update(self, samples): |
|
||||||
# https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm |
|
||||||
data = samples.reshape(-1) |
|
||||||
n_a = data.size |
|
||||||
mean_a = np.mean(data) |
|
||||||
var_a = np.var(data, ddof=0) |
|
||||||
|
|
||||||
n_b = self._n |
|
||||||
mean_b = self._mean |
|
||||||
|
|
||||||
delta = mean_b - mean_a |
|
||||||
m_a = var_a * (n_a - 1) |
|
||||||
m_b = self._var * (n_b - 1) |
|
||||||
m2 = m_a + m_b + delta**2 * n_a * n_b / (n_a + n_b) |
|
||||||
|
|
||||||
self._var = m2 / (n_a + n_b) |
|
||||||
self._mean = (n_a * mean_a + n_b * mean_b) / (n_a + n_b) |
|
||||||
self._n = n_a + n_b |
|
||||||
|
|
||||||
self._min = min(self._min, np.min(data)) |
|
||||||
self._max = max(self._max, np.max(data)) |
|
||||||
|
|
||||||
def __str__(self): |
|
||||||
return _DESC_FMT.format(self._name, self._n, self._mean, self.var, self._min, |
|
||||||
self._max) |
|
||||||
|
|
||||||
# FIXME(mgraczyk): The variance computation does not work with 1 sample batches. |
|
||||||
class VectorStatTracker(StatTracker): |
|
||||||
def __init__(self, name, dim): |
|
||||||
self._name = name |
|
||||||
self._mean = np.zeros((dim, )) |
|
||||||
self._var = np.zeros((dim, dim)) |
|
||||||
self._n = 0 |
|
||||||
self._min = np.full((dim, ), -float("-inf")) |
|
||||||
self._max = np.full((dim, ), -float("inf")) |
|
||||||
|
|
||||||
@property |
|
||||||
def cov(self): |
|
||||||
return self.var |
|
||||||
|
|
||||||
def update(self, samples): |
|
||||||
n_a = samples.shape[0] |
|
||||||
mean_a = np.mean(samples, axis=0) |
|
||||||
var_a = np.cov(samples, ddof=0, rowvar=False) |
|
||||||
|
|
||||||
n_b = self._n |
|
||||||
mean_b = self._mean |
|
||||||
|
|
||||||
delta = mean_b - mean_a |
|
||||||
m_a = var_a * (n_a - 1) |
|
||||||
m_b = self._var * (n_b - 1) |
|
||||||
m2 = m_a + m_b + delta**2 * n_a * n_b / (n_a + n_b) |
|
||||||
|
|
||||||
self._var = m2 / (n_a + n_b) |
|
||||||
self._mean = (n_a * mean_a + n_b * mean_b) / (n_a + n_b) |
|
||||||
self._n = n_a + n_b |
|
||||||
|
|
||||||
self._min = np.minimum(self._min, np.min(samples, axis=0)) |
|
||||||
self._max = np.maximum(self._max, np.max(samples, axis=0)) |
|
@ -1,113 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
import os |
|
||||||
|
|
||||||
from common.basedir import BASEDIR |
|
||||||
os.environ['BASEDIR'] = BASEDIR |
|
||||||
SCALE = 3 |
|
||||||
|
|
||||||
import argparse |
|
||||||
import zmq |
|
||||||
import pygame |
|
||||||
import numpy as np |
|
||||||
import cv2 |
|
||||||
import sys |
|
||||||
import traceback |
|
||||||
from collections import namedtuple |
|
||||||
|
|
||||||
from cereal import car |
|
||||||
from common.params import Params |
|
||||||
from common.lazy_property import lazy_property |
|
||||||
from cereal.messaging import sub_sock, recv_one_or_none, recv_one |
|
||||||
from cereal.services import service_list |
|
||||||
|
|
||||||
_BB_OFFSET = 290, 332 |
|
||||||
_BB_TO_FULL_FRAME = np.asarray([[1., 0., _BB_OFFSET[0]], [0., 1., _BB_OFFSET[1]], |
|
||||||
[0., 0., 1.]]) |
|
||||||
_FULL_FRAME_TO_BB = np.linalg.inv(_BB_TO_FULL_FRAME) |
|
||||||
_FULL_FRAME_SIZE = 1164, 874 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def pygame_modules_have_loaded(): |
|
||||||
return pygame.display.get_init() and pygame.font.get_init() |
|
||||||
|
|
||||||
|
|
||||||
def ui_thread(addr, frame_address): |
|
||||||
context = zmq.Context() |
|
||||||
|
|
||||||
pygame.init() |
|
||||||
pygame.font.init() |
|
||||||
assert pygame_modules_have_loaded() |
|
||||||
|
|
||||||
size = (640 * SCALE, 480 * SCALE) |
|
||||||
pygame.display.set_caption("comma one debug UI") |
|
||||||
screen = pygame.display.set_mode(size, pygame.DOUBLEBUF) |
|
||||||
|
|
||||||
camera_surface = pygame.surface.Surface((640 * SCALE, 480 * SCALE), 0, 24).convert() |
|
||||||
|
|
||||||
frame = context.socket(zmq.SUB) |
|
||||||
frame.connect(frame_address or "tcp://%s:%d" % (addr, 'frame')) |
|
||||||
frame.setsockopt(zmq.SUBSCRIBE, "") |
|
||||||
|
|
||||||
img = np.zeros((480, 640, 3), dtype='uint8') |
|
||||||
imgff = np.zeros((_FULL_FRAME_SIZE[1], _FULL_FRAME_SIZE[0], 3), dtype=np.uint8) |
|
||||||
|
|
||||||
while 1: |
|
||||||
list(pygame.event.get()) |
|
||||||
screen.fill((64, 64, 64)) |
|
||||||
|
|
||||||
# ***** frame ***** |
|
||||||
fpkt = recv_one(frame) |
|
||||||
yuv_img = fpkt.frame.image |
|
||||||
|
|
||||||
if fpkt.frame.transform: |
|
||||||
yuv_transform = np.array(fpkt.frame.transform).reshape(3, 3) |
|
||||||
else: |
|
||||||
# assume frame is flipped |
|
||||||
yuv_transform = np.array([[-1.0, 0.0, _FULL_FRAME_SIZE[0] - 1], |
|
||||||
[0.0, -1.0, _FULL_FRAME_SIZE[1] - 1], [0.0, 0.0, 1.0]]) |
|
||||||
|
|
||||||
if yuv_img and len(yuv_img) == _FULL_FRAME_SIZE[0] * _FULL_FRAME_SIZE[1] * 3 // 2: |
|
||||||
yuv_np = np.frombuffer( |
|
||||||
yuv_img, dtype=np.uint8).reshape(_FULL_FRAME_SIZE[1] * 3 // 2, -1) |
|
||||||
cv2.cvtColor(yuv_np, cv2.COLOR_YUV2RGB_I420, dst=imgff) |
|
||||||
cv2.warpAffine( |
|
||||||
imgff, |
|
||||||
np.dot(yuv_transform, _BB_TO_FULL_FRAME)[:2], (img.shape[1], img.shape[0]), |
|
||||||
dst=img, |
|
||||||
flags=cv2.WARP_INVERSE_MAP) |
|
||||||
else: |
|
||||||
img.fill(0) |
|
||||||
|
|
||||||
height, width = img.shape[:2] |
|
||||||
img_resized = cv2.resize( |
|
||||||
img, (SCALE * width, SCALE * height), interpolation=cv2.INTER_CUBIC) |
|
||||||
# *** blits *** |
|
||||||
pygame.surfarray.blit_array(camera_surface, img_resized.swapaxes(0, 1)) |
|
||||||
screen.blit(camera_surface, (0, 0)) |
|
||||||
|
|
||||||
# this takes time...vsync or something |
|
||||||
pygame.display.flip() |
|
||||||
|
|
||||||
|
|
||||||
def get_arg_parser(): |
|
||||||
parser = argparse.ArgumentParser( |
|
||||||
description="Show replay data in a UI.", |
|
||||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter) |
|
||||||
|
|
||||||
parser.add_argument( |
|
||||||
"ip_address", |
|
||||||
nargs="?", |
|
||||||
default="127.0.0.1", |
|
||||||
help="The ip address on which to receive zmq messages.") |
|
||||||
|
|
||||||
parser.add_argument( |
|
||||||
"--frame-address", |
|
||||||
default=None, |
|
||||||
help="The ip address on which to receive zmq messages.") |
|
||||||
return parser |
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
args = get_arg_parser().parse_args(sys.argv[1:]) |
|
||||||
ui_thread(args.ip_address, args.frame_address) |
|
@ -1,98 +0,0 @@ |
|||||||
#!/usr/bin/env python |
|
||||||
from common.kalman.ned import ecef2geodetic |
|
||||||
|
|
||||||
import csv |
|
||||||
import numpy as np |
|
||||||
import webbrowser |
|
||||||
import os |
|
||||||
import sys |
|
||||||
import json |
|
||||||
import numpy.linalg as LA |
|
||||||
import gmplot |
|
||||||
from dateutil.parser import parse |
|
||||||
from common.numpy_helpers import deep_interp |
|
||||||
# import cvxpy as cvx |
|
||||||
MPH_TO_MS = 0.44704 |
|
||||||
|
|
||||||
|
|
||||||
def downsample(positions, speeds, start_idx, end_idx, dist): |
|
||||||
# TODO: save headings too |
|
||||||
track = [] |
|
||||||
last_position = positions[start_idx] |
|
||||||
valid_indeces = [] |
|
||||||
track_speeds = [] |
|
||||||
for pi in range(start_idx, end_idx): |
|
||||||
# only save points that are at least 10 cm far away |
|
||||||
if LA.norm(positions[pi] - last_position) >= dist: |
|
||||||
#print LA.norm(positions[pi] - last_position) |
|
||||||
last_position = positions[pi] |
|
||||||
track.append(positions[pi]) |
|
||||||
valid_indeces.append(pi) |
|
||||||
track_speeds.append(speeds[pi]) |
|
||||||
print(-start_idx + end_idx, len(valid_indeces)) |
|
||||||
# this compare the original point count vs the filtered count |
|
||||||
|
|
||||||
track = np.array(track) |
|
||||||
track_speeds = np.array(track_speeds) |
|
||||||
return track, track_speeds |
|
||||||
|
|
||||||
def converter(date): |
|
||||||
|
|
||||||
filename = "/home/batman/one/selfdrive/locationd/liveloc_dumps/" + date + "/canonical.csv" # Point one (OK!) |
|
||||||
|
|
||||||
c = csv.DictReader(open(filename, 'rb'), delimiter=',') |
|
||||||
|
|
||||||
start_time = None |
|
||||||
|
|
||||||
t = [] |
|
||||||
ll_positions = [] |
|
||||||
positions = [] |
|
||||||
sats = [] |
|
||||||
flag = [] |
|
||||||
speeds = [] |
|
||||||
|
|
||||||
for row in c: |
|
||||||
t.append(float(row['pctime'])) |
|
||||||
x = float(row['ecefX']) |
|
||||||
y = float(row['ecefY']) |
|
||||||
z = float(row['ecefZ']) |
|
||||||
ecef = np.array((x, y, z)) |
|
||||||
speeds.append(float(row['velSpeed'])) |
|
||||||
|
|
||||||
pos = ecef2geodetic(ecef) |
|
||||||
ll_positions.append(pos) |
|
||||||
positions.append(ecef) |
|
||||||
|
|
||||||
t = np.array(t) |
|
||||||
ll_positions = np.array(ll_positions) |
|
||||||
positions = np.array(positions) |
|
||||||
|
|
||||||
#distances = ll_positions[:,0:2] - START_POS[:2] |
|
||||||
#i_start = np.argmin(LA.norm(distances, axis=1)) |
|
||||||
|
|
||||||
#for i in range(i_start + 500): |
|
||||||
# distances[i] += np.array([100, 100]) |
|
||||||
#i_end = np.argmin(LA.norm(distances, axis=1)) |
|
||||||
|
|
||||||
i_start = 0 |
|
||||||
i_end = len(positions) |
|
||||||
|
|
||||||
print(i_start, i_end) |
|
||||||
track, track_speeds = downsample(positions, speeds, i_start, i_end, 0.2) |
|
||||||
ll_track = np.array([ecef2geodetic(pos) for pos in track]) |
|
||||||
|
|
||||||
track_struct = {} |
|
||||||
print(track_speeds.shape) |
|
||||||
print(track.shape) |
|
||||||
track_struct['race'] = np.hstack((track, |
|
||||||
np.expand_dims(track_speeds, axis=1), |
|
||||||
np.zeros((len(track_speeds), 1)))) |
|
||||||
|
|
||||||
f = open('/home/batman/one/selfdrive/controls/tracks/loop_city.npy', 'w') |
|
||||||
np.save(f, track_struct) |
|
||||||
f.close() |
|
||||||
print("SAVED!") |
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
converter(sys.argv[1]) |
|
@ -1,113 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
import os |
|
||||||
import zmq |
|
||||||
|
|
||||||
import cereal.messaging as messaging |
|
||||||
from cereal.services import service_list |
|
||||||
|
|
||||||
from panda.lib.panda import Panda |
|
||||||
from hexdump import hexdump |
|
||||||
import time |
|
||||||
|
|
||||||
def raw_panda(): |
|
||||||
p = Panda() |
|
||||||
print(p) |
|
||||||
|
|
||||||
p.set_uart_baud(2, 9600) |
|
||||||
p.set_uart_baud(3, 9600) |
|
||||||
|
|
||||||
p.set_uart_parity(2, 1) |
|
||||||
p.set_uart_parity(3, 1) |
|
||||||
|
|
||||||
p.set_uart_callback(2, 1) |
|
||||||
p.set_uart_callback(3, 1) |
|
||||||
|
|
||||||
idx = 0 |
|
||||||
while 1: |
|
||||||
""" |
|
||||||
dat = p.serial_read(2) |
|
||||||
if len(dat) > 0: |
|
||||||
print "2:", |
|
||||||
hexdump(dat) |
|
||||||
|
|
||||||
dat = p.serial_read(3) |
|
||||||
if len(dat) > 0: |
|
||||||
print "3:", |
|
||||||
hexdump(dat) |
|
||||||
|
|
||||||
print "read done, waiting" |
|
||||||
time.sleep(0.01) |
|
||||||
""" |
|
||||||
|
|
||||||
if idx%2 == 1: |
|
||||||
dat = "\x20\x80\xc0\xa0" |
|
||||||
else: |
|
||||||
dat = "\x00\x80\xc0\xc0" |
|
||||||
p.can_send(0, dat, 8) |
|
||||||
|
|
||||||
for r in p.can_recv(): |
|
||||||
if r[-1] in [8, 9]: |
|
||||||
print(r[-1], r[2].encode("hex")) |
|
||||||
|
|
||||||
time.sleep(0.01) |
|
||||||
idx += 1 |
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
#raw_panda() |
|
||||||
#exit(0) |
|
||||||
|
|
||||||
logcan = messaging.sub_sock('can') |
|
||||||
|
|
||||||
t1 = [] |
|
||||||
t2 = [] |
|
||||||
t3 = [] |
|
||||||
|
|
||||||
while len(t1) < 1000 or os.uname()[-1] == "aarch64": |
|
||||||
rr = messaging.recv_sock(logcan, wait=True) |
|
||||||
for c in rr.can: |
|
||||||
if c.src in [9] and len(c.dat) == 5: |
|
||||||
aa = map(lambda x: ord(x)&0x7f, c.dat) |
|
||||||
|
|
||||||
# checksum |
|
||||||
assert (-(aa[0]+aa[1]+aa[2]+aa[3]))&0x7f == aa[4] |
|
||||||
|
|
||||||
#print map(bin, aa[0:4]) |
|
||||||
|
|
||||||
aa[0] &= ~0x20 |
|
||||||
aa[1] &= ~0x20 |
|
||||||
|
|
||||||
st = (aa[0] << 5) + aa[1] |
|
||||||
if st >= 256: |
|
||||||
st = -(512-st) |
|
||||||
|
|
||||||
mt = ((aa[2] >> 3) << 7) + aa[3] |
|
||||||
if mt >= 512: |
|
||||||
mt = -(1024-mt) |
|
||||||
|
|
||||||
print(st, mt) |
|
||||||
t1.append(st) |
|
||||||
t2.append(mt) |
|
||||||
#print map(bin, aa), "apply", st |
|
||||||
|
|
||||||
if c.src in [8] and len(c.dat) == 4: |
|
||||||
aa = map(lambda x: ord(x)&0x7f, c.dat) |
|
||||||
|
|
||||||
# checksum |
|
||||||
assert (-(aa[0]+aa[1]+aa[2]))&0x7f == aa[3] |
|
||||||
|
|
||||||
aa[0] &= ~0x20 |
|
||||||
aa[1] &= ~0x20 |
|
||||||
|
|
||||||
st = (aa[0] << 5) + aa[1] |
|
||||||
if st >= 256: |
|
||||||
st = -(512-st) |
|
||||||
print(aa, "apply", st) |
|
||||||
|
|
||||||
t3.append(st) |
|
||||||
|
|
||||||
import matplotlib.pyplot as plt |
|
||||||
plt.plot(t1) |
|
||||||
plt.plot(t2) |
|
||||||
plt.plot(t3) |
|
||||||
plt.show() |
|
||||||
|
|
@ -1,79 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
|
|
||||||
import argparse |
|
||||||
import time |
|
||||||
import os |
|
||||||
|
|
||||||
from tqdm import tqdm |
|
||||||
|
|
||||||
from cereal.messaging import PubMaster, recv_one, sub_sock |
|
||||||
from cereal.services import service_list |
|
||||||
from tools.lib.logreader import LogReader |
|
||||||
from xx.chffr.lib.route import Route, RouteSegment |
|
||||||
from tools.lib.route_framereader import RouteFrameReader |
|
||||||
from xx.uncommon.column_store import save_dict_as_column_store |
|
||||||
from xx.pipeline.lib.log_time_series import append_dict |
|
||||||
from selfdrive.test.process_replay.compare_logs import save_log |
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
parser = argparse.ArgumentParser(description="Run visiond on segment") |
|
||||||
parser.add_argument("segment_name", help="The segment to run") |
|
||||||
parser.add_argument("output_path", help="The output file") |
|
||||||
|
|
||||||
args = parser.parse_args() |
|
||||||
segment = RouteSegment.from_canonical_name(args.segment_name) |
|
||||||
route = Route(segment._name._route_name) |
|
||||||
|
|
||||||
frame_id_lookup = {} |
|
||||||
frame_reader = RouteFrameReader(route.camera_paths(), None, frame_id_lookup, readahead=True) |
|
||||||
|
|
||||||
msgs = list(LogReader(segment.log_path)) |
|
||||||
|
|
||||||
pm = PubMaster(['liveCalibration', 'frame']) |
|
||||||
model_sock = sub_sock('model') |
|
||||||
|
|
||||||
# Read encodeIdx |
|
||||||
for msg in msgs: |
|
||||||
if msg.which() == 'encodeIdx': |
|
||||||
frame_id_lookup[msg.encodeIdx.frameId] = (msg.encodeIdx.segmentNum, msg.encodeIdx.segmentId) |
|
||||||
|
|
||||||
# Send some livecalibration messages to initalize visiond |
|
||||||
for msg in msgs: |
|
||||||
if msg.which() == 'liveCalibration': |
|
||||||
pm.send('liveCalibration', msg.as_builder()) |
|
||||||
|
|
||||||
time.sleep(1.0) |
|
||||||
values = {} |
|
||||||
|
|
||||||
out_msgs = [] |
|
||||||
for msg in tqdm(msgs): |
|
||||||
w = msg.which() |
|
||||||
|
|
||||||
if w == 'liveCalibration': |
|
||||||
pm.send(w, msg.as_builder()) |
|
||||||
|
|
||||||
if w == 'frame': |
|
||||||
msg = msg.as_builder() |
|
||||||
|
|
||||||
frame_id = msg.frame.frameId |
|
||||||
img = frame_reader.get(frame_id, pix_fmt="rgb24")[:,:,::-1] |
|
||||||
|
|
||||||
msg.frame.image = img.flatten().tobytes() |
|
||||||
pm.send(w, msg) |
|
||||||
|
|
||||||
model = recv_one(model_sock) |
|
||||||
model = model.as_builder() |
|
||||||
model.logMonoTime = 0 |
|
||||||
model = model.as_reader() |
|
||||||
out_msgs.append(model) |
|
||||||
|
|
||||||
save_log(args.output_path, out_msgs) |
|
||||||
|
|
||||||
# tm = model.logMonoTime / 1.0e9 |
|
||||||
# model = model.model |
|
||||||
# append_dict("model/data/path", tm, model.path.to_dict(), values) |
|
||||||
# append_dict("model/data/left_lane", tm, model.leftLane.to_dict(), values) |
|
||||||
# append_dict("model/data/right_lane", tm, model.rightLane.to_dict(), values) |
|
||||||
# append_dict("model/data/lead", tm, model.lead.to_dict(), values) |
|
||||||
|
|
||||||
# save_dict_as_column_store(values, os.path.join(args.output_path, "LiveVisionD", args.segment_name)) |
|
@ -1,68 +0,0 @@ |
|||||||
#!/usr/bin/env python |
|
||||||
|
|
||||||
import matplotlib |
|
||||||
matplotlib.use('TkAgg') |
|
||||||
import matplotlib.pyplot as plt |
|
||||||
|
|
||||||
import numpy as np |
|
||||||
import zmq |
|
||||||
from cereal.services import service_list |
|
||||||
from selfdrive.config import Conversions as CV |
|
||||||
import cereal.messaging as messaging |
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
live_map_sock = messaging.sub_sock(service_list['liveMapData'].port, conflate=True) |
|
||||||
plan_sock = messaging.sub_sock(service_list['plan'].port, conflate=True) |
|
||||||
|
|
||||||
plt.ion() |
|
||||||
fig = plt.figure(figsize=(8, 16)) |
|
||||||
ax = fig.add_subplot(2, 1, 1) |
|
||||||
ax.set_title('Map') |
|
||||||
|
|
||||||
SCALE = 1000 |
|
||||||
ax.set_xlim([-SCALE, SCALE]) |
|
||||||
ax.set_ylim([-SCALE, SCALE]) |
|
||||||
ax.set_xlabel('x [m]') |
|
||||||
ax.set_ylabel('y [m]') |
|
||||||
ax.grid(True) |
|
||||||
|
|
||||||
points_plt, = ax.plot([0.0], [0.0], "--xk") |
|
||||||
cur, = ax.plot([0.0], [0.0], "xr") |
|
||||||
|
|
||||||
speed_txt = ax.text(-500, 900, '') |
|
||||||
curv_txt = ax.text(-500, 775, '') |
|
||||||
|
|
||||||
ax = fig.add_subplot(2, 1, 2) |
|
||||||
ax.set_title('Curvature') |
|
||||||
curvature_plt, = ax.plot([0.0], [0.0], "--xk") |
|
||||||
ax.set_xlim([0, 500]) |
|
||||||
ax.set_ylim([0, 1e-2]) |
|
||||||
ax.set_xlabel('Distance along path [m]') |
|
||||||
ax.set_ylabel('Curvature [1/m]') |
|
||||||
ax.grid(True) |
|
||||||
|
|
||||||
plt.show() |
|
||||||
|
|
||||||
while True: |
|
||||||
m = messaging.recv_one_or_none(live_map_sock) |
|
||||||
p = messaging.recv_one_or_none(plan_sock) |
|
||||||
if p is not None: |
|
||||||
v = p.plan.vCurvature * CV.MS_TO_MPH |
|
||||||
speed_txt.set_text('Desired curvature speed: %.2f mph' % v) |
|
||||||
|
|
||||||
if m is not None: |
|
||||||
print("Current way id: %d" % m.liveMapData.wayId) |
|
||||||
curv_txt.set_text('Curvature valid: %s Dist: %03.0f m\nSpeedlimit valid: %s Speed: %.0f mph' % |
|
||||||
(str(m.liveMapData.curvatureValid), |
|
||||||
m.liveMapData.distToTurn, |
|
||||||
str(m.liveMapData.speedLimitValid), |
|
||||||
m.liveMapData.speedLimit * CV.MS_TO_MPH)) |
|
||||||
|
|
||||||
points_plt.set_xdata(m.liveMapData.roadX) |
|
||||||
points_plt.set_ydata(m.liveMapData.roadY) |
|
||||||
curvature_plt.set_xdata(m.liveMapData.roadCurvatureX) |
|
||||||
curvature_plt.set_ydata(m.liveMapData.roadCurvature) |
|
||||||
|
|
||||||
fig.canvas.draw() |
|
||||||
fig.canvas.flush_events() |
|
Loading…
Reference in new issue