Apollo 10.0
自动驾驶开放平台
msf_localization.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include "yaml-cpp/yaml.h"
20
21#include "cyber/common/file.h"
22#include "cyber/time/clock.h"
29
30namespace apollo {
31namespace localization {
32
34
36 : monitor_logger_(
37 apollo::common::monitor::MonitorMessageItem::LOCALIZATION),
38 localization_state_(msf::LocalizationMeasureState::OK),
39 pcd_msg_index_(-1),
40 raw_imu_msg_(nullptr) {}
41
43 InitParams();
44
45 return localization_integ_.Init(localization_param_);
46}
47
49 // integration module
50 localization_param_.is_ins_can_self_align = FLAGS_integ_ins_can_self_align;
51 localization_param_.is_sins_align_with_vel = FLAGS_integ_sins_align_with_vel;
52 localization_param_.is_sins_state_check = FLAGS_integ_sins_state_check;
53 localization_param_.sins_state_span_time = FLAGS_integ_sins_state_span_time;
54 localization_param_.sins_state_pos_std = FLAGS_integ_sins_state_pos_std;
55 localization_param_.vel_threshold_get_yaw = FLAGS_vel_threshold_get_yaw;
56 localization_param_.is_trans_gpstime_to_utctime =
57 FLAGS_trans_gpstime_to_utctime;
58 localization_param_.gnss_mode = FLAGS_gnss_mode;
59 localization_param_.is_using_raw_gnsspos = true;
60
61 // gnss module
62 localization_param_.enable_ins_aid_rtk = FLAGS_enable_ins_aid_rtk;
63
64 // lidar module
65 localization_param_.map_path = FLAGS_map_dir + "/" + FLAGS_local_map_name;
66 localization_param_.lidar_extrinsic_file = FLAGS_lidar_extrinsics_file;
67 localization_param_.lidar_height_file = FLAGS_lidar_height_file;
68 localization_param_.lidar_height_default = FLAGS_lidar_height_default;
69 localization_param_.localization_mode = FLAGS_lidar_localization_mode;
70 localization_param_.lidar_yaw_align_mode = FLAGS_lidar_yaw_align_mode;
71 localization_param_.lidar_filter_size = FLAGS_lidar_filter_size;
72 localization_param_.map_coverage_theshold = FLAGS_lidar_map_coverage_theshold;
73 localization_param_.imu_lidar_max_delay_time = FLAGS_lidar_imu_max_delay_time;
74 localization_param_.if_use_avx = FLAGS_if_use_avx;
75
76 AINFO << "map: " << localization_param_.map_path;
77 AINFO << "lidar_extrin: " << localization_param_.lidar_extrinsic_file;
78 AINFO << "lidar_height: " << localization_param_.lidar_height_file;
79
80 localization_param_.utm_zone_id = FLAGS_local_utm_zone_id;
81 // try load zone id from local_map folder
82 if (FLAGS_if_utm_zone_id_from_folder) {
83 bool success = LoadZoneIdFromFolder(localization_param_.map_path,
84 &localization_param_.utm_zone_id);
85 if (!success) {
86 AWARN << "Can't load utm zone id from map folder, use default value.";
87 }
88 }
89 AINFO << "utm zone id: " << localization_param_.utm_zone_id;
90
91 // vehicle imu extrinsic
92 imu_vehicle_quat_.x() = FLAGS_imu_vehicle_qx;
93 imu_vehicle_quat_.y() = FLAGS_imu_vehicle_qy;
94 imu_vehicle_quat_.z() = FLAGS_imu_vehicle_qz;
95 imu_vehicle_quat_.w() = FLAGS_imu_vehicle_qw;
96 imu_vehicle_translation_[0] = 0.0;
97 imu_vehicle_translation_[1] = 0.0;
98 imu_vehicle_translation_[2] = 0.0;
99 // try to load imu vehicle quat from file
100 if (FLAGS_if_vehicle_imu_from_file) {
101 double qx = 0.0;
102 double qy = 0.0;
103 double qz = 0.0;
104 double qw = 0.0;
105
106 AINFO << "Vehile imu file: " << FLAGS_vehicle_imu_file;
107 if (LoadImuVehicleExtrinsic(FLAGS_vehicle_imu_file, &qx, &qy, &qz, &qw,
108 &imu_vehicle_translation_)) {
109 imu_vehicle_quat_.x() = qx;
110 imu_vehicle_quat_.y() = qy;
111 imu_vehicle_quat_.z() = qz;
112 imu_vehicle_quat_.w() = qw;
113 } else {
114 AWARN << "Can't load imu vehicle quat from file, use default value.";
115 }
116 }
117 AINFO << "imu_vehicle_quat: " << imu_vehicle_quat_.x() << " "
118 << imu_vehicle_quat_.y() << " " << imu_vehicle_quat_.z() << " "
119 << imu_vehicle_quat_.w();
120
121 // common
122 localization_param_.enable_lidar_localization =
123 FLAGS_enable_lidar_localization;
124
125 if (!FLAGS_if_imuant_from_file) {
126 localization_param_.imu_to_ant_offset.offset_x = FLAGS_imu_to_ant_offset_x;
127 localization_param_.imu_to_ant_offset.offset_y = FLAGS_imu_to_ant_offset_y;
128 localization_param_.imu_to_ant_offset.offset_z = FLAGS_imu_to_ant_offset_z;
129 localization_param_.imu_to_ant_offset.uncertainty_x =
130 FLAGS_imu_to_ant_offset_ux;
131 localization_param_.imu_to_ant_offset.uncertainty_y =
132 FLAGS_imu_to_ant_offset_uy;
133 localization_param_.imu_to_ant_offset.uncertainty_z =
134 FLAGS_imu_to_ant_offset_uz;
135 } else {
136 double offset_x = 0.0;
137 double offset_y = 0.0;
138 double offset_z = 0.0;
139 double uncertainty_x = 0.0;
140 double uncertainty_y = 0.0;
141 double uncertainty_z = 0.0;
142 AINFO << "Ant imu lever arm file: " << FLAGS_ant_imu_leverarm_file;
143 ACHECK(LoadGnssAntennaExtrinsic(FLAGS_ant_imu_leverarm_file, &offset_x,
144 &offset_y, &offset_z, &uncertainty_x,
145 &uncertainty_y, &uncertainty_z));
146 localization_param_.ant_imu_leverarm_file = FLAGS_ant_imu_leverarm_file;
147
148 localization_param_.imu_to_ant_offset.offset_x = offset_x;
149 localization_param_.imu_to_ant_offset.offset_y = offset_y;
150 localization_param_.imu_to_ant_offset.offset_z = offset_z;
151 localization_param_.imu_to_ant_offset.uncertainty_x = uncertainty_x;
152 localization_param_.imu_to_ant_offset.uncertainty_y = uncertainty_y;
153 localization_param_.imu_to_ant_offset.uncertainty_z = uncertainty_z;
154
155 AINFO << localization_param_.imu_to_ant_offset.offset_x << " "
156 << localization_param_.imu_to_ant_offset.offset_y << " "
157 << localization_param_.imu_to_ant_offset.offset_z << " "
158 << localization_param_.imu_to_ant_offset.uncertainty_x << " "
159 << localization_param_.imu_to_ant_offset.uncertainty_y << " "
160 << localization_param_.imu_to_ant_offset.uncertainty_z;
161 }
162
163 localization_param_.imu_delay_time_threshold_1 =
164 FLAGS_imu_delay_time_threshold_1;
165 localization_param_.imu_delay_time_threshold_2 =
166 FLAGS_imu_delay_time_threshold_2;
167 localization_param_.imu_delay_time_threshold_3 =
168 FLAGS_imu_delay_time_threshold_3;
169
170 localization_param_.imu_missing_time_threshold_1 =
171 FLAGS_imu_missing_time_threshold_1;
172 localization_param_.imu_missing_time_threshold_2 =
173 FLAGS_imu_missing_time_threshold_2;
174 localization_param_.imu_missing_time_threshold_3 =
175 FLAGS_imu_missing_time_threshold_3;
176
177 localization_param_.bestgnsspose_loss_time_threshold =
178 FLAGS_bestgnsspose_loss_time_threshold;
179 localization_param_.lidar_loss_time_threshold =
180 FLAGS_lidar_loss_time_threshold;
181
182 localization_param_.localization_std_x_threshold_1 =
183 FLAGS_localization_std_x_threshold_1;
184 localization_param_.localization_std_y_threshold_1 =
185 FLAGS_localization_std_y_threshold_1;
186
187 localization_param_.localization_std_x_threshold_2 =
188 FLAGS_localization_std_x_threshold_2;
189 localization_param_.localization_std_y_threshold_2 =
190 FLAGS_localization_std_y_threshold_2;
191
192 localization_timer_.reset(new cyber::Timer(
193 10, [this]() { this->OnLocalizationTimer(); }, false));
194 localization_timer_->Start();
195}
196
198 const std::shared_ptr<drivers::PointCloud> &message) {
199 ++pcd_msg_index_;
200 if (pcd_msg_index_ % FLAGS_point_cloud_step != 0) {
201 return;
202 }
203
204 localization_integ_.PcdProcess(*message);
205
206 const auto &result = localization_integ_.GetLastestLidarLocalization();
207
208 if (result.state() == msf::LocalizationMeasureState::OK ||
209 result.state() == msf::LocalizationMeasureState::VALID) {
210 // publish lidar message to debug
211 publisher_->PublishLocalizationMsfLidar(result.localization());
212 }
213}
214
216 const std::shared_ptr<drivers::gnss::Imu> &imu_msg) {
217 if (FLAGS_imu_coord_rfu) {
218 localization_integ_.RawImuProcessRfu(*imu_msg);
219 } else {
220 localization_integ_.RawImuProcessFlu(*imu_msg);
221 }
222
223 const auto &result = localization_integ_.GetLastestIntegLocalization();
224
225 // compose localization status
226 LocalizationStatus status;
227 apollo::common::Header *status_headerpb = status.mutable_header();
228 status_headerpb->set_timestamp_sec(
229 result.localization().header().timestamp_sec());
230 status.set_fusion_status(
231 static_cast<MeasureState>(result.integ_status().integ_state));
232 status.set_state_message(result.integ_status().state_message);
233 status.set_measurement_time(result.localization().measurement_time());
234 publisher_->PublishLocalizationStatus(status);
235
236 if (result.state() == msf::LocalizationMeasureState::OK ||
237 result.state() == msf::LocalizationMeasureState::VALID) {
238 // calculate orientation_vehicle_world
239 LocalizationEstimate local_result = result.localization();
240 CompensateImuVehicleExtrinsic(&local_result);
241
242 publisher_->PublishPoseBroadcastTF(local_result);
243 publisher_->PublishPoseBroadcastTopic(local_result);
244 }
245
246 localization_state_ = result.state();
247}
248
250 const std::shared_ptr<drivers::gnss::Imu> &imu_msg) {
251 if (imu_msg) {
252 std::unique_lock<std::mutex> lock(mutex_imu_msg_);
253 raw_imu_msg_ = const_cast<std::shared_ptr<drivers::gnss::Imu> &>(imu_msg);
254 }
255}
256
258 const std::shared_ptr<drivers::gnss::GnssBestPose> &bestgnsspos_msg) {
259 if ((localization_state_ == msf::LocalizationMeasureState::OK ||
260 localization_state_ == msf::LocalizationMeasureState::VALID) &&
261 FLAGS_gnss_only_init) {
262 return;
263 }
264
265 localization_integ_.GnssBestPoseProcess(*bestgnsspos_msg);
266
267 const auto &result = localization_integ_.GetLastestGnssLocalization();
268
269 if (result.state() == msf::LocalizationMeasureState::OK ||
270 result.state() == msf::LocalizationMeasureState::VALID) {
271 publisher_->PublishLocalizationMsfGnss(result.localization());
272 }
273}
274
276 const std::shared_ptr<drivers::gnss::EpochObservation> &raw_obs_msg) {
277 if ((localization_state_ == msf::LocalizationMeasureState::OK ||
278 localization_state_ == msf::LocalizationMeasureState::VALID) &&
279 FLAGS_gnss_only_init) {
280 return;
281 }
282
283 localization_integ_.RawObservationProcess(*raw_obs_msg);
284
285 const auto &result = localization_integ_.GetLastestGnssLocalization();
286
287 if (result.state() == msf::LocalizationMeasureState::OK ||
288 result.state() == msf::LocalizationMeasureState::VALID) {
289 publisher_->PublishLocalizationMsfGnss(result.localization());
290 }
291}
292
294 const std::shared_ptr<drivers::gnss::GnssEphemeris> &gnss_orbit_msg) {
295 if ((localization_state_ == msf::LocalizationMeasureState::OK ||
296 localization_state_ == msf::LocalizationMeasureState::VALID) &&
297 FLAGS_gnss_only_init) {
298 return;
299 }
300
301 localization_integ_.RawEphemerisProcess(*gnss_orbit_msg);
302}
303
305 const std::shared_ptr<drivers::gnss::Heading> &gnss_heading_msg) {
306 if ((localization_state_ == msf::LocalizationMeasureState::OK ||
307 localization_state_ == msf::LocalizationMeasureState::VALID) &&
308 FLAGS_gnss_only_init) {
309 return;
310 }
311 localization_integ_.GnssHeadingProcess(*gnss_heading_msg);
312}
313
315 if (!raw_imu_msg_) {
316 return;
317 }
318 std::unique_lock<std::mutex> lock(mutex_imu_msg_);
319 OnRawImu(raw_imu_msg_);
320}
321
323 const std::shared_ptr<LocalizationMsgPublisher> &publisher) {
324 publisher_ = publisher;
325}
326
327void MSFLocalization::CompensateImuVehicleExtrinsic(
328 LocalizationEstimate *local_result) {
329 CHECK_NOTNULL(local_result);
330 // calculate orientation_vehicle_world
331 apollo::localization::Pose *posepb_loc = local_result->mutable_pose();
332 const apollo::common::Quaternion &orientation = posepb_loc->orientation();
333 const Eigen::Quaternion<double> quaternion(
334 orientation.qw(), orientation.qx(), orientation.qy(), orientation.qz());
335 Eigen::Quaternion<double> quat_vehicle_world = quaternion * imu_vehicle_quat_;
336
337 // set heading according to rotation of vehicle
338 posepb_loc->set_heading(common::math::QuaternionToHeading(
339 quat_vehicle_world.w(), quat_vehicle_world.x(), quat_vehicle_world.y(),
340 quat_vehicle_world.z()));
341
342 // set euler angles according to rotation of vehicle
343 apollo::common::Point3D *eulerangles = posepb_loc->mutable_euler_angles();
345 quat_vehicle_world.w(), quat_vehicle_world.x(), quat_vehicle_world.y(),
346 quat_vehicle_world.z());
347 eulerangles->set_x(euler_angle.pitch());
348 eulerangles->set_y(euler_angle.roll());
349 eulerangles->set_z(euler_angle.yaw());
350
351 // Compensate the translation between imu and vehicle center.
352 apollo::common::PointENU *position = posepb_loc->mutable_position();
353 Eigen::Vector3d compensated_position =
354 quat_vehicle_world.toRotationMatrix() * imu_vehicle_translation_;
355 position->set_x(position->x() + compensated_position[0]);
356 position->set_y(position->y() + compensated_position[1]);
357 position->set_z(position->z() + compensated_position[2]);
358}
359
360bool MSFLocalization::LoadGnssAntennaExtrinsic(
361 const std::string &file_path, double *offset_x, double *offset_y,
362 double *offset_z, double *uncertainty_x, double *uncertainty_y,
363 double *uncertainty_z) {
364 YAML::Node config = YAML::LoadFile(file_path);
365 if (config["leverarm"]) {
366 if (config["leverarm"]["primary"]["offset"]) {
367 *offset_x = config["leverarm"]["primary"]["offset"]["x"].as<double>();
368 *offset_y = config["leverarm"]["primary"]["offset"]["y"].as<double>();
369 *offset_z = config["leverarm"]["primary"]["offset"]["z"].as<double>();
370
371 if (config["leverarm"]["primary"]["uncertainty"]) {
372 *uncertainty_x =
373 config["leverarm"]["primary"]["uncertainty"]["x"].as<double>();
374 *uncertainty_y =
375 config["leverarm"]["primary"]["uncertainty"]["y"].as<double>();
376 *uncertainty_z =
377 config["leverarm"]["primary"]["uncertainty"]["z"].as<double>();
378 }
379 return true;
380 }
381 }
382 return false;
383}
384
385bool MSFLocalization::LoadImuVehicleExtrinsic(const std::string &file_path,
386 double *quat_qx, double *quat_qy,
387 double *quat_qz, double *quat_qw,
388 Eigen::Vector3d *translation) {
389 for (size_t i = 0; i < 3; ++i) {
390 (*translation)[i] = 0.0;
391 }
392 if (!cyber::common::PathExists(file_path)) {
393 return false;
394 }
395 YAML::Node config = YAML::LoadFile(file_path);
396 if (config["transform"]) {
397 if (config["transform"]["rotation"]) {
398 *quat_qx = config["transform"]["rotation"]["x"].as<double>();
399 *quat_qy = config["transform"]["rotation"]["y"].as<double>();
400 *quat_qz = config["transform"]["rotation"]["z"].as<double>();
401 *quat_qw = config["transform"]["rotation"]["w"].as<double>();
402 } else {
403 return false;
404 }
405 if (config["transform"]["translation"]) {
406 (*translation)[0] = config["transform"]["translation"]["x"].as<double>();
407 (*translation)[1] = config["transform"]["translation"]["y"].as<double>();
408 (*translation)[2] = config["transform"]["translation"]["z"].as<double>();
409 return true;
410 }
411 }
412 return false;
413}
414
415bool MSFLocalization::LoadZoneIdFromFolder(const std::string &folder_path,
416 int *zone_id) {
417 std::string map_zone_id_folder;
418 if (cyber::common::DirectoryExists(folder_path + "/map/000/north")) {
419 map_zone_id_folder = folder_path + "/map/000/north";
420 } else if (cyber::common::DirectoryExists(folder_path + "/map/000/south")) {
421 map_zone_id_folder = folder_path + "/map/000/south";
422 } else {
423 return false;
424 }
425
426 auto folder_list = cyber::common::ListSubPaths(map_zone_id_folder);
427 for (auto itr = folder_list.begin(); itr != folder_list.end(); ++itr) {
428 *zone_id = std::stoi(*itr);
429 return true;
430 }
431 return false;
432}
433
434} // namespace localization
435} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
Used to perform oneshot or periodic timing tasks
Definition timer.h:71
void SetPublisher(const std::shared_ptr< LocalizationMsgPublisher > &publisher)
void OnRawImu(const std::shared_ptr< drivers::gnss::Imu > &imu_msg)
void OnPointCloud(const std::shared_ptr< drivers::PointCloud > &message)
void OnGnssBestPose(const std::shared_ptr< drivers::gnss::GnssBestPose > &bestgnsspos_msg)
void OnRawImuCache(const std::shared_ptr< drivers::gnss::Imu > &imu_msg)
void OnGnssHeading(const std::shared_ptr< drivers::gnss::Heading > &gnss_heading_msg)
void OnGnssRtkEph(const std::shared_ptr< drivers::gnss::GnssEphemeris > &gnss_orbit_msg)
void OnGnssRtkObs(const std::shared_ptr< drivers::gnss::EpochObservation > &raw_obs_msg)
const LocalizationResult & GetLastestLidarLocalization() const
void RawImuProcessFlu(const drivers::gnss::Imu &imu_msg)
void PcdProcess(const drivers::PointCloud &message)
const LocalizationResult & GetLastestIntegLocalization() const
common::Status Init(const LocalizationIntegParam &params)
void GnssHeadingProcess(const drivers::gnss::Heading &gnss_heading_msg)
void RawObservationProcess(const drivers::gnss::EpochObservation &raw_obs_msg)
const LocalizationResult & GetLastestGnssLocalization() const
void RawEphemerisProcess(const drivers::gnss::GnssEphemeris &gnss_orbit_msg)
void RawImuProcessRfu(const drivers::gnss::Imu &imu_msg)
void GnssBestPoseProcess(const drivers::gnss::GnssBestPose &bestgnsspos_msg)
Defines the EulerAnglesZXY class.
The gflags used by localization module
#define ACHECK(cond)
Definition log.h:80
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
Math-related util functions.
The class of MSFLocalization
EulerAnglesZXY< double > EulerAnglesZXYd
double QuaternionToHeading(const double qw, const double qx, const double qy, const double qz)
Definition quaternion.h:56
bool PathExists(const std::string &path)
Check if the path exists.
Definition file.cc:195
bool DirectoryExists(const std::string &directory_path)
Check if the directory specified by directory_path exists and is indeed a directory.
Definition file.cc:207
std::vector< std::string > ListSubPaths(const std::string &directory_path, const unsigned char d_type)
List sub-paths.
Definition file.cc:353
class register implement
Definition arena_queue.h:37
Contains a number of helper functions related to quaternions.
optional apollo::common::Quaternion orientation
Definition pose.proto:31