近两年来,车联网、自动驾驶、无人驾驶、汽车智能化、网联化等成为了汽车行业的热点话题,未来汽车一定是朝着安全、可靠及舒适的方向发展。而这一切背后的发展都离不开传感器的作用,尤其是惯惯性传感器——IMU。
IMU全称Inertial Measurement Unit,惯性测量单元,主要用来检测和测量加速度与旋转运动的传感器。其原理是采用惯性定律实现的,这些传感器从超小型的的MEMS传感器,到测量精度非常高的激光陀螺,无论尺寸只有几个毫米的MEMS传感器,到直径几近半米的光纤器件采用的都是这一原理。
最基础的惯性传感器包括加速度计和角速度计(陀螺仪),他们是惯性系统的核心部件,是影响惯性系统性能的主要因素。尤其是陀螺仪其漂移对惯导系统的位置误差增长的影响是时间的三次方函数。而高精度的陀螺仪制造困难,成本高昂。因此提高陀螺仪的精度、同时降低其成本也是当前追求的目标。
本篇博客主要介绍 惯导模块 WHEELTEC N100 模块 在ROS下的使用方法
WHEELTEC N100 模块 是一个全新的,微型,高性能,经过严格 出厂校准的 IMU 核心。
其特点是具有一个强大的 Sigma-Point 卡尔曼滤波器 (SPKF),以及一套高性能算法,高达 1000Hz 的传感器采样频率和圆锥和划船运 动补偿,有较强的抗磁干扰能力。
其实物如下图:
输出:
具有固定 频率输出和问询输出两种模式,默认使用固定频率输出。
本篇介绍如何在ROS环境中使用 WHEELTEC N100 惯导模块。
在linux中设备接到哪个串口号上是随机的,为解决这个问题,可以先将N100 设备的串口号设置成固定的名称,避免后期需要重复的修改配置
从网上下载 CP21xxCustomizationUtility 软件。
下面通过 CP21xxCustomizationUtility 这个 windows 上的软件修改并固定
修改0003那个地方,然后点击 Program Device
外设对应的串口名一般都是会变化的,为了避免手动选择,这里可以通过给 USB 设备创建别名的方式解决。
命名一个wheeltec_udev.sh 脚本文件
echo 'KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60",ATTRS{serial}=="0003", MODE:="0777", GROUP:="dialout", SYMLINK+="fdilink_ahrs"' >/etc/udev/rules.d/fdilink_ahrs.rules
service udev reload
sleep 2
service udev restart
其中 ATTRS{serial}==“0003” 就是刚从0001改为的0003,其它信息没有变,看上面的截图
sudo chmod 777 wheeltec_udev.sh
给这个脚本文件赋权
sudo sh wheeltec_udev.sh
执行脚本
把 WHEELTEC N100 模块连接到 ROS 主控
在终端运行:ll /dev 查看设备
结果现实已经成功用 fdilink_ahrs 这个别名来代表惯导模块了,后续不管接 到哪个 USB 口,使用的时候均不需要考虑端口号变化问题。
将WHEELTEC 100N的 ROS_SDK 保存在工作空间的src文件夹下。
通过
catkin_make
进行编译。
刚装的ros环境会报错,如下:
Make Error at /opt/ros/noetic/share/catkin/cmake/catkinConfig.cmake:83 (find_package):
Could not find a package configuration file provided by "serial" with any
of the following names:
serialConfig.cmake
serial-config.cmake
原因就是在CMakeList.txt文件中包含了 serial的功能包,需要进行安装
sudo apt install ros-noetic-serial
安装成功后会提示如下:
然后在进行 编译
catkin_make
就成功了
看下其launch文件中的相关参数设置
<launch>
<node pkg="fdilink_ahrs" name="ahrs_driver" type="ahrs_driver" output="screen" >
<!-- 是否输出debug信息 -->
<param name="debug" value="false"/>
<!-- 串口设备,可通过rules.d配置固定。
若使用DETA100,则value="/dev/wheeltec_ch340"
若使用WHEELTEC N系列,则不需要改动 -->
<param name="port" value="/dev/fdilink_ahrs"/>
<!-- 波特率 -->
<param name="baud" value="921600"/>
<!-- 发布的imu话题名 -->
<param name="imu_topic" value="imu"/>
<!-- 发布的imu话题中的frame_id -->
<param name="imu_frame" value="gyro_link"/>
<!-- 地磁北的yaw角 -->
<param name="mag_pose_2d_topic" value="/mag_pose_2d"/>
<!-- 欧拉角 -->
<param name="Euler_angles_pub_" value="/euler_angles"/>
<!-- 磁力计磁场强度 -->
<param name="Magnetic_pub_" value="/magnetic"/>
<!-- 发布的数据基于不同设备有不同的坐标系 -->
<param name="device_type" value="1"/> <!-- 0: origin_data, 1: for single imu or ucar in ROS, 2:for Xiao in ROS -->
</node>
</launch>
其中 port 要设置成通过脚本更改后的名称 /dev/fdilink_ahrs
串口的波特率 默认是 921600
编译成功后即可 输入指令运行打开惯导
roslaunch fdilink_ahrs ahrs_data.launch
调用的ahrs_driver节点会发布sensor_msgs/Imu
格式的imu topic
。
std_msgs/Header header
uint32 seq
time stamp
string frame_id
geometry_msgs/Quaternion orientation
float64 x
float64 y
float64 z
float64 w
float64[9] orientation_covariance
geometry_msgs/Vector3 angular_velocity
float64 x
float64 y
float64 z
float64[9] angular_velocity_covariance
geometry_msgs/Vector3 linear_acceleration
float64 x
float64 y
float64 z
float64[9] linear_acceleration_covariance
也会发布geometry_msgs/Pose2D
格式的二维指北角话题,话题名默认为/mag_pose_2d
。
float64 x
float64 y
float64 theta # 指北角
通过
rostopic list
查看当前消息列表
rostopic echo /imu
终端打印 imu消息
ROS使用成功
int position_x ;
int position_y ;
int position_z ;
void ImuCallback(const sensor_msgs::ImuConstPtr& imu_data) {
static tf::TransformBroadcaster br;//广播器
tf::Transform transform;
transform.setOrigin(tf::Vector3(position_x, position_y, position_z));//设置平移部分
//从IMU消息包中获取四元数数据
tf::Quaternion q;
q.setX(imu_data->orientation.x);
q.setY(imu_data->orientation.y);
q.setZ(imu_data->orientation.z);
q.setW(imu_data->orientation.w);
q.normalized();//归一化
transform.setRotation(q);//设置旋转部分
//广播出去
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", "imu"));
}
int main (int argc, char ** argv) {
ros::init(argc, argv, "imu_data_to_tf");
ros::NodeHandle node;
std::string imu_topic;
node.param("/imu_tf/imu_topic", imu_topic, std::string("/imu"));
node.param("/imu_tf/position_x", position_x, 0);
node.param("/imu_tf/position_y", position_y, 0);
node.param("/imu_tf/position_z", position_z, 0);
ros::Subscriber sub = node.subscribe(imu_topic.c_str(), 10, &ImuCallback);
ros::spin();
return 0;
}
订阅imu的消息,将其中orientation 以TF形式发布。
然后通过rviz可以查看 姿态角的变化