IMU相关的功能包位于sensor_ws的handsfree_ros_imu功能包下
惯性测量单元(Inertial Measurement Unit,简称 IMU)是一种能够测量物体加速度和角速度的电子装置。IMU
通常包含三个加速度计和三个陀螺仪,可以测量物体在三个维度上的加速度和角速度。IMU 的输出数据可以用于姿态估计、运动控制、导航等应用中。
IMU 的加速度计可以测量物体在三个维度上的加速度,通常使用微电子机械系统(MEMS)作为传感器。陀螺仪则可以测量物体沿三个维度的角速度,通常使用霍尔效应、红外线等技术作为传感器。IMU
的输出数据通常通过串口或者蓝牙等方式传输给计算机或者控制器进行处理。
IMU 广泛应用于机器人、自动驾驶、运动控制、导航等领域。在机器人领域,IMU 可以用于姿态估计、运动控制、路径规划等;在自动驾驶领域,IMU
可以用于车辆定位和姿态估计等;在运动控制领域,IMU 可以用于跟踪物体的姿态和位置。
在卓越之星/智行机器人/卓尔-AMR机器人体系中,IMU通过串口与ROS系统的AI处理器连接,提供相应的驱动来将串口获取的IMU数据信息转化成为ROS的消息。在ROS系统中,IMU是有对应的主题的,在ROS中,IMU数据通常使用sensor_msgs/Imu消息类型来表示。这个消息类型包含三个部分:线性加速度、角速度和姿态四元数。
具体来说,sensor_msgs/Imu消息类型包含以下成员变量:
# 线性加速度
geometry_msgs/Vector3 linear_acceleration
# 角速度
geometry_msgs/Vector3 angular_velocity
# 姿态四元数
geometry_msgs/Quaternion orientation
其中,linear_acceleration成员变量表示物体在三个维度上的线性加速度,angular_velocity成员变量表示物体沿三个维度的角速度,orientation成员变量表示物体的姿态四元数。这些数据都是以传感器坐标系为参考系的。
在智行系列产品中,我们使用右手坐标系(right-handed coordinate system)描述机器人的运动和姿态。右手坐标系的定义是:当右手的拇指指向
X 轴正方向,食指指向 Y 轴正方向,中指指向 Z 轴正方向时,其余四指所在的平面就是一个右手坐标系:
首先,我们驱动与IMU的硬件通讯,IMU与机器人设备通讯也是通过串口通讯,与激光雷达类似,串口在Linux系统中绑定了端口,端口号挂载为/dev/imu。
使用VSCode远程连接,打开终端输入下面指令来启动与IMU硬件的通讯连接:
roslaunch handsfree_ros_imu handsfree_imu.launch
出现如下现象证明IMU已经顺利通讯:
打开一个新的终端,输入:
rostopic echo /handsfree/imu
可以看到姿态,角速度,线加速度数据展示在了终端:
如果不能获取数据,则需要检查端口是否连接,打开终端输入ls /dev/imu 如果没有出现下面提示:
说明IMU硬件连接出现了故障,需要检查连线。
如果连接正常,在rviz中,我们可以通过下面的方式观察IMU数据:
首先,global options中的Fixed Frame设置成IMU的frame_id:imu_link
其次,Add选择按照类型添加:
Add-》By display type-》rviz imu plugins
Topic选择/ros/imu,x为红色,y为绿色,z为蓝色
这时,晃动机器人,可以观察到IMU数据跟随姿态一起发生了变化。
在这里我们实现一个节点获取 IMU 数据(即获取了当前机器人的加速度、角速度和姿态朝向信息):
#include <ros/ros.h>
#include <sensor_msgs/Imu.h>
void imu_callback(const sensor_msgs::Imu::ConstPtr& imu_msg) {
// 获取IMU数据
geometry_msgs::Vector3 linear_acceleration = imu_msg->linear_acceleration;
geometry_msgs::Vector3 angular_velocity = imu_msg->angular_velocity;
geometry_msgs::Quaternion orientation = imu_msg->orientation;
// 打印IMU数据
ROS_INFO("Linear acceleration: x=%f, y=%f, z=%f", linear_acceleration.x, linear_acceleration.y, linear_acceleration.z);
ROS_INFO("Angular velocity: x=%f, y=%f, z=%f", angular_velocity.x, angular_velocity.y, angular_velocity.z);
ROS_INFO("Orientation: x=%f, y=%f, z=%f, w=%f", orientation.x, orientation.y, orientation.z, orientation.w);
}
int main(int argc, char** argv) {
// 初始化ROS节点
ros::init(argc, argv, "imu_listener");
// 创建节点句柄
ros::NodeHandle nh;
// 订阅IMU数据
ros::Subscriber imu_sub = nh.subscribe<sensor_msgs::Imu>("imu/data", 10, imu_callback);
// 循环等待回调函数
ros::spin();
return 0;
}
在这个节点中,我们定义了一个imu_callback函数来处理 IMU 数据。这个函数会获取 IMU
数据并打印到终端。在main函数中,我们通过ros::Subscriber函数订阅 IMU 数据,然后通过ros::spin()函数循环等待回调函数。