所谓工作空间覆盖,是指在不同的工作空间中,存在重名的功能包的情形。在ROS开发中,在同一工作空间中,功能包不会重名。但是,不同的工作空间中,可能会出现功能包重名的现象。
source /opt/ros/noetic/setup.bash
source /media/d102/EPAN/Desktop/code_study_ubuntu/rosdemo_05/devel/setup.bash
source /media/d102/EPAN/Desktop/code_study_ubuntu/rosdemo_04/devel/setup.bash
source .bashrc
echo $ROS_PACKAGE_PATH
echo $ROS_PACKAGE_PATH
/media/d102/EPAN/Desktop/code_study_ubuntu/rosdemo_04/src:/media/d102/EPAN/Desktop/code_study_ubuntu/rosdemo_05/src:/opt/ros/noetic/share
可见,路径越靠后,优先级越高,功能包重名时,会按照优先级进行查找,优先级高的先被执行
当含有重名功能包时,可能会出现执行异常的情况。比如,C功能包执行时,依赖A中的turtle功能包,但却执行了B中的turtle功能包,由于两个功能包重名,功能有差别,从而导致执行异常
在根目录下的.bashrc文件中,同时source多个文件时,可能会出现在ROS_PACKAGE_PATH中只包含两个工作空间的bug,解决办法如下:(这个BUG很玄学,目前没有找到100%有效的方法,下面方法可供参考)
删除工作空间下的build和devel文件夹重新编译,然后重新载入.bashrc文件
-- Using PYTHON_EXECUTABLE: /home/matthew/anaconda3/envs/torch/bin/python3
-- Using Debian Python package layout
-- Could NOT find PY_em (missing: PY_EM)
CMake Error at /opt/ros/noetic/share/catkin/cmake/empy.cmake:30 (message):
Unable to find either executable 'empy' or Python module 'em'... try
installing the package 'python3-empy'
Call Stack (most recent call first):
/opt/ros/noetic/share/catkin/cmake/all.cmake:164 (include)
/opt/ros/noetic/share/catkin/cmake/catkinConfig.cmake:20 (include)
CMakeLists.txt:58 (find_package)
这是因为catkin找的的python版本为anaconda下面的版本,所以需要改为指定采用下面的命令:
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
有时,需要启动相同的节点,如果直接启动,由于节点名相同,先启动的节点就会由于重名被关闭,为了解决这一问题,可以采用如下三种方法:
# bash1
rosrun turtlesim turtlesim_node __ns:=ns1
# bash2
rosrun turtlesim turtlesim_node __ns:=ns2
rosnode list
/ns1/turtlesim
/ns2/turtlesim
/rosout
/turtlesim
# bash1
rosrun turtlesim turtlesim_node __name:=t1
# bash2
rosrun turtlesim turtlesim_node __name:=t2
rosnode list
/t1
/t2
/turtlesim
# bash1
rosrun turtlesim turtlesim_node __ns:=ns1 __name:=t1
# bash2
rosrun turtlesim turtlesim_node __name:=t2 __ns:=ns2
/ns1/t1
/ns2/t2
# bash1
d102@d102-W65KJ1-KK1:~$ export ROS_NAMESPACE=ns3
d102@d102-W65KJ1-KK1:~$ rosrun turtlesim turtlesim_node
# bash2
d102@d102-W65KJ1-KK1:~$ export ROS_NAMESPACE=ns4
d102@d102-W65KJ1-KK1:~$ rosrun turtlesim turtlesim_node
/ns3/turtlesim
/ns4/turtlesim
<launch>
<!-- 参考节点 -->
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim" />
<!-- 名称重映射 -->
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim_01" />
<!-- 命名空间 -->
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim" ns="ns_01"/>
<!-- 命名空间+名称重映射 -->
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim_02" ns="ns_02"/>
</launch>
rosnode list
/ns3/ns_01/turtlesim
/ns3/ns_02/turtlesim_02
/ns3/turtlesim_01
/turtlesim
ros::init(argc,argv,"server",ros::init_options::AnonymousName);//在节点后面加上时间戳
# bash1
rosrun server_client server
# bash2
rosnode list
/server_1656775703891563446
std::map<std::string, std::string> map;
map["__ns"] = "namespace_01";
ros::init(map,"server",ros::init_options::AnonymousName);//server为节点名
# bash1
rosrun server_client server
# bash2
rosnode list
/namespace_01/server_1656776071871347181
rospy.init_node("server_p",anonymous=True) #会在节点后加入时间戳
# bash1
rosrun server_client server_p.py
# bash2
rosnode list
/server_p_188947_1656776369182