ccg-ros2-workflow 2.2.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +211 -96
  2. package/README.zh-CN.md +256 -0
  3. package/dist/cli.mjs +15 -15
  4. package/dist/index.d.mts +61 -34
  5. package/dist/index.d.ts +61 -34
  6. package/dist/index.mjs +4 -4
  7. package/dist/shared/ccg-ros2-workflow.Bhm8c7P1.mjs +5154 -0
  8. package/package.json +31 -12
  9. package/templates/codex/AGENTS.md +348 -0
  10. package/templates/codex/agents/ccg-implement.toml +73 -0
  11. package/templates/codex/agents/ccg-research.toml +73 -0
  12. package/templates/codex/agents/ccg-review.toml +82 -0
  13. package/templates/codex/config.toml +21 -0
  14. package/templates/codex/hooks/ccg-workflow.py +253 -0
  15. package/templates/codex/hooks.json +15 -0
  16. package/templates/commands/agents/planner.md +97 -122
  17. package/templates/commands/agents/system-integrator.md +2 -2
  18. package/templates/commands/agents/team-architect.md +97 -0
  19. package/templates/commands/agents/team-qa.md +121 -0
  20. package/templates/commands/agents/team-reviewer.md +112 -0
  21. package/templates/commands/commit.md +30 -1
  22. package/templates/commands/context.md +332 -0
  23. package/templates/commands/go.md +206 -0
  24. package/templates/commands/init.md +1 -1
  25. package/templates/commands/spec-impl.md +41 -21
  26. package/templates/commands/spec-init.md +21 -27
  27. package/templates/commands/spec-plan.md +54 -21
  28. package/templates/commands/spec-research.md +78 -26
  29. package/templates/commands/spec-review.md +20 -16
  30. package/templates/{commands → commands-legacy}/analyze.md +1 -1
  31. package/templates/commands-legacy/backend.md +224 -0
  32. package/templates/commands-legacy/codex-exec.md +411 -0
  33. package/templates/{commands → commands-legacy}/debug.md +1 -1
  34. package/templates/commands-legacy/enhance.md +55 -0
  35. package/templates/{commands → commands-legacy}/feat.md +2 -2
  36. package/templates/commands-legacy/frontend.md +213 -0
  37. package/templates/{commands → commands-legacy}/optimize.md +1 -1
  38. package/templates/{commands → commands-legacy}/plan.md +1 -15
  39. package/templates/{commands → commands-legacy}/team-plan.md +1 -1
  40. package/templates/commands-legacy/team.md +475 -0
  41. package/templates/{commands → commands-legacy}/test.md +1 -1
  42. package/templates/commands-legacy/workflow.md +283 -0
  43. package/templates/engine/model-router.md +123 -0
  44. package/templates/engine/phase-guide.md +207 -0
  45. package/templates/engine/strategies/debug-investigate.md +169 -0
  46. package/templates/engine/strategies/deep-research.md +141 -0
  47. package/templates/engine/strategies/direct-fix.md +108 -0
  48. package/templates/engine/strategies/full-collaborate.md +389 -0
  49. package/templates/engine/strategies/git-action.md +43 -0
  50. package/templates/engine/strategies/guided-develop.md +282 -0
  51. package/templates/engine/strategies/optimize-measure.md +103 -0
  52. package/templates/engine/strategies/quick-implement.md +96 -0
  53. package/templates/engine/strategies/refactor-safely.md +180 -0
  54. package/templates/engine/strategies/review-audit.md +123 -0
  55. package/templates/hooks/session-start.js +100 -0
  56. package/templates/hooks/skill-router.js +144 -0
  57. package/templates/hooks/subagent-context.js +161 -0
  58. package/templates/hooks/task-utils.js +190 -0
  59. package/templates/hooks/workflow-state.js +55 -0
  60. package/templates/output-styles/abyss-command.md +56 -0
  61. package/templates/output-styles/abyss-concise.md +89 -0
  62. package/templates/output-styles/abyss-ritual.md +70 -0
  63. package/templates/output-styles/engineer-professional.md +20 -3
  64. package/templates/output-styles/laowang-engineer.md +2 -2
  65. package/templates/prompts/antigravity/analyzer.md +59 -0
  66. package/templates/prompts/antigravity/architect.md +55 -0
  67. package/templates/prompts/antigravity/builder.md +52 -0
  68. package/templates/prompts/antigravity/debugger.md +48 -0
  69. package/templates/prompts/antigravity/frontend.md +50 -0
  70. package/templates/prompts/antigravity/optimizer.md +40 -0
  71. package/templates/prompts/antigravity/reviewer.md +67 -0
  72. package/templates/prompts/antigravity/tester.md +39 -0
  73. package/templates/prompts/claude/debugger.md +1 -1
  74. package/templates/prompts/claude/reviewer.md +1 -1
  75. package/templates/prompts/codex/analyzer.md +8 -0
  76. package/templates/prompts/codex/architect.md +9 -1
  77. package/templates/prompts/codex/builder.md +61 -0
  78. package/templates/prompts/codex/debugger.md +9 -1
  79. package/templates/prompts/codex/optimizer.md +7 -0
  80. package/templates/prompts/codex/reviewer.md +7 -0
  81. package/templates/prompts/codex/tester.md +8 -1
  82. package/templates/prompts/gemini/analyzer.md +11 -3
  83. package/templates/prompts/gemini/architect.md +10 -2
  84. package/templates/prompts/gemini/debugger.md +8 -0
  85. package/templates/prompts/gemini/frontend.md +10 -2
  86. package/templates/prompts/gemini/optimizer.md +9 -2
  87. package/templates/prompts/gemini/reviewer.md +7 -0
  88. package/templates/prompts/gemini/tester.md +8 -1
  89. package/templates/rules/ccg-skill-routing.md +91 -0
  90. package/templates/rules/ccg-skills.md +65 -0
  91. package/templates/skills/SKILL.md +92 -0
  92. package/templates/skills/domains/ai/SKILL.md +34 -0
  93. package/templates/skills/domains/ai/agent-dev.md +242 -0
  94. package/templates/skills/domains/ai/llm-security.md +288 -0
  95. package/templates/skills/domains/ai/prompt-and-eval.md +279 -0
  96. package/templates/skills/domains/ai/rag-system.md +542 -0
  97. package/templates/skills/domains/architecture/SKILL.md +42 -0
  98. package/templates/skills/domains/architecture/api-design.md +225 -0
  99. package/templates/skills/domains/architecture/caching.md +299 -0
  100. package/templates/skills/domains/architecture/cloud-native.md +285 -0
  101. package/templates/skills/domains/architecture/message-queue.md +329 -0
  102. package/templates/skills/domains/architecture/security-arch.md +297 -0
  103. package/templates/skills/domains/data-engineering/SKILL.md +207 -0
  104. package/templates/skills/domains/development/SKILL.md +46 -0
  105. package/templates/skills/domains/development/cpp.md +369 -0
  106. package/templates/skills/domains/development/go.md +323 -0
  107. package/templates/skills/domains/development/java.md +277 -0
  108. package/templates/skills/domains/development/python.md +487 -0
  109. package/templates/skills/domains/development/rust.md +313 -0
  110. package/templates/skills/domains/development/shell.md +313 -0
  111. package/templates/skills/domains/development/typescript.md +277 -0
  112. package/templates/skills/domains/devops/SKILL.md +39 -0
  113. package/templates/skills/domains/devops/cost-optimization.md +272 -0
  114. package/templates/skills/domains/devops/database.md +217 -0
  115. package/templates/skills/domains/devops/devsecops.md +198 -0
  116. package/templates/skills/domains/devops/git-workflow.md +181 -0
  117. package/templates/skills/domains/devops/observability.md +280 -0
  118. package/templates/skills/domains/devops/performance.md +336 -0
  119. package/templates/skills/domains/devops/testing.md +283 -0
  120. package/templates/skills/domains/infrastructure/SKILL.md +200 -0
  121. package/templates/skills/domains/mobile/SKILL.md +224 -0
  122. package/templates/skills/domains/orchestration/SKILL.md +29 -0
  123. package/templates/skills/domains/orchestration/multi-agent.md +263 -0
  124. package/templates/skills/domains/ros2-control/SKILL.md +206 -0
  125. package/templates/skills/domains/ros2-hardware/SKILL.md +277 -0
  126. package/templates/skills/domains/ros2-manipulation/SKILL.md +237 -0
  127. package/templates/skills/domains/ros2-navigation/SKILL.md +196 -0
  128. package/templates/skills/domains/ros2-perception/SKILL.md +166 -0
  129. package/templates/skills/domains/ros2-upper-app/SKILL.md +50 -0
  130. package/templates/skills/domains/ros2-upper-app/launch-files.md +224 -0
  131. package/templates/skills/domains/ros2-upper-app/parameters.md +192 -0
  132. package/templates/skills/domains/ros2-upper-app/python-nodes.md +249 -0
  133. package/templates/skills/domains/ros2-upper-app/rviz-config.md +158 -0
  134. package/templates/skills/domains/ros2-upper-app/simulation.md +225 -0
  135. package/templates/skills/domains/security/SKILL.md +72 -0
  136. package/templates/skills/domains/security/blue-team.md +436 -0
  137. package/templates/skills/domains/security/code-audit.md +265 -0
  138. package/templates/skills/domains/security/pentest.md +226 -0
  139. package/templates/skills/domains/security/red-team.md +374 -0
  140. package/templates/skills/domains/security/threat-intel.md +372 -0
  141. package/templates/skills/domains/security/vuln-research.md +369 -0
  142. package/templates/skills/orchestration/multi-agent/SKILL.md +533 -0
  143. package/templates/skills/run_skill.js +129 -0
  144. package/templates/skills/scrapling/SKILL.md +98 -0
  145. package/templates/skills/scrapling/references/api-quick-ref.md +127 -0
  146. package/templates/skills/scrapling/references/cookie-vault.md +56 -0
  147. package/templates/skills/scrapling/references/maintenance.md +79 -0
  148. package/templates/skills/scrapling/references/site-patterns.md +86 -0
  149. package/templates/skills/scrapling/references/troubleshooting.md +95 -0
  150. package/templates/skills/scrapling/templates/basic_fetch.py +19 -0
  151. package/templates/skills/scrapling/templates/parse_only.py +15 -0
  152. package/templates/skills/scrapling/templates/session_login.py +19 -0
  153. package/templates/skills/scrapling/templates/stealth_cloudflare.py +28 -0
  154. package/templates/skills/tools/gen-docs/SKILL.md +116 -0
  155. package/templates/skills/tools/gen-docs/scripts/doc_generator.js +435 -0
  156. package/templates/skills/tools/lib/shared.js +98 -0
  157. package/templates/skills/tools/override-refusal/SKILL.md +53 -0
  158. package/templates/skills/tools/override-refusal/agents/openai.yaml +4 -0
  159. package/templates/skills/tools/override-refusal/scripts/refusal_rewriter.js +226 -0
  160. package/templates/skills/tools/verify-change/SKILL.md +140 -0
  161. package/templates/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
  162. package/templates/skills/tools/verify-module/SKILL.md +127 -0
  163. package/templates/skills/tools/verify-module/scripts/module_scanner.js +171 -0
  164. package/templates/skills/tools/verify-quality/SKILL.md +160 -0
  165. package/templates/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
  166. package/templates/skills/tools/verify-security/SKILL.md +143 -0
  167. package/templates/skills/tools/verify-security/scripts/security_scanner.js +283 -0
  168. package/templates/spec/guides/index.md +30 -0
  169. package/templates/spec/low-control/index.md +31 -0
  170. package/templates/spec/upper-app/index.md +31 -0
  171. package/bin/codeagent-wrapper-darwin-amd64 +0 -0
  172. package/bin/codeagent-wrapper-darwin-arm64 +0 -0
  173. package/bin/codeagent-wrapper-linux-amd64 +0 -0
  174. package/bin/codeagent-wrapper-linux-arm64 +0 -0
  175. package/bin/codeagent-wrapper-windows-amd64.exe +0 -0
  176. package/bin/codeagent-wrapper-windows-arm64.exe +0 -0
  177. package/dist/shared/ccg-ros2-workflow.DRytDWqb.mjs +0 -2274
  178. package/templates/commands/backend.md +0 -162
  179. package/templates/commands/enhance.md +0 -36
  180. package/templates/commands/frontend.md +0 -162
  181. package/templates/commands/workflow.md +0 -202
  182. /package/templates/{commands → commands-legacy}/execute.md +0 -0
  183. /package/templates/{commands → commands-legacy}/review.md +0 -0
  184. /package/templates/{commands → commands-legacy}/team-exec.md +0 -0
  185. /package/templates/{commands → commands-legacy}/team-research.md +0 -0
  186. /package/templates/{commands → commands-legacy}/team-review.md +0 -0
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: ros2-perception
3
+ description: ROS2 感知技能。激光雷达、相机、点云处理、传感器融合、SLAM 输入。当用户提到激光雷达、LiDAR、点云、PCL、PointCloud2、相机标定、深度图、传感器融合时使用。
4
+ user-invocable: false
5
+ category: domain
6
+ ---
7
+
8
+ # ROS2 感知技能
9
+
10
+ ## 适用场景
11
+
12
+ 机器人感知层开发,处理传感器原始数据并提取语义信息。
13
+
14
+ ### 触发关键词
15
+
16
+ - 激光雷达 / LiDAR / RPLidar / Velodyne / Ouster
17
+ - 点云 / PointCloud2 / PCL / 点云分割 / 体素
18
+ - 相机 / RGB / 深度相机 / RealSense / ZED
19
+ - 标定 / calibration / 内参 / 外参
20
+ - SLAM 输入 / 里程计输入 / 传感器融合
21
+
22
+ ---
23
+
24
+ ## 激光雷达驱动
25
+
26
+ ### 标准包列表
27
+
28
+ | 厂商 | ROS2 包 | 默认 Topic |
29
+ |------|---------|------------|
30
+ | RPLidar | `rplidar_ros` | `/scan` (sensor_msgs/LaserScan) |
31
+ | Velodyne | `velodyne_driver` | `/velodyne_points` (sensor_msgs/PointCloud2) |
32
+ | Ouster | `ouster_ros` | `/ouster/points` |
33
+ | Livox | `livox_ros_driver2` | `/livox/lidar` |
34
+
35
+ ### 启动示例
36
+
37
+ ```python
38
+ # launch/rplidar.launch.py
39
+ Node(
40
+ package='rplidar_ros',
41
+ executable='rplidar_node',
42
+ name='rplidar',
43
+ parameters=[{
44
+ 'serial_port': '/dev/ttyUSB0',
45
+ 'frame_id': 'laser_link',
46
+ 'angle_compensate': True,
47
+ 'scan_mode': 'Standard',
48
+ }],
49
+ )
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 点云处理 (PCL)
55
+
56
+ ### 体素降采样
57
+
58
+ ```cpp
59
+ #include <pcl/filters/voxel_grid.h>
60
+ #include <pcl_conversions/pcl_conversions.h>
61
+
62
+ void cloud_callback(const sensor_msgs::msg::PointCloud2::SharedPtr msg) {
63
+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
64
+ pcl::fromROSMsg(*msg, *cloud);
65
+
66
+ pcl::VoxelGrid<pcl::PointXYZ> voxel;
67
+ voxel.setInputCloud(cloud);
68
+ voxel.setLeafSize(0.05f, 0.05f, 0.05f); // 5cm 体素
69
+ pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);
70
+ voxel.filter(*filtered);
71
+
72
+ sensor_msgs::msg::PointCloud2 output;
73
+ pcl::toROSMsg(*filtered, output);
74
+ output.header = msg->header;
75
+ pub_->publish(output);
76
+ }
77
+ ```
78
+
79
+ ### 平面分割 (RANSAC)
80
+
81
+ ```cpp
82
+ #include <pcl/segmentation/sac_segmentation.h>
83
+
84
+ pcl::SACSegmentation<pcl::PointXYZ> seg;
85
+ seg.setOptimizeCoefficients(true);
86
+ seg.setModelType(pcl::SACMODEL_PLANE);
87
+ seg.setMethodType(pcl::SAC_RANSAC);
88
+ seg.setDistanceThreshold(0.01);
89
+ seg.setInputCloud(cloud);
90
+
91
+ pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
92
+ pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
93
+ seg.segment(*inliers, *coefficients);
94
+ ```
95
+
96
+ ---
97
+
98
+ ## 相机集成
99
+
100
+ ### RealSense 启动
101
+
102
+ ```bash
103
+ ros2 launch realsense2_camera rs_launch.py \
104
+ enable_color:=true \
105
+ enable_depth:=true \
106
+ align_depth.enable:=true \
107
+ pointcloud.enable:=true
108
+ ```
109
+
110
+ ### 深度图转点云
111
+
112
+ ```cpp
113
+ // depth_image_proc 功能包提供
114
+ #include <depth_image_proc/point_cloud_xyz.hpp>
115
+ ```
116
+
117
+ ---
118
+
119
+ ## 传感器融合
120
+
121
+ ### TF2 时间同步
122
+
123
+ ```cpp
124
+ #include <message_filters/subscriber.h>
125
+ #include <message_filters/time_synchronizer.h>
126
+ #include <message_filters/sync_policies/approximate_time.h>
127
+
128
+ using SyncPolicy = message_filters::sync_policies::ApproximateTime<
129
+ sensor_msgs::msg::PointCloud2,
130
+ sensor_msgs::msg::Image>;
131
+
132
+ message_filters::Subscriber<sensor_msgs::msg::PointCloud2> cloud_sub_;
133
+ message_filters::Subscriber<sensor_msgs::msg::Image> image_sub_;
134
+ message_filters::Synchronizer<SyncPolicy> sync_(SyncPolicy(10), cloud_sub_, image_sub_);
135
+ sync_.registerCallback(&Node::fusion_callback, this);
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 关键 QoS 策略
141
+
142
+ | 数据类型 | Reliability | Durability | History | Depth |
143
+ |----------|-------------|------------|---------|-------|
144
+ | LaserScan | Best Effort | Volatile | Keep Last | 5 |
145
+ | PointCloud2 | Best Effort | Volatile | Keep Last | 1 |
146
+ | Image (高分辨率) | Best Effort | Volatile | Keep Last | 1 |
147
+ | 相机内参 | Reliable | Transient Local | Keep Last | 1 |
148
+
149
+ ---
150
+
151
+ ## 调试工具
152
+
153
+ ```bash
154
+ # 查看话题数据
155
+ ros2 topic echo /scan --no-arr
156
+ ros2 topic hz /velodyne_points
157
+
158
+ # RViz2 可视化
159
+ rviz2 -d perception.rviz
160
+
161
+ # 录制 rosbag
162
+ ros2 bag record /scan /velodyne_points /camera/image_raw
163
+
164
+ # 回放
165
+ ros2 bag play <bag_file>
166
+ ```
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: ros2-upper-app
3
+ description: ROS2 上层应用集成域。Launch 编排、参数配置、RViz 可视化、Python 节点、Gazebo/Ignition 仿真。当用户提到 launch 文件、launch.py、参数 YAML、RViz、URDF 显示、Python 节点、rclpy、Gazebo、Ignition 仿真、机器人状态发布时使用。
4
+ user-invocable: false
5
+ category: domain
6
+ ---
7
+
8
+ # ROS2 上层应用集成域
9
+
10
+ ## 域定位
11
+
12
+ 负责 ROS2 系统的**上层编排与可视化**——把各个底层节点(感知/控制/驱动)串成可启动、可配置、可视化、可仿真的整体。
13
+
14
+ **Authority Model**: Antigravity 优先(默认),Gemini 备选。
15
+
16
+ ## 子技能索引
17
+
18
+ | 子技能 | 职责 | 触发关键词 |
19
+ |--------|------|------------|
20
+ | [launch-files.md](./launch-files.md) | Launch 文件编排 | launch, launch.py, IncludeLaunchDescription, launch_arguments |
21
+ | [parameters.md](./parameters.md) | 参数 YAML / declare_parameter | params.yaml, ros__parameters, declare_parameter, override |
22
+ | [rviz-config.md](./rviz-config.md) | RViz 可视化配置 | rviz, rviz2, .rviz config, displays, fixed frame, TF tree |
23
+ | [python-nodes.md](./python-nodes.md) | rclpy 节点开发 | rclpy, Python node, async, MultiThreadedExecutor, callback group |
24
+ | [simulation.md](./simulation.md) | Gazebo / Ignition 仿真 | gazebo, gz, ignition, sdf, world, robot_state_publisher, controller spawner |
25
+
26
+ ## 与其他 ROS2 域的关系
27
+
28
+ ```
29
+ ┌─────────────────────────────┐
30
+ │ ros2-upper-app(本域) │ ← Antigravity 主导
31
+ │ Launch / Params / Viz │
32
+ └──────────┬──────────────────┘
33
+ │ 启动并连接
34
+
35
+ ┌──────────────────────────────────────────────┐
36
+ │ ros2-perception / control / navigation / │ ← Codex 主导
37
+ │ manipulation / hardware │
38
+ └──────────────────────────────────────────────┘
39
+ ```
40
+
41
+ - 本域负责 **how to compose**(如何组装)
42
+ - 其他 ROS2 域负责 **what to compute**(算什么)
43
+
44
+ ## 通用约束
45
+
46
+ - 路径不要硬编码 — 用 `FindPackageShare` + `PathJoinSubstitution`
47
+ - 参数不要散落在 launch 中 — 集中到 `config/*.yaml`
48
+ - 节点命名空间显式声明 — 多机器人场景下避免冲突
49
+ - TF tree 单根原则 — 全系统只有一个根 frame(通常是 `map` 或 `odom`)
50
+ - `use_sim_time` 在仿真场景必须显式传递到所有节点
@@ -0,0 +1,224 @@
1
+ # ROS2 Launch 文件编排
2
+
3
+ ## 何时使用
4
+
5
+ - 启动单节点(`Node`)
6
+ - 多节点编排,带启动顺序、条件、重映射
7
+ - 复用其他 launch 文件(`IncludeLaunchDescription`)
8
+ - 接收命令行参数 / 从 YAML 读取参数
9
+
10
+ ## 标准 launch.py 模板
11
+
12
+ ```python
13
+ from launch import LaunchDescription
14
+ from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, GroupAction
15
+ from launch.conditions import IfCondition, UnlessCondition
16
+ from launch.launch_description_sources import PythonLaunchDescriptionSource
17
+ from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, TextSubstitution
18
+ from launch_ros.actions import Node, PushRosNamespace
19
+ from launch_ros.substitutions import FindPackageShare
20
+
21
+
22
+ def generate_launch_description():
23
+ pkg_share = FindPackageShare('my_robot')
24
+
25
+ use_sim_time = LaunchConfiguration('use_sim_time')
26
+ namespace = LaunchConfiguration('namespace')
27
+ params_file = LaunchConfiguration('params_file')
28
+
29
+ declare_use_sim_time = DeclareLaunchArgument(
30
+ 'use_sim_time', default_value='false',
31
+ description='Use simulation (Gazebo) clock if true')
32
+
33
+ declare_namespace = DeclareLaunchArgument(
34
+ 'namespace', default_value='',
35
+ description='Top-level namespace')
36
+
37
+ declare_params = DeclareLaunchArgument(
38
+ 'params_file',
39
+ default_value=PathJoinSubstitution([pkg_share, 'config', 'params.yaml']),
40
+ description='Full path to the ROS2 parameters file')
41
+
42
+ bringup_group = GroupAction([
43
+ PushRosNamespace(namespace),
44
+
45
+ Node(
46
+ package='my_robot',
47
+ executable='controller_node',
48
+ name='controller',
49
+ parameters=[params_file, {'use_sim_time': use_sim_time}],
50
+ remappings=[
51
+ ('/cmd_vel', 'cmd_vel'),
52
+ ('/odom', 'odom'),
53
+ ],
54
+ output='screen',
55
+ emulate_tty=True,
56
+ ),
57
+
58
+ IncludeLaunchDescription(
59
+ PythonLaunchDescriptionSource(
60
+ PathJoinSubstitution([pkg_share, 'launch', 'sensors.launch.py'])),
61
+ launch_arguments={
62
+ 'use_sim_time': use_sim_time,
63
+ }.items(),
64
+ ),
65
+ ])
66
+
67
+ return LaunchDescription([
68
+ declare_use_sim_time,
69
+ declare_namespace,
70
+ declare_params,
71
+ bringup_group,
72
+ ])
73
+ ```
74
+
75
+ ## 关键 API
76
+
77
+ ### Node 参数
78
+
79
+ | 参数 | 用途 |
80
+ |------|------|
81
+ | `package` | ament 包名 |
82
+ | `executable` | `setup.py` 中 console_scripts 名,或 C++ 可执行文件名 |
83
+ | `name` | 节点运行时名(不写则用代码里的名) |
84
+ | `namespace` | 节点的 ROS namespace |
85
+ | `parameters` | 列表:dict / yaml 文件路径都可以 |
86
+ | `remappings` | `[(from, to), ...]` |
87
+ | `arguments` | 透传给 `argv` |
88
+ | `respawn` | 崩溃自动重启 |
89
+ | `output` | `screen`(打印到终端)/ `log`(写入日志) |
90
+ | `emulate_tty` | 让 RCLCPP_INFO 等日志保留颜色 |
91
+
92
+ ### 路径替换(永远不要硬编码)
93
+
94
+ ```python
95
+ # ❌ 错误
96
+ params=['/opt/ros/humble/share/my_pkg/config/params.yaml']
97
+
98
+ # ✅ 正确
99
+ PathJoinSubstitution([
100
+ FindPackageShare('my_pkg'), 'config', 'params.yaml'
101
+ ])
102
+ ```
103
+
104
+ ## 条件启动
105
+
106
+ ```python
107
+ from launch.conditions import IfCondition, UnlessCondition
108
+
109
+ Node(
110
+ package='rviz2', executable='rviz2',
111
+ condition=IfCondition(LaunchConfiguration('use_rviz')),
112
+ )
113
+
114
+ # CLI: ros2 launch my_robot bringup.launch.py use_rviz:=true
115
+ ```
116
+
117
+ ## 启动顺序与延迟
118
+
119
+ ```python
120
+ from launch.actions import TimerAction
121
+ from launch.event_handlers import OnProcessStart
122
+ from launch.actions import RegisterEventHandler
123
+
124
+ # 方案 A: 固定延时(简单但不优雅)
125
+ TimerAction(period=2.0, actions=[
126
+ Node(package='nav2_bringup', executable='bringup_launcher')
127
+ ])
128
+
129
+ # 方案 B: 事件驱动(推荐)
130
+ RegisterEventHandler(
131
+ OnProcessStart(
132
+ target_action=robot_state_publisher_node,
133
+ on_start=[
134
+ Node(package='controller_manager', executable='spawner',
135
+ arguments=['joint_state_broadcaster'])
136
+ ]
137
+ )
138
+ )
139
+ ```
140
+
141
+ ## 包含其他 launch
142
+
143
+ ### Python launch
144
+
145
+ ```python
146
+ IncludeLaunchDescription(
147
+ PythonLaunchDescriptionSource(
148
+ PathJoinSubstitution([FindPackageShare('nav2_bringup'),
149
+ 'launch', 'bringup_launch.py'])),
150
+ launch_arguments={'use_sim_time': 'true'}.items(),
151
+ )
152
+ ```
153
+
154
+ ### XML launch(老式)
155
+
156
+ ```python
157
+ from launch.launch_description_sources import FrontendLaunchDescriptionSource
158
+
159
+ IncludeLaunchDescription(
160
+ FrontendLaunchDescriptionSource(
161
+ PathJoinSubstitution([FindPackageShare('legacy_pkg'),
162
+ 'launch', 'old.launch.xml']))
163
+ )
164
+ ```
165
+
166
+ ## 多机器人 / 命名空间
167
+
168
+ ```python
169
+ robots = [
170
+ {'name': 'robot1', 'x': '0', 'y': '0'},
171
+ {'name': 'robot2', 'x': '2', 'y': '0'},
172
+ ]
173
+
174
+ actions = []
175
+ for r in robots:
176
+ actions.append(GroupAction([
177
+ PushRosNamespace(r['name']),
178
+ Node(package='my_robot', executable='controller', name='controller'),
179
+ ]))
180
+ ```
181
+
182
+ ## install 配置(否则 launch 找不到)
183
+
184
+ `CMakeLists.txt`(ament_cmake 包):
185
+ ```cmake
186
+ install(DIRECTORY launch config rviz urdf
187
+ DESTINATION share/${PROJECT_NAME})
188
+ ```
189
+
190
+ `setup.py`(ament_python 包):
191
+ ```python
192
+ data_files=[
193
+ ('share/' + package_name, ['package.xml']),
194
+ (os.path.join('share', package_name, 'launch'),
195
+ glob('launch/*.launch.py')),
196
+ (os.path.join('share', package_name, 'config'),
197
+ glob('config/*.yaml')),
198
+ ],
199
+ ```
200
+
201
+ ## 调试
202
+
203
+ ```bash
204
+ # 列出所有可用 launch
205
+ ros2 pkg list | xargs -I{} ros2 launch --show-args {} 2>/dev/null
206
+
207
+ # 看 launch 实际展开成什么节点
208
+ ros2 launch my_robot bringup.launch.py --show-args
209
+
210
+ # 启动后查看节点拓扑
211
+ ros2 node list
212
+ ros2 node info /controller
213
+ ros2 topic list -t
214
+ ```
215
+
216
+ ## 常见反模式
217
+
218
+ | 反模式 | 问题 | 修复 |
219
+ |--------|------|------|
220
+ | 路径硬编码 | 装载到其他机器或 colcon 构建后失效 | `FindPackageShare` |
221
+ | 参数散落 launch 各处 | 难以从外部覆盖,难审计 | 集中到 `config/*.yaml` |
222
+ | 节点重启策略缺失 | 单节点崩溃整个系统挂 | `respawn=True` + 上限 |
223
+ | `use_sim_time` 不传递 | 仿真时间不一致,TF 错乱 | 顶层 LaunchConfiguration 透传到所有 Node |
224
+ | 多 launch 重复 declare 同名参数 | 后者覆盖前者,行为难以预测 | 顶层 declare,子 launch 通过 launch_arguments 接收 |
@@ -0,0 +1,192 @@
1
+ # ROS2 参数体系
2
+
3
+ ## 参数三层模型
4
+
5
+ ```
6
+ [CLI / launch override] 最高优先级
7
+
8
+ [YAML params_file] 中等
9
+
10
+ [declare_parameter 默认值] 最低
11
+ ```
12
+
13
+ ## YAML 标准格式
14
+
15
+ ### 节点完整名(/ namespace + 节点名)
16
+
17
+ ```yaml
18
+ # config/params.yaml
19
+ controller:
20
+ ros__parameters:
21
+ max_speed: 1.0
22
+ safe_distance: 0.5
23
+ enabled_features:
24
+ - lidar
25
+ - imu
26
+
27
+ /robot1/controller:
28
+ ros__parameters:
29
+ max_speed: 0.8
30
+
31
+ # 通配符(rclcpp_components / 多节点共享)
32
+ "/**":
33
+ ros__parameters:
34
+ use_sim_time: false
35
+ ```
36
+
37
+ ### 嵌套参数(reflected as dotted keys)
38
+
39
+ ```yaml
40
+ controller:
41
+ ros__parameters:
42
+ pid:
43
+ kp: 1.0
44
+ ki: 0.1
45
+ kd: 0.01
46
+ ```
47
+
48
+ 代码中读:`this->get_parameter("pid.kp")`
49
+
50
+ ## 节点端声明
51
+
52
+ ### C++
53
+
54
+ ```cpp
55
+ class Controller : public rclcpp::Node {
56
+ public:
57
+ Controller() : Node("controller") {
58
+ this->declare_parameter<double>("max_speed", 1.0);
59
+ this->declare_parameter<double>("safe_distance", 0.5);
60
+ this->declare_parameter<std::vector<std::string>>("enabled_features", {});
61
+
62
+ max_speed_ = this->get_parameter("max_speed").as_double();
63
+ enabled_ = this->get_parameter("enabled_features").as_string_array();
64
+
65
+ // 监听运行时变化
66
+ param_cb_handle_ = this->add_on_set_parameters_callback(
67
+ [this](const std::vector<rclcpp::Parameter>& params) {
68
+ rcl_interfaces::msg::SetParametersResult result;
69
+ result.successful = true;
70
+ for (const auto& p : params) {
71
+ if (p.get_name() == "max_speed") {
72
+ if (p.as_double() < 0) {
73
+ result.successful = false;
74
+ result.reason = "max_speed must be >= 0";
75
+ } else {
76
+ max_speed_ = p.as_double();
77
+ }
78
+ }
79
+ }
80
+ return result;
81
+ });
82
+ }
83
+
84
+ private:
85
+ double max_speed_;
86
+ std::vector<std::string> enabled_;
87
+ OnSetParametersCallbackHandle::SharedPtr param_cb_handle_;
88
+ };
89
+ ```
90
+
91
+ ### Python
92
+
93
+ ```python
94
+ from rcl_interfaces.msg import SetParametersResult
95
+
96
+ class Controller(Node):
97
+ def __init__(self):
98
+ super().__init__('controller')
99
+
100
+ self.declare_parameter('max_speed', 1.0)
101
+ self.declare_parameter('safe_distance', 0.5)
102
+ self.declare_parameter('enabled_features', [])
103
+
104
+ self.max_speed = self.get_parameter('max_speed').value
105
+
106
+ self.add_on_set_parameters_callback(self.on_param_change)
107
+
108
+ def on_param_change(self, params):
109
+ for p in params:
110
+ if p.name == 'max_speed':
111
+ if p.value < 0:
112
+ return SetParametersResult(
113
+ successful=False, reason='must be >= 0')
114
+ self.max_speed = p.value
115
+ return SetParametersResult(successful=True)
116
+ ```
117
+
118
+ ## 参数描述符(强约束 + 文档化)
119
+
120
+ ```cpp
121
+ auto descriptor = rcl_interfaces::msg::ParameterDescriptor();
122
+ descriptor.description = "Maximum linear speed in m/s";
123
+
124
+ rcl_interfaces::msg::FloatingPointRange range;
125
+ range.from_value = 0.0;
126
+ range.to_value = 5.0;
127
+ descriptor.floating_point_range.push_back(range);
128
+
129
+ this->declare_parameter("max_speed", 1.0, descriptor);
130
+ ```
131
+
132
+ 效果:`ros2 param set` 超出 [0, 5] 直接拒绝。
133
+
134
+ ## CLI 操作
135
+
136
+ ```bash
137
+ # 列出节点参数
138
+ ros2 param list /controller
139
+
140
+ # 读
141
+ ros2 param get /controller max_speed
142
+
143
+ # 写
144
+ ros2 param set /controller max_speed 0.8
145
+
146
+ # 整体 dump
147
+ ros2 param dump /controller > current.yaml
148
+
149
+ # 整体 load
150
+ ros2 param load /controller params.yaml
151
+ ```
152
+
153
+ ## 在 Launch 中加载
154
+
155
+ ```python
156
+ Node(
157
+ package='my_robot',
158
+ executable='controller_node',
159
+ name='controller',
160
+ parameters=[
161
+ # 1. 来自 YAML
162
+ PathJoinSubstitution([FindPackageShare('my_robot'),
163
+ 'config', 'params.yaml']),
164
+ # 2. 命令行覆盖单项
165
+ {'max_speed': LaunchConfiguration('max_speed')},
166
+ # 3. 强制 use_sim_time
167
+ {'use_sim_time': use_sim_time},
168
+ ],
169
+ )
170
+ ```
171
+
172
+ 注意:**列表后面的覆盖前面的**。
173
+
174
+ ## 命名约定
175
+
176
+ | 类型 | 风格 |
177
+ |------|------|
178
+ | 简单标量 | `snake_case`: `max_speed` |
179
+ | 嵌套组 | `pid.kp`, `pid.ki` |
180
+ | 频率 | `update_rate_hz` (单位写在名里) |
181
+ | 启用开关 | `enable_<feature>` 或 `<feature>.enabled` |
182
+ | 阈值 | `min_<x>` / `max_<x>` / `<x>_threshold` |
183
+
184
+ ## 反模式
185
+
186
+ | 反模式 | 后果 |
187
+ |--------|------|
188
+ | 不 declare 直接 get | 抛 `ParameterNotDeclaredException` |
189
+ | 在构造函数读完就忘了 | 运行时改参数无效 — 用 set 回调 |
190
+ | 不同节点参数命名风格混乱 | 难维护、难审计 |
191
+ | 把硬件路径写死(`/dev/ttyUSB0`) | udev 编号变化即崩 — 改成参数 + udev rules |
192
+ | 把超大数据(图像、点云)塞参数 | 参数服务器不是为大数据设计的 — 用 topic |