### Loading and Initializing MuJoCo in Browser with JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This snippet initializes the MuJoCo WebAssembly module, sets up a virtual filesystem using Emscripten, loads an XML model from a file, and creates model and data instances. It requires the mujoco-js library and fetches XML models via HTTP. Outputs include model statistics like number of bodies and DOFs; limitations include manual cleanup of resources to prevent memory leaks. ```javascript import load_mujoco from './node_modules/mujoco-js/dist/mujoco_wasm.js'; // Load the MuJoCo WebAssembly module const mujoco = await load_mujoco(); // Set up Emscripten's Virtual File System mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); // Fetch and write XML model to virtual filesystem const modelXML = await (await fetch('./assets/scenes/humanoid.xml')).text(); mujoco.FS.writeFile('/working/humanoid.xml', modelXML); // Load model from virtual filesystem const model = mujoco.MjModel.loadFromXML('/working/humanoid.xml'); const data = new mujoco.MjData(model); console.log(`Model loaded: ${model.nbody} bodies, ${model.nq} DOFs`); // Output: Model loaded: 14 bodies, 28 DOFs // Clean up when done data.delete(); model.delete(); ``` -------------------------------- ### Load and Interact with MuJoCo WASM Model using JavaScript Source: https://github.com/zalo/mujoco_wasm/blob/main/README.md This snippet demonstrates how to load a MuJoCo model from an XML file into the browser using the MuJoCo WASM bindings. It covers setting up the virtual file system, loading the model and data, accessing model and data properties, stepping the simulation, running forward kinematics, resetting the simulation, applying forces, and cleaning up resources. ```javascript import load_mujoco from "./dist/mujoco_wasm.js"; // Load the MuJoCo Module const mujoco = await load_mujoco(); // Set up Emscripten's Virtual File System mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); mujoco.FS.writeFile("/working/humanoid.xml", await (await fetch("./assets/scenes/humanoid.xml")).text()); // Load model and create data let model = mujoco.MjModel.loadFromXML("/working/humanoid.xml"); let data = new mujoco.MjData(model); // Access model properties directly let timestep = model.opt.timestep; let nbody = model.nbody; // Access data buffers (typed arrays) let qpos = data.qpos; // Joint positions let qvel = data.qvel; // Joint velocities let ctrl = data.ctrl; // Control inputs let xpos = data.xpos; // Body positions // Step the simulation mujoco.mj_step(model, data); // Run forward kinematics mujoco.mj_forward(model, data); // Reset simulation mujoco.mj_resetData(model, data); // Apply forces (force, torque, point, body, qfrc_target) mujoco.mj_applyFT(model, data, [fx, fy, fz], [tx, ty, tz], [px, py, pz], bodyId, data.qfrc_applied); // Clean up data.delete(); model.delete(); ``` -------------------------------- ### Load Multiple Assets to Virtual Filesystem with MuJoCo WASM Source: https://context7.com/zalo/mujoco_wasm/llms.txt This Javascript function asynchronously downloads a list of scene files and assets, then writes them to Emscripten's virtual filesystem (MEMFS) under the '/working/' directory. It handles directory creation and determines whether to write files as text (XML) or binary (images, meshes). ```javascript import load_mujoco from './node_modules/mujoco_js/dist/mujoco_wasm.js'; async function downloadExampleScenesFolder(mujoco) { const allFiles = [ 'humanoid.xml', 'car.xml', 'agility_cassie/cassie.xml', 'agility_cassie/scene.xml', 'agility_cassie/assets/pelvis.obj', 'agility_cassie/assets/cassie-texture.png', 'shadow_hand/scene_right.xml', 'shadow_hand/assets/palm.obj', 'mug.xml', 'mug.obj', 'mug.png' ]; // Fetch all files in parallel const requests = allFiles.map(url => fetch('./assets/scenes/' + url)); const responses = await Promise.all(requests); // Write files to virtual filesystem for (let i = 0; i < responses.length; i++) { const filePath = allFiles[i]; const split = filePath.split('/'); // Create directories if needed let working = '/working/'; for (let f = 0; f < split.length - 1; f++) { working += split[f]; if (!mujoco.FS.analyzePath(working).exists) { mujoco.FS.mkdir(working); } working += '/'; } // Write file (binary for images/meshes, text for XML) if (filePath.endsWith('.png') || filePath.endsWith('.obj') || filePath.endsWith('.stl')) { mujoco.FS.writeFile( '/working/' + filePath, new Uint8Array(await responses[i].arrayBuffer()) ); } else { mujoco.FS.writeFile( '/working/' + filePath, await responses[i].text() ); } } console.log(`Loaded ${allFiles.length} files to virtual filesystem`); } // Usage const mujoco = await load_mujoco(); mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); await downloadExampleScenesFolder(mujoco); // Now can load any scene const model = mujoco.MjModel.loadFromXML('/working/agility_cassie/scene.xml'); ``` -------------------------------- ### Stepping the Physics Simulation with MuJoCo JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This code loads a simple MuJoCo model, runs multiple simulation steps using mj_step, accesses post-simulation state like joint positions and velocities, and demonstrates resetting and forward kinematics. It depends on mujoco-js for WebAssembly integration and uses in-memory XML for the model. Inputs are simulation steps count; outputs include state arrays like qpos and qvel; note that timestep is model-defined and integration occurs during steps. ```javascript import load_mujoco from './node_modules/mujoco-js/dist/mujoco_wasm.js'; const mujoco = await load_mujoco(); mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); const modelXML = ''; mujoco.FS.writeFile('/working/simple.xml', modelXML); const model = mujoco.MjModel.loadFromXML('/working/simple.xml'); const data = new mujoco.MjData(model); // Access simulation parameters const timestep = model.opt.timestep; console.log(`Timestep: ${timestep} seconds`); // Output: Timestep: 0.002 seconds // Run 1000 simulation steps for (let i = 0; i < 1000; i++) { mujoco.mj_step(model, data); } // Access state after simulation const qpos = data.qpos; // Joint positions (Float64Array) const qvel = data.qvel; // Joint velocities (Float64Array) const xpos = data.xpos; // Cartesian body positions (Float64Array) console.log(`Position after 1000 steps: [${qpos[0]}, ${qpos[1]}, ${qpos[2]}]`); // Reset simulation to initial state mujoco.mj_resetData(model, data); // Run forward kinematics only (no integration) mujoco.mj_forward(model, data); data.delete(); model.delete(); ``` -------------------------------- ### Control MuJoCo Actuators with Noise in JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This snippet demonstrates how to set control inputs for actuators in a MuJoCo model using the mujoco-wasm library. It includes setting control values to mid-range and adding Gaussian noise to the control signals before stepping the simulation. Dependencies include the mujoco-wasm library and a MuJoCo model file. ```javascript import load_mujoco from './node_modules/mujoco-js/dist/mujoco_wasm.js'; const mujoco = await load_mujoco(); mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); const modelXML = await (await fetch('./assets/scenes/humanoid.xml')).text(); mujoco.FS.writeFile('/working/humanoid.xml', modelXML); const model = mujoco.MjModel.loadFromXML('/working/humanoid.xml'); const data = new mujoco.MjData(model); // Get actuator control ranges const numActuators = model.nu; const ctrlRange = model.actuator_ctrlrange; // [min0, max0, min1, max1, ...] console.log(`Model has ${numActuators} actuators`); // Set control values for each actuator for (let i = 0; i < numActuators; i++) { if (model.actuator_ctrllimited[i]) { const minCtrl = ctrlRange[2 * i]; const maxCtrl = ctrlRange[2 * i + 1]; // Set to mid-range value data.ctrl[i] = (minCtrl + maxCtrl) / 2.0; } else { data.ctrl[i] = 0.0; } } // Add gaussian noise to control signals const noiseRate = 0.1; const noiseStd = 0.05; const timestep = model.opt.timestep; const rate = Math.exp(-timestep / Math.max(1e-10, noiseRate)); const scale = noiseStd * Math.sqrt(1 - rate * rate); for (let i = 0; i < numActuators; i++) { const noise = scale * (Math.sqrt(-2.0 * Math.log(Math.random())) * Math.cos(2.0 * Math.PI * Math.random())); data.ctrl[i] = rate * data.ctrl[i] + noise; } // Step simulation with control inputs mujoco.mj_step(model, data); data.delete(); model.delete(); ``` -------------------------------- ### Create Three.js Visualization from MuJoCo Model in JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This JavaScript code loads a MuJoCo model using the mujoco-js library, creates a Three.js scene, and builds geometries for each MuJoCo geom based on type, size, and color. It groups meshes by body ID and applies materials for realistic rendering, skipping invisible groups. Dependencies include Three.js and mujoco-js; inputs are the model XML, outputs are the populated Three.js scene and bodies object. ```javascript import * as THREE from 'three'; import load_mujoco from './node_modules/mujoco-js/dist/mujoco_wasm.js'; const mujoco = await load_mujoco(); mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); const modelXML = await (await fetch('./assets/scenes/humanoid.xml')).text(); mujoco.FS.writeFile('/working/humanoid.xml', modelXML); const model = mujoco.MjModel.loadFromXML('/working/humanoid.xml'); const data = new mujoco.MjData(model); // Create Three.js scene const scene = new THREE.Scene(); const mujocoRoot = new THREE.Group(); mujocoRoot.name = "MuJoCo Root"; scene.add(mujocoRoot); // Storage for body meshes const bodies = {}; // Decode model names const textDecoder = new TextDecoder('utf-8'); const names = textDecoder.decode(model.names).split('\0'); // Create Three.js geometries for each MuJoCo geom for (let g = 0; g < model.ngeom; g++) { if (model.geom_group[g] >= 3) continue; // Skip invisible groups const bodyId = model.geom_bodyid[g]; const geomType = model.geom_type[g]; const size = [ model.geom_size[g * 3 + 0], model.geom_size[g * 3 + 1], model.geom_size[g * 3 + 2] ]; // Create body group if needed if (!bodies[bodyId]) { bodies[bodyId] = new THREE.Group(); bodies[bodyId].bodyID = bodyId; mujocoRoot.add(bodies[bodyId]); } // Create geometry based on type let geometry; if (geomType === mujoco.mjtGeom.mjGEOM_SPHERE.value) { geometry = new THREE.SphereGeometry(size[0], 20, 20); } else if (geomType === mujoco.mjtGeom.mjGEOM_BOX.value) { geometry = new THREE.BoxGeometry(size[0] * 2, size[2] * 2, size[1] * 2); } else if (geomType === mujoco.mjtGeom.mjGEOM_CAPSULE.value) { geometry = new THREE.CapsuleGeometry(size[0], size[1] * 2, 20, 20); } else if (geomType === mujoco.mjtGeom.mjGEOM_CYLINDER.value) { geometry = new THREE.CylinderGeometry(size[0], size[0], size[1] * 2); } else { geometry = new THREE.SphereGeometry(size[0]); } // Get color from model const color = new THREE.Color( model.geom_rgba[g * 4 + 0], model.geom_rgba[g * 4 + 1], model.geom_rgba[g * 4 + 2] ); const material = new THREE.MeshPhysicalMaterial({ color: color, transparent: model.geom_rgba[g * 4 + 3] < 1.0, opacity: model.geom_rgba[g * 4 + 3] }); const mesh = new THREE.Mesh(geometry, material); mesh.castShadow = true; mesh.receiveShadow = true; mesh.bodyID = bodyId; bodies[bodyId].add(mesh); } console.log(`Created visualization for ${model.ngeom} geometries across ${Object.keys(bodies).length} bodies`); data.delete(); model.delete(); ``` -------------------------------- ### Load MuJoCo Keyframes in JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This snippet shows how to load predefined keyframe positions from a MuJoCo model into the current simulation state using the mujoco-wasm library. It retrieves the number of keyframes, copies the position data for a specified keyframe, and then updates the simulation's derived quantities. Dependencies include the mujoco-wasm library and a MuJoCo model file. ```javascript import load_mujoco from './node_modules/mujoco-js/dist/mujoco_wasm.js'; const mujoco = await load_mujoco(); mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); const modelXML = await (await fetch('./assets/scenes/humanoid.xml')).text(); mujoco.FS.writeFile('/working/humanoid.xml', modelXML); const model = mujoco.MjModel.loadFromXML('/working/humanoid.xml'); const data = new mujoco.MjData(model); // Check number of keyframes const numKeyframes = model.nkey; const nq = model.nq; // Number of position coordinates console.log(`Model contains ${numKeyframes} keyframes`); if (numKeyframes > 0) { // Load keyframe 0 const keyframeIndex = 0; const keyframeStart = keyframeIndex * nq; const keyframeEnd = (keyframeIndex + 1) * nq; // Copy keyframe positions to current state data.qpos.set(model.key_qpos.slice(keyframeStart, keyframeEnd)); // Update derived quantities mujoco.mj_forward(model, data); console.log(`Loaded keyframe ${keyframeIndex}`); console.log(`Root position: [${data.qpos[0]}, ${data.qpos[1]}, ${data.qpos[2]}]`); } data.delete(); model.delete(); ``` -------------------------------- ### Applying Forces and Torques to Bodies in MuJoCo JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This snippet applies external forces and torques to a specific body using mj_applyFT, clears prior forces, and steps the simulation to update positions. It relies on a loaded MuJoCo model from XML and mujoco-js bindings. Inputs include force/torque vectors, application point, and body ID; outputs are updated generalized forces in qfrc_applied and body positions; limitations involve local coordinate application and manual force clearing. ```javascript import load_mujoco from './node_modules/mujoco-js/dist/mujoco_wasm.js'; const mujoco = await load_mujoco(); mujoco.FS.mkdir('/working'); mujoco.FS.mount(mujoco.MEMFS, { root: '.' }, '/working'); const modelXML = await (await fetch('./assets/scenes/humanoid.xml')).text(); mujoco.FS.writeFile('/working/humanoid.xml', modelXML); const model = mujoco.MjModel.loadFromXML('/working/humanoid.xml'); const data = new mujoco.MjData(model); // Define force/torque parameters const force = [0.0, 0.0, 100.0]; // 100N upward force const torque = [0.0, 0.0, 0.0]; // No torque const point = [0.0, 0.5, 0.0]; // Application point (local coordinates) const bodyId = 1; // Body index to apply force to // Clear previous applied forces for (let i = 0; i < data.qfrc_applied.length; i++) { data.qfrc_applied[i] = 0.0; } // Apply force/torque to body mujoco.mj_applyFT( model, data, force, // Force vector [fx, fy, fz] torque, // Torque vector [tx, ty, tz] point, // Application point [px, py, pz] bodyId, // Body ID data.qfrc_applied // Output: generalized forces ); // Step simulation with applied forces mujoco.mj_step(model, data); console.log(`Body ${bodyId} position: [${data.xpos[bodyId*3]}, ${data.xpos[bodyId*3+1]}, ${data.xpos[bodyId*3+2]}]`); data.delete(); model.delete(); ``` -------------------------------- ### Interactive Body Dragging with Raycasting (JavaScript) Source: https://context7.com/zalo/mujoco_wasm/llms.txt This code snippet implements a drag and manipulate functionality for 3D bodies using raycasting. It leverages Three.js for the visual components and raycasting, integrating with MuJoCo for the physics simulation. The drag manager class handles the mouse interactions and applies forces to the selected object in the MuJoCo environment. ```javascript import * as THREE from 'three'; import { toMujocoPos } from './mujocoUtils.js'; class DragStateManager { constructor(scene, renderer, camera, controls) { this.scene = scene; this.camera = camera; this.renderer = renderer; this.controls = controls; this.raycaster = new THREE.Raycaster(); this.mousePos = new THREE.Vector2(); this.physicsObject = null; this.active = false; this.grabDistance = 0.0; this.localHit = new THREE.Vector3(); this.worldHit = new THREE.Vector3(); this.currentWorld = new THREE.Vector3(); } updateRaycaster(x, y) { const rect = this.renderer.domElement.getBoundingClientRect(); this.mousePos.x = ((x - rect.left) / rect.width) * 2 - 1; this.mousePos.y = -((y - rect.top) / rect.height) * 2 + 1; this.raycaster.setFromCamera(this.mousePos, this.camera); } start(x, y) { this.updateRaycaster(x, y); const intersects = this.raycaster.intersectObjects(this.scene.children, true); for (let i = 0; i < intersects.length; i++) { const obj = intersects[i].object; if (obj.bodyID && obj.bodyID > 0) { this.physicsObject = obj; this.grabDistance = intersects[0].distance; const hit = this.raycaster.ray.origin.clone(); hit.addScaledVector(this.raycaster.ray.direction, this.grabDistance); this.localHit = obj.worldToLocal(hit.clone()); this.worldHit.copy(hit); this.currentWorld.copy(hit); this.active = true; this.controls.enabled = false; break; } } } move(x, y) { if (this.active) { this.updateRaycaster(x, y); const hit = this.raycaster.ray.origin.clone(); hit.addScaledVector(this.raycaster.ray.direction, this.grabDistance); this.currentWorld.copy(hit); } } applyDragForce(model, data) { if (!this.physicsObject || !this.physicsObject.bodyID) return; const bodyID = this.physicsObject.bodyID; this.worldHit.copy(this.localHit); this.physicsObject.localToWorld(this.worldHit); // Calculate force proportional to displacement const forceVec = this.currentWorld.clone() .sub(this.worldHit) .multiplyScalar(model.body_mass[bodyID] * 250); const force = toMujocoPos(forceVec); const point = toMujocoPos(this.worldHit.clone()); mujoco.mj_applyFT( model, data, [force.x, force.y, force.z], [0, 0, 0], [point.x, point.y, point.z], bodyID, data.qfrc_applied ); } end() { this.physicsObject = null; this.active = false; this.controls.enabled = true; } } // Usage const dragManager = new DragStateManager(scene, renderer, camera, controls); container.addEventListener('pointerdown', (evt) => dragManager.start(evt.clientX, evt.clientY)); document.addEventListener('pointermove', (evt) => dragManager.move(evt.clientX, evt.clientY)); document.addEventListener('pointerup', (evt) => dragManager.end()); // In animation loop function animate() { for (let i = 0; i < data.qfrc_applied.length; i++) { data.qfrc_applied[i] = 0.0; } dragManager.applyDragForce(model, data); mujoco.mj_step(model, data); renderer.render(scene, camera); requestAnimationFrame(animate); } ``` -------------------------------- ### Synchronize Three.js Scene with MuJoCo Simulation in JavaScript Source: https://context7.com/zalo/mujoco_wasm/llms.txt This JavaScript code updates Three.js object positions and orientations using MuJoCo simulation data, with helper functions for coordinate system conversion. It assumes a pre-initialized model, data, bodies, and scene. Dependencies include Three.js and mujoco-js; it reads from simulation buffers and writes to Three.js objects, suitable for real-time animation loops. Limitations include potential performance overhead in large models. ```javascript import * as THREE from 'three'; import { getPosition, getQuaternion } from './mujocoUtils.js'; // Assume model, data, bodies, and scene are already initialized function updateVisualization(model, data, bodies) { // Update body transforms from simulation for (let b = 0; b < model.nbody; b++) { if (bodies[b]) { // Extract position from xpos (Cartesian positions) getPosition(data.xpos, b, bodies[b].position); // Extract quaternion from xquat (orientations) getQuaternion(data.xquat, b, bodies[b].quaternion); // Update world matrix bodies[b].updateWorldMatrix(); } } } // Helper functions (from mujocoUtils.js) function getPosition(buffer, index, target, swizzle = true) { if (swizzle) { // Convert from MuJoCo to Three.js coordinate system return target.set( buffer[index * 3 + 0], buffer[index * 3 + 2], -buffer[index * 3 + 1] ); } else { return target.set( buffer[index * 3 + 0], buffer[index * 3 + 1], buffer[index * 3 + 2] ); } } function getQuaternion(buffer, index, target, swizzle = true) { if (swizzle) { // Convert from MuJoCo to Three.js coordinate system return target.set( -buffer[index * 4 + 1], -buffer[index * 4 + 3], buffer[index * 4 + 2], -buffer[index * 4 + 0] ); } else { return target.set( buffer[index * 4 + 0], buffer[index * 4 + 1], buffer[index * 4 + 2], buffer[index * 4 + 3] ); } } // Animation loop function animate() { // Step physics mujoco.mj_step(model, data); // Update visualization updateVisualization(model, data, bodies); // Render renderer.render(scene, camera); requestAnimationFrame(animate); } animate(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.