ROS实操入门系列(二)操控小乌龟时,监控行走的路线
获取小乌龟的位姿
使用QTimer接管渲染
完整代码
https://www.lanqiao.cn/courses/2947,提供准备好的云主机ros环境,进行实操,课程包括了 Topic 通讯, Service 通讯,ROS 自定义消息,URDF可视化,TF坐标转换等技术要点。每个技术点都会结合例子先把原理讲解清楚,为了达到学以致用的目的,我们会再进行知识拓展,针对每个技术点实现对应的生动有趣的需求,保证学完后会有很大的收获。
上一章讲解了,小乌龟操控原理及代码控制小乌龟走圆形路线,这一章通过订阅/turtlesim发出的Topic,获得小乌龟的一些位置信息

获取小乌龟的位姿
运行小乌龟节点后,获取该节点的信息,/turtle1/pose就是小乌龟发布的坐标和角度

rosnode info /turtlesim

通过命令,获取该topic传输数据类型

rostopic type /turtle1/pose

创建subscriber订阅上面的/turtle1/pose

运行效果

使用QTimer接管渲染

与C++不同,调试结果为可以正常接收到订阅的消息。但是关于窗体关闭事件方面只能通过关闭QT界面来关闭进程,不能通过ctrl+c 命令行来关闭。
Python可以正常接收到订阅消息的原因,在于Python采用的SIP方式进行操作QT的界面UI的中间是一套异步策略。
但是为了更好的优化体验,我们也是可以和C++实现的代码逻辑相通的。
接管渲染:

创建自己的渲染定时器
    updatetimer = QTimer(self)
    # 设置定时器的频率
    updatetimer.setInterval(20)
    updatetimer.start()
    # 监听timer事件
    updatetimer.timeout.connect(self.on_update)



渲染逻辑:
	def on_update(self):
    	self.update()
    	if rospy.is_shutdown():
        self.close()

完整代码

#!/usr/bin/env python
# coding: utf-8

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import rospy
from geometry_msgs.msg import Twist
from math import radians, degrees
# turtlesim/Pose
from turtlesim.msg import Pose
class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        # 创建自己的渲染定时器
        updatetimer = QTimer(self)
        # 设置定时器的频率
        updatetimer.setInterval(20)
        updatetimer.start()
        # 监听timer事件
        updatetimer.timeout.connect(self.on_update)

        # 设置title
        self.setWindowTitle("小乌龟控制")
        self.resize(400, 0)

        # 设置布局
        layout = QFormLayout()
        self.setLayout(layout)

        # 添加控件
        self.editLinear = QLineEdit("0")
        layout.addRow("线速度", self.editLinear)

        self.editAngular = QLineEdit("0")
        layout.addRow("角速度", self.editAngular)

        self.btnSend = QPushButton("发送")
        layout.addRow(self.btnSend)

        self.labelX = QLabel()
        layout.addRow("当前X坐标", self.labelX)

        self.labelY = QLabel()
        layout.addRow("当前Y坐标", self.labelY)

        self.labelLinear = QLabel()
        layout.addRow("当前线速度", self.labelLinear)

        self.labelAngular = QLabel()
        layout.addRow("当前角速度", self.labelAngular)

        self.labelDegrees = QLabel()
        layout.addRow("当前角度", self.labelDegrees)

        # 添加事件
        self.btnSend.clicked.connect(self.clickSend)

        # 创建publisher
        topicName = "/turtle1/cmd_vel"
        self.publisher = rospy.Publisher(topicName, Twist, queue_size=1000)

        # 接受小乌龟信息
        pose_name = '/turtle1/pose'
        rospy.Subscriber(pose_name,Pose,self.pose_call)

    def pose_call(self,msg):
        if not isinstance(msg,Pose): return
        print msg
        self.labelX.setText(str(msg.x))
        self.labelY.setText(str(msg.y))
        self.labelLinear.setText(str(msg.linear_velocity))
        self.labelAngular.setText(str(msg.angular_velocity))
        # 弧度转角度
        self.labelDegrees.setText(str(degrees(msg.theta)))
        # self.labelDegrees.setText(str(msg.theta))



    def clickSend(self):
        linearX = float(self.editLinear.text())
        # 角度转弧度
        angularZ = radians(float(self.editAngular.text()))

        # 构建消息
        twist = Twist()
        twist.linear.x = linearX
        twist.angular.z = angularZ
        # 发布
        self.publisher.publish(twist)

    def on_update(self):
        self.update()
        if rospy.is_shutdown():
            self.close()

https://www.lanqiao.cn/courses/2947,提供准备好的云主机ros环境,进行实操,课程包括了 Topic 通讯, Service 通讯,ROS 自定义消息,URDF可视化,TF坐标转换等技术要点。每个技术点都会结合例子先把原理讲解清楚,为了达到学以致用的目的,我们会再进行知识拓展,针对每个技术点实现对应的生动有趣的需求,保证学完后会有很大的收获。