[具身智能-705]:遥控手柄与主机之间的协议:遥控手柄与机器人主机之间的协议 以及每个数字编号的含义
and 15 buttons (BtnA, BtnB, BtnC, BtnX, BtnY, BtnZ, BtnTL, BtnTR, BtnTL2, BtnTR2, BtnSelect, BtnStart, BtnMode, BtnThumbL, BtnThumbR).
Testing ... (interrupt to exit)
Axes: 0: 0 1: 0 2: 0 3: 0 4:-32767 5:-32767 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off 12:off 13:off 14:off
备注:
on:标识手柄对应的按键按下
off:标识手柄对应的按键松开
一、分层说明:手柄 ↔ 机器人完整通信链路
分成三层协议,很多开发人员容易混淆:
层级 1:物理传输协议(手柄硬件 ↔ Ubuntu 主机)
手柄是 USB 游戏手柄(VID 0079 国产控制器) 通信标准:USB HID 协议
- 手柄硬件内部:定时通过 USB 上报 HID 报告(原始二进制数据包)
- 报文包含:所有摇杆模拟量、按键开关状态
- 操作系统内核 hid 驱动 → evdev 子系统 → js 驱动
两个独立内核接口: 1)evdev(/dev/input/eventX,现代标准) 2)legacy joystick API(/dev/input/js0,
jstest使用这套)
层级 2:Linux 内核 JS API 协议(/dev/input/js0,jstest 读取的数据)
当前
jstest看到的所有数字,就是这一层解析出来的数据 内核持续向外输出js_event结构体:
c
运行
struct js_event {
__u32 time; // 时间戳
__s16 value; // 值范围 [-32767 ~ +32767]
__u8 type; // 轴事件 / 按键事件
__u8 number; // 【重点】轴编号/按键编号
};
number = 你看到的数字编号
层级 3:ROS2 应用层协议(joy_node)
joy_node 读取 /dev/input/js0,把内核 js 事件转换为 ROS 标准消息: sensor_msgs/msg/Joy
plaintext
std_msgs/Header header
float32[] axes # 浮点 [-1.0 ~ 1.0],对应轴0~7
int32[] buttons # 0=松开,1=按下,对应按键0~14
二、全部编号定义(js0 接口,唯一对照表,ROS 开发直接复制)
🎮 Axes 模拟轴 number【0 ~ 7】
表格
| 编号 number | 名称 | 硬件部件 | 取值规则 | 当前初始值 |
|---|---|---|---|---|
| 0 | X |
左摇杆:左右 前进后退 | 左 =-32767,居中 = 0,右 =+32767 | 0 |
| 1 | Y |
左摇杆:上下 左移右移 | 上 =-32767,居中 = 0,下 =+32767 | 0 |
| 2 | Z |
右摇杆:左右 左转右旋 | 左 =-32767,居中 = 0,右 =+32767 | 0 |
| 3 | Rz |
右摇杆:上下 上旋下旋(俯仰) | 上 =-32767,居中 = 0,下 =+32767 | 0 |
| 4 | Gas | LT 左线性扳机 | 松开 =-32767,按到底 =+32767 | -32767 |
| 5 | Brake | RT 右线性扳机 | 松开 =-32767,按到底 =+32767 | -32767 |
| 6 | Hat0X | 十字方向键 ←→ | 左 =-32767,无操作 = 0,右 =+32767 | 0 |
| 7 | Hat0Y | 十字方向键 ↑↓ | 上 =-32767,无操作 = 0,下 =+32767 | 0 |
⚠️关键:内核原始值
-32767 ~ 32767ROS joy_node 自动线性映射 →[-1.0, 1.0]
🎯 Buttons 按键 number【0 ~ 14】
事件 value:1=按下 on,0=松开 off
表格
| 编号 number | 标识 | 物理按键 |
|---|---|---|
| 0 | BtnA | A 键 |
| 1 | BtnB | B 键 |
| 2 | BtnC | C 键 |
| 3 | BtnX | X 键 |
| 4 | BtnY | Y 键 |
| 5 | BtnZ | Z 键 |
| 6 | BtnTL | LB 左上肩按键 |
| 7 | BtnTR | RB 右上肩按键 |
| 8 | BtnTL2 | LT 扳机底部机械开关 |
| 9 | BtnTR2 | RT 扳机底部机械开关 |
| 10 | BtnSelect | Select 选择键 |
| 11 | BtnStart | Start 开始键 |
| 12 | BtnMode | Mode 模式键 |
| 13 | BtnThumbL | L3(左摇杆垂直按下) |
| 14 | BtnThumbR | R3(右摇杆垂直按下) |
三、重要工程坑(机器人遥控必看)
1. LT/RT 扳机初始偏移问题
轴 4、轴 5 静止 =-32767 → ROS axes 读到 -1.0 如果你想用扳机控制速度,需要归一化矫正公式:
plaintext
# 原始值 [-32767,32767] → [0, 1]
output = (raw_value + 32767) / 65534.0
2. 两套接口编号不互通
/dev/input/js0:旧 JS 接口,编号如上表(jstest)/dev/input/eventX:evdev 接口(evtest) 两套的轴 / 按键编号完全独立,不能混用映射表!
3. 通信延迟说明
USB HID 轮询频率通常 100Hz; Linux 增加少量内核调度延迟;ROS2 层总体延迟足够移动机器人遥控使用。
四、机器人常用映射方案(直接用于代码)
示例:差分底盘遥控
plaintext
axes[1] 左摇杆上下 → 前进/后退速度
axes[2] 右摇杆左右 → 转向角速度
buttons[11] Start键 → 启动机器人
buttons[10] Select键 → 紧急停止
五、补充建议
长远推荐改用 evdev(/dev/input/by-id/xxx-event-if01) 支持震动、陀螺仪拓展,joy_node 同样兼容 evdev 设备; 不要再依赖 js0 老旧接口。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)