第五轮:锁/续跑/超时/自动分支/R4 探针与 encode-once/控制台加固;阶段内断点续跑(gen 按条、prep 按 shard、训练与 APG 定时原子存档+体面停止);分歧以实现方意见为准
This commit is contained in:
@@ -13,6 +13,8 @@ from ml.common.features import features, STEP, H, GAP_CAP, D2R, wrap180
|
||||
DT = 0.02
|
||||
|
||||
|
||||
FIRST_DEG = 5.0 # R7 首次方向判定阈值(度):小于它的抖动不算选边
|
||||
|
||||
def tasks_to_tensors(tasks, device):
|
||||
q0 = torch.tensor([t['q0'] for t in tasks], dtype=torch.float32, device=device)
|
||||
T = torch.tensor([t['T'] for t in tasks], dtype=torch.float32, device=device)
|
||||
@@ -80,6 +82,7 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None,
|
||||
traj = [q.clone()] if return_traj else None
|
||||
n_start = int(round(0.5 / DT)); moved_start = None # R2 起步失败:0.5 s 内关节总行程 < 1°
|
||||
j1_acc = torch.zeros(B, device=device); j1_max = torch.zeros(B, device=device); j1_min = torch.zeros(B, device=device)
|
||||
j1_first = torch.zeros(B, device=device) # 2026-10-18 第五轮(审查 N-3):J1 累计偏离首次超过 FIRST_DEG 时的方向(真正的"首次方向")
|
||||
cold = True
|
||||
for it in range(nmax):
|
||||
tnow = it * DT
|
||||
@@ -146,6 +149,7 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None,
|
||||
qp = q; q = kin.clamp_box(q + d)
|
||||
travel += d.abs().sum(-1)
|
||||
j1_acc = j1_acc + d[:, 0]; j1_max = torch.maximum(j1_max, j1_acc); j1_min = torch.minimum(j1_min, j1_acc)
|
||||
j1_first = torch.where((j1_first == 0) & (j1_acc.abs() >= FIRST_DEG), torch.sign(j1_acc), j1_first)
|
||||
if it + 1 == n_start: moved_start = travel.clone()
|
||||
if return_traj: traj.append(q.clone())
|
||||
mid = qp + 0.5 * (q - qp)
|
||||
@@ -169,7 +173,8 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None,
|
||||
'start_fail': start_fail.float().mean().item(),
|
||||
'time_budget': 'teacher×2(≥3 s)' if bool(has_ref.all()) else ('fixed %.0f s' % (max_sec or NOREF_SEC) if not has_ref.any() else 'mixed')}
|
||||
# 绕行侧:J1 累计位移的正向/负向极值哪个更大(+1 / −1),供 R7 左右比例门禁
|
||||
side = torch.where(j1_max >= -j1_min, torch.ones_like(j1_max), -torch.ones_like(j1_max))
|
||||
# 首次方向;全程没偏离到 FIRST_DEG 的(基本不绕 J1)退回净方向
|
||||
side = torch.where(j1_first != 0, j1_first, torch.where(j1_max >= -j1_min, torch.ones_like(j1_max), -torch.ones_like(j1_max)))
|
||||
per = {'done': done.cpu(), 't_done': t_done.cpu(), 'col': col.cpu(), 'travel': travel.cpu(), 'err': e_end.cpu(),
|
||||
'side': side.cpu(), 'start_fail': start_fail.cpu(), 'brakes': brakes.cpu()}
|
||||
if return_traj: per['traj'] = torch.stack(traj, 1).cpu()
|
||||
@@ -217,7 +222,8 @@ def main():
|
||||
k = t.get('cat', '?') + '/' + t.get('mode', '?'); b = by.setdefault(k, [0, 0, 0]); b[0] += 1; b[1] += int(d); b[2] += int(c > 0)
|
||||
res['by_cat_mode'] = {k: {'n': v[0], 'success': v[1] / v[0], 'collision': v[2] / v[0]} for k, v in by.items()}
|
||||
s = json.dumps(res, indent=1); print(s)
|
||||
if a.out: open(a.out, 'w').write(s)
|
||||
if a.out: # 先写 .tmp 再改名:中断不会留下半截结果被当成已完成(M5 续跑按文件存在跳过)
|
||||
open(a.out + '.tmp', 'w').write(s); os.replace(a.out + '.tmp', a.out)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user