如果你在2024年之前关注人形机器人,大概率会听到波士顿动力(Boston Dynamics)的Atlas、本田的ASIMO,或者特斯拉的Optimus。这些名字背后,是动辄数十年的研发积累、数亿美元的资金投入,以及全球顶尖的实验室。人形机器人,似乎天生就是“巨头游戏”。
但就在最近,一家中国公司——宇树科技(Unitree Robotics)——以“人形机器人第一股”的身份登陆资本市场,打破了这种认知。它的故事,并非始于豪华的实验室,而是一个“草根班子”在杭州的十年跋涉。
这背后真正的问题是什么?一个初创团队,凭什么能在巨头林立的赛道里,不仅活下来,还能率先上市?这绝不仅仅是一个商业奇迹。对于开发者、机器人爱好者乃至所有关注硬科技创业的人来说,宇树的路径揭示了一个更本质的答案:将复杂的机器人技术,通过极致的工程化、模块化和开源策略,变成可被更多人理解和使用的“产品”。
本文将带你一口气看完宇树的十年。我们不止于复述其发展历程,更要深入拆解:它的技术栈究竟有何不同?其开源的“G1”人形机器人软件架构,为开发者社区带来了什么?从四足机器人到人形机器人,技术迁移的关键是什么?更重要的是,作为技术人员,我们能从中学到什么,甚至如何基于其开源生态开始自己的机器人开发?
1. 宇树十年:一条非典型的硬科技突围路径
宇树的故事,起点并不在聚光灯下。2016年,其创始人王兴兴还在上海大学攻读硕士学位时,就凭借开源项目“XDog”在极客圈内小有名气。与许多追求顶尖论文和实验室原型的团队不同,宇树从一开始就带着强烈的“产品思维”和“成本意识”。
第一阶段:四足机器人的“农村包围城市”(2016-2020)宇树没有直接挑战最高难度的“人形”,而是选择了技术相对成熟、应用场景更明确的四足机器人作为切入点。其推出的“Laikago”、“Aliengo”、“A1”等系列产品,核心突破在于自研高性能电机(关节)和运动控制算法。他们通过结构创新和供应链优化,将一台能跑能跳的四足机器人价格从波士顿动力Spot的数十万美元,拉低到数万人民币级别。这一步至关重要:它验证了团队在核心硬件(关节)和底层运动控制上的能力,并形成了稳定的现金流和品牌认知。
第二阶段:技术平台化与社区建设(2020-2023)在四足领域站稳脚跟后,宇树开始系统性地构建其技术中台。最标志性的事件是2021年开源其高性能电机接口和部分控制代码。这一举动看似“慷慨”,实则极具战略眼光:
- 吸引开发者:降低了机器人开发的门槛,让高校、研究机构甚至个人开发者能够基于宇树的硬件进行二次开发。
- 建立标准:其电机接口协议(如Unitree Motor Protocol)逐渐在圈内形成事实标准,增强了生态粘性。
- 反哺研发:来自社区的反馈和创意,成为其产品迭代的重要输入。
第三阶段:进军人形与资本化(2023-2024)在积累了足够的关节技术、运动控制经验和开发者生态后,宇树在2023年正式发布其首款通用人形机器人H1,并在2024年推出更亲民、主打开源的教育研发型人形机器人G1。上市,则是这条技术产品化道路水到渠成的里程碑。它证明了一条路径的可行性:通过极致工程化控制成本,通过开源构建生态,通过产品迭代验证技术,最终在资本市场上获得支持,以进行更长远的技术攻坚。
与特斯拉Optimus的“自动驾驶大脑”优先、波士顿动力的“极致运动性能”优先不同,宇树的路径更贴近工程师思维:先解决“能动”的问题(高性能关节),再解决“怎么动”的问题(运动控制),最后才是“动去干嘛”的问题(AI与任务规划)。这种自底向上的务实风格,是其能快速迭代并推出可用产品的关键。
2. 技术内核拆解:为什么是“关节”决定了天花板?
要理解宇树,必须理解其最核心的竞争力——自研高性能关节模组。在机器人领域,关节相当于人类的“肌肉”和“肌腱”,直接决定了机器人的力量、速度、精度和续航。宇树在这方面做到了高度自主。
2.1 关节模组的核心构成一个典型的宇树机器人关节(如其M系列电机)通常集成以下部分:
- 无框力矩电机:提供动力源,追求高扭矩密度。
- 谐波减速器:增大输出扭矩,实现精密传动。
- 双编码器系统:电机端编码器(控制电流环)和输出端编码器(控制位置环),实现高精度闭环控制。
- 驱动器(FOC控制器):集成在关节内部,实现磁场定向控制,响应快、效率高。
- 通信接口:通常采用CAN总线,实现高速、可靠的分布式控制。
这种高度集成的设计,带来了几个显著优势:
- 简化系统设计:机器人本体只需进行机械结构设计和关节排布,电气连接大幅简化。
- 提升可靠性:模块化设计降低了整机调试难度和故障率。
- 便于量产与维护:标准化的关节可以作为通用部件,用于不同型号的机器人。
2.2 与开源软件的对接:Unitree SDK硬件优势需要通过软件释放。宇树为其机器人提供了较为完善的软件开发工具包(SDK)。以四足机器人为例,其SDK通常包含:
- 低级API:直接控制单个关节的位置、速度、扭矩。
- 高级API:提供步态控制接口,如设置行走速度、转向、步高等。
- 仿真工具:基于Gazebo或Isaac Sim的仿真模型,便于算法开发与测试。
# 示例:使用Python SDK控制A1机器人前进(概念性代码) import unitree_sdk # 创建机器人接口 robot = unitree_sdk.A1Robot() robot.init() # 初始化连接 # 设置基础步态参数 gait_param = unitree_sdk.GaitParam() gait_param.velocity = [0.3, 0.0, 0.0] # X方向速度0.3m/s gait_param.yaw_rate = 0.0 # 无转向 gait_param.height = 0.25 # 身体高度0.25米 # 发送指令 robot.set_gait_command(gait_param) # 运行一段时间 import time time.sleep(5.0) # 停止 robot.stop() robot.close()2.3 从四足到人形的技术迁移四足机器人(12-16个关节)的运动控制,为人形机器人(更多关节,通常30+)奠定了坚实基础。迁移的核心技术包括:
- 全身动力学控制(WBC):如何在多关节、多任务(如保持平衡、移动手脚)约束下,计算最优的关节力矩分配。
- 状态估计:仅凭本体传感器(IMU、关节编码器、足底力传感器)估算机器人的身体姿态和速度。
- 步态规划:生成稳定、高效的行走轨迹。
宇树H1展示的快速行走、跳跃、抗扰动能力,正是其在四足领域积累的这些底层算法,在人形结构上的成功应用。
3. 开源先锋:G1人形机器人及其软件架构解析
2024年,宇树推出的G1人形机器人,最大亮点是其深度的开源策略。它不仅开源了机械结构图纸,更开源了核心软件栈。这对于开发者社区而言,是一个前所未有的学习和实验平台。
3.1 G1硬件概览
- 自由度:全身超过20个关节,兼顾灵巧性与成本。
- 传感器:头部多目相机、IMU、关节编码器、手部力传感器等。
- 算力:内置边缘计算单元(通常为Jetson Orin NX级别),可运行实时控制系统和轻量级AI模型。
- 定位:明确为“教育、科研与开发”,价格相对亲民。
3.2 软件架构总览G1的软件系统采用典型的分层架构,强调模块化和实时性。
[用户层:应用/算法] | [中间件层:ROS 2 / Unitree Middleware] | | [功能层:运动控制] [功能层:感知与导航] | | [驱动层:关节驱动器、传感器驱动] | [硬件层:电机、相机、IMU等]3.3 核心模块深入:运动控制栈这是机器人稳定运动的核心。我们以一个简单的站立平衡任务为例,拆解其软件流程:
// 示例:基于ROS 2的简化状态机与控制循环(概念性代码) // 文件:g1_controller/src/balance_controller.cpp #include <rclcpp/rclcpp.hpp> #include <unitree_control/StateEstimator.h> #include <unitree_control/WBIController.h> // 全身控制器 class BalanceController : public rclcpp::Node { public: BalanceController() : Node("balance_controller") { // 1. 初始化状态估计器(融合IMU和关节信息) state_estimator_ = std::make_shared<StateEstimator>(); // 2. 初始化全身阻抗控制器 wbc_controller_ = std::make_shared<WBIController>(); wbc_controller_->load_robot_model("g1_model.urdf"); // 3. 创建定时器,1kHz控制频率 control_timer_ = this->create_wall_timer( std::chrono::microseconds(1000), std::bind(&BalanceController::controlLoop, this)); } private: void controlLoop() { // a. 更新状态估计 auto current_state = state_estimator_->update(); // b. 计算期望状态(例如:保持身体水平,关节在零位) DesiredState desired; desired.body_orientation = Eigen::Quaterniond::Identity(); desired.joint_positions = zero_positions_; // c. 求解全身控制命令(计算各关节扭矩) auto joint_torques = wbc_controller_->solve(current_state, desired); // d. 通过CAN总线发送扭矩命令到各关节 send_joint_commands(joint_torques); } std::shared_ptr<StateEstimator> state_estimator_; std::shared_ptr<WBIController> wbc_controller_; rclcpp::TimerBase::SharedPtr control_timer_; Eigen::VectorXd zero_positions_; };关键点解析:
- 高实时性:控制循环通常在500Hz-1kHz,要求代码高效且确定。
- 状态估计:仅靠IMU易漂移,需结合关节运动学信息进行融合滤波(如卡尔曼滤波)。
- 全身控制:WBIC(基于模型的全身控制)是主流方法,它将平衡、接触力约束、关节限位等转化为一个二次规划问题求解。
- 通信延迟:从计算扭矩到电机执行,整个环路延迟必须控制在毫秒级,因此多采用实时操作系统(RTOS)或Linux内核实时补丁。
3.4 感知与决策层对于更复杂的任务(如抓取物体),需要感知层提供信息。
# 示例:使用G1头部相机进行物体检测与抓取任务规划(概念性代码) # 文件:g1_vision/scripts/object_grasping.py import rclpy from rclpy.node import Node from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2 import torch from unitree_navigation import ArmPlanner class ObjectGraspingNode(Node): def __init__(self): super().__init__('object_grasping') # 订阅相机话题 self.subscription = self.create_subscription(Image, '/camera/color/image_raw', self.image_callback, 10) self.bridge = CvBridge() # 加载YOLO等目标检测模型 self.model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True) # 机械臂运动规划器 self.arm_planner = ArmPlanner(robot_model='g1_with_arm') def image_callback(self, msg): # 1. 转换图像并推理 cv_image = self.bridge.imgmsg_to_cv2(msg, 'bgr8') results = self.model(cv_image) # 2. 寻找“杯子”类别的物体 detections = results.pandas().xyxy[0] cup_detections = detections[detections['name'] == 'cup'] if not cup_detections.empty: # 获取像素坐标 x1, y1, x2, y2 = cup_detections.iloc[0][['xmin', 'ymin', 'xmax', 'ymax']].astype(int).values center_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2 # 3. 调用手眼标定,将像素坐标转换为机器人基座标系下的3D位置 # (此处简化,实际需深度相机或双目视觉) target_position_3d = self.pixel_to_robot_3d(center_x, center_y, estimated_depth=0.5) # 4. 规划抓取轨迹 grasp_pose = self.calculate_grasp_pose(target_position_3d) trajectory = self.arm_planner.plan_to_pose(grasp_pose) if trajectory.success: self.get_logger().info('抓取轨迹规划成功,开始执行。') # 5. 将轨迹下发给底层控制器执行 self.execute_trajectory(trajectory) else: self.get_logger().warn('轨迹规划失败。')这个例子展示了从视觉感知到动作执行的简化流程。在实际中,还需要处理抓取姿态估计、避障规划、力控制等复杂问题。
4. 开发环境搭建:从零开始运行G1仿真
对于绝大多数开发者,直接操作实体机器人成本高昂。宇树开源生态的价值在于提供了高保真的仿真环境。以下是基于Ubuntu和ROS 2的仿真环境搭建步骤。
4.1 系统与环境准备
- 操作系统:Ubuntu 22.04 LTS(推荐)
- ROS 2:Humble Hawksbill版本
- 工具:Git, CMake, Python3
# 1. 安装ROS 2 Humble(如果未安装) sudo apt update && sudo apt install curl gnupg lsb-release 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 ros-humble-desktop # 2. 创建工作空间 mkdir -p ~/g1_ws/src cd ~/g1_ws/src # 3. 克隆宇树G1仿真相关仓库(请以宇树官方GitHub仓库为准,此处为示例) git clone https://github.com/unitreerobotics/unitree_ros2.git git clone https://github.com/unitreerobotics/unitree_g1_sim.git # 4. 安装依赖 cd ~/g1_ws rosdep install --from-paths src --ignore-src -r -y # 5. 编译工作空间 colcon build --symlink-install source install/setup.bash4.2 启动仿真并控制机器人宇树通常提供Gazebo或Isaac Sim的仿真模型。
# 在终端1:启动Gazebo仿真环境 source ~/g1_ws/install/setup.bash ros2 launch unitree_g1_sim g1_gazebo.launch.py # 在终端2:启动示例控制节点,让机器人原地踏步 ros2 run unitree_g1_sim example_walking如果一切顺利,你将在Gazebo中看到一个G1人形机器人模型,并开始执行简单的踏步动作。这是验证环境是否成功搭建的关键一步。
5. 核心算法实践:自己写一个简单的平衡控制器
理解了架构,最好的学习方式就是动手。我们尝试在仿真中,实现一个最简单的“站立平衡控制器”。这个控制器目标很简单:让机器人在受到轻微推力时,能通过调整脚踝角度来恢复平衡(类似人站立时微调姿势)。
5.1 问题建模我们做一个极大简化:只考虑机器人在矢状面(Sagittal Plane,即前后方向)的平衡,将其建模为一个倒立摆。控制输入是脚踝关节的扭矩,目标是将身体质心(CoM)维持在支撑点上方。
5.2 代码实现
// 文件:my_balance_controller/src/simple_inverted_pendulum_controller.cpp #include <rclcpp/rclcpp.hpp> #include <sensor_msgs/msg/joint_state.hpp> #include <std_msgs/msg/float64.hpp> #include <Eigen/Dense> class SimpleBalanceController : public rclcpp::Node { public: SimpleBalanceController() : Node("simple_balance_controller") { // 订阅关节状态(获取身体倾角) joint_state_sub_ = this->create_subscription<sensor_msgs::msg::JointState>( "/joint_states", 10, std::bind(&SimpleBalanceController::jointStateCallback, this, std::placeholders::_1)); // 发布脚踝关节扭矩命令 ankle_torque_pub_ = this->create_publisher<std_msgs::msg::Float64>("/g1/ankle_joint/effort", 10); // 控制器参数 // 身体质量、质心高度、重力加速度等(此处为示例值,需根据实际模型调整) mass_ = 30.0; // kg com_height_ = 0.8; // m g_ = 9.81; // PD控制器参数 kp_ = 500.0; // 比例增益 kd_ = 50.0; // 微分增益 RCLCPP_INFO(this->get_logger(), "简单倒立摆平衡控制器已启动。"); } private: void jointStateCallback(const sensor_msgs::msg::JointState::SharedPtr msg) { // 1. 从/joint_states中解析身体相对于地面的倾角(theta) // 假设有一个名为'body_pitch_joint'的关节代表身体俯仰角 double body_pitch = 0.0; for (size_t i = 0; i < msg->name.size(); ++i) { if (msg->name[i] == "body_pitch_joint") { body_pitch = msg->position[i]; break; } } // 2. 计算期望的脚踝关节角度来补偿身体倾斜 // 简化模型:脚踝角度 = -身体倾角 * 增益 (负号表示反向补偿) double desired_ankle_angle = -body_pitch * 1.0; // 增益为1.0 // 3. 计算当前脚踝角度(假设关节名为'ankle_joint') double current_ankle_angle = 0.0; for (size_t i = 0; i < msg->name.size(); ++i) { if (msg->name[i] == "ankle_joint") { current_ankle_angle = msg->position[i]; // 获取角速度用于微分项 if (i < msg->velocity.size()) { ankle_velocity_ = msg->velocity[i]; } break; } } // 4. 计算PD控制输出(扭矩) double angle_error = desired_ankle_angle - current_ankle_angle; double torque = kp_ * angle_error + kd_ * (-ankle_velocity_); // 速度负反馈 // 5. 发布扭矩命令 std_msgs::msg::Float64 torque_msg; torque_msg.data = torque; ankle_torque_pub_->publish(torque_msg); } rclcpp::Subscription<sensor_msgs::msg::JointState>::SharedPtr joint_state_sub_; rclcpp::Publisher<std_msgs::msg::Float64>::SharedPtr ankle_torque_pub_; double mass_, com_height_, g_; double kp_, kd_; double ankle_velocity_ = 0.0; }; int main(int argc, char** argv) { rclcpp::init(argc, argv); auto node = std::make_shared<SimpleBalanceController>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; }5.3 在仿真中测试
- 将上述代码放入你的ROS 2包中并编译。
- 启动G1仿真,并让机器人站立。
- 运行你的控制器:
ros2 run my_balance_controller simple_balance_controller。 - 在Gazebo中,尝试用鼠标给机器人身体一个轻微的向前或向后的推力。
- 观察机器人是否能够通过调整脚踝来抵抗推力,维持不倒。
这个例子极度简化,真实的人形平衡需要全身多个关节协同,并考虑双足支撑相、单足支撑相、零力矩点(ZMP)等复杂概念。但它揭示了最核心的控制思想:感知状态(身体倾角)→ 计算误差 → 通过控制器(PD)生成执行命令(关节扭矩)→ 作用于身体 → 改变状态。
6. 常见问题与排查思路
在开发过程中,你一定会遇到各种问题。下表汇总了从环境搭建到算法调试的常见坑点。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 编译错误:找不到unitree相关包 | 1. 仓库未正确克隆。 2. 依赖未安装。 3. 工作空间未正确source。 | 1.ls src/检查仓库是否存在。2. 运行 rosdep install ...查看报错。3. 确认终端已执行 source install/setup.bash。 | 1. 重新克隆仓库。 2. 根据 rosdep提示手动安装缺失依赖。3. 将source命令加入 ~/.bashrc。 |
| Gazebo启动后黑屏或模型加载失败 | 1. 显卡驱动问题。 2. 模型文件路径错误。 3. Gazebo版本不兼容。 | 1. 运行gz sim -s测试Gazebo。2. 查看启动launch文件中的模型路径。 3. 检查ROS 2版本与Gazebo版本匹配性。 | 1. 安装或更新NVIDIA驱动。 2. 设置 GAZEBO_MODEL_PATH环境变量。3. 尝试使用 ignition gazebo(ROS 2 Humble默认)。 |
| 机器人仿真中瘫软倒地 | 1. 控制器未启动或话题不对。 2. 关节初始位置错误。 3. PID参数不合理。 | 1.ros2 topic list查看控制话题是否有数据。2. 检查URDF模型中的初始关节角度。 3. 查看控制器输出的扭矩是否过小或过大。 | 1. 确保控制器节点已运行并发布正确话题。 2. 在启动时通过 spawn_entity设置初始姿态。3. 从较小增益开始调试,逐步增加。 |
| 机器人行走时滑倒或抖动 | 1. 地面摩擦参数设置不当。 2. 步态周期或足底轨迹规划不合理。 3. 控制频率过低或延迟过大。 | 1. 检查Gazebo中地面物理属性的mu值。2. 分析足底接触力曲线,看是否出现冲击或脱空。 3. 使用 rqt_graph和system_monitor查看节点频率和CPU负载。 | 1. 调整地面摩擦系数至合理范围(如0.8-1.2)。 2. 优化步态,确保足底落地平稳,轨迹连续。 3. 优化代码,使用实时线程,或提升硬件性能。 |
| 真实机器人连接失败 | 1. 网络配置错误(IP、端口)。 2. 权限问题(串口/CAN)。 3. 机器人电源或主控未启动。 | 1.ping机器人IP。2. ls -l /dev/ttyUSB*或ip link show查看设备。3. 检查机器人状态指示灯。 | 1. 配置静态IP在同一网段。 2. 将用户加入 dialout组(串口)或配置CAN接口。3. 按手册步骤启动机器人。 |
| 视觉感知延迟大 | 1. 图像传输未压缩或话题带宽占满。 2. 检测模型过于复杂。 3. 未使用GPU加速。 | 1.ros2 topic hz /camera/image查看频率。2. 使用 rqt查看节点计算耗时。3. nvidia-smi查看GPU利用率。 | 1. 使用image_transport进行压缩传输。2. 换用轻量级模型(如YOLOv5s, MobileNet-SSD)。 3. 确保CUDA和cuDNN已安装,并启用模型GPU推理。 |
7. 最佳实践与进阶学习方向
基于宇树开源平台进行开发,遵循一些最佳实践能事半功倍。
7.1 开发流程建议
- 仿真先行:99%的算法开发和调试应在仿真中完成。利用Gazebo/Isaac Sim的高效重置功能,快速迭代。
- 模块化设计:将你的代码分为感知、规划、控制、状态机等独立模块,通过ROS 2话题/服务通信。这便于调试和复用。
- 参数配置化:所有控制器增益、滤波器参数、规划器参数都应写在YAML或JSON配置文件中,避免硬编码。
- 日志与可视化:充分利用ROS 2的
rqt_console、rqt_graph、rqt_plot以及RViz进行数据可视化和调试。 - 版本控制:使用Git管理你的代码,并为仿真环境和机器人本体代码设置不同的分支或仓库。
7.2 安全第一(尤其操作真机)
- 急停开关:必须配置软件和硬件急停,并确保触手可及。
- 限幅保护:在底层控制器中对关节位置、速度、扭矩设置安全限幅,防止自毁。
- 逐步上电:在仿真充分验证后,先在真机上运行“零扭矩”模式,再运行小增益的站立,最后才是行走。
- 专人看护:真机实验时,始终有人在一旁监控,准备随时接管。
7.3 进阶学习方向当你跑通基础Demo后,可以深入以下方向:
- 强化学习(RL):使用
Isaac Gym或PyBullet在仿真中训练步行、跑步策略,然后尝试部署到真机。这是当前最前沿的运动控制研究方向之一。 - 全身运动规划(WBC):深入研究
OSQP、qpOASES等求解器,实现更复杂任务下的全身协调控制。 - 语义导航与操作:结合视觉语言模型(VLM),让机器人理解“请去桌子旁拿起红色的杯子”这类高级指令,并分解为导航、识别、抓取等一系列动作。
- 仿生机械设计:学习宇树关节的设计思路,尝试用3D打印和开源硬件(如ODrive)制作自己的机器人关节。
宇树上市的故事,是一个技术理想主义与工程现实主义结合的故事。它告诉我们,在硬科技领域,清晰的阶段性目标、极致的成本控制、开放的生态建设,与顶尖的算法研究同样重要。对于开发者而言,G1这样的开源平台,则是一张珍贵的“入场券”。
它降低了人形机器人开发的门槛,让你我不必从零开始造轮子,而是能站在一个可用的硬件和基础软件之上,去探索更上层的智能。无论是研究平衡控制、尝试强化学习,还是开发视觉抓取应用,你现在都有了一个真实的载体。
下一步,建议你从搭建仿真环境开始,运行第一个示例,然后修改代码,观察机器人的反应。从让机器人“站稳”,到让它“走起来”,再到完成一个简单的“抓取”任务。每一步的突破,都会让你对人形机器人这个复杂系统有更深的理解。这个领域正在爆发前夜,而动手实践,是理解它最好的方式。