最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

2.2 話題通信

2023-09-18 14:46 作者:猛獅集訓(xùn)營  | 我要投稿

場景

話題通信是ROS中使用頻率最高的一種通信模式,話題通信是基于發(fā)布訂閱模式的,也即:一個節(jié)點發(fā)布消息,另一個節(jié)點訂閱該消息。話題通信的應(yīng)用場景也極其廣泛,比如如下場景:

機器人在執(zhí)行導(dǎo)航功能,使用的傳感器是激光雷達(dá),機器人會采集激光雷達(dá)感知到的信息并計算,然后生成運動控制信息驅(qū)動機器人底盤運動。

在該場景中,就不止一次使用到了話題通信。

  • 以激光雷達(dá)信息的采集處理為例,在ROS中有一個節(jié)點需要時時的發(fā)布當(dāng)前雷達(dá)采集到的數(shù)據(jù),導(dǎo)航模塊中也有節(jié)點會訂閱并解析雷達(dá)數(shù)據(jù)。

  • 再以運動消息的發(fā)布為例,導(dǎo)航模塊會綜合多方面數(shù)據(jù)實時計算出運動控制信息并發(fā)布給底盤驅(qū)動模塊,底盤驅(qū)動有一個節(jié)點訂閱運動信息并將其轉(zhuǎn)換成控制電機的脈沖信號。

以此類推,像雷達(dá)、攝像頭、GPS.... 等等一些傳感器數(shù)據(jù)的采集,也都是使用了話題通信,話題通信適用于不斷更新的數(shù)據(jù)傳輸相關(guān)的應(yīng)用場景。

概念

話題通信是一種以發(fā)布訂閱的方式實現(xiàn)不同節(jié)點之間數(shù)據(jù)傳輸?shù)耐ㄐ拍P?。?shù)據(jù)發(fā)布對象稱為發(fā)布方,數(shù)據(jù)訂閱對象稱之為訂閱方,發(fā)布方和訂閱方通過話題相關(guān)聯(lián),發(fā)布方將消息發(fā)布在話題上,訂閱方則從該話題訂閱消息,消息的流向是單向的。


話題通信的發(fā)布方與訂閱方是一種多對多的關(guān)系,也即,同一話題下可以存在多個發(fā)布方,也可以存在多個訂閱方,這意味著數(shù)據(jù)會出現(xiàn)交叉?zhèn)鬏數(shù)那闆r,當(dāng)然如果沒有訂閱方,數(shù)據(jù)傳輸也會出現(xiàn)丟失的情況。


作用

話題通信一般應(yīng)用于不斷更新的、少邏輯處理的數(shù)據(jù)傳輸場景。

關(guān)于消息接口

關(guān)于消息接口的使用有多種方式:

  1. 在ROS2中通過std_msgs包封裝了一些原生的數(shù)據(jù)類型,比如:String、Int8、Int16、Int32、Int64、Float32、Float64、Char、Bool、Empty.... 這些原生數(shù)據(jù)類型也可以作為話題通信的載體,不過這些數(shù)據(jù)一般只包含一個 data 字段,而std_msgs包中其他的接口文件也比較簡單,結(jié)構(gòu)的單一意味著功能上的局限性,當(dāng)傳輸一些結(jié)構(gòu)復(fù)雜的數(shù)據(jù)時,就顯得力不從心了;

  2. 在ROS2中還預(yù)定義了許多標(biāo)準(zhǔn)話題消息接口,這在實際工作中有著廣泛的應(yīng)用,比如:sensor_msgs包中定義了許多關(guān)于傳感器消息的接口(雷達(dá)、攝像頭、點云......),geometry_msgs包中則定義了許多幾何消息相關(guān)的接口(坐標(biāo)點、坐標(biāo)系、速度指令......);

  3. 如果上述接口文件都不能滿足我們的需求,那么就可以自定義接口消息;

具體如何選型,大家可以根據(jù)具體情況具體分析。




2.2.1 案例以及案例分析

1.案例需求

需求1:編寫話題通信實現(xiàn),發(fā)布方以某個頻率發(fā)布一段文本,訂閱方訂閱消息,并輸出在終端。


需求2:編寫話題通信實現(xiàn),發(fā)布方以某個頻率發(fā)布自定義接口消息,訂閱方訂閱消息,并輸出在終端。


2.案例分析

在上述案例中,需要關(guān)注的要素有三個:

  1. 發(fā)布方;

  2. 訂閱方;

  3. 消息載體。

案例1和案例2的主要區(qū)別在于消息載體,前者可以使用原生的數(shù)據(jù)類型,后者需要自定義接口消息。

3.流程簡介

案例2需要先自定義接口消息,除此之外的實現(xiàn)流程與案例1一致,主要步驟如下:

  1. 編寫發(fā)布方實現(xiàn);

  2. 編寫訂閱方實現(xiàn);

  3. 編輯配置文件;

  4. 編譯;

  5. 執(zhí)行。

案例我們會采用C++和Python分別實現(xiàn),二者都遵循上述實現(xiàn)流程。

4.準(zhǔn)備工作

終端下進入工作空間的src目錄,調(diào)用如下兩條命令分別創(chuàng)建C++功能包和Python功能包。

ros2 pkg create cpp01_topic --build-type ament_cmake --dependencies rclcpp std_msgs base_interfaces_demo ros2 pkg create py01_topic --build-type ament_python --dependencies rclpy std_msgs base_interfaces_demo

2.2.2 話題通信之原生消息(C++)

1.發(fā)布方實現(xiàn)

功能包cpp01_topic的src目錄下,新建C++文件demo01_talker_str.cpp,并編輯文件,輸入如下內(nèi)容:


2.訂閱方實現(xiàn)

功能包cpp01_topic的src目錄下,新建C++文件demo02_listener_str.cpp,并編輯文件,輸入如下內(nèi)容:

/* ? ? ?

? 需求:訂閱發(fā)布方發(fā)布的消息,并輸出到終端。 ? ?

? 步驟: ? ? ?

? ? ? 1.包含頭文件; ? ? ? ?

? ? ? 2.初始化 ROS2 客戶端; ? ? ? ?

? ? ? 3.定義節(jié)點類; ? ? ? ? ? ?

? ? ? ? 3-1.創(chuàng)建訂閱方; ? ? ? ? ? ?

? ? ? ? 3-2.處理訂閱到的消息。 ? ? ? ?

? ? ? 4.調(diào)用spin函數(shù),并傳入節(jié)點對象指針; ? ? ? ?

? ? ? 5.釋放資源。?

*/


// 1.包含頭文件;

#include "rclcpp/rclcpp.hpp"

#include "std_msgs/msg/string.hpp"

using std::placeholders::_1;

// 3.定義節(jié)點類;

class MinimalSubscriber : public rclcpp::Node?

{

??public: ?

? ? MinimalSubscriber() ??

? ? : Node("minimal_subscriber") ? ?

? ? { ? ? ?

? ? ? // 3-1.創(chuàng)建訂閱方; ??

?? ? subscription_ = this->create_subscription<std_msgs::msg::String>("topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); ? ?

? ? ? } ?

?private: ? ?

? ? // 3-2.處理訂閱到的消息; ? ?

? ? void topic_callback(const std_msgs::msg::String & msg) const ? ?

? ? { ? ? ?

? ? ? RCLCPP_INFO(this->get_logger(), "訂閱的消息: '%s'", msg.data.c_str());? ? ? ?} ? ?

? ? ? rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;?

};

int main(int argc, char * argv[])

{ ?

? // 2.初始化 ROS2 客戶端; ?

? rclcpp::init(argc, argv); ?

? // 4.調(diào)用spin函數(shù),并傳入節(jié)點對象指針。 ?rclcpp::spin(std::make_shared<MinimalSubscriber>()); ?

? // 5.釋放資源; ?

? rclcpp::shutdown(); ?

? return 0;?

}

3.編輯配置文件

在C++功能包中,配置文件主要關(guān)注package.xml與CMakeLists.txt。

1.package.xml

在創(chuàng)建功能包時,所依賴的功能包已經(jīng)自動配置了,配置內(nèi)容如下:

<depend>rclcpp</depend><depend>std_msgs</depend><depend>base_interfaces_demo</depend>

需要說明的是<depend>base_interfaces_demo</depend>在本案例中不是必須的。

2.CMakeLists.txt

CMakeLists.txt中發(fā)布和訂閱程序核心配置如下:

find_package(rclcpp REQUIRED)?

find_package(std_msgs REQUIRED)

find_package(base_interfaces_demo REQUIRED)?


add_executable(demo01_talker_str src/demo01_talker_str.cpp) ament_target_dependencies( ?

? demo01_talker_str ?

? "rclcpp" ?

? "std_msgs"?

)?


add_executable(demo02_listener_str src/demo02_listener_str.cpp) ament_target_dependencies( ?

?demo02_listener_str ?

?"rclcpp" ?

?"std_msgs"?

)?


install(TARGETS ?

?demo01_talker_str ?

?demo02_listener_str ?

?DESTINATION lib/${PROJECT_NAME})

4.編譯

終端中進入當(dāng)前工作空間,編譯功能包:

colcon build --packages-select cpp01_topic

5.執(zhí)行

當(dāng)前工作空間下,啟動兩個終端,終端1執(zhí)行發(fā)布程序,終端2執(zhí)行訂閱程序。

終端1輸入如下指令:

. install/setup.bash ros2 run cpp01_topic demo01_talker_str

終端2輸入如下指令:

. install/setup.bash ros2 run cpp01_topic demo02_listener_str

最終運行結(jié)果與案例1類似。



2.2.3 話題通信之原生消息(Python)

1.發(fā)布方實現(xiàn)

功能包py01_topic的py01_topic目錄下,新建Python文件demo01_talker_str_py.py,并編輯文件,輸入如下內(nèi)容:

""" ? ? ?

? 需求:以某個固定頻率發(fā)送文本“hello world!”,文本后綴編號,每發(fā)送一條消息,編號遞增1。 ? ?

? 步驟: ? ? ? ?

? ? ? 1.導(dǎo)包; ? ? ? ?

? ? ? 2.初始化 ROS2 客戶端; ? ? ? ?

? ? ? 3.定義節(jié)點類; ? ? ? ? ? ?

? ? ? ? 3-1.創(chuàng)建發(fā)布方; ? ? ? ? ? ?

? ? ? ? 3-2.創(chuàng)建定時器; ? ? ? ? ? ?

? ? ? ? 3-3.組織消息并發(fā)布。 ? ? ? ?

? ? ? 4.調(diào)用spin函數(shù),并傳入節(jié)點對象; ? ? ? ?

? ? ? 5.釋放資源。

"""

# 1.導(dǎo)包;

import rclpy

from rclpy.node import Node

from std_msgs.msg import String

# 3.定義節(jié)點類;

class MinimalPublisher(Node): ? ?

??

? def __init__(self): ? ? ? ?

? ? super().__init__('minimal_publisher_py') ? ? ? ?

? ? # 3-1.創(chuàng)建發(fā)布方; ? ? ? ?

? ? self.publisher_ = self.create_publisher(String, 'topic', 10) ? ? ? ?

? ? # 3-2.創(chuàng)建定時器; ? ? ? ?

? ? timer_period = 0.5 ? ? ? ?

? ? self.timer = self.create_timer(timer_period, self.timer_callback)? ? ? ? ? ? self.i = 0 ? ?


? ? # 3-3.組織消息并發(fā)布。 ? ?

? ? def timer_callback(self): ? ? ? ?

? ? msg = String() ? ? ? ?

? ? msg.data = 'Hello World(py): %d' % self.i ? ?? ? ??

? ? self.publisher_.publish(msg) ??

? ? self.get_logger().info('發(fā)布的消息: "%s"' % msg.data) ? ? ? ?

? ? self.i += 1

def main(args=None): ? ?

? ?# 2.初始化 ROS2 客戶端; ? ?

? ? rclpy.init(args=args) ? ?

? ?# 4.調(diào)用spin函數(shù),并傳入節(jié)點對象; ? ?

? ? minimal_publisher = MinimalPublisher() ? ?

? ? rclpy.spin(minimal_publisher) ? ?

? ?# 5.釋放資源。 ? ?

? ? rclpy.shutdown()


if __name__ == '__main__': ? ?

? main()

2.訂閱方實現(xiàn)

功能包py01_topic的py01_topic目錄下,新建Python文件demo02_listener_str_py.py,并編輯文件,輸入如下內(nèi)容:


3.編輯配置文件

在Python功能包中,配置文件主要關(guān)注package.xml與setup.py。

1.package.xml

在創(chuàng)建功能包時,所依賴的功能包已經(jīng)自動配置了,配置內(nèi)容如下:

<depend>rclcpp</depend><depend>std_msgs</depend><depend>base_interfaces_demo</depend>

需要說明的是和上一節(jié)C++實現(xiàn)一樣<depend>base_interfaces_demo</depend>在本案例中不是必須的。

2.setup.py

entry_points字段的console_scripts中添加如下內(nèi)容:

entry_points={ ? ?'console_scripts': [ ? ? ? ?'demo01_talker_str_py = py01_topic.demo01_talker_str_py:main', ? ? ? ?'demo02_listener_str_py = py01_topic.demo02_listener_str_py:main' ? ?], },

4.編譯

終端中進入當(dāng)前工作空間,編譯功能包:

colcon build --packages-select py01_topic

5.執(zhí)行

當(dāng)前工作空間下,啟動兩個終端,終端1執(zhí)行發(fā)布程序,終端2執(zhí)行訂閱程序。

終端1輸入如下指令:

. install/setup.bash ros2 run py01_topic demo01_talker_str_py

終端2輸入如下指令:

. install/setup.bash ros2 run py01_topic demo02_listener_str_py

最終運行結(jié)果與案例1類似。



2.2.4 話題通信自定義接口消息

自定義接口消息的流程與在功能包中編寫可執(zhí)行程序的流程類似,主要步驟如下:

  1. 創(chuàng)建并編輯?.msg文件;

  2. 編輯配置文件;

  3. 編譯;

  4. 測試。

接下來,我們可以參考案例2編譯一個msg文件,該文件中包含學(xué)生的姓名、年齡、身高等字段。

1.創(chuàng)建并編輯 .msg 文件

功能包base_interfaces_demo下新建 msg 文件夾,msg文件夾下新建Student.msg文件,文件中輸入如下內(nèi)容:

string ? name int32 ? ?age float64 ?height

2.編輯配置文件

1.package.xml文件

在package.xml中需要添加一些依賴包,具體內(nèi)容如下:

<build_depend>rosidl_default_generators</build_depend> <exec_depend>rosidl_default_runtime</exec_depend> <member_of_group>rosidl_interface_packages</member_of_group>

2.CMakeLists.txt文件

為了將.msg文件轉(zhuǎn)換成對應(yīng)的C++和Python代碼,還需要在CMakeLists.txt中添加如下配置:

find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} ?"msg/Student.msg" )

3.編譯

終端中進入當(dāng)前工作空間,編譯功能包:

colcon build --packages-select base_interfaces_demo

4.測試

編譯完成之后,在工作空間下的install目錄下將生成Student.msg文件對應(yīng)的C++和Python文件,我們也可以在終端下進入工作空間,通過如下命令查看文件定義以及編譯是否正常:

. install/setup.bash ros2 interface show base_interfaces_demo/msg/Student

正常情況下,終端將會輸出與Student.msg文件一致的內(nèi)容。



2.2.5 話題通信之自定義消息(C++)

準(zhǔn)備

C++文件中包含自定義消息相關(guān)頭文件時,可能會拋出異常,可以配置VSCode中c_cpp_properties.json文件,在文件中的 includePath屬性下添加一行:"${workspaceFolder}/install/base_interfaces_demo/include/**"

添加完畢后,包含相關(guān)頭文件時,就不會拋出異常了,其他接口文件或接口包的使用也與此同理。

1.發(fā)布方實現(xiàn)

功能包cpp01_topic的src目錄下,新建C++文件demo01_talker_stu.cpp,并編輯文件,輸入如下內(nèi)容:

/* ? ?

?需求:以某個固定頻率發(fā)送文本學(xué)生信息,包含學(xué)生的姓名、年齡、身高等數(shù)據(jù)。?

*/

// 1.包含頭文件;

#include "rclcpp/rclcpp.hpp"

#include "base_interfaces_demo/msg/student.hpp"

using namespace std::chrono_literals;

using base_interfaces_demo::msg::Student;

// 3.定義節(jié)點類;?

class MinimalPublisher : public rclcpp::Node?

{ ?public:?

? ? MinimalPublisher() ? ?

? ? : Node("student_publisher"), count_(0) ? ?

? ? { ? ? ?

? ? ?// 3-1.創(chuàng)建發(fā)布方; ? ? ?

? ? ?publisher_ = this->create_publisher<Student>("topic_stu", 10); ? ? ?

? ? ?// 3-2.創(chuàng)建定時器; ? ? ?

? ? ?timer_ = this->create_wall_timer(500ms, std::bind(&MinimalPublisher::timer_callback, this)); ? ?

} ?


private: ? ?

?void timer_callback() ? ?

? { ? ? ?

? // 3-3.組織消息并發(fā)布。 ? ? ?

? auto stu = Student(); ? ? ?

? stu.name = "張三"; ? ? ?

? stu.age = count_++; ? ? ?

? stu.height = 1.65; ? ? ?

? RCLCPP_INFO(this->get_logger(), "學(xué)生信息:name=%s,age=%d,height=%.2f", stu.name.c_str(),stu.age,stu.height); ? ? ?

? publisher_->publish(stu); ? ?

?} ? ?

? rclcpp::TimerBase::SharedPtr timer_; ? ?

? rclcpp::Publisher<Student>::SharedPtr publisher_; ? ?

? size_t count_;?

};

int main(int argc, char * argv[])

{ ?

? // 2.初始化 ROS2 客戶端; ?rclcpp::init(argc, argv); ?

? // 4.調(diào)用spin函數(shù),并傳入節(jié)點對象指針。 ?rclcpp::spin(std::make_shared<MinimalPublisher>()); ?

? // 5.釋放資源; ?rclcpp::shutdown(); ?return 0;?

}

2.訂閱方實現(xiàn)

功能包cpp01_topic的src目錄下,新建C++文件demo04_listener_stu.cpp,并編輯文件,輸入如下內(nèi)容:

功能包cpp01_topic的src目錄下,新建C++文件demo04_listener_stu.cpp,并編輯文件,輸入如下內(nèi)容:

/* ? ? ?

? ?需求:訂閱發(fā)布方發(fā)布的學(xué)生消息,并輸出到終端。?

*/

// 1.包含頭文件;

#include "rclcpp/rclcpp.hpp"

#include "base_interfaces_demo/msg/student.hpp"


using std::placeholders::_1;

using base_interfaces_demo::msg::Student;

// 3.定義節(jié)點類;

class MinimalSubscriber : public rclcpp::Node

{ ?

? public: ? ?

? ? MinimalSubscriber() ? ?

? ? : Node("student_subscriber") ? ?

? ? { ? ? ?

? ? ?// 3-1.創(chuàng)建訂閱方; ? ? ?

? ? ?subscription_ = this->create_subscription<Student>("topic_stu", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); ? ?

? ? ?} ?


?private: ? ?

? ?// 3-2.處理訂閱到的消息; ? ?

? ?void topic_callback(const Student & msg) const ? ?

? ?{ ? ? ?

? ? ?RCLCPP_INFO(this->get_logger(), "訂閱的學(xué)生消息:name=%s,age=%d,height=%.2f", msg.name.c_str(),msg.age, msg.height); ? ?

? ? } ? ?

? ? rclcpp::Subscription<Student>::SharedPtr subscription_; };


int main(int argc, char * argv[])

{

?// 2.初始化 ROS2 客戶端; ?

?rclcpp::init(argc, argv); ?

?// 4.調(diào)用spin函數(shù),并傳入節(jié)點對象指針。 ?rclcpp::spin(std::make_shared<MinimalSubscriber>()); ?

?// 5.釋放資源; ?

?rclcpp::shutdown(); ?

?return 0;?

}

3.編輯配置文件

package.xml無需修改,CMakeLists.txt文件需要添加如下內(nèi)容:

add_executable(demo03_talker_stu src/demo03_talker_stu.cpp) ament_target_dependencies( ?

?demo03_talker_stu ?

?"rclcpp" ?

?"std_msgs" ?

?"base_interfaces_demo"?

)?


add_executable(demo04_listener_stu src/demo04_listener_stu.cpp) ament_target_dependencies( ?

?demo04_listener_stu ?

?"rclcpp" ?

?"std_msgs" ?

?"base_interfaces_demo"?

)

文件中install修改為如下內(nèi)容:

install(TARGETS ?

?demo01_talker_str ?

?demo02_listener_str ?

?demo03_talker_stu ?

?demo04_listener_stu ?

?DESTINATION lib/${PROJECT_NAME})

4.編譯

終端中進入當(dāng)前工作空間,編譯功能包:

colcon build --packages-select cpp01_topic

5.執(zhí)行

當(dāng)前工作空間下,啟動兩個終端,終端1執(zhí)行發(fā)布程序,終端2執(zhí)行訂閱程序。

終端1輸入如下指令:

. install/setup.bash?

ros2 run cpp01_topic demo03_talker_stu

終端2輸入如下指令:

. install/setup.bash?

ros2 run cpp01_topic demo04_listener_stu

最終運行結(jié)果與案例2類似。


2.2.6 話題通信之自定義消息(Python)

準(zhǔn)備

Python文件中導(dǎo)入自定義消息相關(guān)的包時,為了方便使用,可以配置VSCode中settings.json文件,在文件中的python.autoComplete.extraPaths和python.analysis.extraPaths屬性下添加一行:"${workspaceFolder}/install/base_interfaces_demo/local/lib/python3.10/dist-packages"

添加完畢后,代碼可以高亮顯示且可以自動補齊,其他接口文件或接口包的使用也與此同理。

1.發(fā)布方實現(xiàn)

功能包py01_topic的py01_topic目錄下,新建Python文件demo03_talker_stu_py.py,并編輯文件,輸入如下內(nèi)容:

""" ? ? ?

? ?需求:以某個固定頻率發(fā)送文本學(xué)生信息,包含學(xué)生的姓名、年齡、身高等數(shù)據(jù)。?

"""

# 1.導(dǎo)包;

import rclpy

from rclpy.node import Node

from base_interfaces_demo.msg import Student


# 3.定義節(jié)點類;

class MinimalPublisher(Node): ? ?


?def __init__(self): ? ? ? ?

? ? super().__init__('stu_publisher_py') ? ? ? ?

? ? # 3-1.創(chuàng)建發(fā)布方; ? ? ? ?

? ? self.publisher_ = self.create_publisher(Student, 'topic_stu', 10)? ? ? ?

? ? # 3-2.創(chuàng)建定時器; ? ? ? ?

? ? timer_period = 0.5 ? ? ? ?

? ? self.timer = self.create_timer(timer_period, self.timer_callback)? ? ? ? ? ? self.i = 0 ? ?

? ? # 3-3.組織消息并發(fā)布。 ? ?

? ? def timer_callback(self): ? ? ? ?

? ? ? ?stu = Student() ? ? ? ?

? ? ? ?stu.name = "李四" ? ? ? ?

? ? ? ?stu.age = self.i ? ? ? ?

? ? ? ?stu.height = 1.70 ? ? ? ?

? ? ? ?self.publisher_.publish(stu) ? ? ? ?

? ? ? ?self.get_logger().info('發(fā)布的學(xué)生消息(py): name=%s,age=%d,height=%.2f' % (stu.name, stu.age, stu.height)) ? ? ? ?

? ? ? ?self.i += 1


def main(args=None): ? ?

? # 2.初始化 ROS2 客戶端; ? ?

? rclpy.init(args=args) ? ?

? # 4.調(diào)用spin函數(shù),并傳入節(jié)點對象; ? ?

? minimal_publisher = MinimalPublisher() ? ?

? rclpy.spin(minimal_publisher) ? ?

? # 5.釋放資源。 ? ?

? rclpy.shutdown()

if __name__ == '__main__': ? ?

? main()

2.訂閱方實現(xiàn)

功能包py01_topic的py01_topic目錄下,新建Python文件demo04_listener_stu_py.py,并編輯文件,輸入如下內(nèi)容:

""" ? ? ?

? 需求:訂閱發(fā)布方發(fā)布的學(xué)生消息,并輸出到終端。?

"""


# 1.導(dǎo)包;

import rclpy

from rclpy.node import Node

from base_interfaces_demo.msg import Student#?


3.定義節(jié)點類;

class MinimalSubscriber(Node): ? ?


?def __init__(self): ? ? ? ?

? ?super().__init__('stu_subscriber_py') ? ? ? ?

? ? # 3-1.創(chuàng)建訂閱方; ? ? ? ?

? ? self.subscription = self.create_subscription( ? ? ? ? ? ?

? ? ? ? Student, ? ? ? ? ? ?

? ? ? ? 'topic_stu', ? ? ? ? ? ?

? ? ? ? self.listener_callback, ? ? ? ? ? ?

? ? ? ? 10) ? ? ? ?

? ? ? ? self.subscription ? ? ?


?# 3-2.處理訂閱到的消息。 ? ?

?def listener_callback(self, stu): ? ? ? ?

? ? ?self.get_logger().info('訂閱的消息(py): name=%s,age=%d,height=%.2f' % (stu.name, stu.age, stu.height))


def main(args=None): ? ?

? # 2.初始化 ROS2 客戶端; ? ?

? ?rclpy.init(args=args) ? ?

? # 4.調(diào)用spin函數(shù),并傳入節(jié)點對象; ? ?

? minimal_subscriber = MinimalSubscriber() ? ?

? rclpy.spin(minimal_subscriber) ? ?

? # 5.釋放資源。 ? ?rclpy.shutdown()


if __name__ == '__main__': ? ?

? main()

3.編輯配置文件

package.xml無需修改,需要修改setup.py文件,entry_points字段的console_scripts中修改為如下內(nèi)容:

entry_points={ ? ?

? 'console_scripts': [ ? ? ? ?

? ? ?'demo01_talker_str_py = py01_topic.demo01_talker_str_py:main',? ? ? ? ? ? ?'demo02_listener_str_py = py01_topic.demo02_listener_str_py:main',? ? ? ? ? ?'demo03_talker_stu_py = py01_topic.demo03_talker_stu_py:main',? ? ? ? ? ?? 'demo04_listener_stu_py = py01_topic.demo04_listener_stu_py:main' ? ?

? ?],?

},

4.編譯

終端中進入當(dāng)前工作空間,編譯功能包:

colcon build --packages-select py01_topic

5.執(zhí)行

當(dāng)前工作空間下,啟動兩個終端,終端1執(zhí)行發(fā)布程序,終端2執(zhí)行訂閱程序。

終端1輸入如下指令:

. install/setup.bash?

ros2 run py01_topic demo03_talker_stu_py

終端2輸入如下指令:

. install/setup.bash?

?ros2 run py01_topic demo04_listener_stu_py

最終運行結(jié)果與案例2類似。

B站有完整的ros系列教程視頻,可以觀看完整內(nèi)容ros課程ROS2理論與實踐

更多內(nèi)容將在猛獅知識星球社區(qū)更新最新課程,后續(xù)將推出更多優(yōu)質(zhì)內(nèi)容——詳情可關(guān)注猛獅集訓(xùn)營公眾號和猛獅集訓(xùn)營官方網(wǎng)站。


2.2 話題通信的評論 (共 條)

分享到微博請遵守國家法律
黔江区| 溧阳市| 中方县| 乌审旗| 胶南市| 西青区| 泰来县| 台前县| 南乐县| 宝鸡市| 当涂县| 建昌县| 乐昌市| 枞阳县| 天长市| 唐海县| 雷波县| 富锦市| 寿阳县| 新巴尔虎左旗| 巍山| 阆中市| 蒙山县| 北安市| 永川市| 汶上县| 巴东县| 潞西市| 五常市| 军事| 溧水县| 阳谷县| 德江县| 江陵县| 花垣县| 清丰县| 辛集市| 二手房| 根河市| 雷州市| 东辽县|