一、核心概述

宇树G1机器人ROS 2通信开发的核心,是基于ROS 2 Humble框架构建上位机与机器人之间的高可靠通信链路,实现机器人状态感知、运动指令下发、模式切换等核心功能。官方提供的ROS 2通信例程深度适配Ubuntu 20.04/22.04系统,涵盖环境配置、驱动部署、话题通信、服务调用等全流程开发环节,为机器人的二次开发与场景落地提供了标准化的技术支撑。

二、详细使用步骤

步骤1:环境准备

1.1 系统与ROS 2版本要求

  • 操作系统:Ubuntu 20.04(Focal)或Ubuntu 22.04(Jammy)

  • ROS 2版本:Humble Hawksbill(官方推荐,兼容性最优)

  • 依赖工具:git、cmake、colcon、python3-pip

1.2 基础环境安装


# 1. 安装基础依赖工具
sudo apt update && sudo apt install -y git cmake build-essential python3-colcon-common-extensions python3-pip

# 2. 安装ROS 2 Humble(若未安装,参考官方标准流程)
# 导入ROS 2密钥与软件源
sudo apt install -y curl gnupg lsb-release
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
# 安装桌面版(含可视化工具)
sudo apt update && sudo apt install -y ros-humble-desktop

# 3. 配置ROS 2环境变量(永久生效)
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

# 4. 安装宇树G1专属驱动依赖
pip3 install transforms3d pyserial
sudo apt install -y ros-humble-rosbridge-suite ros-humble-tf2-tools ros-humble-robot-state-publisher

步骤2:获取G1 ROS 2源码与工作空间构建

2.1 创建并初始化ROS 2工作空间


# 创建工作空间目录结构
mkdir -p ~/unitree_g1_ws/src
cd ~/unitree_g1_ws/src

# 克隆宇树G1 ROS 2官方源码仓库
git clone https://github.com/unitreerobotics/unitree_ros2.git
# 切换至G1专属开发分支(以官方最新分支为准,此处为示例)
cd unitree_ros2
git checkout g1-devel

2.2 编译工作空间与环境配置


# 回到工作空间根目录
cd ~/unitree_g1_ws

# 编译工作空间(--symlink-install避免重复编译,提升效率)
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
# 配置工作空间环境变量(永久生效)
echo "source ~/unitree_g1_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc

# 验证环境配置(查看G1相关功能包)
ros2 pkg list | grep unitree_g1

若输出“unitree_g1_bringup”“unitree_g1_msgs”等包名,说明环境配置成功。

步骤3:机器人与上位机通信连接搭建

3.1 两种连接方式配置

宇树G1支持有线、无线两种连接模式,可根据开发场景灵活选择:

  1. 有线直连(推荐开发调试,稳定性高):用网线连接上位机网口与G1机器人网口;进入上位机“网络设置”,手动配置IP为192.168.123.xxx(xxx范围11-254),子网掩码255.255.255.0,网关192.168.123.1;G1机器人默认有线IP为192.168.123.10。

  2. 无线连接(适合移动场景测试):开启G1机器人后,上位机搜索并连接机器人WiFi热点(默认名称:Unitree-G1-xxxx,密码:unitree123);连接成功后,上位机将自动获取192.168.1.xxx网段IP,G1默认无线IP为192.168.1.10。

3.2 连接有效性验证


# 有线连接验证(ping机器人默认IP)
ping 192.168.123.10 -c 4
# 无线连接验证(ping机器人默认IP)
# ping 192.168.1.10 -c 4

若出现“4 packets transmitted, 4 received”,说明网络连接正常;若丢包或超时,需检查IP配置、网线连接或机器人WiFi热点状态。

步骤4:G1 ROS 2核心驱动启动与通信链路验证

4.1 启动核心驱动节点


# 启动G1基础驱动(包含状态发布、指令接收、模式管理核心功能)
ros2 launch unitree_g1_bringup g1_bringup.launch.py

启动成功标志:终端无红色错误信息,持续输出“Robot state published successfully”等日志。

4.2 核心话题与服务验证


# 1. 查看G1相关所有话题
ros2 topic list | grep unitree_g1
# 核心话题说明:
# /unitree_g1/state:机器人状态话题(含电池、位姿、关节状态、里程计等)
# /unitree_g1/cmd_vel:速度控制指令话题(线速度、角速度)
# /unitree_g1/joint_cmd:关节控制指令话题(单关节/多关节角度控制)
# /unitree_g1/sensor_data:传感器数据话题(IMU、超声波等)

# 2. 查看状态话题数据(实时打印)
ros2 topic echo /unitree_g1/state -n 5  # -n 5表示只打印5条数据

# 3. 查看G1相关所有服务
ros2 service list | grep unitree_g1
# 核心服务说明:
# /unitree_g1/set_mode:机器人模式设置服务(待机/站立/行走/趴卧)
# /unitree_g1/reset_robot:机器人复位服务(关节归零、状态重置)
# /unitree_g1/set_gain:控制增益设置服务(调节运动平滑度)

步骤5:核心功能开发实战示例

5.1 示例1:速度控制(发布/cmd_vel话题)

功能说明:通过发布Twist类型消息到/cmd_vel话题,实现机器人前进、后退、旋转等基础运动控制。

代码文件路径:~/unitree_g1_ws/src/unitree_ros2/unitree_g1_examples/scripts/velocity_control.py


#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist

class G1VelocityController(Node):
    def __init__(self):
        super().__init__('g1_velocity_controller')
        # 创建话题发布者,队列大小10(确保消息不丢失)
        self.vel_publisher = self.create_publisher(Twist, '/unitree_g1/cmd_vel', 10)
        # 定时器回调(10Hz发布频率,与机器人控制频率匹配)
        self.timer = self.create_timer(0.1, self.timer_callback)
        self.get_logger().info("G1速度控制节点已启动,开始下发运动指令...")

    def timer_callback(self):
        # 构造速度指令消息
        vel_msg = Twist()
        # 线速度x:0.2m/s(前进,范围:-0.5~0.5m/s,避免超阈值报错)
        vel_msg.linear.x = 0.2
        vel_msg.linear.y = 0.0  # G1不支持横向平移,固定为0
        vel_msg.linear.z = 0.0
        # 角速度z:0.1rad/s(右转,范围:-0.8~0.8rad/s)
        vel_msg.angular.x = 0.0
        vel_msg.angular.y = 0.0
        vel_msg.angular.z = 0.1

        # 发布指令
        self.vel_publisher.publish(vel_msg)
        self.get_logger().info(f"下发速度指令:线速度x={vel_msg.linear.x}m/s,角速度z={vel_msg.angular.z}rad/s")

def main(args=None):
    rclpy.init(args=args)
    controller_node = G1VelocityController()
    try:
        # 保持节点运行
        rclpy.spin(controller_node)
    except KeyboardInterrupt:
        # 按下Ctrl+C时,发布停止指令
        stop_msg = Twist()
        controller_node.vel_publisher.publish(stop_msg)
        controller_node.get_logger().info("接收到中断信号,发布停止指令,节点退出...")
    finally:
        # 资源清理
        controller_node.destroy_node()
        rclpy.shutdown()

if __name__ == '__main__':
    main()

运行流程:


# 1. 赋予脚本执行权限
chmod +x ~/unitree_g1_ws/src/unitree_ros2/unitree_g1_examples/scripts/velocity_control.py

# 2. 编译新增节点(仅编译示例功能包,提升效率)
cd ~/unitree_g1_ws && colcon build --packages-select unitree_g1_examples

# 3. 启动速度控制节点(需先启动核心驱动)
ros2 run unitree_g1_examples velocity_control.py

5.2 示例2:机器人状态监控(订阅/state话题)

功能说明:订阅/unitree_g1/state话题,解析并打印机器人核心状态信息(电池电压、运动模式、实际速度等),用于开发监控模块。

代码文件路径:~/unitree_g1_ws/src/unitree_ros2/unitree_g1_examples/scripts/state_monitor.py


#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
# 导入G1自定义状态消息类型(需确保unitree_g1_msgs已编译)
from unitree_g1_msgs.msg import G1State

class G1StateMonitor(Node):
    def __init__(self):
        super().__init__('g1_state_monitor')
        # 创建话题订阅者,回调函数处理状态数据
        self.state_subscriber = self.create_subscription(
            G1State,
            '/unitree_g1/state',
            self.state_callback,
            10  # 队列大小
        )
        self.state_subscriber  # 防止变量被垃圾回收
        self.get_logger().info("G1状态监控节点已启动,持续接收状态数据...")

    def state_callback(self, msg):
        # 解析核心状态字段
        battery_volt = msg.battery_voltage  # 电池电压(V,低于11.5V需充电)
        robot_mode = self.parse_robot_mode(msg.robot_mode)  # 解析模式含义
        actual_vel_x = msg.odom.twist.twist.linear.x  # 实际前进速度(m/s)
        actual_ang_z = msg.odom.twist.twist.angular.z  # 实际旋转角速度(rad/s)
        joint_states = msg.joint_states  # 关节状态(角度、速度、力矩)

        # 打印核心状态信息
        self.get_logger().info(
            f"===== G1机器人状态 ====="
            f"\n电池电压:{battery_volt:.2f}V"
            f"\n当前模式:{robot_mode}"
            f"\n实际线速度x:{actual_vel_x:.2f}m/s"
            f"\n实际角速度z:{actual_ang_z:.2f}rad/s"
            f"\n关节数量:{len(joint_states.name)}"
        )

    def parse_robot_mode(self, mode_val):
        # 模式值解析(对应官方定义)
        mode_map = {
            0: "待机模式(Idle)",
            1: "站立模式(Stand)",
            2: "行走模式(Walk)",
            3: "趴卧模式(LieDown)",
            4: "复位模式(Reset)"
        }
        return mode_map.get(mode_val, f"未知模式({mode_val})")

def main(args=None):
    rclpy.init(args=args)
    monitor_node = G1StateMonitor()
    try:
        rclpy.spin(monitor_node)
    except KeyboardInterrupt:
        monitor_node.get_logger().info("状态监控节点退出...")
    finally:
        monitor_node.destroy_node()
        rclpy.shutdown()

if __name__ == '__main__':
    main()

运行流程:


# 1. 赋予执行权限
chmod +x ~/unitree_g1_ws/src/unitree_ros2/unitree_g1_examples/scripts/state_monitor.py

# 2. 编译功能包
cd ~/unitree_g1_ws && colcon build --packages-select unitree_g1_examples

# 3. 启动监控节点
ros2 run unitree_g1_examples state_monitor.py

5.3 示例3:服务调用(设置机器人站立模式)

功能说明:通过调用/unitree_g1/set_mode服务,将机器人从待机模式切换为站立模式,是运动控制的前置步骤。

代码文件路径:~/unitree_g1_ws/src/unitree_ros2/unitree_g1_examples/scripts/set_stand_mode.py


#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
# 导入G1模式设置服务类型
from unitree_g1_msgs.srv import SetMode

class G1StandModeSetter(Node):
    def __init__(self):
        super().__init__('g1_stand_mode_setter')
        # 创建服务客户端,指定服务名与服务类型
        self.set_mode_client = self.create_client(SetMode, '/unitree_g1/set_mode')
        # 等待服务端就绪(超时5秒,避免无限等待)
        while not self.set_mode_client.wait_for_service(timeout_sec=5.0):
            self.get_logger().warn("/unitree_g1/set_mode服务未就绪,等待中...")
        self.get_logger().info("/unitree_g1/set_mode服务已就绪,准备发送站立模式请求...")

    def send_stand_request(self):
        # 构造服务请求(mode=1对应站立模式)
        request = SetMode.Request()
        request.mode = 1  # 模式定义:0=待机,1=站立,2=行走,3=趴卧
        # 发送异步请求并等待结果
        future = self.set_mode_client.call_async(request)
        rclpy.spin_until_future_complete(self, future)

        # 处理服务响应
        if future.done():
            try:
                response = future.result()
                if response.success:
                    self.get_logger().info("机器人站立模式设置成功!")
                else:
                    self.get_logger().error("机器人站立模式设置失败,响应状态:失败")
            except Exception as e:
                self.get_logger().error(f"调用服务失败:{str(e)}")

def main(args=None):
    rclpy.init(args=args)
    mode_setter = G1StandModeSetter()
    # 发送站立模式请求
    mode_setter.send_stand_request()
    # 资源清理
    mode_setter.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

运行流程:


# 1. 赋予执行权限
chmod +x ~/unitree_g1_ws/src/unitree_ros2/unitree_g1_examples/scripts/set_stand_mode.py

# 2. 编译功能包
cd ~/unitree_g1_ws && colcon build --packages-select unitree_g1_examples

# 3. 启动服务调用节点(需先启动核心驱动)
ros2 run unitree_g1_examples set_stand_mode.py

三、常见问题与解决方案

问题1:驱动启动失败,提示“找不到unitree_g1_bringup功能包”

核心原因:工作空间未编译成功、环境变量未配置或配置错误。

解决方案:

  1. 检查工作空间编译日志:进入~/unitree_g1_ws,查看colcon build编译输出,若有红色错误(如依赖缺失、语法错误),根据错误信息补全依赖(如sudo apt install 缺失的包),重新编译;

  2. 验证环境变量:执行echo $ROS_PACKAGE_PATH,查看输出是否包含“~/unitree_g1_ws/install/share”,若未包含,重新执行source /unitree_g1_ws/install/setup.bash,或检查/.bashrc文件中是否添加了该环境变量(可通过cat ~/.bashrc查看);

  3. 若环境变量配置正确仍报错,删除build、install、log三个编译目录,重新编译:rm -rf build install log && colcon build --symlink-install。

问题2:话题无数据(ros2 topic echo无输出)或话题不存在

核心原因:驱动节点未正常启动、机器人未开机/未连接、话题名拼写错误。

解决方案:

  1. 检查驱动节点状态:执行ros2 node list,查看是否存在“/unitree_g1_node”节点,若不存在,重新启动驱动(ros2 launch unitree_g1_bringup g1_bringup.launch.py),并查看终端错误日志;

  2. 验证机器人连接:重新执行ping命令(如ping 192.168.123.10),确认网络连通;若机器人未开机,先开机并等待1-2分钟(机器人系统启动需要时间);

  3. 检查话题名:确保话题名拼写与驱动一致(区分大小写),正确话题名前缀为“/unitree_g1/”,可通过ros2 topic list | grep unitree_g1确认实际存在的话题;

  4. 无线连接场景特殊检查:确认上位机连接的是G1专属WiFi热点,而非其他同名网络,可重新断开WiFi并重新连接。

问题3:指令下发无响应(如发布cmd_vel后机器人不动)

核心原因:机器人未进入运动模式、指令值超安全阈值、话题发布频率不匹配。

解决方案:

  1. 检查机器人模式:必须先通过/set_mode服务将机器人设置为“行走模式(mode=2)”或“站立模式(mode=1)”,待机模式(mode=0)下无法响应运动指令;可通过订阅/state话题查看当前模式;

  2. 验证指令值范围:G1安全速度阈值为:线速度x∈[-0.5, 0.5]m/s,角速度z∈[-0.8, 0.8]rad/s,若指令值超出范围,机器人会忽略指令,需调整指令值至安全范围;

  3. 检查发布频率:机器人控制频率为10Hz,若发布频率过低(如1Hz),可能导致指令响应延迟或无响应,需将发布频率设置为10Hz左右(通过定时器0.1秒回调实现);

  4. 检查关节状态:若机器人处于趴卧模式(mode=3)或关节卡滞,运动指令也无法响应,可调用/reset_robot服务复位机器人后再测试。

问题4:编译时提示“缺少unitree_g1_msgs消息类型”

核心原因:消息功能包(unitree_g1_msgs)未编译,或编译顺序错误(先编译依赖消息的包,再编译消息包)。

解决方案:

  1. 单独编译消息功能包:cd ~/unitree_g1_ws && colcon build --packages-select unitree_g1_msgs,确保消息包编译成功;

  2. 重新编译整个工作空间:colcon build --symlink-install,让依赖消息的功能包(如unitree_g1_bringup、unitree_g1_examples)能正确找到消息类型;

  3. 若仍报错,删除消息包的编译产物:rm -rf install/unitree_g1_msgs log/unitree_g1_msgs,再重新编译消息包和整个工作空间。

问题5:机器人电池电压正常,但频繁掉线或通信卡顿

核心原因:网络连接不稳定、上位机防火墙拦截、机器人WiFi信号弱。

解决方案:

  1. 优先切换为有线连接:有线连接稳定性远高于无线,开发调试阶段建议使用有线直连;

  2. 关闭上位机防火墙:sudo ufw disable(Ubuntu默认防火墙关闭,若手动开启需关闭),避免防火墙拦截ROS 2通信端口;

  3. 优化无线连接:若必须使用无线,确保上位机与机器人距离不超过5米,无遮挡物;可重启机器人WiFi热点(重启机器人)后重新连接;

  4. 检查网络带宽:若同一网络下有其他设备占用大量带宽,可能导致通信卡顿,可断开其他设备后测试。

问题6:调用/set_mode服务提示“服务调用失败,连接超时”

核心原因:服务端未启动、网络连接中断、服务名错误。

解决方案:

  1. 确认驱动节点已启动:ros2 node list查看是否存在/unitree_g1_node,若不存在,重新启动驱动;

  2. 验证服务是否存在:ros2 service list | grep /unitree_g1/set_mode,确认服务存在后再调用;

  3. 检查网络连接:重新ping机器人IP,若丢包率高,解决网络问题(如更换网线、靠近机器人);

  4. 增加服务等待时间:在服务客户端代码中,将wait_for_service的超时时间从5秒改为10秒,避免服务端启动慢导致的连接超时。

问题7:ROS 2节点启动时提示“未找到Python模块transforms3d”

核心原因:未安装宇树G1驱动所需的Python依赖。

解决方案:

  1. 使用pip3安装缺失模块:pip3 install transforms3d pyserial(这两个是G1驱动核心Python依赖);

  2. 若安装后仍报错,检查Python环境:确认使用的是Python3(ROS 2 Humble默认使用Python3),执行which python3,确保pip3安装的模块路径在Python3的site-packages目录下(可通过pip3 show transforms3d查看安装路径);

  3. 若使用虚拟环境,需在虚拟环境中重新安装依赖,并确保启动ROS 2节点时激活了虚拟环境。

四、总结

宇树G1机器人ROS 2通信开发的核心逻辑,是基于“环境配置-源码编译-连接搭建-驱动启动-功能开发”的全流程标准化范式,通过ROS 2的话题、服务通信机制,实现上位机与机器人的双向数据交互。核心要点可归纳为三点:一是环境适配,必须严格匹配Ubuntu 20.04/22.04与ROS 2 Humble版本,避免兼容性问题;二是通信链路验证,驱动启动后需优先通过topic/list、service/list等命令确认通信基础正常;三是指令合规性,运动指令需严格遵循安全阈值,模式切换需按“待机-站立-行走”的逻辑顺序执行。

本文扩充的常见问题解决方案,覆盖了环境配置、编译构建、通信连接、功能执行等全环节高频问题,可有效降低开发调试成本。后续进阶开发(如SLAM建图、自主导航、视觉融合控制)可基于本文的基础通信框架,扩展对应的功能包(如ROS 2的slam_toolbox、nav2等),实现更复杂的机器人应用场景落地。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐