SuperHQ Motion experiment: locomotion and action checkpoints, runtime, clips, evaluation
6adbbb1 verified Download src/profile-controller.js from superhq-ai/motion: direct link, hf CLI and curl.
- Browser
- Download file 2.96 kB
-
https://huggingface.co/superhq-ai/motion/resolve/main/src/profile-controller.js
- Command line
-
hf download hf://superhq-ai/motion/src/profile-controller.js
-
curl -L -o profile-controller.js https://huggingface.co/superhq-ai/motion/resolve/main/src/profile-controller.js
2.96 kB
| import {DenseNetwork} from './network.js'; | |
| import {MotionProfileClock} from './profile-clock.js'; | |
| import {decodeMotionPose} from './controller.js'; | |
| /** Experimental profile-conditioned controller. Host engine owns physics. | |
| * This checkpoint supports the profiles and synthetic transitions in config. | |
| */ | |
| export class MotionProfileController { | |
| constructor(manifest,weights,config) { | |
| if(config?.format!=='superhq-motion-profile-controller-v1'||config.dt!==1/60|| | |
| manifest.layers[0]?.inputs!==34||manifest.layers.at(-1)?.outputs!==143|| | |
| !Array.isArray(config.rig?.end_sites)||config.rig.end_sites.filter(v=>!v).length!==23|| | |
| !config.profiles?.Idle_Loop||!Array.isArray(config.transitions))throw Error('Incompatible profile controller.'); | |
| this.network=new DenseNetwork(manifest,weights);this.config=config;this.rig=config.rig;this.reset(); | |
| } | |
| static async load(baseURL,{fetch:fetcher=globalThis.fetch}={}) { | |
| const base=baseURL instanceof URL?baseURL:new URL(baseURL,globalThis.location?.href); | |
| const request=async(path,binary=false)=>{const r=await fetcher(new URL(path,base));if(!r.ok)throw Error(`Cannot load ${path}: HTTP ${r.status}`);return binary?r.arrayBuffer():r.json();}; | |
| const [manifest,config]=await Promise.all([request('network.json'),request('profile-controller.json')]); | |
| if(manifest.weights!=='weights.bin')throw Error('Unexpected weight filename.'); | |
| const weights=await request(manifest.weights,true); | |
| if(!globalThis.crypto?.subtle)throw Error('Weight verification requires HTTPS or localhost.'); | |
| const digest=Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',weights)),v=>v.toString(16).padStart(2,'0')).join(''); | |
| if(digest!==manifest.sha256)throw Error('Motion weight checksum mismatch.'); | |
| return new MotionProfileController(manifest,weights,config); | |
| } | |
| reset({profile='Idle_Loop',rate=1,phase=0,position=[0,0,0]}={}) { | |
| const value=this.config.profiles[profile];if(!value)throw Error('Unknown motion profile.'); | |
| const clock=new MotionProfileClock(value,{rate});clock.reset(value,{rate,phase,position}); | |
| this.clock=clock;this.profile=profile; | |
| } | |
| setProfile(name,{rate=1}={}) { | |
| if(!this.config.profiles[name])throw Error('Unknown motion profile.'); | |
| if(this.clock.time-this.clock.start<this.clock.transitionSeconds-1e-8)throw Error('Finish the current profile transition before requesting another.'); | |
| const allowed=name===this.profile||this.config.transitions.some(([a,b])=>(a===name&&b===this.profile)||(b===name&&a===this.profile)); | |
| if(!allowed)throw Error('This transition has not been validated; use reset to select a separate profile.'); | |
| this.clock.setProfile(this.config.profiles[name],{rate});this.profile=name; | |
| } | |
| step() { | |
| const state=this.clock.step(),output=this.network.forward(state.input); | |
| return {...decodeMotionPose(output,this.rig,state.simulationPosition),...state,profile:this.profile}; | |
| } | |
| } | |