cmvr-es/docs/ethercat_motor_tutorial.md

238 lines
6.0 KiB
Markdown
Raw 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.

# EtherCAT 电机接入教程
这份文档只说明新增一种 EtherCAT 电机需要改哪里、怎么写。
## 1. 增加 vendor
修改 `protos/cmvr/config/motor_config/motor_config.proto`
```proto
enum MotorVendor {
MOTOR_VENDOR_UNKNOWN = 0;
MOTOR_VENDOR_TI5 = 1;
MOTOR_VENDOR_MUJOCO = 2;
MOTOR_VENDOR_XXX = 3;
}
```
`MOTOR_VENDOR_XXX` 改成真实厂商名,例如 `MOTOR_VENDOR_FOO`。不要复用 `TI5`
## 2. 写电机配置
新增配置文件:
```text
cmvr-es/config/devices/motor/ethercat_motors.pb.txt
```
示例:
```proto
motor {
id: "ethercat_motors"
motor_groups {
id: "right_arm_ethercat"
bus_type: MOTOR_BUS_ETHERCAT
vendor: MOTOR_VENDOR_XXX
protocol: MOTOR_PROTOCOL_ETHERCAT_CIA402
tool_frame: "R_FINGER_TIP"
ethercat {
master_id: "eth0"
cycle_us: 1000
slaves { motor_id: 1 slave_index: 0 vendor_id: 0x00000000 product_code: 0x00000000 }
slaves { motor_id: 2 slave_index: 1 vendor_id: 0x00000000 product_code: 0x00000000 }
slaves { motor_id: 3 slave_index: 2 vendor_id: 0x00000000 product_code: 0x00000000 }
slaves { motor_id: 4 slave_index: 3 vendor_id: 0x00000000 product_code: 0x00000000 }
slaves { motor_id: 5 slave_index: 4 vendor_id: 0x00000000 product_code: 0x00000000 }
slaves { motor_id: 6 slave_index: 5 vendor_id: 0x00000000 product_code: 0x00000000 }
slaves { motor_id: 7 slave_index: 6 vendor_id: 0x00000000 product_code: 0x00000000 }
}
joint_limits {
enable: true
source: JOINT_LIMIT_SOURCE_CUSTOM
joints { joint_name: "R_SHOULDER_P" q_lb: -3.14 q_ub: 3.14 qd: 5.0 qdd: 10.0 }
joints { joint_name: "R_SHOULDER_R" q_lb: -0.78 q_ub: 1.57 qd: 5.0 qdd: 10.0 }
joints { joint_name: "R_SHOULDER_Y" q_lb: -3.14 q_ub: 3.14 qd: 5.0 qdd: 10.0 }
joints { joint_name: "R_ELBOW_R" q_lb: 0 q_ub: 2.05 qd: 5.0 qdd: 10.0 }
joints { joint_name: "R_WRIST_P" q_lb: -3.14 q_ub: 3.14 qd: 5.0 qdd: 10.0 }
joints { joint_name: "R_WRIST_Y" q_lb: -0.78 q_ub: 0.78 qd: 5.0 qdd: 10.0 }
joints { joint_name: "R_WRIST_R" q_lb: -0.57 q_ub: 1.57 qd: 5.0 qdd: 10.0 }
}
motors {
motors { id: 1 joint_name: "R_SHOULDER_P" }
motors { id: 2 joint_name: "R_SHOULDER_R" }
motors { id: 3 joint_name: "R_SHOULDER_Y" }
motors { id: 4 joint_name: "R_ELBOW_R" }
motors { id: 5 joint_name: "R_WRIST_P" }
motors { id: 6 joint_name: "R_WRIST_Y" }
motors { id: 7 joint_name: "R_WRIST_R" }
}
}
}
```
`motors.motors.id` 是系统内的电机逻辑 id。`ethercat.slaves.motor_id` 必须和它对应。
`joint_limits``joint_name` 读取,和 CAN、MuJoCo 电机保持同一个风格。
## 3. 注册设备
修改:
```text
cmvr-es/config/manager/device_manager.pb.txt
```
加入:
```proto
devices {
id: "ethercat_motors"
type: MOTOR_SYSTEM
enable: true
config_file: "devices/motor/ethercat_motors.pb.txt"
}
```
## 4. 机械臂使用 EtherCAT group
修改机械臂配置,例如:
```text
cmvr-es/config/devices/arm/arm.pb.txt
```
把 motor backend 改成:
```proto
motor {
motor_system_id: "ethercat_motors"
motor_group_ids: "right_arm_ethercat"
joint_names: "R_SHOULDER_P"
joint_names: "R_SHOULDER_R"
joint_names: "R_SHOULDER_Y"
joint_names: "R_ELBOW_R"
joint_names: "R_WRIST_P"
joint_names: "R_WRIST_Y"
joint_names: "R_WRIST_R"
}
```
## 5. 实现 bus runtime
EtherCAT 总线资源放在:
```text
cmvr-es/devices/motor/bus_runtime/ethercat/include/ethercat_motor_bus_runtime.h
cmvr-es/devices/motor/bus_runtime/ethercat/src/ethercat_motor_bus_runtime.cpp
```
`EthercatMotorBusRuntime` 负责:
```text
读取 ethercat 配置
初始化 EtherCAT master
扫描/校验 slave_index、vendor_id、product_code
启动 cyclic loop
保存 command/feedback buffer
停止 cyclic loop
```
bus runtime 不创建具体电机,也不关心厂商;它只保存总线连接、线程和数据缓存。
## 6. 增加具体电机 driver
新增目录:
```text
cmvr-es/devices/motor/drivers/xxx_ethercat/
CMakeLists.txt
include/xxx_ethercat_motor.h
include/xxx_ethercat_motor_protocol.h
src/xxx_ethercat_motor.cpp
src/xxx_ethercat_motor_protocol.cpp
```
`XxxEthercatMotor` 继承 `AbstractMotor`
`XxxEthercatMotorProtocol` 继承 `MotorProtocolInterface`,把 `setTarget`、`setQd`、`getQ` 等接口转换成 EtherCAT command/feedback。
## 7. 在 MotorManager 里创建 EtherCAT 电机
修改:
```text
cmvr-es/devices/motor/manager/src/motor_manager.cpp
```
`MotorManager::createEthercatMotors_()` 里按 `vendor + protocol` 创建具体电机:
```cpp
auto ethercat_bus_runtime =
std::dynamic_pointer_cast<EthercatMotorBusRuntime>(bus_runtime);
if (group_cfg.vendor() == config::MOTOR_VENDOR_XXX &&
group_cfg.protocol() == config::MOTOR_PROTOCOL_ETHERCAT_CIA402) {
auto protocol = std::make_shared<XxxEthercatMotorProtocol>(ethercat_bus_runtime);
std::vector<std::shared_ptr<AbstractMotor>> motors;
motors.reserve(motor_cfgs.size());
for (const auto& cfg : motor_cfgs) {
auto motor = std::make_shared<XxxEthercatMotor>(cfg);
motor->setProtocol(protocol);
if (!motor->init()) {
return {};
}
motors.push_back(std::move(motor));
}
return motors;
}
```
## 8. 加入 CMake
修改:
```text
cmvr-es/devices/motor/manager/CMakeLists.txt
```
`motor_manager` 链接新增的具体 EtherCAT 电机 target。
修改:
```text
cmvr-es/devices/motor/CMakeLists.txt
```
加入:
```cmake
add_subdirectory(drivers/xxx_ethercat)
```
## 9. 验证配置
先验证 proto
```bash
./output/bin/protoc \
--encode=cmvr.config.MotorRootConfig \
-I protos \
protos/cmvr/config/motor_config/motor_config.proto \
< cmvr-es/config/devices/motor/ethercat_motors.pb.txt \
> /tmp/ethercat_motors.pb.bin
```
再编译:
```bash
cmake --build cmake-build-debug --target mujoco_manual_ui_test
```
真机联调时先只验证初始化日志master 打开、slave 数量、vendor/product 校验、cyclic loop 启动、每个 motor 注册成功。然后再下发运动命令。