ros-python学习样例笔记

这篇具有很好参考价值的文章主要介绍了ros-python学习样例笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.通信基本原理介绍

待写

2.三种通信方式的程序样例(python版)

2.1 topic 通信方式(非自定义和自定义)

2.1.1 创建工作空间和topic功能包

在ubuntu中打开命令行,输入下面的命令创建并初始化工作空间,一定要回到XXX_ws的目录下初始化工作空间

 #创建工作空间文件夹my_ros(一般命名为XXX_ws)以及源程序目录src
$ mkdir -p ~/my_ros/src
 #必须回到工作目录下,才开始初始化工作空间
$ cd ~/my_ros
 #初始化工作空间,同时该命令还可以用于编译源代码
$ catkin_make
 #进入src目录,创建自定义功能包
$ cd src
 #创建功能包,指定了功能包的包名为"topic_test"
 #引入的依赖有rospy(ros中python编程的必备接口),
 #std_msgs(标准消息接口)和
 #message_generation(用于自定义消息的接口)
$ catkin_create_pkg topic_test rospy std_msgs message_generation
 #创建python源代码的目录,用于保存.py文件
$ mkdir script

主要运行的python程序分为两部分: 消息发布者(Publisher)消息接受者(Subscriber)
由于此例中只使用到ros中提供的std_msgs中的String类型消息,所以对于初始化时自动生成的 CMakeList.txt 和 package.xml 无需修改

2.1.2 topic消息发布者(Publisher)部分

在终端中输入如下代码,开始编辑 消息发布者(Publisher) 的代码文件

 #进入script目录
$ cd ~/my_ros/topic_test/script
 #打开编辑器编辑代码,若文件不存在将会创建该文件
$ gedit Publisher.py

注:也可以使用 RoboWare/eclipse 等的IDE做开发

输入如下所示的python代码 ( 运行前需删掉中文注释,否则将会报错! )

#! /usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String

def talker():
    # 初始化节点,向ros操作系统的master节点注册自己的信息,
    # 定义节点唯一的名称为publisher,同时保证名字唯一的参数(anonymous)为true
    # 即,当名字重复时将会在名字后面添加一串随机数字作为注册名字,从而保证名字唯一
    rospy.init_node('pyTalker',anonymous=True)
    # 定义本节点将向
    # ropy的 Publisher 类的构造方法介绍如下:
    #__init__(self, name, data_class, subscriber_listener=None, tcp_nodelay=False, latch=False, headers=None, queue_size=None
    # 其中 name (为str类型)代表本话题(topic)的名称
    # data_class(message class) 为序列化的消息(message)类
    # subscriber_listener(SubscribeListener) 指定订阅者,默认值为None,可以为空
    # tcp_nodelay(bool) 为设置发布者(publisher)的socket是否采用Nagle算法(默认为False,即采用Nagle算法),通过该设置能够影响发布的效率\能耗
    # latch(bool) 如果为真,最后一条消息将设置为"占用信道",即没一个订阅者都会立即收到该消息
    # headers(dict) 默认为None,如果不为空,将使用传入的"字典"的键值作为未来连接的参数
    # queue_size(int) 默认为None(阻塞式同步收发),指定消息队列的长度,必须指定,如果为0(无限缓冲区)是危险的,如果缓冲队长太大会导致发送不同步
    # 该方法抛出 ROSException 异常
    pub = rospy.Publisher('test_chat',String,queue_size=1)
    # 设定循环的周期为0.1s
    rate = rospy.Rate(10)
    count = 0
    while not rospy.is_shutdown():
        words = 'Happy new year! %d' % count
        # 发布消息的 Publisher类 的核心方法,参数如下:
        # publish(self, *args, **kwds)
        # args 要发送的消息,如果有 keyword 时可以为空
        # kwds 消息的关键词,如果 kwds 被采用,则 args 一定是未指定的
        pub.publish(words)
        rospy.loginfo('pyTalker: send msg = %s ',words)
        count = count+1
        pub.publish(words)
        rate.sleep()

# 进行标准的Python_main检查,这里的try-except捕获rospy.ROSInterruptException异常(处理异常中断)
if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

2.1.3 topic消息接收者(Subscriber)部分

同理创建 消息接受者(Subscriber) 的代码文件

 #打开编辑器编辑代码,若文件不存在将会创建该文件
$ gedit Subscriber.py

输入如下代码 ( 运行代码前需将中文注释都删掉,否则会出错! )

#! /usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String

# 用于处理从指定topic获取的消息,尤其需要注意"message.data"这样使用,才能正确获取全部消息
def callback(message):
    rospy.loginfo('Listener: msg = %s',message.data)

# 主调用的方法,负责向主服务器注册本节点,以及注册,链接,使用指定话题
def listener():
    # 向服务器注册本节点名为'pyListener',允许使用避免重名的机制(若重复,则在名字后加随机数)
    rospy.init_node('pyListener',anonymous=True)
    # 向服务器申请获得含有指定的'test_chat'的topic发布者的地址,并连接
    # 该方法的参数中,'test_chat'为本节点需要链接的话题(topic)名,'String'为获取的消息的类型
    # 'callback'为处理消息的方法名
    rospy.Subscriber('test_chat',String,callback)
    # 以下的spin()方法为ROS消息回调处理函数,调用后将不会返回(下面的程序无法执行),即阻塞本线程(使得本节点不能再执行其他操作,只能处理消息)
    # 与这个函数相近功能的函数有spinOnce(),但spinOnce()会返回(下面的程序仍能执行)且只执行一次,不会阻塞本线程
    rospy.spin()

# 进行标准的Python_main检查
if __name__ == '__main__':
    listener()

2.1.3 编译并运行代码

打开一个终端,输入如下命令

 #进入工作空间目录
$ cd ~/my_ros
 #编译程序(实际上python为脚本语言无需编译)
$ catkin_make

这里所说的 " 编译 " 并不是严格意义上的 " 编译 ",可以理解为是为ros运行做好准备(例如catkin的操作).执行过该命令后,修改.py文件后再运行将会出现修改后的结果 (无需再catkin_make一次)

开三个终端,分别输入如下3条命令,开始执行程序

 #开启服务器,将负责处理注册/连接请求等
$ roscore
 #开始运行topic_test功能包下的 消息发送者(Publisher) 节点
$ rosrun topic_test Publisher.py
 #运行topic_test包下的 消息接收者(Subscriber)节点
$ rosrun topic_test Subscriber.py

如果是完全按照上面的步骤操作,如果过遇到程序无法执行/报错,显示:

[rosrun] Coundn't find excutable named Publisher.py below ....

可能原因是python文件没有执行权限,输入如下命令赋予权限就可以运行了

 #必须在.py文件的目录下
$ cd ~/my_ros/script
 #赋予运行权限
$ chmod +x Publisher.py
$ chmod +x Subscriber.py

程序运行结果为

在新的终端输入如下命令,打开rqt工具,可以看到各个节点之间的关系

$ rqt_graph

2.1.4 自定义消息

自定义消息的使用与使用ros提供的消息一样,不过有几个部分需要注意:

  • 需自定义.msg文件
  • 在package.xml中添加build_depend和exec_depend
  • 在CMakeList.txt中,添加有关.msg文件的依赖包和说明

注: 如果是使用 Roboware,使用"右键->add Msg Folder"或"右键->add Msg File"将会自动修改package.xml和CMakeList.txt文件

a.自定义.msg文件
 #在包中创建msg文件夹,专门用来存放.msg文件,并开始编辑Hello.msg文件
$ mkdir ~/my_ros/topic_test/msg
$ gedit ~/my_ros/topic_test/msg/Hello.msg

在编辑器中输入(类型+属性名)

String message
int32 index
b.修改 package.xml

为了能够使ros生成我们需要的python/c++的消息代码,我们需要在功能包中添加message_generation依赖,在package.xml文件中添加如下两行代码:

<build_depend>message_generation</bulid_depend>
<exec_depend>message_generation</exec_depend>
c.修改 CMakeList.txt

(1)在find_package()中添加message_generation,作用是让catkin在编译时链接message_generation功能包,修改后为:

find_package(catkin REQUIRED COMPONENTS
  message_generation
  rospy
  std_msgs
)

(2)在add_message_files()中添加Hello.msg. 作用是向catkin指明需要用到的.msg文件包含Hello.msg

add_message_files(FILES
  Hello.msg
)

(3)去掉generate_messages()的注释

(4)在catkin_package()中添加message_runtime

catkin_package(
  CATKIN_DEPENDS
  message_runtime
)
d.修改消息发送者文件 (Publisher.py)
#! /usr/bin/env python
# license removed for brevity
import rospy
from topic_test.msg import Hello

def talker():
    rospy.init_node('pyTalker',anonymous=True)
    pub = rospy.Publisher('test_chat',Hello,queue_size=1)
    rate = rospy.Rate(10)
    count = 0
    while not rospy.is_shutdown():

        greeting = Hello()
        greeting.index = count
        greeting.message = 'Happy new year!'
        pub.publish(greeting)
        rospy.loginfo('pyTalker: send msg = %s',greeting.message)
        rospy.loginfo('pyTalker: send index = %d',greeting.index)
        count = count+1
        rate.sleep()
    
if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass
e.修改消息接收者文件 (Subscriber.py)
#! /usr/bin/env python
# license removed for brevity
import rospy
from topic_test.msg import Hello

def callback(message):
    rospy.loginfo('pyListener: msg = %s' % message.message)
    rospy.loginfo('pyListener: index = %d' % message.index)

def listener():
    rospy.init_node('pyListener',anonymous=True)
    rospy.Subscriber('test_chat',Hello,callback)
    rospy.spin()

if __name__ == '__main__':
    listener()
f .运行程序

按照上面的操作,先到工作空间目录下, catkin_make 一下,然后再输入命令运行

运行结果为:

2.2 service 通信方式(自定义)

这里的小demo实现的功能是,由 客户端( client )服务器端( server ) 发送一条消息,消息里包含两个参数 a 和 b , 服务器端( server ) 收到这两个参数后,将他们相加后返回.

由于已经有了之前的基础,这里就不再展示完整操作了,只展示使用的核心部分,比较基础的读者可以自行查看 2.1 中的例子 .

完整的基本步骤如下:

  • 创建 service_test 功能包(与上例 2.1 一样)
  • 创建自定义的.srv文件
  • 修改 CMakeList.txt 和 package.xml
  • 新建script文件夹,并编写 server.py 和 client.py
  • 编译并运行

2.2.1 自定义.srv文件

在srv文件夹中,前两行为要传送的参数,"---"后的一行为返回的参数

int64 a
int64 b
---
int64 result

2.2.2 编写服务器端(server)部分代码

如下为服务器端(server.py)部分代码

#!/usr/bin/env python
import rospy
from service_test.srv import Sum

def handle(req):
    rospy.loginfo("Successful recieved number %s and %s" % (req.a,req.b))
    rospy.loginfo("Sending result: %s" % (req.a+req.b))
    # 有些资料和官方文档个上写,这里应该return的是"SumResponse(req.a+req.b)",但实际运行时不知道为什么会出错,改为直接返回结果后程序正常运行.
    return req.a+req.b

def server():
    rospy.init_node("sum_server")
    # 向master节点注册为service,
    # 这个service的名字为"pyServer_Client"
    # 传送消息类为Sum
    # 处理函数的函数名为handle
    rospy.Service("pyServer_Client",Sum,handle)
    rospy.loginfo("Ready to recieve and handle request:")
    # 消息回调处理函数,将阻塞本线程
    rospy.spin()

if __name__ == "__main__":
    server()

2.2.3 编写客户端(client)部分代码

如下为客户端(client.py)部分代码

#!/usr/bin/env python
import sys
import rospy
from service_test.srv import Sum

def client(x,y):
    rospy.init_node("pyClient")
    # 等待名为"pyServer_Client"的service空闲,当其空闲/可用时程序继续执行
    rospy.wait_for_service("pyServer_Client")
    try:
        # 向master节点注册为客户端,
        # 申请链接的service名为"pyServer_Client",
        # 消息类为Sum
        pyServer_Client = rospy.ServiceProxy("pyServer_Client",Sum)
        # 向服务器发送请求,该请求包含2个参数
        resp = pyServer_Client.call(x,y)
        # 返回得到Sum.srv里result字段的加法运算结果
        return resp.result
    except rospy.ServiceException, e:
        rospy.logwarn("Service call failed ! %s! " % e)

if __name__ == "__main__":
    if len(sys.argv) == 3:
        # 获取输入的两个参数
        x = int(sys.argv[1])
        y = int(sys.argv[2])
    else:
        rospy.logwarn("The parameters inputed count is not right! ")
        sys.exit(1)
    rospy.loginfo("pyClient : Requesting %s + %s" % (x,y))
    rospy.loginfo("pyClient : The Result is %s" % client(x,y))

2.2.4 修改CMakeList.txt文件

修改的地方与2.1.4 c 中修改CMakeList.txt文件大致相同,只是将2.1.4 c(2) 中需要修改"add_message_file"的部分,改为修改"add_service_file"

点这里跳转到2.1.4 c

由于此次使用的是.srv文件,而不是.msg文件,所以catkin应该处理的是我们自定义的.srv文件.

我们需要将"add_message_file"部分注释掉,修改"add_service_file"部分为:

add_service_files(FILES
  Sum.srv
)

2.2.5 修改package.xml文件

这部分与2.1.4 (topic自定义msg的例子)中修改package.xml的一样

点这里跳转 2.1.4 b

2.2.6 运行service_test程序

运行需要的命令与前面提到的相同

$ cd ~/my_ros/src/service_test/script
$ chmod +x server.py
$ chmod +x client.py
$ roscore
$ rosrun service_test server.py
 #这里传入了连个参数1和3
$ rosrun service_test client.py 1 3

程序运行情况为:

当然,运行server.py节点后,可以通过rqt的图形界面工具发送处理请求,这就不需要客户端(client.py)了.在新终端中输入

$ rqt

点击菜单的"插件[Plugins]->[Service]->[Service Call]"就可以得到下面的界面

修改如上图箭头指向的地方为自己想传入的参数,点击"Call"可以得到服务器端返回的结果

2.3 action通信方式(不完整)

这里实现的例子是输入3个数,计算3个数的乘积作为最终结果,中间反馈结果为第1个数和第2个数的成绩(中间结果)
完整的基本步骤如下:

  • 创建 action_test 功能包
  • 创建自定义的.action文件
  • 修改 CMakeList.txt 和 package.xml
  • 新建script文件夹,并编写 action_server.py 和 action_client.py
  • 编译并运行

action_server部分可参考:
http://wiki.ros.org/actionlib_tutorials/Tutorials/Writing a Simple Action Server using the Execute Callback (Python)
action_client部分可参考:
http://wiki.ros.org/actionlib_tutorials/Tutorials/Writing a Simple Action Client (Python)

2.3.1 创建 action_test功能包

$ catkin_create_pkg action_test rospy actionlib actionlib_msgs std_msgs message_generation

2.3.2 创建自定义 .action文件

在 action_test 目录下创建 action 文件夹后,新建 multiply.action 文件,输入如下内容:

#a,b为定义的两个输入参数(goal definition)
int32 a
int32 b
---
#final_result为定义的最终结果(result definition)
int32 final_result
---
#in_result为定义的中间反馈结果(feedback)
int32 in_result

实际上动作(.action)可以包含5中基本消息:目标(goal),结果(result),反馈(feedback),取消(cancel),状态(status).
本例中未涉及的取消(cancel)消息使用actionlib_msgs/GoalID,作用是在动作运行时取消客户端和单独节点上的动作的执行. 状态(status)消息可以根据状态转换(如PENDING,ACTIVE,PREEMPTED和SUCCEEDED)检查当前动作的状态

2.3.3 修改 CMakeList.txt 和 package.xml 文件

package.xml中的内容实际上在指定依赖,创建功能包的时候,已经修改好了,所以不需要修改

CMakeList.txt的内容,如果是使用Roboware创建action Folder,action File,那么这一部分也不需要修改,因为已经修改好了.要修改的地方主要是如下所示的地方:

add_action_files(FILES
  multiply.action
)

2.3.4 编写action_server服务器端部分程序

后面再补充,可参考前面的链接文章来源地址https://www.toymoban.com/news/detail-410775.html

2.3.5 编写action_client客户端部分程序

后面再补充,可参考前面的链接

2.3.6 编译并运行程序

后面再补充,可参考前面的链接

到了这里,关于ros-python学习样例笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微服务架构基本原理学习笔记(三)

    上一篇:微服务架构基本原理学习笔记(二) 微服务本身并没有规定通信规则,换句话说,一个微服务并没有规定可以被哪些应用程序访问,或者被哪些其它的微服务调用。应用程序与微服务间的直接通信,或者微服务与微服务间的直接调用,往往会因为其中错综复杂的关系

    2024年02月11日
    浏览(50)
  • 网络爬虫学习笔记 1 HTTP基本原理

          ~~~~~           HTTP(Hyper Text Transfer Protocol,超文本传输协议)是一种使用最为广泛的网络请求方式,常见于在浏览器输入一个地址。 URL(Universal Resource Locator,统一资源定位器) URI(Uniform Resource Identifier,统一资源标识符) URL 是 URI 的子集,URI还包括一个子类 UR

    2024年02月08日
    浏览(40)
  • 《网络爬虫开发实战》学习笔记:1.1 HTTP基本原理

    1.1.1 URI和URL ​ URI ,全称Uniform Resource Identifier,即 统一资源标志符 ; URL ,全称Uniform Resource Locator,即 统一资源定位符 。 ​ 举例来说,https://github.com/favicon.ico既是一个URI,也是一个URL。即有favicon.ico这样一个图标资源,用这样一个URI/URL指定了访问它的唯一方式,其中包括

    2024年02月03日
    浏览(48)
  • Spring Cloud学习笔记:Eureka简介,Eureka简单样例

    这是本人学习的总结,主要学习资料如下 - 马士兵教育 Eureka 是 SpringCloud Nexflix 的核心子模块,其中包含 Server 和 Client 。 Server 提供服务注册,存储所有可用服务节点。 Client 用于简化和 Server 的通讯复杂度。 下面是 Eureka 的简单架构图 每一个服务节点需要在 Eureka Server 中注册

    2024年04月16日
    浏览(55)
  • Spring Cloud学习笔记(Ribbon):Ribbon的应用样例

    这是本人学习的总结,主要学习资料如下 - 马士兵教育 我们都知道 Ribbon 是用于负载均衡的。提供同一种服务的 Client 可能有多个,比如有多个 User Client 提供查询用户信息的服务,使用 Ribbon 就能简单地达到负载均衡的效果。 想要使用 Ribbon ,无论是服务提供者还是调用服务

    2024年04月25日
    浏览(37)
  • ROS笔记(2)——ROS的基本命令

    目录 一、运行小海龟 二、常用的ROS命令 三、rosbag数据记录工具 在ROS中运行小海龟需要执行以下步骤: 打开终端并启动ROS核心:在终端中输入 \\\" roscore \\\" 并按回车键。 打开另一个终端并启动小海龟节点:在终端中输入 \\\" rosrun turtlesim turtlesim_node \\\" 并按回车键。 打开第三个终端

    2024年02月05日
    浏览(37)
  • ROS学习2:ROS通信机制

    【Autolabor初级教程】ROS机器人入门 机器人操作系统 ROS 快速入门教程 1. 引言 机器人上可能集成各种传感器(雷达、摄像头、GPS等)以及运动控制实现, 为了解耦合 ,在 ROS 中 每一个功能点都是一个单独的进程 , 每一个进程都是独立运行的 。更确切的讲, ROS 是进程(也称为

    2024年02月08日
    浏览(45)
  • ROS学习——通信机制(服务通信)

     2.2.3 服务通信自定义srv调用A(C++) · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程    068服务通信(C++)3_客户端优化_Chapter2-ROS通信机制_哔哩哔哩_bilibili 服务通信也是ROS中一种极其常用的通信模式,服务通信是基于 请求响应 模式的,是一种应答机制。也即: 一个节点

    2024年02月08日
    浏览(77)
  • 基于旭日派的Ros系统小车的再开发——使用python脚本调用MIPI相机(学习笔记)

        这里我们导入了 cv2 、 time 、 ipywidgets 和 Mipi_Camera 这几个库。其中, cv2 是用于图像处理和计算机视觉的库; time 是用于计时和休眠的库; ipywidgets 是用于创建交互式窗口小部件的库; Mipi_Camera 则是用于控制和采集MIPI接口相机图像的库。当然除此之外,我们在代码中还添

    2024年01月21日
    浏览(46)
  • 《区块链原理与技术》学习笔记(四) ——以太坊的基本架构、账户模型和智能合约

    《区块链原理与技术》学习笔记 第四部分 三、以太坊 1. 以太坊简介 1.1 以太坊发展的阶段 1.2 以太坊与比特币对比 2. 以太坊的基本架构及原理 2.1 基本概念 2.2 状态转移 2.3 基本架构 3. 账户模型与转账 3.1 账户模型 4. 智能合约 4.1 合约账户与数据存储 4.2 驱动智能合约 以太坊

    2024年02月13日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包