|
@@ -1,76 +1,14 @@
|
|
|
-#ifndef FASTER_LIO_IMU_PROCESSING_H
|
|
|
-#define FASTER_LIO_IMU_PROCESSING_H
|
|
|
-
|
|
|
-#include <glog/logging.h>
|
|
|
-#include <sensor_msgs/Imu.h>
|
|
|
-#include <sensor_msgs/PointCloud2.h>
|
|
|
-#include <cmath>
|
|
|
-#include <deque>
|
|
|
-#include <fstream>
|
|
|
-
|
|
|
-#include "common_lib.h"
|
|
|
-#include "so3_math.h"
|
|
|
-#include "use-ikfom.hpp"
|
|
|
-#include "utils.h"
|
|
|
-
|
|
|
-namespace faster_lio {
|
|
|
-
|
|
|
-
|
|
|
-constexpr int MAX_INI_COUNT = 20;
|
|
|
+//
|
|
|
+// Created by zx on 22-10-31.
|
|
|
+//
|
|
|
+#include "imu_processing.h"
|
|
|
+namespace faster_lio
|
|
|
+{
|
|
|
|
|
|
bool time_list(const PointType &x, const PointType &y) { return (x.curvature < y.curvature); };
|
|
|
|
|
|
-/// IMU Process and undistortion
|
|
|
-class ImuProcess {
|
|
|
- public:
|
|
|
- EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
|
|
-
|
|
|
- ImuProcess();
|
|
|
- ~ImuProcess();
|
|
|
-
|
|
|
- void Reset();
|
|
|
- void SetExtrinsic(const common::V3D &transl, const common::M3D &rot);
|
|
|
- void SetGyrCov(const common::V3D &scaler);
|
|
|
- void SetAccCov(const common::V3D &scaler);
|
|
|
- void SetGyrBiasCov(const common::V3D &b_g);
|
|
|
- void SetAccBiasCov(const common::V3D &b_a);
|
|
|
- void Process(const common::MeasureGroup &meas, esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state,
|
|
|
- PointCloudType::Ptr pcl_un_);
|
|
|
-
|
|
|
- std::ofstream fout_imu_;
|
|
|
- Eigen::Matrix<double, 12, 12> Q_;
|
|
|
- common::V3D cov_acc_;
|
|
|
- common::V3D cov_gyr_;
|
|
|
- common::V3D cov_acc_scale_;
|
|
|
- common::V3D cov_gyr_scale_;
|
|
|
- common::V3D cov_bias_gyr_;
|
|
|
- common::V3D cov_bias_acc_;
|
|
|
-
|
|
|
- private:
|
|
|
- void IMUInit(const std::deque<common::ImuData> &imus, esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state, int &N);
|
|
|
-
|
|
|
-
|
|
|
- void UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state,
|
|
|
- PointCloudType &pcl_out);
|
|
|
-
|
|
|
- PointCloudType::Ptr cur_pcl_un_;
|
|
|
- common::ImuData last_imu_;
|
|
|
- std::deque<sensor_msgs::ImuConstPtr> v_imu_;
|
|
|
- std::vector<common::Pose6D> IMUpose_;
|
|
|
- std::vector<common::M3D> v_rot_pcl_;
|
|
|
- common::M3D Lidar_R_wrt_IMU_;
|
|
|
- common::V3D Lidar_T_wrt_IMU_;
|
|
|
- common::V3D mean_acc_;
|
|
|
- common::V3D mean_gyr_;
|
|
|
- common::V3D angvel_last_;
|
|
|
- common::V3D acc_s_last_;
|
|
|
- double last_lidar_end_time_ = 0;
|
|
|
- int init_iter_num_ = 1;
|
|
|
- bool b_first_frame_ = true;
|
|
|
- bool imu_need_init_ = true;
|
|
|
-};
|
|
|
-
|
|
|
-ImuProcess::ImuProcess() : b_first_frame_(true), imu_need_init_(true) {
|
|
|
+ImuProcess::ImuProcess() : b_first_frame_(true), imu_need_init_(true)
|
|
|
+{
|
|
|
init_iter_num_ = 1;
|
|
|
Q_ = process_noise_cov();
|
|
|
cov_acc_ = common::V3D(0.1, 0.1, 0.1);
|
|
@@ -85,41 +23,60 @@ ImuProcess::ImuProcess() : b_first_frame_(true), imu_need_init_(true) {
|
|
|
//last_imu_.reset(new sensor_msgs::Imu());
|
|
|
}
|
|
|
|
|
|
-ImuProcess::~ImuProcess() {}
|
|
|
+ImuProcess::~ImuProcess()
|
|
|
+{
|
|
|
+}
|
|
|
|
|
|
-void ImuProcess::Reset() {
|
|
|
+void ImuProcess::Reset()
|
|
|
+{
|
|
|
mean_acc_ = common::V3D(0, 0, -1.0);
|
|
|
mean_gyr_ = common::V3D(0, 0, 0);
|
|
|
angvel_last_ = common::Zero3d;
|
|
|
imu_need_init_ = true;
|
|
|
init_iter_num_ = 1;
|
|
|
- v_imu_.clear();
|
|
|
+ //v_imu_.clear();
|
|
|
IMUpose_.clear();
|
|
|
//last_imu_.reset(new sensor_msgs::Imu());
|
|
|
cur_pcl_un_.reset(new PointCloudType());
|
|
|
}
|
|
|
|
|
|
-void ImuProcess::SetExtrinsic(const common::V3D &transl, const common::M3D &rot) {
|
|
|
+void ImuProcess::SetExtrinsic(const common::V3D &transl, const common::M3D &rot)
|
|
|
+{
|
|
|
Lidar_T_wrt_IMU_ = transl;
|
|
|
Lidar_R_wrt_IMU_ = rot;
|
|
|
}
|
|
|
|
|
|
-void ImuProcess::SetGyrCov(const common::V3D &scaler) { cov_gyr_scale_ = scaler; }
|
|
|
+void ImuProcess::SetGyrCov(const common::V3D &scaler)
|
|
|
+{
|
|
|
+ cov_gyr_scale_ = scaler;
|
|
|
+}
|
|
|
|
|
|
-void ImuProcess::SetAccCov(const common::V3D &scaler) { cov_acc_scale_ = scaler; }
|
|
|
+void ImuProcess::SetAccCov(const common::V3D &scaler)
|
|
|
+{
|
|
|
+ cov_acc_scale_ = scaler;
|
|
|
+}
|
|
|
|
|
|
-void ImuProcess::SetGyrBiasCov(const common::V3D &b_g) { cov_bias_gyr_ = b_g; }
|
|
|
+void ImuProcess::SetGyrBiasCov(const common::V3D &b_g)
|
|
|
+{
|
|
|
+ cov_bias_gyr_ = b_g;
|
|
|
+}
|
|
|
|
|
|
-void ImuProcess::SetAccBiasCov(const common::V3D &b_a) { cov_bias_acc_ = b_a; }
|
|
|
+void ImuProcess::SetAccBiasCov(const common::V3D &b_a)
|
|
|
+{
|
|
|
+ cov_bias_acc_ = b_a;
|
|
|
+}
|
|
|
|
|
|
-void ImuProcess::IMUInit(const std::deque<common::ImuData>& imus, esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state,
|
|
|
- int &N) {
|
|
|
+void ImuProcess::IMUInit(const std::deque<common::ImuData> &imus,
|
|
|
+ esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state,
|
|
|
+ int &N)
|
|
|
+{
|
|
|
/** 1. initializing the gravity_, gyro bias, acc and gyro covariance
|
|
|
** 2. normalize the acceleration measurenments to unit gravity_ **/
|
|
|
|
|
|
common::V3D cur_acc, cur_gyr;
|
|
|
|
|
|
- if (b_first_frame_) {
|
|
|
+ if (b_first_frame_)
|
|
|
+ {
|
|
|
Reset();
|
|
|
N = 1;
|
|
|
b_first_frame_ = false;
|
|
@@ -129,7 +86,8 @@ void ImuProcess::IMUInit(const std::deque<common::ImuData>& imus, esekfom::esekf
|
|
|
mean_gyr_ << gyr_acc[0], gyr_acc[1], gyr_acc[2];
|
|
|
}
|
|
|
|
|
|
- for (const auto &imu : imus) {
|
|
|
+ for (const auto &imu : imus)
|
|
|
+ {
|
|
|
const auto &imu_acc = imu.linear_acceleration;
|
|
|
const auto &gyr_acc = imu.angular_velocity;
|
|
|
cur_acc << imu_acc[0], imu_acc[1], imu_acc[2];
|
|
@@ -166,7 +124,8 @@ void ImuProcess::IMUInit(const std::deque<common::ImuData>& imus, esekfom::esekf
|
|
|
}
|
|
|
|
|
|
void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state,
|
|
|
- PointCloudType &pcl_out) {
|
|
|
+ PointCloudType &pcl_out)
|
|
|
+{
|
|
|
/*** add the imu_ of the last frame-tail to the of current frame-head ***/
|
|
|
auto v_imu = meas.imu_;
|
|
|
v_imu.push_front(last_imu_);
|
|
@@ -192,26 +151,31 @@ void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<s
|
|
|
double dt = 0;
|
|
|
|
|
|
input_ikfom in;
|
|
|
- for (auto it_imu = v_imu.begin(); it_imu < (v_imu.end() - 1); it_imu++) {
|
|
|
+ for (auto it_imu = v_imu.begin(); it_imu < (v_imu.end() - 1); it_imu++)
|
|
|
+ {
|
|
|
auto &&head = *(it_imu);
|
|
|
auto &&tail = *(it_imu + 1);
|
|
|
|
|
|
- if (tail.timebase < last_lidar_end_time_) {
|
|
|
+ if (tail.timebase < last_lidar_end_time_)
|
|
|
+ {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
angvel_avr << 0.5 * (head.angular_velocity[0] + tail.angular_velocity[0]),
|
|
|
- 0.5 * (head.angular_velocity[1] + tail.angular_velocity[1]),
|
|
|
- 0.5 * (head.angular_velocity[2] + tail.angular_velocity[2]);
|
|
|
+ 0.5 * (head.angular_velocity[1] + tail.angular_velocity[1]),
|
|
|
+ 0.5 * (head.angular_velocity[2] + tail.angular_velocity[2]);
|
|
|
acc_avr << 0.5 * (head.linear_acceleration[0] + tail.linear_acceleration[0]),
|
|
|
- 0.5 * (head.linear_acceleration[1] + tail.linear_acceleration[1]),
|
|
|
- 0.5 * (head.linear_acceleration[2] + tail.linear_acceleration[2]);
|
|
|
+ 0.5 * (head.linear_acceleration[1] + tail.linear_acceleration[1]),
|
|
|
+ 0.5 * (head.linear_acceleration[2] + tail.linear_acceleration[2]);
|
|
|
|
|
|
acc_avr = acc_avr * common::G_m_s2 / mean_acc_.norm(); // - state_inout.ba;
|
|
|
|
|
|
- if (head.timebase < last_lidar_end_time_) {
|
|
|
+ if (head.timebase < last_lidar_end_time_)
|
|
|
+ {
|
|
|
dt = tail.timebase - last_lidar_end_time_;
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
dt = tail.timebase - head.timebase;
|
|
|
}
|
|
|
|
|
@@ -227,7 +191,8 @@ void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<s
|
|
|
imu_state = kf_state.get_x();
|
|
|
angvel_last_ = angvel_avr - imu_state.bg;
|
|
|
acc_s_last_ = imu_state.rot * (acc_avr - imu_state.ba);
|
|
|
- for (int i = 0; i < 3; i++) {
|
|
|
+ for (int i = 0; i < 3; i++)
|
|
|
+ {
|
|
|
acc_s_last_[i] += imu_state.grav[i];
|
|
|
}
|
|
|
|
|
@@ -246,11 +211,13 @@ void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<s
|
|
|
last_lidar_end_time_ = pcl_end_time;
|
|
|
|
|
|
/*** undistort each lidar point (backward propagation) ***/
|
|
|
- if (pcl_out.points.empty()) {
|
|
|
+ if (pcl_out.points.empty())
|
|
|
+ {
|
|
|
return;
|
|
|
}
|
|
|
auto it_pcl = pcl_out.points.end() - 1;
|
|
|
- for (auto it_kp = IMUpose_.end() - 1; it_kp != IMUpose_.begin(); it_kp--) {
|
|
|
+ for (auto it_kp = IMUpose_.end() - 1; it_kp != IMUpose_.begin(); it_kp--)
|
|
|
+ {
|
|
|
auto head = it_kp - 1;
|
|
|
auto tail = it_kp;
|
|
|
R_imu = common::MatFromArray(head->rot);
|
|
@@ -259,7 +226,8 @@ void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<s
|
|
|
acc_imu = common::VecFromArray(tail->acc);
|
|
|
angvel_avr = common::VecFromArray(tail->gyr);
|
|
|
|
|
|
- for (; it_pcl->curvature / double(1000) > head->offset_time; it_pcl--) {
|
|
|
+ for (; it_pcl->curvature / double(1000) > head->offset_time; it_pcl--)
|
|
|
+ {
|
|
|
dt = it_pcl->curvature / double(1000) - head->offset_time;
|
|
|
|
|
|
/* Transform to the 'end' frame, using only the rotation
|
|
@@ -271,16 +239,17 @@ void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<s
|
|
|
common::V3D P_i(it_pcl->x, it_pcl->y, it_pcl->z);
|
|
|
common::V3D T_ei(pos_imu + vel_imu * dt + 0.5 * acc_imu * dt * dt - imu_state.pos);
|
|
|
common::V3D p_compensate =
|
|
|
- imu_state.offset_R_L_I.conjugate() *
|
|
|
- (imu_state.rot.conjugate() * (R_i * (imu_state.offset_R_L_I * P_i + imu_state.offset_T_L_I) + T_ei) -
|
|
|
- imu_state.offset_T_L_I); // not accurate!
|
|
|
+ imu_state.offset_R_L_I.conjugate() *
|
|
|
+ (imu_state.rot.conjugate() * (R_i * (imu_state.offset_R_L_I * P_i + imu_state.offset_T_L_I) + T_ei) -
|
|
|
+ imu_state.offset_T_L_I); // not accurate!
|
|
|
|
|
|
// save Undistorted points and their rotation
|
|
|
it_pcl->x = p_compensate(0);
|
|
|
it_pcl->y = p_compensate(1);
|
|
|
it_pcl->z = p_compensate(2);
|
|
|
|
|
|
- if (it_pcl == pcl_out.points.begin()) {
|
|
|
+ if (it_pcl == pcl_out.points.begin())
|
|
|
+ {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -289,14 +258,18 @@ void ImuProcess::UndistortPcl(const common::MeasureGroup &meas, esekfom::esekf<s
|
|
|
|
|
|
|
|
|
void ImuProcess::Process(const common::MeasureGroup &meas, esekfom::esekf<state_ikfom, 12, input_ikfom> &kf_state,
|
|
|
- PointCloudType::Ptr cur_pcl_un_) {
|
|
|
- if (meas.imu_.empty()) {
|
|
|
+ PointCloudType::Ptr cur_pcl_un_)
|
|
|
+{
|
|
|
+ if (meas.imu_.empty())
|
|
|
+ {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- ROS_ASSERT(meas.lidar_ != nullptr);
|
|
|
+ if (meas.lidar_ == nullptr)
|
|
|
+ printf("imuprocess ERROR : meas.lidar_ == nullptr\n");
|
|
|
|
|
|
- if (imu_need_init_) {
|
|
|
+ if (imu_need_init_)
|
|
|
+ {
|
|
|
/// The very first lidar frame
|
|
|
IMUInit(meas.imu_, kf_state, init_iter_num_);
|
|
|
|
|
@@ -319,9 +292,9 @@ void ImuProcess::Process(const common::MeasureGroup &meas, esekfom::esekf<state_
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
- Timer::Evaluate([&, this]() { UndistortPcl(meas, kf_state, *cur_pcl_un_); }, "Undistort Pcl");
|
|
|
+ Timer::Evaluate([&, this]() {
|
|
|
+ UndistortPcl(meas, kf_state, *cur_pcl_un_);
|
|
|
+ }, "Undistort Pcl");
|
|
|
|
|
|
}
|
|
|
-} // namespace faster_lio
|
|
|
-
|
|
|
-#endif
|
|
|
+}
|