arm_urdf.launch 檔案是典型的 ROS 1 XML Launch 檔案
XML 格式 遷移到 Python Launch 檔案 (推薦,因為它更具彈性和表達能力)。
ROS 2 的啟動系統(Launch System)與 ROS 1 截然不同,它使用 Python 程式碼來定義節點、參數和行為。
ROS 1 (XML) 轉換為 ROS 2 (Python) Launch 檔案
以下是將您 ROS 1 Launch 檔案中的每個組件轉換為 ROS 2 Python Launch 檔案的步驟與說明:
1. 檔案結構與依賴項
2. 轉換後的 ROS 2 Python Launch 程式碼
請在您的 robot_arm_urdf 套件中建立一個 launch 資料夾,並將此檔案命名為 arm_urdf.launch.py:
Python
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, Command, PythonExpression
from launch_ros.actions import Node
from launch.launch_description_sources import PythonLaunchDescriptionSource
# 主要函式:定義啟動內容
def generate_launch_description():
# 1. 定義啟動參數 (對應 ROS 1 的 <arg>)
arg_x = DeclareLaunchArgument('arg_x', default_value='0.00')
arg_y = DeclareLaunchArgument('arg_y', default_value='0.00')
arg_z = DeclareLaunchArgument('arg_z', default_value='0.00')
arg_R = DeclareLaunchArgument('arg_R', default_value='0.00')
arg_P = DeclareLaunchArgument('arg_P', default_value='0.00')
arg_Y = DeclareLaunchArgument('arg_Y', default_value='0.00')
# 獲取 robot_arm_urdf 套件的路徑
pkg_dir = get_package_share_directory('robot_arm_urdf')
# 2. 定義 robot_description 參數 (對應 ROS 1 的 <param>)
# 使用 xacro 將 .xacro 檔案轉換為 URDF XML 內容
# 假設您的 URDF 檔案實際上是 xacro 格式 (robot_arm_urdf.urdf 應該改名為 .xacro)
robot_description_content = Command([
'xacro ', os.path.join(pkg_dir, 'urdf', 'robot_arm_urdf.urdf') # 這裡路徑可能要改成 .xacro
])
robot_description = {'robot_description': robot_description_content}
# 3. 啟動 Gazebo 空世界 (對應 ROS 1 的 <include file="$(find gazebo_ros)/launch/empty_world.launch" />)
gazebo_ros_dir = get_package_share_directory('gazebo_ros')
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(gazebo_ros_dir, 'launch', 'gazebo.launch.py')]),
launch_arguments={'world': 'empty.world'}.items(), # 在 ROS 2 中,使用 gazebo.launch.py 並傳遞 world 參數
)
# 4. TF 靜態發佈器 (對應 ROS 1 的 <node name="tf_footprint_base" pkg="tf" type="static_transform_publisher" ...)
static_tf = Node(
package='tf2_ros',
executable='static_transform_publisher',
name='static_tf_pub',
arguments=['0', '0', '0', '0', '0', '0', 'base_link', 'base_footprint', '40'],
)
# 5. 生成模型到 Gazebo (對應 ROS 1 的 <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" ...)
spawn_entity = Node(
package='gazebo_ros',
executable='spawn_entity.py', # ROS 2 使用 spawn_entity.py
name='urdf_spawner',
arguments=[
'-entity', 'robot_arm_urdf',
'-topic', 'robot_description',
'-x', LaunchConfiguration('arg_x'),
'-y', LaunchConfiguration('arg_y'),
'-z', LaunchConfiguration('arg_z'),
'-Y', LaunchConfiguration('arg_Y'),
# ROS 2 Gazebo 不再直接在 spawn_model 帶 -J joint 參數來初始化關節,
# 而是透過 joint_state_broadcaster 和 robot_controller 來控制。
],
output='screen'
)
# 6. 機器人狀態發佈器 (對應 ROS 1 的 <node name="robot_state_publisher" pkg="robot_state_publisher" ...)
# 這是將 URDF 轉換為 TF 樹的核心。
rsp = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
output='screen',
parameters=[robot_description] # 將 robot_description 參數傳給 RSP
)
# 7. 控制器管理與啟動
# (對應 ROS 1 的 <rosparam file="..." command="load"/> 和 <node name="controller_spawner" ...)
# 7a. 加載控制器配置
joint_traj_config = os.path.join(pkg_dir, 'config', 'joint_trajectory_controller.yaml')
# 7b. 啟動關節狀態廣播器和機械手臂控制器 (ROS 2 中使用 spawner 節點)
controller_manager = Node(
package='controller_manager',
executable='ros2_control_node',
parameters=[robot_description, joint_traj_config],
output={
'stdout': 'screen',
'stderr': 'screen',
},
)
# 7c. 關節狀態廣播器
joint_state_broadcaster_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["joint_state_broadcaster", "--controller-manager", "/controller_manager"],
)
# 7d. 機械手臂控制器 (您的 robot_arm_controller)
robot_arm_controller_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["robot_arm_controller", "--controller-manager", "/controller_manager"],
)
# 返回所有動作的清單
return LaunchDescription([
arg_x,
arg_y,
arg_z,
arg_R,
arg_P,
arg_Y,
gazebo,
static_tf,
rsp,
spawn_entity,
joint_state_broadcaster_spawner,
robot_arm_controller_spawner,
])
沒有留言:
張貼留言