今天新到一个九轴IMU – H30,它是一款高精度的姿态传感器,集成三轴 MEMS 陀螺仪、三轴 MEMS加速度计和三轴磁传感器,可以测量载体的三维姿态角度、加速度、角速度和磁场强度信息,实现 0.1°横滚、俯仰角测量精度和 0.5°无参考航向角、1°磁参考航向角测量精度,最大输出频率200HZ。
我们今天就尝试验证下这个模块在ROS2下的使用效果。
一、概述
1. IMU、VRU、AHRS、INS的区别与联系
IMU(Inertial Measurement Unit): 即“惯性测量单元”,一般的IMU仅包含陀螺仪和加速度计,可以输出加速度和角速度。陀螺仪输出载体相对于惯性系的旋转角速率或者角增量,而加速度计输出比力(即去掉重力后的整体加速度或者单位质量上作用的非引力)或者速度增量。现在市场上既有IMU芯片,也有经过阵列排布和标定后的IMU模组。
VRU(Vertical Reference Unit):即“垂直参考单元”,VRU是在IMU传感器的基础上,增加了计算横滚角和俯仰角的算法,可以输出姿态信息,VRU也可以提供无参考标准的航向角,航向角一般启动时为0°,随时间的增加,误差累积。由于在低动态情况,加速度计感受到的主要是垂直方向上的重力,因此可以采用互补滤波等算法进行横滚和俯仰的计算,并达到较好的精度。
AHRS( Attitude and Heading Reference System ):即“航姿参考系统”,AHRS一般由IMU(陀螺、加速度计)和磁力计组成,并增加了计算横滚、俯仰、航向的算法,可以解算被测物体的全姿态,包括绝对航向角。相比于VRU,由于增加了磁力计,因此不仅可以使用重力参考计算横滚、俯仰,还可以利用地磁参考计算航向,其算法通常也是互补滤波算法。除了磁力计,双天线GPS也可以提供航向信息,因此将磁力计替换为GPS航向或其他能提供航向的传感器,也可以组成AHRS系统。
INS(Inertial Navigation System):即“惯性导航系统”,惯性导航系统(INS)是一种高度自主的导航系统,它利用惯性测量单元(IMU)来捕捉载体的比力(即加速度中扣除重力加速度的部分)及角速度信息。结合预设的初始条件,并通过与 GNSS(全球导航卫星系统)等外部系统的信息融合,INS 能够实时推算并输出载体的速度、位置、姿态等关键参数。其核心机制基于推算导航原理,即从某一已知起始点出发,依据连续监测到的载体航向角和速度变化,逐步推算出载体在后续各点的位置,从而实现对运动体当前位置的连续跟踪。在 INS 中,加速度计与陀螺仪是关键传感器,分别负责测量载体的运动参数。陀螺仪精确测量载体绕其本体坐标轴的旋转角速度,同时能够感知到地球自转的影响,为系统提供精确的姿态基准。而加速度计则依据牛顿第二定律工作,通过电容式、压阻式或热对流等多种物理效应,在加速过程中对内部质量块所受的惯性力进行测量,从而计算出载体在各轴向上的加速度。INS 通过复杂的算法处理陀螺仪测量的角速度数据,包括积分运算和坐标变换,以计算并更新载体的姿态角(横滚角、俯仰角和方位角)。基于这些姿态角,系统能够进一步计算出重力加速度向量在载体坐标系中的分量,并从加速度计测量值中减去这些分量,得到载体真实的加速度。随后,对这一加速度进行时间积分,即可得到载体的速度;速度再经过时间积分,最终确定载体的位置。
2. 3 轴、6 轴、9 轴的区别
概念解释:
- 3 轴传感器模块:通常指的是一种集成了三个独立测量轴的传感器设备,这三个轴相互垂直,分别对应于 X、Y、Z 三个方向。这种模块能够感知并测量物体在这三个方向上的物理量,具体测量内容取决于传感器的类型。
- 6 轴传感器模块:结合了三轴加速度计(用于测量物体在 X、Y、Z 方向上的加速度)和三轴陀螺仪(用于测量物体绕 X、Y、Z 轴的旋转角速度)。由于缺少绝对方向参考,每次模块上电时,其航向角会被重置为0°,无法直接区分方向(如东西南北),因此不适合作为指南针使用。
- 9 轴传感器模块:在 6 轴模块的基础上增加了三轴磁场传感器(也称为磁力计),用于感知地球磁场的方向,从而确定绝对方向。在正确校准后,每次模块上电时,航向角能够提供一个固定的绝对方向值(能够区分东西南北),使其能够作为指南针使用。然而,9 轴模块在复杂环境中易受磁干扰影响(特别是在室内环境下),因此在使用时需注意校准和减少磁干扰源。
系统应用:
- 6 轴模块:可构建为 VRU(垂直参考单元)或 IMU(惯性测量单元),主要用于提供载体的姿态(横滚、俯仰)信息以及角速度数据,适用于需要姿态控制和稳定的应用场景。
- 9 轴模块:更进一步,可构建为 AHRS(航姿参考系统),不仅提供姿态和角速度信息,还能通过磁力计确定绝对航向,为需要全面导航信息的系统提供有力支持。然而,其应用需注意环境中的磁干扰因素。
3. 组合导航
INS(惯性导航系统)的核心优势在于其短时间内能提供极高的位姿测量置信度,能够迅速响应并准确反映载体的即时动态。然而,其局限性在于无法直接提供全局坐标信息,且随着运行时间的延长,由于累积误差,会出现较大的漂移现象,因此通常需要借助外部位置数据源进行定期校正。
相比之下,GNSS(全球导航卫星系统)则擅长于提供全局性的绝对坐标信息,具有出色的长期稳定性和精度。但 GNSS 的短期精度和输出频率相对较低,且在复杂环境(如山区、城市峡谷等)中容易受到信号干扰,导致定位精度显著下降,甚至可能完全失效。
为了克服各自的局限性并充分利用两者的优势,INS 与 GNSS 的组合导航系统应运而生。这种组合方式通过融合两种系统的导航信息,实现了优势互补。组合导航系统能够输出高频率且高精度的导航参数(包括位置、速度和姿态),确保了在不同时间尺度上的导航性能均能达到较高水平。
4. 欧拉角和四元数
欧拉角:作为一组三个角度值,分别代表物体绕三维空间坐标轴(X、Y、Z)的旋转量,具体为俯仰角(Pitch,绕 Y 轴旋转)、滚动角(Roll,绕 X 轴旋转)和偏航角(Yaw,绕 Z 轴旋转),这些角度以特定顺序应用,共同定义了物体相对于某一参考坐标系的方向。
四元数:是数学上的一种扩展复数形式,包含四个维度,用于在三维空间中高效且稳定地表示旋转。相比欧拉角,四元数的主要优势在于能够避免“万向节锁定”现象,这是一种在特定旋转角度下,一个轴的旋转会意外地影响另一个轴旋转能力的问题,常出现于欧拉角表示法中。
四元数与欧拉角之间存在密切且复杂的转换关系。从四元数到欧拉角的转换,需要依据特定的旋转顺序(如 XYZ、ZYX 等),并通过一系列复杂的三角函数运算来实现,不同的旋转顺序会直接影响转换结果。反之,从欧拉角到四元数的转换同样依赖于旋转顺序,并涉及相应的三角函数计算来求得四元数的各分量。
尽管四元数在表示三维旋转时展现出更高的鲁棒性和稳定性,但它们也伴随着更高的计算复杂度和存储空间需求。因此,在选择使用欧拉角还是四元数时,需要综合考虑应用场景的具体需求、计算资源以及所需的精度水平。
二、校准与设置
校准与设置基本都只能在win下操作,所以你需要一个windows笔记本。
1. 安装CP2102usb驱动
2. H30线束连上PC
3. YISManager串口连接H30
翻转H30,可以看到三位定向图会跟着改变。
工具栏切换到姿态数据:
4. 航向切换
H30支持无参考航向、磁力计初始化航向以及磁参考航向三种模式切换。
磁力计初始化航向:使用磁力计的航向角做初始化,后续的增量部分由IMU的航向角增量完成,最终输出航向角是相对的磁航向。
- 【工具】→【相关配置】→【功能设置】,选择【VRU】模式,点【设置】按钮。
- 【工具】→【相关配置】→【串口输出设置】,输出频率选200HZ,点击【确定】按钮进行写入后生效磁力计初始化航向功能。
- 【工具】→【指令写入】,输入【59 53 4D 12 00 02 38 99 05】,点击【发送】按钮使用磁力计初始化航向
- 断开并重连,查看左侧当前状态栏,确认输出频率:200HZ,算法模式:VRU
*注:这款IMU的磁力航向不准,使用AHRS的话会导致航向角数据不准,需改为VRU模式。
5. 方向定义
H30载体系使用 X前-Y左-Z上(FLU) 坐标系, 地理坐标系使用 X东-Y北-Z天(ENU)坐标系。
*注:以X、Y、Z的三个手指为轴心,做唯一可以旋转的动作,即可改变对应的坐标输出。
欧拉角旋转顺序为东(X)–北(Y)–天(Z)–321(先转Z轴,再转Y轴,最后转X轴)旋转顺序。具体定义如下:
- 绕 Z 轴方向旋转: 航向角/Yaw/psi(ψ) 范围:[-180°,180°]
- 绕 Y 轴方向旋转: 俯仰角/Pitch/theta(θ) 范围:[-90°, 90°]
- 绕 X 轴方向旋转: 横滚角/Roll/phi(ф) 范围:[-180°,180°]
给个比较形象的旋转方向示意图:
6. 陀螺零偏校准
在使用H30系列模块时,可能会出现输出位姿数据波动较大的状况,需要对系统进行零偏校准操作。
- 打开【工具】→【重置与校准】→【陀螺零偏】界面。
- 保持设备静止,点击【测量估计】,软件开始采集数据并计算陀螺仪零偏值。
- 完成采集后,点击【写入】即完成陀螺零偏校准。
*注:在估算陀螺仪零偏值的过程中,请保持设备的静止。如果在估算过程中设备产生了运动,有可能导致设备输出性能异常。
7. 姿态和航向角重置
如遇到输出的俯仰角和横滚角不为零的问题,说明模块与安装平面存在安装误差角,可以进行姿态角重置。将H30朝正东方向平放,先设置姿态重置,再触发航向角置零。(不用担心自己无法确保正东,下步骤会通过磁力计重新进行矫正)
8. 磁力计校准
地磁传感器出厂前经过椭球校准,但磁传感器很容易受到外界环境磁场干扰,一般都需要在拿到产品后重新校准。找一个相对空旷的无干扰的地方,将模块连接至电脑,打开上位机。在电脑前请尽量远离干扰源。执行如下操作。
- 打开【工具】→【重置与校准】→【磁力计】界面,选择是 3D校准模式,点击 【Start】,根据提示分别缓慢沿X、Y、Z轴旋转H30(setp会自动切换,每个步骤约为6秒)
- 完成后点击【Finish】,查看生成3D校准结果,点击【Write to YIS】将校准参数发送并写入到模块,磁校准完成
旋转方法以及对应角度值的关系:
9. 固定串口号
外设对应的串口号通常都是主控根据设备连接顺序来设置的,如CP2102的设备名一般为【ttyUSBx】,一般都是会变化的,为了避免找不到设备的情况,我们用CH34xSerCfg把H30芯片串口号改为0003:
- 点击【恢复默认值】,会自动把空的各项都填上内容
- 修改Serial String 为 0003,然后点击“写入配置”,左下角显示写入配置成功
- 拔下重新插上H30,点击读取配置,确认配置正常
三、数据读取与可视化
1. 设备识别
通过Type-C转USB线束接到Ubuntu PC,查看设备是否识别:
$ lsusb |grep QinHeng
Bus 001 Device 009: ID 1a86:55d4 QinHeng Electronics USB Single Serial
2. 配置别名
添加别名规则,把:
# idVendor 代表CH9102 的生产商 ID(默认为 1a86)
# idProduct 代表 CH9102 的产品编号(默认为 55d4)
# serial 为之前我们在windows电脑上给H30设置的序列号
sudo vim /etc/udev/rules.d/wheeltec_imu_ACM.rules
KERNEL=="ttyACM*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", ATTRS{serial}=="0003", MODE:="0777", GROUP:="dialout", SYMLINK+="wheeltec_IMU"
sudo service udev reload
sleep 2
sudo service udev restart
ll /dev/wheeltec_IMU
lrwxrwxrwx 1 root root 7 Oct 30 18:02 /dev/wheeltec_IMU -> ttyACM0
3. 测试ROS SDK
3.1 ROS2
# download source
mkdir -P ~/ros2_imu/src
cd ~/ros2_imu/src
git clone https://github.com/yanjingang/serial_ros2.git
git clone git@github.com:yanjingang/yesense_ros2.git
# depend
sudo apt install ros-humble-imu-tools
or
git clone -b humble https://github.com/yanjingang/imu_tools.git
# conf
cd ~/ros2_imu
vim src/yesense_ros2/yesense_std_ros2/config/yesense_config.yaml
serial_port: "/dev/wheeltec_IMU"
baud_rate: 460800
frame_id: "imu_link"
driver_type: "ros_serial"
imu_topic_ros: "/sensors/imu/data"
imu_topic: "/sensors/imu/data_raw"
# build
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
or
colcon build --symlink-install --packages-select=yesense_std_ros2
# run
source ~/ros2_imu/install/setup.sh
ros2 launch yesense_std_ros2 yesense_node.launch.py
# topic
ros2 topic list
ros2 topic hz /sensors/imu/data
average rate: 200.175 HZ
ros2 topic echo /sensors/imu/data
ros2 topic echo /sensors/imu/data_raw
# rviz
rviz2 imu.rviz
rviz2添加rviz_imu_plugin-IMU组件,修改GlobalFrame-FixedFrame和Imu-Topic,让IMU倾斜即可看到对应的变化。
3.2 ROS1
# download source
mkdir -P ~/catkin_imu/src
cd ~/catkin_imu/src
git clone git@github.com:yanjingang/yesense_ros1.git
# conf
cd ~/catkin_imu
find src/yesense_ros1/ -type f |xargs grep -w "sensor/imu" --color -n # 需要改到配置文件里
# build
catkin_make -DCATKIN_WHITELIST_PACKAGES=yesense_ros1
# run
source devel/setup.bash
roslaunch yesense_ros1 yesense_ahrs.launch
# topic
rostopic list
rostopic hz /sensor/imu/data
average rate: 199.175 HZ
rostopic echo /sensor/imu/data
4. IMU数据时间校准
# 用sensor精振和系统时间的gap修正IMU数据时间
vim src/yesense_ros2/yesense_std_ros2/src/yesense_node.cpp
// =========== publish imu message ==============
double now_timestamp = this->get_clock()->now().seconds();
double sensor_timestamp = static_cast<double>(result->sample_timestamp / 1000000.0);
if (std::abs(now_timestamp - (sensor_timestamp + timestamp_gap)) > 0.05) {
timestamp_gap = now_timestamp - sensor_timestamp;
}
double amend_timestamp = sensor_timestamp + timestamp_gap;
printf("tid:%d sensor:%lf now:%lf gap:%lf amend:%lf\n", result->tid, sensor_timestamp, now_timestamp, timestamp_gap, amend_timestamp);
// imu ros data
imu_ros_data.header.frame_id = frame_id; // 如果不加frame_id,rziv会因为frame_id为空而过滤不显示
imu_ros_data.header.stamp = rclcpp::Time(static_cast<int64_t>(amend_timestamp * 1000000000.0)); // this->get_clock()->now();
# build
colcon build --symlink-install --packages-select=yesense_std_ros2
# run
source ~/ros2_imu/install/setup.sh
ros2 launch yesense_std_ros2 yesense_node.launch.py # 检查输出log里的时间戳gap和修正值是否正常
# topic
ros2 topic echo /sensors/imu/data # 检查header里的时间戳是否正常
四、总结
经过初步验证,没有发现有什么问题,另外经过与厂商沟通,H30缺少时钟同步接口,但可以输出上电后的精振时间戳,只能在ros端拿到串口数据后再根据系统时间生成IMU数据的时间,当系统负载过大导致cpu卡顿延迟时,对数据时间精度会有影响。
具体等结合Lidar进行建图看下精度效果后再和大家反馈。
参考: