Permalink
Browse files

openpilot v0.5.2 release

  • Loading branch information...
Vehicle Researcher
Vehicle Researcher committed Aug 20, 2018
1 parent db96b4b commit 0129a8a4ff8da5314e8e4d4d3336e89667ff6d54
Showing with 2,266 additions and 229 deletions.
  1. +0 −2 .gitignore
  2. +3 −3 CONTRIBUTING.md
  3. +6 −5 README.md
  4. +8 −0 RELEASES.md
  5. +1 −0 cereal/car.capnp
  6. +4 −1 cereal/log.capnp
  7. +29 −1 common/dbc.py
  8. +42 −0 common/ffi_wrapper.py
  9. +0 −3 common/params.py
  10. +115 −0 common/transformations/camera.py
  11. +112 −0 common/transformations/model.py
  12. +293 −0 common/transformations/orientation.py
  13. +7 −7 requirements_openpilot.txt
  14. +9 −0 selfdrive/can/common.h
  15. +16 −0 selfdrive/can/dbc_template.cc
  16. +9 −0 selfdrive/can/libdbc_py.py
  17. +18 −2 selfdrive/can/packer.cc
  18. +13 −5 selfdrive/can/packer.py
  19. +38 −0 selfdrive/can/parser.py
  20. +4 −1 selfdrive/can/process_dbc.py
  21. +0 −15 selfdrive/car/ford/carstate.py
  22. +22 −49 selfdrive/car/honda/carstate.py
  23. +1 −1 selfdrive/car/honda/interface.py
  24. +14 −0 selfdrive/car/honda/values.py
  25. +15 −33 selfdrive/car/toyota/carstate.py
  26. +1 −1 selfdrive/common/version.h
  27. +1 −1 selfdrive/controls/controlsd.py
  28. +5 −5 selfdrive/controls/lib/alertmanager.py
  29. +4 −33 selfdrive/controls/lib/driver_monitor.py
  30. +1 −1 selfdrive/controls/lib/vehicle_model.py
  31. +246 −0 selfdrive/locationd/calibrationd.py
  32. +41 −0 selfdrive/locationd/get_vp.c
  33. BIN selfdrive/loggerd/loggerd
  34. +5 −1 selfdrive/manager.py
  35. +8 −0 selfdrive/orbd/.gitignore
  36. +105 −0 selfdrive/orbd/Makefile
  37. +119 −0 selfdrive/orbd/dsp/freethedsp.c
  38. +39 −0 selfdrive/orbd/dsp/gen/calculator.h
  39. +613 −0 selfdrive/orbd/dsp/gen/calculator_stub.c
  40. BIN selfdrive/orbd/dsp/gen/libcalculator_skel.so
  41. +38 −0 selfdrive/orbd/extractor.h
  42. +191 −0 selfdrive/orbd/orbd.cc
  43. +13 −0 selfdrive/orbd/orbd_wrapper.sh
  44. BIN selfdrive/sensord/gpsd
  45. BIN selfdrive/sensord/sensord
  46. +57 −59 selfdrive/ui/ui.c
  47. BIN selfdrive/visiond/visiond
@@ -20,8 +20,6 @@ a.out
*.class
*.pyxbldc
*.vcd
lane.cpp
loc*.cpp
config.json
clcache

@@ -8,11 +8,11 @@ Most open source development activity is coordinated through our [slack](https:/

* Join our slack [slack.comma.ai](https://slack.comma.ai)
* Make sure you have a [GitHub account](https://github.com/signup/free)
* Fork the repository on GitHub
* Fork [our repositories](https://github.com/commaai) on GitHub

## Car Ports (openpilot)

We've released a guide for porting to Toyota cars [here](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6)
We've released a [Model Port guide](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) for porting to Toyota/Lexus models.

If you port openpilot to a substantially new car, you might be eligible for a bounty. See our bounties at [comma.ai/bounties.html](https://comma.ai/bounties.html)
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84). You might also be eligible for a bounty. See our bounties at [comma.ai/bounties.html](https://comma.ai/bounties.html)

@@ -53,12 +53,13 @@ Supported Cars
| Honda | Civic 2017 | Honda Sensing | Yes | Yes | 0mph | 12mph |
| Honda | Civic 2017 *(Hatch)* | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | Civic 2018 | Honda Sensing | Yes | Yes | 0mph | 12mph |
| Honda | CR-V 2015 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | CR-V 2016 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | Civic 2018 *(Hatch)* | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | CR-V 2015 | Touring | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | CR-V 2016 | Touring | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | CR-V 2017 | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | CR-V 2018 | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | Odyssey 2017 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | Odyssey 2018 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | Odyssey 2017 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 0mph |
| Honda | Odyssey 2018 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 0mph |
| Honda | Pilot 2017 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | Pilot 2018 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
| Honda | Ridgeline 2017 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph |
@@ -96,7 +97,7 @@ Community Maintained Cars

[[Honda Fit Pull Request]](https://github.com/commaai/openpilot/pull/266).

Community Maintained Cars are not confirmed by comma.ai to meet our safety model. Be extra cautious using them.
Community Maintained Cars are not confirmed by comma.ai to meet our [safety model](https://github.com/commaai/openpilot/blob/devel/SAFETY.md). Be extra cautious using them.

In Progress Cars
------
@@ -1,3 +1,11 @@
Version 0.5.2 (2018-08-16)
========================
* New calibration: more accurate, a lot faster, open source!
* Enable orbd
* Add little endian support to CAN packer
* Fix fingerprint for Honda Accord 1.5T
* Improve driver monitoring model

Version 0.5.1 (2018-08-01)
========================
* Fix radar error on Civic sedan 2018
@@ -309,6 +309,7 @@ struct CarParams {
cadillac @7;
hyundai @8;
chrysler @9;
tesla @10;
}

# things about the car in the manual
@@ -331,13 +331,16 @@ struct Live20Data {
}

struct LiveCalibrationData {
# deprecated
warpMatrix @0 :List(Float32);
# camera_frame_from_model_frame
warpMatrix2 @5 :List(Float32);
calStatus @1 :Int8;
calCycle @2 :Int32;
calPerc @3 :Int8;

# Maps car space to normalized image space.
# view_frame_from_road_frame
# ui's is inversed needs new
extrinsicMatrix @4 :List(Float32);
}

@@ -4,7 +4,7 @@
import bitstring
import sys
import numbers
from collections import namedtuple
from collections import namedtuple, defaultdict

def int_or_float(s):
# return number, trying to maintain int format
@@ -28,6 +28,7 @@ def __init__(self, fn):
bo_regexp = re.compile(r"^BO\_ (\w+) (\w+) *: (\w+) (\w+)")
sg_regexp = re.compile(r"^SG\_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)")
sgm_regexp = re.compile(r"^SG\_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)")
val_regexp = re.compile(r"VAL\_ (\w+) (\w+) (\s*[-+]?[0-9]+\s+\".+?\"[^;]*)")

# A dictionary which maps message ids to tuples ((name, size), signals).
# name is the ASCII name of the message.
@@ -36,6 +37,9 @@ def __init__(self, fn):
# signals is a list of DBCSignal in order of increasing start_bit.
self.msgs = {}

# A dictionary which maps message ids to a list of tuples (signal name, definition value pairs)
self.def_vals = defaultdict(list)

# lookup to bit reverse each byte
self.bits_index = [(i & ~0b111) + ((-i-1) & 0b111) for i in xrange(64)]

@@ -81,6 +85,30 @@ def __init__(self, fn):
DBCSignal(sgname, start_bit, signal_size, is_little_endian,
is_signed, factor, offset, tmin, tmax, units))

if l.startswith("VAL_ "):
# new signal value/definition
dat = val_regexp.match(l)

if dat is None:
print "bad VAL", l
ids = int(dat.group(1), 0) # could be hex
sgname = dat.group(2)
defvals = dat.group(3)

defvals = defvals.replace("?","\?") #escape sequence in C++
defvals = defvals.split('"')[:-1]

defs = defvals[1::2]
#cleanup, convert to UPPER_CASE_WITH_UNDERSCORES
for i,d in enumerate(defs):
d = defs[i].strip().upper()
defs[i] = d.replace(" ","_")

defvals[1::2] = defs
defvals = '"'+"".join(str(i) for i in defvals)+'"'

self.def_vals[ids].append((sgname, defvals))

for msg in self.msgs.viewvalues():
msg[1].sort(key=lambda x: x.start_bit)

@@ -0,0 +1,42 @@
import os
import sys
import fcntl
import hashlib
from cffi import FFI

TMPDIR = "/tmp/ccache"

def ffi_wrap(name, c_code, c_header, tmpdir=TMPDIR):
cache = name + "_" + hashlib.sha1(c_code).hexdigest()
try:
os.mkdir(tmpdir)
except OSError:
pass

fd = os.open(tmpdir, 0)
fcntl.flock(fd, fcntl.LOCK_EX)
try:
sys.path.append(tmpdir)
try:
mod = __import__(cache)
except Exception:
print "cache miss", cache
compile_code(cache, c_code, c_header, tmpdir)
mod = __import__(cache)
finally:
os.close(fd)

return mod.ffi, mod.lib

def compile_code(name, c_code, c_header, directory):
ffibuilder = FFI()
ffibuilder.set_source(name, c_code, source_extension='.cpp')
ffibuilder.cdef(c_header)
os.environ['OPT'] = "-fwrapv -O2 -DNDEBUG -std=c++11"
os.environ['CFLAGS'] = ""
ffibuilder.compile(verbose=True, debug=False, tmpdir=directory)

def wrap_compiled(name, directory):
sys.path.append(directory)
mod = __import__(name)
return mod.ffi, mod.lib
@@ -66,9 +66,6 @@ class UnknownKeyName(Exception):
# written: visiond
# read: visiond, controlsd
"CalibrationParams": TxType.PERSISTENT,
# written: visiond
# read: visiond, ui
"CloudCalibration": TxType.PERSISTENT,
# written: controlsd
# read: radard
"CarParams": TxType.CLEAR_ON_CAR_START,
@@ -0,0 +1,115 @@
import numpy as np
import common.transformations.orientation as orient

FULL_FRAME_SIZE = (1164, 874)
W, H = FULL_FRAME_SIZE[0], FULL_FRAME_SIZE[1]
eon_focal_length = FOCAL = 910.0

# aka 'K' aka camera_frame_from_view_frame
eon_intrinsics = np.array([
[FOCAL, 0., W/2.],
[ 0., FOCAL, H/2.],
[ 0., 0., 1.]])

# aka 'K_inv' aka view_frame_from_camera_frame
eon_intrinsics_inv = np.linalg.inv(eon_intrinsics)


# device/mesh : x->forward, y-> right, z->down
# view : x->right, y->down, z->forward
device_frame_from_view_frame = np.array([
[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.]
])
view_frame_from_device_frame = device_frame_from_view_frame.T


def get_calib_from_vp(vp):
vp_norm = normalize(vp)
yaw_calib = np.arctan(vp_norm[0])
pitch_calib = np.arctan(vp_norm[1]*np.cos(yaw_calib))
# TODO should be, this but written
# to be compatible with meshcalib and
# get_view_frame_from_road_fram
#pitch_calib = -np.arctan(vp_norm[1]*np.cos(yaw_calib))
roll_calib = 0
return roll_calib, pitch_calib, yaw_calib

# aka 'extrinsic_matrix'
# road : x->forward, y -> left, z->up
def get_view_frame_from_road_frame(roll, pitch, yaw, height):
# TODO
# calibration pitch is currently defined
# opposite to pitch in device frame
pitch = -pitch
device_from_road = orient.rot_from_euler([roll, pitch, yaw]).dot(np.diag([1, -1, -1]))
view_from_road = view_frame_from_device_frame.dot(device_from_road)
return np.hstack((view_from_road, [[0], [height], [0]]))


def vp_from_ke(m):
"""
Computes the vanishing point from the product of the intrinsic and extrinsic
matrices C = KE.
The vanishing point is defined as lim x->infinity C (x, 0, 0, 1).T
"""
return (m[0, 0]/m[2,0], m[1,0]/m[2,0])

def roll_from_ke(m):
# note: different from calibration.h/RollAnglefromKE: i think that one's just wrong
return np.arctan2(-(m[1, 0] - m[1, 1] * m[2, 0] / m[2, 1]),
-(m[0, 0] - m[0, 1] * m[2, 0] / m[2, 1]))

def normalize(img_pts):
# normalizes image coordinates
# accepts single pt or array of pts
img_pts = np.array(img_pts)
input_shape = img_pts.shape
img_pts = np.atleast_2d(img_pts)
img_pts = np.hstack((img_pts, np.ones((img_pts.shape[0],1))))
img_pts_normalized = eon_intrinsics_inv.dot(img_pts.T).T
img_pts_normalized[(img_pts < 0).any(axis=1)] = np.nan
return img_pts_normalized[:,:2].reshape(input_shape)

def denormalize(img_pts):
# denormalizes image coordinates
# accepts single pt or array of pts
img_pts = np.array(img_pts)
input_shape = img_pts.shape
img_pts = np.atleast_2d(img_pts)
img_pts = np.hstack((img_pts, np.ones((img_pts.shape[0],1))))
img_pts_denormalized = eon_intrinsics.dot(img_pts.T).T
img_pts_denormalized[img_pts_denormalized[:,0] > W] = np.nan
img_pts_denormalized[img_pts_denormalized[:,0] < 0] = np.nan
img_pts_denormalized[img_pts_denormalized[:,1] > H] = np.nan
img_pts_denormalized[img_pts_denormalized[:,1] < 0] = np.nan
return img_pts_denormalized[:,:2].reshape(input_shape)

def device_from_ecef(pos_ecef, orientation_ecef, pt_ecef):
# device from ecef frame
# device frame is x -> forward, y-> right, z -> down
# accepts single pt or array of pts
input_shape = pt_ecef.shape
pt_ecef = np.atleast_2d(pt_ecef)
ecef_from_device_rot = orient.rotations_from_quats(orientation_ecef)
device_from_ecef_rot = ecef_from_device_rot.T
pt_ecef_rel = pt_ecef - pos_ecef
pt_device = np.einsum('jk,ik->ij', device_from_ecef_rot, pt_ecef_rel)
return pt_device.reshape(input_shape)

def img_from_device(pt_device):
# img coordinates from pts in device frame
# first transforms to view frame, then to img coords
# accepts single pt or array of pts
input_shape = pt_device.shape
pt_device = np.atleast_2d(pt_device)
pt_view = np.einsum('jk,ik->ij', view_frame_from_device_frame, pt_device)

# This function should never return negative depths
pt_view[pt_view[:,2] < 0] = np.nan

pt_img = pt_view/pt_view[:,2:3]
return pt_img.reshape(input_shape)[:,:2]

Oops, something went wrong.

0 comments on commit 0129a8a

Please sign in to comment.