Examples¶
Basic¶
To simulate a model, all you need is:
#include <MuJoCoTools/MuJoCoModel.h>
#include <MuJoCoTools/MuJoCoViewer.h>
int main()
{
MuJoCoModel model("/path/to/model.xml");
MuJoCoViewer viewer(model.get_model());
viewer.play(); // Hold until window was closed
return 0;
}
Asynchronous Viewer¶
it can be very useful to update the viewer while still running code in a loop:
#include <iostream>
#include <Eigen/Dense>
#include <cmath>
#include <thread>
#include <mutex>
#include <memory>
#include <mujoco/mujoco.h>
#include <MuJoCoTools/MuJoCoModel.h>
#include <MuJoCoTools/MuJoCoViewer.h>
std::shared_ptr<MuJoCoViewer> viewer;
std::mutex mux_viewer;
/**
* Update MuJoCo viewer
*
* Function is designed to run from a thread.
* It will only return when the window was closed.
*/
void update_viewer(const mjModel* m, mjData* d)
{
mux_viewer.lock();
viewer = std::make_shared<MuJoCoViewer>(m); // Viewer needs to be created inside thread
mux_viewer.unlock();
while (!viewer->window_should_close())
{
mux_viewer.lock(); // Block until available
viewer->update(d);
mux_viewer.unlock();
MuJoCoViewer::sleep_seconds(1.0 / 60.0);
}
}
int main()
{
MuJoCoModel model(
"/home/robert/eclipse/ipopt-workspace/Gambol/src/Robots/five_link_biped_3d.xml");
Eigen::VectorXd qpos = model.get_default_qpos();
model.reset_data(qpos);
const mjModel* m = model.get_model();
mjData* d = model.get_data();
// Launch thread to update viewer asynchronously
std::thread t_viewer(update_viewer, m, d);
while (!viewer)
{
// Hold until creation finished
MuJoCoViewer::sleep_seconds(0.1);
}
// Add figure to viewer
auto fig = std::make_shared<MuJoCoFigure>("My Fig");
mux_viewer.lock();
viewer->add_figure(fig.get());
mux_viewer.unlock();
t_viewer.join();
return 1;
}
Heightmap¶
#include <iostream>
#include <chrono>
#include <Eigen/Dense>
#include <cmath>
#include <unistd.h>
#include <mujoco/mujoco.h>
#include <MuJoCoTools/MuJoCoModel.h>
#include <MuJoCoTools/MuJoCoViewer.h>
using namespace std;
int main()
{
MuJoCoModel model("/path/to/model.xml");
Eigen::VectorXd qpos = model.get_default_qpos();
model.reset_data(qpos);
const mjModel* m = model.get_model();
mjData* d = model.get_data();
// Create a random terrain heightmap (10 by 10 nodes)
Eigen::MatrixXd terrain(10, 10);
for (int i = 0; i < terrain.size(); i++)
{
terrain(i) = static_cast<double>(rand()) / static_cast<double>(RAND_MAX) - 1.0;
}
// Create the heightmap in MuJoCo
model.set_heightfield(0, terrain, 5.0, 5.0, 1.0);
MuJoCoViewer viewer(m);
viewer.play(d);
return 1;
}