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;
}