24namespace localization {
29 const std::string &ref_timestamps_path,
30 const std::string &out_poses_path,
31 const std::string &extrinsic_path) {
32 this->input_poses_path_ = input_poses_path;
33 this->ref_timestamps_path_ = ref_timestamps_path;
34 this->out_poses_path_ = out_poses_path;
35 this->extrinsic_path_ = extrinsic_path;
39 AERROR <<
"Load lidar extrinsic failed.";
50 &input_poses_timestamps_);
56 PoseInterpolationByTime(input_poses_, input_poses_timestamps_,
57 ref_timestamps_, ref_ids_, &out_indexes_,
58 &out_timestamps_, &out_poses_);
64void PosesInterpolation::LoadPCDTimestamp() {
65 FILE *file = fopen(ref_timestamps_path_.c_str(),
"r");
69 static constexpr int kSize = 2;
70 while (fscanf(file,
"%u %lf\n", &index, ×tamp) == kSize) {
71 ref_timestamps_.push_back(timestamp);
72 ref_ids_.push_back(index);
76 AINFO <<
"Can't open file to read: " << ref_timestamps_path_;
80void PosesInterpolation::WritePCDPoses() {
82 fout.open(out_poses_path_.c_str(), std::ofstream::out);
85 fout.setf(std::ios::fixed, std::ios::floatfield);
87 for (
size_t i = 0; i < out_poses_.size(); i++) {
90 Eigen::Affine3d pose_tem = out_poses_[i] * velodyne_extrinsic_;
91 Eigen::Quaterniond quatd(pose_tem.linear());
92 Eigen::Translation3d transd(pose_tem.translation());
93 double qx = quatd.x();
94 double qy = quatd.y();
95 double qz = quatd.z();
96 double qr = quatd.w();
98 fout << out_indexes_[i] <<
" " <<
timestamp <<
" " << transd.x() <<
" "
99 << transd.y() <<
" " << transd.z() <<
" " << qx <<
" " << qy <<
" "
100 << qz <<
" " << qr <<
"\n";
105 AERROR <<
"Can't open file to write: " << out_poses_path_ << std::endl;
109void PosesInterpolation::PoseInterpolationByTime(
110 const ::apollo::common::EigenAffine3dVec &in_poses,
111 const std::vector<double> &in_timestamps,
112 const std::vector<double> &ref_timestamps,
113 const std::vector<unsigned int> &ref_indexes,
114 std::vector<unsigned int> *out_indexes, std::vector<double> *out_timestamps,
116 out_indexes->clear();
117 out_timestamps->clear();
120 unsigned int index = 0;
121 for (
size_t i = 0; i < ref_timestamps.size(); i++) {
122 double ref_timestamp = ref_timestamps[i];
123 unsigned int ref_index = ref_indexes[i];
125 while (index < in_timestamps.size() &&
126 in_timestamps.at(index) < ref_timestamp) {
130 if (index < in_timestamps.size()) {
132 double cur_timestamp = in_timestamps[index];
133 double pre_timestamp = in_timestamps[index - 1];
134 assert(cur_timestamp != pre_timestamp);
137 (cur_timestamp - ref_timestamp) / (cur_timestamp - pre_timestamp);
141 Eigen::Affine3d pre_pose = in_poses[index - 1];
142 Eigen::Affine3d cur_pose = in_poses[index];
143 Eigen::Quaterniond pre_quatd(pre_pose.linear());
144 Eigen::Translation3d pre_transd(pre_pose.translation());
145 Eigen::Quaterniond cur_quatd(cur_pose.linear());
146 Eigen::Translation3d cur_transd(cur_pose.translation());
148 Eigen::Quaterniond res_quatd = pre_quatd.slerp(1 - t, cur_quatd);
150 Eigen::Translation3d re_transd;
151 re_transd.x() = pre_transd.x() * t + cur_transd.x() * (1 - t);
152 re_transd.y() = pre_transd.y() * t + cur_transd.y() * (1 - t);
153 re_transd.z() = pre_transd.z() * t + cur_transd.z() * (1 - t);
155 out_poses->push_back(re_transd * res_quatd);
156 out_indexes->push_back(ref_index);
157 out_timestamps->push_back(ref_timestamp);
160 AWARN <<
"[WARN] No more poses. Exit now.";
163 ADEBUG <<
"Frame_id: " << i;
bool Init(const std::string &input_poses_path, const std::string &ref_timestamps_path, const std::string &out_poses_path, const std::string &extrinsic_path)
EigenVector< Eigen::Affine3d > EigenAffine3dVec
EigenVector< Eigen::Vector3d > EigenVector3dVec
bool LoadExtrinsic(const std::string &file_path, Eigen::Affine3d *extrinsic)
Load the velodyne extrinsic from a YAML file.
void LoadPosesAndStds(const std::string &file_path, ::apollo::common::EigenAffine3dVec *poses, ::apollo::common::EigenVector3dVec *stds, std::vector< double > *timestamps)
Load poses and stds their timestamps.
The utilities of velodyne.