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

Migrating to 0.5

The project no longer fetches anything but MuJoCo:

0.4 0.5
CMake cloned the Orocos KDL fork (MJ_KDL_FETCH_OROCOS_KDL) run vcs import < mj_kdl_wrapper.repos before configuring; the fork tracks branch vereshchagin-driver-weighting
MJ_KDL_FETCH_MENAGERIE, mj-kdl-fetch-menagerie, mj-kdl-fetch-examples removed; the bundled assets/ are the only models shipped. Point RobotSpec.path at any other MJCF, e.g. a MuJoCo Menagerie checkout
Python mjk.menagerie.model_path() / asset_path() and their MJ_KDL_* env overrides mjk.ASSETS_DIR / "kinova_gen3/gen3.xml"
The asset cache was filled by the Menagerie fetch cmake --install copies assets/ into ~/.cache/mj_kdl_wrapper/assets for programs that do not know the source tree
F/T wrench was MuJoCo's reading (the parent's force on the child) the load on the sensor, as a physical F/T reports it: the negation

Migrating to 0.4

The Env now owns everything the loop touches: the model/data, the robots, the scene slots (env.scene) and the viewer (env.viewer). The loop and its calls take the Env:

0.3.x 0.4
init_robot_from_mjcf(&r, model, data, ...) + env_add_robot(&env, &r) init_robot_from_mjcf(&r, &env, ...) (registers it)
init_window_sim(&viewer, &robot) / (&viewer, m, d) open_viewer(&env, title)
step(&robot), step_n(), step(&viewer, m, d) step(&env)
update(&robot), read_measurements(), apply_commands() update(&env) (every robot and scene slot)
pace_realtime(&robot) / (&viewer, m) pace_realtime(&env)
get_body_frame(m, d, ...), get_site_frame, set_body_pose(m, d, ...) same names, taking &env
init_scene_state(), read/apply/rebind_scene_state() bind_scene_*(&env.scene, ...); update(&env) and rebuilds handle the rest
scene_add_object(&m, &d, &spec, ...) scene_add_object(&env, ...)
record_frame(&vr, m, d), render_rgb(&vr, m, d, out) record_frame(&vr, &env), render_rgb(&vr, &env, out)
set_joint_pos(&r, q, call_forward), mark_kinematics_*() set_joint_pos(&r, q); frames notice state changes themselves
init_window(), render(), cleanup(&viewer) removed; cleanup(&env) closes the viewer

reset(&env) now re-seeds every robot's ports and F/T readings and every scene slot, then runs on_reset, and the Simulate UI's reset button does the same. A Robot's MuJoCo index maps are private.

Also changed in 0.4:

Change What to do
Calls that can fail return mj_kdl::Status instead of bool if (!s) still works; print s.error
Spec string fields (path, prefix, mjcf_path, tool_body, ...) are std::string drop .c_str(); empty means not set
set_body_pose() takes [x, y, z, w] (was [w, x, y, z]) reorder the quaternion
Control modes are MuJoCo actuator groups (RobotSpec::modes, set_control_mode()) nothing is written to qfrc_applied any more
Unset required numbers (timestep, primitive size/mass/friction/rgba, camera pos/fovy) fail the build set them
Earlier docs used tool_body = "g_base" for the 2F-85, which leaves the mount's mass out of KDL use "g_base_mount"
Python: joint ports read as read-only numpy arrays assign whole vectors; port[i] = x raises
Python: Env.save_xml() -> save_model_xml(), Robot.tip_to_tcp -> tip_T_tcp rename; there are no aliases
get_camera_names() removed loop i < model->ncam with mj_id2name(model, mjOBJ_CAMERA, i)
get_joint_position() / get_joint_velocity() removed a bind_scene_joint() slot's position/velocity, or model/data directly
realtime_factor_of() removed read Viewer::realtime_factor
use_camera(VideoRecorder*) / set_free_camera(VideoRecorder*) removed (the Viewer overloads stay) write vr.cam: type = mjCAMERA_FIXED, fixedcamid = mj_name2id(model, mjOBJ_CAMERA, name); or mjv_defaultFreeCamera()
scene_object_site_name() removed (C++ and Python) the asset's own site name; objects are no longer auto-prefixed: set SceneObject::prefix (Python SceneObject.prefix) to prefix them
attach_to_spec(), add_floor_to_spec(), add_skybox_to_spec(), add_objects_to_spec(), compile_and_make_data(), ensure_plugins_loaded() are internal go through SceneSpec and build_scene(); to run on your own pair, set Env::adopt
Python: Env.time(), timestep(), camera_names(), save_binary(), mjk.mujoco_version() removed env.data.time, env.model.opt.timestep, [env.model.camera(i).name for i in range(env.model.ncam)], mujoco.mj_saveModel(env.model, path, None), mjk.__mujoco_version__
Python: Env.actuator_ctrl(), set_actuator_ctrl(), has_actuator(), set_body_wrench() removed env.data.actuator(n).ctrl[0] (read or assign), env.model.actuator(n) (KeyError when missing), env.data.body(n).xfrc_applied[:] = [*f, *t]
Python: Robot.fk_frame(), gravity_torques() removed PyKDL ChainFkSolverPos_recursive / ChainDynParam on robot.kdl_chain() with a JntArray of robot.jnt_pos_msr
Python: Robot.ft_sensor_frame(name) removed env.site_frame(<the sensor's frame_site>)
find_ft_sensor() removed search robot.ft_sensors (in ToolFrameSpec::ft_sensors order) by .name
MJCF SceneObjects are no longer prefixed with name + "_" use the asset's own element names; set SceneObject::prefix when an asset is used twice
LogLevel is a threshold, INFO < WARN < ERROR < NONE, default INFO (it was a verbosity where ERROR printed everything) set_log_level(WARN) now prints warnings and errors; the default prints what it did before
LOG_INFO() / LOG_WARN() / LOG_ERROR() MJ_LOG_INFO() / MJ_LOG_WARN() / MJ_LOG_ERROR()
The header no longer includes <GLFW/glfw3.h> include it yourself for the GLFW_KEY_* codes of key_pressed() / capture_key()
init_env() dropped an on_reset set before it it keeps it, like adopt
scene_add_object() / scene_remove_object() started from a fresh mjData at qpos0 the time, qpos/qvel (by joint name and type) and act/ctrl (by actuator name) carry over into the new model; call reset(&env) for the old behaviour
A rebuild whose robot or F/T sensor rebinding failed left the Env half rebound it is left unchanged and the call returns the error
scene_add_object() / scene_remove_object() could be called from on_reset they fail there; change the scene outside the hook
A VideoRecorder kept rendering the old model after a rebuild it builds its render context at the first frame and follows rebuilds
init_offscreen() / init_video_recorder() on an open recorder leaked it they free it first
open_viewer() without a usable display could abort on the render thread it returns an error Status when no window can be created
Simulate UI: a reset was detected from time jumping back (also on API reset, rebuild, history scrub, the Load key) only an explicit UI Reset runs the reset path and on_reset; scrubbing and the Load key no longer reset
Simulate UI: the right arrow single-stepped MuJoCo behind the wrapper; a dropped model file was loaded the right arrow no longer single-steps; drag-and-drop loading is gone (build scenes with SceneSpec)
CMake: find_package(mj_kdl_wrapper 0.3) accepted any 0.x (SameMajorVersion) the minor version must match (SameMinorVersion); ask for 0.4
Install: licenses went to lib/, image_io.hpp and camera_ros.hpp were always installed licenses in share/doc/mj_kdl_wrapper; only the headers of what was built
New: pkg-config file mj_kdl_wrapper.pc pkg-config --cflags --libs mj_kdl_wrapper; see the Standalone Installation Guide
Python: Scene removed Env.build(spec); its frame, pose, object and save calls are on Env
Python: Robot.from_scene(scene, ...) env.create_robot(...) or env.create_robot_from_chain(...)
Python: Robot.update(), step(), pace(), step_n(), Scene.step(), step_n() env.update(), env.step(), env.pace(); loop for several steps
Python: SimulateViewer.open(robot_or_scene, title), .close(), .step(), .pace(), .step_n() env.open_viewer(title); env.viewer has is_running() and the trace, camera and key calls; env.close() closes it
Python: Robot.set_joint_pos(q, call_forward) set_joint_pos(q)
Python: VideoRecorder.open(scene, ...) / open_preset(scene, ...) pass the Env: open(env, ...)
Python: Env.spec was a writable copy whose changes did nothing it is read-only; change the scene with add_object() / remove_object()
Python: Env.on_reset got a ResetContext that dangled once the call returned it gets a copy, safe to keep
Python: menagerie.model_path() knew only kinova_gen3 and robotiq_2f85 also universal_robots_ur5e and universal_robots_ur10e

Migrating from 0.3.1

step() no longer sleeps. Pacing moved out of the physics call and into pace_realtime(), so a loop that owns its own timing is no longer fought by a hidden sleep inside step(). A windowed run that should track wall time needs one pace_realtime(&env) call per iteration; headless runs are unaffected, because pacing only ever happened when a viewer existed. See Loop Pacing and the Real-Time Factor.

Migrating from 0.2.x

0.3.0 removes the euler placement field from RobotSpec, AttachmentSpec, SceneObject and CameraSpec, and from attach_child(). Placement orientation is now the quaternion quat, in [x, y, z, w] order, with identity { 0, 0, 0, 1 }. There is no compatibility shim: code setting euler no longer compiles.

quat is the library's own convention. MuJoCo's [w, x, y, z] ordering stays inside the wrapper and is never exposed through these specs.

C++, a 180-degree flip about x:

// 0.2.x
cam.euler = { 180.0, 0.0, 0.0 };
// 0.3.0
cam.quat = { 1.0, 0.0, 0.0, 0.0 };

Python, the same rotation:

# 0.2.x
cam.euler = [180.0, 0.0, 0.0]
# 0.3.0
cam.quat = [1.0, 0.0, 0.0, 0.0]

For angles without an exact quaternion, convert with SciPy – Rotation.from_euler("xyz", [rx, ry, rz], degrees=True).as_quat() returns [x, y, z, w] directly.