ROS2 2일차(2) launch
2024. 9. 20. 10:11ㆍROS2/기초
https://puzzling-cashew-c4c.notion.site/ROS-2-Launch-launch-file-55c2125808ef4b64bade278852b37d6e
참조 문서
ros2에서 launch는 아래와 같은 구조
ros2 launch <패키지 이름> <launch 파일이름>
그리고 기본적으로 launch파일은 Python문법을 사용해 ros1에서 사용하던 xml 방식과 비교해보면 매우 편리해졌음
gcamp_world.launch.py 파일 살펴보기
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import ExecuteProcess, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
# this is the function launch system will look for
def generate_launch_description():
use_sim_time = LaunchConfiguration('use_sim_time', default='false')
rviz_file = "skidbot.rviz"
robot_file = "skidbot.urdf"
package_name = "gcamp_gazebo"
world_file_name = "gcamp_world.world"
# full path to urdf and world file
world = os.path.join(
get_package_share_directory(package_name), "worlds", world_file_name
)
urdf = os.path.join(get_package_share_directory(package_name), "urdf", robot_file)
rviz = os.path.join(get_package_share_directory(package_name), "rviz", rviz_file)
# read urdf contents because to spawn an entity in
# gazebo we need to provide entire urdf as string on command line
robot_desc = open(urdf, "r").read()
# double quotes need to be with escape sequence
xml = robot_desc.replace('"', '\\"')
# this is argument format for spwan_entity service
spwan_args = '{name: "skidbot", xml: "' + xml + '" }'
robot_state_publisher_node = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}],
arguments=[urdf],
)
# create and return launch description object
return LaunchDescription(
[
# robot state publisher allows robot model spawn in RVIZ
robot_state_publisher_node,
# start gazebo, notice we are using libgazebo_ros_factory.so instead of libgazebo_ros_init.so
# That is because only libgazebo_ros_factory.so contains the service call to /spawn_entity
ExecuteProcess(
cmd=["gazebo", "--verbose", world, "-s", "libgazebo_ros_factory.so"],
output="screen",
),
# tell gazebo to spwan your robot in the world by calling service
ExecuteProcess(
cmd=[ "ros2", "service", "call", "/spawn_entity", "gazebo_msgs/SpawnEntity", spwan_args ],
output="screen",
),
ExecuteProcess(
cmd=["ros2", "run", "rviz2", "rviz2", "-d", rviz], output="screen"
),
]
)
여기서 아래 ExecuteProcess 아래 부분은 개별적으로 실행 가능
이 파일을 launch 하면
- gazebo 실행
- 로봇 생성
- rviz 실행
gazebo 실행과 로봇 생성 같은 경우엔 파라미터를 미리 설정해줘야하는데
# full path to urdf and world file
world = os.path.join(
get_package_share_directory(package_name), "worlds", world_file_name
)
urdf = os.path.join(get_package_share_directory(package_name), "urdf", robot_file)
rviz = os.path.join(get_package_share_directory(package_name), "rviz", rviz_file)
여기서 미리 설정하여 코드를 여러번 쓸 필요가 없음
launch file을 작성하는 데에는 여러 방식이 있음
첫번째로 ExecuteProcess 방식
rviz만 동작시키는 launch file
cd ~/ch_ws/src/gcamp_ros2_basic/gcamp_gazebo/launch
touch first_launch.launch.py
code first_launch.launch.py
first_launch.launch.py
#!/usr/bin/env python3
import os
from launch import LaunchDescription
from launch.actions import ExecuteProcess, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
# this is the function launch system will look for
def generate_launch_description():
# create and return launch description object
return LaunchDescription(
[
ExecuteProcess(
cmd=["ros2", "run", "rviz2", "rviz2"], output="screen"
),
]
)
cd ~/ch_ws
source install/setup.bash
ros2 launch gcamp_gazebo/first_launch.launch.py
- generate_launch_description : ros2 launch 커멘드를 통해 launch file을 실행시키면, 이 이름을 가진 함수를 찾아들어갑니다. 그래서 모든 launch file에는 빠지지 않고 제일 먼저 등장하는 함수입니다.
- LaunchDescription : 이 부분에서는 말 그대로, 어떤 Node들을 실행시킬지 기술해둔 Description을 작성합니다. 다만 특정한 규칙으로 실행시킨 Node에 대한 옵션을 지정해주어야 하며, 여러 Node들의 실행이 필요할 수 있기에, 기본적으로 list의 구조를 가짐을 파악할 수 있습니다.
- ExecuteProcess : 프로세스 하나를 실행시킨다는 구분의 개념으로 생각하시면 좋습니다.
- cmd : 앞에서 살펴본 바와 같이 터미널에서 입력하는 커멘드를 그대로 실행하고자 할 시에 사용 됩니다. 입력은 list 형태로 주어지며, space를 기점으로 나누어 주면 됩니다.
- output : Error log 등의 output이 출력되는 수단을 입력합니다.
두번째 node 방식
ros2 run turtlesim turtlesim_node
ros2 run turtlesim draw_square
이렇게 따로 실행시켜야 하는 두 노드를 하나의 launch file로 만들어보기
cd ~/ch_ws/src/gcamp_ros2_basic/gcamp_gazebo/launch
touch second_launch.launch.py
code second_launch.launch.py
second_launch.launch.py
#!/usr/bin/env python3
import os
from launch import LaunchDescription
from launch.actions import ExecuteProcess, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
# this is the function launch system will look for
def generate_launch_description():
turtlesim_node = Node(
package='turtlesim',
executable='turtlesim_node',
parameters=[],
arguments=[],
output="screen",
)
turtlesim_teleop_node = Node(
package='turtlesim',
executable='draw_square',
parameters=[],
arguments=[],
output="screen",
)
# create and return launch description object
return LaunchDescription(
[
turtlesim_node,
turtlesim_teleop_node,
]
)
cd ~/ch_ws
source install/setup.bash
ros2 launch gcamp_gazebo/second_launch.launch.py
그러면 거북이가 켜지는 것과 사각형으로 움직이는 것이 한번에 실행되는 것을 볼 수 있다.
- Node : Node 하나를 실행시킬 수 있는 옵션입니다.
- package : 실행시킬 Node가 포함된 package를 선택해줍니다.
- executable : c++ Node의 경우, colcon build를 하면 실행 가능한 프로그램이 생성됩니다. python의 경우도 추가 작업이 필요한데요, 우선 지금은 기존 커멘드의 마지막 인자라고 생각하시면 좋습니다.
- parameters : 실행시킬 Node의 추가 매개변수가 있다면 여기 추가됩니다.
- arguments , name, remappings 등 여러 옵션들이 있다
https://github.com/mit-racecar/racecar/blob/master/racecar/config/racecar-v2/vesc.yaml
위와 같이 매개변수들을 .yaml 파일로 생성 후 launch 할 때 import 할 수 있다.
'ROS2 > 기초' 카테고리의 다른 글
ROS2 2일차(5) tf2 (0) | 2024.09.20 |
---|---|
ROS2 2일차(4) topic 프로그래밍 (0) | 2024.09.20 |
ROS2 2일차(3) topic (0) | 2024.09.20 |
ROS2 2일차(1) node (0) | 2024.09.20 |
ROS2 1일차 Gazebo 월드 생성 및 모델 (0) | 2024.09.19 |