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.pswp.cn/web/88438.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88438.shtml
英文地址,请注明出处:http://en.pswp.cn/web/88438.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术演进中的开发沉思-30 MFC系列:五大机制

MFC&#xff0c;记得我刚毕业时在 CRT 显示器前敲下第一行 MFC 代码时&#xff0c;那时什么都不懂&#xff0c;没有框架的概念。只觉得眼前的 CObject 像位沉默且复杂的大家族&#xff0c; 就像老北京胡同里的大家族&#xff0c;每个门牌号都藏着自己的故事。但现在看看&#x…

机器学习-06(Optimization-自动调整学习率)

临界点其实不一定是在训练神经网络过程中遇到的最大阻碍。随着对参数的不断更新&#xff0c;Loss值会不断下降&#xff0c;直至几乎没有变化&#xff0c;不再下降。当参数更新到临界点时&#xff0c;意味着gradient非常小&#xff0c;所以要认定参数是否到达临界点应当确认grad…

Uniapp中的uni.scss

uni.scss为uni-app新建项目自带工程文件&#xff0c;使用的预处理器为sass/scss&#xff0c;由此可见&#xff0c;uni-app官方推荐的是scss。 uni.scss特点 无需引入&#xff0c;uni-app在编译时&#xff0c;会自动引入此文件在此中定义的scss变量&#xff0c;可以全局使用&…

PreparedStatement 实现分页查询详解

PreparedStatement 实现分页查询详解 在 JDBC 中使用 PreparedStatement 实现分页查询是高效安全的方式&#xff0c;可以避免 SQL 注入并提升性能。下面我将详细说明实现步骤和原理。 &#x1f4d0; 分页查询核心参数参数名说明计算公式pageNum当前页码&#xff08;从1开始&…

ClamAV 和 FreshClam:Linux 服务器上的开源杀毒解决方案

ClamAV 和 FreshClam:Linux 服务器上的开源杀毒解决方案 1. 概述 ClamAV 是一款开源的防病毒引擎,专为 Linux 服务器设计,用于检测恶意软件、病毒、木马和其他安全威胁。它广泛应用于邮件服务器、文件存储系统和 Web 服务器,提供高效的病毒扫描功能。 主要特点: 免费开…

PySpark中python环境打包和JAR包依赖

在 PySpark 中打包 Python 环境并调度到集群是处理依赖一致性的关键步骤。以下是完整的解决方案&#xff0c;包含环境打包、分发和配置方法&#xff1a; 一、环境打包方法 使用 Conda 打包环境 # 创建 Conda 环境 conda create -n pyspark_env python3.8 conda activate pyspar…

和鲸社区深度学习基础训练营2025年关卡2(1)纯numpy

拟分3种实现方法&#xff1a;1.纯numpy2.sklearn中的MLPClassifier3.pytorch题目&#xff1a; 在 MNIST 数据集上训练 MLP 模型并比较不同的激活函数和优化算法任务描述&#xff1a;使用 MNIST 数据集中的前 20,000 个样本训练一个多层感知机 (MLP) 模型。你需要比较三种不同的…

Sequential Thinking:AI深度思考的新范式及其与CoT、ReAct的对比分析

引言&#xff1a;AI深度思考的演进与Sequential Thinking的崛起在人工智能技术快速发展的今天&#xff0c;AI模型的思考能力正经历着从简单应答到深度推理的革命性转变。这一演进过程不仅反映了技术本身的进步&#xff0c;更体现了人类对机器智能认知边界的持续探索。早期的大语…

云原生详解:构建现代化应用的未来

引言 在数字化转型的浪潮中,"云原生"已成为技术领域最热门的话题之一。从初创公司到全球500强企业,都在积极探索云原生技术以提升业务敏捷性和创新能力。本文将全面解析云原生的概念、核心技术、优势以及实践路径,帮助您深入理解这一改变IT格局的技术范式。 什么…

SSE事件流简单示例

文章目录1、推送-SseEmitter2、接收-EventSourceListenerSSE&#xff08;Server-Sent Events&#xff0c;服务器推送事件&#xff09;是一种基于HTTP的服务器向客户端实时推送数据的技术标准。1、推送-SseEmitter SseEmitter用于实现服务器向客户端单向、长连接的实时数据推送…

Elasticsearch RESTful API入门:基础搜索与查询DSL

Elasticsearch RESTful API入门&#xff1a;基础搜索与查询DSL 本文为Elasticsearch初学者详细解析RESTful API的核心操作与查询DSL语法&#xff0c;包含大量实战示例及最佳实践。 一、Elasticsearch与RESTful API简介 Elasticsearch&#xff08;ES&#xff09;作为分布式搜索…

(六)复习(OutBox Message)

文章目录 项目地址一、OutBox Message1.1 OutBox表配置1. OutBoxMessage类2. OutboxMessage表配置3. 给每个模块生成outboxmessage表1.2 发布OutBox Message1. 修改Intercepotor2. 配置Quartz3. 创建Quatz方法发布领域事件4. 创建Quatz定时任务5. 注册Quatz服务和配置6. 流程梳…

STM32-ADC内部温度

在通道16无引脚&#xff08;测量温度不准确&#xff09;跟ADC代码差不多&#xff1b;不需要使能引脚时钟&#xff1b;将内部温度测量打开/*** brief 启用或禁用温度传感器和内部参考电压功能* param NewState: 新的功能状态&#xff0c;取值为ENABLE或DISABLE* retval 无* no…

「Linux命令基础」文本模式系统关闭与重启

关机重启基本命令 直接拔掉计算机电源可能损坏内部元件;Linux系统通过命令关闭计算机则是安全流程,让所有程序有机会保存数据、释放资源。 关机命令:shutdown Linux系统提供了多种用于关闭或重启系统的命令,其中 shutdown 是最常用的一种,它可以安全地通知用户系统即将…

射频信号(大宽高比)时频图目标检测anchors配置

一、大宽高比目标YOLO检测参数设置 这是yolov7的一个label的txt文件&#xff1a; 1 0.500 0.201 1.000 0.091 2 0.500 0.402 1.000 0.150 3 0.500 0.604 1.000 0.093 0 0.500 0.804 1.000 0.217 对应的样本&#xff1a; 长宽比分别是&#xff1a;1/0.09110.98, 1/0.1506.67…

OpenStack 鉴权服务介绍.md

引言 OpenStack是一个开源的云计算管理平台&#xff0c;其中的Keystone组件承担了身份认证和授权的关键任务。Keystone的主要功能包括管理用户及其权限、维护OpenStack Services的Endpoint&#xff0c;以及实现认证&#xff08;Authentication&#xff09;和鉴权&#xff08;Au…

Linux_3:进程间通信

IPC1.什么是IPC&#xff1f;Inter Process Communication2.进程间通信常用的几种方式1&#xff0c;管道通信&#xff1a;有名管道&#xff0c;无名管道2&#xff0c;信号- 系统开销小3&#xff0c;消息队列-内核的链表4&#xff0c;信号量-计数器5&#xff0c;共享内存6&#x…

【Springboot】Bean解释

在 Spring Boot 中&#xff0c;Bean 就像是你餐厅里的一名员工。比如&#xff0c;你有一名服务员&#xff08;Service&#xff09;、一名厨师&#xff08;Chef&#xff09;和一名收银员&#xff08;Cashier&#xff09;。这些员工都是餐厅正常运转所必需的&#xff0c;他们各自…

axios的post请求,数据为什么要用qs处理?什么时候不用?

为什么使用 qs 处理 POST 数据axios 的 POST 请求默认将 JavaScript 对象序列化为 JSON 格式&#xff08;Content-Type: application/json&#xff09;。但某些后端接口&#xff08;尤其是传统表单提交&#xff09;要求数据以 application/x-www-form-urlencoded 格式传输&…

【unitrix】 4.21 类型级二进制数基本结构体(types.rs)

一、源码 这段代码定义了一个类型级数值系统的 Rust 实现&#xff0c;主要用于在编译时表示和操作各种数值类型。 use crate::sealed::Sealed; use crate::number::{NonZero, TypedInt, Unsigned, Primitive}; // // 特殊浮点值枚举 ///// 特殊浮点值&#xff08;NaN/∞&#x…