Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
9e098e5
Add curvature learner atop latest stock_additions
sshane Aug 8, 2020
914e1b3
Clean up curvature learner, define values in dicts
sshane Aug 8, 2020
0f3d357
does this add or replace?
sshane Aug 8, 2020
c7fd2ce
add more of my data
sshane Aug 8, 2020
912569f
new tune, branch should be working now
sshane Aug 8, 2020
5b7fc4c
rearrange
sshane Aug 8, 2020
ed7d4c2
Up write freq
sshane Aug 8, 2020
1d9bd98
new tune, increase lr, and use curvature from start of path not car
sshane Aug 9, 2020
def0cb6
tune curvature bands thanks to trae! slightly less variance
sshane Aug 10, 2020
64c62be
make abs
sshane Aug 10, 2020
64c052c
this was most common for outer
sshane Aug 10, 2020
b1110cc
add kmeans clustering test file
sshane Aug 10, 2020
a789dc1
update
sshane Aug 10, 2020
69bed08
fix all zeros
sshane Aug 10, 2020
bc80f6e
add more data from trae!
sshane Aug 10, 2020
c89ab01
clean up cluster_curvature
sshane Aug 10, 2020
f740a12
add version and test file
sshane Aug 10, 2020
e949f98
fix scaling factor
sshane Aug 10, 2020
2dae221
add new clustering to curvature_learner.py
sshane Aug 10, 2020
12f239f
rewrite file if version is newer than current version
sshane Aug 10, 2020
730bd4b
debugging
sshane Aug 10, 2020
79fa973
temp fix
sshane Aug 10, 2020
bc024d0
temp fix
sshane Aug 10, 2020
2517862
fix
sshane Aug 10, 2020
d931b6b
revert, ready to test!
sshane Aug 10, 2020
90799ee
add more of trae's data
sshane Aug 10, 2020
b58f7d2
multiply cluster y coords by factor, don't need to keep doing it ever…
sshane Aug 10, 2020
d46ce0c
rename
sshane Aug 10, 2020
b8b2514
add timing
sshane Aug 11, 2020
69465d5
measure one second
sshane Aug 11, 2020
0919854
measure one second
sshane Aug 11, 2020
173ebfe
measure one second
sshane Aug 11, 2020
ea9fe36
revert
sshane Aug 11, 2020
5c22246
use list instead of dict
sshane Aug 11, 2020
7497c17
switching to list gave us about 5% speed increase! some clean up
sshane Aug 11, 2020
41a7336
lower min lr prob
sshane Aug 11, 2020
3c6f247
clean up
sshane Aug 11, 2020
4f25869
speed up learning rate
sshane Aug 11, 2020
79fe770
refactor
sshane Aug 11, 2020
961cc89
clean up
sshane Aug 11, 2020
aff8cec
remove old file
sshane Aug 12, 2020
1c71391
Revert "remove old file"
sshane Aug 12, 2020
e834207
Add more data!
sshane Aug 12, 2020
78b1aaa
refactor cluster_curvature a bit
sshane Aug 12, 2020
f41d89c
1 more cluster for low speed, more y weight
sshane Aug 12, 2020
96370e6
update version and clusters
sshane Aug 12, 2020
653512c
Revert INDI Prius Values (#163)
d412k5t412 Aug 12, 2020
9f0e16b
add Curvature Learner to readme
sshane Aug 12, 2020
6523bd8
Merge branch 'curv-learner' of https://github.com/ShaneSmiskol/openpi…
sshane Aug 12, 2020
e07de3d
update readme
sshane Aug 12, 2020
a45afb9
add cluster image
sshane Aug 12, 2020
4184196
fix
sshane Aug 12, 2020
39a54aa
fix
sshane Aug 12, 2020
a355754
fix
sshane Aug 12, 2020
3807aa6
center
sshane Aug 12, 2020
18c1314
Update README.md
sshane Aug 12, 2020
b5a7a38
Update README.md
sshane Aug 12, 2020
7bafe9a
update intro text!
sshane Aug 12, 2020
43bbdf2
add more info to features section
sshane Aug 12, 2020
7831452
update wording
sshane Aug 12, 2020
f05efb9
Add fast learning. each cluster in each direction gets ~2.3 minutes o…
sshane Aug 12, 2020
6478d30
bump version
sshane Aug 12, 2020
2bb5c83
create a folder for curvature_learner
sshane Aug 12, 2020
eb25862
remove old file
sshane Aug 12, 2020
1acb8e7
remove old file
sshane Aug 12, 2020
a38c5b8
lower learning rate and multiplier
sshane Aug 12, 2020
0977e30
tune clusters and fast learning rate
sshane Aug 12, 2020
4816e3a
add more data!
sshane Aug 12, 2020
8a9e8b8
some clean up and comments
sshane Aug 12, 2020
92fc2c4
only calculate abs(lat_pos) once, move direction calc to cluster_sample
sshane Aug 12, 2020
ce5a942
move function under update
sshane Aug 12, 2020
10fbee1
bump version
sshane Aug 12, 2020
42b5679
remove comment
sshane Aug 12, 2020
27a55f2
one less cluster
sshane Aug 12, 2020
29c732e
bump version
sshane Aug 12, 2020
2ae93be
30 -> 20 min
sshane Aug 13, 2020
571d33a
bump version
sshane Aug 13, 2020
dadaf2d
tune clusters and 90 seconds per cluster. up min curvature
sshane Aug 13, 2020
a6f6dc2
fix y axis factor
sshane Aug 13, 2020
855cce3
separate file to keep the offset file clean, add a param to toggle cu…
sshane Aug 13, 2020
5c66917
tune clusters and add cluster names back, strip leading and trailing 0's
sshane Aug 13, 2020
4a58a0a
whoops
sshane Aug 13, 2020
305f593
another fix!
sshane Aug 13, 2020
50a52e2
back to known good
sshane Aug 13, 2020
75d56ef
add distplot for min_angle as a curvature
sshane Aug 13, 2020
29582d0
Force battery temperature to 0 on comma two (#165)
d412k5t412 Aug 14, 2020
76438e5
copy with same name as old just to diffs are easier
sshane Aug 14, 2020
7d1300e
revert some settings to August 11th
sshane Aug 14, 2020
d1e1826
revert fast learning rate for now
sshane Aug 14, 2020
92bbd18
faster lr
sshane Aug 14, 2020
c639118
comment out fast learning for now
sshane Aug 14, 2020
ccea4d6
switch in curvature learner reverted to be similar to August 11th
sshane Aug 14, 2020
bcd58c8
bump version
sshane Aug 14, 2020
b3f1a87
move out
sshane Aug 14, 2020
7c9b257
remove for now
sshane Aug 14, 2020
f85a577
add a file to verify my logic is good
sshane Aug 14, 2020
ecbbd88
tune clusters and y axis factor
sshane Aug 14, 2020
10eedd5
slower learning
sshane Aug 14, 2020
5c45260
fully revert to original learning rate
sshane Aug 14, 2020
a0a47de
tune clusters and debug
sshane Aug 14, 2020
e326577
bump version
sshane Aug 14, 2020
95d7e36
debug
sshane Aug 14, 2020
c812e43
debug
sshane Aug 14, 2020
f9164bd
Debug
sshane Aug 15, 2020
593c5b3
Temp
sshane Aug 15, 2020
1486b1f
add debugging options
sshane Aug 15, 2020
01e3393
Make live
sshane Aug 15, 2020
d9d3904
Tune
sshane Aug 15, 2020
0256d0d
add straight line data
sshane Aug 15, 2020
7527ed2
remove
sshane Aug 15, 2020
9448aa0
some param tuning for cluster_curvature.py
sshane Aug 15, 2020
413b312
add center band/cluster. cluster will never be None
sshane Aug 15, 2020
80674f5
bump version
sshane Aug 15, 2020
a6dc01b
Disable center
sshane Aug 16, 2020
4678b49
Lower learning rate
sshane Aug 16, 2020
0d50d58
remove center cluster
sshane Aug 16, 2020
f17c4af
move lr_prob back
sshane Aug 16, 2020
9042907
revert
sshane Aug 16, 2020
62498fc
revert
sshane Aug 16, 2020
82e38b3
ensure float
sshane Aug 16, 2020
d8174fe
use old planner code to calculate true curvature of poly
sshane Sep 8, 2020
227ec4b
don't eval poly for direction detection and enable debugging
sshane Sep 8, 2020
9f9c5cc
remove debugging
sshane Sep 8, 2020
849ed1f
remove
sshane Sep 8, 2020
dd70245
fix
sshane Sep 8, 2020
6906057
Tune
sshane Sep 8, 2020
69aac72
Tune
sshane Sep 8, 2020
12e6c38
add direction
sshane Sep 8, 2020
012e858
the logic is correct, idk why it's oscillating
sshane Sep 8, 2020
79dd107
remove lr_prob restriction to test
sshane Sep 8, 2020
d7ca703
just so it's easier to read while debugging. positive values make it …
sshane Sep 13, 2020
7ce7f9f
use angle_steers since that will reduce likelihood of mistakes in cal…
sshane Sep 13, 2020
67b7953
fix
sshane Sep 13, 2020
2f093d5
fix
sshane Sep 13, 2020
ebe7f60
revert readme
sshane Sep 14, 2020
f97e275
revert opparams
sshane Sep 14, 2020
598d6ed
revert indi tuning
sshane Sep 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .media/curvature-clusters.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
144 changes: 144 additions & 0 deletions selfdrive/controls/lib/curvature_learner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import os
import math
import json
import numpy as np
from common.numpy_fast import clip
from common.realtime import sec_since_boot
from selfdrive.config import Conversions as CV
from common.op_params import opParams

# CurvatureLearner v4 by Zorrobyte
# Modified to add direction as a learning factor as well as clusters based on speed x curvature (lateral pos in 0.9 seconds)
# Clusters found with sklearn KMeans, this assigns more clusters to areas with more data and viceversa
# Version 5 due to json incompatibilities

GATHER_DATA = True
VERSION = 5.83

FT_TO_M = 0.3048


def find_distance(pt1, pt2):
x1, x2 = pt1[0], pt2[0]
y1, y2 = pt1[1], pt2[1]
return math.hypot(x2 - x1, y2 - y1)


# def eval_poly(poly, x):
# return poly[2]*x + poly[1]*x**2 + poly[0]*x**3


class CurvatureLearner:
def __init__(self):
self.op_params = opParams()
self.curvature_file = '/data/curvature_offsets.json'
# self.fast_learn_file = '/data/curvature_fast_learn.json'
rate = 1 / 20. # pathplanner is 20 hz
# self.learning_rate = 2.5833e-3 * rate
self.learning_rate = .8e-3 * rate # equivelent to x / 12000
self.write_frequency = 5 # in seconds
self.min_lr_prob = .5
self.min_speed = 15 * CV.MPH_TO_MS
self.TR = 1.2

self.y_axis_factor = 177.32840012 # weight y/curvature as much as speed
self.min_curvature = 0.02 # from map-angle-to-curvature

self.directions = ['left', 'right']
self.cluster_coords = [[10.05319434, 22.75010184], [11.56311835, 4.66648626], [13.57491646, 11.64505509], [18.36658232, 2.41488393],
[18.98342402, 7.59894138], [24.24826343, 7.03329587], [25.79352542, 2.00537934], [28.80542914, 5.36122992]]
# self.cluster_names = ['CLUSTER_{}'.format(idx) for idx in range(len(self.cluster_coords))]
self.cluster_names = ['22.5MPH-.13CURV', '25.9MPH-.03CURV', '30.4MPH-.07CURV', '41.1MPH-.01CURV', '42.5MPH-.04CURV', '54.2MPH-.04CURV', '57.7MPH-.01CURV', '64.4MPH-.03CURV']

# self.fast_learning_for = 90 # seconds per cluster # todo: finish this once curv-learner is working well
# self.fast_learning_for = round(self.fast_learning_for / rate) # speed up learning first time user uses curvature learner
# self.fast_lr_multiplier = 2. # 2x faster learning until ~1 MIN for each cluster
self._load_curvature()

def update(self, v_ego, d_poly, lane_probs, angle_steers):
self._gather_data(v_ego, d_poly, angle_steers)
offset = 0
if v_ego < self.min_speed or math.isnan(d_poly[0]) or len(d_poly) != 4 or not self.op_params.get('curvature_learner'):
return offset

cluster, direction, curvature = self.cluster_sample(v_ego, d_poly, angle_steers)
d_poly_offset = float(d_poly[3])
if cluster is not None:
lr_prob = lane_probs[0] + lane_probs[1] - lane_probs[0] * lane_probs[1]
# if lr_prob >= self.min_lr_prob: # only learn when lane lines are present; still use existing offset
if direction == 'right':
d_poly_offset = -d_poly_offset # d_poly's sign switches for oversteering in different directions

# lr = self.get_learning_rate(direction, cluster) # todo: faster learning for first ~minute per cluster
lr = self.learning_rate
self.learned_offsets[direction][cluster] -= d_poly_offset * self.learning_rate # the learning
offset = -self.learned_offsets[direction][cluster]
print('CLUSTER: {}\nOFFSET: {}\nCURV: {}\nDIR: {}\n-----'.format(cluster, round(offset, 6), round(curvature, 6), direction))


self._write_data()
return float(clip(offset, -0.05, 0.05))

def cluster_sample(self, v_ego, d_poly, angle_steers):
dist = v_ego * self.TR
path_x = np.arange(int(round(dist))) # eval curvature 0.9 seconds out (doesn't include path offset, just curvature)
y_p = 3 * d_poly[0] * path_x ** 2 + 2 * d_poly[1] * path_x + d_poly[2]
y_pp = 6 * d_poly[0] * path_x + 2 * d_poly[1]
curv = y_pp / (1. + y_p ** 2) ** 1.5
# direction = 'left' if curv[0] > 0 else 'right' # todo: [0] might be fastest, but explore mean if wrong often
direction = 'left' if angle_steers > 0 else 'right'

curv = np.sqrt(np.abs(curv))
curv = np.max(curv) # todo: takes maximum curvature, but could experiment with averaging. edit: mean doesn't decrease std that much, except with sharp band

closest_cluster = None
if curv >= self.min_curvature:
sample_coord = [v_ego, curv * self.y_axis_factor] # we multiply y so that the dist function weights x and y the same
dists = [find_distance(sample_coord, cluster_coord) for cluster_coord in self.cluster_coords] # todo: remove clusters far away based on v_ego to speed this up
closest_cluster = self.cluster_names[min(range(len(dists)), key=dists.__getitem__)]
return closest_cluster, direction, curv

# def get_learning_rate(self, direction, cluster): # todo: make sure this is correct
# lr = self.learning_rate
# fast_iter_left = self.fast_learn[direction][cluster]
# if not isinstance(fast_iter_left, str):
# if 1 <= fast_iter_left: # decrement until we reach 0
# self.fast_learn[direction][cluster] -= 1
# lr *= self.fast_lr_multiplier
# else: # mark done
# self.fast_learn[direction][cluster] = 'done'
# return lr

def _gather_data(self, v_ego, d_poly, angle_steers):
if GATHER_DATA:
with open('/data/curv_learner_data', 'a') as f:
f.write('{}\n'.format({'v_ego': v_ego, 'd_poly': list(d_poly), 'angle_steers': angle_steers}))

def _load_curvature(self):
self._last_write_time = 0
try:
with open(self.curvature_file, 'r') as f:
self.learned_offsets = json.load(f)
# with open(self.fast_learn_file, 'r') as f:
# self.fast_learn = json.load(f)
if 'version' in self.learned_offsets and self.learned_offsets['version'] == VERSION:
return
except:
pass
# can't read file, doesn't exist, or old version
# todo: old: self.learned_offsets = {d: {c: {'offset': 0., 'fast_learn': self.fast_learning_for} for c in self.cluster_names} for d in self.directions}
self.learned_offsets = {d: {c: 0. for c in self.cluster_names} for d in self.directions}
# self.fast_learn = {d: {c: self.fast_learning_for for c in self.cluster_names} for d in self.directions}
self.learned_offsets['version'] = VERSION # update version
self._write_data() # rewrite/create new file

def _write_data(self):
if sec_since_boot() - self._last_write_time >= self.write_frequency:
with open(self.curvature_file, 'w') as f:
f.write(json.dumps(self.learned_offsets, indent=2))
# with open(self.fast_learn_file, 'w') as f:
# f.write(json.dumps(self.fast_learn, indent=2))

os.chmod(self.curvature_file, 0o777)
# os.chmod(self.fast_learn_file, 0o777)
self._last_write_time = sec_since_boot()
Loading