ros2 run
명령어를 통해 노드 1개를 실행시킬 수 있다.
그러나 노드 1개로만 프로그램이 이루어지는 게 아니기 때문에, 노드를 여러 개 실행할 수 있는 방법이 필요하다.
launch라는 개념을 이용해 노드 여러 개를 실행할 수 있는데, 이 과정에서 파라미터를 바꾼다던지 workspace를 설정한다던지 하는 것이 가능하다. 이런 것을 종합적으로 처리하기 위해서, launch는 .launch 파일을 실행하는 것으로 수행한다.
.launch파일은 ROS 1에서는 XML기반이었는데, 더 활용도가 높은 방식인 python방식이 추가되었다.
python방식을 기반으로 한 launch에 대해 알아보자.
topic_service_action_rclpy_example 패키지에, argument 노드와 calculator 노드를 실행시키는 launch파일을 작성해 보자.
launch파일은 패키지에 launch라는 폴더를 만들어 그 안에 위치시킨다.
실행시킬 노드들이 사용할 파라미터
를 설정할 파일
을 지정
하는 역할을 한다.
topic_service_action_rclpy_example/launch/arithmetic.launch.py
코드 분석
namespace
Node클래스를 사용할 때 namespace를 지정하면 모든 노드와 노드에 포함된 토픽,서비스,액션 이름을 일괄 변경 가능하다.
복수의 로봇을 사용하는데 각 로봇에 동일 프로그램을 사용해야 할 때, 중복을 피하기 위해 사용하기 좋은 기능이다.
아래는 namespace를 지정했을 경우 launch.py파일 예시이다.
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
ros_namespace=LaunchConfiguration('ros_namespace')
return LaunchDescription([
DeclareLaunchArgument('ros_namespace',
default-value=os.environment['ROS_NAMESPACE'], #환경 변수에 있는 ROS_NAMESPACE읽어오기
description='Namespace for robot'),
Node(
package='topic_service_action_rclcpp_example',
executable='argument',
name='argument',
parameters=[param_dir],
output='screen'),
Node(
package='topic_service_action_rclcpp_example',
executable='calculator',
name='calculator',
parameters=[param_dir],
output='screen',),
])
하나의 런치 파일로 동일 패키지의 노드 실행뿐만 아니라 다른 패키지의 노드 실행도 묶어 할 수 있어 유용하다.
직접 만든 패키지가 아닌 다운받은 패키지의 노드를 실행하고자 할 때도, 그 패키지의 런치 파일을 불러오는 것으로 손쉽게 노드를 실행할 수 있다.
아래는 같은 패키지와 다른 패키지의 런치 파일을 불러오는 상황일 경우 launch.py파일 예시이다.
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.actions import LogInfo
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import ThisLaunchFileDir
def generate_launch_description():
return LaunchDescription([
LogInfo(msg=['Execute three launch files!']),
#같은 패키지에 속한 런치 파일을 불러올 경우
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[ThisLaunchFileDir(), '/xxxxx.launch.py']),
),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[ThisLaunchFileDir(), '/yyyyy.launch.py']),
),
#다른 패키지에 속한 런치 파일을 불러올 경우
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
#bbbbb라는 다른 패키지의 이름을 입력해 준다
[get_package_share_directory('bbbbb'), '/launch/zzzzz.launch.py']),
),
])
launch파일을 ROS 2시스템에서 사용하기 위해선, 해당 패키지에서 패키지 빌드를 해서 정해진 위치에 설치를 해야 한다.
CMakeLists.txt파일에 install()로 아래와 같이 기재해주면 된다.
install(DIRECTORY
런치 파일이 담긴 폴더명
DESTINATION share/${PROJECT_NAME}
)
생략
$ cd ~/ros2_ws
$ colcon build --symlink-install --packages-select topic_service_action_rclpy_example
launch는 ros2 launch 패키지명 런치파일명
을 사용해서 실행한다.(1개 실행은 ros2 run이었다)
$ ros2 launch topic_service_action_rclpy_example arithmetic.launch.py