Getting Started
Installation
To install MuJoCo.jl
, simply run the following code in a Julia REPL:
import Pkg
Pkg.add("MuJoCo.jl")
This will download and install the package, along with the underlying C library. We highly recommend activating a project to manage dependencies - see the docs for more information.
Once installed, you can load the package in the REPL just like any other Julia package. To use the visualiser and see your MuJoCo models in action, you will need to install some additional dependencies with
using MuJoCo
install_visualiser()
Basic Usage
You should now be able to load in and play around with any MuJoCo model of your choosing. You can create your own MuJoCo models with the MJCF modelling language, but for now we'll load in a model of a humanoid for demonstration purposes.
using MuJoCo
model, data = MuJoCo.sample_model_and_data()
@show typeof(model), typeof(data)
(Model, Data)
The Model
and Data
types encode all the information required to simulate a model in MuJoCo, and are wrappers of the mjModel
and mjData
structs in the C API, respectively. We can directly access any data from these structs:
println("Simulation timestep: ", model.opt.timestep)
println("Positions of joints: ", data.qpos)
Simulation timestep: 0.005
Positions of joints: [0.0; 0.0; 1.282; 1.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0;;]
We can also directly read and write from/to these fields. However, we cannot directly overwrite any arrays. Instead, we can use Julia's broadcasting to set values as we see fit. Let's write a function that inputs random control torques to the humanoid's joints.
function random_controller!(m::Model, d::Data)
nu = m.nu
d.ctrl .= 2*rand(nu) .- 1
return nothing
end
random_controller! (generic function with 1 method)
We can now simulate motion of the humanoid under this control scheme. Let's simulate over 100 time-steps.
for t in 1:100
random_controller!(model, data)
step!(model, data)
end
At each time-step, random_controller!
sets the control signal to some random value, and step!
calls the MuJoCo physics engine to simulate the response of the system. step!
directly modifies the data
struct. For example, looking at data.qpos
again shows that the joints have all moved.
println("New joint positions: ", data.qpos)
New joint positions: [0.003084334560449839; 0.03172205938690198; 1.057358025160325; 0.9361061433627246; -0.0011375557873683326; 0.05824384253046185; 0.34685969661043736; 0.05295086297869525; -0.4745502971626004; -0.3634757655964897; 0.18981392463942062; -0.37246110135502736; 0.12050346678630611; -1.3840793484090628; -0.8978636490723068; -0.3450498920681054; -0.20736660452719227; 0.1385623687374213; -0.6349273520834933; -2.016490515463138; -0.11114496652393813; -0.05949710791854648; 0.8232819066044271; -1.099377626335998; -0.7066894200267646; 0.8574566918050747; -0.23369752928192258; -1.1697048519245823;;]
After finishing our initial simulations, we can re-set the model back to its starting position by calling mj_resetData
, one of the underlying C library functions. Any of the functions listed in the LibMuJoCo Index can be used just as they are described in the MuJoCo documentation.
mj_resetData(model, data)
println("Reset joint positions: ", data.qpos)
Reset joint positions: [0.0; 0.0; 1.282; 1.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0;;]
Visualising a Model
Of course, the best way to understand what a MuJoCo model is doing is to visualise it. To use the visualiser, simply initialise it and call visualise!
. We can test our controller by passing in our function via the controller
keyword.
init_visualiser()
visualise!(model, data, controller=random_controller!)
Press F1
for help after running the visualiser to print the available options in a terminal. Some of the most interesting are:
- Press
CTRL+RightArrow
(orCMD
for Mac) to cycle between the passive dynamics and the controlled motion - Press
SPACE
to pause/unpause - Double-click on an object select it
CTRL+RightClick
and drag to apply a force- Press
Backspace
to reset the model - Press
ESC
to exit the simulation
Visualising a Trajectory
Sometimes it will be more convenient to simulate the motion of a MuJoCo model and save its response for later analysis. The visualiser includes a Trajectory
mode to enable this. Let's reset!
our humanoid model and set its initial height to 2 metres above the ground.
reset!(model, data)
data.qpos[3] = 2
forward!(model, data) # Propagate the physics forward
The motion of every MuJoCo model can be described by some physical state vector consisting of the positions and velocities of its components, and the state of its actuators. We have included get_physics_state
and set_physics_state!
to allow users to record (and set) the states of a model during simulation. Let's simulate our humanoid for another 100 timesteps and record its state.
tmax = 400
nx = model.nq + model.nv + model.na # State vector dimension
states = zeros(nx, tmax)
for t in 1:tmax
states[:,t] = get_physics_state(model, data)
step!(model, data)
end
We'll also go back and save the humanoid states under our random controller.
reset!(model, data)
ctrl_states = zeros(nx, tmax)
for t in 1:tmax
ctrl_states[:,t] = get_physics_state(model, data)
random_controller!(model, data)
step!(model, data)
end
We can now play back either the passive or controlled humanoid motion whenever we like using the Trajectory
mode in the visualiser. This allows us to re-wind the simulation, simulate it backwards, skip forward/backwards a few frames, and add some cool visualisation features.
visualise!(model, data, trajectories = [states, ctrl_states])
You might find the following tips useful:
- Press
CTRL+RightArrow
(orCMD
for Mac) to cycle between the passive dynamics and the saved trajectories - Press
F1
to see the newTrajectory
mode button and mouse options, including:- Press
UP
orDOWN
to cycle between trajectories - PRESS
CTRL+R
for reverse mode - Press
CTRL+B
to turn burst-mode on - Press
CTRL+D
to add a doppler shift
- Press
We strongly recommend saving trajectories for later visualisation if you're simulating any particularly complicated tasks in MuJoCo. You can start up the visualiser with all three of the passive dynamics, controlled dynamics, and saved trajectories. See visualise!
for details.
Happy visualising!