1
1
#include < cstdio>
2
2
#include < cstdlib>
3
3
#include < mutex>
4
+ #include < cmath>
4
5
5
6
#include < eigen3/Eigen/Dense>
6
7
15
16
16
17
ExitHandler do_exit;
17
18
18
- mat3 update_calibration (cereal::LiveCalibrationData::Reader live_calib, bool wide_camera) {
19
+ mat3 update_calibration (Eigen::Matrix< float , 3 , 4 > &extrinsics, bool wide_camera, bool bigmodel_frame ) {
19
20
/*
20
21
import numpy as np
21
22
from common.transformations.model import medmodel_frame_from_road_frame
22
23
medmodel_frame_from_ground = medmodel_frame_from_road_frame[:, (0, 1, 3)]
23
24
ground_from_medmodel_frame = np.linalg.inv(medmodel_frame_from_ground)
24
25
*/
25
- static const auto ground_from_medmodel_frame = (Eigen::Matrix<float , 3 , 3 >() <<
26
- 0.00000000e+00 , 0.00000000e+00 , 1.00000000e+00 ,
26
+ static const auto ground_from_medmodel_frame = (Eigen::Matrix<float , 3 , 3 >() <<
27
+ 0.00000000e+00 , 0.00000000e+00 , 1.00000000e+00 ,
27
28
-1.09890110e-03 , 0.00000000e+00 , 2.81318681e-01 ,
28
29
-1.84808520e-20 , 9.00738606e-04 , -4.28751576e-02 ).finished ();
29
30
31
+ static const auto ground_from_sbigmodel_frame = (Eigen::Matrix<float , 3 , 3 >() <<
32
+ 0.00000000e+00 , 7.31372216e-19 , 1.00000000e+00 ,
33
+ -2.19780220e-03 , 4.11497335e-19 , 5.62637363e-01 ,
34
+ -5.46146580e-20 , 1.80147721e-03 , -2.73464241e-01 ).finished ();
35
+
30
36
static const auto cam_intrinsics = Eigen::Matrix<float , 3 , 3 , Eigen::RowMajor>(wide_camera ? ecam_intrinsic_matrix.v : fcam_intrinsic_matrix.v );
31
37
static const mat3 yuv_transform = get_model_yuv_transform ();
32
38
33
- auto extrinsic_matrix = live_calib.getExtrinsicMatrix ();
34
- Eigen::Matrix<float , 3 , 4 > extrinsic_matrix_eigen;
35
- for (int i = 0 ; i < 4 *3 ; i++) {
36
- extrinsic_matrix_eigen (i / 4 , i % 4 ) = extrinsic_matrix[i];
37
- }
38
-
39
- auto camera_frame_from_road_frame = cam_intrinsics * extrinsic_matrix_eigen;
39
+ auto ground_from_model_frame = bigmodel_frame ? ground_from_sbigmodel_frame : ground_from_medmodel_frame;
40
+ auto camera_frame_from_road_frame = cam_intrinsics * extrinsics;
40
41
Eigen::Matrix<float , 3 , 3 > camera_frame_from_ground;
41
42
camera_frame_from_ground.col (0 ) = camera_frame_from_road_frame.col (0 );
42
43
camera_frame_from_ground.col (1 ) = camera_frame_from_road_frame.col (1 );
43
44
camera_frame_from_ground.col (2 ) = camera_frame_from_road_frame.col (3 );
44
45
45
- auto warp_matrix = camera_frame_from_ground * ground_from_medmodel_frame ;
46
+ auto warp_matrix = camera_frame_from_ground * ground_from_model_frame ;
46
47
mat3 transform = {};
47
48
for (int i=0 ; i<3 *3 ; i++) {
48
49
transform.v [i] = warp_matrix (i / 3 , i % 3 );
49
50
}
50
51
return matmul3 (yuv_transform, transform);
51
52
}
52
53
53
- void run_model (ModelState &model, VisionIpcClient &vipc_client, bool wide_camera ) {
54
+ void run_model (ModelState &model, VisionIpcClient &vipc_client_main, VisionIpcClient &vipc_client_extra, bool main_wide_camera, bool use_extra, bool use_extra_client ) {
54
55
// messaging
55
56
PubMaster pm ({" modelV2" , " cameraOdometry" });
56
57
SubMaster sm ({" lateralPlan" , " roadCameraState" , " liveCalibration" });
@@ -62,20 +63,80 @@ void run_model(ModelState &model, VisionIpcClient &vipc_client, bool wide_camera
62
63
double last = 0 ;
63
64
uint32_t run_count = 0 ;
64
65
65
- mat3 model_transform = {};
66
+ mat3 model_transform_main = {};
67
+ mat3 model_transform_extra = {};
66
68
bool live_calib_seen = false ;
67
69
70
+ VisionBuf *buf_main = nullptr ;
71
+ VisionBuf *buf_extra = nullptr ;
72
+
73
+ VisionIpcBufExtra meta_main = {0 };
74
+ VisionIpcBufExtra meta_extra = {0 };
75
+
68
76
while (!do_exit) {
69
- VisionIpcBufExtra extra = {};
70
- VisionBuf *buf = vipc_client.recv (&extra);
71
- if (buf == nullptr ) continue ;
77
+ // TODO: change sync logic to use timestamp start of frame in case camerad skips a frame
78
+ // log frame id in model packet
79
+
80
+ // Keep receiving frames until we are at least 1 frame ahead of previous extra frame
81
+ while (meta_main.frame_id <= meta_extra.frame_id ) {
82
+ buf_main = vipc_client_main.recv (&meta_main);
83
+ if (meta_main.frame_id <= meta_extra.frame_id ) {
84
+ LOGE (" main camera behind! main: %d (%.5f), extra: %d (%.5f)" ,
85
+ meta_main.frame_id , double (meta_main.timestamp_sof ) / 1e9 ,
86
+ meta_extra.frame_id , double (meta_extra.timestamp_sof ) / 1e9 );
87
+ }
88
+
89
+ if (buf_main == nullptr ) break ;
90
+ }
91
+
92
+ if (buf_main == nullptr ) {
93
+ LOGE (" vipc_client_main no frame" );
94
+ continue ;
95
+ }
96
+
97
+ if (use_extra_client) {
98
+ // Keep receiving extra frames until frame id matches main camera
99
+ do {
100
+ buf_extra = vipc_client_extra.recv (&meta_extra);
101
+
102
+ if (meta_main.frame_id > meta_extra.frame_id ) {
103
+ LOGE (" extra camera behind! main: %d (%.5f), extra: %d (%.5f)" ,
104
+ meta_main.frame_id , double (meta_main.timestamp_sof ) / 1e9 ,
105
+ meta_extra.frame_id , double (meta_extra.timestamp_sof ) / 1e9 );
106
+ }
107
+ } while (buf_extra != nullptr && meta_main.frame_id > meta_extra.frame_id );
108
+
109
+ if (buf_extra == nullptr ) {
110
+ LOGE (" vipc_client_extra no frame" );
111
+ continue ;
112
+ }
113
+
114
+ if (meta_main.frame_id != meta_extra.frame_id || std::abs ((int64_t )meta_main.timestamp_sof - (int64_t )meta_extra.timestamp_sof ) > 10000000ULL ) {
115
+ LOGE (" frames out of sync! main: %d (%.5f), extra: %d (%.5f)" ,
116
+ meta_main.frame_id , double (meta_main.timestamp_sof ) / 1e9 ,
117
+ meta_extra.frame_id , double (meta_extra.timestamp_sof ) / 1e9 );
118
+ }
119
+ } else {
120
+ // Use single camera
121
+ buf_extra = buf_main;
122
+ meta_extra = meta_main;
123
+ }
72
124
73
125
// TODO: path planner timeout?
74
126
sm.update (0 );
75
127
int desire = ((int )sm[" lateralPlan" ].getLateralPlan ().getDesire ());
76
128
frame_id = sm[" roadCameraState" ].getRoadCameraState ().getFrameId ();
77
129
if (sm.updated (" liveCalibration" )) {
78
- model_transform = update_calibration (sm[" liveCalibration" ].getLiveCalibration (), wide_camera);
130
+ auto extrinsic_matrix = sm[" liveCalibration" ].getLiveCalibration ().getExtrinsicMatrix ();
131
+ Eigen::Matrix<float , 3 , 4 > extrinsic_matrix_eigen;
132
+ for (int i = 0 ; i < 4 *3 ; i++) {
133
+ extrinsic_matrix_eigen (i / 4 , i % 4 ) = extrinsic_matrix[i];
134
+ }
135
+
136
+ model_transform_main = update_calibration (extrinsic_matrix_eigen, main_wide_camera, false );
137
+ if (use_extra) {
138
+ model_transform_extra = update_calibration (extrinsic_matrix_eigen, Hardware::TICI (), true );
139
+ }
79
140
live_calib_seen = true ;
80
141
}
81
142
@@ -85,13 +146,12 @@ void run_model(ModelState &model, VisionIpcClient &vipc_client, bool wide_camera
85
146
}
86
147
87
148
double mt1 = millis_since_boot ();
88
- ModelOutput *model_output = model_eval_frame (&model, buf->buf_cl , buf->width , buf->height ,
89
- model_transform, vec_desire);
149
+ ModelOutput *model_output = model_eval_frame (&model, buf_main, buf_extra, model_transform_main, model_transform_extra, vec_desire);
90
150
double mt2 = millis_since_boot ();
91
151
float model_execution_time = (mt2 - mt1) / 1000.0 ;
92
152
93
153
// tracked dropped frames
94
- uint32_t vipc_dropped_frames = extra .frame_id - last_vipc_frame_id - 1 ;
154
+ uint32_t vipc_dropped_frames = meta_main .frame_id - last_vipc_frame_id - 1 ;
95
155
float frames_dropped = frame_dropped_filter.update ((float )std::min (vipc_dropped_frames, 10U ));
96
156
if (run_count < 10 ) { // let frame drops warm up
97
157
frame_dropped_filter.reset (0 );
@@ -101,13 +161,13 @@ void run_model(ModelState &model, VisionIpcClient &vipc_client, bool wide_camera
101
161
102
162
float frame_drop_ratio = frames_dropped / (1 + frames_dropped);
103
163
104
- model_publish (pm, extra .frame_id , frame_id, frame_drop_ratio, *model_output, extra .timestamp_eof , model_execution_time,
164
+ model_publish (pm, meta_main .frame_id , frame_id, frame_drop_ratio, *model_output, meta_main .timestamp_eof , model_execution_time,
105
165
kj::ArrayPtr<const float >(model.output .data (), model.output .size ()), live_calib_seen);
106
- posenet_publish (pm, extra .frame_id , vipc_dropped_frames, *model_output, extra .timestamp_eof , live_calib_seen);
166
+ posenet_publish (pm, meta_main .frame_id , vipc_dropped_frames, *model_output, meta_main .timestamp_eof , live_calib_seen);
107
167
108
168
// printf("model process: %.2fms, from last %.2fms, vipc_frame_id %u, frame_id, %u, frame_drop %.3f\n", mt2 - mt1, mt1 - last, extra.frame_id, frame_id, frame_drop_ratio);
109
169
last = mt1;
110
- last_vipc_frame_id = extra .frame_id ;
170
+ last_vipc_frame_id = meta_main .frame_id ;
111
171
}
112
172
}
113
173
@@ -120,28 +180,42 @@ int main(int argc, char **argv) {
120
180
assert (ret == 0 );
121
181
}
122
182
123
- bool wide_camera = Hardware::TICI () ? Params ().getBool (" EnableWideCamera" ) : false ;
183
+ bool main_wide_camera = Hardware::TICI () ? Params ().getBool (" EnableWideCamera" ) : false ;
184
+ bool use_extra = USE_EXTRA;
185
+ bool use_extra_client = Hardware::TICI () && use_extra && !main_wide_camera;
124
186
125
187
// cl init
126
188
cl_device_id device_id = cl_get_device_id (CL_DEVICE_TYPE_DEFAULT);
127
189
cl_context context = CL_CHECK_ERR (clCreateContext (NULL , 1 , &device_id, NULL , NULL , &err));
128
190
129
191
// init the models
130
192
ModelState model;
131
- model_init (&model, device_id, context);
193
+ model_init (&model, device_id, context, use_extra );
132
194
LOGW (" models loaded, modeld starting" );
133
195
134
- VisionIpcClient vipc_client = VisionIpcClient (" camerad" , wide_camera ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD, true , device_id, context);
135
- while (!do_exit && !vipc_client.connect (false )) {
196
+ VisionIpcClient vipc_client_main = VisionIpcClient (" camerad" , main_wide_camera ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD, true , device_id, context);
197
+ VisionIpcClient vipc_client_extra = VisionIpcClient (" camerad" , VISION_STREAM_WIDE_ROAD, false , device_id, context);
198
+
199
+ while (!do_exit && !vipc_client_main.connect (false )) {
200
+ util::sleep_for (100 );
201
+ }
202
+
203
+ while (!do_exit && use_extra_client && !vipc_client_extra.connect (false )) {
136
204
util::sleep_for (100 );
137
205
}
138
206
139
207
// run the models
140
208
// vipc_client.connected is false only when do_exit is true
141
- if (vipc_client.connected ) {
142
- const VisionBuf *b = &vipc_client.buffers [0 ];
143
- LOGW (" connected with buffer size: %d (%d x %d)" , b->len , b->width , b->height );
144
- run_model (model, vipc_client, wide_camera);
209
+ if (!do_exit) {
210
+ const VisionBuf *b = &vipc_client_main.buffers [0 ];
211
+ LOGW (" connected main cam with buffer size: %d (%d x %d)" , b->len , b->width , b->height );
212
+
213
+ if (use_extra_client) {
214
+ const VisionBuf *wb = &vipc_client_extra.buffers [0 ];
215
+ LOGW (" connected extra cam with buffer size: %d (%d x %d)" , wb->len , wb->width , wb->height );
216
+ }
217
+
218
+ run_model (model, vipc_client_main, vipc_client_extra, main_wide_camera, use_extra, use_extra_client);
145
219
}
146
220
147
221
model_free (&model);
0 commit comments