네임스페이스란?
ROS2에서 네임스페이스(namespace)는 특정 노드나 토픽을 구분하여 동일한 이름을 사용할 수 있게 해주는 기능을 의미한다. 이는 다중 노드 시스템에서 명명 충돌을 방지하고, 시스템을 계층적으로 관리하는 데 매우 유용하다. 네임스페이스는 파일 시스템의 디렉토리와 비슷한 구조로 생각할 수 있으며, 이를 통해 논리적으로 관련된 노드나 토픽을 그룹화할 수 있다.
네임스페이스 구성
네임스페이스는 기본적으로 다음과 같이 구성된다:
예를 들어, "camera"라는 네임스페이스 안에 "image_publisher"라는 노드를 배치하면, 전체 이름은 "camera/image_publisher"가 된다. 이를 통해 네임스페이스는 노드 간의 중복 이름 문제를 해결할 수 있다.
네임스페이스의 주요 특징
- 계층적 구조: 네임스페이스는 여러 레벨로 나뉠 수 있다. 예를 들어,
/robot1/sensors/camera/image
와 같은 구조로, 상위 네임스페이스가 하위 네임스페이스를 포함할 수 있다. - 유연한 설정: 네임스페이스는 실행 시에 동적으로 설정할 수 있으며, 런치 파일이나 명령줄 인자 등을 통해 쉽게 변경할 수 있다.
네임스페이스 설정 방법
ROS2에서 노드의 네임스페이스는 다양한 방식으로 설정할 수 있다. 다음은 몇 가지 대표적인 방법이다.
1. 런치 파일을 통한 네임스페이스 설정
런치 파일에서 노드의 네임스페이스를 설정하는 방법은 다음과 같다.
<node name="my_node" namespace="my_namespace" package="my_package" executable="my_executable" output="screen">
이 코드에서 namespace는 노드의 네임스페이스를 설정하는 요소이다. 런치 파일에서 이러한 방식을 통해 네임스페이스를 정의하면, 실행 중인 노드가 해당 네임스페이스 안에서 작동하게 된다.
2. 명령줄에서의 네임스페이스 설정
ROS2 노드를 실행할 때 명령줄 인자를 사용하여 네임스페이스를 지정할 수 있다. 예를 들어, ros2 run
명령을 사용하여 네임스페이스를 설정하는 방법은 다음과 같다.
ros2 run my_package my_executable --ros-args --namespace /my_namespace
이렇게 명령줄에서 네임스페이스를 설정하면, 노드가 지정된 네임스페이스 내에서 작동하게 된다.
네임스페이스 적용 예제
다음은 네임스페이스를 적용한 예제다. 네임스페이스를 사용하여 두 개의 카메라 노드를 실행할 때, 네임스페이스를 통해 각각의 카메라가 독립적인 이름을 가질 수 있다.
ros2 run image_tools cam2image --ros-args --namespace /camera1
ros2 run image_tools cam2image --ros-args --namespace /camera2
위 명령에서, 두 개의 카메라 노드는 각각 /camera1과 /camera2라는 네임스페이스를 가진다. 이로 인해 두 노드가 서로 독립적으로 작동할 수 있으며, 동일한 토픽 이름을 사용하더라도 네임스페이스를 통해 명확하게 구분된다.
네임스페이스와 토픽의 상호작용
네임스페이스는 노드뿐만 아니라 토픽에도 적용될 수 있다. ROS2에서는 네임스페이스가 토픽 이름에 자동으로 추가되며, 이로 인해 각 네임스페이스 내에서 동일한 토픽 이름을 사용할 수 있다. 예를 들어, /camera1/image와 /camera2/image라는 두 토픽은 각기 다른 네임스페이스 내에서 동일한 이름을 사용할 수 있으므로 충돌을 피할 수 있다.
토픽 네임스페이스의 자동 적용
만약 노드가 특정 네임스페이스에 포함되어 있다면, 해당 노드에서 퍼블리싱하는 모든 토픽도 그 네임스페이스의 영향을 받는다. 즉, 노드의 네임스페이스가 /robot1/sensors/camera
라면, 해당 노드에서 퍼블리싱하는 토픽의 이름도 /robot1/sensors/camera/<토픽 이름>
으로 변경된다.
토픽의 네임스페이스 예제
다음 예시에서 노드와 토픽에 네임스페이스가 적용되는 방식이다.
ros2 run image_tools cam2image --ros-args --namespace /robot1/sensors/camera
위 명령어로 실행되는 노드가 퍼블리싱하는 기본 토픽 이름이 /image라고 가정하면, 네임스페이스가 적용된 후 해당 노드에서 퍼블리싱되는 토픽 이름은 /robot1/sensors/camera/image가 된다. 네임스페이스를 사용함으로써 다른 로봇이나 센서와의 명명 충돌을 방지할 수 있다.
네임스페이스와 리매핑
리매핑(remapping)은 네임스페이스와 함께 사용되어, 특정 노드나 토픽의 이름을 변경하거나 네트워크 상에서 통신하는 방법을 재구성할 수 있게 한다. 예를 들어, 네임스페이스 내의 특정 토픽을 다른 이름으로 리매핑하면, 이를 통해 원하는 통신을 설정할 수 있다.
리매핑을 통한 토픽 이름 변경
리매핑은 주로 명령줄에서 설정할 수 있으며, 노드 간의 통신을 유연하게 구성하는 데 유용하다. 다음은 리매핑을 통해 토픽 이름을 변경하는 예이다.
ros2 run my_package my_node --ros-args --remap __ns:=/robot1 --remap /old_topic:=/new_topic
위 명령에서, 노드는 /robot1 네임스페이스로 실행되며, /old_topic이라는 토픽은 /new_topic으로 리매핑된다. 이를 통해 토픽 이름을 원하는 대로 변경하고, 다른 노드들과의 통신을 제어할 수 있다.
런치 파일에서 리매핑 설정
런치 파일에서도 리매핑을 설정할 수 있으며, 네임스페이스와 함께 사용되어 보다 복잡한 통신 구조를 설정할 수 있다.
<node name="my_node" namespace="robot1" package="my_package" executable="my_executable" output="screen">
<remap from="/old_topic" to="/new_topic" />
</node>
위의 런치 파일에서는 robot1 네임스페이스 안에서 my_node가 실행되며, /old_topic이 /new_topic으로 리매핑된다. 이를 통해 복잡한 네임스페이스 구조에서도 원하는 통신 구조를 설정할 수 있다.
네임스페이스 실습 예제
네임스페이스를 실습할 때는 다음과 같은 시나리오를 활용할 수 있다. 예를 들어, 로봇 2대가 동일한 코드 기반으로 실행되지만 각 로봇은 별도의 네임스페이스를 사용하여 실행된다고 가정하자.
ros2 run my_robot_package robot_node --ros-args --namespace /robot1
ros2 run my_robot_package robot_node --ros-args --namespace /robot2
이 경우 robot1과 robot2라는 각각의 네임스페이스가 지정되었기 때문에, 동일한 노드와 토픽 이름을 사용하더라도 두 로봇이 서로 간섭하지 않고 독립적으로 작동할 수 있다.
각 로봇은 /robot1/cmd_vel 또는 /robot2/cmd_vel 같은 토픽을 통해 명령을 받을 수 있으며, 이는 네임스페이스를 통해 각 로봇이 별개의 개체로 취급됨을 의미한다.