Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MAAIQIANG123
gpt-vue_01
提交
d4080bba
G
gpt-vue_01
项目概览
MAAIQIANG123
/
gpt-vue_01
与 Fork 源项目一致
Fork自
inscode / ChatGPT Template With Vue
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gpt-vue_01
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
d4080bba
编写于
5月 20, 2023
作者:
6
6467a2983a260c3da56c82e1
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
UPDATE
上级
3daf8636
变更
2
展开全部
隐藏空白更改
内联
并排
Showing
2 changed file
with
1587 addition
and
0 deletion
+1587
-0
imu.cpp
imu.cpp
+1104
-0
imu222.cpp
imu222.cpp
+483
-0
未找到文件。
imu.cpp
0 → 100644
浏览文件 @
d4080bba
此差异已折叠。
点击以展开。
imu222.cpp
0 → 100644
浏览文件 @
d4080bba
#include <cmath>
#include <math.h>
#include <deque>
#include <mutex>
#include <thread>
#include <fstream>
#include <csignal>
#include <ros/ros.h>
#include <so3_math.h>
#include <Eigen/Eigen>
#include <common_lib.h>
#include <pcl/common/io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <condition_variable>
#include <nav_msgs/Odometry.h>
#include <pcl/common/transforms.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <tf/transform_broadcaster.h>
#include <eigen_conversions/eigen_msg.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/Imu.h>
#include <sensor_msgs/PointCloud2.h>
#include <geometry_msgs/Vector3.h>
#include "use-ikfom.hpp"
/// *************Preconfiguration
/**
* 定义 MAX_INI_COUNT 常量为 20
*/
#define MAX_INI_COUNT (20)
/**
* 比较两个 PointType 类型的对象的曲率值,按升序排列
* @param x PointType 类型的对象
* @param y PointType 类型的对象
* @return 返回比较结果,如果 x 的曲率小于 y 的曲率,返回 true,否则返回 false
*/
const
bool
time_list
(
PointType
&
x
,
PointType
&
y
)
{
return
(
x
.
curvature
<
y
.
curvature
);};
/// *************IMU Process and undistortion
class
ImuProcess
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
ImuProcess
();
// 构造函数
~
ImuProcess
();
// 析构函数
void
Reset
();
// 复位函数
void
Reset
(
double
start_timestamp
,
const
sensor_msgs
::
ImuConstPtr
&
lastimu
);
// 复位函数,带有起始时间戳和上一个IMU的指针参数
void
set_extrinsic
(
const
V3D
&
transl
,
const
M3D
&
rot
);
// 设置外参,包括平移和旋转矩阵
void
set_extrinsic
(
const
V3D
&
transl
);
// 设置外参,仅包括平移
void
set_extrinsic
(
const
MD
(
4
,
4
)
&
T
);
// 设置外参,包括齐次变换矩阵
void
set_gyr_cov
(
const
V3D
&
scaler
);
// 设置角速度测量噪声的方差
void
set_acc_cov
(
const
V3D
&
scaler
);
// 设置加速度测量噪声的方差
void
set_gyr_bias_cov
(
const
V3D
&
b_g
);
// 设置角速度Bias噪声的方差
void
set_acc_bias_cov
(
const
V3D
&
b_a
);
// 设置加速度Bias噪声的方差
Eigen
::
Matrix
<
double
,
12
,
12
>
Q
;
// 12x12的协方差矩阵
void
Process
(
const
MeasureGroup
&
meas
,
esekfom
::
esekf
<
state_ikfom
,
12
,
input_ikfom
>
&
kf_state
,
PointCloudXYZI
::
Ptr
pcl_un_
);
// IMU处理函数
ofstream
fout_imu
;
// 输出文件流
V3D
cov_acc
;
// 加速度噪声方差
V3D
cov_gyr
;
// 角速度噪声方差
V3D
cov_acc_scale
;
// 加速度scale噪声方差
V3D
cov_gyr_scale
;
// 角速度scale噪声方差
V3D
cov_bias_gyr
;
// 角速度Bias噪声方差
V3D
cov_bias_acc
;
// 加速度Bias噪声方差
double
first_lidar_time
;
// 第一个激光雷达时间戳
// 声明私有成员函数
private:
// IMU初始化函数
void
IMU_init
(
const
MeasureGroup
&
meas
,
esekfom
::
esekf
<
state_ikfom
,
12
,
input_ikfom
>
&
kf_state
,
int
&
N
);
// 去除点云畸变函数
void
UndistortPcl
(
const
MeasureGroup
&
meas
,
esekfom
::
esekf
<
state_ikfom
,
12
,
input_ikfom
>
&
kf_state
,
PointCloudXYZI
&
pcl_in_out
);
// 点云数据成员指针
PointCloudXYZI
::
Ptr
cur_pcl_un_
;
// 上一个IMU数据成员指针
sensor_msgs
::
ImuConstPtr
last_imu_
;
// IMU数据成员双端队列
deque
<
sensor_msgs
::
ImuConstPtr
>
v_imu_
;
// IMU位姿数据存储向量
vector
<
Pose6D
>
IMUpose
;
// 点云旋转矩阵存储向量
vector
<
M3D
>
v_rot_pcl_
;
// 相对于IMU坐标系的激光雷达旋转矩阵
M3D
Lidar_R_wrt_IMU
;
// 相对于IMU坐标系的激光雷达位置向量
V3D
Lidar_T_wrt_IMU
;
// IMU加速度均值向量
V3D
mean_acc
;
// IMU陀螺仪均值向量
V3D
mean_gyr
;
// 上一个时刻的角速度向量
V3D
angvel_last
;
// 上一个时刻的加速度向量
V3D
acc_s_last
;
// 初始时间戳
double
start_timestamp_
;
// 上一个激光雷达结束时间
double
last_lidar_end_time_
;
// 初始化迭代次数
int
init_iter_num
=
1
;
// 是否是第一帧数据
bool
b_first_frame_
=
true
;
// 是否需要IMU初始化
bool
imu_need_init_
=
true
;
};
ImuProcess
::
ImuProcess
()
//定义ImuProcess的构造函数
:
b_first_frame_
(
true
),
imu_need_init_
(
true
),
start_timestamp_
(
-
1
)
//成员变量初始化
{
init_iter_num
=
1
;
//初始化参数
Q
=
process_noise_cov
();
//初始化噪声矩阵Q
cov_acc
=
V3D
(
0.1
,
0.1
,
0.1
);
//初始化加速度计噪声协方差
cov_gyr
=
V3D
(
0.1
,
0.1
,
0.1
);
//初始化陀螺仪噪声协方差
cov_bias_gyr
=
V3D
(
0.0001
,
0.0001
,
0.0001
);
//初始化陀螺仪偏置噪声协方差
cov_bias_acc
=
V3D
(
0.0001
,
0.0001
,
0.0001
);
//初始化加速度计偏置噪声协方差
mean_acc
=
V3D
(
0
,
0
,
-
1.0
);
//初始化加速度计均值
mean_gyr
=
V3D
(
0
,
0
,
0
);
//初始化陀螺仪均值
angvel_last
=
Zero3d
;
//设置上一个角速度为零向量
Lidar_T_wrt_IMU
=
Zero3d
;
//设置Lidar_T_wrt_IMU为零向量
Lidar_R_wrt_IMU
=
Eye3d
;
//设置Lidar_R_wrt_IMU为单位矩阵
last_imu_
.
reset
(
new
sensor_msgs
::
Imu
());
//将last_imu_初始化为一个新的sensor_msgs::Imu指针
}
ImuProcess
::~
ImuProcess
()
{}
//析构函数,释放对象时调用
void
ImuProcess
::
Reset
()
{
// ROS_WARN("Reset ImuProcess"); //注释掉的代码,不会被执行,ROS_WARN是输出警告信息的函数
mean_acc
=
V3D
(
0
,
0
,
-
1.0
);
//将均值加速度重置为(0, 0, -1.0)
mean_gyr
=
V3D
(
0
,
0
,
0
);
//将均值陀螺仪重置为(0, 0, 0)
angvel_last
=
Zero3d
;
//将上一个角速度值重置为0
imu_need_init_
=
true
;
//需要初始化IMU
start_timestamp_
=
-
1
;
//起始时间戳为-1
init_iter_num
=
1
;
//初始化迭代次数为1
v_imu_
.
clear
();
//清空imu数据
IMUpose
.
clear
();
//清空imu位姿数据
last_imu_
.
reset
(
new
sensor_msgs
::
Imu
());
//将上一个IMU数据重置为新的sensor_msgs::Imu对象
cur_pcl_un_
.
reset
(
new
PointCloudXYZI
());
//将当前点云数据重置为新的PointCloudXYZI对象
}
void
ImuProcess
::
set_extrinsic
(
const
MD
(
4
,
4
)
&
T
)
{
// 设置激光雷达相对于IMU的平移向量
Lidar_T_wrt_IMU
=
T
.
block
<
3
,
1
>
(
0
,
3
);
// 设置激光雷达相对于IMU的旋转矩阵
Lidar_R_wrt_IMU
=
T
.
block
<
3
,
3
>
(
0
,
0
);
}
void
ImuProcess
::
set_extrinsic
(
const
V3D
&
transl
)
{
// 设置激光雷达相对于IMU的平移向量
Lidar_T_wrt_IMU
=
transl
;
// 设置激光雷达相对于IMU的旋转矩阵为单位矩阵
Lidar_R_wrt_IMU
.
setIdentity
();
}
void
ImuProcess
::
set_extrinsic
(
const
V3D
&
transl
,
const
M3D
&
rot
)
{
// 设置激光雷达相对于IMU的平移向量
Lidar_T_wrt_IMU
=
transl
;
// 设置激光雷达相对于IMU的旋转矩阵
Lidar_R_wrt_IMU
=
rot
;
}
void
ImuProcess
::
set_gyr_cov
(
const
V3D
&
scaler
)
{
// 设置陀螺仪的测量噪声方差
cov_gyr_scale
=
scaler
;
}
// 设置加速度计噪声协方差矩阵的比例因子
void
ImuProcess
::
set_acc_cov
(
const
V3D
&
scaler
)
{
cov_acc_scale
=
scaler
;
}
// 设置陀螺仪零偏噪声协方差矩阵
void
ImuProcess
::
set_gyr_bias_cov
(
const
V3D
&
b_g
)
{
cov_bias_gyr
=
b_g
;
}
// 设置加速度计零偏噪声协方差矩阵
void
ImuProcess
::
set_acc_bias_cov
(
const
V3D
&
b_a
)
{
cov_bias_acc
=
b_a
;
}
// IMU初始化函数
void
ImuProcess
::
IMU_init
(
const
MeasureGroup
&
meas
,
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 **/
V3D
cur_acc
,
cur_gyr
;
if
(
b_first_frame_
)
// 如果是第一帧数据
{
// 进行初始化
Reset
();
// 重置一些变量
N
=
1
;
// 记录数据数量
b_first_frame_
=
false
;
// 标记为不是第一帧数据
const
auto
&
imu_acc
=
meas
.
imu
.
front
()
->
linear_acceleration
;
// 获取第一帧imu数据的加速度
const
auto
&
gyr_acc
=
meas
.
imu
.
front
()
->
angular_velocity
;
// 获取第一帧imu数据的角速度
mean_acc
<<
imu_acc
.
x
,
imu_acc
.
y
,
imu_acc
.
z
;
// 计算加速度均值
mean_gyr
<<
gyr_acc
.
x
,
gyr_acc
.
y
,
gyr_acc
.
z
;
// 计算角速度均值
first_lidar_time
=
meas
.
lidar_beg_time
;
// 记录第一帧激光雷达数据的时间戳
}
// 循环遍历测量中的每个IMU数据
for
(
const
auto
&
imu
:
meas
.
imu
)
{
// 从IMU数据中提取线性加速度和角速度
const
auto
&
imu_acc
=
imu
->
linear_acceleration
;
const
auto
&
gyr_acc
=
imu
->
angular_velocity
;
// 将当前加速度和角速度保存在Eigen向量中
cur_acc
<<
imu_acc
.
x
,
imu_acc
.
y
,
imu_acc
.
z
;
cur_gyr
<<
gyr_acc
.
x
,
gyr_acc
.
y
,
gyr_acc
.
z
;
// 计算平均加速度和角速度
mean_acc
=
(
cur_acc
-
mean_acc
)
/
N
;
mean_gyr
=
(
cur_gyr
-
mean_gyr
)
/
N
;
// 计算加速度和角速度的协方差矩阵
cov_acc
=
cov_acc
*
(
N
-
1.0
)
/
N
(
cur_acc
-
mean_acc
).
cwiseProduct
(
cur_acc
-
mean_acc
)
*
(
N
-
1.0
)
/
(
N
*
N
);
cov_gyr
=
cov_gyr
*
(
N
-
1.0
)
/
N
(
cur_gyr
-
mean_gyr
).
cwiseProduct
(
cur_gyr
-
mean_gyr
)
*
(
N
-
1.0
)
/
(
N
*
N
);
// 增加已处理的测量数量
N
++
;
}
// 从卡尔曼滤波器状态获取初始化状态
state_ikfom
init_state
=
kf_state
.
get_x
();
// 根据平均加速度计算重力向量并设置为初始化状态
init_state
.
grav
=
S2
(
-
mean_acc
/
mean_acc
.
norm
()
*
G_m_s2
);
// 获取当前IMU的方向
const
auto
&
orientation
=
meas
.
imu
.
front
()
->
orientation
;
// 如果orientation消息可用,则使用imu的orientation作为初始姿态
if
(
orientation
.
x
!=
0
||
orientation
.
y
!=
0
||
orientation
.
z
!=
0
||
orientation
.
w
!=
0
){
Eigen
::
Quaterniond
qua
(
orientation
.
w
,
orientation
.
x
,
orientation
.
y
,
orientation
.
z
);
init_state
.
rot
=
qua
;
}
}
// 初始化状态量
//state_inout.rot = Eye3d; // Exp(mean_acc.cross(V3D(0, 0, -1 / scale_gravity)));
// 上述语句是注释掉的,意为旋转状态初始化为单位矩阵,即不旋转,但后续也没有使用到,因此可以忽略
init_state
.
bg
=
mean_gyr
;
// 陀螺仪偏置初始化为零偏
init_state
.
offset_T_L_I
=
Lidar_T_wrt_IMU
;
// 激光雷达相对IMU的位置初始化
init_state
.
offset_R_L_I
=
Lidar_R_wrt_IMU
;
// 激光雷达相对IMU的旋转初始化
kf_state
.
change_x
(
init_state
);
// 更新KF的状态量
// 初始化协方差矩阵
esekfom
::
esekf
<
state_ikfom
,
12
,
input_ikfom
>::
cov
init_P
=
kf_state
.
get_P
();
// 获取KF的协方差矩阵
init_P
.
setIdentity
();
// 设置为对角线全为1的单位矩阵
init_P
(
6
,
6
)
=
init_P
(
7
,
7
)
=
init_P
(
8
,
8
)
=
0.00001
;
// 陀螺仪偏置协方差初始化为0.00001
init_P
(
9
,
9
)
=
init_P
(
10
,
10
)
=
init_P
(
11
,
11
)
=
0.00001
;
// 激光雷达位置偏差协方差初始化为0.00001
init_P
(
15
,
15
)
=
init_P
(
16
,
16
)
=
init_P
(
17
,
17
)
=
0.0001
;
// 速度偏差协方差初始化为0.0001
init_P
(
18
,
18
)
=
init_P
(
19
,
19
)
=
init_P
(
20
,
20
)
=
0.001
;
// 位置偏差协方差初始化为0.001
init_P
(
21
,
21
)
=
init_P
(
22
,
22
)
=
0.00001
;
// 重力加速度偏差协方差初始化为0.00001
kf_state
.
change_P
(
init_P
);
// 更新KF的协方差矩阵
last_imu_
=
meas
.
imu
.
back
();
// 记录最后一个IMU数据,用于后续计算时间间隔
}
// 通过对接收到的IMU和当前EKF状态信息来去畸变点云数据。
void
ImuProcess
::
UndistortPcl
(
const
MeasureGroup
&
meas
,
esekfom
::
esekf
<
state_ikfom
,
12
,
input_ikfom
>
&
kf_state
,
PointCloudXYZI
&
pcl_out
)
{
// 将上一帧IMU数据的尾部添加到当前帧IMU数据的头部。
auto
v_imu
=
meas
.
imu
;
v_imu
.
push_front
(
last_imu_
);
// 获取IMU和点云数据的时间戳
const
double
&
imu_beg_time
=
v_imu
.
front
()
->
header
.
stamp
.
toSec
();
const
double
&
imu_end_time
=
v_imu
.
back
()
->
header
.
stamp
.
toSec
();
const
double
&
pcl_beg_time
=
meas
.
lidar_beg_time
;
// 根据时间排序点云数据
pcl_out
=
*
(
meas
.
lidar
);
sort
(
pcl_out
.
points
.
begin
(),
pcl_out
.
points
.
end
(),
time_list
);
const
double
&
pcl_end_time
=
pcl_beg_time
+
pcl_out
.
points
.
back
().
curvature
/
double
(
1000
);
}
// cout<<"[ IMU Process ]: Process lidar from "<<pcl_beg_time<<" to "<<pcl_end_time<<", " \
// <<meas.imu.size()<<" imu msgs from "<<imu_beg_time<<" to "<<imu_end_time<<endl;
/*** Initialize IMU pose ***/
state_ikfom
imu_state
=
kf_state
.
get_x
();
IMUpose
.
clear
();
IMUpose
.
push_back
(
set_pose6d
(
0.0
,
acc_s_last
,
angvel_last
,
imu_state
.
vel
,
imu_state
.
pos
,
imu_state
.
rot
.
toRotationMatrix
()));
/*** forward propagation at each imu point ***/
V3D
angvel_avr
,
acc_avr
,
acc_imu
,
vel_imu
,
pos_imu
;
M3D
R_imu
;
double
dt
=
0
;
input_ikfom
in
;
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
->
header
.
stamp
.
toSec
()
<
last_lidar_end_time_
)
continue
;
angvel_avr
<<
0.5
*
(
head
->
angular_velocity
.
x
+
tail
->
angular_velocity
.
x
),
0.5
*
(
head
->
angular_velocity
.
y
+
tail
->
angular_velocity
.
y
),
0.5
*
(
head
->
angular_velocity
.
z
+
tail
->
angular_velocity
.
z
);
acc_avr
<<
0.5
*
(
head
->
linear_acceleration
.
x
+
tail
->
linear_acceleration
.
x
),
0.5
*
(
head
->
linear_acceleration
.
y
+
tail
->
linear_acceleration
.
y
),
0.5
*
(
head
->
linear_acceleration
.
z
+
tail
->
linear_acceleration
.
z
);
fout_imu
<<
setw
(
10
)
<<
head
->
header
.
stamp
.
toSec
()
-
first_lidar_time
<<
" "
<<
angvel_avr
.
transpose
()
<<
" "
<<
acc_avr
.
transpose
()
<<
endl
;
acc_avr
=
acc_avr
*
G_m_s2
/
mean_acc
.
norm
();
// - state_inout.ba;
if
(
head
->
header
.
stamp
.
toSec
()
<
last_lidar_end_time_
)
{
dt
=
tail
->
header
.
stamp
.
toSec
()
-
last_lidar_end_time_
;
// dt = tail->header.stamp.toSec() - pcl_beg_time;
}
else
{
dt
=
tail
->
header
.
stamp
.
toSec
()
-
head
->
header
.
stamp
.
toSec
();
}
// 将平均角速度以及平均加速度设置为Kalman滤波器的输入
in
.
acc
=
acc_avr
;
in
.
gyro
=
angvel_avr
;
// 将协方差矩阵的对角线设置为陀螺仪和加速度计的方差,以及陀螺仪偏移和加速度计偏移的方差
Q
.
block
<
3
,
3
>
(
0
,
0
).
diagonal
()
=
cov_gyr
;
Q
.
block
<
3
,
3
>
(
3
,
3
).
diagonal
()
=
cov_acc
;
Q
.
block
<
3
,
3
>
(
6
,
6
).
diagonal
()
=
cov_bias_gyr
;
Q
.
block
<
3
,
3
>
(
9
,
9
).
diagonal
()
=
cov_bias_acc
;
// 使用Kalman滤波器的predict函数进行预测,传入时间步长dt,协方差矩阵Q以及输入in
kf_state
.
predict
(
dt
,
Q
,
in
);
/* save the poses at each IMU measurements */
// 获取当前时刻的KF状态量
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
++
)
{
acc_s_last
[
i
]
=
imu_state
.
grav
[
i
];
}
// 计算时间偏移量、更新IMUpose向量
double
&&
offs_t
=
tail
->
header
.
stamp
.
toSec
()
-
pcl_beg_time
;
IMUpose
.
push_back
(
set_pose6d
(
offs_t
,
acc_s_last
,
angvel_last
,
imu_state
.
vel
,
imu_state
.
pos
,
imu_state
.
rot
.
toRotationMatrix
()));
/*** calculated the pos and attitude prediction at the frame-end ***/
// 确定note,基于pcl_end_time和imu_end_time的比较。note用于决定在预测步骤中加或减pcl_end_time和imu_end_time之间的时间差
double
note
=
pcl_end_time
>
imu_end_time
?
1.0
:
-
1.0
;
// 计算pcl_end_time和imu_end_time之间的时间差
dt
=
note
*
(
pcl_end_time
-
imu_end_time
);
// 使用时间差和输入噪声协方差矩阵预测卡尔曼滤波器的状态
kf_state
.
predict
(
dt
,
Q
,
in
);
// 更新imu_state为当前卡尔曼滤波器的状态
imu_state
=
kf_state
.
get_x
();
// 存储最后一个IMU测量值
last_imu_
=
meas
.
imu
.
back
();
// 存储点云的最后一个时间戳
last_lidar_end_time_
=
pcl_end_time
;
/*** 反向传播,使每个激光点失真 ***/
// 初始化迭代器到最后一个IMU位姿和点云中的最后一个点
auto
it_pcl
=
pcl_out
.
points
.
end
()
-
1
;
for
(
auto
it_kp
=
IMUpose
.
end
()
-
1
;
it_kp
!=
IMUpose
.
begin
();
it_kp
--
)
{
// 将head设置为it_kp之前的IMU位姿,将tail设置为it_kp
auto
head
=
it_kp
-
1
;
auto
tail
=
it_kp
;
// 从head IMU位姿中提取旋转矩阵
R_imu
<<
MAT_FROM_ARRAY
(
head
->
rot
);
// 从head IMU位姿中提取速度向量
vel_imu
<<
VEC_FROM_ARRAY
(
head
->
vel
);
// 从head IMU位姿中提取位置向量
pos_imu
<<
VEC_FROM_ARRAY
(
head
->
pos
);
// 从tail IMU位姿中提取加速度向量
acc_imu
<<
VEC_FROM_ARRAY
(
tail
->
acc
);
// 从tail IMU位姿中提取角速度向量
angvel_avr
<<
VEC_FROM_ARRAY
(
tail
->
gyr
);
// 遍历所有曲率大于head IMU位姿的偏移时间的激光点
for
(;
it_pcl
->
curvature
/
double
(
1000
)
>
head
->
offset_time
;
it_pcl
--
)
{
// 计算head IMU位姿和激光点之间的时间差
dt
=
it_pcl
->
curvature
/
double
(
1000
)
-
head
->
offset_time
;
/* Transform to the 'end' frame, using only the rotation
* Note: Compensation direction is INVERSE of Frame's moving direction
* So if we want to compensate a point at timestamp-i to the frame-e
* P_compensate = R_imu_e ^ T * (R_i * P_i + T_ei) where T_ei is represented in global frame */
M3D
R_i
(
R_imu
*
Exp
(
angvel_avr
,
dt
));
V3D
P_i
(
it_pcl
->
x
,
it_pcl
->
y
,
it_pcl
->
z
);
V3D
T_ei
(
pos_imu
+
vel_imu
*
dt
+
0.5
*
acc_imu
*
dt
*
dt
-
imu_state
.
pos
);
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!
// 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
())
break
;
}
}
}
void
ImuProcess
::
Process
(
const
MeasureGroup
&
meas
,
esekfom
::
esekf
<
state_ikfom
,
12
,
input_ikfom
>
&
kf_state
,
PointCloudXYZI
::
Ptr
cur_pcl_un_
)
{
double
t1
,
t2
,
t3
;
t1
=
omp_get_wtime
();
if
(
meas
.
imu
.
empty
())
{
return
;};
ROS_ASSERT
(
meas
.
lidar
!=
nullptr
);
if
(
imu_need_init_
)
{
/// The very first lidar frame
IMU_init
(
meas
,
kf_state
,
init_iter_num
);
imu_need_init_
=
true
;
last_imu_
=
meas
.
imu
.
back
();
state_ikfom
imu_state
=
kf_state
.
get_x
();
if
(
init_iter_num
>
MAX_INI_COUNT
)
{
cov_acc
*=
pow
(
G_m_s2
/
mean_acc
.
norm
(),
2
);
imu_need_init_
=
false
;
cov_acc
=
cov_acc_scale
;
cov_gyr
=
cov_gyr_scale
;
ROS_INFO
(
"IMU Initial Done"
);
// ROS_INFO("IMU Initial Done: Gravity: %.4f %.4f %.4f %.4f; state.bias_g: %.4f %.4f %.4f; acc covarience: %.8f %.8f %.8f; gry covarience: %.8f %.8f %.8f",\
// imu_state.grav[0], imu_state.grav[1], imu_state.grav[2], mean_acc.norm(), cov_bias_gyr[0], cov_bias_gyr[1], cov_bias_gyr[2], cov_acc[0], cov_acc[1], cov_acc[2], cov_gyr[0], cov_gyr[1], cov_gyr[2]);
fout_imu
.
open
(
DEBUG_FILE_DIR
(
"imu.txt"
),
ios
::
out
);
}
return
;
}
UndistortPcl
(
meas
,
kf_state
,
*
cur_pcl_un_
);
t2
=
omp_get_wtime
();
t3
=
omp_get_wtime
();
// cout<<"[ IMU Process ]: Time: "<<t3 - t1<<endl;
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录