解决ROSPY没有spinOnce

之前ROS编程一直用C++,C++订阅消息的时候可以用spin(一直进入回调函数),大循环中用spinOnce时才进入回调函数。最近想显示一个图像界面,python中有matplot模块可以直接figure图像。找到一个最简单的话题订阅程序:

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)

def listener():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # node are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    listener()

改为两线程程序:

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)

def listener():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # node are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)
    #这里加一个while循环就行
    while(1):
        #此处添加另外一个线程的代码


    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    listener()

rospy.spin()作用是当节点停止时让python程序退出,显然和C++ spin的作用不同。

官方的解释:The final addition, rospy.spin() simply keeps your node from exiting until the node has been shutdown. Unlike roscpp, rospy.spin() does not affect the subscriber callback functions, as those have their own threads.

### 实现树莓派与STM32通过ROS进行串口通信 #### 设置硬件连接 为了确保树莓派和STM32之间的稳定通信,需按照特定方式连接两者。通常情况下,会采用TTL转USB模块(如CH340),该模块能够有效地转换信号以便于不同平台间的交流[^3]。 #### 安装必要软件包 在树莓派上安装`rosserial`库是必不可少的操作之一。此库允许ROS节点与其他微控制器(例如STM32)建立联系并交换数据。可以通过执行以下命令完成安装: ```bash sudo apt-get update && sudo apt-get install ros-noetic-rosserial-python ``` 对于不同的ROS版本,请替换上述命令中的`noetic`为对应的发行版名称。 #### 配置串口权限 由于Linux系统默认可能不会授予普通用户访问某些硬件资源的权限,在尝试启动涉及串口操作的应用程序之前,应该先确认当前使用的串口号以及相应的读写权限。这一步骤可通过如下指令实现: ```bash ls -l /dev/ttyUSB* ``` 如果发现目标设备文件存在但无法正常工作,则可能是缺少必要的权限;此时可以临时赋予完全控制权作为测试手段: ```bash sudo chmod 777 /dev/ttyUSB0 ``` 请注意,实际应用中建议创建专门的用户组并将自己加入其中以获得更安全合理的权限管理机制[^4]。 #### 编写Arduino风格固件代码 针对STM32编写一段简单的C/C++程序用于接收来自ROS的消息并向其发送反馈信息。这里提供了一个基础模板供参考: ```cpp #include <ros.h> #include <std_msgs/String.h> char hello[13]="hello world!"; ros::NodeHandle nh; std_msgs::String str_msg; void setup() { nh.initNode(); nh.advertise(str_pub); } void loop(){ str_msg.data = hello; str_pub.publish(&str_msg); nh.spinOnce(); } ``` 这段代码展示了如何初始化一个名为`nh`的对象代表本地网络句柄,并定义消息类型为字符串形式的数据结构体实例化对象`str_msg`。最后,在主循环内定时发布含有固定文本的信息至指定主题下[^1]。 #### 创建Python脚本处理订阅/发布的逻辑 为了让整个过程更加直观易懂,可以在树莓派侧开发一个小工具负责监听由MCU发出的内容或是向对方推送新指令。下面给出了一种基于Python语言编写的解决方案片段: ```python import rospy from std_msgs.msg import String def callback(data): rospy.loginfo(rospy.get_caller_id()+"I heard %s",data.data) if __name__ == '__main__': try: pub = rospy.Publisher('chatter', String, queue_size=10) rospy.Subscriber("chatter_back", String, callback) rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): hello_str = "hello world %s"%rospy.get_time() rospy.loginfo(hello_str) pub.publish(hello_str) rate.sleep() except rospy.ROSInterruptException as e: pass ``` 以上部分实现了两个主要功能——一方面持续不断地向外广播时间戳标记过的问候语句;另一方面也准备好了响应任何从远端传来的回应内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值