ROS学习记录:用C++实现IMU航向锁定

前言

获取IMU数据的C++节点
在了解了如何获取到IMU的姿态信息(链接在上面)后,接下来尝试实现让一个节点在订阅IMU数据的时候,还能发布运动控制指令,使机器人能对姿态变化做出反应,达到一个航向锁定的效果。

一、实现步骤

在这里插入图片描述

二、开始操作

1、打开一个终端,输入cd ~/catkin_ws1/src,进入工作空间

在这里插入图片描述

2、输入 code . 打开VScode

在这里插入图片描述

3、在VScode中打开上一篇文章编写的imu_node.cpp, 上一篇文章链接已经放在开头

在这里插入图片描述

4、在imu_node.cpp中写入如下代码

#include "ros/ros.h" //包含ros头文件
#include "sensor_msgs/Imu.h"  //包含sensor_msgs/Imu消息类型头文件
#include "tf/tf.h"//用于使用TF工具,将四元素转换为欧拉角
#include "geometry_msgs/Twist.h"//引入速度消息包的头文件

ros::Publisher vel_pub;//定义一个发布对象vel_pub

void IMUCallback(sensor_msgs::Imu msg)   //IMU消息回调函数
{
    if(msg.orientation_covariance[0]<0)   //检查协方差,确保数据有效性
        return;                            //如果协方差小于0,数据无效,直接返回
    tf::Quaternion quaternion(            //创建四元素
        msg.orientation.x,              //从IMU消息中获取四元素数据
        msg.orientation.y,
        msg.orientation.z,
        msg.orientation.w
    );

    double roll,pitch,yaw;           //定义滚转、俯仰、偏航角

    tf::Matrix3x3(quaternion).getRPY(roll,pitch,yaw);// 利用TF库将四元数转换为欧拉角
    roll = roll*180/M_PI;       // 弧度转换为角度
    pitch = pitch*180/M_PI;     // 弧度转换为角度
    yaw = yaw*180/M_PI;         // 弧度转换为角度
    ROS_INFO("滚转= %.0f  俯仰= %.0f 偏航= %.0f",roll,pitch,yaw);    // 打印欧拉角

    double target_yaw = 90;     //设置目标偏航角
    double diff_angle = target_yaw-yaw;// 计算目标偏航角与当前偏航角之间的差值

    geometry_msgs::Twist vel_cmd;// 创建Twist类型消息对象用于发布速度指令
    vel_cmd.angular.z = diff_angle*0.01;// 计算角速度
    vel_pub.publish(vel_cmd);// 发布速度指令
}

int main(int argc, char  *argv[])   // 主函数
{
    setlocale(LC_ALL,"");           // 设置本地区域选项
    ros::init(argc,argv,"imu_node");        // 初始化ROS节点

    ros::NodeHandle n;              // 创建节点句柄
    ros::Subscriber imu_sub = n.subscribe("/imu/data",10,IMUCallback); // 创建imu_sub订阅者,订阅IMU数据消息
    vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel",10);//创建速度指令发布器

    ros::spin();// 进入自发循环,阻塞程序直至节点关闭

    return 0;
}

5、按CTRL+S进行保存,再按CTRL+SHIFT进行编译,编译成功

在这里插入图片描述

6、在终端中输入cd ~/catkin_ws1,进入工作空间

在这里插入图片描述

7、再输入source ./devel/setup.bash,设置ROS的环境变量,以便在当前的终端窗口中正确运行ROS软件包。

在这里插入图片描述

8、再输入roslaunch wpr_simulation wpb_simple.launch,启动机器人仿真环境

在这里插入图片描述

9、再打开一个终端,进入工作空间后输入source ./devel/setup.bash,设置环境变量

在这里插入图片描述

10、输入rosrun imu_pkg imu_node运行刚刚我们更新的节点

在这里插入图片描述

11、可以看到机器人偏航角锁定在了90度

在这里插入图片描述

12、这时因为在代码中,我们设定了目标偏航角为90度,如果想要机器人朝向其它角度可以自行修改

在这里插入图片描述

13、点这个旋转按钮,对机器人进行旋转,拖动这个蓝色的圈圈,机器人转动后,一松开鼠标,可以发现机器人会自行转回去直至目标角度90度,这便是偏航角锁定

在这里插入图片描述

ROS机器人偏航角锁定演示

14、回到节点代码,在这里加上这一句代码,给机器一个前进的速度,可以预想到,机器人会一边前进一边转弯。

在这里插入图片描述

#include "ros/ros.h" //包含ros头文件
#include "sensor_msgs/Imu.h"  //包含sensor_msgs/Imu消息类型头文件
#include "tf/tf.h"//用于使用TF工具,将四元素转换为欧拉角
#include "geometry_msgs/Twist.h"//引入速度消息包的头文件

ros::Publisher vel_pub;//定义一个发布对象vel_pub

void IMUCallback(sensor_msgs::Imu msg)   //IMU消息回调函数
{
    if(msg.orientation_covariance[0]<0)   //检查协方差,确保数据有效性
        return;                            //如果协方差小于0,数据无效,直接返回
    tf::Quaternion quaternion(            //创建四元素
        msg.orientation.x,              //从IMU消息中获取四元素数据
        msg.orientation.y,
        msg.orientation.z,
        msg.orientation.w
    );

    double roll,pitch,yaw;           //定义滚转、俯仰、偏航角

    tf::Matrix3x3(quaternion).getRPY(roll,pitch,yaw);// 利用TF库将四元数转换为欧拉角
    roll = roll*180/M_PI;       // 弧度转换为角度
    pitch = pitch*180/M_PI;     // 弧度转换为角度
    yaw = yaw*180/M_PI;         // 弧度转换为角度
    ROS_INFO("滚转= %.0f  俯仰= %.0f 偏航= %.0f",roll,pitch,yaw);    // 打印欧拉角

    double target_yaw = 90;     //设置目标偏航角
    double diff_angle = target_yaw-yaw;// 计算目标偏航角与当前偏航角之间的差值

    geometry_msgs::Twist vel_cmd;// 创建Twist类型消息对象用于发布速度指令
    vel_cmd.angular.z = diff_angle*0.01;// 计算角速度
    vel_cmd.linear.x = 0.1;//给机器人x轴方向一个0.1m/s的线速度
    vel_pub.publish(vel_cmd);// 发布速度指令
}

int main(int argc, char  *argv[])   // 主函数
{
    setlocale(LC_ALL,"");           // 设置本地区域选项
    ros::init(argc,argv,"imu_node");        // 初始化ROS节点

    ros::NodeHandle n;              // 创建节点句柄
    ros::Subscriber imu_sub = n.subscribe("/imu/data",10,IMUCallback); // 创建imu_sub订阅者,订阅IMU数据消息
    vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel",10);//创建速度指令发布器

    ros::spin();// 进入自发循环,阻塞程序直至节点关闭

    return 0;
}

15、CTRL+S保存后,在按CTRL+SHIFT编译,编译成功

在这里插入图片描述

16、先按CTRL+Z停止运行刚刚的节点,在重新运行节点

在这里插入图片描述

17、可以看到当拉动蓝色的圈圈后,机器人一边转一边前进

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/643207.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自己手写一个单向链表【C风格】

//单链表 #include <iostream> #define MAX_SIZE 20 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0typedef int ElemType;//元素的类型 typedef int Status;//返回状态typedef struct Node {ElemType data;//链表中保存的数据struct Node* next;//指向下…

从零开始学逆向,js逆向启蒙:有道翻译

语言&#xff1a;js、python 工具&#xff1a;pycharm、chrome浏览器F12调试、chatgpt&#xff08;补充js第三方库&#xff0c;转python&#xff09;、node.js(js运行)&#xff08;必须&#xff09; 目标&#xff1a;学习掌握基本js逆向知识。 对象&#xff1a; 有道翻译 &a…

使用C/C++ API接口操作 Zookeeper 数据

ZooKeeper 支持 Java 和 C 的API接口。本文将介绍使用 C/C 语言客户端库的编译安装和使用入门。 一、编译安装 PS&#xff1a;就在上一篇文章还觉得安装和配置 jdk 、maven 麻烦&#xff0c;所以当时选择 apache-zookeeper-[version]-bin.tar.gz 的版本。然而&#xff0c;本文…

K8S认证|CKA题库+答案| 12. 查看Pod日志

12、查看Pod日志 您必须在以下Cluster/Node上完成此考题&#xff1a; Cluster Master node Worker node k8s master …

企业ov代码签名证书1300

我们在下载一些软件代码时&#xff0c;有时候操作系统会出现未知软件拦截&#xff0c;各个杀毒软件也会因为软件身份不明拦截软件下载。而代码签名证书可以对软件进行数字签名&#xff0c;以验证软件的身份和完整性。这种数字签名机制确保了软件在传输和安装过程中没有被篡改或…

1小时从0开始搭建自己的直播平台(详细步骤)

本文讲述了如何从0开始&#xff0c;利用腾讯云的平台&#xff0c;快速搭建一个直播平台的过程。 文章目录 效果图详细步骤准备工作第一步&#xff1a;添加域名并检验cname配置1.先填加一个推流域名2. 点击完下一步&#xff0c;得到一个cname地址3. 将cname地址&#xff0c;配置…

哥白尼哨兵系列卫星数据不能下载的解决方法

自2023年1月24日起&#xff0c;一个新的哥白尼数据空间生态系统已经启动&#xff0c;为所有哨兵数据&#xff08;Sentinel-1, Sentinel-2, Sentinel-3 and Sentinel-5P&#xff09;提供可视化和数据处理&#xff0c;地址为&#xff1a;https://dataspace.copernicus.eu/。详细介…

重构2:重构的原则之笔记

最近在看重构2&#xff1a;改善既有代码的设计这本书&#xff0c;对于代码重构指导非常有帮助&#xff0c;然后也是做个笔记记录下&#xff0c;以下是我阅读本书的前两章的时候整理的思维导图&#xff1a;

若依框架对于后端返回异常后怎么处理?

1、后端返回自定义异常serviceException 2、触发该异常后返回json数据 因为若依对请求和响应都封装了&#xff0c;所以根据返回值response获取不到Code值但若依提供了一个catch方法用来捕获返回异常的数据 3、处理的方法

Golang的基本使用

目录 变量的声明 Golang常用容器 defer 有趣的多态 结构体标签和reflect 反射 Golang最强的协程 channel go可能造成的内存泄露 变量的声明 方法 1:有类型,有var,不赋值 在Golang中默认值为0 方法 2:无类型,有var,赋值 方法 3:无类型,无var,赋值 多变量声明 多变…

Volatile的内存语义

1、volatile的特性 可见性&#xff1a;对一个volatile变量的读&#xff0c;总能够看到任意一个线程对这个volatile变量的写入。 原子性&#xff1a;对任意单个volatile变量的读/写具有原子性&#xff0c;但类似于volatile这种复合操作不具有原子性。 接下来我们用程序验证。…

Springboot开发 -- Postman 调试类型详解

引言 在 Spring Boot 应用开发过程中&#xff0c;接口测试是必不可少的一环。Postman 作为一款强大的 API 开发和测试工具&#xff0c;可以帮助开发者轻松构建、测试和管理 HTTP 请求。本文将为大家介绍如何在 Spring Boot 开发中使用 Postman 进行接口测试。 一、准备工作 安…

3D透视图转的时候模型闪动怎么解决?---模大狮模型网

在3D建模与渲染的世界中&#xff0c;透视图是我们观察和操作模型的重要窗口。然而&#xff0c;有时候在旋转透视图时&#xff0c;模型会出现闪动的现象&#xff0c;这不仅影响了我们的工作效率&#xff0c;还可能对最终的渲染效果产生负面影响。本文将探讨这一问题的成因&#…

魔众文库系统v6.6.0分销功能,后台日志重构,文档转换优化

分销功能&#xff0c;后台日志重构&#xff0c;文档转换优化 [新功能] 升级支持支付宝授权登录最新方式 [新功能] 后台左上角标题支持自定义&#xff0c;修改 modstart.php 中 admin.title 配置 [新功能] 日志界面重构&#xff0c;全新日志查看体验 [新功能] 链接选择弹窗增…

C++:vector的介绍及使用

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 文章目录 前言 一、vector的介绍 二、vector的使用 2.1.构造和赋值重载&#xff08;Member functions&#xff09; 2.2 vector iterator 的使用 2.3 vector 空间增长问题 2.4 vector 增删查改 三 sort 四 v…

电脑文件qt5core.dll如何修复?如何快速的解决qt5core.dll丢失问题

软件应用程序依赖于各种复杂的文件系统以保证其顺畅运行。这些文件中&#xff0c;动态链接库&#xff08;Dynamic Link Library&#xff0c;简称DLL&#xff09;是Windows操作系统中实现多种功能的关键组件之一。然而&#xff0c;DLL文件出现问题是Windows用户可能面临的常见挑…

内容营销SEO包括哪些内容?

在seo领域&#xff0c;内容营销其实主要就包含两方面&#xff0c;内容的创造以及优化&#xff0c;文章是内容&#xff0c;视频是内容&#xff0c;而对于seo&#xff0c;文章的内容比重自然就很大了&#xff0c;毕竟光是文章&#xff0c;就能分为好几类&#xff0c;比如长篇指南…

几张自己绘制的UML图

全部来源于公司项目&#xff0c;使用建模工具 Enterprise Architect。自己做的其余文档&#xff08;含绘图&#xff09;&#xff0c;因保密协议不便于公开。

深入了解Socket套接字

目录 一、引入&#x1f64c; 1、概念 &#x1f389; 2、分类&#x1f389; Socket 套接字主要针对传输层协议分为流套接字、数据报套接字、原始套接字&#xff08;了解即可&#xff09;三类。 1&#xff09;流套接字&#xff1a;使用传输层TCP协议 2&#xff09;数据报套…

《我的阿勒泰》读后感

暂没时间写&#xff0c;记录在此&#xff0c;防止忘记&#xff0c;后面补上!!! 【经典语录】 01、如果天气好的话&#xff0c;阳光广阔地照耀着世界&#xff0c;暖洋洋又懒洋洋。这样的阳光下&#xff0c;似乎脚下的每一株草都和我一样&#xff0c;也把身子完全舒展开了。 02、…