Go to file
xtkuang 28f1dd1bf8 feat: add gRPC motor control over Modbus TCP
Add synchronous and streaming MotorService APIs backed by the PLC Modbus TCP runtime and protocol driver. Extend AUBO JSON commands and isolate vendor libstdc++ paths while keeping build-tree tests runnable.
2026-07-30 15:09:07 +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 gRPC motor control over Modbus TCP 2026-07-30 15:09:07 +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 gRPC motor control over Modbus TCP 2026-07-30 15:09:07 +08:00
model feat(collision): add collision primitive generation tools 2026-07-27 15:39:54 +08:00
protos feat: add gRPC motor control over Modbus TCP 2026-07-30 15:09:07 +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 接口开放。