ROS2 Teleop over OmniSocket UDP/KCP
ros-control-py/udp_teleop_bridge 现在把 teleop 控制流统一接到 OmniSocket peer 传输上。
transport:=udp表示 OmniSocket UDP,经udpserver/udppeer的消息协议传输transport:=kcp表示 OmniSocket KCP,经kcpserver/kcppeer的消息协议传输- 不再使用原来的裸
socket.sendto()/recvfrom()UDP 路径
机器人最终接收的话题保持不变:
- topic:
/hric/robot/cmd_vel - type:
geometry_msgs/msg/TwistStamped - frame_id:
pelvis
控制负载也保持不变:
- fixed payload: 24-byte little-endian
<6f> - order:
lx, ly, lz, ax, ay, az
目录
udp_teleop_bridge/udp_teleop_bridge/cmd_vel_udp_sender.py: 订阅TwistStamped,经 OmniSocket 发送 24 字节控制包udp_teleop_bridge/udp_teleop_bridge/udp_cmd_vel_receiver.py: 从 OmniSocket 接收控制包,补时间戳并发布到机器人 ROS2 topicudp_teleop_bridge/udp_teleop_bridge/omni_transport.py: 统一封装 OmniSocket UDP/KCP sessionudp_teleop_bridge/config/xbox_twist_joy.yaml: Xbox 手柄映射udp_teleop_bridge/launch/*.launch.py: Linux 启动入口
Linux 构建
先安装 ROS 2 官方 teleop 依赖:
sudo apt install ros-${ROS_DISTRO}-joy ros-${ROS_DISTRO}-teleop-twist-joy ros-${ROS_DISTRO}-teleop-twist-keyboard
再构建并安装 OmniSocket Python 扩展:
make python-ext
make python-install
最后构建 ROS 包:
colcon build --packages-select udp_teleop_bridge
source install/setup.bash
如果 omnisocket 没有安装到当前 ROS Python 环境,sender/receiver 会直接报错退出。
先验证机器人控制语义
在机器人本机先直接低速发布 /hric/robot/cmd_vel,确认 linear.x、linear.y、angular.z 的物理方向符合预期:
ros2 topic pub /hric/robot/cmd_vel geometry_msgs/msg/TwistStamped \
"{header: {frame_id: pelvis}, twist: {linear: {x: 0.10, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}}" \
-r 20
ros2 topic pub /hric/robot/cmd_vel geometry_msgs/msg/TwistStamped \
"{header: {frame_id: pelvis}, twist: {linear: {x: 0.0, y: 0.10, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}}" \
-r 20
ros2 topic pub /hric/robot/cmd_vel geometry_msgs/msg/TwistStamped \
"{header: {frame_id: pelvis}, twist: {linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.30}}}" \
-r 20
停止:
ros2 topic pub --once /hric/robot/cmd_vel geometry_msgs/msg/TwistStamped \
"{header: {frame_id: pelvis}, twist: {linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}}"
启动 OmniSocket Hub
OmniSocket UDP:
./bin/udpserver -listen :9001
OmniSocket KCP:
./bin/kcpserver -listen :9002
server_addr 不传时,节点会按 transport 自动选择默认值:
udp->127.0.0.1:9001kcp->127.0.0.1:9002
relay_via 只在 transport:=kcp 时生效。
机器人端运行
UDP:
ros2 launch udp_teleop_bridge robot_udp_receiver.launch.py \
transport:=udp \
server_addr:=127.0.0.1:9001 \
peer_id:=ros-bridge-ctrl \
output_topic:=/hric/robot/cmd_vel \
frame_id:=pelvis \
watchdog_timeout:=0.5
KCP:
ros2 launch udp_teleop_bridge robot_udp_receiver.launch.py \
transport:=kcp \
server_addr:=127.0.0.1:9002 \
peer_id:=ros-bridge-ctrl \
output_topic:=/hric/robot/cmd_vel \
frame_id:=pelvis \
watchdog_timeout:=0.5
如果只允许某个 sender 控制,可以加:
expected_sender:=ros-keyboard-ctrl
控制端键盘运行
终端 A,启动 sender:
ros2 launch udp_teleop_bridge keyboard_sender.launch.py \
transport:=udp \
server_addr:=127.0.0.1:9001 \
peer_id:=ros-keyboard-ctrl \
target_peer:=ros-bridge-ctrl
如果走 KCP:
ros2 launch udp_teleop_bridge keyboard_sender.launch.py \
transport:=kcp \
server_addr:=127.0.0.1:9002 \
peer_id:=ros-keyboard-ctrl \
target_peer:=ros-bridge-ctrl
终端 B,启动官方键盘 teleop:
ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args \
--remap cmd_vel:=/teleop/cmd_vel \
-p stamped:=true \
-p frame_id:=pelvis \
-p speed:=0.20 \
-p turn:=0.60
键盘默认键位(teleop_twist_keyboard,建议使用 US 键盘布局):
i: 前进(linear.x > 0),: 后退(linear.x < 0)j: 左转(angular.z > 0)l: 右转(angular.z < 0)Shift + J: 左平移(linear.y > 0)Shift + L: 右平移(linear.y < 0)u/o/m/.: 组合前进或后退加转向k或其他未映射按键: 停止q/z: 整体速度增加 / 降低 10%w/x: 仅线速度增加 / 降低 10%e/c: 仅角速度增加 / 降低 10%Ctrl-C: 退出键盘 teleop
控制端 Xbox 手柄运行
UDP:
ros2 launch udp_teleop_bridge xbox_to_udp.launch.py \
transport:=udp \
server_addr:=127.0.0.1:9001 \
peer_id:=ros-gamepad-ctrl \
target_peer:=ros-bridge-ctrl \
joy_dev:=/dev/input/js0 \
frame_id:=pelvis
KCP:
ros2 launch udp_teleop_bridge xbox_to_udp.launch.py \
transport:=kcp \
server_addr:=127.0.0.1:9002 \
peer_id:=ros-gamepad-ctrl \
target_peer:=ros-bridge-ctrl \
joy_dev:=/dev/input/js0 \
frame_id:=pelvis
当前默认手柄映射:
- 左摇杆上下 ->
linear.x - 左摇杆左右 ->
linear.y - 右摇杆左右 ->
angular.z RB按住才允许运动LB为 turbo
手柄实际操控含义(基于 config/xbox_twist_joy.yaml 的 Xbox 默认映射):
- 左摇杆向前 / 向后: 前进 / 后退
- 左摇杆向左 / 向右: 左平移 / 右平移
- 右摇杆向左 / 向右: 左转 / 右转
- 按住
RB: 以常速启用运动输出 - 同时按住
LB+RB: 启用 turbo,更高的线速度和角速度 - 松开
RB或将摇杆回中: 输出回到零速
数据流
键盘链路:
teleop_twist_keyboard -> /teleop/cmd_vel (TwistStamped) -> cmd_vel_udp_sender -> OmniSocket UDP/KCP -> udp_cmd_vel_receiver -> /hric/robot/cmd_vel
手柄链路:
joy_node -> teleop_twist_joy -> /teleop/cmd_vel (TwistStamped) -> cmd_vel_udp_sender -> OmniSocket UDP/KCP -> udp_cmd_vel_receiver -> /hric/robot/cmd_vel
安全行为
- sender 默认按 20 Hz 重发最新命令
- sender 输入超时后会改发零速
- sender 退出时会主动发送数个零速控制包
- receiver 超时后会在 ROS 主线程发布零速 stop
- receiver 只接受
MSG_TYPE_BINARY且长度为 24 字节的负载 - 非预期 sender、非 binary 消息、错误长度消息都会被丢弃并记录日志