다중 로봇에서 생기는 문제
ROS로 하나의 pc에서 로봇을 여러 대 운용하기 시작하면 가장 먼저 부딪히는 문제는
“로봇을 어떻게 구분할 것인가”다.
각 로봇마다 동일한 cmd_vel, odom 토픽을 사용하기 때문에
아무 설정 없이 실행하면 통신 충돌이 발생한다.
이 문제를 해결하는 방법으로 흔히 ROS_DOMAIN_ID와 Namespace가 언급된다.
ROS_DOMAIN_ID의 한계
ROS_DOMAIN_ID는 DDS 레벨에서 통신을 분리한다.
도메인이 다르면 서로를 아예 발견하지 못한다.
이 방식은 로봇 간 완전한 격리에는 효과적이지만,
-
중앙 제어
-
로봇 간 협업
-
상태 공유
가 필요한 다중 로봇 시스템에서는 오히려 제약이 된다.
즉, ROS_DOMAIN_ID는 “분리”에는 강하지만
“함께 동작하는 시스템”을 만들기에는 적합하지 않다.
Namespace가 적합한 이유
위 이미지를 보다시피 Namespace는 같은 ROS 네트워크 안에서 토픽과 노드의 이름만 논리적으로 분리한다.
/robot1/cmd_vel
/robot2/cmd_vel
이 구조의 장점은 명확하다.
-
로봇들은 서로를 인식할 수 있고
-
중앙 제어 및 협업이 가능하며
-
코드 수정 없이 로봇 수를 늘릴 수 있다
다중 로봇을 하나의 분산 시스템으로 설계할 수 있게 된다.
Namespace 사용 방법
Namespace는 코드가 아니라 실행 시점 설정이다.
노드 내부 (상대 경로 사용)
self.create_publisher(Twist, 'cmd_vel', 10)
Launch 파일에서 Namespace 적용
from launch import LaunchDescription
from launch.actions import GroupAction, DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node, PushRosNamespace
def generate_launch_description():
namespace = LaunchConfiguration('namespace')
return LaunchDescription([
DeclareLaunchArgument(
'namespace',
default_value='',
description='robot namespace'
),
GroupAction([
PushRosNamespace(namespace),
Node(
package='my_robot_pkg',
executable='controller_node'
),
])
])
이 Launch 파일을 다음과 같이 실행하면,
ros2 launch <package_name> my_robot.launch.py namespace:=robot1
해당 그룹 안의 모든 노드는 자동으로
/robot1 네임스페이스 아래에서 실행된다.
실행 결과
위 설정으로 실행하면 노드는 내부적으로 다음 토픽을 사용하게 된다.
/robot1/cmd_vel
같은 Launch 파일을 다시 실행하되 네임스페이스만 바꾸면,
ros2 launch <package_name> my_robot.launch.py namespace:=robot2
두 번째 로봇이 추가되며, 토픽 구조는 다음과 같이 분리된다.
/robot1/cmd_vel
/robot2/cmd_vel
한 줄 정리
ROS_DOMAIN_ID는 로봇을 격리할 때 사용하는 도구이고,
Namespace는 로봇을 함께 운용하기 위한 설계 방식이다.
다중 로봇 시스템의 기본 선택은 Namespace가 된다.
