이는 turtlebot4에서 제공해주는 파일이며, gz sim에서 turtlebot4의 시뮬레이션을 할수있게 해준다.
# Copyright 2023 Clearpath Robotics, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# @author Roni Kreinin (rkreinin@clearpathrobotics.com)
import os
from pathlib import Path
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription, SetEnvironmentVariable
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node
ARGUMENTS = [
DeclareLaunchArgument('use_sim_time', default_value='true',
choices=['true', 'false'],
description='use_sim_time'),
DeclareLaunchArgument('world', default_value='warehouse',
description='Simulation World'),
DeclareLaunchArgument('model', default_value='lite',
choices=['standard', 'lite'],
description='Turtlebot4 Model'),
]
def generate_launch_description():
# Directories
pkg_turtlebot4_gz_bringup = get_package_share_directory(
'turtlebot4_gz_bringup')
pkg_turtlebot4_gz_gui_plugins = get_package_share_directory(
'turtlebot4_gz_gui_plugins')
pkg_turtlebot4_description = get_package_share_directory(
'turtlebot4_description')
pkg_irobot_create_description = get_package_share_directory(
'irobot_create_description')
pkg_irobot_create_gz_bringup = get_package_share_directory(
'irobot_create_gz_bringup')
pkg_irobot_create_gz_plugins = get_package_share_directory(
'irobot_create_gz_plugins')
pkg_ros_gz_sim = get_package_share_directory(
'ros_gz_sim')
# Set Gazebo resource path
gz_resource_path = SetEnvironmentVariable(
name='GZ_SIM_RESOURCE_PATH',
value=':'.join([
os.path.join(pkg_turtlebot4_gz_bringup, 'worlds'),
os.path.join(pkg_irobot_create_gz_bringup, 'worlds'),
str(Path(pkg_turtlebot4_description).parent.resolve()),
str(Path(pkg_irobot_create_description).parent.resolve())
])
)
gz_gui_plugin_path = SetEnvironmentVariable(
name='GZ_GUI_PLUGIN_PATH',
value=':'.join([
os.path.join(pkg_turtlebot4_gz_gui_plugins, 'lib'),
os.path.join(pkg_irobot_create_gz_plugins, 'lib')
])
)
# Paths
gz_sim_launch = PathJoinSubstitution(
[pkg_ros_gz_sim, 'launch', 'gz_sim.launch.py'])
# Gazebo harmonic
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource([gz_sim_launch]),
launch_arguments=[
('gz_args', [
LaunchConfiguration('world'),
'.sdf',
' -r',
' -v 4',
' --gui-config ',
PathJoinSubstitution([
pkg_turtlebot4_gz_bringup,
'gui',
LaunchConfiguration('model'),
'gui.config'
])
])
]
)
# Clock bridge
clock_bridge = Node(package='ros_gz_bridge', executable='parameter_bridge',
name='clock_bridge',
output='screen',
arguments=[
'/clock' + '@rosgraph_msgs/msg/Clock' + '[gz.msgs.Clock'
])
# Create launch description and add actions
ld = LaunchDescription(ARGUMENTS)
ld.add_action(gz_resource_path)
ld.add_action(gz_gui_plugin_path)
ld.add_action(gazebo)
ld.add_action(clock_bridge)
return ld
1. 임포트

- 17 , 19 라인
- ROS2 패키지 내부의 특정 파일의 절대 경로를 찾는 일이 많기에 os와 pathlib으로 경로를 동적으로 찾을수있게 설정
- import os
- os와 상호작용하는 기능을 제공하는 파이썬 내장 모듈이다.
- 여기에서는 환경변수 설정과 경로 결합( join ) 등에 사용된다. ( os.path.join()으로 여러 개의 디렉터리를 하나의 경로 문자열로 조합하는 것이 가능 )
- from pathlib import path
- 파일 및 디렉토리의 path를 객체로 다루기 위한 모듈이다.
- 여기에서는 ROS 패키지의 description directory의 parent directory path를 가져올때 사용됨.
- 21라인 ( 사진1 참고 )
- Ros2에서는 패키지 내 특정 resource file ( ex. URDF , Xacro , SDF , YAML 등 )의 경로를 가져오는 것이 필수적인데, 이때 get_package_share_directory()를 사용하면, 하드코딩 없이 유연하게 패키지 경로를 찾을수있다.
- ament_index_python
- ROS2의 패키지 관리 시스템에서 패키지의 공유 폴더 ( share directory )의 path를 검색하는 기능을 제공함.
- get_package_share_directory
- get_package_share_directory('패키지 이름')을 사용하면, 해당 패키지의 share directory를 반환함.
- 23라인
- launch파일이 실행될때, 어떤 노드 실행 , 환경변수 설정, 다른 launch파일 포함 등을 해야하는 지 한 곳에서 정리해서 관리할 수 있게 하려고...
- LaunchDescription
- 이는 ROS2 런치 시스템에서 어떠한 액션( launch action )을 실행할지 정의하는 객체이다.
- LaunchDescription( [액션 리스트] )형태로 실행할 여러 액션을 리스트로 포함시켜야 함.
- 24,25라인
- DeclareLaunchArgument
- launch 파일에서 실행할때, 사용자가 인자를 설정할 수 있도록 선언하는 기능
- ex) DeclareLaunchArgument( 'use_sim_time' , default_value='true' , choice=['true','false'] , description='use_sim_time' )
- IncludeLaunchDescription
- 다른 launch 파일을 포함하여 실행하는 기능 ( 여기에서는 gz sim을 실행하기 위한 gz_sim.launch.py를 사용하기 위함. )
- SetEnvironmentVariable
- 실행환경의 특정 환경 변수값을 설정하는 기능
- 여기에서는 gz의 resource path와 GUI plugin path를 설정하는데 사용
- DeclareLaunchArgument
- 27 라인
- 경로를 동적으로 생성해서, os간의 호환성을 보장하기 위함. 그리고 사용자가 실행시 입력한 값을 동적으로 참조하기 위함
- LaunchConfiguration
- 실행인자의 값을 동적으로 가져오는 기능
- PathJoinSubstitution( [ 경로 요소 리스트 ] )
- 여러개의 경로 요소를 합쳐서 하나의 올바른 경로를 생성하는 기능
- os별 차이를 자동으로 처리해줌. ( window는 c:/로 시작하는 반면, 리눅스는 /home/usr처럼.. )
- LaunchConfiguration
- 경로를 동적으로 생성해서, os간의 호환성을 보장하기 위함. 그리고 사용자가 실행시 입력한 값을 동적으로 참조하기 위함


2. Argument부분
- 해당 부분은 Launch파일에서 사용할 인자( arguments )를 선언한다.
- ROS2는 사용자가 launch file을 실행할때, 특정한 옵션을 선택할수있다. 이때 DeclareLaunchArgument()를 사용하면 된다.
( import 부분의 24라인 )
여기에서는 총 3개의 argument가 선언되었다. - 1번째 argument...
- use_sim_time는 실행시에 사용자가 설정할 수 있는 인자 이름이다.
- default_value=true로 설정하여, 기본적으로 시뮬레이션에서 gz sim의 시간을 ROS2 시스템 시간으로 사용한다..
이는 /clock 토픽을 기반으로 시간이 흐름. - choice=[ true , false ]는 사용자가 설정할 수 있는 값을 의미
- description='use_sim_'time'은 인자에 대한 설명이다. ( launch파일 실행시 도움말로 표시됨 )
- 위의 인자가 필요한 이유??
- ==> ros2에서 turtlebot4와 gz sim같의 시간이 다르게 흐를수있다. 그래서 이를 조정하기 위해서 사용한다.
- 실제 로봇을 사용할때는 use_sim_time:=false로 설정해야함...! ( 그렇지 않으면, 실제 센서 데이터나 로봇의 움직임이 비정상적으로 동작할 수 있음 . )
- ==> ros2에서 turtlebot4와 gz sim같의 시간이 다르게 흐를수있다. 그래서 이를 조정하기 위해서 사용한다.
- 2번째 argument...
- gz sim에서 어떠한 world를 load할지 결정한다.
- world는 실행시 설정하는 인자이름
- default_value는 warehouse이다.
- description은 설명부분...
- 3번째 argument
- model : 실행시 설정한 인자 이름
- default_value는 lite모델로...
- description은 설명...

3-1. generate_launch_description의 필요한 pkg들의 share dir path 가져오기
- import문에 21라인에서 가져온 함수를 여기서 사용함. ( 동적으로 경로를 찾기 위해서... )
- turtlebot4_gz_bringup
- Gazebo 시뮬레이션에서 TurtleBot4를 실행하기 위한 주요 설정 파일 (launch, worlds, config)이 들어 있음.
특히, 월드 파일(.sdf), GUI 설정 파일, launch 파일 등이 포함되어 있음.
- Gazebo 시뮬레이션에서 TurtleBot4를 실행하기 위한 주요 설정 파일 (launch, worlds, config)이 들어 있음.
- turtlebot4_gz_gui_plugins
- Gazebo에서 TurtleBot4 전용 GUI 플러그인을 제공.
ROS 2에서 Gazebo의 UI를 커스터마이징하는 기능을 추가하는 역할.
- Gazebo에서 TurtleBot4 전용 GUI 플러그인을 제공.
- turtlebot4_description
- TurtleBot4의 모델(URDF/Xacro) 파일을 포함하는 패키지
시뮬레이션 및 실제 로봇에서 로봇의 물리적 구조 및 센서 배치를 정의하는 데 사용됨.
- TurtleBot4의 모델(URDF/Xacro) 파일을 포함하는 패키지
- irobot_create_description
- iRobot Create3 로봇의 모델(URDF/Xacro) 파일을 포함.
iRobot Create3는 TurtleBot4의 베이스로 사용됨.
- iRobot Create3 로봇의 모델(URDF/Xacro) 파일을 포함.
- irobot_create_gz_bringup
- iRobot Create3를 Gazebo에서 실행하기 위한 launch 파일 및 환경 설정을 포함.
- irobot_create_gz_plugins
- iRobot Create3 전용 Gazebo 물리 엔진 및 센서 플러그인을 포함.
- ros_gz_sim
- gazebo.launch.py 등의 실행 파일이 포함되어 있음. gz실행을 위한 기본적인 패키지



3-2. generate_launch_description의 gz_resource_path
- 해당 부분은 gz가 resource를 어디에서 로드해야하는지 지정하는 역할을 한다.
- GZ_SIM_RESOURCE_PATH
- 해당되는 이름은 내가 임의 지정이 아닌, gazebo에서 미리 정의된 환경변수이며 반드시 해당 이름을 사용할것.
- 환경변수이니, 당연 임의 수정하면 gz가 인식을 못함. ( gz가 resource( world , model )를 찾을때 필수로 사용함. )
- value=':'
- 여러개의 경로를 : 으로 구분해서, 여러개의 디렉토리를 동시에 검색하는 것이 가능하다.
- os.path.join( pkg_turtlebot4_gz_bringup, 'worlds' )
- turtlebot4의 시뮬레이션 월드 파일( SDF , .world ) 경로를 추가한다.
- 뒤에 'worlds'인자는 get_package_share_directory로 얻은 경로에서 더 하위 디렉토리로 가기 위함이다.
- os.path.join( pkg_irobot_create_gz_bringup , 'worlds' )
- 위와 동일
- str( path( pkg_turtlebot4_description).parent.resolve() )
- get_package_share_directory로 얻은 경로에서 parent.resolve()를 사용해서 부모 디렉토리로 이동한다.
- 이렇게 해서 turtlebot4_description뿐만 아니라 ROS2의 모든 모델 파일을 검색할 수 있게 함.
- str( path( pkg_irobot_create_description).parent.resolve() )
- 위와 동일한 이유
- 근데 나의 pc에서는 위의 2개의 부모는 같다...
- ==>하지만 사용자 환경에 따라 다를 수가 있다...! 그래서 서로 각각 추가하는것이 안전.



3-3. generate_launch_description의 gz_gui_plugin_path
- 이것도 경로를 얻는것
- gazebo에서 사용할 gui플러그인 라이브러리가 어디에 있는지 경로를 설정하는 역할.


3-4. generate_launch_description의 gz_sim_launch
- gazebo를 실행하는 ROS2 launch파일의 경로를 생성하는 역할이다.
- PathJoinSubstition은 import부분의 27라인을 참고하자.

3-5. generate_launch_description의 gazebo 실행을 위한 부분
- gazebo를 실행하는 부분. ( import부분의 25라인 )
- PythonLaunchDescriptionSource( [gz_sim_launch] )
- python기반의 launch파일( gz_sim_launch.py )을 로드하는 역할.
즉, 이 코드를 실행하면, gz_sim.launch.py가 실행되어, gazebo를 띄워준다.
- python기반의 launch파일( gz_sim_launch.py )을 로드하는 역할.
- launch_arguments= [ ]
- gazebo 실행 인자들을 전달한다.
- 'gz_args'
- 해당 인자로 gazebo에게 실행에 필요한 설정들을 전달,
- --gui-config
- gui파일을 설정한다.
- --gui-config /opt/ros/jazzy/share/turtlebot4_gz_bringup/gui/lite/gui.config ( 사용자가 선택한 모델이 lite라면 다음과 같이 경로가 나올것임 )

3-6. generate_launch_description의 clock bridge 노드를 실행
- gazebo와 ros간의 시간 동기화를 위해서 clock 데이터를 변환하는 bridge 실행
- package='ros_gz_bridge'
- gazebo와 ros간의 bridge를 제공하는 package
- executable='parameter_bridge'
- 파라미터 bridge를 실행하는 실행 파일이다.
- name='clock_bridge'
- 노드 이름 지정
- output='screen'
- 실행 로그를 터미널 화면에 출력
- /clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock
- gz의 clock메시지를 ros2 clock 메시지로 변환


3-7. generate_launch_description의 LaunchDescription
- import문의 23라인에서 말했듯이 LaunchDescription은 ros2의 launch시스템에서 실행할 요소들을 모아두는 컨테이너이다.
- ARGUMENTS는 launch파일 실행시 사용할 인자값들을 포함하는 리스트이다.
- ld.add_action( gz_resource_path )
- gazebo 리소스 경로에 대한 환경변수 설정
- ld.add_action( gz_gui_plugin_path )
- gazebo gui 플러그인 경로 설정
- 이게 없으면, gz의 ui에서 터틀봇에 대한 ui가 제대로 동작 못함.
- ld.add_action( gazebo )
- gazebo실행을 하기 위한...
- ld.add_action
- Gazebo에서 생성한 /clock 토픽을 ROS 2에서 사용할 수 있도록 변환(Bridge)하는 역할을 한다.
'코딩 및 기타' 카테고리의 다른 글
| map server ( Nav2 ) (0) | 2025.03.23 |
|---|---|
| ros2 turtlebot 자주쓰던 명령어 (0) | 2025.03.19 |
| 조합 최적화 (0) | 2025.02.14 |
| informed sampler란? (0) | 2025.02.13 |
| HSVC ( hierarchical state validity checking ) (0) | 2025.02.12 |