1. 다중 노드 실행 개요
ROS2에서 여러 노드를 동시에 실행할 때, 런치 파일을 활용하여 다중 노드를 실행할 수 있다. 런치 파일을 통해 각 노드의 실행 순서를 정의하고, 실행 환경 및 파라미터를 설정할 수 있다. 여러 노드를 동시에 실행하는 것은 분산된 로봇 시스템이나 복잡한 작업을 처리하는 데 필수적이다.
2. 런치 파일을 통한 다중 노드 실행
런치 파일에서 다중 노드를 실행하기 위해서는 각각의 노드에 대한 정보를 명시적으로 정의해야 한다. 노드를 정의할 때는 노드 이름, 실행 파일 경로, 파라미터, 네임스페이스 등을 지정할 수 있다.
다음은 간단한 예시이다:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='package_name',
executable='node1_executable',
name='node1',
output='screen'
),
Node(
package='package_name',
executable='node2_executable',
name='node2',
output='screen'
),
])
이 예시에서는 package_name
패키지에 속한 node1_executable
과 node2_executable
두 개의 노드를 런치 파일에서 동시에 실행하고 있다. 노드의 출력은 screen
으로 지정되어 터미널에 출력된다.
3. 런치 파일에서의 노드 파라미터 설정
다중 노드를 실행할 때 각 노드마다 고유의 파라미터를 설정할 수 있다. 파라미터는 런치 파일에서 정의할 수 있으며, 각 노드에 대해 별도로 지정된다.
Node(
package='package_name',
executable='node_executable',
name='node_name',
parameters=[
{'param1': 'value1'},
{'param2': 'value2'}
]
)
위 코드에서 param1
과 param2
는 해당 노드에서 사용할 파라미터로 설정되며, 실행 중에 동적으로 사용할 수 있다.
4. 그룹 실행 개요
그룹 실행은 여러 노드를 한 그룹으로 묶어 실행하는 방법이다. 이를 통해 노드 간 네임스페이스, 파라미터 공유, 실행 조건을 더욱 효율적으로 관리할 수 있다. 그룹 실행은 주로 네임스페이스나 특정 조건 하에 묶여야 하는 노드를 다룰 때 유용하다.
그룹을 정의하는 기본 구조는 다음과 같다:
from launch_ros.actions import PushRosNamespace
group = GroupAction([
PushRosNamespace('group_namespace'),
Node(
package='package_name',
executable='node1_executable',
name='node1',
),
Node(
package='package_name',
executable='node2_executable',
name='node2',
),
])
이 예시에서는 group_namespace
라는 네임스페이스 내에서 node1
과 node2
를 그룹화하여 실행하고 있다.
5. 그룹 실행에서 네임스페이스의 역할
그룹 실행에서 네임스페이스는 중요하다. 각각의 노드를 네임스페이스로 묶으면 노드 이름 충돌을 피할 수 있으며, 논리적인 구조를 제공하여 노드 간 통신을 더 체계적으로 관리할 수 있다.
노드의 네임스페이스를 설정할 때는 PushRosNamespace
클래스를 사용한다. 각 그룹 내에서 동일한 네임스페이스를 공유하는 노드들은 통신 시 네임스페이스가 자동으로 포함된다.
다음과 같은 방식으로 네임스페이스를 설정할 수 있다:
PushRosNamespace('namespace_name')
여기에서 namespace_name
은 그룹 내의 모든 노드에 적용되는 네임스페이스이다.
6. 조건부 실행
다중 노드 실행이나 그룹 실행 시, 특정 조건에 따라 노드를 실행하거나 실행하지 않을 수 있다. 이를 위해 ROS2 런치 파일에서 조건문을 활용할 수 있다. 주로 IfCondition
과 UnlessCondition
을 사용하여 특정 조건에 따라 노드 실행 여부를 결정할 수 있다.
from launch.conditions import IfCondition
from launch_ros.actions import Node
Node(
package='package_name',
executable='node_executable',
name='node_name',
condition=IfCondition('condition_expression')
)
위 예시에서는 condition_expression
이 참일 경우에만 해당 노드를 실행한다. IfCondition
외에도 반대로 조건이 거짓일 때 실행하는 UnlessCondition
도 사용할 수 있다.
7. 그룹 실행의 활용 예시
그룹 실행은 복잡한 시스템에서 자주 사용된다. 예를 들어, 다중 로봇 시스템을 구성할 때 각 로봇마다 동일한 노드를 실행해야 하지만, 로봇 간의 충돌을 피하기 위해 서로 다른 네임스페이스를 사용하는 경우가 있다. 이를 런치 파일에서 그룹을 통해 간단히 구현할 수 있다.
from launch import LaunchDescription
from launch_ros.actions import PushRosNamespace, Node
def generate_launch_description():
return LaunchDescription([
PushRosNamespace('robot1'),
Node(
package='robot_control',
executable='control_node',
name='controller',
),
PushRosNamespace('robot2'),
Node(
package='robot_control',
executable='control_node',
name='controller',
),
])
이 예시에서는 두 개의 로봇(robot1
, robot2
) 각각에 동일한 control_node
노드를 실행하지만, 서로 다른 네임스페이스를 사용하여 실행된다. 이를 통해 두 로봇 간의 노드 이름 충돌을 방지할 수 있다.
8. 런치 파일에서 매개변수 전달
다중 노드를 실행할 때, 각 노드에 공통적인 파라미터를 전달하거나 그룹별로 다른 파라미터를 설정할 수 있다. 이를 통해 더욱 유연한 노드 실행 환경을 구성할 수 있다.
다음은 그룹 내에서 파라미터를 전달하는 예시이다:
from launch_ros.actions import Node
from launch.actions import GroupAction
from launch_ros.actions import PushRosNamespace
def generate_launch_description():
return LaunchDescription([
GroupAction([
PushRosNamespace('robot_group'),
Node(
package='robot_package',
executable='robot_node',
name='robot1',
parameters=[
{'robot_speed': '1.0'},
{'robot_size': 'large'}
]
),
Node(
package='robot_package',
executable='robot_node',
name='robot2',
parameters=[
{'robot_speed': '0.5'},
{'robot_size': 'small'}
]
)
])
])
위 예시에서 두 개의 로봇 노드 robot1
과 robot2
는 각각 다른 파라미터(robot_speed
, robot_size
)를 전달받아 실행된다.
9. 런치 파일에서 환경 변수 설정
다중 노드를 실행할 때 환경 변수를 설정하여 노드의 동작을 제어할 수 있다. 환경 변수는 런치 파일에서 직접 정의할 수 있으며, 이를 통해 런치 파일이 실행되는 동안의 실행 환경을 동적으로 설정할 수 있다.
환경 변수를 설정하는 기본적인 방법은 다음과 같다:
from launch.actions import SetEnvironmentVariable
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
SetEnvironmentVariable('ROS_LOG_LEVEL', 'DEBUG'),
Node(
package='package_name',
executable='node_executable',
name='node_name'
)
])
이 예시에서는 ROS_LOG_LEVEL
환경 변수를 DEBUG
로 설정하여 노드 실행 중에 디버그 수준의 로그가 출력되도록 한다.
10. 런치 파일에서 조건부 그룹 실행
그룹 실행 역시 조건을 걸어 실행할 수 있다. 예를 들어, 특정 조건에 따라 그룹 전체의 실행을 제어할 수 있다. 조건부 그룹 실행은 시스템의 특정 상태에 따라 그룹 내의 노드를 선택적으로 실행할 때 유용하다.
조건부 그룹 실행은 다음과 같이 구현할 수 있다:
from launch.actions import GroupAction
from launch.conditions import IfCondition
from launch_ros.actions import PushRosNamespace, Node
def generate_launch_description():
return LaunchDescription([
GroupAction([
PushRosNamespace('robot1'),
Node(
package='robot_control',
executable='control_node',
name='controller1',
),
Node(
package='robot_sensors',
executable='sensor_node',
name='sensor1',
),
], condition=IfCondition('condition_expression'))
])
이 코드에서 condition_expression
이 참일 경우에만 그룹 내의 노드들이 실행된다. 이를 통해 다중 노드 실행 시 특정 조건에 따라 그룹 실행을 유연하게 제어할 수 있다.
11. 그룹 실행의 동기화
여러 노드를 그룹화하여 실행할 때, 각 노드의 실행 순서를 제어하거나 동기화할 필요가 있다. 특히 로봇 시스템에서는 센서 노드와 제어 노드가 특정 순서로 실행되어야 할 수 있다. 이를 위해 런치 파일에서 TimerAction
을 사용하여 특정 시간 간격을 두고 노드를 실행할 수 있다.
다음은 동기화를 위한 예시이다:
from launch.actions import TimerAction
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='package_name',
executable='sensor_node',
name='sensor_node'
),
TimerAction(
period=5.0,
actions=[Node(
package='package_name',
executable='control_node',
name='control_node'
)]
)
])
이 예시에서는 sensor_node
가 먼저 실행되고, 5초 후에 control_node
가 실행된다. 이를 통해 노드 간 실행 순서를 제어할 수 있다.
12. 런치 파일에서 조건부 실행을 통한 다중 노드 그룹 제어
조건부 실행과 그룹 실행을 결합하여 복잡한 시스템을 구성할 수 있다. 예를 들어, 여러 노드를 그룹으로 묶고, 특정 조건에 따라 해당 그룹을 실행할지 여부를 제어할 수 있다. 이러한 방식은 다양한 환경에서 시스템을 더 유연하게 관리할 수 있게 해준다.
from launch.conditions import IfCondition, UnlessCondition
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='package_name',
executable='node1_executable',
name='node1',
condition=IfCondition('use_node1')
),
Node(
package='package_name',
executable='node2_executable',
name='node2',
condition=UnlessCondition('use_node2')
),
])
위 예시에서는 use_node1
조건이 참일 경우 node1_executable
이 실행되고, use_node2
조건이 거짓일 경우 node2_executable
이 실행된다. 이러한 조건부 실행은 런치 파일에서 노드 실행의 유연성을 크게 향상시킨다.
13. 런치 파일에서 그룹화된 노드의 순차적 실행
런치 파일에서 그룹 내 노드들을 순차적으로 실행하는 방법도 존재한다. 주로 시간 간격이나 실행 조건에 따라 노드를 차례대로 실행할 때 TimerAction
을 활용할 수 있다. 이를 통해 각 노드가 실행될 타이밍을 제어하거나, 서로 다른 노드가 의존성을 가지고 실행되어야 하는 경우에 유용하게 사용된다.
예를 들어, 첫 번째 노드가 실행된 후에 두 번째 노드를 실행할 수 있다:
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import TimerAction
def generate_launch_description():
return LaunchDescription([
Node(
package='sensor_package',
executable='sensor_node',
name='sensor_node',
),
TimerAction(
period=3.0,
actions=[Node(
package='control_package',
executable='control_node',
name='control_node',
)]
),
])
위 예시에서 sensor_node
가 먼저 실행되고, 3초 후에 control_node
가 실행된다. 이를 통해 특정 작업이 먼저 완료된 후 다음 작업을 실행하도록 노드 간 순서를 제어할 수 있다.
14. 런치 파일에서 노드 간 의존성 설정
노드 간 의존성을 설정하는 것은 로봇 시스템에서 중요한 부분이다. 예를 들어, 센서 데이터를 수집하는 노드가 완전히 실행된 후에 제어 노드가 데이터를 기반으로 작업을 수행해야 할 수 있다. 이를 런치 파일에서 설정할 수 있는 방법 중 하나는 RequiredAction
을 사용하는 것이다.
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import RequiredAction
def generate_launch_description():
return LaunchDescription([
Node(
package='sensor_package',
executable='sensor_node',
name='sensor_node',
output='screen',
),
RequiredAction(
condition=lambda: True,
actions=[Node(
package='control_package',
executable='control_node',
name='control_node',
output='screen',
)]
)
])
위 코드는 sensor_node
가 실행된 후에만 control_node
가 실행되는 방식으로 구성된다. 노드 간 의존성이 있을 때 이러한 방법으로 순차적인 실행을 보장할 수 있다.
15. 다중 노드 그룹화의 효율적 사용
다중 노드 그룹화는 로봇 시스템에서 여러 개의 동일한 노드 그룹을 생성하고, 각 그룹이 다른 파라미터나 네임스페이스를 통해 독립적으로 작동하도록 할 때 특히 유용하다. 예를 들어, 여러 대의 로봇이 동일한 제어 노드를 실행하지만 서로 다른 환경에서 작동할 수 있다.
다음은 여러 대의 로봇을 위한 그룹화된 노드 실행 예시이다:
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import GroupAction, PushRosNamespace
def generate_launch_description():
return LaunchDescription([
GroupAction([
PushRosNamespace('robot1'),
Node(
package='robot_control',
executable='controller_node',
name='controller1',
),
Node(
package='robot_sensors',
executable='sensor_node',
name='sensor1',
),
]),
GroupAction([
PushRosNamespace('robot2'),
Node(
package='robot_control',
executable='controller_node',
name='controller2',
),
Node(
package='robot_sensors',
executable='sensor_node',
name='sensor2',
),
]),
])
이 코드에서는 robot1
과 robot2
네임스페이스 내에서 각각의 제어 및 센서 노드가 독립적으로 실행된다. 그룹화를 통해 여러 노드 간의 충돌을 방지하면서 동일한 구조의 시스템을 반복적으로 구성할 수 있다.