Go to file
xtkuang af67751937 feat: add safe UME teleoperation framework
Add the UME RobotArm and Damiao CAN-FD path, migrate the legacy UME controller, and introduce guarded cross-machine gRPC teleoperation with lifecycle, authority, configuration, and test coverage.
2026-07-31 08:48:04 +08:00
.vscode Add Aubo arm support 2026-07-02 08:29:19 +08:00
assets feat: fix google test 2026-02-27 16:31:37 +08:00
cmake feat: add gRPC motor control over Modbus TCP 2026-07-30 15:09:07 +08:00
cmvr-es feat: add safe UME teleoperation framework 2026-07-31 08:48:04 +08:00
data refactor:Refactor all the code 2026-06-24 15:45:54 +08:00
dependency merge: resolve xtkuang_dev into dev 2026-07-27 17:47:30 +08:00
docs feat: add safe UME teleoperation framework 2026-07-31 08:48:04 +08:00
model feat: add safe UME teleoperation framework 2026-07-31 08:48:04 +08:00
protos feat: add safe UME teleoperation framework 2026-07-31 08:48:04 +08:00
python refactor:Refactor all the code 2026-06-24 15:45:54 +08:00
script merge: resolve xtkuang_dev into dev 2026-07-27 17:47:30 +08:00
scripts feat(collision): add collision primitive generation tools 2026-07-27 15:39:54 +08:00
test merge: resolve xtkuang_dev into dev 2026-07-27 17:47:30 +08:00
.aiignore fix: readme 2026-02-05 17:31:18 +08:00
.codex feat: add px 6ax gen3 as touch pressure sensor 2026-05-08 16:58:52 +08:00
.gitignore feat: complete QUIC edge integration 2026-07-24 12:35:04 +08:00
.gitmodules feat:add eye hand calibration and pose follow 2025-08-22 16:57:29 +08:00
CMakeLists.txt feat: add gRPC motor control over Modbus TCP 2026-07-30 15:09:07 +08:00
compile_commands.json feat: add px 6ax gen3 as touch pressure sensor 2026-05-08 16:58:52 +08:00
LICENSE feat:add eye hand calibration and pose follow 2025-08-22 16:57:29 +08:00
MUJOCO_LOG.TXT feat(collision): add collision primitive generation tools 2026-07-27 15:39:54 +08:00
README.md feat: add gRPC motor control over Modbus TCP 2026-07-30 15:09:07 +08:00
request.txt merge: resolve xtkuang_dev into dev 2026-07-27 17:47:30 +08:00

CMVR-ES

简介

CMVR-ES 工程。

安装

1. 拉取 Git 子模块

git submodule update --init --recursive

2. 安装系统依赖

# 基础工具
sudo apt-get update
sudo apt install -y build-essential cmake git pkg-config patchelf libboost-all-dev libssl-dev

# OpenCV
sudo apt install -y \
  libjpeg-dev libpng-dev libtiff-dev \
  libavcodec-dev libavformat-dev libswscale-dev \
  libv4l-dev libxvidcore-dev libx264-dev \
  libgtk-3-dev

# PulseAudio
sudo apt-get install libpulse-dev

# OpenGL
sudo apt-get install libgl1-mesa-dev

# GLFW
sudo apt-get install libglfw3-dev

# Assimp
sudo apt-get install libassimp-dev

# visp
sudo apt-get install -y libx11-dev liblapack-dev libzbar-dev libpthread-stubs0-dev libdc1394-dev nlohmann-json3-dev

# RealSense
sudo apt-get install -y \
  libusb-1.0-0-dev libudev-dev \
  libglu1-mesa-dev
  
# Matplot++
sudo apt install gnuplot-qt

3. 配置 IgH EtherCAT

工程已内置 IgH EtherCAT 1.7.0 的 userspace 文件:

dependency/x86/third_party/ethercat/v1.7.0

先设置本机路径:

export CMVR_ES_ROOT=/path/to/cmvr-es
export IGH_ETHERCAT_ROOT=$CMVR_ES_ROOT/dependency/x86/third_party/ethercat/v1.7.0

安装当前内核的 header

sudo apt-get update
sudo apt-get install -y linux-headers-$(uname -r)

如果内置目录里已经有当前内核版本的 EtherCAT 内核模块,直接安装到系统:

sudo mkdir -p /lib/modules/$(uname -r)/ethercat
sudo cp -r $IGH_ETHERCAT_ROOT/lib/modules/$(uname -r)/ethercat/* /lib/modules/$(uname -r)/ethercat/
sudo depmod

内置内核模块只适用于相同内核版本。如果 $IGH_ETHERCAT_ROOT/lib/modules/$(uname -r) 不存在,说明这台机器的内核版本不匹配,需要在这台机器上重新编译安装 IgH EtherCAT

sudo apt-get update
sudo apt-get install -y \
  build-essential autoconf automake libtool pkg-config git \
  linux-headers-$(uname -r)

cd /tmp
git clone --branch stable-1.7 --depth 1 https://gitlab.com/etherlab.org/ethercat.git ethercat-stable-1.7
cd ethercat-stable-1.7

./bootstrap
./configure \
  --prefix=$IGH_ETHERCAT_ROOT \
  --libdir=$IGH_ETHERCAT_ROOT/lib \
  --includedir=$IGH_ETHERCAT_ROOT/include \
  --sysconfdir=$IGH_ETHERCAT_ROOT/etc \
  --with-systemdsystemunitdir=$IGH_ETHERCAT_ROOT/lib/systemd/system \
  --enable-generic \
  --with-linux-dir=/lib/modules/$(uname -r)/build

make -j$(nproc) all modules
make install
sudo make modules_install
sudo depmod

启动 EtherCAT。eno1 换成实际连接 EtherCAT 从站的网卡:

sudo script/ethercat/start_ethercat.sh eno1

脚本会写入内置 IgH 配置文件:

$IGH_ETHERCAT_ROOT/etc/ethercat.conf

脚本会把该网卡的 MAC 写到 MASTER0_DEVICE,使用 DEVICE_MODULES="generic",把网卡从 NetworkManager 断开,并通过 ethercatctl -c 启动 IgH master。

查看状态:

script/ethercat/status_ethercat.sh

$IGH_ETHERCAT_ROOT/bin/ethercat master
$IGH_ETHERCAT_ROOT/bin/ethercat slaves
$IGH_ETHERCAT_ROOT/bin/ethercat pdos

停止 EtherCAT

sudo script/ethercat/stop_ethercat.sh eno1
sudo script/ethercat/stop_ethercat.sh eno1 --restore-network

MotorService 与 Modbus TCP PLC

工程包含从 gRPC MotorServiceMotorManagerAbstractMotorModbusTcpMotorBusRuntime 的 CMVR PLC v1 电机控制链x86-64 的 libmodbus 3.1.11 已放在 dependency/x86/third_party/modbus/3.1.11

PLC 对接时特别注意:

  • host 必须配置为 IPv4 字面量PLC boot ID 必须非零且每次重启变化;
  • owner 决策、命令 ACK 都必须回显对应 session重连不得执行旧 mailbox
  • PLC 在进程启动时可以离线;连接 supervisor 会继续退避重试,离线期间状态 返回不可用且运动命令不会写 mailbox
  • 状态区按 odd/even seqlock 发布,上位机使用 sequence-before → 64-word block → sequence-after 三段读取验证;
  • 每次 OpenCyclicPosition/Velocity 创建新 stream epochPLC 必须原子清零 last_applied_cyclic_sequence、旧样本去重状态和 cyclic watchdog确认 StreamActive 与正确 mode 后才 ACK重开后的首样本序列从 1 开始并必须 重新应用;
  • 活动 cyclic 流跨 connection_epoch 后不会自动重开;旧流的当前和后续 setpoint 均被拒绝并在 Quick Stop 后终止,客户端必须新建 gRPC 流。断链前 或断链期间 pending 的 setpoint 不会应用到新 session
  • 任何清理 Quick Stop 未确认时MotorService 都会 fail-closed 锁存,并在 成功执行 setEnabled(true) 前拒绝新的运动命令;
  • Modbus Quick Stop 只是功能性停止,不能替代硬接线急停或驱动器 STO。
  • 当前 Modbus 后端只提供 x86-64 的 libmodbus 3.1.11dependency/arm 尚无对应库,因此 ARM 构建暂不支持该后端。

完整 gRPC 语义、配置样例、寄存器表、TIA Portal 要求、构建测试和安全边界见 docs/motor_service_modbus_tcp.md

AUBO 控制柜 IO

AuboArm 通过通用的 executeJsonCommand 接口提供控制柜 Standard 数字 IO 读写。第一版支持以下命令:

operation 说明 必填字段
get_di 读取控制柜数字输入 index
get_do 读取控制柜数字输出及其 runstate index
set_do 设置控制柜数字输出 indexvalue

JSON 命令示例:

{"command":"cabinet_io","operation":"get_di","index":0}
{"command":"cabinet_io","operation":"get_do","index":0}
{"command":"cabinet_io","operation":"set_do","index":0,"value":true}

其中 index0 开始,运行时会根据控制器返回的 IO 数量检查范围。 set_do.value 必须是 JSON 布尔值 truefalse,不接受 0/1 或字符串。 set_do 成功响应中的 requested_value 表示 SDK 已接受的请求值;需要确认控制器 当前输出状态时,再调用一次 get_do 读取实际值。

成功响应示例:

{
  "success": true,
  "command": "cabinet_io",
  "operation": "get_di",
  "index": 0,
  "count": 16,
  "value": false
}

通过 gRPC 调用

该功能复用 cmvr.api.SystemService/ExecuteJsonCommand。默认配置中的 gRPC 端口是 50052,读取 DI0

grpcurl -plaintext \
  -d '{
    "header":{"deviceId":"aubo_arm"},
    "requestJson":"{\"command\":\"cabinet_io\",\"operation\":\"get_di\",\"index\":0}"
  }' \
  127.0.0.1:50052 \
  cmvr.api.SystemService/ExecuteJsonCommand

设置 DO0 为高电平:

grpcurl -plaintext \
  -d '{
    "header":{"deviceId":"aubo_arm"},
    "requestJson":"{\"command\":\"cabinet_io\",\"operation\":\"set_do\",\"index\":0,\"value\":true}"
  }' \
  127.0.0.1:50052 \
  cmvr.api.SystemService/ExecuteJsonCommand

使用源码树默认配置时,先在 cmvr-es/config/manager/device_manager.pb.txt 中把 aubo_armenable 改为 true,并在 cmvr-es/config/devices/arm/aubo_arm.pb.txt 中配置正确的控制器地址和登录信息, 然后重新安装配置并启动安装产物:

cmake --install build
./output/bin/cmvr_es

output/bin/cmvr_es 读取的是 output/bin/config/;如果进程使用显式配置路径, 应修改该配置根下的对应文件。 设备未启用或初始化失败时gRPC 会返回 Device not found: aubo_arm

安全约束

  • 该接口只访问控制柜 Standard 数字 IO不操作工具端 IO、可配置 IO 或安全 IO。
  • set_do 不会修改控制器的输出 runstate。只有目标通道的 runstate 为 StandardOutputRunState::None 时才允许写入,否则返回 output_managed_by_runstate
  • 接口不会调用会重置全部输出配置的 setDigitalOutputRunstateDefault()
  • 模拟量 IO 涉及 domain、单位和量程第一版暂不通过该 JSON 接口开放。