🤖 roboto_origin_03 Wiki
首页 / 电机子模块 / 快速开始

本文面向初次接触 roboto_motors 的开发者,目标是在 10 分钟内完成环境验证、编译安装,并运行第一段能实际控制电机的代码。阅读本文前,建议先浏览 项目概览与适用场景 以确认本项目是否匹配你的硬件组合。整体流程遵循「环境检查 → 编译安装 → 最小可运行示例 → 验证反馈」四步闭环,确保每一步都有明确的判断标准。

Sources: README_CN.md

前置条件检查

在编译代码前,请确认以下两项硬件与软件条件已经满足。若 CAN 接口尚未配置或依赖包缺失,请先跳转到 CAN总线接口配置编译依赖与安装 完成准备。

检查项 最低要求 验证命令
操作系统 Linux (内核支持 SocketCAN) uname -r
CAN 接口 已启用 can0 并匹配电机波特率 ip link show can0
依赖库 spdlog, fmt, Boost, Eigen3, pybind11 apt list --installed | grep spdlog
编译工具 cmake ≥ 3.12, colcon (ROS 2 方式) 或 g++ ≥ 9 cmake --version

本项目通过抽象接口屏蔽底层总线差异,目前生产环境仅支持 SocketCAN 后端。所有电机驱动共享同一套 CAN 抽象层,因此无论你使用达妙 DM、EVO 还是 LeadRobot,上层初始化与调用范式完全一致。

Sources: src/protocol/can_iso.hpp, src/protocol/can/socket_can.hpp

编译与安装

仓库提供两条编译路径:ROS 2 colcon 工作流(推荐,自动处理 ament 依赖与 Python 模块安装路径)和独立 CMake 工作流(适合无 ROS 2 环境的服务器或嵌入式场景)。

方式一:ROS 2 工作流(推荐)

将本仓库放入 ROS 2 工作空间的 src 目录后,执行标准 colcon 构建命令。ament_cmake 会自动识别 package.xml 中的依赖声明,并将静态库、头文件和 Python 扩展模块安装到对应的目标目录。

# 假设工作空间为 ~/roboto_ws
cd ~/roboto_ws
colcon build --packages-select roboto_motors --cmake-args -DCMAKE_BUILD_TYPE=Release
source install/setup.bash

构建成功后,Python 模块 motors_py 可通过 from motors_py import MotorDriver 直接导入,无需手动设置 PYTHONPATH

Sources: CMakeLists.txt, package.xml

方式二:独立 CMake 工作流

若你仅在裸机 Linux 上使用 C++ SDK,或需要手动控制安装前缀,可直接使用 CMake:

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
sudo make install

顶层 CMakeLists.txt 中声明了 C++17 标准、-O3 优化、ccache 加速以及 POSITION_INDEPENDENT_CODE,确保静态库既能被可执行文件链接,也能被 Python 扩展安全加载。

Sources: CMakeLists.txt

电机型号速查

通过工厂方法创建实例时,motor_model 参数为整数枚举值。下表列出当前已适配的全部型号及其对应数值,避免你在初始化时因型号错误导致工厂抛出 runtime_error

品牌 型号 motor_type motor_model
DM(达妙) DM4340P-48V "DM" 0
DM(达妙) DM10010L-48V "DM" 1
EVO EVO431040 "EVO" 0
EVO EVO811825 "EVO" 1
EVO EVO811832 "EVO" 2
LeadRobot LRO-5550 "LRO" 0
LeadRobot LRO-6562 "LRO" 1
LeadRobot LRO-8462 "LRO" 2
LeadRobot LRO-10062 "LRO" 3

工厂方法 MotorDriver::create_motor 的完整签名为:(motor_id, interface_type, interface, motor_type, motor_model, master_id_offset=0, motor_zero_offset=0.0)。其中 interface_type 当前固定填 "can"interface 填实际网卡名(如 "can0")。master_id_offset 仅对 DM 电机有意义,用于区分主从 ID;motor_zero_offset 以弧度为单位,用于统一多关节坐标系。

Sources: src/motor_driver.cpp, src/drivers/dm/dm_motor_driver.hpp, src/drivers/evo/evo_motor_driver.hpp, src/drivers/lro/lro_motor_driver.hpp

运行第一个程序

以下给出两段最小可运行示例:Python 版适合算法验证与快速调试,C++ 版适合部署到实时控制循环。两段代码均执行「创建实例 → 初始化使能 → MIT 阻抗控制 → 读取反馈 → 安全失能」的完整生命周期。

Python 示例

from motors_py import MotorDriver, MotorControlMode
import time

# 1. 创建电机实例:以 DM4340P-48V 为例,CAN ID 为 0x01
motor = MotorDriver.create_motor(
    motor_id=0x01,
    interface_type="can",
    interface="can0",
    motor_type="DM",
    motor_model=0
)

# 2. 初始化并使能电机
motor.init_motor()

# 3. 切换到 MIT 模式并发送控制指令
motor.set_motor_control_mode(MotorControlMode.MIT)
motor.motor_mit_cmd(0.0, 0.0, 10.0, 1.0, 0.0)

# 4. 读取实时反馈
time.sleep(0.1)
motor.refresh_motor_status()
print(f"pos={motor.get_motor_pos():.3f} rad, "
      f"spd={motor.get_motor_spd():.3f} rad/s, "
      f"temp={motor.get_motor_temperature():.1f} °C")

# 5. 安全关闭
motor.deinit_motor()

C++ 示例

#include "motor_driver.hpp"
#include <iostream>
#include <memory>
#include <unistd.h>

int main() {
    // 1. 创建电机实例
    auto motor = MotorDriver::create_motor(
        0x01, "can", "can0", "DM", 0);

    // 2. 初始化并使能
    motor->init_motor();

    // 3. MIT 阻抗控制
    motor->set_motor_control_mode(MotorDriver::MIT);
    motor->motor_mit_cmd(0.0f, 0.0f, 10.0f, 1.0f, 0.0f);

    // 4. 读取反馈
    usleep(100000);
    motor->refresh_motor_status();
    std::cout << "pos=" << motor->get_motor_pos()
              << " spd=" << motor->get_motor_spd()
              << " temp=" << motor->get_motor_temperature() << "\n";

    // 5. 安全关闭
    motor->deinit_motor();
    return 0;
}

两段代码的共同要点:

Sources: src/pybind_module.cpp, include/motor_driver.hpp

控制模式速查

roboto_motors 抽象基类定义了四种统一控制模式。不同品牌电机对模式的支持存在差异,下表给出快速对照,帮助你在首次上电时选择正确的控制策略。

模式枚举 数值 适用品牌 调用方法 典型场景
NONE 0 全部 初始状态,未使能
MIT 1 DM、EVO、LRO motor_mit_cmd(pos, vel, kp, kd, torque) 阻抗控制、腿足机器人
POS 2 DM、LRO motor_pos_cmd(pos, spd, ignore_limit) 关节定位、机械臂
SPD 3 DM、LRO motor_spd_cmd(spd) 轮式驱动、传送带

切换模式前务必调用 set_motor_control_mode(mode);部分电机(如 DM)在收到与当前模式不匹配的控制帧时会静默丢弃或报协议错误。MIT 模式下的五个参数物理意义为:目标位置(rad)、目标速度(rad/s)、位置刚度 Kp、速度阻尼 Kd、前馈力矩(Nm),其数学原理将在 MIT阻抗控制原理与实现 中详细推导。

Sources: include/motor_driver.hpp

验证通信与常见排查

完成首次编译并运行示例后,可通过以下清单验证通信链路是否真正打通。

现象 期望结果 若不符合,检查项
init_motor() 返回值 非零(成功)或布尔真 CAN 接口是否 up;波特率是否 1M;电机供电是否正常
get_response_count() 持续递增 电机 ID 是否与 motor_id 一致;总线终端电阻 120Ω 是否接入
get_motor_pos() 数值合理,非固定死值 是否调用了 refresh_motor_status();回调是否被正确注册
deinit_motor() 后电机 可手动自由转动 指令是否真正发送到总线;电机是否进入刹车状态

create_motor 抛出 "Motor type not supported" 异常,请核对 motor_type 字符串大小写(必须全大写 "DM" / "EVO" / "LRO")以及 motor_model 数值是否在枚举范围内。

Sources: src/motor_driver.cpp

下一步学习路径

完成本文的「最小闭环」后,建议按以下顺序继续深入:

  1. 环境深化 — 若你需要配置多路 CAN 或 CAN-FD,阅读 CAN总线接口配置;若依赖安装遇到问题,阅读 编译依赖与安装
  2. SDK 深入 — 根据你的主力语言选择 Python SDK快速上手C++ SDK快速上手,其中包含批量多电机控制、实时循环模板和线程安全注意事项。
  3. 架构理解 — 当你需要扩展新品牌电机或自定义协议时,架构总览与模块划分MotorDriver抽象基类与接口设计 将帮助你定位修改点。

下图汇总了从「首次克隆仓库」到「稳定运行控制循环」的完整决策流程:

flowchart TD
    A[克隆仓库] --> B{CAN接口已配置?}
    B -->|否| C[CAN总线接口配置]
    B -->|是| D{依赖已安装?}
    D -->|否| E[编译依赖与安装]
    D -->|是| F[colcon build / cmake]
    F --> G[运行Python/C++最小示例]
    G --> H{反馈正常?}
    H -->|否| I[检查ID/波特率/终端电阻]
    H -->|是| J[进入Python/C++ SDK深入指南]
    C --> B
    E --> D
    I --> G