当前位置: 首页 > news >正文

ROS1学习第三弹

ROS1学习第二弹
本文纯属记录学习过程,所学教程来自B站古月居ROS入门21讲

tf工具的使用

命令行中

1.rosrun tf view_frames 生成当前各个坐标的结构图,导出pdf文件到当前终端所在文件夹下面在这里插入图片描述2.rosrun rviz rviz -d rospackage find turtle_tf /rviz/turtle_rviz.rviz
在图中蓝色处要修改一下父亲坐标系
在这里插入图片描述

代码实现

广播:

#include<ros/ros.h>
#include<tf/transform_broadcaster.h>
#include<turtlesim/Pose.h>std::string turtle_name;  // 存储乌龟名称(由命令行参数传入)// 回调函数:处理订阅的乌龟位姿消息,并发布TF变换
void poseCallback(const turtlesim::PoseConstPtr& msg)
{// 创建TF广播器(static确保只创建一次)static tf::TransformBroadcaster bro;// 创建变换对象,设置平移部分(x, y, z)tf::Transform transform;transform.setOrigin(tf::Vector3(msg->x, msg->y, 0.0));// 创建四元数对象,设置旋转部分(由欧拉角转换而来)tf::Quaternion q;q.setRPY(0, 0, msg->theta);  // 绕Z轴旋转theta角度(乌龟朝向)transform.setRotation(q);// 发送带时间戳的变换:// 参数1:变换对象// 参数2:当前时间戳// 参数3:父坐标系名称("world")// 参数4:子坐标系名称(乌龟名称,如"turtle1")bro.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));
}int main(int argc, char **argv)
{// 初始化ROS节点,节点名称必须唯一// 注意:节点名称在命令行中通过__name:=参数指定,而非此处的硬编码名称ros::init(argc, argv, "my_tf_broadcaster");// 检查命令行参数(必须提供乌龟名称,如"turtle1"或"turtle2")if(argc != 2){ROS_ERROR("需要传入乌龟名称作为参数");return -1;}// 从命令行参数获取乌龟名称(argv[1])turtle_name = argv[1];// 创建节点句柄,用于与ROS系统通信ros::NodeHandle node;// 订阅乌龟的位姿话题(如"/turtle1/pose")// 回调函数poseCallback将在收到消息时被调用ros::Subscriber sub = node.subscribe(turtle_name + "/pose", 10, &poseCallback);// 进入循环等待回调(阻塞当前线程)ros::spin();return 0;
}

监听:

#include<ros/ros.h>
#include<tf/transform_listener.h>
#include<geometry_msgs/Twist.h>
#include<turtlesim/Spawn.h>int main(int argc, char **argv)
{// 初始化ROS节点,命名为"my_tf_listener"ros::init(argc, argv, "my_tf_listener");ros::NodeHandle node;// 等待/spawn服务可用(用于创建新乌龟)ros::service::waitForService("/spawn");// 创建服务客户端,连接到/spawn服务ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");// 准备Spawn服务请求(创建新乌龟)turtlesim::Spawn srv;// 注意:此处未设置srv.request参数,将使用默认值(可能导致重复创建同名乌龟)add_turtle.call(srv);  // 调用服务创建乌龟// 创建速度指令发布者,发布到/turtle2/cmd_vel话题,控制turtle2移动ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel", 10);// 创建TF监听器,用于接收和缓存TF变换数据tf::TransformListener listener;// 设置循环频率为10Hzros::Rate rate(10.0);while(node.ok())  // 主循环,直到节点被关闭{tf::StampedTransform transform;  // 存储变换结果的对象try{// 等待并查找turtle1相对于turtle2的变换// 参数1:目标坐标系(turtle2)// 参数2:源坐标系(turtle1)// 参数3:时间戳(ros::Time(0)表示最新可用变换)// 参数4:超时时间(等待3秒)listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);}catch(tf::TransformException &ex){// 捕获变换异常并打印错误信息ROS_ERROR("%s", ex.what());ros::Duration(1.0).sleep();  // 暂停1秒后继续continue;}// 计算控制指令,使turtle2跟随turtle1geometry_msgs::Twist vel_msg;// 角速度控制(转向):// atan2计算turtle1相对于turtle2的角度,乘以4.0放大控制量vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x());// 线速度控制(前进):// 计算turtle1与turtle2的距离,乘以0.5作为前进速度vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2));// 发布控制指令turtle_vel.publish(vel_msg);rate.sleep();  // 休眠以维持10Hz的频率}return 0;
}

launch文件

launch语法

<launch><node pkg="pkg_name", node="node_name", type="executable_name"/>
</launch>

参数设置(param)

用于设置ROS系统运行中的参数,存储在参数服务器中

<param name="output_frame" value="odom"/>
  • name:参数名
  • value:参数值

参数文件加载(rosparam)

加载YAML文件中的多个参数

<rosparam file="params.yaml" command="load" ns="params"/>

局部变量(arg)

launch文件内部的局部变量,仅限于launch文件使用

<arg name="arg-name" default="arg-value"/>
  • name:参数名
  • default:参数值(默认值)

局部变量调用方法

  1. 在param中调用
<param name="foo" value="$(arg arg-name)"/>
  1. 在node中调用
<node name="node" pkg="package" type="type" args="$(arg arg-name)"/>

重映射(remap)

重命名ROS计算图资源(如Topic、Service等)

<remap from="/turtlebot/cmd_vel" to="/cmd_vel"/>
  • from:原始名称
  • to:映射后的新名称

包含其他launch文件(include)

在launch文件中包含另一个launch文件,类似C语言中的头文件包含

<include file="${dirname}/other.launch"/>
  • file:被包含的launch文件路径(可使用$(find pkg)或变量如${dirname}

其余可参考官网

工作空间中

以最简单的在同一终端下运行两个节点为例:

<launch><node pkg="learning_topic" type="person_subscriber" name="talker" output="screen" /><node pkg="learning_topic" type="person_publisher" name="listener" output="screen" />
</launch>

在这里插入图片描述

<launch><!-- 全局参数 --><param name="/turtle_number" value="2"/><!-- 节点1 --><node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node" output="screen"><!-- 节点自己的参数 --><param name="turtle_name1" value="Tom"/><param name="turtle_name2" value="Jerry"/><!-- 加载YAML参数文件 --><rosparam file="$(find learning_launch)/config/param.yaml" command="load" /></node><!-- 节点2 --><node pkg="turtlesim" type="turtle_teleop_key" name="turtle_teleop_key" output="screen"/>
</launch>

在这里插入图片描述调用之前的 learning_tf 功能包

<launch><node pkg="turtlesim" type="turtlesim_node" name="sim" /><node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen" /><node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle1" name="turtle1_tf_broadcaster" /><node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle2" name="turtle2_tf_broadcaster" /><node pkg="learning_tf" type="learning_tf_listener" name="listener" /></launch>

在这里插入图片描述

可视化工具

rqt_bag
rqt_graph
rqt_plot
rqt_console
rqt_image_view
rqt_shell
rqt_dep
rqt_logger_level
rqt_topic
rosrun rviz rivz

http://www.dtcms.com/a/274193.html

相关文章:

  • uniApp实战五:自定义组件实现便捷选择
  • MyBatis缓存穿透深度解析:从原理到实战解决方案
  • Selenium 自动化实战技巧【selenium】
  • frame 与新窗口切换操作【selenium 】
  • 【JMeter】调试方法
  • Conda 安装与配置详解及常见问题解决
  • 从代码学习深度强化学习 - PPO PyTorch版
  • 番外-linux系统运行.net framework 4.0的项目
  • 《Java EE与中间件》实验三 基于Spring Boot框架的购物车
  • 【flutter】flutter网易云信令 + im + 声网rtm从0实现通话视频文字聊天的踩坑
  • 如何蒸馏 设计 中文nl2sql 数据集,进行grpo强化学习 训练qwen3-8b,可以提升大模型nl2sql的能力,支持300行sql生成
  • Redis 分片集群
  • mysql报错服务没有报告任何错误
  • AIGC(生成式AI)试用 33 -- 用AI学AI名词
  • 彻底解决JavaFx在Linux中文无法正常显示的问题(究其根本原因)
  • 剑指offer——数组:数组中重复的数字
  • 博客系统开发全流程解析(前端+后端+数据库)与 AI 协作初体验
  • [大模型问数]实现大模型调用MYSQL(03)【MCP笔记】
  • Prometheus+Grafana部署及企业微信邮件/群消息告警通知配置
  • Shader面试题100道之(81-100)
  • 中学物理模拟实验Python程序集成打包
  • 牛客周赛 Round 99
  • Spring 声明式事务:从原理到实现的完整解析
  • 破解多宠管理难题,端侧AI重新定义宠物智能硬件
  • 《Spring 中上下文传递的那些事儿》Part 10:上下文敏感信息脱敏与审计日志记录
  • ESP32_启动日志分析
  • 【TCP/IP】17. 移动 IP
  • Linux权限的概念
  • 硬件加速(FPGA)
  • 函数指针指针函数 智能指针