feat(level1): ROS2 完全体 12 包 / 80 测试 / 23 文档 / 工程化 / Docker 分组

This commit is contained in:
xs
2026-08-04 10:19:47 +08:00
parent 5ef38ab508
commit 549d6b337e
141 changed files with 8949 additions and 1594 deletions
+34 -46
View File
@@ -1,72 +1,60 @@
"""robot_tf2_launch.py - 启动 URDF + JointStatePublisher + robot_state_publisher + Tf2Listener。
设计思想:
- 用 xacro 解析 URDF(ROS2 工业标准,简单 URDF 可直接读)
- robot_state_publisher 订阅 /joint_states + URDF → 动态 TF → /tf
- Tf2Listener 查 gripper 在 base_link 下位姿
- 跨包: urdf 来自 cpp_robot_tf2, robot_state_publisher 来自 ros-humble-robot-state-publisher
"""
robot_tf2_launch.py —— 启动 3 关节机械臂的 TF2 演示。
启动顺序:
joint_state_publisher (本包) → /joint_states
robot_state_publisher (系统包 ros-humble-robot-state-publisher)
读取 URDF + JointState → 算 base_link -> link1 -> link2 -> gripper 的 TF → /tf
tf2_listener (本包) 查 base_link -> gripper,周期打印末端位姿。
URDF 通过 CommandLineAction 用 xacro/直接读 XML,
这里用 'command' 直接 cat 文件,launch 时读出来给 robot_state_publisher。
"""
import os
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.substitutions import Command, FindExecutable, PathJoinSubstitution
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
from launch_ros.substitutions import FindPackageShare
def generate_launch_description():
pkg_share = get_package_share_directory('cpp_robot_tf2')
urdf_path = os.path.join(pkg_share, 'urdf', 'simple_arm.urdf')
def generate_launch_description() -> LaunchDescription:
"""生成启动描述:URDF + JointState + robot_state_publisher + TF listener。
# robot_description 参数:把 URDF 文件内容作为字符串直接传入。
# 注意:不在 launch 时执行 shell 命令(launch 的 Command 列表拼接有时会
# 丢空格,产生 'cat/root/...' 之类错误);改为 launch 启动前直接读文件。
with open(urdf_path, 'r', encoding='utf-8') as f:
robot_description = f.read()
Returns:
LaunchDescription: 启动描述实例。
"""
# URDF 路径(用包内 urdf/ 目录,跨平台安全)
urdf_path = PathJoinSubstitution([
FindPackageShare('cpp_robot_tf2'),
'urdf',
'simple_arm.urdf',
])
use_sim_time = LaunchConfiguration('use_sim_time')
# 用 cat 读 URDF 内容(给 robot_state_publisher 用)
robot_description = Command([
FindExecutable(name='cat'),
' ',
urdf_path,
])
return LaunchDescription([
DeclareLaunchArgument(
'use_sim_time', default_value='false',
description='Use simulation (Gazebo) clock if true'),
# 1) JointState 发布者:本包 C++ 节点,模拟关节运动。
# 1) JointStatePublisher(C++ 发布关节角度)
Node(
package='cpp_robot_tf2',
executable='joint_state_publisher',
name='joint_state_publisher_cpp',
executable='joint_state_publisher_cpp',
name='joint_state_publisher',
output='screen',
parameters=[{'use_sim_time': use_sim_time}],
),
# 2) robot_state_publisher:ROS2 系统包,URDF + JointState -> /tf
# 2) robot_state_publisher(ROS2 系统包) — URDF + /joint_states → /tf
Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
output='screen',
parameters=[{
'robot_description': robot_description,
'use_sim_time': use_sim_time,
}],
parameters=[{'robot_description': robot_description}],
),
# 3) tf2_listener:本包 C++ 节点,周期打印 gripper 位姿
# 3) TF2 listener(C++ 查 gripper 位姿)
Node(
package='cpp_robot_tf2',
executable='tf2_listener',
name='tf2_listener_cpp',
executable='tf2_listener_cpp',
name='tf2_listener',
output='screen',
parameters=[{'use_sim_time': use_sim_time}],
),
])