mujoco-react 9.0.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -10
- package/dist/index.d.ts +43 -33
- package/dist/index.js +547 -195
- package/dist/index.js.map +1 -1
- package/dist/spark.d.ts +1 -1
- package/dist/{types-izZlUweI.d.ts → types-S8ggQY2n.d.ts} +103 -1
- package/package.json +1 -1
- package/src/core/MujocoSimProvider.tsx +146 -2
- package/src/core/createController.tsx +6 -2
- package/src/hooks/useCameraFrameCapture.ts +94 -0
- package/src/hooks/useCameraSequenceRecorder.ts +59 -0
- package/src/hooks/useFrameCapture.ts +8 -42
- package/src/index.ts +26 -9
- package/src/rendering/cameraFrameCapture.ts +184 -0
- package/src/types.ts +136 -0
package/README.md
CHANGED
|
@@ -213,18 +213,20 @@ function Scene() {
|
|
|
213
213
|
## Write Controllers
|
|
214
214
|
|
|
215
215
|
```tsx
|
|
216
|
-
import { useBeforePhysicsStep } from "mujoco-react";
|
|
216
|
+
import { RobotActuators, useBeforePhysicsStep, useCtrl } from "mujoco-react";
|
|
217
217
|
|
|
218
218
|
function MyController() {
|
|
219
|
+
const shoulder = useCtrl(RobotActuators.franka.actuator1);
|
|
220
|
+
|
|
219
221
|
useBeforePhysicsStep(({ data }) => {
|
|
220
|
-
|
|
222
|
+
shoulder.write(Math.sin(data.time));
|
|
221
223
|
});
|
|
222
224
|
|
|
223
225
|
return null;
|
|
224
226
|
}
|
|
225
227
|
```
|
|
226
228
|
|
|
227
|
-
Controllers are just React children that read sensors, write
|
|
229
|
+
Controllers are just React children that read sensors, write named controls, apply forces, or call the `MujocoSimAPI` at physics-step time.
|
|
228
230
|
|
|
229
231
|
With generated resource values, reusable controllers can be scoped to one robot without hand-typing names:
|
|
230
232
|
|
|
@@ -388,15 +390,20 @@ function useWebSocketControls(url: string) {
|
|
|
388
390
|
For reusable controllers with typed config, default merging, and children, use the `createController` factory:
|
|
389
391
|
|
|
390
392
|
```tsx
|
|
391
|
-
import {
|
|
393
|
+
import {
|
|
394
|
+
RobotActuators,
|
|
395
|
+
createController,
|
|
396
|
+
useBeforePhysicsStep,
|
|
397
|
+
useCtrl,
|
|
398
|
+
} from "mujoco-react";
|
|
392
399
|
|
|
393
400
|
export const MyController = createController<{ gain: number }>(
|
|
394
401
|
{ name: "MyController", defaultConfig: { gain: 1.0 } },
|
|
395
402
|
({ config, children }) => {
|
|
396
|
-
const shoulder = useCtrl(
|
|
403
|
+
const shoulder = useCtrl(RobotActuators.franka.actuator1);
|
|
397
404
|
|
|
398
|
-
useBeforePhysicsStep(() => {
|
|
399
|
-
shoulder.write(config.gain * Math.sin(
|
|
405
|
+
useBeforePhysicsStep(({ data }) => {
|
|
406
|
+
shoulder.write(config.gain * Math.sin(data.time));
|
|
400
407
|
});
|
|
401
408
|
|
|
402
409
|
return <>{children}</>;
|
|
@@ -826,8 +833,12 @@ if (mujoco) {
|
|
|
826
833
|
Run logic **before** `mj_step` each frame. Write to `data.ctrl`, apply forces, drive automation.
|
|
827
834
|
|
|
828
835
|
```tsx
|
|
836
|
+
import { RobotActuators, useBeforePhysicsStep, useCtrl } from "mujoco-react";
|
|
837
|
+
|
|
838
|
+
const shoulder = useCtrl(RobotActuators.franka.actuator1);
|
|
839
|
+
|
|
829
840
|
useBeforePhysicsStep(({ data }) => {
|
|
830
|
-
|
|
841
|
+
shoulder.write(Math.sin(data.time));
|
|
831
842
|
});
|
|
832
843
|
```
|
|
833
844
|
|
|
@@ -861,8 +872,8 @@ Read sensor values by name. Returns a `SensorHandle` with `read()`, `dim`, and `
|
|
|
861
872
|
```tsx
|
|
862
873
|
import { RobotSensors, useSensor } from "mujoco-react";
|
|
863
874
|
|
|
864
|
-
const
|
|
865
|
-
//
|
|
875
|
+
const imu = useSensor(RobotSensors.g1["imu-torso-angular-velocity"]);
|
|
876
|
+
// imu.read() -> Float64Array, imu.dim -> number
|
|
866
877
|
```
|
|
867
878
|
|
|
868
879
|
### `useBodyState(name)`
|
|
@@ -983,6 +994,27 @@ const video = useVideoRecorder({ fps: 30, mimeType: "video/webm" });
|
|
|
983
994
|
// video.start(), video.stop() -> returns Blob
|
|
984
995
|
```
|
|
985
996
|
|
|
997
|
+
### Frame Capture
|
|
998
|
+
|
|
999
|
+
Capture dataset/debug stills from the rendered MuJoCo canvas:
|
|
1000
|
+
|
|
1001
|
+
```tsx
|
|
1002
|
+
const apiRef = useRef<MujocoSimAPI>(null);
|
|
1003
|
+
|
|
1004
|
+
const frame = await apiRef.current?.captureFrame({ type: "image/png" });
|
|
1005
|
+
const blob = await apiRef.current?.captureFrameBlob({ type: "image/png" });
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
Use `useFrameCapture()` or the standalone `captureFrame()` helpers when you own
|
|
1009
|
+
the canvas or want to capture a custom container.
|
|
1010
|
+
|
|
1011
|
+
Use `captureCameraFrame()` / `captureCameraFrameBlob()` when dataset generation
|
|
1012
|
+
needs a fixed offscreen camera pose or resolution without moving the user's
|
|
1013
|
+
interactive viewport.
|
|
1014
|
+
|
|
1015
|
+
Use `recordCameraSequence()` / `useCameraSequenceRecorder()` to step policy
|
|
1016
|
+
rollouts and capture synchronized frames from one or more fixed camera configs.
|
|
1017
|
+
|
|
986
1018
|
### `useCtrlNoise(config)`
|
|
987
1019
|
|
|
988
1020
|
Apply Gaussian noise to controls for robustness testing:
|
|
@@ -1104,7 +1136,10 @@ The full API object available via `ref` or `useMujoco()` (when `isReady`):
|
|
|
1104
1136
|
|--------|-------------|
|
|
1105
1137
|
| `raycast(origin, direction, maxDist?)` | Physics raycast via `mj_ray` |
|
|
1106
1138
|
| `project2DTo3D(x, y, camPos, lookAt)` | Screen-to-world raycast (returns bodyId + geomId) |
|
|
1139
|
+
| `getCanvas()` | Return the underlying R3F canvas element |
|
|
1107
1140
|
| `getCanvasSnapshot(w?, h?, mime?)` | Base64 screenshot |
|
|
1141
|
+
| `captureFrame(options?)` | Capture the canvas as a data URL |
|
|
1142
|
+
| `captureFrameBlob(options?)` | Capture the canvas as a Blob |
|
|
1108
1143
|
|
|
1109
1144
|
### Scene Management
|
|
1110
1145
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { M as MujocoContextValue, a as MujocoCanvasProps, b as MujocoSimAPI, S as SceneConfig, R as ReadyCallbackInput, c as StepCallbackInput, d as SelectionCallbackInput, e as MujocoModule, P as PhysicsStepCallback, f as MujocoModel, g as MujocoData, C as ControlGroupInfo, A as ActuatedJointInfo, h as ControlGroupSelector, O as ObservationConfig, i as ObservationResult, I as IkConfig, j as IkContextValue, B as BodyProps, k as IkGizmoProps, D as DragInteractionProps, l as SceneLightsProps, m as ScenarioLightingProps, n as SplatEnvironmentProps, V as VisualScenarioEffectsProps, o as VisualScenarioConfig, p as SplatRendererKind, q as PairedSplatEnvironmentConfig, r as SplatFormat, s as SplatCollisionProxyConfig, t as SplatCollisionPrimitive, u as ScenarioLightingPreset, v as SplatEnvironmentMetadataInput, w as SplatEnvironmentMetadata, x as SplatSceneInput, y as DebugProps, G as GeomInfo, z as ContactListenerProps, T as TrajectoryPlayerProps, E as ActuatorInfo, F as Sites, H as SitePositionResult, J as Sensors, K as SensorHandle, L as SensorInfo, N as Joints, Q as JointStateResult, U as Bodies, W as BodyStateResult, X as Actuators, Y as CtrlHandle, Z as ContactInfo, _ as KeyboardTeleopConfig, $ as PolicyConfig, a0 as PolicyVector, a1 as ObservationHandle, a2 as TrajectoryInput, a3 as TrajectoryStateChangeInput, a4 as PlaybackState, a5 as TrajectoryFrame } from './types-
|
|
3
|
-
export {
|
|
2
|
+
import { M as MujocoContextValue, a as MujocoCanvasProps, b as MujocoSimAPI, S as SceneConfig, R as ReadyCallbackInput, c as StepCallbackInput, d as SelectionCallbackInput, e as MujocoModule, P as PhysicsStepCallback, f as MujocoModel, g as MujocoData, C as ControlGroupInfo, A as ActuatedJointInfo, h as ControlGroupSelector, O as ObservationConfig, i as ObservationResult, I as IkConfig, j as IkContextValue, B as BodyProps, k as IkGizmoProps, D as DragInteractionProps, l as SceneLightsProps, m as ScenarioLightingProps, n as SplatEnvironmentProps, V as VisualScenarioEffectsProps, o as VisualScenarioConfig, p as SplatRendererKind, q as PairedSplatEnvironmentConfig, r as SplatFormat, s as SplatCollisionProxyConfig, t as SplatCollisionPrimitive, u as ScenarioLightingPreset, v as SplatEnvironmentMetadataInput, w as SplatEnvironmentMetadata, x as SplatSceneInput, y as DebugProps, G as GeomInfo, z as ContactListenerProps, T as TrajectoryPlayerProps, E as ActuatorInfo, F as Sites, H as SitePositionResult, J as Sensors, K as SensorHandle, L as SensorInfo, N as Joints, Q as JointStateResult, U as Bodies, W as BodyStateResult, X as Actuators, Y as CtrlHandle, Z as ContactInfo, _ as KeyboardTeleopConfig, $ as PolicyConfig, a0 as PolicyVector, a1 as ObservationHandle, a2 as TrajectoryInput, a3 as TrajectoryStateChangeInput, a4 as PlaybackState, a5 as TrajectoryFrame, a6 as FrameCaptureOptions, a7 as FrameCaptureResult, a8 as FrameCaptureBlobResult, a9 as FrameCaptureAPI, aa as CameraFrameCaptureOptions, ab as CameraFrameCaptureAPI, ac as CameraFrameSequenceRecorderAPI, ad as CameraFrameCaptureResult, ae as CameraFrameCaptureBlobResult } from './types-S8ggQY2n.js';
|
|
3
|
+
export { af as BodyInfo, ag as CameraFrameCaptureQuaternion, ah as CameraFrameCaptureVector3, ai as CameraFrameSequenceCamera, aj as CameraFrameSequenceFrame, ak as CameraFrameSequenceOptions, al as CameraFrameSequenceResult, am as ControlJointInfo, an as FrameCaptureStatus, ao as FrameCaptureTarget, ap as FrameCaptureTargetRef, aq as Geoms, ar as IKSolveFn, as as IkGizmoDragInput, at as IkSolveInput, au as JointInfo, av as KeyBinding, aw as Keyframes, ax as ModelOptions, ay as MujocoContact, az as MujocoContactArray, aA as MujocoFrameCaptureOptions, aB as ObservationLayoutItem, aC as ObservationOutput, aD as PhysicsConfig, aE as PhysicsStepInput, aF as PolicyActionInput, aG as PolicyInferenceInput, aH as PolicyObservationInput, aI as RayHit, aJ as Register, aK as RegisteredRobotMap, aL as ResetCallbackInput, aM as ResourceSelector, aN as RobotActuators, aO as RobotBodies, aP as RobotGeoms, aQ as RobotJoints, aR as RobotKeyframes, aS as RobotResource, aT as RobotResources, aU as RobotSensors, aV as RobotSites, aW as Robots, aX as ScenarioCameraConfig, aY as ScenarioMaterialConfig, aZ as SceneMarker, a_ as SceneObject, a$ as SensorResult, b0 as SiteInfo, b1 as SplatAssetConfig, b2 as SplatScenarioConfig, b3 as StateSnapshot, b4 as TrajectoryData, b5 as TrajectoryFrameCallbackInput, b6 as VisualScenarioMaterialFilterInput, b7 as XmlPatch, b8 as getContact, b9 as registerRobotResources } from './types-S8ggQY2n.js';
|
|
4
4
|
import * as React$1 from 'react';
|
|
5
|
-
import React__default from 'react';
|
|
6
5
|
import { ThreeElements } from '@react-three/fiber';
|
|
7
6
|
import * as THREE from 'three';
|
|
8
7
|
|
|
@@ -243,8 +242,10 @@ type ControllerComponent<TConfig> = React.FC<{
|
|
|
243
242
|
* const MyController = createController<{ speed: number }>(
|
|
244
243
|
* { name: 'my-controller', defaultConfig: { speed: 1.0 } },
|
|
245
244
|
* function MyControllerImpl({ config }) {
|
|
245
|
+
* const wheel = useCtrl(RobotActuators.mobile.leftWheel);
|
|
246
|
+
*
|
|
246
247
|
* useBeforePhysicsStep(({ data }) => {
|
|
247
|
-
*
|
|
248
|
+
* wheel.write(config.speed);
|
|
248
249
|
* });
|
|
249
250
|
* return null;
|
|
250
251
|
* },
|
|
@@ -270,9 +271,11 @@ declare function createController<TConfig>(options: ControllerOptions<TConfig>,
|
|
|
270
271
|
* { name: 'useMyController', defaultConfig: { gain: 1.0 } },
|
|
271
272
|
* function useMyControllerImpl(config) {
|
|
272
273
|
* // config is MyConfig | null — hooks must be called unconditionally
|
|
274
|
+
* const joint = useCtrl(config?.actuator ?? RobotActuators.franka.actuator1);
|
|
275
|
+
*
|
|
273
276
|
* useBeforePhysicsStep(({ data }) => {
|
|
274
277
|
* if (!config) return;
|
|
275
|
-
*
|
|
278
|
+
* joint.write(config.gain * Math.sin(data.time));
|
|
276
279
|
* });
|
|
277
280
|
* if (!config) return null;
|
|
278
281
|
* return { /* value *\/ };
|
|
@@ -758,33 +761,6 @@ declare function useVideoRecorder(options?: VideoRecorderOptions): {
|
|
|
758
761
|
* useFrameCapture — still-frame capture for canvas-backed MuJoCo/R3F scenes.
|
|
759
762
|
*/
|
|
760
763
|
|
|
761
|
-
type FrameCaptureStatus = 'idle' | 'capturing' | 'captured' | 'error';
|
|
762
|
-
type FrameCaptureTarget = HTMLCanvasElement | HTMLElement | null | undefined;
|
|
763
|
-
type FrameCaptureTargetRef = React__default.RefObject<HTMLCanvasElement | HTMLElement | null>;
|
|
764
|
-
interface FrameCaptureOptions {
|
|
765
|
-
target?: FrameCaptureTarget | FrameCaptureTargetRef;
|
|
766
|
-
type?: string;
|
|
767
|
-
quality?: number;
|
|
768
|
-
waitForAnimationFrame?: boolean;
|
|
769
|
-
}
|
|
770
|
-
interface FrameCaptureResult {
|
|
771
|
-
canvas: HTMLCanvasElement;
|
|
772
|
-
dataUrl: string;
|
|
773
|
-
type: string;
|
|
774
|
-
}
|
|
775
|
-
interface FrameCaptureBlobResult {
|
|
776
|
-
canvas: HTMLCanvasElement;
|
|
777
|
-
blob: Blob;
|
|
778
|
-
type: string;
|
|
779
|
-
}
|
|
780
|
-
interface FrameCaptureAPI {
|
|
781
|
-
status: FrameCaptureStatus;
|
|
782
|
-
error: Error | null;
|
|
783
|
-
isCapturing: boolean;
|
|
784
|
-
capture: (options?: FrameCaptureOptions) => Promise<FrameCaptureResult>;
|
|
785
|
-
captureBlob: (options?: FrameCaptureOptions) => Promise<FrameCaptureBlobResult>;
|
|
786
|
-
reset: () => void;
|
|
787
|
-
}
|
|
788
764
|
/**
|
|
789
765
|
* Capture the current canvas frame as a data URL.
|
|
790
766
|
*
|
|
@@ -801,6 +777,40 @@ declare function captureFrameBlob(options: FrameCaptureOptions): Promise<FrameCa
|
|
|
801
777
|
*/
|
|
802
778
|
declare function useFrameCapture(defaultOptions?: FrameCaptureOptions): FrameCaptureAPI;
|
|
803
779
|
|
|
780
|
+
/**
|
|
781
|
+
* @license
|
|
782
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
783
|
+
*
|
|
784
|
+
* React state wrapper around MuJoCo/R3F offscreen camera-frame capture.
|
|
785
|
+
*/
|
|
786
|
+
|
|
787
|
+
declare function useCameraFrameCapture(defaultOptions?: CameraFrameCaptureOptions): CameraFrameCaptureAPI;
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* @license
|
|
791
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
792
|
+
*
|
|
793
|
+
* React state wrapper around fixed-camera simulation sequence recording.
|
|
794
|
+
*/
|
|
795
|
+
|
|
796
|
+
declare function useCameraSequenceRecorder(): CameraFrameSequenceRecorderAPI;
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* @license
|
|
800
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
801
|
+
*
|
|
802
|
+
* Offscreen camera-frame capture for R3F/MuJoCo scenes.
|
|
803
|
+
*/
|
|
804
|
+
|
|
805
|
+
declare function renderCameraFrameToCanvas(renderer: THREE.WebGLRenderer, scene: THREE.Scene, fallbackCamera: THREE.Camera, options?: CameraFrameCaptureOptions): {
|
|
806
|
+
canvas: HTMLCanvasElement;
|
|
807
|
+
camera: THREE.Camera;
|
|
808
|
+
width: number;
|
|
809
|
+
height: number;
|
|
810
|
+
};
|
|
811
|
+
declare function captureCameraFrame(renderer: THREE.WebGLRenderer, scene: THREE.Scene, fallbackCamera: THREE.Camera, options?: CameraFrameCaptureOptions): Promise<CameraFrameCaptureResult>;
|
|
812
|
+
declare function captureCameraFrameBlob(renderer: THREE.WebGLRenderer, scene: THREE.Scene, fallbackCamera: THREE.Camera, options?: CameraFrameCaptureOptions): Promise<CameraFrameCaptureBlobResult>;
|
|
813
|
+
|
|
804
814
|
/**
|
|
805
815
|
* @license
|
|
806
816
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -896,4 +906,4 @@ interface CameraAnimationAPI {
|
|
|
896
906
|
*/
|
|
897
907
|
declare function useCameraAnimation(): CameraAnimationAPI;
|
|
898
908
|
|
|
899
|
-
export { ActuatedJointInfo, ActuatorInfo, Actuators, Bodies, Body, BodyProps, BodyStateResult, type CameraAnimationAPI, ContactInfo, ContactListener, ContactListenerProps, ContactMarkers, ControlGroupInfo, ControlGroupSelector, type ControllerComponent, type ControllerOptions, CtrlHandle, Debug, DebugProps, DragInteraction, DragInteractionProps, FlexRenderer,
|
|
909
|
+
export { ActuatedJointInfo, ActuatorInfo, Actuators, Bodies, Body, BodyProps, BodyStateResult, type CameraAnimationAPI, CameraFrameCaptureAPI, CameraFrameCaptureBlobResult, CameraFrameCaptureOptions, CameraFrameCaptureResult, CameraFrameSequenceRecorderAPI, ContactInfo, ContactListener, ContactListenerProps, ContactMarkers, ControlGroupInfo, ControlGroupSelector, type ControllerComponent, type ControllerOptions, CtrlHandle, Debug, DebugProps, DragInteraction, DragInteractionProps, FlexRenderer, FrameCaptureAPI, FrameCaptureBlobResult, FrameCaptureOptions, FrameCaptureResult, GeomInfo, IkConfig, IkContextValue, IkGizmo, IkGizmoProps, InstancedGeomRenderer, JointStateResult, Joints, KeyboardTeleopConfig, MujocoCanvas, MujocoCanvasProps, MujocoContextValue, MujocoData, type MujocoLoader, type MujocoLoaderOptions, MujocoModel, MujocoModule, MujocoPhysics, type MujocoPhysicsProps, MujocoProvider, type MujocoProviderProps, MujocoSimAPI, MujocoSimProvider, type MujocoWasmVariant, ObservationConfig, ObservationHandle, ObservationResult, PairedSplatEnvironmentConfig, PhysicsStepCallback, PlaybackState, PolicyConfig, PolicyVector, ReadyCallbackInput, ScenarioLighting, ScenarioLightingPreset, ScenarioLightingProps, SceneConfig, SceneLights, SceneLightsProps, SelectionCallbackInput, SensorHandle, SensorInfo, Sensors, SitePositionResult, Sites, SplatCollisionPrimitive, SplatCollisionProxyConfig, SplatEnvironment, SplatEnvironmentMetadata, SplatEnvironmentMetadataInput, SplatEnvironmentProps, SplatFormat, SplatRendererKind, SplatSceneInput, StepCallbackInput, TendonRenderer, TrajectoryFrame, TrajectoryInput, TrajectoryPlayer, TrajectoryPlayerProps, TrajectoryStateChangeInput, VisualScenarioConfig, VisualScenarioEffects, VisualScenarioEffectsProps, buildObservation, captureCameraFrame, captureCameraFrameBlob, captureFrame, captureFrameBlob, createContiguousControlGroup, createController, createControllerHook, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getControlMap, getName, getScenarioBackground, getScenarioCameraPosition, loadScene, renderCameraFrameToCanvas, resolveControlGroup, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useCameraFrameCapture, useCameraSequenceRecorder, useContactEvents, useContacts, useCtrl, useCtrlNoise, useFrameCapture, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useSplatEnvironment, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder, useVisualScenarioEffects, withSplatEnvironment };
|