ROS学习之基础包创建的详细流程:包括rosnode, rostopic, rosrun,roslaunch等使用

news2024/7/6 18:07:41

0 引言

本文旨在学习ROS基础包的从零开始创建,包括如何创建一个发布消息节点,一个接收消息节点,还有如何使用roslaunch同时启动多个节点,如何编译ROS工程包等操作。

默认已在Ubuntu系统中安装ROS机器人系统,比如Ubuntu18.04-melodic
工程目录tree

# catkin_ws/src 目录下
.
├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
└── hello_world
    ├── CMakeLists.txt
    ├── include
    │   └── hello_world
    ├── launch
    │   └── talker_listener.launch
    ├── package.xml
    └── src
        ├── listener.cpp
        └── talker.cpp

1 工作空间创建并初始化

# 新开一个终端
# 创建一个名为catkin_ws工作空间,及src子目录
mkdir -p ~/catkin_ws/src
# 进入到src文件夹
cd ~/catkin_ws/src
# 初始化工作空间
catkin_init_workspace
# 回到工作空间根目录 
cd .. 
# 编译工作空间 
catkin_make

2 创建ROS程序包

# 切换到src文件夹
cd ~/catkin_ws/src
# 创建名为hello_world的ROS程序包,以后创建其他的包也是此方法,只需修改包的名称即可
catkin_create_pkg hello_world roscpp rospy std_msgs

执行后,src目录下新建了一个 hello_world文件夹及子目录和子文件

.
├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
└── hello_world
    ├── CMakeLists.txt
    ├── include
    │   └── hello_world
    ├── package.xml
    └── src

3 创建消息节点

3.1 发布消息节点

在 hello_world/src 代码资源文件夹下新建发布消息节点的talker.cpp文件,详细代码如下:

#include "ros/ros.h" //创建ROS节点必须包含的头文件,固定格式
#include "std_msgs/String.h" //节点中使用某种特定的消息类型
#include <sstream> // c++中用来处理面向流的输入和输出的标准库

int main(int argc,char **argv)
{
	ros::init(argc,argv,"talker"); // 初始化一个名为talker的节点,以后写其他的节点只要修改talker就行
	ros::NodeHandle n; // 创建名为n的节点句柄,自己写程序只要改n这个地方就行
	// ROS节点中发布话题的方式,chatter_pub是发布者实例,发布消息的类型是std_msgs/String的话题,
	// topic话题名称为chatter,队列大小为1000,n为访问实例,要修改的话就改提到的这几个地方
	ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter", 1000);
	ros::Rate loop_rate(10); // 制定循环的频率,此处为10HZ,固定格式
	int count=0; // 进入节点的主循环,在节点未发生异常的情况下将一直在循环,固定格式
	while(ros::ok()) // 当Ctrl+c按下时,ros::ok()将会返回false,固定格式
	{
		// 初始化std_msgs::String类型的消息
		std_msgs::String msg;
		std::stringstream ss;
		ss<<"hello world"<<count;
		msg.data=ss.str(); // 用data来存储字符串
		// 发布消息
		ROS_INFO("%s",msg.data.c_str()); //ROS_INFO类似于cout和printf
		chatter_pub.publish(msg); // 发布封装完毕的消息msg
		// 循环等待回调函数
		ros::spinOnce(); // 用来处理节点订阅话题的所有回调函数
		// 按照循环频率延时,固定格式
		loop_rate.sleep();
		++count;
	}
	return 0;
}

3.2 接收消息节点

在 hello_world/src 代码资源文件夹下新建接收消息节点的listener.cpp文件,详细代码如下:


#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc,char **argv)
{
	ros::init(argc,argv,"listener"); // 初始化一个名为listener的节点
	ros::NodeHandle n; // 创建名为n的节点句柄
	// 创建一个Subscriber的话题,注册回调函数chatterCallback
	ros::Subscriber sub=n.subscribe("chatter", 1000, chatterCallback);
	// 循环等待回调函数
	ros::spin();
	return 0;
}  

// 接收到订阅的消息,进入回调函数
void chatterCallback(const std_msgs::String::ConstPtr & msg)
{
	ROS_INFO("I heard: [%s]", msg->data.c_str()); // 将接收的消息打印出来
}

4 编辑CMakeLists.txt

执行第2步后,hello_world文件夹下生成了CMakeLists.txt,打开编辑:

# 第一行修改cmake最小版本为 2.8.3
cmake_minimum_required(VERSION 2.8.3)

# 最后添加以下几行
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker hello_world)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener hello_world)

5 编译程序包

# 回到catkin_ws工作空间
cd ~/catkin_ws/src
# 执行catkin_make编译
catkin_make

6 运行消息节点

# 新开终端
roscore
# 新开终端,运行talker节点
source ~/catkin_ws/devel/setup.bash 
rosrun hello_world talker

运行后,可以看到已成功创建发布消息的节点,并持续发布消息:

[ INFO] [1688019211.336438520]: hello world0
[ INFO] [1688019211.436538723]: hello world1
[ INFO] [1688019211.536531392]: hello world2
[ INFO] [1688019211.636536978]: hello world3
[ INFO] [1688019211.736561791]: hello world4
[ INFO] [1688019211.836520559]: hello world5
[ INFO] [1688019211.936556623]: hello world6
[ INFO] [1688019212.036533914]: hello world7
[ INFO] [1688019212.136574843]: hello world8
[ INFO] [1688019212.236534653]: hello world9
[ INFO] [1688019212.336576466]: hello world10
[ INFO] [1688019212.436533892]: hello world11
[ INFO] [1688019212.536543132]: hello world12
...
# 新开终端,运行listener节点
source ~/catkin_ws/devel/setup.bash 
rosrun hello_world listener

运行后,可以看到打印已订阅talker发出的消息:

[ INFO] [1688019425.918466687]: I heard: [hello world4]
[ INFO] [1688019426.018305977]: I heard: [hello world5]
[ INFO] [1688019426.117968093]: I heard: [hello world6]
[ INFO] [1688019426.218154007]: I heard: [hello world7]
[ INFO] [1688019426.318345417]: I heard: [hello world8]
[ INFO] [1688019426.418056486]: I heard: [hello world9]
[ INFO] [1688019426.517999187]: I heard: [hello world10]
[ INFO] [1688019426.618130109]: I heard: [hello world11]
[ INFO] [1688019426.718321709]: I heard: [hello world12]
[ INFO] [1688019426.818094286]: I heard: [hello world13]
[ INFO] [1688019426.917948960]: I heard: [hello world14]
[ INFO] [1688019427.017976226]: I heard: [hello world15]
[ INFO] [1688019427.118302080]: I heard: [hello world16]

7 添加launch启动文件

rosrun只能启动一个消息节点,可以用ROS中launch文件启动多个节点,在hello_world文件夹中新建launch文件夹,并在launch文件夹中新建talker_listener.launch,打开talker_listener.launch,添加如下xml格式的代码:

<launch>
	<node name="listener_node" pkg="hello_world" type="listener" output="screen"/>
	<node name="talker_node" pkg="hello_world" type="talker" output="screen"/>
</launch>

  • node name: 该节点的名字,相当于代码中 ros::init() 中设置的信息,有了它代码中的名称会被覆盖;
  • pkg: 表示该节点的package,相当于 rosrun 命令后面的第一个参数;
  • type: 可执行文件的名字,rosrun 命令的第二个参数;是否可以理解为要执行的节点;
  • output=“screen”: 将标准输出显示在屏幕上而不是记录在日志中

8 重新编译

# 新开终端
# 重新编译前,先给talker_listener.launch可执行权限
sudo chmod +x ~/catkin_ws/src/hello_world/launch/talker_listener.launch

# 回到catkin_ws工作空间
cd ~/catkin_ws
# 重新编译
catkin_make

9 运行launch文件

# 编译后,重新source
source ~/catkin_ws/devel/setup.bash
# 运行talker_listener.launch
roslaunch hello_world talker_listener.launch

运行后,自动启动了roscore, 也启动了talker和listener两个消息节点:

Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://px:35833/

SUMMARY
========

PARAMETERS
 * /rosdistro: melodic
 * /rosversion: 1.14.11

NODES
  /
    listener_node (hello_world/listener)
    talker_node (hello_world/talker)

ROS_MASTER_URI=http://localhost:11311

process[listener_node-1]: started with pid [30875]
process[talker_node-2]: started with pid [30877]
[ INFO] [1688020081.054048128]: hello world0
[ INFO] [1688020081.154174941]: hello world1
[ INFO] [1688020081.254183692]: hello world2
[ INFO] [1688020081.354176431]: hello world3
[ INFO] [1688020081.354852999]: I heard: [hello world3]
[ INFO] [1688020081.454181460]: hello world4
[ INFO] [1688020081.454357334]: I heard: [hello world4]
[ INFO] [1688020081.554196089]: hello world5
[ INFO] [1688020081.554813633]: I heard: [hello world5]
[ INFO] [1688020081.654196695]: hello world6
[ INFO] [1688020081.654732170]: I heard: [hello world6]
...

10 查看节点和topic

查看消息node

rosnode list

输出:

/listener_node
/rosout
/talker_node

查看话题topic

rostopic list

输出:

/chatter
/rosout
/rosout_agg

用rqt_graph查看消息节点node和话题topic的关系

请添加图片描述
至此,成功创建一个ROS基础包,并包含一个发布节点,一个接收节点,一个话题用来传递消息,也学习了基础的ROS包编译等操作。




须知少时凌云志,曾许人间第一流。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AOP--拦截器

AOP应用--拦截器Spring拦截器拦截器执行流程前缀的添加统一异常处理统一数据返回格式返回String类型 AOP应用–拦截器 AOP的作用&#xff1a;统一功能处理&#xff1b;我们将以三个内容作为学习的掌握点&#xff1b;而这三点也是我们非常迫切需要的 1&#xff1a;用户登录权限…

Windows系统分区大小

Microsoft Reserved&#xff08;MSR&#xff09;——保留分区——16MB左右 EFI System Partition&#xff08;ESP&#xff09;——系统分区——100MB左右 Recovery Partition&#xff08;自起名字REP&#xff09;——恢复分区——450MB左右 其他分区——剩余

对rabbitmq进行压测

添加rabbitmq依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactI…

C# PaddleOCR标注工具

基于以下开源项目改造的 https://gitee.com/BaoJianQiang/FastOCRLabel 效果 Demo下载

CMake使用gRPC(Protobuf) 的c++ demo

gRPC的命令参数里&#xff0c; 1. 如果要用pacakge&#xff0c;需要--proto_path的参数&#xff0c; 例如helloworld.proto的绝对路径是 /home/user/grpc_demo_ws/grpc_demo/hello_world/proto/helloworld.proto 在helloworld.proto里面的pacakge是 package grpc_demo.hello_w…

同步(通信原理)

同步原理&#xff1a; 在通信系统中&#xff0c;同步是指发送端和接收端在时间上保持一致&#xff0c;使得接收端能够正确地解析和还原发送端发送的信号。同步的原理可以根据具体的通信系统和协议来区分&#xff0c;下面是几种常见的同步原理&#xff1a; 1. 时钟同步&#x…

uniapp 配置chooseLocation微信小程序腾讯地图选点

uniapp 配置chooseLocation微信小程序腾讯地图选点 场景 在uniapp中使用地图选点 搜索功能&#xff0c;回显功能&#xff0c;移动选点功能 使用到的API是uni.chooseLocation 详细看一下都有哪些属性 latitude &#xff1a;目标地纬度 Number longitude &#xff1a;目标地经度…

论文阅读: (CVPR2023 SDT )基于书写者风格和字符风格解耦的手写文字生成及源码对应

目录 引言SDT整体结构介绍代码与论文对应搭建模型部分数据集部分 总结 引言 许久不认真看论文了&#xff0c;这不赶紧捡起来。这也是自己看的第一篇用到Transformer结构的CV论文。之所以选择这篇文章来看&#xff0c;是考虑到之前做过手写字体生成的项目。这个工作可以用来合成…

浅析基于物联网技术的校园能耗智慧监控平台的设计及应用

摘 要&#xff1a;为打造低碳绿色校园&#xff0c;营造良好的学习环境&#xff0c;针对目前校园建筑能耗大&#xff0c;特别是空调节能困难等问题&#xff0c;特采用物联网技术构建校园建筑能耗智慧监控平台。通过设计空调监控子系统&#xff0c;搭建空调监控模型实现了空调等智…

在 Jetpack Compose 中使用 Snackbar

Jetpack Compose 是 Android 的现代 UI 工具库&#xff0c;提供了丰富的组件和功能来构建漂亮、交互丰富的用户界面。在本文中&#xff0c;我们将学习如何在 Jetpack Compose 中使用 Snackbar 组件来显示临时消息或操作反馈。 什么是 Snackbar&#xff1f; Snackbar 是一种用于…

基于Layui实现管理页面

基于Layui实现的后台管理页面&#xff08;仅前端&#xff09; 注&#xff1a;这是博主在帮朋友实现的一个简单的系统前端框架&#xff08;无后端&#xff09;&#xff0c;跟大家分享出来&#xff0c;可以直接将对应菜单跟html文件链接起来&#xff0c;页面使用标签页方式存在&…

面试了一个前阿里P7,Java八股文与架构核心知识简直背得炉火纯青

前几天&#xff0c;跟个老朋友吃饭&#xff0c;他最近想跳槽去大厂&#xff0c;觉得压力很大&#xff0c;问我能不能分享些所谓的经验套路。 每次有这类请求&#xff0c;都觉得有些有趣&#xff0c;不知道你发现没有大家身边真的有很多人不知道怎么面试&#xff0c;也不知道怎…

赛效:如何将PDF文件免费转换成Word文档

1&#xff1a;在网页上打开wdashi&#xff0c;默认进入PDF转Word页面&#xff0c;点击中间的上传文件图标。 2&#xff1a;将PDF文件添加上去之后&#xff0c;点击右下角的“开始转换”。 3&#xff1a;稍等片刻转换成功后&#xff0c;点击绿色的“立即下载”按钮&#xff0c;将…

win10修改IP地址报错:出现一个意外情况,不能完成所有你在......

问题描述 在修改网卡适配器的时候出现一下报错&#xff1a;出现一个意外情况&#xff0c;不能完成你在设置中所要求的更改 问题原因 该问题是由于我之前卸载VMware导致注册表出现问题。 解决方法 解决办法为:修复注册表(下载一个CCleaner下载试用版即可&#xff08;https…

2. 查询至少连续三天下单的用户

文章目录 题目需求思路一实现一思路二实现二 题目需求 查询订单信息表(order_info)中 最少连续3天 下单的用户id&#xff0c;期望结果如下&#xff1a; user_id101 订单信息表&#xff1a;order_info order_id(订单id)user_id(用户id)create_date (下单日期)total_amount(订…

MySQL 数据表修复方法

MySQL表检查与修复 — check/repair指令 目录 MySQL表检查与修复 --- check/repair指令1. 指令详解2. 操作方法&#xff1a;命令提示符(cmd指令)操作方法SQLyog 操作方法&#xff08;推荐&#xff09; 本文主要讲check table和repair table指令&#xff1b; 1. 指令详解 在检…

如何把图片转文字?图片转文字方法分享!​

如何把图片转文字呢&#xff1f;在我们日常的工作或者生活当中&#xff0c;总会遇到需要将图片中的文字提取出来整理出文档&#xff0c;比如同事领导给你发的文件&#xff0c;或者在自己看到了喜欢书的段落句子&#xff0c;想要摘抄下来&#xff0c;这些都是可以用图片转文字来…

C++ Vector容器使用方法详解

Vector概述 C 标准库向量类是序列容器的类模板。 向量以线性排列方式存储给定类型的元素&#xff0c;并允许快速随机访问任何元素。 向量是需要力求保证访问性能时的首选序列容器。vector是种容器&#xff0c;类似数组一样&#xff0c;但它的size可以动态改变。vector的元素在内…

【GESP】2023年06月图形化二级 -- 时间规划

文章目录 时间规划【题目描述】【输入描述】【输出描述】【参考答案】其他测试用例 时间规划 【题目描述】 默认小猫角色和白色背景&#xff0c;小明在为自己规划学习时间。现在他想知道两个时刻之间有多少分钟。你能通过编程帮他做到吗&#xff1f; 【输入描述】 新建变量“…

餐饮市场分析(上)

阅读原文 研究某一类餐饮产品的市场概况&#xff0c;并在不同地区和品牌之间进行对比 一、数据需求 使用美团搜索商品返回的数据。 首先进入美团首页&#xff0c;切换到对应城市&#xff0c;并搜索感兴趣的关键词。接下来尝试翻页获取更多数据&#xff0c;点击下一页时发现页…