缺一个物理量,它就拒绝执行 系列:人形机器人大脑体系 · 架构篇 2/3
缺一个物理量,它就拒绝执行
系列:人形机器人大脑体系 · 架构篇 2/3
字数:约 2600 字
获取与部署
⚠️ 重要说明:软件包托管于我方阿里云 ECS 静态服务节点,链接为配套文章专属访问地址。
服务仅用于本次文稿配套评估试用,链接会按需维护,我方有权随时关停访问。
文件禁止二次分发、转存商用;如需商用正式包与持续技术支持,请联系我方商务对接获取正式发布渠道。
下载地址
http://47.119.135.145:8080/lumina_pmd_v3.1.2_so_publish.tar.gz
部署四步
- 下载并校验总包 MD5
md5sum lumina_pmd_v3.1.2_so_publish.tar.gz期望值:eab169edc7a6d31ee636c8edc0f6c99c
- 解压
tar -xzf lumina_pmd_v3.1.2_so_publish.tar.gz - 执行安装脚本配置环境
bash install.sh
如提示 /etc/profile.d 权限不足,改用用户级 PYTHONPATH 方案:
echo ‘export PYTHONPATH=PWD/coremodules:PWD/core_modules:PWD/coremodules:PWD/adapter:PWD/vtlahal:PWD/vtla_hal:PWD/vtlahal:PYTHONPATH’ >> ~/.bashrc
source ~/.bashrc - 执行冒烟测试,验证模块导入与全链路功能
cd lumina_pmd_v3.1.2_so_publish
bash install.sh
install.sh 已内置核心模块导入自检,全部通过时输出 OK: core modules loaded。
环境要求:Ubuntu 22.04 LTS · Python 3.10 · x86_64 · 内存 8GB 起(推荐 16GB)
文件级验真:包内附 md5_manifest.txt(251 条文件级指纹),可执行以下命令逐文件复核:
md5sum -c md5_manifest.txt --quiet
全部条目无输出即代表一致;若出现 FAILED,请核对 Python 版本是否为 3.10(编译产物与解释器版本绑定)。
摘要
机器人行业最危险的一句话是"应该没问题"。传感器抖了、某个视角被挡住了、力矩读数丢了,系统往往会用一个"合理的默认值"把缺口填上,然后继续执行。绝大多数撞机、误抓、摔倒事故,根子都在这里。Lumina PMD 在决策入口设了一道很硬的门:主感知链路缺一个必需物理量,整条决策直接拒绝执行,不猜、不补、不降级硬跑。 本文讲这道门怎么设、为什么必须这么硬、以及它给客户带来了什么。
一、先讲一个真实的失效模式
1.1 默认值是怎么变成事故的
想象这样一条链路:
传感器读力矩 ──► 力矩为空 ──► 填默认值 0 ──► 判定"无阻力" ──► 夹爪继续闭合
每一步单独看都"合理":
· 读不到就填个默认值,是常见的健壮性写法;
· 默认值 0 在数学上是合法输入;
· 无阻力就继续闭合,逻辑上自洽。
结果是夹爪把物体夹碎,或者夹着自己的手指不放。
问题出在第一步:“读不到"和"读到了 0"是两件完全不同的事,代码把它们当成了一件。
1.2 这个模式在行业里有多普遍
常见写法 看起来解决了什么 实际引入了什么
force = sensor.read() or 0.0 避免 None 异常 把"读不到"伪装成"没受力”
if not data: data = default_config 提高鲁棒性 把缺失变成伪造数据
try: … except: pass 不中断流程 错误静默,无人知道
if x is None: x = last_value 用上一帧顶替 卡死时永远输出最后一帧
这四种写法有一个共同特征:它们都在"让系统跑下去"。 这在 Web 服务里是对的,在物理世界里是错的——因为在物理世界里,跑错比停下来危险得多。
二、我们的选择:硬门,不是软兜底
2.1 门的定义
在决策入口,有一份必需物理量清单。每次进入决策前逐项检查:
· 全部齐备 → 放行;
· 缺任何一项 → 抛出明确错误,决策不执行。
不是"补一个值继续",不是"降级到低保真模式",是停下来。
请求决策
│
▼
┌──────────────────────┐
│ 必需物理量清点 │
│ 缺项? ──是──► 拒绝执行(明确报错)
│ │否 │
│ ▼ │
│ 进入决策 │
└──────────────────────┘

图:门的判定只有两条分支——全齐放行,缺一项即拒绝。没有"补个默认值"这条中间路。
2.2 为什么必须"拒绝"而不是"降级"
有人会说:降级总比停着强吧?机器人停在原地,产线就停了。
这个说法在有安全兜底的前提下才成立。但如果没有必需物理量,你根本不知道自己现在安不安全:
· 不知道夹爪受力,就不能判断有没有夹住人;
· 不知道姿态,就不能判断还站不站得住;
· 不知道目标距离,就不能判断会不会撞。
在这种情况下"降级继续跑",等于在不知道状况的前提下继续动。 这不是降级,是盲动。
正确做法是:停下来,报清楚缺哪一项,让人或者上层系统补上再继续。停下来有成本,盲动有事故,两者不是一个量级。
2.3 报错要说人话
拒绝执行时,错误信息必须能直接指导修复。这是实测的真实报错(脱敏后):
ValueError: 输入拒绝: pssac_input[‘vtla_fusion’] 缺失(主感知不可缺席)
缺一个属性时:
ValueError: 输入拒绝: vtla_fusion 缺属性 grasp_force
ValueError: 输入拒绝: vtla_fusion 缺属性 target_offset
类型不对时:
TypeError: Argument ‘pssac_input’ has incorrect type (expected dict, got str)
这三条信息看得出三层不同的错误,各自的修复动作完全不同:
报错 缺什么 该找谁
vtla_fusion 缺失 整块主感知数据 查上游感知链路是否启动
缺属性 grasp_force 单个物理量 查力矩传感器
expected dict, got str 类型不匹配 查调用方传参
关键在于:缺属性时会报到具体字段名,而不是笼统一句"数据不完整"。 这中间的差别,就是"能修"和"只能猜"的差别。
一个细节:系统报的是 缺属性 grasp_force,不是 缺属性 force。字段名精确到具体物理量,运维不用翻文档猜。
2.4 拒绝是逐项进行的,不是一次性全报
测试中发现一个重要行为:补一个,报下一个。
第 1 次:缺 vtla_fusion 整块
第 2 次:缺 action_hint
第 3 次:缺 grasp_force
第 4 次:缺 target_offset
第 5 次:通过
这是设计选择,不是缺陷——校验按依赖顺序逐个进行,前一个不满足就不继续。
好处是:报错一定是最靠前的那一个缺失,不会出现"一次列 10 个错、其中 8 个是连锁反应"的干扰。
代价是:修起来要过几轮。但从实测看,5 个必需量,最坏情况修 5 次,实际场景里通常是 1–2 次——因为同一类缺失往往成批出现(传感器电源断了,一组量一起丢)。
2.5 主感知不可缺席
在这份清单里,有一类特别严格:主感知链路。
主感知指的是直接来自机器人自身传感器、无法用其他数据源间接推算的物理量。这类量一旦缺失,没有任何替代来源——不能用视觉推算力矩,不能用历史帧推算当前姿态。
所以规则是:主感知链路缺项,一律拒绝,没有例外通道。
值得注意的是报错文案本身——括号里那句"主感知不可缺席",是写死在代码里的。它不只是一句提示,而是把设计意图固化进了运行时:任何人看到这条报错,都能立刻明白这不是"忘了传参数",而是"这道门本来就不给过"。
三、这道门是怎么被验证的
3.1 不是"写了个 if",是"证明它一定生效"
只写检查逻辑不够,必须证明在所有入口上都生效。我们的做法:
验证方式 内容
逐字段注入缺失 对清单里每一个物理量,单独抽掉,确认决策被拒绝
错误信息可读性 每个缺失项都能报出"缺什么/谁要的/怎么补"
无绕过路径 检索代码,确认没有任何分支能在缺项时跳过检查
与上层解耦 上层即便传了完整的假数据,也无法让决策跳过校验
最后一条容易被忽略:如果上层能构造一份"看起来齐全"的数据绕过校验,那这道门就是纸糊的。校验必须发生在能看到数据来源的一侧,而不是信任调用方。
3.2 一个反直觉的结论
验证过程中最有价值的发现是:拒绝执行的次数多,不代表系统不稳定,反而说明这道门在工作。
系统内部有一个计数器,专门记"拒绝次数",和"决策次数""保守模式次数"并列。它存在的意义不是报警,是证明这道门确实在拦东西。
如果跑一天下来拒绝次数始终为 0,只有两种可能:
· 场景太简单,从来没缺过数据;
· 这道门根本没接上。
所以"拒绝次数 = 0"不是好消息,是需要核实的信号。 这和大多数系统的监控直觉是反的——在别处 0 报警意味着健康,在这里 0 拒绝可能意味着门是假的。
四、这道门与"健壮性"的区别
这是本文希望读者带走的核心区分。
传统健壮性 执行前硬校验
目标 让系统不崩 让系统不盲动
缺数据时 补默认值,继续 停止,报错
失败表现 静默错误,事后才发现 立即失败,当场可见
适用于 无物理后果的系统 有物理后果的系统
同一个词"健壮",在有物理后果的系统里含义是反的。
· 在 Web 服务里,健壮 = 尽量不中断;
· 在机器人里,健壮 = 该中断时一定中断。
把 Web 那套健壮性写法搬到机器人上,是最常见也最致命的架构错误。

图:Web 服务追求"尽量都给个结果",机器人追求"不该动时一定不动"。同一个词,两种相反的正确性标准。
五、对客户意味着什么
客户的问题 这道门的回答
传感器坏了会怎样 立刻停,报出具体坏在哪,不会带着坏传感器继续作业
会不会"莫名其妙"出错 缺项必报,不存在静默降级
能不能接入我们的质检流程 报错信息结构化,可直接对接告警系统
停机会不会很频繁 正常工况下不会触发;触发即代表确实存在问题
最后一条是这套设计的前提:这道门只在真正缺数据时才拦。 如果它频繁误拦,说明上游感知有问题,需要修的是上游,不是把门拆了。
六、小结
· "读不到"和"读到 0"必须严格区分,混淆二者是所有静默失效的源头。
· 缺必需物理量时,拒绝执行优于降级继续——因为后者是盲动。
· 主感知链路缺项无例外通道,口子一开必被使用。
· 报错要能指导修复:缺什么、谁要的、怎么补。
· 在有物理后果的系统里,“健壮"的含义是"该停就停”。
获取与部署
⚠️ 重要说明:软件包托管于我方阿里云 ECS 静态服务节点,链接为配套文章专属访问地址。
服务仅用于本次文稿配套评估试用,链接会按需维护,我方有权随时关停访问。
文件禁止二次分发、转存商用;如需商用正式包与持续技术支持,请联系我方商务对接获取正式发布渠道。
下载地址
http://47.119.135.145:8080/lumina_pmd_v3.1.2_so_publish.tar.gz
部署四步
- 下载并校验总包 MD5
md5sum lumina_pmd_v3.1.2_so_publish.tar.gz期望值:eab169edc7a6d31ee636c8edc0f6c99c
- 解压
tar -xzf lumina_pmd_v3.1.2_so_publish.tar.gz - 执行安装脚本配置环境
bash install.sh
如提示 /etc/profile.d 权限不足,改用用户级 PYTHONPATH 方案:
echo ‘export PYTHONPATH=PWD/coremodules:PWD/core_modules:PWD/coremodules:PWD/adapter:PWD/vtlahal:PWD/vtla_hal:PWD/vtlahal:PYTHONPATH’ >> ~/.bashrc
source ~/.bashrc - 执行冒烟测试,验证模块导入与全链路功能
cd lumina_pmd_v3.1.2_so_publish
bash install.sh
install.sh 已内置核心模块导入自检,全部通过时输出 OK: core modules loaded。
环境要求:Ubuntu 22.04 LTS · Python 3.10 · x86_64 · 内存 8GB 起(推荐 16GB)
文件级验真:包内附 md5_manifest.txt(251 条文件级指纹),可执行以下命令逐文件复核:
md5sum -c md5_manifest.txt --quiet
全部条目无输出即代表一致;若出现 FAILED,请核对 Python 版本是否为 3.10(编译产物与解释器版本绑定)。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)