4.4 ROS節點名稱重名
場景:ROS 中創建的節點是有名稱的,C++初始化節點時通過API:
ros::init(argc,argv,"xxxx");
來定義節點名稱,在Python中初始化節點則通過rospy.init_node("yyyy")
來定義節點名稱。在ROS的網絡拓撲中,是不可以出現重名的節點的,因為假設可以重名存在,那么調用時會產生混淆,這也就意味着,不可以啟動重名節點或者同一個節點啟動多次,的確,在ROS中如果啟動重名節點的話,之前已經存在的節點會被直接關閉,但是如果有這種需求的話,怎么優化呢?
在ROS中給出的解決策略是使用命名空間或名稱重映射。
命名空間就是為名稱添加前綴,名稱重映射是為名稱起別名。這兩種策略都可以解決節點重名問題,兩種策略的實現途徑有多種:
- rosrun 命令
- launch 文件
- 編碼實現
以上三種途徑都可以通過命名空間或名稱重映射的方式,來避免節點重名,本節將對三者的使用逐一演示,三者要實現的需求類似。
案例
啟動兩個 turtlesim_node 節點,當然如果直接打開兩個終端,直接啟動,那么第一次啟動的節點會關閉,並給出提示:
[ WARN] [1578812836.351049332]: Shutdown request received. [ WARN] [1578812836.351207362]: Reason given for shutdown: [new node registered with same name]
因為兩個節點不能重名,接下來將會介紹解決重名問題的多種方案。
4.4.1 rosrun設置命名空間與重映射
1.rosrun設置命名空間
1.1設置命名空間演示
語法: rosrun 包名 節點名 __ns:=新名稱
rosrun turtlesim turtlesim_node __ns:=/xxx rosrun turtlesim turtlesim_node __ns:=/yyy
兩個節點都可以正常運行
1.2運行結果
rosnode list
查看節點信息,顯示結果:
/xxx/turtlesim /yyy/turtlesim
2.rosrun名稱重映射
2.1為節點起別名
語法: rosrun 包名 節點名 __name:=新名稱
rosrun turtlesim turtlesim_node __name:=t1 | rosrun turtlesim turtlesim_node /turtlesim:=t1(不適用於python) rosrun turtlesim turtlesim_node __name:=t2 | rosrun turtlesim turtlesim_node /turtlesim:=t2(不適用於python)
兩個節點都可以運行
2.2運行結果
rosnode list
查看節點信息,顯示結果:
/t1 /t2
3.rosrun命名空間與名稱重映射疊加
3.1設置命名空間同時名稱重映射
語法: rosrun 包名 節點名 __ns:=新名稱 __name:=新名稱
rosrun turtlesim turtlesim_node __ns:=/xxx __name:=tn
3.2運行結果
rosnode list
查看節點信息,顯示結果:
/xxx/tn
使用環境變量也可以設置命名空間,啟動節點前在終端鍵入如下命令:
export ROS_NAMESPACE=xxxx
4.4.2 launch文件設置命名空間與重映射
介紹 launch 文件的使用語法時,在 node 標簽中有兩個屬性: name 和 ns,二者分別是用於實現名稱重映射與命名空間設置的。使用launch文件設置命名空間與名稱重映射也比較簡單。
1.launch文件
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1" />
<node pkg="turtlesim" type="turtlesim_node" name="t2" />
<node pkg="turtlesim" type="turtlesim_node" name="t1" ns="hello"/>
</launch>
在 node 標簽中,name 屬性是必須的,ns 可選。
2.運行
rosnode list
查看節點信息,顯示結果:
/t1 /t2 /t1/hello
4.4.3 編碼設置命名空間與重映射
如果自定義節點實現,那么可以更靈活的設置命名空間與重映射實現。
1.C++ 實現:重映射
1.1名稱別名設置
核心代碼:
ros::init(argc,argv,"zhangsan",ros::init_options::AnonymousName);
1.2執行
會在名稱后面添加時間戳。
2.C++ 實現:命名空間
2.1命名空間設置
核心代碼
std::map<std::string, std::string> map; map["__ns"] = "xxxx"; ros::init(map,"wangqiang");
2.2執行
節點名稱設置了命名空間。
3.Python 實現:重映射
3.1名稱別名設置
核心代碼:
rospy.init_node("lisi",anonymous=True)
3.2執行
會在節點名稱后綴時間戳。