Files
2026-06-09 12:42:15 +08:00

252 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 板卡运动控制适配说明
本文档说明如何把当前 C++ Modbus RTU 协议库迁移到真实驱动板,并对接板卡已有的运动控制模块。
## 迁移结论
你不需要重写 Modbus 协议层。板卡侧主要实现 `MotionControlAdapter` 接口,然后在串口收齐一帧 RTU 数据后调用 `MotionControlBridge::process_request()`
```mermaid
flowchart LR
UartRx["UART/RS-485 收完整 RTU 帧"] --> Bridge["MotionControlBridge"]
Bridge --> Server["DeviceServer"]
Server --> Bank["RegisterBank"]
Bridge --> Adapter["MotionControlAdapter 接口"]
Adapter --> Motion["板卡已有运动控制模块"]
Motion --> Adapter
Bridge --> UartTx["UART/RS-485 发响应帧"]
```
## 需要实现的接口
接口定义在 `include/line_laser_modbus/motion_adapter.hpp`
```cpp
class MotionControlAdapter {
public:
virtual ~MotionControlAdapter() = default;
virtual void on_mode_changed(WorkMode mode) = 0;
virtual void on_target_pose(const Pose6D& pose) = 0;
virtual void on_correction(const Pose6D& correction) = 0;
[[nodiscard]] virtual Pose6D current_pose() const = 0;
[[nodiscard]] virtual DeviceState current_state() const = 0;
};
```
每个函数的含义:
- `on_mode_changed()`:上位机写入 `0xD000` 模式命令字,且模式值和切换规则合法后调用。
- `on_target_pose()`:上位机写入 `0xD020 ~ 0xD02D` 目标示教位姿后调用。
- `on_correction()`:上位机写入 `0xD036 ~ 0xD043` 六轴纠偏量后调用。
- `current_pose()`:返回板卡当前实际位姿,桥接层会写入 `0xD00A ~ 0xD017`
- `current_state()`:返回板卡当前状态字,桥接层会写入 `0xD001`
## 推荐固件主循环
```mermaid
sequenceDiagram
participant UART as UART_RS485
participant Main as 固件主循环
participant Bridge as MotionControlBridge
participant Adapter as 你的板卡适配器
participant Motion as 运动控制模块
Motion-->>Adapter: 更新当前位姿和状态
UART-->>Main: 收到完整 RTU 请求帧
Main->>Bridge: process_request(request)
Bridge->>Adapter: current_pose()
Bridge->>Adapter: current_state()
Bridge->>Bridge: 写入当前位姿和状态寄存器
Bridge->>Bridge: DeviceServer 处理读写请求
Bridge->>Adapter: 写请求成功后回调模式/目标/纠偏
Adapter->>Motion: 转发给板卡运动控制逻辑
Bridge-->>Main: response
Main-->>UART: response 非空则发送
```
伪代码:
```cpp
#include "line_laser_modbus/motion_adapter.hpp"
class BoardMotionAdapter final : public line_laser_modbus::MotionControlAdapter {
public:
void on_mode_changed(line_laser_modbus::WorkMode mode) override {
// 调用你的板卡模式切换函数,例如 motion_set_mode(...)
}
void on_target_pose(const line_laser_modbus::Pose6D& pose) override {
// 把目标示教位姿送入轨迹/插补/记录模块
}
void on_correction(const line_laser_modbus::Pose6D& correction) override {
// 把实时纠偏量送入跟踪控制模块
}
line_laser_modbus::Pose6D current_pose() const override {
// 从板卡轴控反馈读取当前实际 XYZABC
return {};
}
line_laser_modbus::DeviceState current_state() const override {
// 从板卡报警、运行、急停、标定等状态生成协议状态字
return line_laser_modbus::DeviceState::StandbyReady;
}
};
line_laser_modbus::DeviceServer server;
BoardMotionAdapter adapter;
line_laser_modbus::MotionControlBridge bridge(server, adapter);
void on_complete_rtu_frame(const line_laser_modbus::ByteVector& request) {
const auto response = bridge.process_request(request);
if (!response.empty()) {
uart_send(response.data(), response.size());
}
}
```
## 数据流
```mermaid
flowchart TD
HostWriteMode["上位机写模式 0xD000"] --> ServerCheck["DeviceServer 校验模式合法性"]
ServerCheck --> AdapterMode["on_mode_changed(mode)"]
AdapterMode --> BoardMode["板卡切换运动模式"]
HostWriteTarget["上位机写目标位姿 0xD020"] --> BankTarget["RegisterBank 保存目标位姿"]
BankTarget --> AdapterTarget["on_target_pose(pose)"]
AdapterTarget --> BoardTarget["板卡轨迹/示教模块"]
HostWriteCorrection["上位机写纠偏量 0xD036"] --> BankCorrection["RegisterBank 保存纠偏量"]
BankCorrection --> AdapterCorrection["on_correction(correction)"]
AdapterCorrection --> BoardCorrection["板卡实时跟踪模块"]
BoardFeedback["板卡轴控反馈"] --> AdapterFeedback["current_pose/current_state"]
AdapterFeedback --> BridgePublish["MotionControlBridge 发布到寄存器"]
BridgePublish --> HostRead["上位机读取当前位姿/状态"]
```
## 模式和状态映射建议
```mermaid
flowchart LR
subgraph WorkMode["WorkMode 模式命令"]
M0["0 待机复位"]
M1["1 系统标定"]
M2["2 焊前扫描示教"]
M3["3 在线全轴跟踪"]
M4["4 轨迹批量复现"]
M5["5 紧急停止"]
end
subgraph BoardAction["板卡动作"]
A0["清空轨迹/纠偏/停机待命"]
A1["执行标定流程"]
A2["接收并记录目标轨迹点"]
A3["启用实时纠偏叠加"]
A4["调用已保存标准轨迹"]
A5["断使能/急停制动"]
end
M0 --> A0
M1 --> A1
M2 --> A2
M3 --> A3
M4 --> A4
M5 --> A5
```
`current_state()` 建议从板卡真实状态生成:
- 无故障待命:`DeviceState::StandbyReady`
- 运动中:`DeviceState::MotionRunning`
- 示教完成:`DeviceState::TeachingComplete`
- 在线跟踪正常:`DeviceState::OnlineTrackingNormal`
- 任意报警:`DeviceState::Alarm`
- 标定完成:`DeviceState::CalibrationComplete`
- 急停触发:`DeviceState::EmergencyTriggered`
## 线程和中断注意事项
如果板卡上通信任务和运动控制任务不是同一个线程,需要处理共享数据同步。
```mermaid
flowchart TB
UartTask["通信任务<br/>调用 MotionControlBridge"] --> Shared["共享运动数据快照"]
MotionTask["运动控制任务<br/>更新轴位姿和状态"] --> Shared
Shared --> Lock["互斥锁 / 临界区 / 双缓冲"]
```
建议:
- 不要在串口中断里直接执行复杂运动控制逻辑;中断只收字节,完整帧交给通信任务处理。
- `current_pose()``current_state()` 应尽量只读取快照,避免阻塞。
- `on_correction()` 如果运行在通信任务中,应把纠偏量写入线程安全队列或双缓冲,再由运动控制周期消费。
- 如果驱动板不支持 C++ 异常,当前实现仍可使用,因为协议和适配层没有依赖异常流程。
## 与现有代码的关系
```mermaid
classDiagram
class MotionControlAdapter {
<<interface>>
+on_mode_changed(mode)
+on_target_pose(pose)
+on_correction(correction)
+current_pose() Pose6D
+current_state() DeviceState
}
class MotionControlBridge {
-DeviceServer server_
-MotionControlAdapter adapter_
+process_request(request)
+publish_feedback()
}
class DeviceServer {
+process_request(request)
+bank()
}
class RegisterBank {
+read(address, quantity)
+write(address, registers)
+set_current_pose(pose)
+set_state(state)
}
MotionControlBridge --> MotionControlAdapter
MotionControlBridge --> DeviceServer
DeviceServer --> RegisterBank
```
## Demo
`apps/adapter_demo.cpp` 提供了一个模拟板卡适配器:
- `DemoBoardMotion` 实现 `MotionControlAdapter`
- 上位机 demo 写入在线跟踪模式、目标位姿和纠偏量。
- 桥接层把这些写请求回调给 `DemoBoardMotion`
- 读取当前位姿时,桥接层先从 `DemoBoardMotion::current_pose()` 发布反馈,再返回 Modbus 响应。
构建后可运行:
```bash
cmake --build cpp/build --config Release
cpp/build/Release/adapter_demo.exe
```
## 最小迁移清单
- 实现一个继承 `MotionControlAdapter` 的板卡适配类。
- 在 UART/RS-485 层实现完整 RTU 帧接收和响应发送。
-`MotionControlBridge::process_request()` 连接协议处理。
-`on_mode_changed()` 中接入板卡模式切换。
-`on_target_pose()` 中接入轨迹示教/记录模块。
-`on_correction()` 中接入实时纠偏模块。
-`current_pose()``current_state()` 中返回板卡真实反馈。