HumanoidPF, LessMimic, APEX Notes
日期:2026-05-28
0. 本地 clone 状态
已 clone:
submodules/Click-and-Traverse
official repo: https://github.com/GalaxyGeneralRobotics/Click-and-Traverse
paper/project: HumanoidPF / CAT
submodules/LessMimic
official repo: https://github.com/Yutang-Lin/LessMimic
APEX 官方项目页目前写的是 Code (Coming Soon),没有官方代码可 clone。项目页:
LessMimic 的 GitHub 仓库目前也只有 README 和 resources/teaser.png,README 明确写着 Code will be released. Stay tuned.,所以 LessMimic 不能做代码级实现分析,只能基于 paper/README/project page。
1. HumanoidPF 到底是不是启发式
结论:
HumanoidPF 的 field 是从 obstacle occupancy + goal 算出来的几何场。
它不是 learned field,也不是 object affordance rule。
但它仍然包含手工设计的公式和超参。
所以它介于两者之间:
不是:手写 chair/socket/pick/place 这种 affordance 规则
也不是:从数据学习出来的 neural affordance field
而是:algorithmic geometric potential/guidance field
1.1 field 构造
核心文件:
submodules/Click-and-Traverse/procedural_obstacle_generation/pf_modular.py
submodules/Click-and-Traverse/procedural_obstacle_generation/main.py
make_sdf(...):
phi_obs = np.ones(obs_mask.shape, dtype=float)
phi_obs[obs_mask] = -1.0
sdf = skfmm.distance(phi_obs, dx=voxel).astype(np.float32)
也就是从 3D obstacle occupancy mask 算 signed distance field。
grad3(sdf, voxel):
dfx, dfy, dfz = np.gradient(scalar_field, voxel, voxel, voxel, edge_order=2)
return np.stack([dfx, dfy, dfz], axis=-1).astype(np.float32)
这得到 obstacle boundary normal field,代码里叫 bf.npy。
make_guidance_field_progressive(...) 是 HumanoidPF 核心:
- 用 goal seed 和 obstacle mask 跑 Fast Marching,得到到 goal 的 geodesic distance
T。 - 取
-grad(T)得到朝 goal 的 guidance direction。 - 用 SDF normal field
bf把靠近障碍物时的方向投影到 obstacle tangent plane:
- 根据到 obstacle 的距离
d_out做 smooth blending:
- inside obstacle 时直接用 normal 推出去:
- normalize 后乘 goal-distance-based speed,保存为
gf.npy。
生成脚本 main.py 会为每个 obstacle scene 保存:
sdf.npy # signed distance
bf.npy # SDF gradient / obstacle normal field
gf.npy # goal-conditioned guidance field
obs.npy # occupancy
obs.obj # visualization/collision mesh
1.2 field 如何进入 policy observation
核心文件:
环境初始化时加载:
self.sdf = jp.array(np.load(f"{pf_path}/sdf.npy"))[...,None]
self.bf = jp.array(np.load(f"{pf_path}/bf.npy"))
self.gf = jp.array(np.load(f"{pf_path}/gf.npy"))
每个 step 在 humanoid 多个 body site 上采样:
all_poses = concat([
head_pos,
pelvis_pos,
torso_pos,
feet_pos,
hands_pos,
knees_pos,
shoulders_pos,
])
all_gf = self.sample_field(self.gf, all_poses)
all_bf = self.sample_field(self.bf, all_poses)
all_df = self.sample_field(self.sdf, all_poses)
采样函数是 trilinear interpolation:
policy observation 里放的是:
head/pelvis/torso/feet/hands/knees/shoulders:
gf # guidance direction
bf # obstacle boundary normal
df # signed distance
并且这些向量先被转到 navigation/body frame,df 会 clip 到 [-1.0, 0.5],bf 只在距离 obstacle 小于 0.5m 时保留。
1.3 field 如何进入 reward / termination
termination:
contact_termination |= any(headdf < -term_collision_threshold)
contact_termination |= any(pelvdf < -term_collision_threshold)
contact_termination |= any(torsdf < -term_collision_threshold)
contact_termination |= any(feetdf < -term_collision_threshold)
contact_termination |= any(handsdf < -term_collision_threshold)
contact_termination |= any(kneesdf < -term_collision_threshold)
contact_termination |= any(shldsdf < -term_collision_threshold)
reward 有两类:
gfalignment reward:body part 速度要和 guidance field 方向一致,且只在靠近障碍物时强启用。
cos_align = dot(normalize(gf_vel), normalize(body_vel))
window = sigmoid(k * (tau - sdf))
reward_near = window * alpha_align * cos_align
dfcollision penalty:SDF 小于 safety margin 时 softplus penalty。
训练入口 train_ppo.py 把不同 body-level obstacle reward 分成:
这解释了为什么 HumanoidPF 不是简单 root potential field。它是 body-part sampled 的 3D geometry field。
1.4 field 如何生成 command
compute_cmd_from_rtf(...) 还会把 pelvis guidance 和其他 contact-body guidance/normal 投影成 velocity command:
v = rtf[:2] * 0.7
delta = projection correction from contact-body gf/bf
v_new = v + mean(delta)
command = [move_flag, vx, vy, yaw]
代码注释说这是:
reuse command in velocity control for our HumanoidPF,
can be seen as a single iteration of field projection
所以 HumanoidPF 的 field 同时用于:
2. LessMimic 到底是什么 field
本地代码状态:
没有 release 训练代码,所以不能像 HumanoidPF 那样确认函数级实现。
根据 README、arXiv abstract、项目页,LessMimic 的 DF 也是几何距离场,不是简单 object socket 规则。它强调:
surface distances
gradients
velocity decompositions
interaction latents encoded via VAE
AIP-derived RL
DAgger-style distillation to egocentric depth
核心区别:
| 方法 | field 来源 | field 作用 | 是否 learned |
|---|---|---|---|
| HumanoidPF | occupancy + goal 的 SDF/geodesic/guidance | traversal observation/reward/command | field 本身不是 learned,policy 是 learned |
| LessMimic | object distance field / geometry cues | interaction observation/reward representation | DF 几何是 computed;interaction latent/AIP 是 learned |
LessMimic 最关键的不是“DF 是神经网络算的”,而是:
也就是说,DF 本身仍然可以是 analytic/computed;novelty 在于:
3. APEX 可借鉴点
APEX 官方 code 当前未发布。只能根据 paper/project page 确认:
- 它不是 field/potential paper。
- 核心是 high-platform traversal 的 contact-rich maneuver learning。
- 最关键可借鉴的是 generalized ratchet progress reward:
track best-so-far task progress
reward only genuine improvement
penalize non-improving steps
avoid velocity-tracking-induced jumping/impact
对 PhysHSI 的意义:
long-horizon HSI 里可以用 ratchet progress 处理 sparse subgoal:
approach target
establish contact
lift object
carry through clutter
place stable
sit stable
它不直接回答 affordance field,但回答“怎么让 contact-rich RL 不靠速度 reward 硬冲”。
4. 对我们方案的修正
之前把 Kimodo constraint generator 也叫 affordance field,这不够严谨。应改为两层:
Layer A: Affordance-aware constraint generation
输入: SAGE scene_context / object_sockets / task_validation
输出: Kimodo constraints
本质: 约束生成,不必叫 field
Layer B: Body-part field-conditioned RL policy
输入: geometry field sampled at body parts + task/action phase
输出: state policy action
本质: 类 HumanoidPF/LessMimic 的 policy representation
真正有论文价值的是 Layer B。
4.1 我们不能只做启发式 field
如果我们只做:
reviewer 会合理地说:
更强版本应该是:
建议定义:
F_geo:
SDF / ESDF
SDF gradient / obstacle normal
geodesic guidance to subgoal
height/support map
held-object inflated collision volume
F_inter:
contact likelihood for body part and phase
desired body/object relative velocity decomposition
attach/release probability
support/grasp/place stability latent
F_geo 从 SAGE geometry 算,类似 HumanoidPF。
F_inter 从成功/失败 rollout 学,类似 LessMimic 的 interaction latent/AIP 方向。
4.2 对 Kimodo 的正确定位
Kimodo 不需要 field。Kimodo 需要 constraints。
在我们的系统里 Kimodo 应该是:
不是:
可行流程:
SAGE scene/task
-> current object_sockets/keyframe_targets
-> Kimodo reference
-> tracking teacher with F_geo/F_inter rewards
-> successful/failed rollouts
-> train field-conditioned state policy
4.3 和 HumanoidPF/LessMimic 的差异空间
HumanoidPF 只处理 obstacle traversal:
LessMimic 处理 object interaction:
我们的空间应该是:
SAGE crowded HSI:
obstacle traversal
object interaction
held-object navigation
sit/pick/place/carry composition
用同一个 body-part field observation/reward interface 统一。
具体差异要落在实验:
- TokenHSI/UniHSI 能交互但 crowded collision 多。
- HumanoidPF/CAT 能避障但没有 sit/carry/place。
- LessMimic 有 interaction DF,但官方目前不强调 crowded indoor obstacle traversal / held-object clearance through clutter。
- 我们要证明:
body-part geometry guidance + learned interaction latent
优于
PF traversal -> HSI interaction 的 hard switch
5. 推荐下一步实现
第一步不要重写 Kimodo constraint generator。
更合理的 MVP:
1. 在 SAGE 上实现 HumanoidPF-style F_geo:
occupancy/ESDF
geodesic-to-subgoal guidance
obstacle normal
body-part sampling API
2. 把 F_geo 接到 tracking/RL env:
observation: head/pelvis/torso/feet/hands/knees/shoulders sampled field
reward: gf alignment + df safety penalty
termination: body-part df threshold
3. 对 HSI 增加 interaction channels:
hand-object DF
pelvis-seat DF
object-support DF
held-object inflated collision DF
4. 用 Kimodo/reference rollout bootstrap F_inter:
VAE or small latent encoder over body-part DF sequences
discriminator/AIP over interaction field trajectories
这样方案才不是“把已有 affordance hints 换个名字”。