最近智元机器人把自家面向商用和工业场景的人形机器人直接拉去参加了人形机器人赛事,并且拿下了双榜第一。这件事在外界看来可能只是“机器人跑酷”“机器人搬箱子”的新闻,但放在技术视角下,其实是一次非常典型的工程化压力测试。平时在工厂、门店里“上班”的机器人,和赛场上顶着计时器、裁判评分、环境干扰完成任务的机器人,本质上考验的是同一套能力体系:感知准不准、决策快不快、控制稳不稳、系统扛不扛得住。
本文不打算只停留在新闻评论层面,而是从技术拆解的角度,梳理智元这类“上班用”人形机器人参赛并夺榜背后涉及的关键技术栈,包括运动控制、视觉感知、任务规划、灵巧操作、系统稳定性等,同时给出工程实践中的代码示例、配置思路、常见故障排查方法,以及从“能比赛”走向“能量产、能上岗”的落地建议。
如果你正在做人形机器人相关开发,或者对具身智能、VLA 模型、强化学习控制感兴趣,这篇文章可以作为一份系统化的技术参考。
1. 背景:当“上班用”的机器人走上赛场
1.1 什么是“上班用”的机器人
智元机器人给人的印象,通常是出现在工厂流水线、商用服务场景、物料搬运作业里的人形机器人。它的产品定位并不是实验室里的演示样机,而是能够承担重复性劳动、在真实物理环境中完成任务的通用具身智能机器人。
所谓“上班用”,可以理解为:
- 面向真实业务场景,而不是固定展台。
- 需要长时间运行,不能频繁人工干预。
- 任务多样,环境动态变化。
- 对稳定性、安全性和可维护性有硬性要求。
一台机器人如果只会在实验室抓固定位置的杯子,那不能算“上班”。只有到了商场、车间、仓库,面对光照变化、人员走动、货物摆放不整齐这些现实干扰,仍然能稳定执行任务,才算具备上岗条件。
1.2 为什么要把上班的机器人送去比赛
比赛不是作秀,而是一种极端情况下的能力验证。人形机器人赛事通常会设置多种任务关卡,比如:
- 规定时间内完成行走、避障。
- 完成物体识别、抓取、搬运。
- 在干扰环境下保持任务不中断。
- 自主决策,减少人工遥控。
这些关卡和“上班”场景高度重合。区别在于,比赛会用更严格的计时、更复杂的任务组合、更不可控的现场环境,把机器人的能力边界压出来。
智元拿到双榜第一,说明这台机器人在运动能力和操作能力两个维度上都达到了较高水平。从技术角度看,这个结果至少能验证几件事:
- 运动控制算法不只是在仿真里有效,在真实硬件上同样稳定。
- 视觉感知与决策模型能够应对现场光照、背景变化。
- 整机系统在高压连续任务下没有明显掉链子。
- 软件、硬件、算法的协同已经进入工程化阶段。
1.3 这场比赛关注的人群
这篇文章适合以下几类读者:
- 正在做人形机器人、复合机器人开发的工程师。
- 对具身智能、VLA 模型、强化学习控制感兴趣的研究者。
- 准备采购或集成商用机器人的项目经理、技术负责人。
- 从事机器人赛事或产学研合作的高校师生。
不管你是写算法、做硬件,还是做系统集成,都可以从“比赛双榜第一”这件事里提炼出一些通用的技术经验。
2. 双榜第一的含金量:比赛到底在考什么
2.1 赛事的常见榜单划分
人形机器人赛事通常不会只设一个“总分榜”,而是会从不同维度分组测试。常见的榜单划分方式包括:
- 运动能力榜:侧重行走速度、转弯灵活性、上下坡、稳定站立、抗扰动。
- 操作能力榜:侧重物体抓取、工具使用、精细装配、任务完成度。
- 全能赛 / 综合任务赛:要求机器人在连续任务流中完成多种操作。
智元这次拿下的“双榜第一”,大概率同时覆盖了运动能力和操作能力两个维度。换句话说,这台机器人不是单项偏科型选手,而是综合能力均衡且突出。
2.2 现场评分通常看什么
赛事评分一般会参考以下指标:
| 评分维度 | 具体考察内容 | 为什么重要 |
|---|---|---|
| 任务完成时间 | 从开始到结束的总耗时 | 体现决策与执行效率 |
| 成功率 | 一次尝试内完成任务的比例 | 体现系统稳定性 |
| 自主性 | 是否需要人工干预 | 体现感知-决策-控制闭环能力 |
| 动作质量 | 行走是否流畅、抓取是否准确 | 体现控制算法性能 |
| 安全表现 | 是否碰撞、是否超出区域 | 体现安全边界设计 |
一台“上班用”的机器人,在工厂里的考核维度其实也差不多:能不能按时完成、出错率多高、需不需要人守着、动作会不会碰到人和设备。所以比赛成绩好的机器人,在真实业务场景里往往也有更好的表现基础。
2.3 双榜第一背后的技术结论
综合来看,双榜第一至少说明:
- 机器人硬件本体(关节、电机、传感器)质量可靠。
- 底层运动控制算法具备较强的鲁棒性。
- 上层视觉感知和任务决策模型实际可用。
- 整机系统集成度较高,软件栈稳定。
但要注意,赛事环境不等于生产环境。比赛里没有粉尘、高温、电磁干扰,也没有连续 8 小时高强度作业。所以“比赛第一”只能代表起点,不能直接等同于“量产可用”。
3. 拆解机器人“上班+比赛”能力的技术底座
一台能在比赛和工厂场景同时执行任务的人形机器人,技术架构通常包含四大块:
- 感知层:看得到、认得准。
- 决策层:知道该干什么、怎么干。
- 运动控制层:走得稳、站得住、抓得准。
- 系统集成层:所有模块协同工作,不出故障。
下面逐个拆解。
3.1 感知层:视觉语言模型与环境理解
人形机器人需要理解三维物理世界。传统视觉方案只能解决“识别物体”,但解决不了“理解场景”。现在主流方案会用视觉语言模型(VLM)对环境做大模型的语义理解。
比如,机器人看到一张桌子,上面有一个红色杯子、一个蓝色盒子。传统目标检测只能输出“杯子”“盒子”的坐标框。而 VLM 可以进一步推理出“把红色杯子放到托盘上”这样的任务语义。
感知层通常包含:
- RGB 相机:捕捉颜色、纹理、文字信息。
- 深度相机 / 激光雷达:获取三维几何信息。
- 点云处理:生成物体位姿估计。
- VLM / 多模态大模型:理解场景语义,做开放词汇识别。
这里给出一个视觉感知调用的示例思路:
# 文件路径:perception/vlm_client.py # 说明:调用多模态模型进行场景理解的示意代码,需根据实际模型 API 调整 import requests import base64 import json def encode_image_to_base64(image_path: str) -> str: with open(image_path, "rb") as f: return base64.b64encode(f.read()).decode("utf-8") def scene_understanding(image_path: str, prompt: str) -> str: """ 将图像和任务指令发送给多模态模型,返回场景理解结果。 这里仅演示请求结构,具体接口地址和参数需按实际模型文档修改。 """ image_b64 = encode_image_to_base64(image_path) payload = { "model": "your-vlm-model", "messages": [ { "role": "user", "content": [ {"type": "text", "text": prompt}, {"type": "image", "image": image_b64} ] } ] } response = requests.post( "http://your-vlm-service/v1/chat/completions", json=payload, timeout=30 ) response.raise_for_status() result = response.json() return result["choices"][0]["message"]["content"] if __name__ == "__main__": prompt = "请描述图片中的物体和它们的相对位置,输出为JSON格式:{'objects': [{'name': '...', 'bbox': [...]}]}" result = scene_understanding("camera_frame.jpg", prompt) print(result)这段代码的核心思路是:把相机图像和任务指令一起交给多模态模型,让模型输出结构化的场景描述,然后决策模块再根据这些描述做任务规划。
3.2 决策层:从任务规划到动作生成
决策层解决的核心问题是“下一步做什么”。人形机器人不像工业机械臂那样只做固定轨迹,它需要根据场景变化动态调整策略。
决策层的常见组成:
- 任务规划器(Task Planner):把高层任务拆成子步骤。
- 运动规划器(Motion Planner):生成无碰撞的运动轨迹。
- VLA 模型(Vision-Language-Action):直接把视觉、语言输入映射为底层动作。
一个简单的任务状态机示例可以这样写:
# 文件路径:decision/task_state_machine.py # 说明:简化版任务状态机,用于控制机器人按顺序完成任务 import time import logging logging.basicConfig(level=logging.INFO) class TaskStateMachine: def __init__(self): self.state = "IDLE" self.state_handlers = { "IDLE": self.handle_idle, "NAVIGATE": self.handle_navigate, "DETECT": self.handle_detect, "GRASP": self.handle_grasp, "PLACE": self.handle_place, "FINISH": self.handle_finish, } def handle_idle(self, context): logging.info("初始化完成,准备开始任务") return "NAVIGATE" def handle_navigate(self, context): logging.info("正在导航到目标区域") # 此处调用导航接口,返回 True 表示到达 arrived = context["nav_api"].go_to(context["target_area"]) return "DETECT" if arrived else "NAVIGATE" def handle_detect(self, context): logging.info("正在识别目标物体") obj = context["vision_api"].detect(context["target_object"]) if obj is not None: context["object_pose"] = obj["pose"] return "GRASP" return "DETECT" def handle_grasp(self, context): logging.info("正在抓取物体") success = context["arm_api"].grasp(context["object_pose"]) return "PLACE" if success else "GRASP" def handle_place(self, context): logging.info("正在放置物体") context["arm_api"].place(context["place_pose"]) return "FINISH" def handle_finish(self, context): logging.info("任务完成") return "FINISH" def run(self, context): while self.state != "FINISH": handler = self.state_handlers[self.state] self.state = handler(context) time.sleep(0.1) # 使用示例 if __name__ == "__main__": # 以下 api 对象均为示意,实际需替换为真实控制接口 context = { "target_area": "table_1", "target_object": "red_cup", "place_pose": [0.5, 0.2, 0.8], "nav_api": None, "vision_api": None, "arm_api": None, } sm = TaskStateMachine() # sm.run(context)状态机的好处是逻辑清晰、便于调试。实际工业项目中,状态机通常会和行为树(Behavior Tree)结合使用,用来处理更复杂的分支和异常恢复。
3.3 运动控制层:走得稳、站得住
人形机器人运动控制是整个系统中最难的部分之一。双足行走本质上是“不稳定系统下的动态平衡控制”,比轮式机器人复杂得多。
目前主流的人形机器人运动控制方案包括:
- 基于模型预测控制(MPC)的全身运动控制。
- 基于强化学习(RL)的运动策略。
- 传统 ZMP(零力矩点)控制与倒立摆模型。
- 混合方案:先用仿真训练 RL 策略,再迁移到真机。
MPC 的核心思想是:在每个控制周期内,基于当前状态预测未来一段时间内系统的最优运动轨迹,并在下一周期重新计算。强化学习则是通过大量仿真试错,学习一个从状态到动作的映射网络。
运动控制模块通常和硬件驱动紧密耦合,调试时往往需要先做关节力矩标定和动力学辨识。
下面是一个简单的运动指令发送示例,使用 ROS 2 话题发布控制指令:
# 文件路径:control/walk_command.py # 说明:通过 ROS 2 发布行走指令的示意代码 import rclpy from rclpy.node import Node from geometry_msgs.msg import Twist class WalkCommandNode(Node): def __init__(self): super().__init__("walk_command_node") self.publisher = self.create_publisher(Twist, "/cmd_vel", 10) def send_walk_command(self, linear_x: float, angular_z: float, duration: float): msg = Twist() msg.linear.x = linear_x msg.angular.z = angular_z rate = self.create_rate(10) # 10 Hz cycles = int(duration * 10) for _ in range(cycles): self.publisher.publish(msg) rate.sleep() # 停止 stop_msg = Twist() self.publisher.publish(stop_msg) def main(args=None): rclpy.init(args=args) node = WalkCommandNode() node.send_walk_command(0.3, 0.0, 2.0) # 向前行走 2 秒 node.destroy_node() rclpy.shutdown() if __name__ == "__main__": main()实际人形机器人的运动控制往往不会直接用/cmd_vel这种简易接口,而是通过控制全身关节力矩来完成行走。这里的代码只是演示“控制指令如何传递”的思路。
3.4 操作层:灵巧手与抓取规划
“双榜第一”里的操作榜,重点考察的就是抓取和操作能力。人形机器人的手通常采用多自由度灵巧手,配合力控传感器完成精细操作。
抓取流程一般分为:
- 识别物体位姿。
- 生成抓取候选点。
- 规划机械臂运动轨迹。
- 执行抓取,并通过力反馈判断是否抓稳。
抓取规划常用的库包括:
- MoveIt:做机械臂运动规划。
- GPD / AnyGrasp:生成抓取姿态。
- 自研抓取网络:基于点云直接输出抓取位姿。
3.5 导航与定位:知道自己在哪里
机器人在真实环境里移动,必须知道自己在哪、目标在哪、怎么避障。这依赖 SLAM(同步定位与建图)技术。
常见方案:
- 激光 SLAM:如 Cartographer、LIO-SAM。
- 视觉 SLAM:如 ORB-SLAM3。
- 多传感器融合定位:融合 IMU、轮式里程计、视觉、激光。
SLAM 模块输出机器人的位姿信息,运动控制模块基于位姿信息做路径跟踪。
4. 从“能比赛”到“能上班”:可靠性是关键
4.1 比赛环境与生产环境的差距
比赛环境是“可控的复杂”,生产环境是“不可控的复杂”。两者差距体现在:
| 维度 | 比赛现场 | 工厂/商用现场 |
|---|---|---|
| 光照 | 相对稳定 | 复杂、变化大 |
| 人员流动 | 较少、有隔离 | 频繁、不可控 |
| 任务类型 | 固定、可预知 | 多样、动态变更 |
| 连续运行时长 | 分钟级 | 小时级、天级 |
| 故障容忍度 | 可重试 | 不允许频繁失败 |
| 网络稳定性 | 场地可控 | 可能断网、延迟 |
所以比赛成绩好,只能说明机器人具备基本能力,真正投入商用还需要解决可靠性和鲁棒性问题。
4.2 成功率是硬指标
一台“上班用”的机器人,抓取成功率如果只有 95%,看起来很高,但放在每天执行 1000 次任务的场景里,就意味着每天失败 50 次,需要人工介入 50 次。这是企业无法接受的。
工业场景通常要求:
- 单次任务成功率 ≥ 99.9%。
- 平均无故障运行时间 ≥ 数百小时。
- 关键任务失败必须有自恢复机制。
要提高成功率,不能只依赖算法优化,还要从系统层面做冗余设计:
- 硬件冗余:关节电流、温度异常时自动降载。
- 软件冗余:感知结果置信度低时,切换到备选方案。
- 任务冗余:抓取失败后自动调整抓取点重试。
4.3 仿真到真机的迁移
当前人形机器人训练大量依赖强化学习,而强化学习需要海量试错,不可能全在真机上完成。所以主流方案是“仿真训练 + 真机微调”。
仿真环境常用:
- Isaac Sim / Isaac Lab
- MuJoCo
- PyBullet
- 自研物理引擎
仿真的好处是:可以批量生成任务场景,可以加速时间,可以注入噪声和扰动,可以失败后自动重置。
但仿真和真机之间有“Sim-to-Real Gap”,主要体现在:
- 关节摩擦、动力学参数不一致。
- 相机成像差异。
- 延迟差异。
- 电机响应延迟。
解决思路包括:
- 领域随机化:在仿真中随机化质量、摩擦、光照、延迟。
- 系统辨识:用真机数据修正仿真模型。
- 真机微调:用少量真机数据继续训练策略。
4.4 参数配置管理
机器人系统中的参数非常多:PID 参数、控制周期、相机内参、任务阈值、速度限制等。比赛和现场调试时,参数配置混乱是常见问题。
推荐使用统一配置文件管理参数:
# 文件路径:config/robot_config.yaml # 说明:机器人参数配置示例 robot: name: "agibot_work" joint_count: 32 control_frequency: 100 # Hz control: max_linear_velocity: 0.8 # m/s max_angular_velocity: 1.0 # rad/s walking_height: 0.95 # m step_length: 0.4 # m zmp_gain: [0.8, 0.8] vision: camera_fps: 30 depth_size: [640, 480] vlm_timeout: 3.0 # 秒 object_conf_threshold: 0.6 safety: emergency_stop_force: 50 # N max_joint_temperature: 80 # 摄氏度 collision_velocity_limit: 0.3 # m/s配置文件的好处是:不同场景(比赛、产线、展厅)可以切换不同配置,不需要重新编译代码。
5. 常见问题与排查思路
人形机器人在比赛和现场运行中,最常见的故障集中在以下几类。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 行走时左右晃动大 | ZMP 控制参数不合适、踝关节刚度不足 | 重新整定 ZMP 参数;检查踝关节力矩输出 |
| 站立时轻微前倾后仰 | 质心估计不准、IMU 漂移 | 修正质心参数;做 IMU 零偏校准 |
| 抓取物体时滑落 | 夹持力不足、手部摩擦系数小 | 增大目标夹持力;更换接触面材料 |
| 视觉识别置信度低 | 光照变化、物体纹理缺失 | 添加补光;切换识别模型;融合点云信息 |
| 任务执行卡住不切换 | 状态机异常分支未处理 | 检查状态机是否有死循环;增加超时保护 |
| 机器人突然停止 | 急停触发、关节过温、网络超时 | 查看急停日志;检查关节温度;检查通信链路 |
| 仿真表现好但真机差 | Sim-to-Real 差距 | 增加领域随机化;做真机系统辨识 |
| 操作响应延迟高 | VLM 推理耗时过长 | 缓存高频场景;用小模型做初步过滤;增加超时降级策略 |
下面针对几个高频问题展开说明。
5.1 行走失稳问题
行走失稳是最典型的问题。排查顺序建议如下:
- 先查看 IMU 数据是否平滑,排除传感器异常。
- 再确认关节 PDI 参数是否合理,特别是踝关节和髋关节。
- 检查实际质心位置是否和算法假设一致。
- 在仿真中复现同样工况,对比差异。
- 如果是强化学习策略,检查是否对扰动做了足够随机化。
5.2 抓取失败问题
抓取失败的根因可能是感知、规划或执行任意一环。排查时可以分三步:
- 先确认感知输出位姿是否准确。可以用可视化工具渲染物体位姿和实际位置对比。
- 再检查抓取姿态是否可执行。比如末端是否与桌面碰撞。
- 最后看力控反馈。如果夹持力到了仍滑落,说明接触模型有问题。
5.3 系统运行不稳定问题
系统层面的不稳定通常是模块间通信导致的。建议在日志里记录每个关键动作的时间戳,以便定位阻塞点:
# 文件路径:utils/timing_logger.py # 说明:记录模块耗时分布的轻量工具 import time import threading from collections import defaultdict class TimingLogger: def __init__(self): self._lock = threading.Lock() self._records = defaultdict(list) def timeit(self, module_name: str): def decorator(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) cost = time.perf_counter() - start with self._lock: self._records[module_name].append(cost) return result return wrapper return decorator def report(self): with self._lock: for module_name, costs in self._records.items(): avg_cost = sum(costs) / len(costs) max_cost = max(costs) print(f"{module_name}: avg={avg_cost*1000:.1f}ms, max={max_cost*1000:.1f}ms") # 使用示例 logger = TimingLogger() @logger.timeit("vision_detection") def detect_object(): time.sleep(0.05) # 模拟检测耗时 return True @logger.timeit("motion_planning") def plan_trajectory(): time.sleep(0.03) # 模拟规划耗时 return True if __name__ == "__main__": for _ in range(10): detect_object() plan_trajectory() logger.report()通过耗时日志,可以快速定位是感知慢、规划慢还是控制慢。
6. 最佳实践与工程建议
结合比赛中暴露出来的共性问题以及机器人量产落地的经验,这里整理几条工程建议。
6.1 算法模块解耦
不要把感知、决策、控制全写在一个节点里。建议按模块拆分进程或线程,模块之间通过标准消息通信。这样单个模块出错时可以独立重启,不影响整体系统。
推荐模块划分:
- perception_node:视觉感知与目标检测。
- planner_node:任务规划与运动规划。
- control_node:下发关节指令。
- safety_node:监控急停、温度、电流。
- status_node:汇总状态并上报日志。
6.2 仿真先行,真机验证
新算法不要直接上真机。先在仿真里跑通,再设置安全限制后上真机。真机测试时,建议:
- 先低速运行。
- 限制关节角度范围。
- 打开碰撞检测。
- 旁边保持急停人员。
6.3 参数配置与代码分离
所有需要调优的参数尽量抽到配置文件里。比赛现场调参通常时间紧迫,如果每次都要改代码重新编译,会浪费大量时间。
6.4 日志体系要完善
机器人系统故障排查依赖日志。建议每条日志包含:
- 时间戳。
- 模块名称。
- 任务 ID。
- 运行状态。
- 关键参数快照。
这样可以回放故障前几秒的状态,快速定位问题。
6.5 安全边界必须前置
人形机器人在人机共融环境里运行,安全是第一优先级。建议在软硬件层面都加防护:
- 硬件急停按钮。
- 关节力矩限制。
- 碰撞检测。
- 电子围栏。
- 任务超时熔断机制。
6.6 做好数据闭环
比赛和现场运行都会产生大量数据。这些数据不要只存在本地,建议统一归档,用于后续模型训练和算法迭代。
数据闭环流程:
- 运行中采集传感器数据、动作指令、状态日志。
- 自动标注任务结果(成功/失败)。
- 失败数据进行人工复核并补充标签。
- 定期用采集数据微调感知模型和运动策略。
7. 总结与下一步关注点
智元把“上班用”的机器人拉去比赛并拿下双榜第一,这个事件给人形机器人行业传递了一个信号:人形机器人正在从“能演示”走向“能比赛、能上岗”的阶段。双榜第一的背后,不是单点算法的突破,而是感知、决策、控制、系统集成这套完整技术栈的协同成熟。
对于开发者来说,可以从这场比赛里提取几个技术学习方向:
- 关注运动控制从仿真到真机的迁移方法。
- 关注 VLA 模型在真实机器人上的部署与推理优化。
- 关注多传感器融合与场景理解。
- 关注系统稳定性设计和故障恢复机制。
- 关注数据闭环在机器人迭代中的实际作用。
接下来的行业竞争重点,大概率会从“单任务能力”转向“长时间连续作业的可靠性”和“复杂场景下的泛化能力”。哪家机器人能在真实生产环境里稳定运行数千小时,哪家才有机会真正打开商用市场。
如果你正在入门人形机器人方向,可以从运动控制仿真做起,先在 Isaac Lab 或 MuJoCo 里搭一个简单双足模型,尝试实现稳定站立和行走,再逐步加入视觉感知和抓取任务。比赛里的每一个满分动作,背后都是在仿真环境里跌倒了成千上万次换来的。
可以先把本文提到的几个模块作为学习路线:感知 → 决策 → 控制 → 系统集成,每个模块都值得单独深入。后续我也会围绕这些技术点分别整理更细的实操教程,包括运动控制仿真环境搭建、VLA 模型部署、抓取规划库使用等,欢迎持续关注。
如果本文对你有帮助,可以先收藏备用,动手试的时候再翻出来对照着排查。