|
import torch |
|
|
|
|
|
def foot_contact_by_height(pos): |
|
eps = 0.25 |
|
return (-eps < pos[..., 1]) * (pos[..., 1] < eps) |
|
|
|
|
|
def velocity(pos, padding=False): |
|
velo = pos[1:, ...] - pos[:-1, ...] |
|
velo_norm = torch.norm(velo, dim=-1) |
|
if padding: |
|
pad = torch.zeros_like(velo_norm[:1, :]) |
|
velo_norm = torch.cat([pad, velo_norm], dim=0) |
|
return velo_norm |
|
|
|
|
|
def foot_contact(pos, ref_height=1., threshold=0.018): |
|
velo_norm = velocity(pos) |
|
contact = velo_norm < threshold |
|
contact = contact.int() |
|
padding = torch.zeros_like(contact) |
|
contact = torch.cat([padding[:1, :], contact], dim=0) |
|
return contact |
|
|
|
|
|
def alpha(t): |
|
return 2.0 * t * t * t - 3.0 * t * t + 1 |
|
|
|
|
|
def lerp(a, l, r): |
|
return (1 - a) * l + a * r |
|
|
|
|
|
def constrain_from_contact(contact, glb, fid='TBD', L=5): |
|
""" |
|
:param contact: contact label |
|
:param glb: original global position |
|
:param fid: joint id to fix, corresponding to the order in contact |
|
:param L: frame to look forward/backward |
|
:return: |
|
""" |
|
T = glb.shape[0] |
|
|
|
for i, fidx in enumerate(fid): |
|
fixed = contact[:, i] |
|
s = 0 |
|
while s < T: |
|
while s < T and fixed[s] == 0: |
|
s += 1 |
|
if s >= T: |
|
break |
|
t = s |
|
avg = glb[t, fidx].clone() |
|
while t + 1 < T and fixed[t + 1] == 1: |
|
t += 1 |
|
avg += glb[t, fidx].clone() |
|
avg /= (t - s + 1) |
|
|
|
for j in range(s, t + 1): |
|
glb[j, fidx] = avg.clone() |
|
s = t + 1 |
|
|
|
for s in range(T): |
|
if fixed[s] == 1: |
|
continue |
|
l, r = None, None |
|
consl, consr = False, False |
|
for k in range(L): |
|
if s - k - 1 < 0: |
|
break |
|
if fixed[s - k - 1]: |
|
l = s - k - 1 |
|
consl = True |
|
break |
|
for k in range(L): |
|
if s + k + 1 >= T: |
|
break |
|
if fixed[s + k + 1]: |
|
r = s + k + 1 |
|
consr = True |
|
break |
|
if not consl and not consr: |
|
continue |
|
if consl and consr: |
|
litp = lerp(alpha(1.0 * (s - l + 1) / (L + 1)), |
|
glb[s, fidx], glb[l, fidx]) |
|
ritp = lerp(alpha(1.0 * (r - s + 1) / (L + 1)), |
|
glb[s, fidx], glb[r, fidx]) |
|
itp = lerp(alpha(1.0 * (s - l + 1) / (r - l + 1)), |
|
ritp, litp) |
|
glb[s, fidx] = itp.clone() |
|
continue |
|
if consl: |
|
litp = lerp(alpha(1.0 * (s - l + 1) / (L + 1)), |
|
glb[s, fidx], glb[l, fidx]) |
|
glb[s, fidx] = litp.clone() |
|
continue |
|
if consr: |
|
ritp = lerp(alpha(1.0 * (r - s + 1) / (L + 1)), |
|
glb[s, fidx], glb[r, fidx]) |
|
glb[s, fidx] = ritp.clone() |
|
return glb |
|
|