1
1
#!/usr/bin/env python3
2
- import os
3
- import sys
4
- import signal
5
2
import numpy as np
6
3
from collections import deque , defaultdict
7
4
12
9
from openpilot .common .filter_simple import FirstOrderFilter
13
10
from openpilot .system .swaglog import cloudlog
14
11
from openpilot .selfdrive .controls .lib .vehicle_model import ACCELERATION_DUE_TO_GRAVITY
12
+ from openpilot .selfdrive .locationd .helpers import PointBuckets , ParameterEstimator
15
13
16
14
HISTORY = 5 # secs
17
15
POINTS_PER_BUCKET = 1500
@@ -43,56 +41,15 @@ def slope2rot(slope):
43
41
return np .array ([[cos , - sin ], [sin , cos ]])
44
42
45
43
46
- class NPQueue :
47
- def __init__ (self , maxlen , rowsize ):
48
- self .maxlen = maxlen
49
- self .arr = np .empty ((0 , rowsize ))
50
-
51
- def __len__ (self ):
52
- return len (self .arr )
53
-
54
- def append (self , pt ):
55
- if len (self .arr ) < self .maxlen :
56
- self .arr = np .append (self .arr , [pt ], axis = 0 )
57
- else :
58
- self .arr [:- 1 ] = self .arr [1 :]
59
- self .arr [- 1 ] = pt
60
-
61
-
62
- class PointBuckets :
63
- def __init__ (self , x_bounds , min_points , min_points_total ):
64
- self .x_bounds = x_bounds
65
- self .buckets = {bounds : NPQueue (maxlen = POINTS_PER_BUCKET , rowsize = 3 ) for bounds in x_bounds }
66
- self .buckets_min_points = dict (zip (x_bounds , min_points ))
67
- self .min_points_total = min_points_total
68
-
69
- def bucket_lengths (self ):
70
- return [len (v ) for v in self .buckets .values ()]
71
-
72
- def __len__ (self ):
73
- return sum (self .bucket_lengths ())
74
-
75
- def is_valid (self ):
76
- return all (len (v ) >= min_pts for v , min_pts in zip (self .buckets .values (), self .buckets_min_points .values ())) and (self .__len__ () >= self .min_points_total )
77
-
44
+ class TorqueBuckets (PointBuckets ):
78
45
def add_point (self , x , y ):
79
46
for bound_min , bound_max in self .x_bounds :
80
47
if (x >= bound_min ) and (x < bound_max ):
81
48
self .buckets [(bound_min , bound_max )].append ([x , 1.0 , y ])
82
49
break
83
50
84
- def get_points (self , num_points = None ):
85
- points = np .vstack ([x .arr for x in self .buckets .values ()])
86
- if num_points is None :
87
- return points
88
- return points [np .random .choice (np .arange (len (points )), min (len (points ), num_points ), replace = False )]
89
51
90
- def load_points (self , points ):
91
- for x , y in points :
92
- self .add_point (x , y )
93
-
94
-
95
- class TorqueEstimator :
52
+ class TorqueEstimator (ParameterEstimator ):
96
53
def __init__ (self , CP , decimated = False ):
97
54
self .hist_len = int (HISTORY / DT_MDL )
98
55
self .lag = CP .steerActuatorDelay + .2 # from controlsd
@@ -113,7 +70,7 @@ def __init__(self, CP, decimated=False):
113
70
self .offline_friction = 0.0
114
71
self .offline_latAccelFactor = 0.0
115
72
self .resets = 0.0
116
- self .use_params = CP .carName in ALLOWED_CARS
73
+ self .use_params = CP .carName in ALLOWED_CARS and CP . lateralTuning . which () == 'torque'
117
74
118
75
if CP .lateralTuning .which () == 'torque' :
119
76
self .offline_friction = CP .lateralTuning .torque .friction
@@ -135,7 +92,7 @@ def __init__(self, CP, decimated=False):
135
92
136
93
# try to restore cached params
137
94
params = Params ()
138
- params_cache = params .get ("LiveTorqueCarParams " )
95
+ params_cache = params .get ("CarParamsPrevRoute " )
139
96
torque_cache = params .get ("LiveTorqueParameters" )
140
97
if params_cache is not None and torque_cache is not None :
141
98
try :
@@ -158,7 +115,6 @@ def __init__(self, CP, decimated=False):
158
115
cloudlog .info ("restored torque params from cache" )
159
116
except Exception :
160
117
cloudlog .exception ("failed to restore cached torque params" )
161
- params .remove ("LiveTorqueCarParams" )
162
118
params .remove ("LiveTorqueParameters" )
163
119
164
120
self .filtered_params = {}
@@ -176,7 +132,11 @@ def reset(self):
176
132
self .resets += 1.0
177
133
self .decay = MIN_FILTER_DECAY
178
134
self .raw_points = defaultdict (lambda : deque (maxlen = self .hist_len ))
179
- self .filtered_points = PointBuckets (x_bounds = STEER_BUCKET_BOUNDS , min_points = self .min_bucket_points , min_points_total = self .min_points_total )
135
+ self .filtered_points = TorqueBuckets (x_bounds = STEER_BUCKET_BOUNDS ,
136
+ min_points = self .min_bucket_points ,
137
+ min_points_total = self .min_points_total ,
138
+ points_per_bucket = POINTS_PER_BUCKET ,
139
+ rowsize = 3 )
180
140
181
141
def estimate_params (self ):
182
142
points = self .filtered_points .get_points (self .fit_points )
@@ -256,34 +216,17 @@ def get_msg(self, valid=True, with_points=False):
256
216
return msg
257
217
258
218
259
- def main (sm = None , pm = None ):
219
+ def main ():
260
220
config_realtime_process ([0 , 1 , 2 , 3 ], 5 )
261
221
262
- if sm is None :
263
- sm = messaging .SubMaster (['carControl' , 'carState' , 'liveLocationKalman' ], poll = ['liveLocationKalman' ])
264
-
265
- if pm is None :
266
- pm = messaging .PubMaster (['liveTorqueParameters' ])
222
+ pm = messaging .PubMaster (['liveTorqueParameters' ])
223
+ sm = messaging .SubMaster (['carControl' , 'carState' , 'liveLocationKalman' ], poll = ['liveLocationKalman' ])
267
224
268
225
params = Params ()
269
226
CP = car .CarParams .from_bytes (params .get ("CarParams" , block = True ))
270
227
# with car.CarParams.from_bytes(params.get("CarParams", block=True)) as CP:
271
228
estimator = TorqueEstimator (CP )
272
229
273
- def cache_params (sig , frame ):
274
- signal .signal (sig , signal .SIG_DFL )
275
- cloudlog .warning ("caching torque params" )
276
-
277
- params = Params ()
278
- params .put ("LiveTorqueCarParams" , CP .as_builder ().to_bytes ())
279
-
280
- msg = estimator .get_msg (with_points = True )
281
- params .put ("LiveTorqueParameters" , msg .to_bytes ())
282
-
283
- sys .exit (0 )
284
- if "REPLAY" not in os .environ :
285
- signal .signal (signal .SIGINT , cache_params )
286
-
287
230
while True :
288
231
sm .update ()
289
232
if sm .all_checks ():
@@ -296,6 +239,10 @@ def cache_params(sig, frame):
296
239
if sm .frame % 5 == 0 :
297
240
pm .send ('liveTorqueParameters' , estimator .get_msg (valid = sm .all_checks ()))
298
241
242
+ # Cache points every 60 seconds while onroad
243
+ if sm .frame % 240 == 0 :
244
+ msg = estimator .get_msg (valid = sm .all_checks (), with_points = True )
245
+ params .put_nonblocking ("LiveTorqueParameters" , msg .to_bytes ())
299
246
300
247
if __name__ == "__main__" :
301
248
main ()
0 commit comments