@@ -87,43 +87,37 @@ function MyComponent() {
8787
8888## Writing a Controller
8989
90- A controller is a hook that uses handle-based access for type-safe actuator and sensor control :
90+ A controller is a hook that reads sensors and writes actuators each physics step :
9191
9292``` tsx
93- import { createControllerHook , useCtrl , useSensor , useBeforePhysicsStep } from " mujoco-react" ;
93+ import { useCtrl , useSensor , useBeforePhysicsStep } from " mujoco-react" ;
9494
95- export const useMyController = createControllerHook <{ gain: number }, { amplitude: number }>(
96- { name: " useMyController" , defaultConfig: { gain: 1.0 } },
97- (config ) => {
98- const shoulder = useCtrl (" shoulder" );
99- const elbow = useCtrl (" elbow" );
100- const force = useSensor (" force_sensor" );
101-
102- useBeforePhysicsStep (() => {
103- if (! config ) return ;
104- shoulder .write (config .gain * Math .sin (Date .now () / 1000 ));
105- elbow .write (force .read ()[0 ] * - 0.5 );
106- });
107-
108- return config ? { amplitude: shoulder .read () } : null ;
109- },
110- );
95+ function useMyController(gain : number ) {
96+ const shoulder = useCtrl (" shoulder" );
97+ const elbow = useCtrl (" elbow" );
98+ const force = useSensor (" force_sensor" );
11199
112- // const result = useMyController({ gain: 2.0 });
113- // const disabled = useMyController(null); // returns null, no-ops
100+ useBeforePhysicsStep (() => {
101+ shoulder .write (gain * Math .sin (Date .now () / 1000 ));
102+ elbow .write (force .read ()[0 ] * - 0.5 );
103+ });
104+ }
114105```
115106
116- For controllers that render children (debug overlays, context providers, etc.), use the component factory:
107+ For reusable controllers with typed config, default merging, and children, use the ` createController ` factory:
117108
118109``` tsx
119- import { createController , useBeforePhysicsStep } from " mujoco-react" ;
110+ import { createController , useCtrl , useBeforePhysicsStep } from " mujoco-react" ;
120111
121112export const MyController = createController <{ gain: number }>(
122113 { name: " MyController" , defaultConfig: { gain: 1.0 } },
123114 ({ config , children }) => {
124- useBeforePhysicsStep ((_model , data ) => {
125- data .ctrl [0 ] = config .gain * Math .sin (data .time );
115+ const shoulder = useCtrl (" shoulder" );
116+
117+ useBeforePhysicsStep (() => {
118+ shoulder .write (config .gain * Math .sin (Date .now () / 1000 ));
126119 });
120+
127121 return <>{ children } </>;
128122 },
129123);
@@ -133,6 +127,8 @@ export const MyController = createController<{ gain: number }>(
133127// </MyController>
134128```
135129
130+ A ` createControllerHook ` factory is also available for the hook equivalent — see the [ Building Controllers] ( https://dadd.mintlify.app/guides/building-controllers ) guide.
131+
136132## Architecture
137133
138134` <MujocoCanvas> ` wraps R3F ` <Canvas> ` and forwards all Canvas props (` camera ` , ` shadows ` , ` gl ` , etc.). For full control over the Canvas, use ` <MujocoPhysics> ` inside your own:
0 commit comments