最近具身智能圈子里放出了一个叫 AirVLA 的方案,名字听起来很“大模型”,但核心一句话就能讲明白:它让桌面机械臂的视觉-语言-行动(VLA)模型从“只会平面抓取”升级到了“能在三维空间里完成空中抓取,并顺带解决路径移动的导航问题”。这个项目由某高校机器人团队联合某具身智能创业公司推出,方案一公开就吸引了不少做机械臂操作、sim-to-real 和端到端控制的人去试。如果你也在折腾机械臂抓取,或者正准备入局具身智能,这篇就是我基于公开信息和个人复现经验做的一次技术拆解。
这类项目最让人兴奋的地方,不是网络结构又刷高了多少分,而是它把“空中抓取”这个特别考验三维空间理解的硬骨头,真正放进了端到端 VLA 的框架里,并且给了完整的数据采集、训练和部署思路。我先从它到底解决了什么痛点说起。
1. 为什么“空中抓取”值得单独拿出来说:场景痛点与价值拆解
1.1 桌面机械臂的“平面惯性”限制
绝大多数桌面机械臂,无论学校实验室的还是工厂小工位上的,日常工作都发生在一个近似水平的工作平面上。目标物体基本平铺在桌面、料盘或者传送带上,机械臂末端只需要计算水平方向和偏航角,高度直接取一个固定值,夹爪下去就能捏住。这套玩法在结构化场景里很成熟,但你一旦遇到下面这些情况,它立刻就不够用了:
- 目标物体被堆叠起来,顶层物体已经在桌面平面之上;
- 物体悬挂在支架上,或者被气爪夹持在半空中;
- 目标本身在倾斜表面上,姿态不是“躺着”而是“斜着”“立着”;
- 需要绕过隔板、围栏去抓取,而不是直线怼进去。
这些场景的共同点是:机械臂必须在三维空间中对目标做完整的位置和姿态估计,并且末端在移动过程中还要实时避障、保持轨迹连续。也就是说,这不是给控制系统多加一个“抬升”自由度那么简单,而是感知、决策、控制整个回路都要三维化。过去很多项目之所以回避空中抓取,就是因为感知误差、标定误差、控制误差在三维空间里会被层层放大,失败一次就要重试,成本比平面抓取高得多。
平面抓取和空中抓取看起来只是“多了个高度方向”,实际上对系统要求是质的差别:
| 维度 | 平面抓取 | 空中抓取 |
|---|---|---|
| 位姿自由度 | 3 维(x、y、偏航角) | 6 维(x、y、z、俯仰、横滚、偏航) |
| 目标先验 | 有“放在平面”的强先验 | 姿态任意,先验很弱 |
| 感知需求 | 单目 RGB 基本够用 | 通常需要 RGB-D 或多视角深度 |
| 误差容忍度 | 水平偏移容忍可达数个厘米 | 三维偏移容忍通常在毫米级 |
| 规划复杂度 | 平面路径规划即可 | 需要三维避障和轨迹优化 |
| 典型失败模式 | 夹偏、滑落 | 撞杆、抓空、姿态翻车 |
1.2 VLA 模型为什么适合干这件事
传统做法是把空中抓取拆成一条流水线:先做目标检测,再做 6D 位姿估计,然后交给运动规划器生成轨迹,最后夹爪闭合。每一步都可以单独调优,但问题也恰恰出在这里:每个模块的误差会像接力赛一样传给下一棒,等传到夹爪的时候,可能已经累积出一个让人无语的偏转。最难受的是,当抓取失败时,你很难判断到底是检测框歪了、位姿估计差了、还是规划轨迹没跟上。
VLA 模型把这些环节合并成了一个端到端映射:视觉输入和语言指令直接生成动作轨迹。它学习的不是中间环节的孤立表征,而是“看到这个场景、理解这个指令、做出这个动作”的整体关联。空中抓取这种非结构化任务,恰恰需要这种把感知和动作揉在一起的建模方式,而不是靠手工拆模块去硬凑。AirVLA 的核心就是把“视觉基础模型 + 语言大模型 + 动作策略”拼成一套可训练的完整系统。
1.3 具体能落地的场景
这套能力放到实际场景里很有想象空间:
- 多目标顺序分拣:用户直接说“把空中那个蓝色圆柱抓过来”,机械臂根据颜色和位置语义定位并抓取;
- 层叠货架取物:物体被放在高层隔板上,机械臂需要先绕过隔板边缘,再从空中插进去抓;
- 动态传送带跟踪:目标在传送带上移动,机械臂不能等它停,必须边运动边预测抓取;
- 人机协作递接:人把工具伸到空中,机械臂在中间位置接过工具,而不是等人放到台面上。
这些场景放在制造业分拣、医疗辅助、家庭服务里都很实用。AirVLA 更大的意义在于,它把过去“实验室自嗨”的空中抓取,做成了一个有数据方案、有训练代码、有部署流程的参考实现,让后来者有一个可以复现和改善的基线。
2. 核心底座:AirVLA 的“视觉-语言-行动”拼图怎么搭
2.1 视觉侧:教会模型看见“体积”而不是“图片”
空中抓取对视觉最直接的要求是:模型必须感知到目标的完整三维形状和空间位姿,而不是只把它当成一个像素区域。AirVLA 的视觉编码器一般会采用预训练的视觉基础模型(比如 ViT)作为主干,但光有 RGB 特征不够,几何信息必须进来。
常见的做法有两种。
一种是把深度图归一化后直接用:深度图记录每个像素到相机的距离,网络可以在特征层面学会“哪里凸出来、哪里凹进去”。这个方法实现简单,但深度图对物体材质、反光和透明物体很敏感,容易产生空洞。
另一种是使用点云或者体素特征,把局部区域的点云编码成几何表征。点云编码器能天然保留三维结构,但对算力要求更高,而且需要对点云做降采样、去噪等预处理。
如果条件允许,最好用双相机方案:一个固定在外部支架上做全局观测,一个装在机械臂上做近距离感知。两个视角的特征通过 cross-attention 融合,模型能同时获得“全局在哪里”和“局部长什么样”的信息。AirVLA 在实践中很强调多视角,因为单目 RGB 在没有桌面先验的时候,很难可靠恢复一个空中物体的深度,尤其是细长的、浅色的、半透明的物体。
注意:如果算力有限,退化成单 RGB-D 相机也能启动项目,但在空中抓取的成功率上限会比较低,尤其遇到姿态偏转比较大的目标时,识别会明显吃力。
2.2 语言侧:指令不是用来“聊天”的,而是用来“规划”的
VLA 里的 L 不是让你跟机械臂聊天的,它的作用是提供任务意图和约束条件。比如“绕过左边的支架再抓”这句话,核心是两件事:目标是谁,路径约束是什么。
语言大模型在这里更像一个“任务规划器”:它把自然语言指令解析成结构化的任务描述,再作为条件注入动作策略。AirVLA 在训练时会做大量的指令改写增强(paraphrase augmentation),确保同一个意图的不同说法都能触发相同的任务逻辑。也就是说,训练数据里既有原始指令,又有用语言模型生成的各种变体,模型才不会对某一句话产生过拟合。
实际推理时,并不需要语言模型真正生成一长串自然语言,再用这个文本去引导动作。更高效的做法是让语言模型输出一个任务向量(task embedding),或者接一个轻量级的意图头,直接把这句话映射成一个用于条件化的向量。这样省掉了自然语言生成的推理延迟,动作策略拿到的是“意图向量”而不是一篇文章。
2.3 动作侧:连续位姿轨迹比单步动点重要
动作空间的设计决定了模型上限。AirVLA 采用的基本是“输出未来 N 步末端轨迹”的方案,每一步包含末端位置和姿态。轨迹通常表示成 SE(3) 空间中的齐次变换序列,或者更紧凑的“位置向量 + 四元数”形式。
这里特别值得说的是输出层的选择。早期很多 VLA 模型是单步输出,也就是每次只预测一个动作点,然后重新推理下一帧,这种方式对视频流推理友好,但容易丢失运动连续性。AirVLA 偏向使用扩散策略(Diffusion Policy)来生成轨迹,原因很简单:扩散模型擅长建模多峰分布,也就是说“绕左边走”和“绕右边走”都是可行方案,模型可以保留这种不确定性,而不是强迫自己输出唯一的均值轨迹。
伪代码结构大致长这样:
class AirVLA(nn.Module): def __init__(self, vis_encoder, text_encoder, action_head): super().__init__() self.vis_encoder = vis_encoder # 视觉编码器,输入 RGB-D self.text_encoder = text_encoder # 语言条件编码器 self.action_head = action_head # Diffusion Policy 动作头 def forward(self, rgb, depth, instruction): feat = self.vis_encoder(rgb, depth) # (B, N, D) lang = self.text_encoder(instruction) # (B, D_lang) cond = fuse(feat, lang) # cross-attention 融合 traj = self.action_head.diffuse(cond) # (B, T, 7),xyz + quat return traj训练时,动作头的目标是恢复被噪声污染的轨迹,损失函数由位姿项和扩散项组成。一个典型写法是:
loss = se3_pos_loss(pred_pos, pos_gt) + quat_loss(pred_quat, quat_gt) loss += diffusion_noise_prediction_loss其中四元数损失要小心 double cover 问题:q和-q表示同一个旋转,直接算欧氏距离可能让模型在训练时震荡。比较好的做法是使用规范化四元数夹角距离,或者在数据预处理时统一四元数符号。
2.4 为什么“端到端”而不是“模块化”
模块化系统的核心问题是误差在模块间单向传递,且中间表征不一定对最终任务最友好。端到端 VLA 的好处是梯度可以从最终动作目标一直回传到视觉编码器,让模型自主学习“什么视觉特征对抓取最有用”,而不是要求人去预先定义。
但端到端有个被低估的代价:它对数据规模非常贪婪,而且训练结束后很难通过单独调一个模块来修复特定 bug。这也是为什么 AirVLA 在发布方案时,把数据采集、增强、仿真混合这整套流程都一并公开了,因为脱离数据策略谈模型结构,基本等于空中楼阁。
3. 空中抓取的四个技术难点:每一步都是误差放大器
3.1 6D 位姿估计:没有桌面提供“水平先验”
平面抓取能这么鲁棒,一个重要原因是目标通常平放在桌面上,系统天然知道它的“躺平姿态”,只需要估计水平位置和朝向角就行。空中抓取完全不一样,目标可能以任意姿态悬在三维空间中,模型必须估计完整的旋转量——也就是常说的 6D 位姿。
6D 位姿估计的难点在于,纯视觉特征往往对“细小姿态差异”不够敏感。一个圆柱体转了 5 度,在图像上的像素变化很小,但对机械臂末端来说,这个角度误差可能导致夹爪抓空。比较好的优化方向是在训练时直接用 SE(3) 距离作为评估指标和辅助损失,而不是简单地对旋转矩阵元素做逐项回归。
实践中还容易忽略一个细节:深度传感器和 RGB 相机之间的对齐。如果深度图是 2D 像素对齐到 RGB 的,那么目标边缘部分的深度会明显偏大或偏小,直接让位姿估计在边缘处翻车。建议在感知数据进入网络之前,先做严格的时间戳同步和空间对齐检查。
3.2 目标运动预测
空中目标不一定是静止的。传送带上的物体、被人递过来的工具、从上方掉落的产品,全都处于运动中。机械臂如果要抓这些目标,就必须对未来一段时间的物体位置做预测,通常需要预测未来 0.3 到 0.8 秒的轨迹。
经典的做法是卡尔曼滤波配合运动模型,但如果目标的运动模式不规律,比如突然转向或者被外力干扰,线性模型很容易失手。AirVLA 的做法更“数据驱动”:在训练数据里混入大量动态场景,让模型在输出动作轨迹时,条件向量中额外编码目标的速度信息。这样模型输出的轨迹本身就已经包含了“目标在移动”这件事的补偿,而不是靠底层控制器临时去追。
我在复现时深有体会:动态目标最怕的不是速度过快,而是模型对“目标当前速度方向”的判断滞后了半拍。所以数据里一定要有“减速—停顿—加速”这类变速模式,模型才能学会预测不是匀速直线运动。
3.3 手眼标定误差放大效应
空中抓取对坐标系的准确性极其敏感。相机负责看世界,机械臂负责动,两者之间必须有一个精确的坐标变换。桌面上的相机如果外参误差了半厘米,平面抓取可能还能靠夹爪的宽容度容忍;但在空中,目标悬在三维空间中,末端必须经过一段较长路径才能到达,坐标误差会通过杠杆效应被放大,最终表现为“总是差半个手指头那么点位置”。
解决思路有两个方向。第一是提高标定精度:采用自动手眼标定方法,定期让机械臂带着标定板走一组位姿,在线更新相机到机械臂的变换矩阵。第二是引入闭环视觉伺服:在接近目标的最后阶段,不再依赖全局坐标,而是通过手眼相机直接对目标进行局部定位,把位置误差在末端附近闭环掉。
一个我常用的检查方法:让机械臂夹持一个校准针,针尖去点击固定目标板上几个已知坐标的点,然后反投影到相机坐标系中比对。如果差超过一两毫米,先别调模型,去重新标定。这个步骤虽然耗时,但能帮你省掉后面几个通宵。
3.4 导航与避障:别把“空中行进”当成免费动作
AirVLA 提到的“导航”,放在桌面机械臂语境中,指的更多是任务空间里的路径规划能力:机械臂要从当前位置到达目标抓取位姿,同时不能撞到支架、隔板、周边物体,甚至不能陷入奇异点。
端到端模型直接输出的轨迹,在大多数情况下看起来很合理,但如果你直接把它发给底层控制器,很可能在插值过程中撞上障碍物。因为网络输出的轨迹是稀疏的关键点序列,插值之后连杆姿态没有被显式检查。实际部署时,比较稳妥的做法是用模型生成若干个轨迹候选,再由带碰撞检测的运动规划器做最终校验与精修。另一种思路是在模型训练中加入碰撞感知,用点云构造隐式碰撞场,把碰撞代价算进轨迹损失里,强制模型产生绕障轨迹。
这里我特别提醒:空中抓取时,机械臂容易在“绕过障碍再插入”这个动作上触发奇异点,尤其是腕部翻转角度比较大的情况。建议在轨迹生成后加一道奇异点检查,或者让底层控制器在奇异点附近切换姿态表达,否则会出现“轨迹看着没问题,但机械臂在某个点突然速度爆炸”这种吓人现象。
4. 实操过程:从零到一复现 AirVLA 的典型训练与部署流程
4.1 数据采集:三个来源和各自的坑
端到端 VLA 对数据的依赖程度远超传统方法,数据质量直接决定模型上限。AirVLA 的完整数据方案归纳下来有三个来源。
第一个是真机遥操作。操作员通过遥操作设备控制机械臂完成抓取,系统同步记录多视角图像、深度图、语言指令和关节轨迹。这个方案的数据最真实,但代价是采集速度慢,而且操作员水平直接影响数据质量。我发现不同人示教出来的轨迹风格差异极大,有人习惯绕大弯,有人走直线,如果不加筛选就让模型学,它会学出一个“风格平均”,在边缘场景下表现反而更差。建议采集完数据后先做一轮质量筛选,去掉那些抖动明显、抓取失败、夹爪开闭时机不对的样本。
第二个是仿真合成。在仿真环境里放几百个物体对象,让它们在空间中以各种姿态悬浮或抛掷,自动生成图像、深度和完美标注的 6D 位姿。这个方案能快速获得海量样本,而且标注极其干净,不需要人工标记。坑在于仿真数据太“干净”,材质、光照、相机噪声跟真机差别大,直接拿到真机上往往要打折扣。
第三个是语言指令增强。用语言模型给每个场景生成几十或上百条不同表达方式的指令,比如“抓空中那个蓝色圆柱”“把悬着的圆柱拿下来”“蓝色圆柱拿到左边”,让模型对表达方式有鲁棒性。
数据配比上,我的个人建议是:先用 500 条真机轨迹 + 2000 条仿真轨迹把完整流程打通,验证没大问题后再扩到 5000 条以上。纯仿真数据训练出来的模型,直接上真机大概率会失败,所以我至少保证 30% 是真机数据混合进去。
4.2 模型结构与训练配置
AirVLA 的整体训练流程大体分四步:加载预训练视觉编码器和语言模型 → 冻结部分参数 → 训练动作头和融合层 → 端到端微调。
一个可参考的训练配置:
- 视觉编码器:预训练 ViT,输入为 RGB 和深度图,输出视觉特征。前几层冻结,后几层参与微调;
- 语言条件:轻量级文本编码器,输出任务向量;
- 动作头:扩散策略,输出未来 16~32 步的 SE(3) 轨迹;
- 优化器:AdamW,初始学习率 1e-4,配合余弦衰减;
- 混合精度训练,视觉和语言部分用 BF16,动作头用 FP32。
时间预估上,在单张 A100 上处理 5000 条轨迹数据,大约需要两到三天;多卡并行可以压缩到半天左右。如果只有单张消费级显卡,可以把轨迹步数缩短、图片分辨率降到 224,先完成 baseline 验证,再逐步加量。
4.3 推理与真机部署
真机部署和离线训练完全是两个难度级别。推理流程大致是:接收当前多视角图像、深度图、语言指令 → 模型输出未来 N 步轨迹 → 底层控制器执行第一步或前几步 → 下一帧继续推理。
时延预算是空中抓取能否成功的关键。视觉编码大约 20 毫秒,语言条件可以预先缓存(同一指令不需要每次都重新编码),扩散去噪大约需要 30 到 50 步,整体单次推理做到 5 赫兹左右问题不大。如果机械臂控制频率需要更高,可以只取轨迹的前几帧执行,下一帧再刷新,而不是必须等完整轨迹全部执行完。
工程优化上,有几个实操有效的做法:
- 把视觉编码器和动作头分别导出为 TensorRT 或 ONNX,减少框架开销;
- 对语言指令做 embedding 缓存,避免重复计算;
- 底层控制器启用阻抗控制,避免末端刚性冲击导致目标被推走;
- 接入安全急停,空中抓取调试期间,机械臂动作幅度大,安全保护一定要提前配好。
4.4 最小实验配置清单
如果你想复现一个简化版 AirVLA,可以参考这一套起步配置:
| 组件 | 推荐规格 | 主要作用 | 备注 |
|---|---|---|---|
| 机械臂 | 6 轴轻量级桌面臂 | 提供完整空间位姿能力 | 尽量别用 4 轴臂,缺俯仰和横滚自由度 |
| 视觉传感器 | RGB-D 相机,支持深度对齐 | 获取三维几何信息 | 预算够可以上双相机 |
| 末端夹爪 | 两指平行夹爪,指面带软胶 | 空中抓取稳定 | 软胶减少接触瞬间滑动 |
| 算力设备 | 桌面级显卡 | 训练和推理 | 实机部署再考虑小卡优化 |
| 标定工具 | Apriltag 标定板 + 自动标定脚本 | 手眼标定 | 建议每次实验前重标定 |
验收指标不要只盯着成功率,还要记录周期时间、碰撞次数和目标损坏率。我试着用三维重建的思量来类比:空中抓取的成功率是“是否有捷径”的最终结果,而周期时间和碰撞次数才是决定这套方案真实强度的关键指标。
5. 常见问题与排查:复现路上我遇到的那些坑
5.1 抓不到位:总是差“半个手指”的距离
这是最经典也最让人崩溃的问题。机械臂看着目标在眼前,但每次夹爪落点都偏一点。
排查优先级我建议按这个顺序来:
- 手眼标定误差:先把标定重做一遍,确认相机到机械臂基座的外参没有问题;
- 深度真值偏差:检查相机深度图和 RGB 图边缘是否对齐;
- 夹爪中心与 TCP 偏移:很多机械臂的 TCP 定义在法兰中心,而不是夹爪几何中心,空中抓取时这点偏移会被放大;
- 运动学标定误差:长期使用后机械臂关节零位可能漂移,可以用激光或校准针重新标定。
我的实操经验是,先做一个“点到点”自检:机械臂末端夹持校准针,依次触碰目标板上几个已知坐标点,在相机画面里观察针尖与预期位置的重合程度。这个测试五分钟能做完,却能帮你快速判断问题出在感知层还是执行层。
5.2 模型在仿真里行,真机上就不行
这几乎是所有具身智能项目都要面对的问题,AirVLA 也不例外。仿真环境里的光照均匀、物体纹理干净、相机噪声为零,一旦放到真实环境,目标表面反光、背景杂乱、深度传感器噪点都可能导致感知输出漂移。
我建议优先做三件事:
- 域随机化:在仿真里随机光照角度、纹理颜色、相机位置和噪声强度;
- 真机数据混合:真机数据比例尽量别低于百分之三十;
- 输入归一化:真机和仿真图像都做相同的归一化处理,减少风格差异。
还有一个容易被忽略的细节:真机相机帧率和机械臂控制器频率之间的时间同步。仿真里数据天然对齐,真机上如果图像时间戳和控制指令时间戳差了几十毫秒,空中抓取就会看起来比实际慢半拍。
5.3 轨迹看着合理,但机械臂还是会撞到障碍
这种情况多发生在障碍物比较靠近路径中间的时候。模型输出的末端轨迹避开了障碍,但机械臂的其他连杆在运动过程中还是可能扫到障碍物,尤其当机械臂是六轴或七轴结构时,肘部、前臂都可能成为碰撞点。
解决办法是在轨迹执行前,再做一次基于完整机械臂模型的碰撞检测。最简单的做法是把模型生成的轨迹离散成密集的关键点,在每个关键点处用机械臂正运动学算出连杆位姿,再跟点云障碍做碰撞查询。如果检测到碰撞,可以用 RRT 类规划器做局部修整,或者重新让模型生成一条带绕障约束的新轨迹。
5.4 语言指令换个说法就失灵
我遇到过一种很典型的过拟合:模型对“抓取空中的蓝色圆柱”执行得很好,但换一句“把那个蓝色圆柱拿过来”就完全无响应。问题出在训练数据里指令表达太单一,模型学会的其实是关键词匹配而非意图理解。
解决方向有两个。第一是训练时做指令增强,确保每个任务至少对应几十种不同表达方式;第二是让语言编码器输出的不是文本本身,而是“任务意图向量”,这个向量跟具体措辞解耦。这样即使指令说法变了,只要意图相同,任务向量在语义空间就会落在相近位置。
5.5 空中抓取最值得留意的一条经验
做了几轮实验之后,我最大的感受是:在空中抓取里,数据质量和系统标定的权重远高于网络结构的花哨程度。很多失败不是“模型不够聪明”,而是“感知输入就不准”或者“执行链路误差累积太大”。在项目初期,建议用“固定高度”做起点:先让目标在一个固定高度、固定姿态下被抓取,验证感知、动作、控制这条环路是通的,再逐步放开 z 轴自由度和姿态自由度。这个循序渐进的过程能帮你把每个环节的误差单独逼出来,而不是等所有问题在最终实验里一起爆发。
我自己在复现这类项目时还有另一个体会:空中抓取这件事,难点不在网络结构多先进,而在把三维空间里的误差预算控制住。模型可以很强,但如果相机到机械臂的坐标变换有半厘米误差,目标又悬在空中,那么末端到达时就是会差那么一点点。所以如果你也准备上手,我建议先别急着调网络,拿一台精度勉强够用的机械臂,把相机标定和深度对齐做到肉眼可见的准,再去调模型,整个流程会顺畅非常多。这套方案的后续还可以往动态抓取、双臂协同、更复杂的语言约束这些方向扩展,每一步都够单独写一篇了。