Manufacturing-MoE / src /arc_gravity.py
rasitcesur's picture
Sync from rasitcesur/Manufacturing-MoE via hub-sync
547ac30 verified
Raw History Blame Contribute Delete
3.32 kB
"""Gravity/subtree representation for GMAW motion; uses public config and target commanded q ONLY.
No private simulator coefficients, true target energies or target telemetry are consulted.
"""
from pathlib import Path
import sys,json,numpy as np
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT/'runtime'))
from arc_base_physics import fk_positions,torch_tips
def gravity_context(cfg,program):
n=cfg['n'];pa=np.asarray(cfg['parents'],int);mass=np.asarray(cfg['mass'],float).copy()
edges=torch_tips(cfg);sub=np.zeros(n)
pm=program['segments'][0].get('payload_kg',1.)
for i in edges: mass[i]+=pm/max(1,len(edges))
sub[:]=mass
for i in range(n-1,-1,-1):
if pa[i]>=0:sub[pa[i]]+=sub[i]
depth=np.zeros(n)
for i in range(n):
if pa[i]>=0:depth[i]=depth[pa[i]]+1
joint_up=np.zeros(n);joint_down=np.zeros(n);net=np.zeros(n);delta=np.zeros(n);max_tau=np.zeros(n)
ancestors=[]
for k in range(n):
an=[];r=k
while r>=0:an.append(r);r=pa[r]
ancestors.append(an)
for seg in program['segments']:
q0=np.asarray(seg['q0'],float);q1=np.asarray(seg['q1'],float);d=q1-q0
# Midpoint approximation to signed conservative potential work. Orientation determines its sign.
q=.5*(q0+q1);rotation,pivot=fk_positions(cfg,q)
axes=[]
for i in range(n):
rp=np.eye(3) if pa[i]<0 else rotation[pa[i]]
axes.append(rp@np.asarray(cfg['axes'][i],float))
cm=[pivot[i]+rotation[i]@np.asarray(cfg['coms'][i],float) for i in range(n)]
tau=np.zeros(n)
for k in range(n):
for i in ancestors[k]:
tau[i]+=mass[k]*9.81*np.cross(axes[i],cm[k]-pivot[i])[2]
work=tau*d
joint_up+=np.maximum(work,0);joint_down+=np.maximum(-work,0);net+=work
delta+=d;max_tau=np.maximum(max_tau,np.abs(tau))
j=np.zeros((15,10),np.float32)
for i in range(n):
j[i]=[np.log1p(joint_up[i]),np.log1p(joint_down[i]),np.sign(net[i])*np.log1p(abs(net[i])),
np.sign(delta[i])*np.log1p(abs(delta[i])),np.log1p(max_tau[i]),
np.sign(net[i])*np.log1p(max_tau[i]),np.log1p(sub[i]),sub[i]/max(mass.sum(),.01),
depth[i]/15.,float(joint_up[i]+joint_down[i]<1e-8)]
allup=joint_up.sum();alldown=joint_down.sum()
g=np.array([np.log1p(allup),np.log1p(alldown),np.sign(net.sum())*np.log1p(abs(net.sum())),
allup/(allup+alldown+1e-8),np.log1p(mass.sum()),np.log1p(sub.max()),
float(np.mean(np.abs(delta)<1e-8)),float(np.mean(j[:n,9]))],np.float32)
return j,g
def generate(split):
base=ROOT/'data/arc_welding'
machines={m['robot_id']:m['robot'] for m in json.loads((base/f'{split}_machines.json').read_text())}
js=[];gs=[]
for line in (base/f'{split}_programs.jsonl').open():
record=json.loads(line)
j,g=gravity_context(machines[record['robot_id']],record['program'])
js.append(j);gs.append(g)
assert len(js)==len(np.load(base/f'{split}.npz')['y'])
np.savez_compressed(base/f'{split}_gravity_v53.npz',joint_gravity=np.array(js,np.float32),global_gravity=np.array(gs,np.float32))
print(split,len(js),'signed gravity complete',flush=True)
if __name__=='__main__':
for split in ('train','val','test','ood'):generate(split)