19#include "yaml-cpp/yaml.h"
27namespace localization {
35 pose_forecastor_(new PoseForcast()),
37 lidar_extrinsic_file_(
""),
38 lidar_height_file_(
""),
39 localization_mode_(2),
41 lidar_filter_size_(17),
42 delta_yaw_limit_(0.25 * 3.14159 / 180.0),
43 init_delta_yaw_limit_(1.5 * 3.14159 / 180.0),
44 compensate_pitch_roll_limit_(0.035),
46 map_coverage_theshold_(0.8),
49 is_get_first_lidar_msg_(false),
55 pre_location_time_(0.0),
56 location_covariance_(
Matrix3D::Zero()),
59 imu_lidar_max_delay_time_(0.5),
60 is_unstable_reset_(true),
62 unstable_threshold_(0.3),
65 forecast_timer_(-1) {}
71 delete pose_forecastor_;
72 pose_forecastor_ =
nullptr;
100 is_get_first_lidar_msg_ =
false;
101 cur_predict_location_ = TransformD::Identity();
102 pre_predict_location_ = TransformD::Identity();
103 pre_location_ = TransformD::Identity();
104 velocity_ = Vector3D::Zero();
105 location_ = TransformD::Identity();
106 location_covariance_ = Matrix3D::Zero();
110 bool success = LoadLidarExtrinsic(lidar_extrinsic_file_, &lidar_extrinsic_);
112 AERROR <<
"LocalizationLidar: Fail to access the lidar"
114 << lidar_extrinsic_file_;
116 "Fail to access the lidar extrinsic file");
119 success = LoadLidarHeight(lidar_height_file_, &lidar_height_);
121 AWARN <<
"LocalizationLidar: Fail to load the lidar"
123 << lidar_height_file_ <<
" Will use default value!";
127 if (!locator_->
Init(map_path_, lidar_filter_size_, lidar_filter_size_,
131 "Fail to load localization map!");
141 const double deg_to_rad = 0.017453292519943;
142 const double max_gyro_input = 200 * deg_to_rad;
143 const double max_acc_input = 5.0;
144 pose_forecastor_->SetMaxListNum(400);
145 pose_forecastor_->SetMaxAccelInput(max_acc_input);
146 pose_forecastor_->SetMaxGyroInput(max_gyro_input);
147 pose_forecastor_->SetZoneId(utm_zone_id_);
152double LocalizationLidarProcess::ComputeDeltaYawLimit(
153 const int64_t index_cur,
const int64_t index_stable,
const double limit_min,
154 const double limit_max) {
155 if (index_cur > index_stable) {
159 double ratio =
static_cast<double>(index_cur);
160 ratio /=
static_cast<double>(index_stable);
161 return limit_min * ratio + limit_max * (1.0 - ratio);
166 AERROR <<
"PcdProcess: Receive an invalid lidar msg!";
174 static unsigned int pcd_index = 0;
177 &forecast_integ_state_)) {
178 AINFO <<
"PcdProcess: Discard a lidar msg because can't get predict pose. "
179 <<
"More info see log in function GetPredictPose.";
184 forecast_timer_ = -1;
189 forecast_timer_, 10, delta_yaw_limit_, init_delta_yaw_limit_));
191 if (!is_get_first_lidar_msg_) {
192 pre_predict_location_ = cur_predict_location_;
193 pre_location_ = cur_predict_location_;
194 velocity_ = Vector3D::Zero();
195 is_get_first_lidar_msg_ =
true;
198 velocity_ = cur_predict_location_.translation() - pre_location_.translation();
200 int ret = locator_->
Update(pcd_index++, cur_predict_location_, velocity_,
201 lidar_frame, if_use_avx_);
205 timer.
End(
"Lidar process");
211 CHECK_NOTNULL(lidar_status);
212 CHECK_NOTNULL(location);
213 CHECK_NOTNULL(covariance);
215 *lidar_status =
static_cast<int>(lidar_status_);
216 *location = location_;
217 *covariance = location_covariance_;
221 if (lidar_local_msg ==
nullptr) {
225 lidar_local_msg->set_measurement_time(pre_location_time_);
228 headerpb->set_timestamp_sec(pre_location_time_);
232 position->set_x(location_.translation()(0));
233 position->set_y(location_.translation()(1));
234 position->set_z(location_.translation()(2));
237 Eigen::Quaterniond quat(location_.linear());
238 quaternion->set_qx(quat.x());
239 quaternion->set_qy(quat.y());
240 quaternion->set_qz(quat.z());
241 quaternion->set_qw(quat.w());
244 lidar_local_msg->mutable_uncertainty();
247 uncertainty->mutable_position_std_dev();
248 position_std_dev->set_x(location_covariance_(0, 0));
249 position_std_dev->set_y(location_covariance_(1, 1));
250 position_std_dev->set_z(0.0);
252 static constexpr double yaw_covariance = 0.15 * 0.15 * DEG_TO_RAD2;
254 uncertainty->mutable_orientation_std_dev();
255 orientation_std_dev->set_x(0.0);
256 orientation_std_dev->set_y(0.0);
257 orientation_std_dev->set_z(yaw_covariance);
259 MsfStatus* msf_status = lidar_local_msg->mutable_msf_status();
260 msf_status->set_local_lidar_status(local_lidar_status_);
261 msf_status->set_local_lidar_quality(local_lidar_quality_);
263 return static_cast<int>(lidar_status_);
267 pose_forecastor_->PushInspvaData(sins_pva_msg);
271 pose_forecastor_->PushImuData(imu_msg);
274bool LocalizationLidarProcess::GetPredictPose(
const double lidar_time,
275 TransformD* predict_pose,
277 CHECK_NOTNULL(predict_pose);
278 CHECK_NOTNULL(forecast_state);
280 double latest_imu_time = pose_forecastor_->GetLastestImuTime();
281 if (latest_imu_time - lidar_time > imu_lidar_max_delay_time_) {
282 AERROR << std::setprecision(16) <<
"LocalizationLidar GetPredictPose: "
283 <<
"Lidar msg too old! "
284 <<
"lidar time: " << lidar_time
285 <<
"delay time: " << latest_imu_time - lidar_time;
293 state = pose_forecastor_->GetBestForcastPose(lidar_time, -1, init_pose,
297 init_pose.x = pre_location_.translation()(0);
298 init_pose.y = pre_location_.translation()(1);
299 init_pose.z = pre_location_.translation()(2);
300 Eigen::Quaterniond quatd(pre_location_.linear());
301 init_pose.qx = quatd.x();
302 init_pose.qy = quatd.y();
303 init_pose.qz = quatd.z();
304 init_pose.qw = quatd.w();
306 state = pose_forecastor_->GetBestForcastPose(lidar_time, pre_location_time_,
307 init_pose, &forecast_pose);
311 AINFO <<
"LocalizationLidar GetPredictPose: "
312 <<
"Receive a lidar msg, but can't query predict pose.";
317 if (std::abs(forecast_pose.x) < 10.0 || std::abs(forecast_pose.y) < 10.0) {
318 AERROR <<
"LocalizationLidar Fatal Error: invalid pose!";
322 Eigen::Quaterniond quatd(forecast_pose.qw, forecast_pose.qx, forecast_pose.qy,
324 Eigen::Translation3d transd(
325 Eigen::Vector3d(forecast_pose.x, forecast_pose.y, forecast_pose.z));
326 *predict_pose = transd * quatd;
332 AINFO <<
"The delta translation input lidar localization: " << lidar_time
333 <<
" " << forecast_pose.x - pre_location_.translation()(0) <<
" "
334 << forecast_pose.y - pre_location_.translation()(1) <<
" "
335 << forecast_pose.z - pre_location_.translation()(2);
341bool LocalizationLidarProcess::CheckState() {
return true; }
343void LocalizationLidarProcess::UpdateState(
const int ret,
const double time) {
345 double location_score = 0.0;
346 locator_->
GetResult(&location_, &location_covariance_, &location_score);
349 double local_uncertainty_x = std::sqrt(location_covariance_(0, 0));
350 double local_uncertainty_y = std::sqrt(location_covariance_(1, 1));
352 local_uncertainty_x = local_uncertainty_x > 0.1 ? local_uncertainty_x : 0.1;
353 local_uncertainty_y = local_uncertainty_y > 0.1 ? local_uncertainty_y : 0.1;
355 double cur_location_std_area =
356 std::sqrt(local_uncertainty_x * local_uncertainty_x +
357 local_uncertainty_y * local_uncertainty_y);
358 if (cur_location_std_area > unstable_threshold_ || location_score < 0.8) {
360 }
else if (cur_location_std_area <= unstable_threshold_ &&
361 location_score < 0.85) {
363 }
else if (cur_location_std_area <= unstable_threshold_ &&
364 location_score < 0.95) {
366 }
else if (cur_location_std_area <= unstable_threshold_) {
379 if (unstable_count_ >= 2 && is_unstable_reset_) {
382 AWARN <<
"Reinit lidar localization due to big covariance";
386 if (out_map_count_ > 0) {
390 pre_location_ = location_;
391 pre_location_time_ = time;
393 }
else if (ret == -2) {
395 double location_score = 0.0;
396 locator_->
GetResult(&location_, &location_covariance_, &location_score);
398 pre_location_ = location_;
399 pre_location_time_ = time;
400 if (out_map_count_ < 10) {
406 AERROR <<
"LocalizationLidar: The reflection map load failed!";
411bool LocalizationLidarProcess::LoadLidarExtrinsic(
const std::string& file_path,
412 TransformD* lidar_extrinsic) {
413 CHECK_NOTNULL(lidar_extrinsic);
415 YAML::Node config = YAML::LoadFile(file_path);
416 if (config[
"transform"]) {
417 if (config[
"transform"][
"translation"]) {
418 lidar_extrinsic->translation()(0) =
419 config[
"transform"][
"translation"][
"x"].as<double>();
420 lidar_extrinsic->translation()(1) =
421 config[
"transform"][
"translation"][
"y"].as<double>();
422 lidar_extrinsic->translation()(2) =
423 config[
"transform"][
"translation"][
"z"].as<double>();
424 if (config[
"transform"][
"rotation"]) {
425 double qx = config[
"transform"][
"rotation"][
"x"].as<
double>();
426 double qy = config[
"transform"][
"rotation"][
"y"].as<
double>();
427 double qz = config[
"transform"][
"rotation"][
"z"].as<
double>();
428 double qw = config[
"transform"][
"rotation"][
"w"].as<
double>();
429 lidar_extrinsic->linear() =
430 Eigen::Quaterniond(qw, qx, qy, qz).toRotationMatrix();
438bool LocalizationLidarProcess::LoadLidarHeight(
const std::string& file_path,
439 LidarHeight* height) {
440 CHECK_NOTNULL(height);
446 YAML::Node config = YAML::LoadFile(file_path);
447 if (config[
"vehicle"]) {
448 if (config[
"vehicle"][
"parameters"]) {
449 height->height = config[
"vehicle"][
"parameters"][
"height"].as<
double>();
451 config[
"vehicle"][
"parameters"][
"height_var"].as<
double>();
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
int64_t End(const std::string &msg)
apollo::common::Status Init(const LocalizationIntegParam ¶ms)
Eigen::Affine3d TransformD
~LocalizationLidarProcess()
void RawImuProcess(const ImuData &imu_msg)
void IntegPvaProcess(const InsPva &sins_pva_msg)
void GetResult(int *lidar_status, TransformD *location, Matrix3D *covariance) const
void PcdProcess(const LidarFrame &lidar_frame)
LocalizationLidarProcess()
void SetLocalizationMode(int mode)
int Update(const unsigned int frame_idx, const Eigen::Affine3d &pose, const Eigen::Vector3d velocity, const LidarFrame &lidar_frame, bool use_avx=false)
void SetDeltaYawLimit(double limit)
void SetImageAlignMode(int mode)
bool Init(const std::string &map_path, const unsigned int search_range_x, const unsigned int search_range_y, const int zone_id, const unsigned int resolution_id=0)
void GetResult(Eigen::Affine3d *location, Eigen::Matrix3d *covariance, double *location_score)
void SetVehicleHeight(double height)
void SetDeltaPitchRollLimit(double limit)
void SetValidThreshold(float valid_threashold)
void SetVelodyneExtrinsic(const Eigen::Affine3d &pose)
The class of LocalizationLidarProcess
@ LOCALIZATION_ERROR_LIDAR
bool PathExists(const std::string &path)
Check if the path exists.
uint32_t height
Height of point cloud
@ MSF_LOCAL_LIDAR_VERY_GOOD
@ MSF_LOCAL_LIDAR_NOT_BAD
@ MSF_LOCAL_LIDAR_MAP_LOADING_FAILED
@ MSF_LOCAL_LIDAR_NOT_GOOD
@ MSF_LOCAL_LIDAR_UNDEFINED_STATUS
@ MSF_LOCAL_LIDAR_OUT_OF_MAP
std::string lidar_height_file
double unstable_reset_threshold
bool is_lidar_unstable_reset
std::string lidar_extrinsic_file
double lidar_height_default
double map_coverage_theshold
double imu_lidar_max_delay_time