天天看點

20.ROS程式設計學習:通信的各種進階使用python一.以話題通信的python初始化節點api進階使用二、話題通信釋出方對象進階三、回頭函數

目錄

一.以話題通信的python初始化節點api進階使用

1.初始化節點代碼提示與python話題通信例程

2.初始化節點使用進階

二、話題通信釋出方對象進階

三、回頭函數

學習參考:B站趙虛左的ROS教程

一.以話題通信的python初始化節點api進階使用

1.初始化節點代碼提示與python話題通信例程

def init_node(name, argv=None, anonymous=False, log_level=None, disable_rostime=False,disable_rosout=False, disable_signals=False, xmlrpc_port=0, tcpros_port=0):
           

利用到之前學習的話題通信python實作

(4條消息) 3.ROS程式設計學習:話題通信python_機械專業的計算機小白的部落格-CSDN部落格

20.ROS程式設計學習:通信的各種進階使用python一.以話題通信的python初始化節點api進階使用二、話題通信釋出方對象進階三、回頭函數

https://blog.csdn.net/wzfafabga/article/details/127107231

2.初始化節點使用進階

作用:ROS初始化

參數:name ---- 設定節點名稱,必須保證節點名稱唯一,argv=None ---- 封裝節點調用時傳遞的參數,anonymous=False ---- 可以為節點生成随機數字尾,可以解決相同節點啟動兩次節點重名導緻前一節點shotdown問題.

使用:

1.argv使用

可以按照ROS中指定的文法格式傳參,ROS可以解析并加以使用.

在啟動節點時,添加了 _A:=1000,作用是在參數伺服器添加鍵名A,同時鍵值為1000

[email protected]:~/catkin_ws$ rosrun sub_pub pub_p.py _A:=1000
           

參考參數伺服器python實作:

(4條消息) 11.ROS程式設計學習:參數管理機制python實作_機械專業的計算機小白的部落格-CSDN部落格

20.ROS程式設計學習:通信的各種進階使用python一.以話題通信的python初始化節點api進階使用二、話題通信釋出方對象進階三、回頭函數

https://blog.csdn.net/wzfafabga/article/details/127432682

列出參數伺服器的所有參數。

rosparam list
           

 可知鍵名為/pub_py/A

[email protected]:~/catkin_ws$ rosparam list
/pub_py/A
/rosdistro
/roslaunch/uris/host_rosmelodic_virtual_machine__41671
/rosversion
/run_id
           

查找指定鍵名的鍵值

rosparam get /pub_py/A 
           

鍵值為1000

[email protected]:~/catkin_ws$ rosparam get /pub_py/A 
1000
           

由此可見在啟動節點時,加入符合特定文法的代碼,ROS能解析,并實作功能,這是因為傳入參數被初始化節點的argv形參(是一個清單)接收,實作了功能。如下是初始化函數封裝的一部分代碼,可見argv傳入的就是系統的argv,如果相對argv操作,import sys。

if argv is None:
        argv = sys.argv
           

同樣的argv也在服務通信的用戶端優化中應用了

(4條消息) 8.ROS程式設計學習:自定義服務資料python調用_機械專業的計算機小白的部落格-CSDN部落格

20.ROS程式設計學習:通信的各種進階使用python一.以話題通信的python初始化節點api進階使用二、話題通信釋出方對象進階三、回頭函數

https://blog.csdn.net/wzfafabga/article/details/1273960592.anonymous使用

如果同時啟動兩次

[email protected]:~/catkin_ws$ rosrun sub_pub pub_p.py
           

第一個啟動的節點的終端會提示:

shutdown request: [/pub_py] Reason: new node registered with same name
           

 修改初始化節點:

pub_p.py 

#! /usr/bin/env python
# -*- coding: UTF-8 -*-

import rospy
from std_msgs.msg import String

if __name__ == "__main__":
    rospy.init_node(name = "pub_py", anonymous = True) 
    pub = rospy.Publisher (name="chongfu_py", data_class = String, queue_size=10)
    msg = String()
    rate = rospy.Rate(1)
    count = 0
    rospy.sleep(3)
    while not rospy.is_shutdown():
        count += 1
        if(count <= 10):
            msg.data = "hello" + str(count)
            pub.publish(msg)
            rospy.loginfo("釋出資料:%s", msg.data)
        else:
            rospy.signal_shutdown("退出循環")
        rate.sleep()
           

從 

rospy.init_node(name = "pub_py") 
           

修改為

rospy.init_node(name = "pub_py", anonymous = True) 
           

同時啟動兩次節點。

rosrun sub_pub pub_p.py 
           
rosrun sub_pub pub_p.py 
           

 檢視所有啟動節點。

rosnode list
           

 節點後跟有随機數,使相同節點啟動節點名不同,不會造成第一個啟動的節點被shotdown。

[email protected]:~/catkin_ws$ rosnode list 
/pub_py_20907_1667219173751
/pub_py_20951_1667219175884
/rosout
           

二、話題通信釋出方對象進階

作用與c++對應,主要還是處理latch的布爾值。

官方解釋:@param latch:如果為True,則最後釋出的消息是“latch”,這意味着任何未來的訂閱者将在連接配接後立即收到該消息。

@param latch: If True, the last message published is 'latched', meaning that any future subscribers will be sent that message immediately upon connection.
           

pub_p.py 

#! /usr/bin/env python
# -*- coding: UTF-8 -*-

import rospy
from std_msgs.msg import String

if __name__ == "__main__":
    rospy.init_node(name = "pub_py", anonymous = True) 
    pub = rospy.Publisher(name="chongfu_py", data_class = String, queue_size= 10, latch = True)
    msg = String()
    rate = rospy.Rate(1)
    count = 0
    rospy.sleep(3)
    while not rospy.is_shutdown():
        count += 1
        if(count <= 10):
            msg.data = "hello" + str(count)
            pub.publish(msg)
            rospy.loginfo("釋出資料:%s", msg.data)
        # else:
        #     rospy.signal_shutdown("退出循環")
        rate.sleep()
           

修改:

釋出者的建立修改前:

pub = rospy.Publisher(name="chongfu_py", data_class = String, queue_size= 10)
           

釋出者的建立修改後:

pub = rospy.Publisher(name="chongfu_py", data_class = String, queue_size= 10, latch = True)
           

測試:

啟動釋出者

rosrun sub_pub pub_p.py
           

循環到十次時停止釋出消息,如果latch為False,訂閱者這時啟動是不會接收到任何消息的。

[email protected]:~/catkin_ws$ rosrun sub_pub pub_p.py
[INFO] [1667221214.189930]: 釋出資料:hello1
[INFO] [1667221214.191267]: 釋出資料:hello2
[INFO] [1667221215.193347]: 釋出資料:hello3
[INFO] [1667221216.192330]: 釋出資料:hello4
[INFO] [1667221217.192395]: 釋出資料:hello5
[INFO] [1667221218.192578]: 釋出資料:hello6
[INFO] [1667221219.193270]: 釋出資料:hello7
[INFO] [1667221220.192703]: 釋出資料:hello8
[INFO] [1667221221.193090]: 釋出資料:hello9
[INFO] [1667221222.192738]: 釋出資料:hello10
           

由于本程式latch為True,訂閱者接收到了最後釋出的一條消息,其中原理與c++實作相同,隻不過ROS提供了python接口。

[email protected]:~/catkin_ws$ rosrun sub_pub sub_p.py 
[INFO] [1667221300.839786]: 訂閱的資料:hello10
           

三、回頭函數

python中隻有不停的回頭spin,沒有回一次頭的函數spinonce。

rospy.spin()
           

與c++相同,運作到回頭函數就會在回調函數中不停的循環,回頭函數後面的代碼不會運作。