msf_localization.cc 16.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

Z
Zhang Liangliang 已提交
17 18
#include "modules/localization/msf/msf_localization.h"

19
#include <yaml-cpp/yaml.h>
20
#include <list>
Z
Zhang Liangliang 已提交
21 22 23

#include "modules/drivers/gnss/proto/config.pb.h"

D
Dong Li 已提交
24
#include "modules/common/math/euler_angles_zxy.h"
25
#include "modules/common/math/math_utils.h"
26
#include "modules/common/math/quaternion.h"
27
#include "modules/common/time/time.h"
28 29 30
#include "modules/common/util/file.h"
#include "modules/common/util/string_tokenizer.h"
#include "modules/localization/common/localization_gflags.h"
31
#include "modules/localization/msf/msf_localization_component.h"
32 33 34 35

namespace apollo {
namespace localization {

D
Dong Li 已提交
36
using apollo::common::Status;
37 38
using apollo::common::monitor::MonitorMessageItem;
using apollo::common::time::Clock;
D
Dong Li 已提交
39
using ::Eigen::Vector3d;
40 41

MSFLocalization::MSFLocalization()
42 43
    : monitor_logger_(
          apollo::common::monitor::MonitorMessageItem::LOCALIZATION),
44
      localization_state_(msf::LocalizationMeasureState::OK),
45
      pcd_msg_index_(-1) {}
46

47 48
Status MSFLocalization::Init() {
  InitParams();
49

50
  return localization_integ_.Init(localization_param_);
51 52
}

53
void MSFLocalization::InitParams() {
54
  // integration module
55 56 57 58 59 60 61
  localization_param_.is_ins_can_self_align = FLAGS_integ_ins_can_self_align;
  localization_param_.is_sins_align_with_vel = FLAGS_integ_sins_align_with_vel;
  localization_param_.is_sins_state_check = FLAGS_integ_sins_state_check;
  localization_param_.sins_state_span_time = FLAGS_integ_sins_state_span_time;
  localization_param_.sins_state_pos_std = FLAGS_integ_sins_state_pos_std;
  localization_param_.vel_threshold_get_yaw = FLAGS_vel_threshold_get_yaw;
  localization_param_.is_trans_gpstime_to_utctime =
62
      FLAGS_trans_gpstime_to_utctime;
63 64
  localization_param_.gnss_mode = FLAGS_gnss_mode;
  localization_param_.is_using_raw_gnsspos = true;
65 66

  // gnss module
67
  localization_param_.enable_ins_aid_rtk = FLAGS_enable_ins_aid_rtk;
68 69

  // lidar module
70
  localization_param_.map_path = FLAGS_map_dir + "/" + FLAGS_local_map_name;
71 72 73 74 75 76 77 78
  localization_param_.lidar_extrinsic_file = FLAGS_lidar_extrinsics_file;
  localization_param_.lidar_height_file = FLAGS_lidar_height_file;
  localization_param_.lidar_height_default = FLAGS_lidar_height_default;
  localization_param_.localization_mode = FLAGS_lidar_localization_mode;
  localization_param_.lidar_yaw_align_mode = FLAGS_lidar_yaw_align_mode;
  localization_param_.lidar_filter_size = FLAGS_lidar_filter_size;
  localization_param_.map_coverage_theshold = FLAGS_lidar_map_coverage_theshold;
  localization_param_.imu_lidar_max_delay_time = FLAGS_lidar_imu_max_delay_time;
79
  localization_param_.if_use_avx = FLAGS_if_use_avx;
80 81 82 83 84 85

  AINFO << "map: " << localization_param_.map_path;
  AINFO << "lidar_extrin: " << localization_param_.lidar_extrinsic_file;
  AINFO << "lidar_height: " << localization_param_.lidar_height_file;

  localization_param_.utm_zone_id = FLAGS_local_utm_zone_id;
86
  // try load zone id from local_map folder
87
  if (FLAGS_if_utm_zone_id_from_folder) {
88 89
    bool success = LoadZoneIdFromFolder(localization_param_.map_path,
                                        &localization_param_.utm_zone_id);
90
    if (!success) {
91
      AWARN << "Can't load utm zone id from map folder, use default value.";
92 93
    }
  }
94
  AINFO << "utm zone id: " << localization_param_.utm_zone_id;
95

96
  // vehicle imu extrinsic
97 98 99 100
  imu_vehicle_quat_.x() = FLAGS_imu_vehicle_qx;
  imu_vehicle_quat_.y() = FLAGS_imu_vehicle_qy;
  imu_vehicle_quat_.z() = FLAGS_imu_vehicle_qz;
  imu_vehicle_quat_.w() = FLAGS_imu_vehicle_qw;
101 102 103 104 105 106 107 108 109 110 111 112
  // try to load imu vehicle quat from file
  if (FLAGS_if_vehicle_imu_from_file) {
    double qx = 0.0;
    double qy = 0.0;
    double qz = 0.0;
    double qw = 0.0;

    std::string vehicle_imu_file =
        common::util::TranslatePath(FLAGS_vehicle_imu_file);
    AINFO << "Vehile imu file: " << vehicle_imu_file;

    if (LoadImuVehicleExtrinsic(vehicle_imu_file, &qx, &qy, &qz, &qw)) {
113 114 115 116
      imu_vehicle_quat_.x() = qx;
      imu_vehicle_quat_.y() = qy;
      imu_vehicle_quat_.z() = qz;
      imu_vehicle_quat_.w() = qw;
117 118 119 120
    } else {
      AWARN << "Can't load imu vehicle quat from file, use default value.";
    }
  }
D
Dong Li 已提交
121 122
  AINFO << "imu_vehicle_quat: " << imu_vehicle_quat_.x() << " "
        << imu_vehicle_quat_.y() << " " << imu_vehicle_quat_.z() << " "
123
        << imu_vehicle_quat_.w();
124

125
  // common
126
  localization_param_.enable_lidar_localization =
127 128
      FLAGS_enable_lidar_localization;

129
  if (!FLAGS_if_imuant_from_file) {
130 131 132 133
    localization_param_.imu_to_ant_offset.offset_x = FLAGS_imu_to_ant_offset_x;
    localization_param_.imu_to_ant_offset.offset_y = FLAGS_imu_to_ant_offset_y;
    localization_param_.imu_to_ant_offset.offset_z = FLAGS_imu_to_ant_offset_z;
    localization_param_.imu_to_ant_offset.uncertainty_x =
134
        FLAGS_imu_to_ant_offset_ux;
135
    localization_param_.imu_to_ant_offset.uncertainty_y =
136
        FLAGS_imu_to_ant_offset_uy;
137
    localization_param_.imu_to_ant_offset.uncertainty_z =
138 139 140 141 142 143 144 145
        FLAGS_imu_to_ant_offset_uz;
  } else {
    double offset_x = 0.0;
    double offset_y = 0.0;
    double offset_z = 0.0;
    double uncertainty_x = 0.0;
    double uncertainty_y = 0.0;
    double uncertainty_z = 0.0;
146 147 148
    std::string ant_imu_leverarm_file =
        common::util::TranslatePath(FLAGS_ant_imu_leverarm_file);
    AERROR << "Ant imu lever arm file: " << ant_imu_leverarm_file;
149 150 151
    CHECK(LoadGnssAntennaExtrinsic(ant_imu_leverarm_file, &offset_x, &offset_y,
                                   &offset_z, &uncertainty_x, &uncertainty_y,
                                   &uncertainty_z));
152
    localization_param_.ant_imu_leverarm_file = ant_imu_leverarm_file;
153

154 155 156 157 158 159 160 161 162 163 164 165 166
    localization_param_.imu_to_ant_offset.offset_x = offset_x;
    localization_param_.imu_to_ant_offset.offset_y = offset_y;
    localization_param_.imu_to_ant_offset.offset_z = offset_z;
    localization_param_.imu_to_ant_offset.uncertainty_x = uncertainty_x;
    localization_param_.imu_to_ant_offset.uncertainty_y = uncertainty_y;
    localization_param_.imu_to_ant_offset.uncertainty_z = uncertainty_z;

    AINFO << localization_param_.imu_to_ant_offset.offset_x << " "
          << localization_param_.imu_to_ant_offset.offset_y << " "
          << localization_param_.imu_to_ant_offset.offset_z << " "
          << localization_param_.imu_to_ant_offset.uncertainty_x << " "
          << localization_param_.imu_to_ant_offset.uncertainty_y << " "
          << localization_param_.imu_to_ant_offset.uncertainty_z;
167
  }
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196

  localization_param_.imu_delay_time_threshold_1 =
      FLAGS_imu_delay_time_threshold_1;
  localization_param_.imu_delay_time_threshold_2 =
      FLAGS_imu_delay_time_threshold_2;
  localization_param_.imu_delay_time_threshold_3 =
      FLAGS_imu_delay_time_threshold_3;

  localization_param_.imu_missing_time_threshold_1 =
      FLAGS_imu_missing_time_threshold_1;
  localization_param_.imu_missing_time_threshold_2 =
      FLAGS_imu_missing_time_threshold_2;
  localization_param_.imu_missing_time_threshold_3 =
      FLAGS_imu_missing_time_threshold_3;

  localization_param_.bestgnsspose_loss_time_threshold =
      FLAGS_bestgnsspose_loss_time_threshold;
  localization_param_.lidar_loss_time_threshold =
      FLAGS_lidar_loss_time_threshold;

  localization_param_.localization_std_x_threshold_1 =
      FLAGS_localization_std_x_threshold_1;
  localization_param_.localization_std_y_threshold_1 =
      FLAGS_localization_std_y_threshold_1;

  localization_param_.localization_std_x_threshold_2 =
      FLAGS_localization_std_x_threshold_2;
  localization_param_.localization_std_y_threshold_2 =
      FLAGS_localization_std_y_threshold_2;
197 198
}

199 200
void MSFLocalization::OnPointCloud(
    const std::shared_ptr<drivers::PointCloud> &message) {
201 202 203 204 205
  ++pcd_msg_index_;
  if (pcd_msg_index_ % FLAGS_point_cloud_step != 0) {
    return;
  }

206
  localization_integ_.PcdProcess(*message);
207

208 209 210 211 212 213 214 215 216
  std::list<msf::LocalizationResult> lidar_localization_list;
  localization_integ_.GetLidarLocalizationList(&lidar_localization_list);

  for (auto itr = lidar_localization_list.begin();
       itr != lidar_localization_list.end(); ++itr) {
    if (itr->state() == msf::LocalizationMeasureState::OK ||
        itr->state() == msf::LocalizationMeasureState::VALID) {
      // publish lidar message to debug
      publisher_->PublishLocalizationMsfLidar(itr->localization());
217 218 219 220 221
    }
  }
  return;
}

222 223
void MSFLocalization::OnRawImu(
    const std::shared_ptr<drivers::gnss::Imu> &imu_msg) {
224
  if (FLAGS_imu_coord_rfu) {
225
    localization_integ_.RawImuProcessRfu(*imu_msg);
226
  } else {
227
    localization_integ_.RawImuProcessFlu(*imu_msg);
228 229
  }

230 231
  std::list<msf::LocalizationResult> integ_localization_list;
  localization_integ_.GetIntegLocalizationList(&integ_localization_list);
232

233 234
  for (auto itr = integ_localization_list.begin();
       itr != integ_localization_list.end(); ++itr) {
235 236 237 238 239
    // compose localization status
    LocalizationStatus status;
    apollo::common::Header *status_headerpb = status.mutable_header();
    status_headerpb->set_timestamp_sec(
        itr->localization().header().timestamp_sec());
240 241 242
    status.set_fusion_status(
        static_cast<MeasureState>(itr->integ_status().integ_state));
    status.set_state_message(itr->integ_status().state_message);
243
    status.set_measurement_time(itr->localization().measurement_time());
244
    publisher_->PublishLocalizationStatus(status);
245

246 247
    if (itr->state() == msf::LocalizationMeasureState::OK ||
        itr->state() == msf::LocalizationMeasureState::VALID) {
248
      // caculate orientation_vehicle_world
249
      LocalizationEstimate local_result = itr->localization();
250
      apollo::localization::Pose *posepb_loc = local_result.mutable_pose();
D
Dong Li 已提交
251
      const apollo::common::Quaternion &orientation = posepb_loc->orientation();
252
      const Eigen::Quaternion<double> quaternion(
D
Dong Li 已提交
253 254
          orientation.qw(), orientation.qx(), orientation.qy(),
          orientation.qz());
Z
zhouyao 已提交
255
      Eigen::Quaternion<double> quat_vehicle_world =
Z
zhouyao 已提交
256
          quaternion * imu_vehicle_quat_;
257 258

      // set heading according to rotation of vehicle
D
Dong Li 已提交
259 260 261
      posepb_loc->set_heading(common::math::QuaternionToHeading(
          quat_vehicle_world.w(), quat_vehicle_world.x(),
          quat_vehicle_world.y(), quat_vehicle_world.z()));
262 263

      // set euler angles according to rotation of vehicle
D
Dong Li 已提交
264 265 266 267
      apollo::common::Point3D *eulerangles = posepb_loc->mutable_euler_angles();
      common::math::EulerAnglesZXYd euler_angle(
          quat_vehicle_world.w(), quat_vehicle_world.x(),
          quat_vehicle_world.y(), quat_vehicle_world.z());
268 269 270
      eulerangles->set_x(euler_angle.pitch());
      eulerangles->set_y(euler_angle.roll());
      eulerangles->set_z(euler_angle.yaw());
271

272 273
      publisher_->PublishPoseBroadcastTF(local_result);
      publisher_->PublishPoseBroadcastTopic(local_result);
274 275 276
    }
  }

D
Dong Li 已提交
277
  if (!integ_localization_list.empty()) {
278 279 280 281 282 283
    localization_state_ = integ_localization_list.back().state();
  }

  return;
}  // namespace localization

284
void MSFLocalization::OnGnssBestPose(
285
    const std::shared_ptr<drivers::gnss::GnssBestPose> &bestgnsspos_msg) {
286 287
  if ((localization_state_ == msf::LocalizationMeasureState::OK ||
       localization_state_ == msf::LocalizationMeasureState::VALID) &&
288
      FLAGS_gnss_only_init) {
289 290 291
    return;
  }

292
  localization_integ_.GnssBestPoseProcess(*bestgnsspos_msg);
293

294 295 296 297 298 299 300 301
  std::list<msf::LocalizationResult> gnss_localization_list;
  localization_integ_.GetGnssLocalizationList(&gnss_localization_list);

  for (auto itr = gnss_localization_list.begin();
       itr != gnss_localization_list.end(); ++itr) {
    if (itr->state() == msf::LocalizationMeasureState::OK ||
        itr->state() == msf::LocalizationMeasureState::VALID) {
      publisher_->PublishLocalizationMsfGnss(itr->localization());
302 303 304 305 306 307
    }
  }

  return;
}

308
void MSFLocalization::OnGnssRtkObs(
309
    const std::shared_ptr<drivers::gnss::EpochObservation> &raw_obs_msg) {
310 311
  if ((localization_state_ == msf::LocalizationMeasureState::OK ||
       localization_state_ == msf::LocalizationMeasureState::VALID) &&
312
      FLAGS_gnss_only_init) {
313 314 315
    return;
  }

316
  localization_integ_.RawObservationProcess(*raw_obs_msg);
317

318 319 320 321 322 323 324 325
  std::list<msf::LocalizationResult> gnss_localization_list;
  localization_integ_.GetGnssLocalizationList(&gnss_localization_list);

  for (auto itr = gnss_localization_list.begin();
       itr != gnss_localization_list.end(); ++itr) {
    if (itr->state() == msf::LocalizationMeasureState::OK ||
        itr->state() == msf::LocalizationMeasureState::VALID) {
      publisher_->PublishLocalizationMsfGnss(itr->localization());
326 327 328 329 330 331
    }
  }

  return;
}

332
void MSFLocalization::OnGnssRtkEph(
333
    const std::shared_ptr<drivers::gnss::GnssEphemeris> &gnss_orbit_msg) {
334 335
  if ((localization_state_ == msf::LocalizationMeasureState::OK ||
       localization_state_ == msf::LocalizationMeasureState::VALID) &&
336
      FLAGS_gnss_only_init) {
337 338 339
    return;
  }

340
  localization_integ_.RawEphemerisProcess(*gnss_orbit_msg);
341 342 343
  return;
}

344 345 346 347 348 349 350 351 352 353 354
void MSFLocalization::OnGnssHeading(
    const std::shared_ptr<drivers::gnss::Heading> &gnss_heading_msg) {
  if ((localization_state_ == msf::LocalizationMeasureState::OK ||
       localization_state_ == msf::LocalizationMeasureState::VALID) &&
      FLAGS_gnss_only_init) {
    return;
  }
  localization_integ_.GnssHeadingProcess(*gnss_heading_msg);
  return;
}

355 356 357 358 359
void MSFLocalization::SetPublisher(
    const std::shared_ptr<LocalizationMsgPublisher> &publisher) {
  publisher_ = publisher;
}

A
Aaron Xiao 已提交
360
bool MSFLocalization::LoadGnssAntennaExtrinsic(
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
    const std::string &file_path, double *offset_x, double *offset_y,
    double *offset_z, double *uncertainty_x, double *uncertainty_y,
    double *uncertainty_z) {
  YAML::Node config = YAML::LoadFile(file_path);
  if (config["leverarm"]) {
    if (config["leverarm"]["primary"]["offset"]) {
      *offset_x = config["leverarm"]["primary"]["offset"]["x"].as<double>();
      *offset_y = config["leverarm"]["primary"]["offset"]["y"].as<double>();
      *offset_z = config["leverarm"]["primary"]["offset"]["z"].as<double>();

      if (config["leverarm"]["primary"]["uncertainty"]) {
        *uncertainty_x =
            config["leverarm"]["primary"]["uncertainty"]["x"].as<double>();
        *uncertainty_y =
            config["leverarm"]["primary"]["uncertainty"]["y"].as<double>();
        *uncertainty_z =
            config["leverarm"]["primary"]["uncertainty"]["z"].as<double>();
      }
      return true;
    }
  }
  return false;
}

D
Dong Li 已提交
385 386 387 388
bool MSFLocalization::LoadImuVehicleExtrinsic(const std::string &file_path,
                                              double *quat_qx, double *quat_qy,
                                              double *quat_qz,
                                              double *quat_qw) {
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
  if (!common::util::PathExists(file_path)) {
    return false;
  }
  YAML::Node config = YAML::LoadFile(file_path);
  if (config["transform"]) {
    if (config["transform"]["translation"]) {
      if (config["transform"]["rotation"]) {
        *quat_qx = config["transform"]["rotation"]["x"].as<double>();
        *quat_qy = config["transform"]["rotation"]["y"].as<double>();
        *quat_qz = config["transform"]["rotation"]["z"].as<double>();
        *quat_qw = config["transform"]["rotation"]["w"].as<double>();
        return true;
      }
    }
  }
  return false;
}

bool MSFLocalization::LoadZoneIdFromFolder(const std::string &folder_path,
D
Dong Li 已提交
408
                                           int *zone_id) {
409 410 411 412 413 414 415 416 417
  std::string map_zone_id_folder;
  if (common::util::DirectoryExists(folder_path + "/map/000/north")) {
    map_zone_id_folder = folder_path + "/map/000/north";
  } else if (common::util::DirectoryExists(folder_path + "/map/000/south")) {
    map_zone_id_folder = folder_path + "/map/000/south";
  } else {
    return false;
  }

418
  auto folder_list = common::util::ListSubPaths(map_zone_id_folder);
419 420 421 422 423 424 425
  for (auto itr = folder_list.begin(); itr != folder_list.end(); ++itr) {
    *zone_id = std::stoi(*itr);
    return true;
  }
  return false;
}

426 427
}  // namespace localization
}  // namespace apollo