Python写ROS话题

2023-05-16

Python写ROS话题

  • 导入ROS模块
  • 发送话题
  • 接收话题
    • 第一种方式:rospy.Subscriber
    • 第二种方式:rospy.wait_for_message
    • 完整程序
  • 多线程处理同时接受多个话题

导入ROS模块

用python编写ROS的程序有很多有点,Python的numpy模块可以方便快速的完成机器人规划、正逆运动学的开发,如果需要完成更复杂的计算功能,可以使用scipy模块完成科学计算,对采集数据的时间系列分析可以采用pandas做数据分析,最重要的是Python的matplotlib模块可以完成绝大部分的数据绘图,可以与pyqt5结合完成数据的可视化显示。当然Python还可以方便的调用机器人学习、深度学习等模块完成人工智能的开发,用最短的时间完成机器人的智能化。
Python中使用ROS首先要导入rospy模块

import rospy

完成机械臂的控制还需要导入其他数据模块,ROS在C++中的数据类型在Python也可以找到,其中最常用的数据模块是std_msgs、sensor_msgs、geometry_msgs模块。

from std_msgs.msg import Float64MultiArray
from sensor_msgs.msg import JointState
from geometry_msgs.msg import WrenchStamped

发送话题

ros话题是最常用的通讯方式,通过话题实现数据传输,下面将介绍话题发布。
首先,需要建立一个一个节点,并发起一个或多个话题

#建立节点
rospy.init_node("joint_position_command", anonymous=True)
#在该节点上发起话题
pub = rospy.Publisher("/all_joints_position_group_controller/command", Float64MultiArray, queue_size=1)

其次,设定发布的频率,每秒发送的次数

rate = rospy.Rate(100) # 100hz

然后,发送数据

pub.publish(send_data)

最后,需要休眠等待

rate.sleep()

完整的程序如下

#!/usr/bin/env python
# -*-coding:utf-8-*-
# 本文档用于发送关节角度
# 程序员:CYT
# 版权:哈尔滨工业大学(深圳)
# 日期:初稿:2019.11.6

import rospy
from std_msgs.msg import Float64MultiArray

import os
import numpy as np

def talker():
    # 建立节点
    rospy.init_node("joint_position_command", anonymous=True)
    #建立话题
    pub = rospy.Publisher("joint_command", Float64MultiArray, queue_size=1)
    #设置发送频率
    rate = rospy.Rate(100)  # 100hz

    #假设数据
    command_pos = np.zeros([1000,7])

    # 重写数据
    kk = len(command_pos[:, 0])
    n = len(command_pos[0, :])
    command_data = np.zeros([kk, n])
    for i in range(kk):
        for j in range(n):
            command_data[i, j] = command_pos[i, j]

    #主循环中发送数据
    k = 0
    while not rospy.is_shutdown():
        if k == kk:
            break
        tip_str = "第 %s 次命令:" % k
        rospy.loginfo(tip_str)

        send_data = Float64MultiArray()
        send_data.data = command_data[k, :]
        print send_data.data
        #发送数据
        pub.publish(send_data)
        #休眠
        rate.sleep()
        k = k + 1

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

接收话题

Python接受话题有两种方式,但是与C++相比,其只有rospy.spin(),没有ros::spinOnce,所以想要在循环中处理需要特别注意。

第一种方式:rospy.Subscriber

第一种方式与c++类似,调用回调函数来处理,但是因为只有rospy.spin()来调用回调函数,所以程序会阻塞在回调函数中,接受到一个数据,调用一次。

#建立节点
rospy.init_node('listener', anonymous=True)
#订阅话题
rospy.Subscriber('/joint_states', JointState, callback)
#调用回调函数,并阻塞,直到程序结束
rospy.spin()

第二种方式:rospy.wait_for_message

该方法无需节点,也无需回调函数,其与一个函数类似,等待话题发布消息,当接收到一个消息时,返回数据,继续执行后面的程序。相对于第一种,我们把它称为半阻塞,接收的话题如果没有发布消息,它会一直等待,但是接收到一个消息后,等待结束,会继续执行后面的程序。

msg2 = rospy.wait_for_message('/joint_states', JointState, timeout=None)

完整程序

通过两个函数演示两种不同的就收方法,当上文中话题启动后,下文中的程序就可接受到数据。

#!/usr/bin/env python
# -*-coding:utf-8-*-
# 本文档用于接收信息
# 程序员:CYT
# 版权:哈尔滨工业大学(深圳)
# 日期:初稿:2019.12.12

import numpy as np

import rospy
from std_msgs.msg import Float64MultiArray

def callback(data):
    print "msg:", data

def listener1():
    #建立节点
    rospy.init_node('listener', anonymous=True)
    #订阅话题
    rospy.Subscriber('joint_command', Float64MultiArray, callback)
    #调用回调函数,并阻塞
    rospy.spin()

def listener2():
    #用循环来订阅所有数据
    while not rospy.is_shutdown():
        #订阅话题
        msg = rospy.wait_for_message('joint_command', Float64MultiArray, timeout=None)
        print "msg: %s" % msg

if __name__ == '__main__':
    #运行程序1
    #listener1()
    #运行程序2
    listener2()

多线程处理同时接受多个话题

在实际运用中,一个节点需要发送多个话题和接受多个话题,如机器人阻抗控制,需要同时接受关节角状态和末端六维力的数据,由于Python中没有ros::spinOnce,用rospy.spin()会阻塞程序,主程序无法执行其他模块,所以需要引入线程来处理。
单独建立一个函数,存放rospy.spin(),用于线程调用

def thread_spin(self):
    rospy.spin()

调用线程处理回调函数,使其在子线程中阻塞,主程序正常运行

# 运行线程1,收话题线程
t1 = threading.Thread(target=self.thread_spin)
t1.start()

如果采用第二中方式,程序可以类似于C++的ros::spinOnce处理话题接受,当并不相同,且存在一个缺点:rospy.wait_for_message会一直等待话题,直到接收到一个数据,其等待时间与所接受的话题有关,所以其主程序循环周期不稳定。

def listener2(self):
        # 用循环来订阅所有数据
        while not rospy.is_shutdown():
            # 订阅话题
            msg1 = rospy.wait_for_message('joint_command1', Float64MultiArray, timeout=None)
            print "msg1: %s" % msg1
            msg2 = rospy.wait_for_message('joint_command2', Float64MultiArray, timeout=None)
            print "msg2: %s" % msg2
            #处理其他函数
            print "处理其他函数!"

多个回调函数的数据可以通过全局变量供主函数调用,也可以采用类来写该函数,通过类变量共享的特点实现数据调用。

#!/usr/bin/env python
# -*-coding:utf-8-*-
# 本文档用于接收信息
# 程序员:CYT
# 版权:哈尔滨工业大学(深圳)
# 日期:初稿:2019.12.12

import numpy as np
#ros模块
import rospy
from std_msgs.msg import Float64MultiArray
#线程
import threading

class SubTopic(object):
    #定义全局变量
    qq = np.zeros(7)
    F = np.zeros(6)
    def __init__(self,flag = True):
        self.init()
        self.flag = flag
    def init(self):
        #调用第一个函数
        if(self.flag==True):
            print "第一种方式,多线程处理"
            self.listener1()
        else:
            print "第二中方式处理"
            self.listener2()

    def thread_spin(self):
        rospy.spin()

    def callback1(self, data):
        print "msg1:", data

    def callback2(self, data):
        print "msg2:", data

    def listener1(self):
        # 建立节点
        rospy.init_node('listener', anonymous=True)
        # 订阅话题
        rospy.Subscriber('joint_command1', Float64MultiArray, self.callback1)
        rospy.Subscriber('joint_command2', Float64MultiArray, self.callback2)
        # 运行线程1,收话题线程
        t1 = threading.Thread(target=self.thread_spin)  # 末端位置订阅线程
        t1.start()
        #处理其他函数
        while not rospy.is_shutdown():
            #处理其他函数
            print "处理其他函数!"

    def listener2(self):
        # 用循环来订阅所有数据
        while not rospy.is_shutdown():
            # 订阅话题
            msg1 = rospy.wait_for_message('joint_command1', Float64MultiArray, timeout=None)
            print "msg1: %s" % msg1
            msg2 = rospy.wait_for_message('joint_command2', Float64MultiArray, timeout=None)
            print "msg2: %s" % msg2
            #处理其他函数
            print "处理其他函数!"

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python写ROS话题 的相关文章

随机推荐

  • SSH无法启动错误解决:Failed to start OpenSSH server daemon.

    一 错误信息如下 xff1a sshd service OpenSSH server daemon Loaded loaded usr lib systemd system sshd service enabled vendor prese
  • linux小知识:修改/etc/profile全局变量文件出错,导致服务命令全部失效解决方案

    现象 xff1a 由于修改profile文件时改错了 xff0c 导致所有的命令都失效了 赶紧解决赶紧解决 1 在当前窗口执行以下命令 export PATH 61 usr local sbin usr local bin sbin bin
  • docker容器如何迁移

    docker容器如何迁移 xff1f 前言 xff1a 迁移容器涉及到备份和恢复 xff0c 可以将任何一个docker容器从一台机器迁移到另一台机器 在迁移过程中 xff0c 首先将把容器备份为Docker镜像快照 然后 xff0c 该D
  • 缓存IO和直接IO的区别

    1 缓存IO 缓存I O又被称作标准I O xff0c 大多数文件系统的默认I O操作都是缓存I O 在Linux的缓存I O机制中 xff0c 数据先从磁盘复制到内核空间的缓冲区 xff0c 然后从内核空间缓冲区复制到应用程序的地址空间
  • 修改svn的配置文件并对密码加密

    svn管理 公司项目进出新人 xff0c 需要对代码管理工具进行增删 由于对linux不是很了解 对svn的配置有没有进行过交接 所有的操作都是自己在centos服务器上进行尝试 对于普通的svn的账号密码管理有了基本了解 但是在服务器上看
  • deepin安装微信qq

    在网页上下载最新微信或者qq env WINEPREFIX 61 deepinwine Deepin WeChat deepin wine WeChatSetup exe 该命令运行在WeChatSetup exe所在文件夹 xff0c 最
  • 在Java中,执行SQL查询到数据后,存储在哪里了?

    前言 xff1a 我们项目运行过程中 xff0c 肯定会有查询数据库这步操作 xff0c 无论你是MySQL还是Oracle 那么这种情况就必须搞清楚 xff0c 从数据库里查询得到的数据默认存储到哪了 xff0c 为什么一次查询过多的数据
  • Java小知识:摆脱BeanUtil.copyProperties!! 最优的替代方案 -Bean Converter插件使用方式来了~

    前言 xff1a 开发中为什么不推荐使用BeanUtil copyProperties xff1f 使用BeanUtil copyProperties会有哪些严重后果 xff1f 这些就不在这里眼神了哈 xff0c 大家可以自行查阅一下即可
  • Vue小知识: $ is not defined错误解决

    错误原因 xff1a 该错误是未安装JQuery依赖包导致 解决方案 xff1a 安装依赖包 1 执行安装jquery依赖包命令 cnpm install jquery save 2 webpack配置 xff08 1 xff09 在项目根
  • JVM小知识:linux 命令查看jvm堆内存信息

    1 查看当前java进程的pid pgrep lf java 2 查看java堆的详细信息 jmap heap PID 3 查看java堆中对象的相关信息 xff0c 包含数量以及占用的空间大小 jmap histo PID 4 查看监控
  • IDEA小知识:查看内存使用情况的步骤

    1 展示idea自带的内存指标 xff0c 如图 1 图 2 点击File gt 选择Setting gt 进入APPearance gt 勾选Show memory indicator 图 xff08 1 xff09 图 xff08 2
  • 【无标题】

    CMake Error at xxaipkg CMakeLists txt 50 add message files Unknown CMake command add message files Configuring incomplet
  • npm安装淘宝镜像报错

    npm install g cnpm registry 61 https registry npm taobao org 执行命令报错 无法安装cnpm 解决方案 xff1a 用管理员方式打开命令行 xff0c 就可以安装成功了
  • Leetcode——贪心算法(c++和java实现)

    本来有一段时间没有刷题了 xff0c 但是突然发现了这本书LeetCode 101 A LeetCode Grinding Guide C 43 43 Version xff0c 感觉真不错 xff0c 思路简单清晰 xff0c 没有过多的
  • 树莓派3B+安装c++版本opencv3.4.1,配置开发环境以及注意事项

    树莓派3B 43 安装c 43 43 版本opencv3 4 1 xff0c 配置开发环境以及注意事项 树莓派3B 43 ubuntu mate系统的安装 树莓派 xff0c Raspberry Pi xff0c 是一个只有信用卡大小的微型
  • 由frankmocap得到的.pkl文件转为.bvh或者.fbx

    需求 由Frankmocap所得到的 pkl文件转为blender里的 bvh或者Maya里的 fbx Frankmocap github项目地址 2D转3D转 bvh可以看VideoTo3dPoseAndBvh xff0c bvh转3D相
  • centos 安装docker

    查看系统内核版本 docker需要内核版本在3 8以上 centos7 版本是3 10 安装支持aufs CentOS7 默认不支持aufs文件系统 需要自己安装支持aufs的内核 进入repo目录 cd etc yum repo d 下载
  • echarts框架下大数据量展示的解决方案

    echarts 43 大数据量 这是个无解的问题 xff01 大数据量 xff0c 什么样的数据才算大呢 xff1f 在echart 4 5 0版本中 xff0c 画折线图 xff0c 数据线一共1001000条 xff0c 每条数据500
  • Open vSwitch介绍

    Open vSwitch介绍 1 vSwitch功能2 OvS架构3 OvS报文处理3 1 传统OvS方式3 2 OvS 43 DPDK处理方式 4 OvS补充说明4 1 基本概念4 2 匹配项与规则4 2 1 匹配项4 2 2 动作 本节
  • Python写ROS话题

    Python写ROS话题 导入ROS模块发送话题接收话题第一种方式 xff1a rospy Subscriber第二种方式 xff1a rospy wait for message完整程序 多线程处理同时接受多个话题 导入ROS模块 用py