跳转至

gRPC 例程(传统控制)

本例程针对传统控制(MPC)模式,介绍如何获取 gRPC 客户端工程、配置运行环境,并通过交互式命令行(Python / C++)或程序集成方式控制机器人。MPC 客户端位于仓库的 mpc_client/ 目录,服务端口固定为 6666,包名为 adam_control


获取客户端

完整客户端工程(含 Proto 协议、生成文件与示例脚本)将发布于 GitHub:

git clone https://github.com/pndbotics/pnd_grpc.git
cd pnd_grpc

🔗 仓库地址:pnd_grpc

工程结构

仓库同时提供传统控制(MPC)与强化学习(RL)两套客户端,分别位于 mpc_client/rl_client/

pnd_grpc/
├── mpc_client/             # 传统控制(MPC)客户端 ← 本例程
│   ├── proto/              # gRPC 协议定义(adam_control.proto,权威来源)
│   ├── include/            # protoc 生成的 C++ 头文件与源文件
│   ├── src/                # C++ API 封装 + 交互式命令行客户端
│   ├── python/             # Python 交互式客户端 + 生成的桩代码
│   ├── ip_config.json      # 机器人服务端 IP / 端口配置
│   ├── build.sh / run.sh / clean.sh
│   └── README.md           # 传统控制模式详细使用说明
├── rl_client/              # 强化学习(RL)模式客户端
│   ├── comm/
│   │   ├── proto/          # gRPC 协议定义(robot_control.proto)
│   │   └── grpc/           # protoc 生成的 Python 桩代码
│   ├── tools/grpc_client.py# Python 交互式客户端示例
│   └── README.md           # 强化学习模式详细使用说明
└── README.md               # 项目总览

本例程仅涉及 mpc_client/ 其中 proto/adam_control.proto 是接口的唯一权威来源,协议变更后执行 ./build.sh 重新生成 C++(include/)与 Python(python/)桩代码即可,不影响接口兼容性;强化学习(RL)客户端的使用方式见 gRPC 例程(强化学习)


环境准备

系统要求

推荐在 Ubuntu 22.04 x86_64 下进行客户端开发与调试。客户端可在任意能访问机器人网络的计算机上运行,与控制程序分离部署。

安装依赖

仅需 grpcio 即可运行;grpcio-tools 用于 build.sh 重新生成桩代码:

pip install -r mpc_client/python/requirements.txt
# requirements.txt: grpcio>=1.46.0  grpcio-tools>=1.46.0
sudo apt-get install -y protobuf-compiler libprotobuf-dev
sudo apt-get install -y nlohmann-json3-dev
# gRPC(grpc++)通常需自行编译安装(建议 v1.46.3),或使用系统/第三方预编译包

网络连接

使用网线将您的计算机与机器人连接至同一网段,网络配置方式见快速开发(真机)。服务端 gRPC 端口固定为 6666


配置服务端 IP

与 RL 客户端通过 --addr 传参不同,MPC 客户端在启动时读取 mpc_client/ip_config.json

{
  "server": {
    "ip": "192.168.x.x",
    "port": 6666,
    "comment": "ip 填写机器人网卡 IP;port 默认 6666,一般无需修改"
  }
}

配置要点

  • 修改 IP 后 C++ 客户端无需重新编译(运行时读取配置)。
  • 服务端口固定为 6666,应与机器人端 PndControl 启动日志中的 gRPC client connect address 一致。
  • 占位 IP(xx.xx.xx.xx0.0.0.0、空)会在启动时被拒绝并提示配置。

连接前检查清单

  1. 机器人端 PndControl 已启动,且编译时启用 gRPC(buildrobot.sh-Dgrpc_on=true)。
  2. 已执行 install.shsystemctl restart pnd_adam_dds.service 使新二进制生效。
  3. ip_config.json 中的 IP 与控制台打印的 gRPC 地址一致。
  4. 客户端机器到机器人 6666 端口网络可达(防火墙未阻断)。

编译与运行

cd mpc_client
chmod +x build.sh run.sh clean.sh

./build.sh        # 生成 C++/Python 桩代码 + cmake 编译,输出 bin/adam_command_client
./run.sh          # 默认启动 Python 客户端
./run.sh python   # 同上
./run.sh bin      # 启动 C++ 客户端(需先 build)
./clean.sh        # 删除 build/、bin/、lib/,保留 include/ 与 python/ 中的桩代码

也可直接运行:

cd mpc_client/python && python3 adam_command_client.py
cd mpc_client/bin && ./adam_command_client

build.sh 会依据 proto/adam_control.proto 生成桩代码,并在 build/ 下用 cmake 编译。若本机 protoc 版本与仓库内生成文件不同,可重复执行 ./build.sh 覆盖本地桩代码。


交互式 CLI 例程

Python 与 C++ 客户端均提供 REPL 交互:输入 help 查看命令,exit 返回/退出。客户端会根据机器人当前 FSM 状态动态启用命令,Python 客户端额外支持 Tab 补全且命令大小写不敏感。

$ ./run.sh python
Running Python client: .../mpc_client/python/adam_command_client.py
已连接到 gRPC 服务: 192.168.31.76:6666
Adam Command Client v1.1.0
Type 'help' for usage information.

> help
Available commands:
  SetMode
  SetStandMotion
  SetStandCarryBox
  SetStandAction
  SetStandDynamic
  SetSpeed
  AutoUnigaitCOM
  SetErrorClear
  GetStandList
  GetRobotState
  SetControlMode  <0=Traditional|1=RL>  -- switch control paradigm
  GetControlState                       -- query current control mode from DDS rt/control_mode_state
  clear
  exit

> GetRobotState
Current Mode: Start
Current Motion:
Enable Mode List: ['Zero']
Enable Motion List: []
Enable Action List: []
Enable Carry Box List: []
Stand Pitch: 0.0
Stand Roll: 0.0
Stand Yaw: 0.0
Stand Height: 0.0
X Velocity: 0.0
Y Velocity: 0.0
Yaw Velocity: 0.0
Balance Control State: False
Control Mode: 0 (Traditional)

> SetMode
Available Modes:  Zero
Enter parameter for Setmode: Zero
Success: Mode set successfully

> SetMode
Available Modes:  Stand
Enter parameter for Setmode: Stand
Success: Mode set successfully

> SetStandMotion
Available Motions:  Greeting, Chest Expansion, Stretching, Gentleman's Salute
Enter parameter for Setstandmotion: Greeting
Success: Motion executed successfully

> SetStandAction
Current action values (stand_pitch stand_roll stand_yaw base_height) (0.0, 0.0, 0.0, 0.0)
Please enter values within the following ranges:
  - Pitch: [-0.1, 0.1]
  - Roll: [-0.06, 0.06]
  - Yaw: [-0.25, 0.25]
  - Base Height: [-0.2, 0.0]
Action> Enter action values (stand_pitch stand_roll stand_yaw stand_height): 0.0 0.0 0.0 -0.1
Success: Action executed successfully

> GetControlState
Control State: domain_id=0 (Traditional)

> SetControlMode
Current control mode: 0 (Traditional)
Enter control mode (0/1): 1
  Waiting for hardware to switch to RL (timeout=30s, poll every 0.5s)...
  [  0.0s] Current mode: 0 (Traditional)
  [  2.5s] Current mode: 1 (RL)
Success: Switched to RL successfully.

> exit
Exiting Adam Command Client.

CLI 命令对照

命令 对应 RPC 适用模式 说明
SetMode SetMode mode_enable_list 切换 Start/Zero/Stand/Walk/Run/Stop
SetStandMotion SetStandMotion Stand 预定义动作(如 Greeting
SetStandCarryBox SetStandCarryBox Stand 搬箱动作(1蹲下/2站立/0放下)
SetStandAction SetStandAction Stand 姿态 pitch/roll/yaw + 蹲起高度
SetStandDynamic SetStandDynamic Stand 动态平衡开/关
SetSpeed SetSpeed Walk / Run 设置 x/y/yaw 速度(注意安全)
AutoUnigaitCOM AutoUnigaitCOM Walk / Run COM X 方向偏置平衡
SetErrorClear SetErrorClear Stop 清除驱动错误,无需关电
GetStandList GetStandList 任意 获取固定动作/模式列表
GetRobotState GetRobotState 任意 获取当前状态与各 *_enable_list
SetControlMode SetControlMode 任意 切换控制范式 0Traditional / 1RL
GetControlState GetControlState 任意 查询当前控制范式

先查状态再下发

下发模式/动作类指令前应先 GetRobotState,仅当目标模式/动作出现在对应 *_enable_list 中时才可执行;列表外的指令会被客户端或服务端拒绝。


典型控制流程

Start → Zero → Stand ┬─ SetStandMotion / SetStandAction / SetStandCarryBox / SetStandDynamic
                     └─ Walk / Run → SetSpeed / AutoUnigaitCOM
(异常)Stop → SetErrorClear

操作步骤:

  1. GetRobotState — 确认当前 FSM 与 mode_enable_list
  2. SetModeZero — 零位校准
  3. SetModeStand — 进入站立
  4. Stand 下执行动作,例如 SetStandMotionGreeting)或 SetStandAction(姿态/蹲起高度)
  5. 如需行走:SetModeWalk / Run,再用 SetSpeed 设置速度
  6. 若驱动报错:SetModeStop,再 SetErrorClear 清错

安全提示

  • SetSpeed 存在安全风险,生产环境建议使用手柄键控,客户端示例仅作接口演示。
  • SetStandAction 的 pitch/roll/yaw 与蹲起高度需在允许范围内(见下),超出会被拒绝。
  • 操作前请确保机器人处于安全悬挂或开阔场地,并遵循操作指南中的安全规范。

SetStandAction 姿态参数范围

参数 范围
Pitch [-0.1, 0.1]
Roll [-0.06, 0.06]
Yaw [-0.25, 0.25]
Base Height [-0.2, 0.0]

程序集成例程

交互式 CLI 适合手动调试。若需在自己的程序中集成,可参考以下封装。

Python

直接使用 Stub:

import grpc
import adam_control_pb2 as pb2
import adam_control_pb2_grpc as pb2_grpc

channel = grpc.insecure_channel("192.168.1.100:6666")
stub = pb2_grpc.RobotControlStub(channel)

# 切换模式
r = stub.SetMode(pb2.SetModeRequest(mode="Stand"))
print(r.success, r.message)

# 查询状态与 enable_list
s = stub.GetRobotState(pb2.GetRobotStateRequest(get_state_flag=True))
print(s.fsm_name, list(s.mode_enable_list))

# Stand 下执行动作
stub.SetStandMotion(pb2.SetStandMotionRequest(motion="Greeting"))
stub.SetStandAction(pb2.SetActionRequest(
    stand_pitch=0.0, stand_roll=0.0, stand_yaw=0.0, stand_height=-0.1))

# 切换控制范式并读取确认
stub.SetControlMode(pb2.SetControlModeRequest(domain_id=0))
ctrl = stub.GetControlState(pb2.GetControlStateRequest())
print(ctrl.domain_id)  # 0=Traditional, 1=RL

或复用示例客户端 adam_command_client.pyAdamCommand 的封装方法:

ok, msg = client.set_mode("Stand")
ok, msg = client.set_stand_motion("Greeting")
ok, msg = client.set_stand_action(0.0, 0.0, 0.0, -0.1)
ok, cur_mode, msg = client.set_control_mode(0)             # 下发切换指令
ok, final_mode, msg = client.wait_for_control_mode(0, timeout_sec=30)  # 轮询确认
client.get_control_state()

C++

#include "adam_command.h"

adam_control::AdamCommand client("192.168.1.100:6666");

std::string message;
bool ok = client.SetMode("Stand", message);

// 切换控制范式并轮询硬件确认(默认 30s 超时)
int final_mode = -1;
ok = client.SetControlModeAndWait(0, final_mode, message);

int domain_id = -1;
ok = client.GetControlState(domain_id, message);

可将 src/adam_command.cpp 编译为 libadam_command 链接到自有工程(见 src/CMakeLists.txt)。adam_command.h 另提供异步 API(如 SetModeAsync),适用于非阻塞集成场景。


代码解析

mpc_client/python/adam_command_client.py 的核心逻辑如下:

  1. 读取配置:从 ../ip_config.json 读取 ip / port 拼接服务端地址;占位 IP 会被拒绝并提示。
  2. 连接检查:连接前用 grpc.channel_ready_future 做 5s 超时检查,失败时打印排查提示(PndControl 是否启动、端口是否可达等)。
  3. 状态感知:每次命令前调用 GetRobotState 刷新 fsm_name 与各 *_enable_list,据此动态启用命令与 Tab 补全;Stand 才开放动作类命令,Walk/Run 才开放速度类命令,Stop 才开放 SetErrorClear
  4. 状态机输入:命令进入参数输入态(WAIT_PARAMETER / WAIT_SPEED_INPUT / WAIT_ACTION_INPUT),对枚举参数与数值范围做校验。
  5. 控制范式切换SetControlMode 下发 DDS rt/control_mode_cmd 后,轮询 GetControlState(默认 30s)确认硬件切换,与 C++ 客户端行为一致。

常见问题

现象 可能原因 处理建议
failed to connect to all addresses IP/端口错误或 gRPC 未启用 检查 ip_config.jsonPndControl 日志、防火墙、6666 端口可达性
this command can only be executed when mode is 'Stand' 未先切到对应模式 SetMode 切到 Stand(或 Walk/Run
Invalid parameter / enable_list 外指令 当前状态不允许该模式/动作 GetRobotState 查看 *_enable_list
SetControlMode 超时 硬件切换较慢 GetControlState 继续确认;检查 DDS 服务
ModuleNotFoundError: grpc 未安装 Python 依赖 pip install -r mpc_client/python/requirements.txt
C++ 编译找不到 nlohmann_json 未安装 dev 包 sudo apt install nlohmann-json3-dev

相关文档

文档 说明
传统控制 gRPC 接口说明 传统控制(MPC)模式 gRPC 接口定义与参数说明
gRPC 例程(强化学习) 强化学习(RL)模式客户端获取与交互示例
手臂控制例程 DDS 实时上肢控制
灵巧手控制说明 DDS 手指控制