53 pva_buffer_size_ = 150;
55 map_height_time_ = 0.0;
57 novatel_heading_time_ = 0.0;
64 &imu_gnssant_extrinsic_);
66 AERROR <<
"IntegratedLocalization: Fail to access the lever arm "
67 "between imu and gnss extrinsic file: "
70 AINFO <<
"gnss and imu lever arm in vehicle frame: "
71 <<
" " << imu_gnssant_extrinsic_.
ant_num <<
" "
72 << imu_gnssant_extrinsic_.
transform_1.translation()[0] <<
" "
73 << imu_gnssant_extrinsic_.
transform_1.translation()[1] <<
" "
74 << imu_gnssant_extrinsic_.
transform_1.translation()[2] <<
" "
75 << imu_gnssant_extrinsic_.
transform_2.translation()[0] <<
" "
76 << imu_gnssant_extrinsic_.
transform_2.translation()[1] <<
" "
77 << imu_gnssant_extrinsic_.
transform_2.translation()[2];
79 AINFO <<
"the ant_imu_leverarm_file does not existence!";
82 double vehicle_to_imu_quatern[4] = {
86 double dcm[3][3] = {0.0};
88 double lever_arm_x = imu_gnssant_extrinsic_.
transform_1.translation()[0];
89 double lever_arm_y = imu_gnssant_extrinsic_.
transform_1.translation()[1];
90 double lever_arm_z = imu_gnssant_extrinsic_.
transform_1.translation()[2];
92 imu_gnssant_extrinsic_.
transform_1.translation()[0] =
93 dcm[0][0] * lever_arm_x + dcm[0][1] * lever_arm_y +
94 dcm[0][2] * lever_arm_z;
95 imu_gnssant_extrinsic_.
transform_1.translation()[1] =
96 dcm[1][0] * lever_arm_x + dcm[1][1] * lever_arm_y +
97 dcm[1][2] * lever_arm_z;
98 imu_gnssant_extrinsic_.
transform_1.translation()[2] =
99 dcm[2][0] * lever_arm_x + dcm[2][1] * lever_arm_y +
100 dcm[2][2] * lever_arm_z;
102 lever_arm_x = imu_gnssant_extrinsic_.
transform_2.translation()[0];
103 lever_arm_y = imu_gnssant_extrinsic_.
transform_2.translation()[1];
104 lever_arm_z = imu_gnssant_extrinsic_.
transform_2.translation()[2];
106 imu_gnssant_extrinsic_.
transform_2.translation()[0] =
107 dcm[0][0] * lever_arm_x + dcm[0][1] * lever_arm_y +
108 dcm[0][2] * lever_arm_z;
109 imu_gnssant_extrinsic_.
transform_2.translation()[1] =
110 dcm[1][0] * lever_arm_x + dcm[1][1] * lever_arm_y +
111 dcm[1][2] * lever_arm_z;
112 imu_gnssant_extrinsic_.
transform_2.translation()[2] =
113 dcm[2][0] * lever_arm_x + dcm[2][1] * lever_arm_y +
114 dcm[2][2] * lever_arm_z;
116 AINFO <<
"gnss and imu lever arm in imu frame: "
117 <<
" " << imu_gnssant_extrinsic_.
ant_num <<
" "
118 << imu_gnssant_extrinsic_.
transform_1.translation()[0] <<
" "
119 << imu_gnssant_extrinsic_.
transform_1.translation()[1] <<
" "
120 << imu_gnssant_extrinsic_.
transform_1.translation()[2] <<
" "
121 << imu_gnssant_extrinsic_.
transform_2.translation()[0] <<
" "
122 << imu_gnssant_extrinsic_.
transform_2.translation()[1] <<
" "
123 << imu_gnssant_extrinsic_.
transform_2.translation()[2];
126 if (imu_gnssant_extrinsic_.
ant_num == 1) {
127 is_using_novatel_heading_ =
false;
133 const GnssBestPose& bestgnsspos_msg, MeasureData* measure) {
137 CHECK_NOTNULL(measure);
140 AWARN <<
"Discard a bestgnsspose msg. "
141 <<
"The status of this msg is not OK.";
155 AWARN <<
"Discard a bestgnsspose msg for large std.";
159 if (!send_init_bestgnsspose_) {
161 send_init_bestgnsspose_ =
true;
164 AINFO <<
"Waiting calculate velocity successfully...";
170 ADEBUG << std::setprecision(16)
171 <<
"MeasureDataRepublish Debug Log: bestgnsspos msg: "
172 <<
"[time:" << measure->time <<
"]"
173 <<
"[x:" << measure->gnss_pos.longitude *
RAD_TO_DEG <<
"]"
174 <<
"[y:" << measure->gnss_pos.latitude *
RAD_TO_DEG <<
"]"
175 <<
"[z:" << measure->gnss_pos.height <<
"]"
179 <<
"[position_type:" << bestgnsspos_msg.
sol_type() <<
"]";
185 const MeasureData& gnss_local_msg, MeasureData* measure) {
190 CHECK_NOTNULL(measure);
192 MeasureData measure_data = gnss_local_msg;
193 if (is_trans_gpstime_to_utctime_) {
197 AINFO <<
"the gnss velocity: " << measure_data.gnss_vel.ve <<
" "
198 << measure_data.gnss_vel.vn <<
" " << measure_data.gnss_vel.vu;
200 measure_data.gnss_att.pitch = 0.0;
201 measure_data.gnss_att.roll = 0.0;
203 Eigen::Vector3d pos_xyz = Eigen::Vector3d::Zero();
204 pos_xyz[0] = measure_data.gnss_pos.longitude;
205 pos_xyz[1] = measure_data.gnss_pos.latitude;
206 pos_xyz[2] = measure_data.gnss_pos.height;
208 Eigen::Vector3d pos_blh = Eigen::Vector3d::Zero();
210 measure_data.gnss_pos.longitude = pos_blh[0];
211 measure_data.gnss_pos.latitude = pos_blh[1];
212 measure_data.gnss_pos.height = pos_blh[2];
214 double ve_std = std::sqrt(measure_data.variance[3][3]);
215 double vn_std = std::sqrt(measure_data.variance[4][4]);
216 double vu_std = std::sqrt(measure_data.variance[5][5]);
217 AINFO <<
"the gnss velocity std: " << ve_std <<
" " << vn_std <<
" "
223 measure_data.measure_type = MeasureType::GNSS_POS_ONLY;
224 height_mutex_.lock();
225 if ((measure_data.time - 1.0 < map_height_time_)) {
226 measure_data.measure_type = MeasureType::GNSS_POS_XY;
228 height_mutex_.unlock();
229 measure_data.is_have_variance =
true;
231 measure_data.measure_type = MeasureType::GNSS_POS_VEL;
232 measure_data.is_have_variance =
false;
234 static bool is_sent_init_pos =
false;
235 if (!is_sent_init_pos) {
236 is_sent_init_pos =
true;
237 measure_data.gnss_vel.ve = 0.0;
238 measure_data.gnss_vel.vn = 0.0;
239 measure_data.gnss_vel.vu = 0.0;
240 AINFO <<
"send sins init position using rtk-gnss position!";
241 *measure = measure_data;
245 static int position_good_counter = 0;
246 if (position_good_counter < 10) {
247 ++position_good_counter;
251 if (gnss_local_msg.measure_type != MeasureType::GNSS_POS_VEL &&
252 gnss_local_msg.measure_type != MeasureType::ENU_VEL_ONLY) {
253 AERROR <<
"gnss does not have velocity,"
254 <<
"the gnss velocity std: " << ve_std <<
" " << vn_std <<
" "
258 if (!gnss_local_msg.is_have_variance) {
259 AERROR <<
"gnss velocity does not have velocity variance!";
262 if ((ve_std > 0.1) || (vn_std > 0.1)) {
263 AWARN <<
"gnss velocity variance is large: " << ve_std <<
" " << vn_std;
268 static double pre_yaw_from_vel = 0.0;
269 static double pre_measure_time = 0.0;
270 double yaw_from_vel =
271 atan2(measure_data.gnss_vel.ve, measure_data.gnss_vel.vn);
272 if (pre_measure_time < 0.1) {
273 pre_measure_time = measure_data.time;
274 pre_yaw_from_vel = yaw_from_vel;
277 static constexpr double rad_round = 2 * M_PI;
278 static constexpr double rad_pi = M_PI;
280 double delta_yaw = yaw_from_vel - pre_yaw_from_vel;
281 if (delta_yaw > rad_pi) {
282 delta_yaw = delta_yaw - rad_round;
284 if (delta_yaw < -rad_pi) {
285 delta_yaw = delta_yaw + rad_round;
288 AINFO <<
"yaw from position difference: " << yaw_from_vel *
RAD_TO_DEG;
289 double delta_time = measure_data.time - pre_measure_time;
290 if (delta_time < 1.0e-10) {
291 AINFO <<
"the delta time is too small: " << delta_time;
293 double yaw_incr = delta_yaw / delta_time;
295 static constexpr double rad_5deg = 5 *
DEG_TO_RAD;
296 if ((yaw_incr > rad_5deg) || (yaw_incr < -rad_5deg)) {
297 AWARN <<
"yaw velocity is large! pre, "
298 <<
"cur yaw from vel and velocity: "
301 pre_measure_time = measure_data.time;
302 pre_yaw_from_vel = yaw_from_vel;
305 pre_measure_time = measure_data.time;
306 pre_yaw_from_vel = yaw_from_vel;
309 *measure = measure_data;
311 ADEBUG << std::setprecision(16)
312 <<
"MeasureDataRepublish Debug Log: rtkgnss msg: "
313 <<
"[time:" << measure_data.time <<
"]"
314 <<
"[x:" << measure_data.gnss_pos.longitude *
RAD_TO_DEG <<
"]"
315 <<
"[y:" << measure_data.gnss_pos.latitude *
RAD_TO_DEG <<
"]"
316 <<
"[z:" << measure_data.gnss_pos.height <<
"]"
317 <<
"[std_x:" << measure_data.variance[0][0] <<
"]"
318 <<
"[std_y:" << measure_data.variance[1][1] <<
"]"
319 <<
"[std_z:" << measure_data.variance[2][2] <<
"]";
336 CHECK_NOTNULL(measure);
338 MeasureData measure_data;
344 lidar_local_msg.
pose().
position().
y(), local_utm_zone_id_,
false,
346 measure_data.gnss_pos.longitude = temp_wgs.
log;
347 measure_data.gnss_pos.latitude = temp_wgs.
lat;
348 measure_data.gnss_pos.height = lidar_local_msg.
pose().
position().
z();
356 temp_quat.y(), temp_quat.z());
358 height_mutex_.lock();
363 map_height_time_ = measure_data.time;
364 height_mutex_.unlock();
366 measure_data.gnss_att.yaw = euler.yaw();
367 measure_data.measure_type = MeasureType::POINT_CLOUD_POS;
368 measure_data.frame_type = FrameType::UTM;
370 measure_data.is_have_variance =
true;
376 static constexpr double height_var = 0.03 * 0.03;
377 measure_data.variance[0][0] = longitude_var;
378 measure_data.variance[1][1] = latitude_var;
379 measure_data.variance[2][2] = height_var;
380 measure_data.variance[8][8] = yaw_var;
382 *measure = measure_data;
384 ADEBUG << std::setprecision(16)
385 <<
"MeasureDataRepublish Debug Log: lidarLocal msg: "
386 <<
"[time:" << measure_data.time <<
"]"
387 <<
"[x:" << measure_data.gnss_pos.longitude *
RAD_TO_DEG <<
"]"
388 <<
"[y:" << measure_data.gnss_pos.latitude *
RAD_TO_DEG <<
"]"
389 <<
"[z:" << measure_data.gnss_pos.height <<
"]"
390 <<
"[yaw:" << measure_data.gnss_att.yaw *
RAD_TO_DEG <<
"]"
391 <<
"[std_x:" << std::sqrt(longitude_var) <<
"]"
392 <<
"[std_y:" << std::sqrt(latitude_var) <<
"]"
393 <<
"[std_z:" << std::sqrt(height_var) <<
"]";
404 const GnssBestPose& bestgnsspos_msg, MeasureData* measure) {
405 CHECK_NOTNULL(measure);
408 if (is_trans_gpstime_to_utctime_) {
414 measure->gnss_pos.height =
417 measure->variance[0][0] =
419 measure->variance[1][1] =
421 measure->variance[2][2] =
424 measure->measure_type = MeasureType::GNSS_POS_ONLY;
425 measure->frame_type = FrameType::ENU;
426 height_mutex_.lock();
427 if ((measure->time - 1.0 < map_height_time_)) {
428 measure->measure_type = MeasureType::GNSS_POS_XY;
430 height_mutex_.unlock();
431 measure->is_have_variance =
true;
452 const GnssBestPose& bestgnsspos_msg, MeasureData* measure) {
453 CHECK_NOTNULL(measure);
457 measure->measure_type = MeasureType::GNSS_POS_VEL;
458 measure->frame_type = FrameType::ENU;
459 measure->is_have_variance =
false;
461 if (!pre_bestgnsspose_valid_) {
462 pre_bestgnsspose_valid_ =
true;
463 pre_bestgnsspose_ = *measure;
467 static int position_good_counter = 0;
468 if (position_good_counter < BESTPOSE_GOOD_COUNT) {
469 ++position_good_counter;
470 pre_bestgnsspose_ = *measure;
474 const double re = 6378137.0;
475 const double e = 0.0033528;
476 double temp_sin_lati_2 =
477 sin(measure->gnss_pos.latitude) * sin(measure->gnss_pos.latitude);
478 double rn = re / (1 - e * temp_sin_lati_2);
479 double rm = re / (1 + 2.0 * e - 3.0 * e * temp_sin_lati_2);
481 double inv_time = 1.0 / (measure->time - pre_bestgnsspose_.time);
482 if (measure->time - pre_bestgnsspose_.time > BESTPOSE_TIME_MAX_INTERVAL) {
483 pre_bestgnsspose_ = *measure;
484 position_good_counter = 0;
487 measure->gnss_vel.ve =
488 (measure->gnss_pos.longitude - pre_bestgnsspose_.gnss_pos.longitude) *
489 rn * inv_time * cos(measure->gnss_pos.latitude);
490 measure->gnss_vel.vn =
491 (measure->gnss_pos.latitude - pre_bestgnsspose_.gnss_pos.latitude) * rm *
493 measure->gnss_vel.vu =
494 (measure->gnss_pos.height - pre_bestgnsspose_.gnss_pos.height) * inv_time;
496 pre_bestgnsspose_ = *measure;
497 AINFO <<
"novatel bestgnsspos velocity: " << measure->gnss_vel.ve <<
" "
498 << measure->gnss_vel.vn <<
" " << measure->gnss_vel.vu;
500 static double pre_yaw_from_vel = 0.0;
501 double yaw_from_vel = atan2(measure->gnss_vel.ve, measure->gnss_vel.vn);
502 if (!pre_yaw_from_vel) {
503 pre_yaw_from_vel = yaw_from_vel;
506 static constexpr double rad_round = 2 * M_PI;
507 static constexpr double rad_pi = M_PI;
509 double delta_yaw = yaw_from_vel - pre_yaw_from_vel;
510 if (delta_yaw > rad_pi) {
511 delta_yaw = delta_yaw - rad_round;
513 if (delta_yaw < -rad_pi) {
514 delta_yaw = delta_yaw + rad_round;
517 AINFO <<
"yaw calculated from position difference: "
519 static constexpr double rad_5deg = 5 *
DEG_TO_RAD;
520 if (delta_yaw > rad_5deg || delta_yaw < -rad_5deg) {
521 AWARN <<
"novatel bestgnsspos delta yaw is large! "
522 <<
"pre, cur yaw from vel and delta: "
525 pre_yaw_from_vel = yaw_from_vel;
528 pre_yaw_from_vel = yaw_from_vel;
537 if ((imu_gnssant_extrinsic_.
ant_num == 1)) {
542 AINFO <<
"the heading solution_status and position_type: " << solution_status
543 <<
" " << position_type;
545 if (solution_status != 0) {
547 AINFO <<
"the heading's solution_status is not computed: "
551 *status = position_type;
552 if ((position_type == 0) || (position_type == 1)) {
553 AINFO <<
"the heading's solution_type is invalid or fixed: "
558 if (is_trans_gpstime_to_utctime_) {
562 novatel_heading_mutex_.lock();
563 novatel_heading_time_ = measure_data->time;
564 novatel_heading_mutex_.unlock();
566 double delta_time_between_height = 0.0;
567 height_mutex_.lock();
568 delta_time_between_height = measure_data->time - map_height_time_;
569 height_mutex_.unlock();
571 if (delta_time_between_height < 1.0) {
572 AINFO <<
"the heading time and delta time: " << std::setprecision(15)
573 << measure_data->time <<
" " << delta_time_between_height;
577 integ_pva_mutex_.lock();
579 integ_pva_list_.back().init_and_alignment && (integ_pva_list_.size() > 1);
580 integ_pva_mutex_.unlock();
583 static double pre_publish_time = 0.0;
584 if (measure_data->time - pre_publish_time < 0.5) {
587 pre_publish_time = measure_data->time;
589 double gnss_yaw = heading_msg.
heading();
592 static double imu_ant_yaw_angle = 0.0;
593 if (imu_ant_yaw_angle == 0.0) {
595 -atan2(imu_gnssant_extrinsic_.
transform_2.translation()[0] -
596 imu_gnssant_extrinsic_.
transform_1.translation()[0],
597 imu_gnssant_extrinsic_.
transform_2.translation()[1] -
598 imu_gnssant_extrinsic_.
transform_1.translation()[1]) *
600 AINFO <<
"imu_gnssant_extrinsic_: "
601 << imu_gnssant_extrinsic_.
transform_2.translation()[0] <<
", "
602 << imu_gnssant_extrinsic_.
transform_1.translation()[0] <<
", "
603 << imu_gnssant_extrinsic_.
transform_2.translation()[1] <<
", "
604 << imu_gnssant_extrinsic_.
transform_2.translation()[1];
605 AINFO <<
"the yaw between double ant yaw and vehicle: "
606 << imu_ant_yaw_angle;
608 AINFO <<
"novatel heading is: " << std::setprecision(15) << measure_data->time
609 <<
" " << std::setprecision(6) << gnss_yaw;
610 if (gnss_yaw > 180) {
614 gnss_yaw += imu_ant_yaw_angle;
616 if (gnss_yaw > 180) {
619 measure_data->measure_type = MeasureType::GNSS_DOUBLE_ANT_YAW;
620 measure_data->is_have_variance =
true;
622 AINFO <<
"the novatel heading std: " << std::setprecision(15)
623 << measure_data->time <<
" " << heading_std;
624 measure_data->variance[8][8] =
625 heading_std * heading_std * 3.046174197867086e-04;
626 measure_data->gnss_att.yaw = -gnss_yaw * 0.017453292519943;
628 AINFO <<
"measure data heading is: " << std::setprecision(15)
629 << measure_data->time <<
" " << std::setprecision(6)
630 << measure_data->gnss_att.yaw;