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