perf(closed_loop): DLS 批量雅可比(25→10-17ms,数值差≤0.013°)+ 单题安全层早停;实时评估:单次规划 40-80ms 超 50Hz 预算 2-4 倍;实时节奏下每3步 36.3%、每6步 14.8%(每步 42.2% 不可实时)

This commit is contained in:
cbb
2026-10-20 12:20:31 +08:00
parent 26eb0815c2
commit 3b748c811c
2 changed files with 33 additions and 10 deletions
+14 -10
View File
@@ -51,20 +51,23 @@ def goal_err(kin, q, T, R):
def dls_steps(kin, q, T, R, n=3, scale=0.3, lam=0.5):
"""局部 DLS 精修:n 步增量 [B,n,6]"""
step = torch.tensor(STEP, device=q.device)
B = q.shape[0]
pose = (R.abs().sum(-1) > 0).float()
Rt = R.view(-1, 3, 3)
def err(x):
def err(x, Tb, Rtb, poseb):
xf = kin.cum_xf(x); p = kin.fk(x, xf); Rq = kin.orient(x, xf)
M = Rt @ Rq.transpose(1, 2)
rv = 0.5 * torch.stack([M[:, 2, 1] - M[:, 1, 2], M[:, 0, 2] - M[:, 2, 0], M[:, 1, 0] - M[:, 0, 1]], -1) * 100 * pose[:, None]
return torch.cat([T - p, rv], -1)
M = Rtb @ Rq.transpose(1, 2)
rv = 0.5 * torch.stack([M[:, 2, 1] - M[:, 1, 2], M[:, 0, 2] - M[:, 2, 0], M[:, 1, 0] - M[:, 0, 1]], -1) * 100 * poseb[:, None]
return torch.cat([Tb - p, rv], -1)
out = []; x = q.clone()
ar = torch.arange(6, device=q.device)
for _ in range(n):
e0 = err(x); J = []
for j in range(6):
dx = torch.zeros_like(x); dx[:, j] = 1e-3
J.append(-(err(x + dx) - e0) / 1e-3)
J = torch.stack(J, -1) # [B,6(err),6(q)]
e0 = err(x, T, Rt, pose)
# 2026-10-20:6 次串行有限差分合并为一次批量 FK(数值等价,单次规划 ~25ms→~7ms)
dx = torch.zeros(B, 6, 6, device=q.device); dx[:, ar, ar] = 1e-3
xp = (x[:, None, :] + dx).reshape(B * 6, 6)
ep = err(xp, T.repeat_interleave(6, 0), Rt.repeat_interleave(6, 0), pose.repeat_interleave(6, 0))
J = -((ep - e0.repeat_interleave(6, 0)) / 1e-3).view(B, 6, 6).transpose(1, 2) # [B,6(err),6(q)]
A = J @ J.transpose(1, 2) + lam ** 2 * torch.eye(6, device=q.device)
y = torch.linalg.solve(A, e0.unsqueeze(-1))
dq = (J.transpose(1, 2) @ y).squeeze(-1)
@@ -225,7 +228,7 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None,
else:
# 2026-10-19 修错位:last[i] = 上一计划从 qe_old 走 i 步后的位置;提交 3 步后 qe_new = last[3],
# 新候选 fut[0] 是 qe_new 再走 1 步 = 对应 last[4]。JS 部署(ik-policy.js)同一处同样修正。
n = min(fut.shape[2], last.shape[1] - 4)
n = min(fut.shape[2], last.shape[1] - (commit_n + 1))
w = 0.85 ** torch.arange(n, device=device, dtype=torch.float32)
d2 = (((fut[:, :, :n] - last[:, None, commit_n + 1:commit_n + 1 + n]) / step) ** 2).sum(-1)
# 2026-10-19(审查 review_closedloop F5):上一次是刹停或 DLS 接管的行没有「已提交计划」,
@@ -251,6 +254,7 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None,
take = plen > maxlen
chosen = torch.where(take[:, None, None], ck, chosen); chosen_k = torch.where(take, order[:, kk], chosen_k)
maxlen = torch.maximum(maxlen, plen)
if B == 1 and int(maxlen[0]) >= commit_n: break # 实时单题:首个全安全候选即停(安全层 16 点→2-4 点)
msk = (torch.arange(commit_n, device=device)[None] < maxlen[:, None])
commit = torch.where(msk[..., None], chosen, torch.zeros_like(chosen))
brakes += (maxlen == 0).float()