3.4 節(jié)點(diǎn)重名
問題描述
在 ROS2 中不同的節(jié)點(diǎn)可以有相同的節(jié)點(diǎn)名稱,比如可以啟動(dòng)多個(gè) turtlesim_node 節(jié)點(diǎn),這些節(jié)點(diǎn)的名稱都是 turtlesim。節(jié)點(diǎn)重名雖然是被允許的,但是開發(fā)者應(yīng)該主動(dòng)避免這種情況,因?yàn)楣?jié)點(diǎn)重名時(shí)可能會(huì)導(dǎo)致操作上的混淆,仍以啟動(dòng)了多個(gè) turtlesim_node 節(jié)點(diǎn)為例,當(dāng)使用計(jì)算圖(rqt_graph)查看節(jié)點(diǎn)運(yùn)行狀態(tài)時(shí),由于他們的節(jié)點(diǎn)名稱一致,那么雖然實(shí)際有多個(gè)節(jié)點(diǎn),但是在計(jì)算圖上顯示一個(gè)。并且節(jié)點(diǎn)名稱也會(huì)和話題名稱、服務(wù)名稱、動(dòng)作名稱、參數(shù)等產(chǎn)生關(guān)聯(lián),屆時(shí)也可能會(huì)導(dǎo)致通信邏輯上的混亂。
那么在 ROS2 中如何避免節(jié)點(diǎn)重名呢?
解決思路
避免重名問題,一般有兩種策略:
名稱重映射,也即為節(jié)點(diǎn)起別名;
命名空間,是為節(jié)點(diǎn)名稱添加前綴,可以有多級(jí),格式:/xxx/yyy/zzz。
這也是在 ROS2 中解決重名問題的常用策略。
解決方案
上述兩種策略的實(shí)現(xiàn)途徑主要有如下三種:
ros2 run 命令實(shí)現(xiàn);
launch 文件實(shí)現(xiàn);
編碼實(shí)現(xiàn)。
本節(jié)將逐一演示上述三種方案的實(shí)現(xiàn)語(yǔ)法。
3.4.1 ros2 run設(shè)置節(jié)點(diǎn)名稱
1.ros2 run設(shè)置命名空間
1.1設(shè)置命名空間演示
語(yǔ)法:ros2 run 包名 節(jié)點(diǎn)名 --ros-args --remap __ns:=命名空間
示例:
ros2 run turtlesim turtlesim_node --ros-args --remap __ns:=/t1
1.2運(yùn)行結(jié)果
使用ros2 node list
查看節(jié)點(diǎn)信息,顯示結(jié)果:
/t1/turtlesim
2.ros2 run名稱重映射
2.1為節(jié)點(diǎn)起別名
語(yǔ)法:?ros2 run 包名 節(jié)點(diǎn)名 --ros-args --remap __name:=新名稱
或
ros2 run 包名 節(jié)點(diǎn)名 --ros-args --remap __node:=新名稱
示例:
ros2 run turtlesim turtlesim_node --ros-args --remap __name:=turtle1
2.2運(yùn)行結(jié)果
使用ros2 node list
查看節(jié)點(diǎn)信息,顯示結(jié)果:
/turtle1
3.ros2 run命名空間與名稱重映射疊加
3.1設(shè)置命名空間同時(shí)名稱重映射
語(yǔ)法: ros2 run 包名 節(jié)點(diǎn)名 --ros-args --remap __ns:=新名稱 --remap __name:=新名稱
ros2 run turtlesim turtlesim_node --ros-args --remap __ns:=/t1 --remap __name:=turtle1
3.2運(yùn)行結(jié)果
使用ros2 node list
查看節(jié)點(diǎn)信息,顯示結(jié)果:
/t1/turtle1
3.4.2 launch設(shè)置節(jié)點(diǎn)名稱
在ROS2中l(wèi)aunch文件可以由Python、XML或YAML三種語(yǔ)言編寫(關(guān)于launch文件的基本使用可以參考4.1 啟動(dòng)文件launch簡(jiǎn)介),每種實(shí)現(xiàn)方式都可以設(shè)置節(jié)點(diǎn)的命名空間或?yàn)楣?jié)點(diǎn)起別名。
1.Python方式實(shí)現(xiàn)的launch文件設(shè)置命名空間與名稱重映射
在 Python 方式實(shí)現(xiàn)的 launch 文件中,可以通過類?launch_ros.actions.Node
來創(chuàng)建被啟動(dòng)的節(jié)點(diǎn)對(duì)象,在對(duì)象的構(gòu)造函數(shù)中提供了 name 和 namespace 參數(shù)來設(shè)置節(jié)點(diǎn)的名稱與命名空間,使用示例如下:

2.XML方式實(shí)現(xiàn)的launch文件設(shè)置命名空間與名稱重映射
在 XML 方式實(shí)現(xiàn)的 launch 文件中,可以通過 node 標(biāo)簽中 name 和 namespace 屬性來設(shè)置節(jié)點(diǎn)的名稱與命名空間,使用示例如下:

3.YAML方式實(shí)現(xiàn)的launch文件設(shè)置命名空間與名稱重映射
在 YAML 方式實(shí)現(xiàn)的 launch 文件中,可以通過 node 屬性中 name 和 namespace 屬性來設(shè)置節(jié)點(diǎn)的名稱與命名空間,使用示例如下:

4.測(cè)試
上述三種方式在設(shè)置命名空間與名稱重映射時(shí)雖然語(yǔ)法不同,但是實(shí)現(xiàn)功能類似,都是啟動(dòng)了三個(gè) turtlesim_node 節(jié)點(diǎn),第一個(gè)節(jié)點(diǎn)設(shè)置了節(jié)點(diǎn)名稱,第二個(gè)節(jié)點(diǎn)設(shè)置了命名空間,第三個(gè)節(jié)點(diǎn)既設(shè)置了命名空間又設(shè)置了節(jié)點(diǎn)名稱,分別執(zhí)行三個(gè)launch文件,然后使用ros2 node list
查看節(jié)點(diǎn)信息,顯示結(jié)果都如下所示:

3.4.3 編碼設(shè)置節(jié)點(diǎn)名稱
在 rclcpp 和 rclpy 中,節(jié)點(diǎn)類的構(gòu)造函數(shù)中,都分別提供了設(shè)置節(jié)點(diǎn)名稱與命名空間的參數(shù)。
1.rclcpp中的相關(guān)API
rclcpp中節(jié)點(diǎn)類的構(gòu)造函數(shù)如下:
Node (const std::string &node_name, const NodeOptions &options=NodeOptions())?
Node (const std::string &node_name, const std::string &namespace_, const NodeOptions &options=NodeOptions())
構(gòu)造函數(shù)1中可以直接通過node_name設(shè)置節(jié)點(diǎn)名稱,構(gòu)造函數(shù)2既可以通過node_name設(shè)置節(jié)點(diǎn)名稱也可以通過namespace_設(shè)置命名空間。
2.rclpy中的相關(guān)API
rclpy中節(jié)點(diǎn)類的構(gòu)造函數(shù)如下:

構(gòu)造函數(shù)中可以使用node_name設(shè)置節(jié)點(diǎn)名稱,namespace設(shè)置命名空間。

B站有完整的ros系列教程視頻,可以觀看完整內(nèi)容ros課程ROS2理論與實(shí)踐
更多內(nèi)容將在猛獅知識(shí)星球社區(qū)更新最新課程,后續(xù)將推出更多優(yōu)質(zhì)內(nèi)容——詳情可關(guān)注猛獅集訓(xùn)營(yíng)公眾號(hào)和猛獅集訓(xùn)營(yíng)官方網(wǎng)站。