Instructions to use djduecaster/dfreq-tug with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Microduck
How to use djduecaster/dfreq-tug with Microduck:
# Replace SLOT with the slot specified in the model card (walk, stand, sitstand, ground_pick, kick_left, kick_right, roulade). sudo robotctl policy load SLOT djduecaster/dfreq-tug
- Notebooks
- Google Colab
- Kaggle
File size: 3,152 Bytes
c234222 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | """Original source-authored feedback controller; no model imports or learned weights.
Experimental simulation artifact, unscored. Raw Arena obs -> residual joint targets.
Only ONNX and NumPy are required. This script never runs a simulator or network call.
"""
from pathlib import Path
import hashlib,json
import numpy as np
import onnx
from onnx import TensorProto,helper,numpy_helper
# Interface joint order: left hip yaw/roll/pitch/knee/ankle; neck/head four;
# right hip yaw/roll/pitch/knee/ankle. Parameters below are authored here.
# These are conservative initial hypotheses, not identified control gains.
PARAMS=dict(knee_flex=0.08,back_lean=0.02,pitch_kp=0.12,pitch_kd=0.02,
roll_kp=0.10,roll_kd=0.02,joint_damping=0.003)
def coefficients(params=PARAMS):
w=np.zeros((61,14),np.float32); b=np.zeros(14,np.float32)
c=params['knee_flex']
# Mirrored sagittal axes; +hip -knee +ankle is the left-chain rotation.
b[[2,3,4]]=[c/2,c,c/2+params['back_lean']]
b[[11,12,13]]=[-c/2,-c,-c/2-params['back_lean']]
for j,sign in [(4,1),(13,-1)]:
w[3,j]=sign*params['pitch_kp'] # projected gravity x ~ trunk pitch
w[1,j]=sign*params['pitch_kd'] # gyro y, corrective ankle response
for j in (1,10):
w[4,j]=-params['roll_kp'] # projected gravity y ~ -trunk roll
w[0,j]=params['roll_kd']
active=[1,2,3,4,10,11,12,13]
for j in active: w[20+j,j]=-params['joint_damping']
limits=np.zeros(14,np.float32)
limits[active]=[.12,.15,.30,.20,.12,.15,.30,.20]
return w,b,-limits,limits
def act(obs,params=PARAMS):
w,b,lo,hi=coefficients(params)
return np.clip(np.asarray(obs,np.float32)@w+b,lo,hi)
def build(path,params=PARAMS):
w,b,lo,hi=coefficients(params)
constants=[numpy_helper.from_array(a,n) for a,n in [(w,'feedback'),(b,'pose_bias'),(lo,'lower'),(hi,'upper')]]
graph=helper.make_graph([
helper.make_node('MatMul',['obs','feedback'],['response']),
helper.make_node('Add',['response','pose_bias'],['raw_action']),
helper.make_node('Max',['raw_action','lower'],['floored_action']),
helper.make_node('Min',['floored_action','upper'],['action'])],
'original_observation_feedback_brace',
[helper.make_tensor_value_info('obs',TensorProto.FLOAT,[1,61])],
[helper.make_tensor_value_info('action',TensorProto.FLOAT,[1,14])],constants)
model=helper.make_model(graph,producer_name='source-authored CPU brace prototype',opset_imports=[helper.make_opsetid('',13)])
model.ir_version=8
model.doc_string='Unscored original affine feedback brace. No reference policy weights, clock, seeds, recurrence, or training.'
onnx.checker.check_model(model)
onnx.save(model,str(path))
return {'parameters':params,'sha256':hashlib.sha256(path.read_bytes()).hexdigest(),'bytes':path.stat().st_size,
'learned_weights':False,'reference_weights_used':False,'simulated':False}
if __name__=='__main__':
root=Path(__file__).resolve().parent
info=build(root/'policy.onnx')
(root/'build.json').write_text(json.dumps(info,indent=2)+'\n')
print(json.dumps(info,indent=2))
|