海外域名提示風(fēng)險(xiǎn)網(wǎng)站嗎帝國(guó)cms怎么做網(wǎng)站聲明
鶴壁市浩天電氣有限公司
2026/01/24 15:49:28
海外域名提示風(fēng)險(xiǎn)網(wǎng)站嗎,帝國(guó)cms怎么做網(wǎng)站聲明,北京網(wǎng)站維護(hù)一般價(jià)格多少,中國(guó)工商注冊(cè)網(wǎng)官網(wǎng)下載的概念在各個(gè)領(lǐng)域隨處可見(jiàn)#xff0c;無(wú)論是硬件結(jié)構(gòu)還是軟件開(kāi)發(fā)#xff0c;都有廣泛的應(yīng)用。 1.1.1 硬件接口
比如生活中最為常見(jiàn)的插頭和插座#xff0c;兩者必須匹配才能使用#xff0c;電腦和手機(jī)上的USB接口也是#xff0c;什么Micro-USB、TypeC等等#xff0c;都…的概念在各個(gè)領(lǐng)域隨處可見(jiàn)無(wú)論是硬件結(jié)構(gòu)還是軟件開(kāi)發(fā)都有廣泛的應(yīng)用。1.1.1 硬件接口比如生活中最為常見(jiàn)的插頭和插座兩者必須匹配才能使用電腦和手機(jī)上的USB接口也是什么Micro-USB、TypeC等等都是關(guān)于接口的具體定義。1.1.2 軟件接口軟件開(kāi)發(fā)中接口的使用就更多了比如我們?cè)诰帉?xiě)程序時(shí)使用的函數(shù)和函數(shù)的輸入輸出也稱之為接口每一次調(diào)用函數(shù)的時(shí)候就像是把主程序和調(diào)用函數(shù)通過(guò)這個(gè)接口連接到一起系統(tǒng)才能正常工作。更為形象的是圖形化編程中使用的程序模塊每一個(gè)模塊都有固定的結(jié)構(gòu)和形狀只有兩個(gè)模塊相互匹配才能在一起工作這就很好的講代碼形象化了。1.1.3 定義所以什么是接口它是一種相互關(guān)系只有彼此匹配才能建立連接?;氐絉OS的通信系統(tǒng)它的主要目的就是傳輸數(shù)據(jù)那就得讓大家高效的建立連接并且準(zhǔn)確包裝和解析傳輸?shù)臄?shù)據(jù)內(nèi)容話題、服務(wù)等機(jī)制也就誕生了他們傳輸?shù)臄?shù)據(jù)都要符合通信接口的標(biāo)準(zhǔn)定義比如攝像頭驅(qū)動(dòng)發(fā)布的圖像話題由每個(gè)像素點(diǎn)的R、G、B三原色值組成控制機(jī)器人運(yùn)動(dòng)的速度指令由線速度和角速度組成進(jìn)行機(jī)器人配置的服務(wù)有配置的參數(shù)和反饋的結(jié)果組成等等類似這些常用的定義在ROS系統(tǒng)中都有提供我們也可以自己開(kāi)發(fā)。這些接口看上去像是給我們加了一些約束但卻是ROS系統(tǒng)的精髓所在舉個(gè)例子我們使用相機(jī)驅(qū)動(dòng)節(jié)點(diǎn)的時(shí)候完全不用關(guān)注它是如何驅(qū)動(dòng)相機(jī)的只要一句話運(yùn)行我們就可以知道發(fā)布出來(lái)的圖像數(shù)據(jù)是什么樣的了直接開(kāi)始我們的應(yīng)用開(kāi)發(fā)類似的鍵盤(pán)控制我們也可以安裝一個(gè)ROS包如何實(shí)現(xiàn)的呢不用關(guān)心反正它發(fā)布出來(lái)的肯定是線速度和角速度。1.2 ROS通信接口接口可以讓程序之間的依賴降低便于我們使用別人的代碼也方便別人使用我們的代碼這就是ROS的核心目標(biāo)減少重復(fù)造輪子。ROS有三種常用的通信機(jī)制分別是話題、服務(wù)、動(dòng)作通過(guò)每一種通信種定義的接口各種節(jié)點(diǎn)才能有機(jī)的聯(lián)系到一起。1.2.1 語(yǔ)言無(wú)關(guān)為了保證每一個(gè)節(jié)點(diǎn)可以使用不同語(yǔ)言編程ROS將這些接口的設(shè)計(jì)做成了和語(yǔ)言無(wú)關(guān)的比如這里看到的int32表示32位的整型數(shù)int64表示64位的整型數(shù)bool表示布爾值還可以定義數(shù)組、結(jié)構(gòu)體這些定義在編譯過(guò)程中會(huì)自動(dòng)生成對(duì)應(yīng)到C、Python等語(yǔ)言里的數(shù)據(jù)結(jié)構(gòu)。其中話題通信接口的定義使用的是.msg文件由于是單向傳輸只需要描述傳輸?shù)拿恳粠瑪?shù)據(jù)是什么就行比如在這個(gè)定義里會(huì)傳輸兩個(gè)32位的整型數(shù)x、y我們可以用來(lái)傳輸二維坐標(biāo)的數(shù)值服務(wù)通信接口的定義使用的是.srv文件包含請(qǐng)求和應(yīng)答兩部分定義通過(guò)中間的---區(qū)分比如之前我們學(xué)習(xí)的加法求和功能請(qǐng)求數(shù)據(jù)是兩個(gè)64位整型數(shù)a和b應(yīng)答是求和的結(jié)果sum動(dòng)作是另外一種通信機(jī)制用來(lái)描述機(jī)器人的一個(gè)運(yùn)動(dòng)過(guò)程使用.action文件定義比如我們讓小海龜轉(zhuǎn)90度一邊轉(zhuǎn)一邊周期反饋當(dāng)前的狀態(tài)此時(shí)接口的定義分成了三個(gè)部分分別是動(dòng)作的目標(biāo)比如是開(kāi)始運(yùn)動(dòng)運(yùn)動(dòng)的結(jié)果最終旋轉(zhuǎn)的90度是否完成還有一個(gè)周期反饋比如每隔1s反饋一下當(dāng)前轉(zhuǎn)到第10度、20度還是30度了讓我們知道運(yùn)動(dòng)的進(jìn)度。1.2.2 標(biāo)準(zhǔn)接口那么ROS系統(tǒng)到底給我們定義了哪些接口呢我們可以在ROS安裝路徑中的share文件夾中找到涵蓋眾多標(biāo)準(zhǔn)定義我們可以打開(kāi)幾個(gè)看看piNanoPC-T6:~$ ls /opt/ros/humble/share/geometry_msgs/msg/Accel.idl PointStamped.idl PoseStamped.idl TwistStamped.idlAccel.msg PointStamped.msg PoseStamped.msg TwistStamped.msgAccelStamped.idl Polygon.idl PoseWithCovariance.idl TwistWithCovariance.idlAccelStamped.msg PolygonInstance.idl PoseWithCovariance.msg TwistWithCovariance.msgAccelWithCovariance.idl PolygonInstance.msg PoseWithCovarianceStamped.idl TwistWithCovarianceStamped.idlAccelWithCovariance.msg PolygonInstanceStamped.idl PoseWithCovarianceStamped.msg TwistWithCovarianceStamped.msgAccelWithCovarianceStamped.idl PolygonInstanceStamped.msg Quaternion.idl Vector3.idlAccelWithCovarianceStamped.msg Polygon.msg Quaternion.msg Vector3.msgInertia.idl PolygonStamped.idl QuaternionStamped.idl Vector3Stamped.idlInertia.msg PolygonStamped.msg QuaternionStamped.msg Vector3Stamped.msgInertiaStamped.idl Pose2D.idl Transform.idl VelocityStamped.idlInertiaStamped.msg Pose2D.msg Transform.msg VelocityStamped.msgPoint32.idl PoseArray.idl TransformStamped.idl Wrench.idlPoint32.msg PoseArray.msg TransformStamped.msg Wrench.msgPoint.idl Pose.idl Twist.idl WrenchStamped.idlPoint.msg Pose.msg Twist.msg WrenchStamped.msgpiNanoPC-T6:~$ ls /opt/ros/humble/share/std_srvs/srv/Empty.idl Empty_Response.msg SetBool.idl SetBool_Response.msg Trigger.idl Trigger_Response.msgEmpty_Request.msg Empty.srv SetBool_Request.msg SetBool.srv Trigger_Request.msg Trigger.srvpiNanoPC-T6:~$ ls /opt/ros/humble/share/std_msgs/msg/Bool.idl Empty.idl Header.idl Int64.idl MultiArrayLayout.idl UInt32MultiArray.idlBool.msg Empty.msg Header.msg Int64.msg MultiArrayLayout.msg UInt32MultiArray.msgByte.idl Float32.idl Int16.idl Int64MultiArray.idl String.idl UInt64.idlByte.msg Float32.msg Int16.msg Int64MultiArray.msg String.msg UInt64.msgByteMultiArray.idl Float32MultiArray.idl Int16MultiArray.idl Int8.idl UInt16.idl UInt64MultiArray.idlByteMultiArray.msg Float32MultiArray.msg Int16MultiArray.msg Int8.msg UInt16.msg UInt64MultiArray.msgChar.idl Float64.idl Int32.idl Int8MultiArray.idl UInt16MultiArray.idl UInt8.idlChar.msg Float64.msg Int32.msg Int8MultiArray.msg UInt16MultiArray.msg UInt8.msgColorRGBA.idl Float64MultiArray.idl Int32MultiArray.idl MultiArrayDimension.idl UInt32.idl UInt8MultiArray.idlColorRGBA.msg Float64MultiArray.msg Int32MultiArray.msg MultiArrayDimension.msg UInt32.msg UInt8MultiArray.msg回到頂部二、接口案例接下來(lái)我們就來(lái)看看 接口到底該如何實(shí)現(xiàn)。我們創(chuàng)建my_learning_interface的C版本的功能包piNanoPC-T6:~/dev_ws$ cd srcpiNanoPC-T6:~/dev_ws/src$ ros2 pkg create --build-type ament_cmake my_learning_interface移除當(dāng)前目錄下的文件src、include。修改package.xml添加接口依賴buildtool_dependament_cmake/buildtool_depend!-- 核心依賴 --build_dependrosidl_default_generators/build_dependexec_dependrosidl_default_runtime/exec_dependmember_of_grouprosidl_interface_packages/member_of_group2.1 服務(wù)接口了解了通信接口的概念接下來(lái)我們?cè)購(gòu)拇a實(shí)現(xiàn)的角度研究下如何定義以及使用一個(gè)接口。在前面介紹服務(wù)的文章中我們編寫(xiě)了這樣一個(gè)例程我們?cè)賮?lái)回顧下。有三個(gè)節(jié)點(diǎn)第一個(gè)相機(jī)驅(qū)動(dòng)節(jié)點(diǎn)發(fā)布圖像話題第二個(gè)是機(jī)器視覺(jué)識(shí)別節(jié)點(diǎn)封裝了一個(gè)服務(wù)的服務(wù)端對(duì)象提供目標(biāo)識(shí)別位置的查詢服務(wù)第三個(gè)節(jié)點(diǎn)在需要目標(biāo)位置的時(shí)候就可以發(fā)送請(qǐng)求收到位置進(jìn)行使用了。2.1.1 接口定義在這個(gè)例程中我們使用GetObjectPosition.srv定義了服務(wù)通信的接口。那這個(gè)接口是怎么定義的呢我們使用VS Code加載功能包my_learning_interface在my_learning_interface文件夾下創(chuàng)建子文件夾srv接著新建文件GetObjectPosition.srv# 請(qǐng)求部分bool get # 獲取目標(biāo)位置的指令---# 響應(yīng)部分int32 x # 目標(biāo)的X坐標(biāo)int32 y # 目標(biāo)的Y坐標(biāo)定義中有兩個(gè)部分上邊是獲取目標(biāo)位置的指令get為true的話就表示我們需要一次位置服務(wù)端就會(huì)反饋這個(gè)x、y坐標(biāo)了。完成定義后還需要在功能包的CMakeLists.txt中配置編譯選項(xiàng)讓編譯器在編譯過(guò)程中根據(jù)接口定義自動(dòng)生成不同語(yǔ)言的代碼...find_package(ament_cmake REQUIRED)find_package(rosidl_default_generators REQUIRED)# 添加要生成的消息/服務(wù)/動(dòng)作rosidl_generate_interfaces(${PROJECT_NAME}srv/GetObjectPosition.srv)...編譯程序piNanoPC-T6:~/dev_ws$ colcon build --paths src/my_learning_interface2.1.2 使用接口包我們?cè)凇禦OS2核心概念之服務(wù)》文章中創(chuàng)建了功能包my_learning_service那在客戶端和服務(wù)端代碼中是如何使用接口的呢。修改功能包my_learning_service依賴package.xmldependmy_learning_interface/depend2.1.2.3 客戶端在my_learning_service目錄下的service_adder_client.py代碼中我們引入了GetObjectPosition接口......from learning_interface.srv import GetObjectPosition # 自定義的服務(wù)接口class objectClient(Node):def __init__(self, name):super().__init__(name) # ROS2節(jié)點(diǎn)父類初始化self.client self.create_client(GetObjectPosition, get_target_position)while not self.client.wait_for_service(timeout_sec1.0):self.get_logger().info(service not available, waiting again...)self.request GetObjectPosition.Request()......2.1.2.4 服務(wù)端同樣在my_learning_service目錄下的service_object_server.py代碼中我們引入了GetObjectPosition接口......from my_learning_interface.srv import GetObjectPosition # 自定義的服務(wù)接口# 橘子的HSV顏色范圍lower_orange np.array([10, 100, 100]) # 橙色的HSV閾值下限upper_orange np.array([25, 255, 255]) # 橙色的HSV閾值上限class ImageSubscriber(Node):def __init__(self, name):super().__init__(name) # ROS2節(jié)點(diǎn)父類初始化self.sub self.create_subscription(Image, image_raw, self.listener_callback, 10) # 創(chuàng)建訂閱者對(duì)象消息類型、話題名、訂閱者回調(diào)函數(shù)、隊(duì)列長(zhǎng)度self.cv_bridge CvBridge() # 創(chuàng)建一個(gè)圖像轉(zhuǎn)換對(duì)象用于OpenCV圖像與ROS的圖像消息的互相轉(zhuǎn)換self.srv self.create_service(GetObjectPosition, # 創(chuàng)建服務(wù)器對(duì)象接口類型、服務(wù)名、服務(wù)器回調(diào)函數(shù)get_target_position,self.object_position_callback)self.objectX 0self.objectY 0......2.2 話題接口話題通信接口的定義也是類似的繼續(xù)從之前的機(jī)器視覺(jué)案例中來(lái)衍生我們想把服務(wù)換成話題周期發(fā)布目標(biāo)識(shí)別的位置不管有沒(méi)有人需要。接著我們采用話題通信的機(jī)制對(duì)物體位置識(shí)別進(jìn)行改造此時(shí)會(huì)有三個(gè)節(jié)點(diǎn)出現(xiàn)相機(jī)驅(qū)動(dòng)節(jié)點(diǎn)將驅(qū)動(dòng)相機(jī)并發(fā)布圖像話題此時(shí)的話題數(shù)據(jù)使用的是ROS中標(biāo)準(zhǔn)定義的Image圖像消息視覺(jué)識(shí)別發(fā)布者節(jié)點(diǎn)訂閱圖像數(shù)據(jù)并運(yùn)行視覺(jué)識(shí)別功能識(shí)別目標(biāo)的位置這個(gè)位置我們希望封裝成話題消息發(fā)布出去誰(shuí)需要使用誰(shuí)就來(lái)訂閱目標(biāo)位置訂閱者節(jié)點(diǎn)訂閱目標(biāo)的位置打印到終端中。2.2.1 接口定義在這個(gè)例程中我們使用ObjectPosition.msg定義了話題通信的接口。那這個(gè)接口是怎么定義的呢我們?cè)趍y_learning_interface文件夾下創(chuàng)建子文件夾msg接著新建文件ObjectPosition.msgint32 x # 表示目標(biāo)的X坐標(biāo)int32 y # 表示目標(biāo)的Y坐標(biāo)話題消息的內(nèi)容是一個(gè)位置我們使用x、y坐標(biāo)值進(jìn)行描述。完成定義后還需要在功能包的CMakeLists.txt中配置編譯選項(xiàng)讓編譯器在編譯過(guò)程中根據(jù)接口定義自動(dòng)生成不同語(yǔ)言的代碼...rosidl_generate_interfaces(${PROJECT_NAME}msg/ObjectPosition.msg)...編譯程序piNanoPC-T6:~/dev_ws$ colcon build --paths src/my_learning_interface2.2.2 視覺(jué)識(shí)別發(fā)布者節(jié)點(diǎn)打開(kāi)my_learning_topic功能包在my_learning_topic文件夾下創(chuàng)建interface_object_pub.pyROS2接口示例-發(fā)布目標(biāo)位置author: zysince : 2025/12/12import rclpy # ROS2 Python接口庫(kù)from rclpy.node import Node # ROS2 節(jié)點(diǎn)類from sensor_msgs.msg import Image # 圖像消息類型from cv_bridge import CvBridge # ROS與OpenCV圖像轉(zhuǎn)換類import cv2 # Opencv圖像處理庫(kù)import numpy as np # Python數(shù)值計(jì)算庫(kù)from my_learning_interface.msg import ObjectPosition # 自定義的目標(biāo)位置消息# 橘子的HSV顏色范圍lower_orange np.array([10, 100, 100]) # 橙色的HSV閾值下限upper_orange np.array([25, 255, 255]) # 橙色的HSV閾值上限創(chuàng)建一個(gè)訂閱者節(jié)點(diǎn)class ImageSubscriber(Node):def __init__(self, name):super().__init__(name) # ROS2節(jié)點(diǎn)父類初始化self.sub self.create_subscription(Image, image_raw, self.listener_callback, 10) # 創(chuàng)建訂閱者對(duì)象消息類型、話題名、訂閱者回調(diào)函數(shù)、隊(duì)列長(zhǎng)度self.pub self.create_publisher(ObjectPosition, object_position, 10) # 創(chuàng)建發(fā)布者對(duì)象消息類型、話題名、隊(duì)列長(zhǎng)度self.cv_bridge CvBridge() # 創(chuàng)建一個(gè)圖像轉(zhuǎn)換對(duì)象用于OpenCV圖像與ROS的圖像消息的互相轉(zhuǎn)換self.objectX 0self.objectY 0def object_detect(self, image):hsv_img cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 圖像從BGR顏色模型轉(zhuǎn)換為HSV模型mask_orange cv2.inRange(hsv_img, lower_orange, upper_orange) # 圖像二值化contours, hierarchy cv2.findContours(mask_orange , cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # 圖像中輪廓檢測(cè)for cnt in contours: # 去除一些輪廓面積太小的噪聲if cnt.shape[0] 150:continue(x, y, w, h) cv2.boundingRect(cnt) # 得到橘子所在輪廓的左上角xy像素坐標(biāo)及輪廓范圍的寬和高cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2) # 將橘子的輪廓勾勒出來(lái)cv2.circle(image, (int(xw/2), int(yh/2)), 5, # 將橘子的圖像中心點(diǎn)畫(huà)出來(lái)(0, 255, 0), -1)self.objectX int(xw/2)self.objectY int(yh/2)cv2.imshow(object, image) # 使用OpenCV顯示處理后的圖像效果cv2.waitKey(50)def listener_callback(self, data):self.get_logger().info(Receiving video frame) # 輸出日志信息提示已進(jìn)入回調(diào)函數(shù)image self.cv_bridge.imgmsg_to_cv2(data, bgr8) # 將ROS的圖像消息轉(zhuǎn)化成OpenCV圖像position ObjectPosition()self.object_detect(image) # 橘子檢測(cè)position.x, position.y int(self.objectX), int(self.objectY)self.pub.publish(position) # 發(fā)布目標(biāo)位置def main(argsNone): # ROS2節(jié)點(diǎn)主入口main函數(shù)rclpy.init(argsargs) # ROS2 Python接口初始化node ImageSubscriber(topic_webcam_sub) # 創(chuàng)建ROS2節(jié)點(diǎn)對(duì)象并進(jìn)行初始化rclpy.spin(node) # 循環(huán)等待ROS2退出node.destroy_node() # 銷毀節(jié)點(diǎn)對(duì)象rclpy.shutdown() # 關(guān)閉ROS2 Python接口完成代碼的編寫(xiě)后需要設(shè)置功能包的編譯選項(xiàng)讓系統(tǒng)知道Python程序的入口打開(kāi)功能包的setup.py文件加入如下入口點(diǎn)的配置entry_points{console_scripts: [topic_helloworld_pub my_learning_topic.topic_helloworld_pub:main,topic_helloworld_sub my_learning_topic.topic_helloworld_sub:main,topic_webcam_pub my_learning_topic.topic_webcam_pub:main,topic_webcam_sub my_learning_topic.topic_webcam_sub:main,interface_object_pub my_learning_topic.interface_object_pub:main],},2.2.3 目標(biāo)位置訂閱者節(jié)點(diǎn)在my_learning_topic文件夾下創(chuàng)建interface_object_sub.pyROS2接口示例-訂閱目標(biāo)位置author: zysince : 2025/12/12import rclpy # ROS2 Python接口庫(kù)from rclpy.node import Node # ROS2 節(jié)點(diǎn)類from std_msgs.msg import String # 字符串消息類型from my_learning_interface.msg import ObjectPosition # 自定義的目標(biāo)位置消息創(chuàng)建一個(gè)訂閱者節(jié)點(diǎn)class SubscriberNode(Node):def __init__(self, name):super().__init__(name) # ROS2節(jié)點(diǎn)父類初始化self.sub self.create_subscription(ObjectPosition, /object_position, self.listener_callback, 10) # 創(chuàng)建訂閱者對(duì)象消息類型、話題名、訂閱者回調(diào)函數(shù)、隊(duì)列長(zhǎng)度def listener_callback(self, msg): # 創(chuàng)建回調(diào)函數(shù)執(zhí)行收到話題消息后對(duì)數(shù)據(jù)的處理self.get_logger().info(Target Position: (%d, %d) % (msg.x, msg.y))# 輸出日志信息提示訂閱收到的話題消息def main(argsNone): # ROS2節(jié)點(diǎn)主入口main函數(shù)rclpy.init(argsargs) # ROS2 Python接口初始化node SubscriberNode(interface_position_sub) # 創(chuàng)建ROS2節(jié)點(diǎn)對(duì)象并進(jìn)行初始化rclpy.spin(node) # 循環(huán)等待ROS2退出node.destroy_node() # 銷毀節(jié)點(diǎn)對(duì)象rclpy.shutdown() # 關(guān)閉ROS2 Python接口完成代碼的編寫(xiě)后需要設(shè)置功能包的編譯選項(xiàng)讓系統(tǒng)知道Python程序的入口打開(kāi)功能包的setup.py文件加入如下入口點(diǎn)的配置entry_points{console_scripts: [topic_helloworld_pub my_learning_topic.topic_helloworld_pub:main,topic_helloworld_sub my_learning_topic.topic_helloworld_sub:main,topic_webcam_pub my_learning_topic.topic_webcam_pub:main,topic_webcam_sub my_learning_topic.topic_webcam_sub:main,interface_object_pub my_learning_topic.interface_object_pub:main,interface_object_sub my_learning_topic.interface_object_sub:main],},2.2.4 編譯運(yùn)行編譯程序piNanoPC-T6:~/dev_ws$ colcon build --paths src/my_learning_topic啟動(dòng)第一個(gè)終端第一個(gè)節(jié)點(diǎn)是相機(jī)驅(qū)動(dòng)節(jié)點(diǎn)發(fā)布圖像數(shù)據(jù)piNanoPC-T6:~/dev_ws$ ros2 run usb_cam usb_cam_node_exe --ros-args -p video_device:/dev/video21啟動(dòng)第二個(gè)終端第二個(gè)是視覺(jué)識(shí)別節(jié)點(diǎn)訂閱圖像數(shù)據(jù)并運(yùn)行視覺(jué)識(shí)別功能識(shí)別目標(biāo)的位置并封裝成話題/object_position消息發(fā)布出去piNanoPC-T6:~/dev_ws$ ros2 run my_learning_topic interface_object_pub[INFO] [1765721881.329790004] [topic_webcam_sub]: Receiving video frame[INFO] [1765721881.389374344] [topic_webcam_sub]: Receiving video frame[INFO] [1765721881.447783021] [topic_webcam_sub]: Receiving video frame[INFO] [1765721881.503004156] [topic_webcam_sub]: Receiving video frame[INFO] [1765721881.558974970] [topic_webcam_sub]: Receiving video frame[INFO] [1765721881.614349516] [topic_webcam_sub]: Receiving video frame[INFO] [1765721881.672467705] [topic_webcam_sub]: Receiving video frame啟動(dòng)第三個(gè)終端第三個(gè)節(jié)點(diǎn)是目標(biāo)位置訂閱者節(jié)點(diǎn)訂閱目標(biāo)的位置打印到終端中piNanoPC-T6:~/dev_ws$ ros2 run my_learning_topic interface_object_sub[INFO] [1765721902.910225255] [interface_position_sub]: Target Position: (387, 293)[INFO] [1765721902.965309682] [interface_position_sub]: Target Position: (387, 293)[INFO] [1765721903.025286418] [interface_position_sub]: Target Position: (387, 293)[INFO] [1765721903.078277510] [interface_position_sub]: Target Position: (387, 292)[INFO] [1765721903.134822213] [interface_position_sub]: Target Position: (387, 293)2.3 接口命令行操作查看系統(tǒng)接口列表piNanoPC-T6:~/dev_ws$ ros2 interface listpiNanoPC-T6:~/dev_ws$ ros2 interface listMessages:action_msgs/msg/GoalInfoaction_msgs/msg/GoalStatusaction_msgs/msg/GoalStatusArrayactionlib_msgs/msg/GoalIDactionlib_msgs/msg/GoalStatus......my_learning_interface/msg/ObjectPosition......Services:action_msgs/srv/CancelGoalcomposition_interfaces/srv/ListNodescomposition_interfaces/srv/LoadNodecomposition_interfaces/srv/UnloadNode......my_learning_interface/srv/AddTwoIntsmy_learning_interface/srv/GetObjectPosition......Actions:action_tutorials_interfaces/action/Fibonacciexample_interfaces/action/Fibonaccilearning_interface/action/MoveCircletf2_msgs/action/LookupTransformturtlesim/action/RotateAbsolute查看某個(gè)接口的詳細(xì)定義piNanoPC-T6:~/dev_ws$ ros2 interface show my_learning_interface/msg/ObjectPositionint32 x # 表示目標(biāo)的X坐標(biāo)int32 y # 表示目標(biāo)的Y坐標(biāo)查看某個(gè)功能包中的接口定義piNanoPC-T6:~/dev_ws$ ros2 interface package my_learning_interfacemy_learning_interface/srv/GetObjectPositionmy_learning_interface/msg/ObjectPositionmy_learning_interface/srv/AddTwoInts通過(guò)rqt_graph可以將節(jié)點(diǎn)和話題以及他們之間的連接可視化