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.
- package/README.md +211 -96
- package/README.zh-CN.md +256 -0
- package/dist/cli.mjs +15 -15
- package/dist/index.d.mts +61 -34
- package/dist/index.d.ts +61 -34
- package/dist/index.mjs +4 -4
- package/dist/shared/ccg-ros2-workflow.Bhm8c7P1.mjs +5154 -0
- package/package.json +31 -12
- package/templates/codex/AGENTS.md +348 -0
- package/templates/codex/agents/ccg-implement.toml +73 -0
- package/templates/codex/agents/ccg-research.toml +73 -0
- package/templates/codex/agents/ccg-review.toml +82 -0
- package/templates/codex/config.toml +21 -0
- package/templates/codex/hooks/ccg-workflow.py +253 -0
- package/templates/codex/hooks.json +15 -0
- package/templates/commands/agents/planner.md +97 -122
- package/templates/commands/agents/system-integrator.md +2 -2
- package/templates/commands/agents/team-architect.md +97 -0
- package/templates/commands/agents/team-qa.md +121 -0
- package/templates/commands/agents/team-reviewer.md +112 -0
- package/templates/commands/commit.md +30 -1
- package/templates/commands/context.md +332 -0
- package/templates/commands/go.md +206 -0
- package/templates/commands/init.md +1 -1
- package/templates/commands/spec-impl.md +41 -21
- package/templates/commands/spec-init.md +21 -27
- package/templates/commands/spec-plan.md +54 -21
- package/templates/commands/spec-research.md +78 -26
- package/templates/commands/spec-review.md +20 -16
- package/templates/{commands → commands-legacy}/analyze.md +1 -1
- package/templates/commands-legacy/backend.md +224 -0
- package/templates/commands-legacy/codex-exec.md +411 -0
- package/templates/{commands → commands-legacy}/debug.md +1 -1
- package/templates/commands-legacy/enhance.md +55 -0
- package/templates/{commands → commands-legacy}/feat.md +2 -2
- package/templates/commands-legacy/frontend.md +213 -0
- package/templates/{commands → commands-legacy}/optimize.md +1 -1
- package/templates/{commands → commands-legacy}/plan.md +1 -15
- package/templates/{commands → commands-legacy}/team-plan.md +1 -1
- package/templates/commands-legacy/team.md +475 -0
- package/templates/{commands → commands-legacy}/test.md +1 -1
- package/templates/commands-legacy/workflow.md +283 -0
- package/templates/engine/model-router.md +123 -0
- package/templates/engine/phase-guide.md +207 -0
- package/templates/engine/strategies/debug-investigate.md +169 -0
- package/templates/engine/strategies/deep-research.md +141 -0
- package/templates/engine/strategies/direct-fix.md +108 -0
- package/templates/engine/strategies/full-collaborate.md +389 -0
- package/templates/engine/strategies/git-action.md +43 -0
- package/templates/engine/strategies/guided-develop.md +282 -0
- package/templates/engine/strategies/optimize-measure.md +103 -0
- package/templates/engine/strategies/quick-implement.md +96 -0
- package/templates/engine/strategies/refactor-safely.md +180 -0
- package/templates/engine/strategies/review-audit.md +123 -0
- package/templates/hooks/session-start.js +100 -0
- package/templates/hooks/skill-router.js +144 -0
- package/templates/hooks/subagent-context.js +161 -0
- package/templates/hooks/task-utils.js +190 -0
- package/templates/hooks/workflow-state.js +55 -0
- package/templates/output-styles/abyss-command.md +56 -0
- package/templates/output-styles/abyss-concise.md +89 -0
- package/templates/output-styles/abyss-ritual.md +70 -0
- package/templates/output-styles/engineer-professional.md +20 -3
- package/templates/output-styles/laowang-engineer.md +2 -2
- package/templates/prompts/antigravity/analyzer.md +59 -0
- package/templates/prompts/antigravity/architect.md +55 -0
- package/templates/prompts/antigravity/builder.md +52 -0
- package/templates/prompts/antigravity/debugger.md +48 -0
- package/templates/prompts/antigravity/frontend.md +50 -0
- package/templates/prompts/antigravity/optimizer.md +40 -0
- package/templates/prompts/antigravity/reviewer.md +67 -0
- package/templates/prompts/antigravity/tester.md +39 -0
- package/templates/prompts/claude/debugger.md +1 -1
- package/templates/prompts/claude/reviewer.md +1 -1
- package/templates/prompts/codex/analyzer.md +8 -0
- package/templates/prompts/codex/architect.md +9 -1
- package/templates/prompts/codex/builder.md +61 -0
- package/templates/prompts/codex/debugger.md +9 -1
- package/templates/prompts/codex/optimizer.md +7 -0
- package/templates/prompts/codex/reviewer.md +7 -0
- package/templates/prompts/codex/tester.md +8 -1
- package/templates/prompts/gemini/analyzer.md +11 -3
- package/templates/prompts/gemini/architect.md +10 -2
- package/templates/prompts/gemini/debugger.md +8 -0
- package/templates/prompts/gemini/frontend.md +10 -2
- package/templates/prompts/gemini/optimizer.md +9 -2
- package/templates/prompts/gemini/reviewer.md +7 -0
- package/templates/prompts/gemini/tester.md +8 -1
- package/templates/rules/ccg-skill-routing.md +91 -0
- package/templates/rules/ccg-skills.md +65 -0
- package/templates/skills/SKILL.md +92 -0
- package/templates/skills/domains/ai/SKILL.md +34 -0
- package/templates/skills/domains/ai/agent-dev.md +242 -0
- package/templates/skills/domains/ai/llm-security.md +288 -0
- package/templates/skills/domains/ai/prompt-and-eval.md +279 -0
- package/templates/skills/domains/ai/rag-system.md +542 -0
- package/templates/skills/domains/architecture/SKILL.md +42 -0
- package/templates/skills/domains/architecture/api-design.md +225 -0
- package/templates/skills/domains/architecture/caching.md +299 -0
- package/templates/skills/domains/architecture/cloud-native.md +285 -0
- package/templates/skills/domains/architecture/message-queue.md +329 -0
- package/templates/skills/domains/architecture/security-arch.md +297 -0
- package/templates/skills/domains/data-engineering/SKILL.md +207 -0
- package/templates/skills/domains/development/SKILL.md +46 -0
- package/templates/skills/domains/development/cpp.md +369 -0
- package/templates/skills/domains/development/go.md +323 -0
- package/templates/skills/domains/development/java.md +277 -0
- package/templates/skills/domains/development/python.md +487 -0
- package/templates/skills/domains/development/rust.md +313 -0
- package/templates/skills/domains/development/shell.md +313 -0
- package/templates/skills/domains/development/typescript.md +277 -0
- package/templates/skills/domains/devops/SKILL.md +39 -0
- package/templates/skills/domains/devops/cost-optimization.md +272 -0
- package/templates/skills/domains/devops/database.md +217 -0
- package/templates/skills/domains/devops/devsecops.md +198 -0
- package/templates/skills/domains/devops/git-workflow.md +181 -0
- package/templates/skills/domains/devops/observability.md +280 -0
- package/templates/skills/domains/devops/performance.md +336 -0
- package/templates/skills/domains/devops/testing.md +283 -0
- package/templates/skills/domains/infrastructure/SKILL.md +200 -0
- package/templates/skills/domains/mobile/SKILL.md +224 -0
- package/templates/skills/domains/orchestration/SKILL.md +29 -0
- package/templates/skills/domains/orchestration/multi-agent.md +263 -0
- package/templates/skills/domains/ros2-control/SKILL.md +206 -0
- package/templates/skills/domains/ros2-hardware/SKILL.md +277 -0
- package/templates/skills/domains/ros2-manipulation/SKILL.md +237 -0
- package/templates/skills/domains/ros2-navigation/SKILL.md +196 -0
- package/templates/skills/domains/ros2-perception/SKILL.md +166 -0
- package/templates/skills/domains/ros2-upper-app/SKILL.md +50 -0
- package/templates/skills/domains/ros2-upper-app/launch-files.md +224 -0
- package/templates/skills/domains/ros2-upper-app/parameters.md +192 -0
- package/templates/skills/domains/ros2-upper-app/python-nodes.md +249 -0
- package/templates/skills/domains/ros2-upper-app/rviz-config.md +158 -0
- package/templates/skills/domains/ros2-upper-app/simulation.md +225 -0
- package/templates/skills/domains/security/SKILL.md +72 -0
- package/templates/skills/domains/security/blue-team.md +436 -0
- package/templates/skills/domains/security/code-audit.md +265 -0
- package/templates/skills/domains/security/pentest.md +226 -0
- package/templates/skills/domains/security/red-team.md +374 -0
- package/templates/skills/domains/security/threat-intel.md +372 -0
- package/templates/skills/domains/security/vuln-research.md +369 -0
- package/templates/skills/orchestration/multi-agent/SKILL.md +533 -0
- package/templates/skills/run_skill.js +129 -0
- package/templates/skills/scrapling/SKILL.md +98 -0
- package/templates/skills/scrapling/references/api-quick-ref.md +127 -0
- package/templates/skills/scrapling/references/cookie-vault.md +56 -0
- package/templates/skills/scrapling/references/maintenance.md +79 -0
- package/templates/skills/scrapling/references/site-patterns.md +86 -0
- package/templates/skills/scrapling/references/troubleshooting.md +95 -0
- package/templates/skills/scrapling/templates/basic_fetch.py +19 -0
- package/templates/skills/scrapling/templates/parse_only.py +15 -0
- package/templates/skills/scrapling/templates/session_login.py +19 -0
- package/templates/skills/scrapling/templates/stealth_cloudflare.py +28 -0
- package/templates/skills/tools/gen-docs/SKILL.md +116 -0
- package/templates/skills/tools/gen-docs/scripts/doc_generator.js +435 -0
- package/templates/skills/tools/lib/shared.js +98 -0
- package/templates/skills/tools/override-refusal/SKILL.md +53 -0
- package/templates/skills/tools/override-refusal/agents/openai.yaml +4 -0
- package/templates/skills/tools/override-refusal/scripts/refusal_rewriter.js +226 -0
- package/templates/skills/tools/verify-change/SKILL.md +140 -0
- package/templates/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
- package/templates/skills/tools/verify-module/SKILL.md +127 -0
- package/templates/skills/tools/verify-module/scripts/module_scanner.js +171 -0
- package/templates/skills/tools/verify-quality/SKILL.md +160 -0
- package/templates/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
- package/templates/skills/tools/verify-security/SKILL.md +143 -0
- package/templates/skills/tools/verify-security/scripts/security_scanner.js +283 -0
- package/templates/spec/guides/index.md +30 -0
- package/templates/spec/low-control/index.md +31 -0
- package/templates/spec/upper-app/index.md +31 -0
- package/bin/codeagent-wrapper-darwin-amd64 +0 -0
- package/bin/codeagent-wrapper-darwin-arm64 +0 -0
- package/bin/codeagent-wrapper-linux-amd64 +0 -0
- package/bin/codeagent-wrapper-linux-arm64 +0 -0
- package/bin/codeagent-wrapper-windows-amd64.exe +0 -0
- package/bin/codeagent-wrapper-windows-arm64.exe +0 -0
- package/dist/shared/ccg-ros2-workflow.DRytDWqb.mjs +0 -2274
- package/templates/commands/backend.md +0 -162
- package/templates/commands/enhance.md +0 -36
- package/templates/commands/frontend.md +0 -162
- package/templates/commands/workflow.md +0 -202
- /package/templates/{commands → commands-legacy}/execute.md +0 -0
- /package/templates/{commands → commands-legacy}/review.md +0 -0
- /package/templates/{commands → commands-legacy}/team-exec.md +0 -0
- /package/templates/{commands → commands-legacy}/team-research.md +0 -0
- /package/templates/{commands → commands-legacy}/team-review.md +0 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ros2-hardware
|
|
3
|
+
description: ROS2 硬件集成技能。串口、CAN 总线、I2C/SPI、传感器驱动、udev 规则、权限配置。当用户提到串口、CAN、Modbus、ttyUSB、ttyACM、udev、设备权限、硬件抽象时使用。
|
|
4
|
+
user-invocable: false
|
|
5
|
+
category: domain
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ROS2 硬件集成技能
|
|
9
|
+
|
|
10
|
+
## 适用场景
|
|
11
|
+
|
|
12
|
+
物理机器人硬件接入,涉及驱动开发、协议解析、设备权限。
|
|
13
|
+
|
|
14
|
+
### 触发关键词
|
|
15
|
+
|
|
16
|
+
- 串口 / Serial / RS232 / RS485 / ttyUSB / ttyACM
|
|
17
|
+
- CAN / SocketCAN / can0 / candump / cansend
|
|
18
|
+
- I2C / SPI / GPIO
|
|
19
|
+
- USB / udev / 设备权限
|
|
20
|
+
- Modbus / Modbus RTU / Modbus TCP
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 串口通信
|
|
25
|
+
|
|
26
|
+
### ROS2 推荐库:`serial_driver` (transport_drivers)
|
|
27
|
+
|
|
28
|
+
```cpp
|
|
29
|
+
#include <io_context/io_context.hpp>
|
|
30
|
+
#include <serial_driver/serial_driver.hpp>
|
|
31
|
+
|
|
32
|
+
using drivers::common::IoContext;
|
|
33
|
+
using drivers::serial_driver::SerialDriver;
|
|
34
|
+
using drivers::serial_driver::SerialPortConfig;
|
|
35
|
+
|
|
36
|
+
IoContext ctx(2);
|
|
37
|
+
SerialPortConfig config(115200, // baud_rate
|
|
38
|
+
drivers::serial_driver::FlowControl::NONE,
|
|
39
|
+
drivers::serial_driver::Parity::NONE,
|
|
40
|
+
drivers::serial_driver::StopBits::ONE);
|
|
41
|
+
auto driver = std::make_unique<SerialDriver>(ctx);
|
|
42
|
+
driver->init_port("/dev/ttyUSB0", config);
|
|
43
|
+
driver->port()->open();
|
|
44
|
+
|
|
45
|
+
driver->port()->async_receive([](const std::vector<uint8_t>& buffer, size_t bytes_transferred) {
|
|
46
|
+
// 处理接收数据
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
std::vector<uint8_t> data{0xAA, 0x55};
|
|
50
|
+
driver->port()->async_send(data);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 简单方案:Python pyserial
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import serial
|
|
57
|
+
|
|
58
|
+
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1.0)
|
|
59
|
+
ser.write(b'\xAA\x55')
|
|
60
|
+
data = ser.read(8)
|
|
61
|
+
ser.close()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## CAN 总线
|
|
67
|
+
|
|
68
|
+
### SocketCAN 配置
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# 启用 CAN0
|
|
72
|
+
sudo ip link set can0 up type can bitrate 1000000
|
|
73
|
+
|
|
74
|
+
# 检查状态
|
|
75
|
+
ip -details link show can0
|
|
76
|
+
|
|
77
|
+
# 抓包调试
|
|
78
|
+
candump can0
|
|
79
|
+
cansend can0 100#1122334455667788
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### ROS2 推荐:`ros2_socketcan`
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
ros2 launch ros2_socketcan socket_can_bridge.launch.xml \
|
|
86
|
+
interface:=can0
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
发布的话题:
|
|
90
|
+
- `/from_can_bus` (can_msgs/Frame): 接收的 CAN 帧
|
|
91
|
+
- `/to_can_bus` (can_msgs/Frame): 发送的 CAN 帧
|
|
92
|
+
|
|
93
|
+
### C++ SocketCAN 直接调用
|
|
94
|
+
|
|
95
|
+
```cpp
|
|
96
|
+
#include <linux/can.h>
|
|
97
|
+
#include <linux/can/raw.h>
|
|
98
|
+
#include <sys/ioctl.h>
|
|
99
|
+
#include <net/if.h>
|
|
100
|
+
|
|
101
|
+
int sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
|
|
102
|
+
struct ifreq ifr;
|
|
103
|
+
strcpy(ifr.ifr_name, "can0");
|
|
104
|
+
ioctl(sock, SIOCGIFINDEX, &ifr);
|
|
105
|
+
|
|
106
|
+
struct sockaddr_can addr = {};
|
|
107
|
+
addr.can_family = AF_CAN;
|
|
108
|
+
addr.can_ifindex = ifr.ifr_ifindex;
|
|
109
|
+
bind(sock, (struct sockaddr*)&addr, sizeof(addr));
|
|
110
|
+
|
|
111
|
+
struct can_frame frame;
|
|
112
|
+
read(sock, &frame, sizeof(frame)); // 阻塞接收
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## udev 规则(关键!)
|
|
118
|
+
|
|
119
|
+
避免 `/dev/ttyUSB0` 编号变化导致驱动失效。
|
|
120
|
+
|
|
121
|
+
### 创建规则文件
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
sudo nano /etc/udev/rules.d/99-my-robot.rules
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
# RPLidar A2
|
|
129
|
+
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \
|
|
130
|
+
MODE="0666", SYMLINK+="rplidar"
|
|
131
|
+
|
|
132
|
+
# 电机驱动
|
|
133
|
+
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
|
|
134
|
+
ATTRS{serial}=="A12345", MODE="0666", SYMLINK+="motor_driver"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 重载规则
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
sudo udevadm control --reload-rules
|
|
141
|
+
sudo udevadm trigger
|
|
142
|
+
ls -l /dev/rplidar # 验证 symlink
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 查询设备信息
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# 查看 USB 设备 vendor/product ID
|
|
149
|
+
lsusb
|
|
150
|
+
|
|
151
|
+
# 查看串口完整属性
|
|
152
|
+
udevadm info -a -n /dev/ttyUSB0
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 设备权限
|
|
158
|
+
|
|
159
|
+
### 添加用户到 dialout 组(串口)
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
sudo usermod -aG dialout $USER
|
|
163
|
+
# 重新登录生效
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### CAN 用户权限
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
sudo usermod -aG can $USER
|
|
170
|
+
# 或在 udev 规则中设置 GROUP="can"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## I2C / SPI
|
|
176
|
+
|
|
177
|
+
### Linux i2c-tools
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
sudo apt install i2c-tools
|
|
181
|
+
i2cdetect -y 1 # 扫描总线 1
|
|
182
|
+
i2cget -y 1 0x68 0x75 # 读寄存器
|
|
183
|
+
i2cset -y 1 0x68 0x6B 0x00 # 写寄存器
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### ROS2 节点示例 (libi2c-dev)
|
|
187
|
+
|
|
188
|
+
```cpp
|
|
189
|
+
#include <fcntl.h>
|
|
190
|
+
#include <linux/i2c-dev.h>
|
|
191
|
+
#include <sys/ioctl.h>
|
|
192
|
+
|
|
193
|
+
int fd = open("/dev/i2c-1", O_RDWR);
|
|
194
|
+
ioctl(fd, I2C_SLAVE, 0x68); // IMU 地址
|
|
195
|
+
|
|
196
|
+
uint8_t reg = 0x3B;
|
|
197
|
+
write(fd, ®, 1);
|
|
198
|
+
uint8_t buf[14];
|
|
199
|
+
read(fd, buf, 14);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 硬件抽象层 (HAL) 设计
|
|
205
|
+
|
|
206
|
+
### 接口模式
|
|
207
|
+
|
|
208
|
+
```cpp
|
|
209
|
+
class HardwareInterface {
|
|
210
|
+
public:
|
|
211
|
+
virtual ~HardwareInterface() = default;
|
|
212
|
+
virtual bool connect() = 0;
|
|
213
|
+
virtual bool disconnect() = 0;
|
|
214
|
+
virtual bool read(uint8_t* data, size_t len) = 0;
|
|
215
|
+
virtual bool write(const uint8_t* data, size_t len) = 0;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
class SerialHardware : public HardwareInterface { /* ... */ };
|
|
219
|
+
class CanHardware : public HardwareInterface { /* ... */ };
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 错误处理
|
|
223
|
+
|
|
224
|
+
```cpp
|
|
225
|
+
class HardwareDriver : public rclcpp::Node {
|
|
226
|
+
private:
|
|
227
|
+
void publish_diagnostic() {
|
|
228
|
+
diagnostic_msgs::msg::DiagnosticStatus status;
|
|
229
|
+
status.name = "Motor Driver";
|
|
230
|
+
if (!hw_->is_connected()) {
|
|
231
|
+
status.level = DiagnosticStatus::ERROR;
|
|
232
|
+
status.message = "Hardware disconnected";
|
|
233
|
+
} else {
|
|
234
|
+
status.level = DiagnosticStatus::OK;
|
|
235
|
+
}
|
|
236
|
+
diag_pub_->publish(status);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// 自动重连
|
|
240
|
+
void reconnect_loop() {
|
|
241
|
+
if (!hw_->is_connected()) {
|
|
242
|
+
RCLCPP_WARN(this->get_logger(), "Reconnecting...");
|
|
243
|
+
hw_->connect();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 调试工具
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# 串口
|
|
255
|
+
sudo apt install minicom screen
|
|
256
|
+
screen /dev/ttyUSB0 115200
|
|
257
|
+
|
|
258
|
+
# CAN
|
|
259
|
+
sudo apt install can-utils
|
|
260
|
+
candump -tz can0
|
|
261
|
+
cangen can0 -v # 生成测试帧
|
|
262
|
+
|
|
263
|
+
# 系统设备
|
|
264
|
+
dmesg | tail # 查看插拔日志
|
|
265
|
+
udevadm monitor # 实时监控 udev 事件
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 安全清单
|
|
271
|
+
|
|
272
|
+
- [ ] udev 规则避免设备编号漂移
|
|
273
|
+
- [ ] 软件层面的硬件超时检测
|
|
274
|
+
- [ ] 自动重连逻辑
|
|
275
|
+
- [ ] 硬件诊断话题 `/diagnostics`
|
|
276
|
+
- [ ] 急停按钮独立硬件回路(不经软件)
|
|
277
|
+
- [ ] 看门狗定时器(硬件级)
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ros2-manipulation
|
|
3
|
+
description: ROS2 机械臂操作技能。MoveIt 2、运动规划、抓取规划、逆运动学、笛卡尔规划。当用户提到 MoveIt、机械臂、抓取、IK、URDF、joint_trajectory、planning scene 时使用。
|
|
4
|
+
user-invocable: false
|
|
5
|
+
category: domain
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ROS2 机械臂操作技能
|
|
9
|
+
|
|
10
|
+
## 适用场景
|
|
11
|
+
|
|
12
|
+
机械臂运动规划、抓取、操作任务。
|
|
13
|
+
|
|
14
|
+
### 触发关键词
|
|
15
|
+
|
|
16
|
+
- MoveIt / MoveIt2 / move_group
|
|
17
|
+
- 机械臂 / manipulator / arm
|
|
18
|
+
- 抓取 / grasp / pick / place
|
|
19
|
+
- 逆运动学 / IK / FK / 运动学
|
|
20
|
+
- URDF / SRDF / xacro
|
|
21
|
+
- 轨迹 / trajectory / OMPL / CHOMP / STOMP
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## MoveIt 2 架构
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
[move_group] (核心节点)
|
|
29
|
+
├── [Planning Pipeline] (OMPL/CHOMP/STOMP)
|
|
30
|
+
├── [Planning Scene] (碰撞检测)
|
|
31
|
+
├── [Trajectory Execution] (FollowJointTrajectory Action)
|
|
32
|
+
└── [Robot State] (joint_states)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 启动 MoveIt 2
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ros2 launch <robot>_moveit_config demo.launch.py
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## URDF/SRDF 基础
|
|
44
|
+
|
|
45
|
+
### URDF 关键元素
|
|
46
|
+
|
|
47
|
+
```xml
|
|
48
|
+
<robot name="my_robot">
|
|
49
|
+
<link name="base_link">
|
|
50
|
+
<visual>
|
|
51
|
+
<geometry><cylinder length="0.1" radius="0.05"/></geometry>
|
|
52
|
+
</visual>
|
|
53
|
+
<collision>
|
|
54
|
+
<geometry><cylinder length="0.1" radius="0.05"/></geometry>
|
|
55
|
+
</collision>
|
|
56
|
+
<inertial>
|
|
57
|
+
<mass value="1.0"/>
|
|
58
|
+
<inertia ixx="0.01" iyy="0.01" izz="0.01" ixy="0" ixz="0" iyz="0"/>
|
|
59
|
+
</inertial>
|
|
60
|
+
</link>
|
|
61
|
+
|
|
62
|
+
<joint name="joint1" type="revolute">
|
|
63
|
+
<parent link="base_link"/>
|
|
64
|
+
<child link="link1"/>
|
|
65
|
+
<origin xyz="0 0 0.1" rpy="0 0 0"/>
|
|
66
|
+
<axis xyz="0 0 1"/>
|
|
67
|
+
<limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
|
|
68
|
+
</joint>
|
|
69
|
+
</robot>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### SRDF 规划组
|
|
73
|
+
|
|
74
|
+
```xml
|
|
75
|
+
<robot name="my_robot">
|
|
76
|
+
<group name="arm">
|
|
77
|
+
<chain base_link="base_link" tip_link="end_effector"/>
|
|
78
|
+
</group>
|
|
79
|
+
<group_state name="home" group="arm">
|
|
80
|
+
<joint name="joint1" value="0"/>
|
|
81
|
+
<joint name="joint2" value="-1.57"/>
|
|
82
|
+
</group_state>
|
|
83
|
+
</robot>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## C++ MoveIt 2 API
|
|
89
|
+
|
|
90
|
+
```cpp
|
|
91
|
+
#include <moveit/move_group_interface/move_group_interface.h>
|
|
92
|
+
|
|
93
|
+
auto move_group = std::make_shared<moveit::planning_interface::MoveGroupInterface>(
|
|
94
|
+
node, "arm");
|
|
95
|
+
|
|
96
|
+
// 设置目标位姿
|
|
97
|
+
geometry_msgs::msg::Pose target;
|
|
98
|
+
target.position.x = 0.5;
|
|
99
|
+
target.position.y = 0.0;
|
|
100
|
+
target.position.z = 0.5;
|
|
101
|
+
target.orientation.w = 1.0;
|
|
102
|
+
move_group->setPoseTarget(target);
|
|
103
|
+
|
|
104
|
+
// 规划
|
|
105
|
+
moveit::planning_interface::MoveGroupInterface::Plan plan;
|
|
106
|
+
auto success = (move_group->plan(plan) ==
|
|
107
|
+
moveit::core::MoveItErrorCode::SUCCESS);
|
|
108
|
+
|
|
109
|
+
if (success) {
|
|
110
|
+
move_group->execute(plan);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 笛卡尔路径
|
|
115
|
+
|
|
116
|
+
```cpp
|
|
117
|
+
std::vector<geometry_msgs::msg::Pose> waypoints;
|
|
118
|
+
waypoints.push_back(start_pose);
|
|
119
|
+
waypoints.push_back(mid_pose);
|
|
120
|
+
waypoints.push_back(end_pose);
|
|
121
|
+
|
|
122
|
+
moveit_msgs::msg::RobotTrajectory trajectory;
|
|
123
|
+
double fraction = move_group->computeCartesianPath(
|
|
124
|
+
waypoints, 0.01, 0.0, trajectory);
|
|
125
|
+
|
|
126
|
+
if (fraction > 0.95) {
|
|
127
|
+
move_group->execute(trajectory);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Python MoveIt 2 (pymoveit2)
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from pymoveit2 import MoveIt2
|
|
137
|
+
from rclpy.executors import MultiThreadedExecutor
|
|
138
|
+
|
|
139
|
+
moveit2 = MoveIt2(
|
|
140
|
+
node=node,
|
|
141
|
+
joint_names=["joint1", "joint2", "joint3"],
|
|
142
|
+
base_link_name="base_link",
|
|
143
|
+
end_effector_name="end_effector",
|
|
144
|
+
group_name="arm",
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# 关节空间运动
|
|
148
|
+
moveit2.move_to_configuration([0.0, -1.57, 0.0])
|
|
149
|
+
moveit2.wait_until_executed()
|
|
150
|
+
|
|
151
|
+
# 笛卡尔运动
|
|
152
|
+
moveit2.move_to_pose(
|
|
153
|
+
position=[0.5, 0.0, 0.5],
|
|
154
|
+
quat_xyzw=[0.0, 0.0, 0.0, 1.0],
|
|
155
|
+
cartesian=True,
|
|
156
|
+
)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 抓取规划
|
|
162
|
+
|
|
163
|
+
### Grasp Pose 生成
|
|
164
|
+
|
|
165
|
+
```cpp
|
|
166
|
+
moveit_msgs::msg::Grasp grasp;
|
|
167
|
+
grasp.grasp_pose.header.frame_id = "base_link";
|
|
168
|
+
grasp.grasp_pose.pose.position.x = 0.5;
|
|
169
|
+
grasp.grasp_pose.pose.position.y = 0.0;
|
|
170
|
+
grasp.grasp_pose.pose.position.z = 0.3;
|
|
171
|
+
|
|
172
|
+
// 接近
|
|
173
|
+
grasp.pre_grasp_approach.direction.vector.z = -1.0;
|
|
174
|
+
grasp.pre_grasp_approach.min_distance = 0.05;
|
|
175
|
+
grasp.pre_grasp_approach.desired_distance = 0.1;
|
|
176
|
+
|
|
177
|
+
// 抓取后撤
|
|
178
|
+
grasp.post_grasp_retreat.direction.vector.z = 1.0;
|
|
179
|
+
grasp.post_grasp_retreat.min_distance = 0.05;
|
|
180
|
+
grasp.post_grasp_retreat.desired_distance = 0.15;
|
|
181
|
+
|
|
182
|
+
move_group->pick("target_object", {grasp});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Planning Scene 管理
|
|
188
|
+
|
|
189
|
+
### 添加碰撞物体
|
|
190
|
+
|
|
191
|
+
```cpp
|
|
192
|
+
moveit_msgs::msg::CollisionObject obj;
|
|
193
|
+
obj.header.frame_id = "base_link";
|
|
194
|
+
obj.id = "table";
|
|
195
|
+
|
|
196
|
+
shape_msgs::msg::SolidPrimitive box;
|
|
197
|
+
box.type = box.BOX;
|
|
198
|
+
box.dimensions = {1.0, 1.0, 0.05};
|
|
199
|
+
obj.primitives.push_back(box);
|
|
200
|
+
|
|
201
|
+
geometry_msgs::msg::Pose pose;
|
|
202
|
+
pose.position.z = -0.025;
|
|
203
|
+
pose.orientation.w = 1.0;
|
|
204
|
+
obj.primitive_poses.push_back(pose);
|
|
205
|
+
|
|
206
|
+
obj.operation = obj.ADD;
|
|
207
|
+
|
|
208
|
+
moveit::planning_interface::PlanningSceneInterface psi;
|
|
209
|
+
psi.applyCollisionObject(obj);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 规划器对比
|
|
215
|
+
|
|
216
|
+
| 规划器 | 类型 | 特点 |
|
|
217
|
+
|--------|------|------|
|
|
218
|
+
| **OMPL/RRTConnect** | 采样 | 默认,快速找解 |
|
|
219
|
+
| **OMPL/RRTstar** | 采样 | 渐近最优 |
|
|
220
|
+
| **CHOMP** | 优化 | 平滑轨迹 |
|
|
221
|
+
| **STOMP** | 优化 | 处理硬约束 |
|
|
222
|
+
| **Pilz** | 工业 | 直线/圆弧/PTP |
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 调试
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# 可视化规划场景
|
|
230
|
+
rviz2 -d moveit.rviz
|
|
231
|
+
|
|
232
|
+
# 查看规划组
|
|
233
|
+
ros2 topic echo /move_group/planning_scene
|
|
234
|
+
|
|
235
|
+
# 监控执行状态
|
|
236
|
+
ros2 topic echo /joint_trajectory_controller/state
|
|
237
|
+
```
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ros2-navigation
|
|
3
|
+
description: ROS2 导航技能。Nav2 栈、SLAM、路径规划、costmap、全局/局部规划器。当用户提到 Nav2、SLAM、slam_toolbox、Cartographer、AMCL、costmap、规划器、navfn 时使用。
|
|
4
|
+
user-invocable: false
|
|
5
|
+
category: domain
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ROS2 导航技能
|
|
9
|
+
|
|
10
|
+
## 适用场景
|
|
11
|
+
|
|
12
|
+
机器人自主导航,从 SLAM 建图到 Nav2 路径规划。
|
|
13
|
+
|
|
14
|
+
### 触发关键词
|
|
15
|
+
|
|
16
|
+
- 导航 / Nav2 / navigation_stack
|
|
17
|
+
- SLAM / slam_toolbox / Cartographer / RTAB-Map
|
|
18
|
+
- 定位 / AMCL / 蒙特卡洛
|
|
19
|
+
- 地图 / map_server / OccupancyGrid
|
|
20
|
+
- 规划 / planner / Dijkstra / A* / DWB / Hybrid A*
|
|
21
|
+
- 代价地图 / costmap / 膨胀层 / 障碍层
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Nav2 栈架构
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
[BT Navigator] (行为树)
|
|
29
|
+
├── [Planner Server] (NavfnPlanner / SmacPlanner)
|
|
30
|
+
├── [Controller Server] (DWBController / RPP / MPPI)
|
|
31
|
+
├── [Recovery Server] (Spin / BackUp / Wait)
|
|
32
|
+
└── [Costmap 2D] (Global + Local)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 标准启动
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ros2 launch nav2_bringup bringup_launch.py \
|
|
39
|
+
map:=/path/to/map.yaml \
|
|
40
|
+
use_sim_time:=false \
|
|
41
|
+
params_file:=/path/to/nav2_params.yaml
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### nav2_params.yaml 关键配置
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
amcl:
|
|
48
|
+
ros__parameters:
|
|
49
|
+
use_sim_time: False
|
|
50
|
+
alpha1: 0.2
|
|
51
|
+
alpha2: 0.2
|
|
52
|
+
base_frame_id: "base_footprint"
|
|
53
|
+
odom_frame_id: "odom"
|
|
54
|
+
global_frame_id: "map"
|
|
55
|
+
laser_model_type: "likelihood_field"
|
|
56
|
+
max_particles: 2000
|
|
57
|
+
min_particles: 500
|
|
58
|
+
|
|
59
|
+
global_costmap:
|
|
60
|
+
global_costmap:
|
|
61
|
+
ros__parameters:
|
|
62
|
+
update_frequency: 1.0
|
|
63
|
+
publish_frequency: 1.0
|
|
64
|
+
global_frame: map
|
|
65
|
+
robot_base_frame: base_link
|
|
66
|
+
robot_radius: 0.22
|
|
67
|
+
resolution: 0.05
|
|
68
|
+
plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
|
|
69
|
+
obstacle_layer:
|
|
70
|
+
plugin: "nav2_costmap_2d::ObstacleLayer"
|
|
71
|
+
observation_sources: scan
|
|
72
|
+
scan:
|
|
73
|
+
topic: /scan
|
|
74
|
+
max_obstacle_height: 2.0
|
|
75
|
+
clearing: True
|
|
76
|
+
marking: True
|
|
77
|
+
data_type: "LaserScan"
|
|
78
|
+
inflation_layer:
|
|
79
|
+
plugin: "nav2_costmap_2d::InflationLayer"
|
|
80
|
+
cost_scaling_factor: 3.0
|
|
81
|
+
inflation_radius: 0.55
|
|
82
|
+
|
|
83
|
+
planner_server:
|
|
84
|
+
ros__parameters:
|
|
85
|
+
planner_plugins: ["GridBased"]
|
|
86
|
+
GridBased:
|
|
87
|
+
plugin: "nav2_navfn_planner/NavfnPlanner"
|
|
88
|
+
tolerance: 0.5
|
|
89
|
+
use_astar: false
|
|
90
|
+
allow_unknown: true
|
|
91
|
+
|
|
92
|
+
controller_server:
|
|
93
|
+
ros__parameters:
|
|
94
|
+
controller_frequency: 20.0
|
|
95
|
+
controller_plugins: ["FollowPath"]
|
|
96
|
+
FollowPath:
|
|
97
|
+
plugin: "dwb_core::DWBLocalPlanner"
|
|
98
|
+
min_vel_x: 0.0
|
|
99
|
+
max_vel_x: 0.5
|
|
100
|
+
max_vel_theta: 1.0
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## SLAM 选型
|
|
106
|
+
|
|
107
|
+
| 工具 | 适用场景 | 特点 |
|
|
108
|
+
|------|----------|------|
|
|
109
|
+
| **slam_toolbox** | 2D 室内 | 在线建图 + 离线优化,推荐 |
|
|
110
|
+
| **Cartographer** | 2D/3D 室内外 | Google 维护,稳定 |
|
|
111
|
+
| **RTAB-Map** | 3D + 视觉 | 视觉惯性,大场景 |
|
|
112
|
+
| **LIO-SAM** | 3D 户外 | 激光 + IMU 紧耦合 |
|
|
113
|
+
|
|
114
|
+
### slam_toolbox 启动
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
ros2 launch slam_toolbox online_async_launch.py \
|
|
118
|
+
use_sim_time:=false \
|
|
119
|
+
params_file:=/path/to/mapper_params.yaml
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 保存地图
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
ros2 run nav2_map_server map_saver_cli -f my_map
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 行为树 (BT)
|
|
131
|
+
|
|
132
|
+
### 自定义行为节点
|
|
133
|
+
|
|
134
|
+
```xml
|
|
135
|
+
<root main_tree_to_execute="MainTree">
|
|
136
|
+
<BehaviorTree ID="MainTree">
|
|
137
|
+
<RecoveryNode number_of_retries="6" name="NavigateRecovery">
|
|
138
|
+
<PipelineSequence name="NavigateWithReplanning">
|
|
139
|
+
<RateController hz="1.0">
|
|
140
|
+
<RecoveryNode number_of_retries="1" name="ComputePathToPose">
|
|
141
|
+
<ComputePathToPose goal="{goal}" path="{path}" planner_id="GridBased"/>
|
|
142
|
+
<ClearEntireCostmap name="ClearGlobalCostmap-Context"
|
|
143
|
+
service_name="global_costmap/clear_entirely_global_costmap"/>
|
|
144
|
+
</RecoveryNode>
|
|
145
|
+
</RateController>
|
|
146
|
+
<RecoveryNode number_of_retries="1" name="FollowPath">
|
|
147
|
+
<FollowPath path="{path}" controller_id="FollowPath"/>
|
|
148
|
+
<ClearEntireCostmap name="ClearLocalCostmap-Context"
|
|
149
|
+
service_name="local_costmap/clear_entirely_local_costmap"/>
|
|
150
|
+
</RecoveryNode>
|
|
151
|
+
</PipelineSequence>
|
|
152
|
+
</RecoveryNode>
|
|
153
|
+
</BehaviorTree>
|
|
154
|
+
</root>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 程序化导航
|
|
160
|
+
|
|
161
|
+
### Nav2 Action Client
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from nav2_simple_commander.robot_navigator import BasicNavigator
|
|
165
|
+
from geometry_msgs.msg import PoseStamped
|
|
166
|
+
|
|
167
|
+
navigator = BasicNavigator()
|
|
168
|
+
navigator.waitUntilNav2Active()
|
|
169
|
+
|
|
170
|
+
goal = PoseStamped()
|
|
171
|
+
goal.header.frame_id = 'map'
|
|
172
|
+
goal.pose.position.x = 5.0
|
|
173
|
+
goal.pose.position.y = 3.0
|
|
174
|
+
goal.pose.orientation.w = 1.0
|
|
175
|
+
|
|
176
|
+
navigator.goToPose(goal)
|
|
177
|
+
|
|
178
|
+
while not navigator.isTaskComplete():
|
|
179
|
+
feedback = navigator.getFeedback()
|
|
180
|
+
print(f'Distance remaining: {feedback.distance_remaining}')
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 调试与可视化
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# RViz2 with Nav2 plugin
|
|
189
|
+
rviz2 -d $(ros2 pkg prefix nav2_bringup)/share/nav2_bringup/rviz/nav2_default_view.rviz
|
|
190
|
+
|
|
191
|
+
# 查看代价地图
|
|
192
|
+
ros2 topic echo /global_costmap/costmap
|
|
193
|
+
|
|
194
|
+
# 检查 TF 树
|
|
195
|
+
ros2 run tf2_tools view_frames
|
|
196
|
+
```
|