Mujoco KDL Wrapper  0.3.18
MuJoCo + KDL bridge for robot kinematics and dynamics
Loading...
Searching...
No Matches
Visualization

GLFW window management and the real-time render/tick loop. More...

Classes

struct  mj_kdl::Viewer

Functions

bool mj_kdl::init_window (Viewer *v, Robot *r, const char *title="MuJoCo", int width=1280, int height=720)
bool mj_kdl::init_window_sim (Viewer *v, Robot *r, const char *title="MuJoCo")
bool mj_kdl::init_window_sim (Viewer *v, mjModel *m, mjData *d, const char *title="MuJoCo")
void mj_kdl::clear_trace (Viewer *v)
void mj_kdl::add_trace_segment (Viewer *v, const KDL::Vector &a, const KDL::Vector &b, const float rgba[4]=nullptr)
void mj_kdl::add_overlay_arrow (Viewer *v, const KDL::Vector &from, const KDL::Vector &dir, double length, const float rgba[4]=nullptr)
void mj_kdl::cleanup (Viewer *v)
bool mj_kdl::step (Viewer *v, mjModel *m, mjData *d)
void mj_kdl::pace_realtime (Viewer *v, const mjModel *m)
double mj_kdl::realtime_factor_of (const Viewer *v)
void mj_kdl::pace_realtime (Robot *r)
bool mj_kdl::is_running (const Viewer *v)
bool mj_kdl::key_pressed (const Viewer *v, int glfw_key)
void mj_kdl::capture_key (Viewer *v, int glfw_key, bool capture=true)
bool mj_kdl::render (Viewer *v, const Robot *r)
bool mj_kdl::render (Viewer *v, mjModel *m, mjData *d)
bool mj_kdl::use_camera (Viewer *v, const mjModel *model, const char *name)

Detailed Description

GLFW window management and the real-time render/tick loop.

Use init_window_sim() + step() for the full simulate UI with physics panels. Use init_window() + render() for a lightweight manual render loop.

The simulate UI owns a user scene merged into every frame; draw your own overlay geometry (e.g. a live end-effector trajectory trace) into it with clear_trace() and add_trace_segment(). Both are no-ops in headless mode.

Function Documentation

◆ add_overlay_arrow()

void mj_kdl::add_overlay_arrow ( Viewer * v,
const KDL::Vector & from,
const KDL::Vector & dir,
double length,
const float rgba[4] = nullptr )

Append a world-space arrow to the viewer's user scene. Thread-safe. Shares the user scene with add_trace_segment(), so clear_trace() clears both and one call per frame is enough for either. dir need not be normalised; a zero-length dir draws nothing. Silently drops the arrow once the user-scene geom buffer is full. No-op when v is not backed by an init_window_sim() window (e.g. headless).

Parameters
[in,out]vViewer initialised by init_window_sim().
[in]fromArrow tail (world frame) [m].
[in]dirDirection the arrow points; normalised internally.
[in]lengthArrow length [m].
[in]rgbaOptional [r, g, b, a] colour; nullptr -> warm orange.

◆ add_trace_segment()

void mj_kdl::add_trace_segment ( Viewer * v,
const KDL::Vector & a,
const KDL::Vector & b,
const float rgba[4] = nullptr )

Append a single line segment to the viewer's user scene. Thread-safe. The render thread merges the user scene into each frame automatically. Silently drops the segment once the user-scene geom buffer is full. No-op when v is not backed by an init_window_sim() window (e.g. headless).

Parameters
[in,out]vViewer initialised by init_window_sim().
[in]aSegment start point (world frame) [m].
[in]bSegment end point (world frame) [m].
[in]rgbaOptional [r, g, b, a] colour; nullptr -> warm orange.

Referenced by admittance_ft::run_gui().

◆ capture_key()

void mj_kdl::capture_key ( Viewer * v,
int glfw_key,
bool capture = true )

Claim a key for the caller, so the simulate UI never acts on it.

The UI binds keys of its own: the left and right arrows scrub the history and single-step, escape restores the free camera, space pauses. A caller that drives a robot with those keys would otherwise fight the UI for them. A captured key is still reported by key_pressed(); it is only withheld from the UI's own handler.

Has no effect on a window opened by init_window(), which has no UI to withhold the key from.

Parameters
[in,out]vViewer initialised by init_window_sim(), or nullptr.
[in]glfw_keyA GLFW key code, e.g. GLFW_KEY_LEFT.
[in]capturetrue to claim the key, false to give it back.

◆ cleanup()

void mj_kdl::cleanup ( Viewer * v)

Release the GLFW window and MuJoCo visualization contexts owned by v.

Parameters
[in,out]vViewer to tear down; all pointers set to null afterwards.

◆ clear_trace()

void mj_kdl::clear_trace ( Viewer * v)

Reset the viewer's user-scene geom count to 0. Call once per frame before appending trace segments with add_trace_segment(). No-op when v is not backed by an init_window_sim() window (e.g. headless).

Parameters
[in,out]vViewer initialised by init_window_sim().

◆ init_window()

bool mj_kdl::init_window ( Viewer * v,
Robot * r,
const char * title = "MuJoCo",
int width = 1280,
int height = 720 )

Open a GLFW window and initialise MuJoCo visualization contexts. Must be called after init_robot() or init_from_mjcf().

Parameters
[out]vViewer to initialise; must be zero-initialised before call.
[in]rRobot whose model drives the rendering context.
[in]titleWindow title string.
[in]widthWindow width in pixels.
[in]heightWindow height in pixels.
Returns
true on success, false if GLFW or MuJoCo context creation fails.

◆ init_window_sim() [1/2]

bool mj_kdl::init_window_sim ( Viewer * v,
mjModel * m,
mjData * d,
const char * title = "MuJoCo" )

Open the simulate UI for a robot-less model/data pair (e.g. a Scene or Env with no Robot). Physics, camera and pause are handled by the UI directly.

Returns
true on success.

◆ init_window_sim() [2/2]

bool mj_kdl::init_window_sim ( Viewer * v,
Robot * r,
const char * title = "MuJoCo" )

Open the full MuJoCo simulate UI (panels, physics controls, joint viewer) in a background render thread, then return so the caller can drive the physics loop with tick().

Use this instead of init_window() when you want the simulate UI panels alongside a user-owned loop. tick() automatically acquires the render mutex, steps physics, and handles pause / perturbation / speed controls.

Note: the render thread owns the GLFW window; on Linux (X11 / Wayland) this works correctly. Not supported on macOS.

Parameters
[out]vViewer to initialise; freed by cleanup(Viewer *).
[in]rRobot to simulate. r is registered globally; pass the same Robot to every subsequent step() call so that keyboard and mouse perturbation callbacks operate on the correct model. Only one (Viewer, Robot) pair may be active at a time.
[in]titleLabel shown in the window title bar (default "MuJoCo").
Returns
true on success.

Referenced by main(), main(), and admittance_ft::run_gui().

◆ is_running()

bool mj_kdl::is_running ( const Viewer * v)

Returns true if the viewer window is open and not scheduled for closing.

Parameters
[in]vViewer created by init_window().

Referenced by admittance_ft::run_gui().

◆ key_pressed()

bool mj_kdl::key_pressed ( const Viewer * v,
int glfw_key )

Whether a key is currently held down in the viewer's window.

The simulate UI opened by init_window_sim() owns its GLFW window on the render thread, so a caller driving physics on its own thread must not call glfwGetKey() itself. This reads the key state that the UI's own key callback records, which is safe from any thread.

For a window opened by init_window() this forwards to glfwGetKey() and must therefore be called from the thread that owns the window, as GLFW requires.

Keys the UI consumes for itself (',' and '.' for the speed control) are reported like any other.

Parameters
[in]vViewer, or nullptr.
[in]glfw_keyA GLFW key code, e.g. GLFW_KEY_UP.
Returns
true while the key is held; false for a nullptr or headless viewer, or an out-of-range key code.

◆ pace_realtime() [1/2]

void mj_kdl::pace_realtime ( Robot * r)

Paces a loop that drives a Robot, using the viewer the library holds. Does nothing when the run has no viewer, so a headless path needs no branch.

Parameters
[in,out]rRobot being stepped.

◆ pace_realtime() [2/2]

void mj_kdl::pace_realtime ( Viewer * v,
const mjModel * m )

Sleeps until this step's share of wall time has elapsed, so a loop with no timing of its own runs at the viewer's real-time factor.

step() never sleeps: pacing is the caller's job. A loop that already paces itself must not call this – it reads realtime_factor_of() and scales its own period instead, so that only one component owns the loop's timing.

Parameters
[in,out]vViewer whose real-time factor and last tick time are used.
[in]mShared MuJoCo model, for its timestep.

Referenced by main(), main(), admittance_ft::run_gui(), admittance_ft::run_selfcheck(), and admittance_ft::settle_and_tare().

◆ realtime_factor_of()

double mj_kdl::realtime_factor_of ( const Viewer * v)

The viewer's current real-time factor, as the user has set it with the speed keys.

Parameters
[in]vViewer, or nullptr.
Returns
the factor; 0.0 means uncapped ("RTF: MAX"), 1.0 if v is nullptr.

◆ render() [1/2]

bool mj_kdl::render ( Viewer * v,
const Robot * r )

Render the current simulation frame to the viewer window.

Parameters
[in,out]vViewer created by init_window().
[in]rRobot whose model and data are rendered.
Returns
true if the window is still open after rendering.

◆ render() [2/2]

bool mj_kdl::render ( Viewer * v,
mjModel * m,
mjData * d )

Render the current simulation frame to the viewer window. Model/data overload – use when no single Robot owns the scene (e.g. multi-robot).

Parameters
[in,out]vViewer created by init_window().
[in]mMuJoCo model.
[in]dMuJoCo data.
Returns
true if the window is still open after rendering.

◆ step()

bool mj_kdl::step ( Viewer * v,
mjModel * m,
mjData * d )

Model/data overload of step() for multi-robot or no-robot GUI loops. Equivalent to the former tick(Viewer*, mjModel*, mjData*).

Parameters
[in,out]vViewer initialised by init_window() or init_window_sim().
[in]mShared MuJoCo model.
[in]dShared MuJoCo data.
Returns
true while the window is open; false once the user closes it.

◆ use_camera()

bool mj_kdl::use_camera ( Viewer * v,
const mjModel * model,
const char * name )

Switch the viewer to a named fixed camera defined in the model. Works for both init_window() and init_window_sim() paths. Pass nullptr or an empty string to return to the free camera.

Returns
true if the camera name was found; false if not found (viewer unchanged).