ROS2编译Python节点来发布和订阅的实践《2》

通过熟悉:ROS2对比ROS1的一些变化与优势(全新安装ROS2以及编译错误处理)《1》
我们大概了解到了ROS2的重新设计带来的巨大优势,最核心的就是去掉了roscore,这样就避免了因为节点管理器崩溃而使整个系统都崩溃的场景出现,通过DDS的传输协议进行数据的通信,真正做到了去中心化的设计。
虽然很多命令跟ROS1比较都有了新的变化,但很容易接受并熟悉它,也处理了在编译C++与Python的过程中常遇到的一些问题。这节主要来看下,通过Python来定义发布节点与订阅节点。

1、创建工作空间

1.1、ROS2环境

同样,我们新建一个工作空间和创建一个名叫my_pub_sub的package包,然后在这个包下面来写我们的节点。当然如果说环境包含了ROS1的情况,我们先设置ROS2的环境

source /opt/ros/dashing/setup.bash

当然最好的方法还是前面介绍的自行来选择环境:gedit ~/.bashrc

echo "ROS melodic (1) or ROS2 dashing (2)?"
read edition
if [ "$edition" -eq "1" ];thensource /opt/ros/melodic/setup.bashecho using ros melodic
elsesource /opt/ros/dashing/setup.bashecho using ros2 dashing
fi

1.2、创建包

创建包之前,首先建立工作空间 

mkdir -p ~/my_pub_sub_ws/src
cd ~/my_pub_sub_ws/src

对于Python包的创建,生成类型--build-type需指定为ament_python,而编译C++文件指定为ament_cmake
所以这里我们的Python创建包的命令,如下:

ros2 pkg create --build-type ament_python my_pub_sub

如下图,我们将会看到自动生成了my_pub_sub/my_pub_sub的目录,以及一些配置相关文件,诸如:package.xml,setup.cfg,setup.py 

2、测试节点

我们还是使用上节的例子,来测试下新建的环境,这次也是试图没有使用rclpy依赖项,也就是没有指定参数--dependencies rclpy

2.1、PYNode.py

 新建一个Python节点文件

cd ~/my_pub_sub_ws/src/my_pub_sub/my_pub_sub
gedit PYNode.py
#!/usr/bin/env python3import rclpy
from rclpy.node import Nodedef main(args=None):rclpy.init(args=args)node = Node("ChyiChin_Node")node.get_logger().info("Python TEST")rclpy.spin(node)rclpy.shutdown()if __name__ == '__main__':main()

加个可执行权限:chmod +x PYNode.py

当然对文件是否加可执行权限,取决于你的运行方式,这里是运行节点可以不加,有的时候如果是需要直接运行这个Python文件,比如这样的操作:./PYNode.py 就需要加上可执行权限,不然会报权限错误:bash: ./PYNode.py: Permission denied

2.2、修改setup.cfg

cd ~/my_pub_sub_ws/src/my_pub_sub
gedit setup.cfg

将 破折号 修改为 下划线 _,修改为script_dirinstall_scripts
修改之后的内容如下:

script_dir=$base/lib/my_pub_sub
[install]
install_scripts=$base/lib/my_pub_sub

2.3、修改setup.py 

cd ~/my_pub_sub_ws/src/my_pub_sub
gedit setup.py

入口处填写:"ChyiChin_Node=my_pub_sub.PYNode:main"

2.4、编译

修改好了之后,我们就开始编译这个my_pub_sub包

cd ~/my_pub_sub_ws
colcon build --packages-select my_pub_sub
source install/setup.bash

 执行节点:ros2 run my_pub_sub ChyiChin_Node

[INFO] [ChyiChin_Node]: Python TEST

一切OK,没有发现问题,看来只需要指定Python的入口函数的位置,就可以正常的执行Python文件了。所以对于在package.xml里面做修改也是不需要的,因为网上有些是在这个xml文件中做了依赖项的配置,不设置也是可以的,也能正常运行。

cd ~/my_pub_sub_ws/src/my_pub_sub
gedit package.xml
/*
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>
*/

代码比较简单,这里的rclpy库,类似ROS1中rospy的用法,主要是对节点的创建与管理,ROS2的底层是使用C语言写的,名字就是rcl库,而这个rclpy就是在这个基础上做的对Python的封装接口,对C++做的封装就是rclcpp,这样的好处就是Python与C++在调用API的时候更加的统一相似,同时对ROS2进行功能更新时,直接更新rcl库,再新增cpp与python的支持即可。

3、发布节点

配置环境和编译没有问题之后,接下来就是常见的发布与订阅操作,我们先来写一个发布的节点。 

cd ~/my_pub_sub_ws/src/my_pub_sub/my_pub_sub
gedit pub_test.py
#!/usr/bin/env python3import rclpy
from rclpy.node import Node
from std_msgs.msg import Stringclass Publisher(Node):def __init__(self,name):super().__init__(name)self.publisher = self.create_publisher(String,"talker_topic",10)timer_period = 5self.timer = self.create_timer(timer_period,self.timer_callback)self.get_logger().info("hello,I'm %s!" %name)self.i = 0def timer_callback(self): msg = String()msg.data = 'NO.%d,hello!' %(self.i)self.publisher.publish(msg)self.get_logger().info("Publishing: %s"%msg.data)self.i += 1def main(args=None):rclpy.init(args=args)node = Publisher("talker") rclpy.spin(node)rclpy.shutdown()if __name__ == '__main__':main()
cd ~/my_pub_sub_ws/src/my_pub_sub
gedit setup.py

入口处填写(这个跟前面的使用逗号进行隔开):"talker=my_pub_sub.pub_test:main"

 编译:

cd ~/my_pub_sub_ws
colcon build --packages-select my_pub_sub
source install/setup.bash

运行发布节点:ros2 run my_pub_sub talker

[INFO] [talker]: hello,I'm talker!
[INFO] [talker]: Publishing: NO.0,hello!
[INFO] [talker]: Publishing: NO.1,hello!
[INFO] [talker]: Publishing: NO.2,hello!
[INFO] [talker]: Publishing: NO.3,hello!
[INFO] [talker]: Publishing: NO.4,hello!
...

 查看下话题:ros2 topic list

/parameter_events
/rosout
/talker_topic

 查看talker_topic话题当前传输的信息:ros2 topic echo /talker_topic

data: NO.9,hello!
---
data: NO.10,hello!
---
data: NO.11,hello!
---
data: NO.12,hello!

代码也比较简单,初始化一个talker节点,里面创建一个类型是String的talker_topic的话题,队列长度为10,另外在上述代码基础上增加了一个定时器,每隔5秒调用一次timer_callback函数,这个函数的作用是发布String类型的字符串。

4、订阅节点

发布节点创建好了,接下来写一个订阅这个发布信息的节点

cd ~/my_pub_sub_ws/src/my_pub_sub/my_pub_sub
gedit sub_test.py

 

#!/usr/bin/env python3import rclpy
from rclpy.node import Node
from std_msgs.msg import Stringclass Subscriber(Node):def __init__(self,name):super().__init__(name)self.subscriber = self.create_subscription(String,"talker_topic",self.sub_callback,10)self.count = 0def sub_callback(self,msg):self.get_logger().info("I heard: %s" %msg.data)if self.count >= 3 : self.destroy_node()def main(args=None):rclpy.init(args=args)node = Subscriber("listener")rclpy.spin(node)rclpy.shutdown()if __name__ == "__main__":main()
cd ~/my_pub_sub_ws/src/my_pub_sub
gedit setup.py

入口处增加,同样使用逗号跟前面的隔开:"listener=my_pub_sub.sub_test:main"
这个setup.py文件的截图如下所示:

cd ~/my_pub_sub_ws
colcon build --packages-select my_pub_sub
source install/setup.bash

运行订阅节点:ros2 run my_pub_sub listener

如果关闭了发布节点,重新运行即可,这样就监听到发布的消息了: 

[INFO] [listener]: I heard: NO.0,hello!
[INFO] [listener]: I heard: NO.1,hello!
[INFO] [listener]: I heard: NO.2,hello!
[INFO] [listener]: I heard: NO.3,hello!
[INFO] [listener]: I heard: NO.4,hello!

发布与订阅,截图如下:

查看节点: ros2 node list

/talker
/listener 

恩,没有问题,正确显示一个发布节点talker和一个订阅节点listener

5、混合环境的错误

在这种混合版本的环境,很容易出现下面这样的错误:

ROS_DISTRO was set to 'dashing' before. Please make sure that the environment does not mix paths from different distributions.
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.

如果使用ROS2版本: 

sudo gedit /opt/ros/melodic/share/ros_environment/catkin_env_hook/1.ros_distro.sh

将其内容注释即可:

if [ -n "$ROS_DISTRO" -a "$ROS_DISTRO" != "melodic" ]; thenecho "ROS_DISTRO was set to '$ROS_DISTRO' before. Please make sure that the environment does not mix paths from different distributions."
fi
export ROS_DISTRO=melodic

如果使用ROS1版本:

sudo gedit /opt/ros/dashing/share/ros_environment/environment/1.ros_distro.sh

将其内容注释即可:

if [ -n "$ROS_DISTRO" -a "$ROS_DISTRO" != "dashing" ]; thenecho "ROS_DISTRO was set to '$ROS_DISTRO' before. Please make sure that the environment does not mix paths from different distributions."
fi
export ROS_DISTRO=dashing

测试环境如果经常有ROS1和ROS2的测试的情况,那就混合环境,当然最好的情况还是只有一个版本的环境,避免一些不必要的错误出现。而且是在编译之前做这个操作,不然将会在所在工作空间的install/setup.bash中出现混合环境:

COLCON_CURRENT_PREFIX="/opt/ros/melodic"
_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash"
COLCON_CURRENT_PREFIX="/opt/ros/dashing"
_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash"

甚至出现下面这样的错误: 

AttributeError: type object 'type' has no attribute '_TYPE_SUPPORT' This might be a ROS 1 message type but it should be a ROS 2 message type. Make sure to source your ROS 2 workspace after your ROS 1 workspace.

所以最好的设置就是前面说的修改 ~/.bashrc 自行进行环境的选择。 

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

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

相关文章

【0基础学Java第十一课】-- 认识异常

11. 认识异常 11.1 异常的概念与体系结构11.1.1 异常的概念11.1.2 异常的体系结构11.1.3 异常的分类 11.2 异常的处理11.2.1 防御式编程11.2.2 异常的抛出 throw11.2.3 异常的捕获异常声明throwstry-catch捕获并处理finally问题&#xff1a;既然 finally 和 try-catch-finally …

【学历是敲门砖】如果你想有个好的起点,不妨冲一冲计算机考研,这本书将会助你一臂之力

目录 计算机考研难点 《计算机考研精炼1000题》揭秘问答 1. 为什么是1000题&#xff1f; 2. 有什么优势&#xff1f; 3. 编写团队水平如何&#xff1f; 4. 题目及解析品质如何&#xff1f;可以试读吗&#xff1f; 购买链接 高质量的学习提升圈子 京东热卖下单链接&…

Mac安装配置typescript及在VSCode上运行ts

一、Mac上安装typescript sudo npm install -g typescript 测试一下&#xff1a;出现Version则证明安装成功 tsc -v 二、在VSCode上运行 新建一个xxx.ts文件&#xff0c;测试能否运行 console.log("helloworld") 运行报错&#xff1a;ts-node: command not…

宅家追剧神器推荐,高亮轻薄投影仪极米Z7X带你开启追剧新体验

周末假期怎么玩&#xff1f;相信有不少朋友已经准备好了出游计划&#xff0c;当然也有很多小伙伴想趁周末在家追追剧、看看电影、玩玩游戏放松一下。那么&#xff0c;今天笔者就给大家带来了一款假期娱乐神器——极米Z7X&#xff0c;无论是出游还是宅家追剧&#xff0c;极米Z7X…

外部 prometheus监控k8s集群资源(pod、CPU、service、namespace、deployment等)

prometheus监控k8s集群资源 一&#xff0c;通过CADvisior 监控pod的资源状态1.1 授权外边用户可以访问prometheus接口。1.2 获取token保存1.3 配置prometheus.yml 启动并查看状态1.4 Grafana 导入仪表盘 二&#xff0c;通过kube-state-metrics 监控k8s资源状态2.1 部署 kube-st…

mybatis 语法使用各种踩坑(持续更新中。。。)

1、大小写命名&#xff1a;这个别说了&#xff0c;都是泪。 2、联表查询查询&#xff0c;多条合成一条&#xff0c;不生效的原因 博主各种检查关联关系和字段大小写&#xff0c;本来是4条数据最后合成一条数据&#xff0c;死活给你直接返回了4条数据&#xff0c;而且每个类似p…

为什么说品牌低价不是一件好事

消费者货比三价为的是买到低价质优的产品&#xff0c;而网络电商平台的公开&#xff0c;也促进了消费者及品牌进行比价&#xff0c;那品牌低价一定就是好事吗&#xff0c;一定会拉高品牌销量吗。其实是不一定的&#xff0c;低价意味着成本的降低&#xff0c;也可能滋生很多产品…

iview table 默认排序字段不高亮解决办法

iview treeSelect 组件封装 1、表格增加排序时触发的方法2、定义三个变量&#xff0c;sortColumnDefaultStyle存放默认的样式&#xff0c;定义页面默认的列以及顺序3、显示的列加上 sortable, 和样式4、使用下面这块代表默认选中5、点击时清除掉默认的排序6、把排序的字段查询时…

软件开发团队如何确保团队成员与项目进度一致?

在软件开发团队中&#xff0c;确保团队成员的利益与项目进度保持一致&#xff0c;可以采取以下措施&#xff1a; 建立基础流程&#xff1a;建立几个最主要的流程&#xff0c;如任务跟踪、开发效率提升、任务完成等&#xff0c;可以帮助小团队从无序逐步进入有序。 关注员工反馈…

CRS工时分析软件:制造业IE改善的秘密武器

当前全球经济危机下&#xff0c;现场改善及控制浪费是制造型企业关注的焦点&#xff0c;生产现场管理的优劣直接体现了企业在行业中的竞争力&#xff0c;也是体现企业盈利的重要环节。掌握生产现场改善的手法和科学识别现场管理中的浪费&#xff0c;最终为企业降低成本、提高效…

Lua脚本解决redis实现的分布式锁多条命令原子性问题

线程1现在持有锁之后&#xff0c;在执行业务逻辑过程中&#xff0c;他正准备删除锁&#xff0c;而且已经走到了条件判断的过程中&#xff0c;比如他已经拿到了当前这把锁确实是属于他自己的&#xff0c;正准备删除锁&#xff0c;但是此时他的锁到期了&#xff0c;那么此时线程2…

win10 eclipse安装教程 (java)

前言&#xff1a;安装eclipse之前必须安装JDK&#xff0c;JDK是编译环境&#xff0c;eclipse是集成开发平台。 一、JDK的安装 Java Development Kit 简称 JDK (一) 官方下载地址&#xff1a; Java Archive Downloads - Java SE 8u211 and later (oracle.com) 找到&#xff…