🤖 roboto_origin_03 Wiki
首页 / 部署 / 硬件连接与 CAN/IMU 映射

本文档面向首次接触本项目的开发者,系统梳理机器人主控与电机、IMU 的物理连接方式,以及这些硬件在软件层中的映射关系。理解这一层映射是后续进行电机标定、策略推理和故障排查的前提。全文以 src/inference/config/robot.yaml 为核心配置入口,配合 udev 规则与驱动代码,建立从“插哪根线”到“代码里怎么寻址”的完整认知链路。

Sources: robot.yaml, 99-auto-up-devs-orangepi.rules

整体硬件拓扑

ATOM01 部署框架采用主控板(Orange Pi 5 Plus 或 RDK X5)作为计算核心,通过 USB 转 CAN 适配器与下肢、腰部、手臂的 23 个关节电机通信,同时通过串口连接 IMU 获取机身姿态。下图展示了这一拓扑的软件视角:

graph TD
    A[主控板<br/>Orange Pi 5 Plus / RDK X5] -->|USB| B[USB-CAN 适配器 ×4]
    A -->|USB| C[IMU 串口适配器<br/>CP210x]
    B -->|can0| D[左腿 6 电机<br/>ID 1-6]
    B -->|can1| E[右腿+腰 7 电机<br/>ID 7-13]
    B -->|can2| F[左手 5 电机<br/>ID 14-18]
    B -->|can3| G[右手 5 电机<br/>ID 19-23]
    C -->|/dev/ttyUSB0| H[HiPNUC IMU<br/>ID 8]

从软件角度看,robot_interface.cpp 在构造时会读取 robot.yaml,并依次调用 setup_motors()setup_imu() 完成驱动实例化。所有后续控制与反馈都通过这两个接口向下分发。

Sources: robot_interface.cpp, robot_interface.hpp

CAN 总线连接与电机映射

物理连接与 udev 规则

本项目使用 4 路 USB 转 CAN 适配器,默认建议按机身部位分配如下表所示。如果不使用 udev 规则,必须严格按照插入顺序绑定接口;更推荐的方式是通过 udev 规则将物理 USB 端口与接口名永久绑定。

总线接口 对应部位 电机数量 电机 ID 范围 默认 USB 端口属性 (Orange Pi)
can0 左腿 6 1 ~ 6 5-1.4.1
can1 右腿+腰 7 7 ~ 13 5-1.4.2
can2 左手 5 14 ~ 18 5-1.4.3
can3 右手 5 19 ~ 23 5-1.4.4

udev 规则文件 assets/99-auto-up-devs-orangepi.rules 完成了三件事:第一,根据 idVendor/idProduct1d50:606f)识别 CAN 适配器;第二,利用 KERNELS 匹配物理 USB 端口,将设备重命名为 can0 ~ can3;第三,在设备插入时自动执行 ip link set canX up type can bitrate 1000000,将总线波特率设为 1 Mbps 并启用队列。IMU 的 USB 串口芯片(10c4:ea60)也在同一条规则中被赋予 0666 权限并创建 /dev/ttyUSB0 符号链接。

Sources: 99-auto-up-devs-orangepi.rules

电机型号与总线分配详表

robot.yaml 中的 motors 段通过 motor_num 数组定义了每条总线上的电机数量。代码在 setup_motors() 中按顺序遍历 motor_interfacemotor_num,将 motor_id 列表依次分配到对应总线。对于本项目默认配置,电机与总线的精确映射如下:

总线 电机 ID 电机型号 型号数值
can0 1 DM10010L_48V 1
can0 2 DM10010L_48V 1
can0 3 DM10010L_48V 1
can0 4 DM10010L_48V 1
can0 5 DM4340P_48V 0
can0 6 DM4340P_48V 0
can1 7 DM10010L_48V 1
can1 8 DM10010L_48V 1
can1 9 DM10010L_48V 1
can1 10 DM10010L_48V 1
can1 11 DM4340P_48V 0
can1 12 DM4340P_48V 0
can1 13 DM10010L_48V 1
can2 14 DM4340P_48V 0
can2 15 DM4340P_48V 0
can2 16 DM4340P_48V 0
can2 17 DM4340P_48V 0
can2 18 DM4340P_48V 0
can3 19 DM4340P_48V 0
can3 20 DM4340P_48V 0
can3 21 DM4340P_48V 0
can3 22 DM4340P_48V 0
can3 23 DM4340P_48V 0

其中型号 0 对应 DM4340P_48V,型号 1 对应 DM10010L_48V。电机驱动代码根据该型号索引加载对应的电流、速度和力矩限制参数。

Sources: dm_motor_driver.hpp, dm_motor_driver.cpp, robot_interface.cpp

master_id_offset 与 CAN 帧过滤

在 DM 电机驱动中,每个电机对象在初始化时会计算 master_id = motor_id + master_id_offset。默认配置下 master_id_offset 为 16,因此 ID 为 1 的电机其 master_id 为 17。驱动层将 master_id 注册到 SocketCAN 接收回调的过滤键中,这样总线上回传的反馈帧就能准确路由到对应的电机实例。

Sources: dm_motor_driver.cpp

IMU 连接与配置

串口模式(默认)

robot.yaml 默认将 IMU 配置为串口通信:

imu:
    imu_id: 8
    imu_interface_type: "serial"
    imu_interface: "/dev/ttyUSB0"
    imu_type: "HIPNUC"
    baudrate: 921600

RobotInterface 构造时会调用 setup_imu(),进而通过 IMUDriver::create_imu() 实例化 HipnucIMUDriver。该驱动打开 /dev/ttyUSB0,以 921600 波特率接收 HiPNUC 协议数据包,解析出四元数(w, x, y, z)、角速度(x, y, z)和线加速度。

Sources: imu_driver.cpp, robot_interface.cpp

CAN 模式(备选)

项目中同样预留了基于 CAN 的 IMU 配置脚本 src/imu/init_imu.sh。该脚本使用 J1939 协议,通过 cansendcan4 接口发送配置指令,将 IMU 波特率修改为 1 Mbps 并开启四元数输出。若改用 CAN 模式,需同步修改 robot.yaml 中的 imu_interface_typeimu_interface 字段。对于初学者,建议保持默认串口模式,因为 udev 规则已为串口设备自动完成了权限和别名配置。

Sources: init_imu.sh

robot.yaml 配置参数详解

robot.yaml 是连接硬件与上层策略推理的“枢纽文件”,它包含 imumotorsrobot 三个顶层字段。下面按字段说明其含义与修改注意事项。

motors 字段

参数 类型 说明
motor_id 整数数组 全部电机的逻辑 ID,共 23 个
motor_interface_type 字符串 通信协议,可选 "can" / "canfd"
motor_interface 字符串数组 CAN 总线接口名,如 ["can0", "can1", ...]
motor_num 整数数组 每条总线上的电机数量,与 motor_interface 一一对应
motor_type 字符串数组 每条总线上的电机品牌,如 ["DM", "DM", ...]
motor_model 整数数组 每个电机的具体型号索引,顺序与 motor_id 一致
master_id_offset 整数 用于 CAN 回调过滤的偏移量,默认 16
motor_zero_offset 浮点数组 每个电机的零点偏移量,顺序与 motor_id 一致

修改 motor_num 时务必保证数组之和等于 motor_id 的长度;修改 motor_interface 时务必保证数组长度与 motor_num 一致。motor_zero_offset 中的第 13 个值(对应腰部 yaw 电机)默认为 2.093,该值与机械限位标零方式有关,后续在 电机零点标定 中会详细说明。

Sources: robot.yaml

imu 字段

参数 类型 说明
imu_id 整数 IMU 设备逻辑 ID,默认 8
imu_interface_type 字符串 通信方式,"serial""can"
imu_interface 字符串 设备路径或 CAN 接口名,如 /dev/ttyUSB0
imu_type 字符串 IMU 品牌/协议,当前仅支持 "HIPNUC"
baudrate 整数 串口波特率,默认 921600

Sources: robot.yaml

robot 字段

参数 类型 说明
type 字符串 机器人类型,如 "atom01",用于选择运动学解耦器
kp 浮点数组 各关节 MIT 控制的刚度增益
kd 浮点数组 各关节 MIT 控制的阻尼增益
motor_sign 整数数组 电机方向符号,用于对齐 URDF 与电机实际正方向
close_chain_motor_id 整数数组 闭链关节对应的电机 ID,用于踝关节解耦
urdf2motor 整数数组 URDF 关节索引到电机数组索引的映射
extrinsic_R 浮点数组 IMU 到机体坐标系的 3×3 旋转矩阵(行优先)

motor_signurdf2motor 是运动学一致性的关键。urdf2motor 默认恒等映射 [0, 1, 2, ..., 22],表示 URDF 的第 i 个关节直接对应 motor_id 列表的第 i 个电机;motor_sign 则在读取电机位置和下发指令时进行方向翻转。extrinsic_R 默认单位阵,表示 IMU 坐标系与机体坐标系完全重合,若安装姿态不同则需填入实际外参。

Sources: robot.yaml, robot_interface.cpp

连接验证 checklist

完成物理接线与 udev 规则部署后,建议按以下步骤验证映射是否生效:

  1. 检查 CAN 接口状态:执行 ip a,确认 can0 ~ can3 均已 UP 且波特率为 1000000
  2. 检查串口设备:执行 ls -l /dev/ttyUSB0,确认文件存在且权限为 crw-rw-rw-
  3. 检查 udev 规则:执行 udevadm info -q property -n can0,确认 NAMEKERNELS 匹配规则文件中的配置。
  4. 验证电机回读:source 工作空间后,运行 python3 scripts/motors_py_example.py 或调用 ROS2 /read_joints 服务,观察各电机是否能正常返回位置与状态。

若上述任一步骤异常,请先排查物理连接与 udev 规则,再进入 常见问题排查与调试技巧 进一步诊断。

下一步

确认硬件连接与映射配置无误后,请继续阅读 电机零点标定,完成首次上电前的电机零位校准。