mujoco_rs/lib.rs
1//! # MuJoCo-rs
2//! A wrapper around the MuJoCo C library with a Rust-native viewer.
3//! If you're familiar with MuJoCo, this should be pretty straightforward to use as the wrappers
4//! mainly encapsulate some C structs or just rename them to match the Rust's PascalCase style.
5//!
6//! The main structs are [`wrappers::mj_model::MjModel`] and [`wrappers::mj_data::MjData`].
7//! These two structs (and some other) wrap the C structure in order to achieve memory safety.
8//!
9//! Their fields aren't publicly exposed and can instead be manipulated through views
10//! (e. g., [`MjData::joint`](wrappers::mj_data::MjData::joint) and then [`wrappers::mj_data::MjJointDataInfo::view`]).
11//! To access the wrapped attributes directly, call the corresponding `ffi()` methods
12//! (e. g., [`MjData::ffi`](wrappers::MjData::ffi))
13//!
14//! ## Documentation
15//! A more guided documentation can be obtained [here](https://mujoco-rs.readthedocs.io/en/latest/).
16//!
17//! ## 3D viewer
18//! The Rust-native viewer is available ([`viewer::MjViewer`]), as well as the MuJoCo's original C++
19//! one ([`viewer::MjViewerCpp`]).
20//! The C++ viewer however requires manual compilation of a patched MuJoCo repository,
21//! like described [here](https://mujoco-rs.readthedocs.io/en/latest/installation.html#static-linking-with-c-viewer).
22//!
23//! ## Features
24//! This crate has the following public features:
25//! - `viewer`, which enables the Rust-native viewer ([`viewer::MjViewer`]),
26//! - `cpp-viewer`, which additionally enables the MuJoCo's original viewer (C++ based) ([`viewer::MjViewerCpp`]),
27//! - `renderer`, which enables the image renderer ([`renderer::MjRenderer`]).
28//!
29//! ## Functions
30//! Most functions are wrapped under methods at different structs. Some functions
31//! are available under the [`wrappers::fun`] module.
32//!
33//! If a certain function can't be found, you can use the raw FFI bindings, available under
34//! the [`mujoco_c`] module. Note that to access the lower-level ffi structs inside of wrappers,
35//! `ffi()` or `ffi_mut()` must be called (e. g., [`wrappers::MjData::ffi`] and [`wrappers::MjModel::ffi`]).
36
37use std::ffi::CStr;
38
39pub mod wrappers;
40pub mod prelude;
41pub mod util;
42
43
44#[cfg(feature = "renderer")]
45pub mod renderer;
46
47#[cfg(feature = "viewer")]
48pub mod viewer;
49
50#[allow(warnings)]
51pub mod mujoco_c; // raw MuJoCo C and C++ bindings
52
53
54/// Returns the version string of the MuJoCo library
55pub fn get_mujoco_version() -> &'static str {
56 let arr = unsafe { mujoco_c::mj_versionString() };
57 unsafe { CStr::from_ptr(arr).to_str().unwrap() }
58}
59
60#[cfg(test)]
61mod tests {
62 use crate::get_mujoco_version;
63
64 #[test]
65 fn test_version() {
66 let version = get_mujoco_version();
67 assert!(!version.is_empty());
68 }
69
70
71 #[allow(unused)]
72 pub(crate) fn test_leaks() {
73 use super::*;
74 use wrappers::*;
75 use std::hint::black_box;
76
77 const N_ITEMS: usize = 10000;
78 const N_REPEATS: usize = 1000;
79 const EXAMPLE_MODEL: &str = "
80 <mujoco>
81 <worldbody>
82 <light ambient=\"0.2 0.2 0.2\"/>
83 <body name=\"ball\">
84 <geom name=\"sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/>
85 <joint name=\"sphere\" type=\"free\"/>
86 </body>
87
88 <geom name=\"floor\" type=\"plane\" size=\"10 10 1\" euler=\"5 0 0\"/>
89
90 </worldbody>
91 </mujoco>
92 ";
93
94 for _ in 0..N_REPEATS {
95 let model = MjModel::from_xml_string(EXAMPLE_MODEL).expect("failed to load the model.");
96 let mut datas: Vec<_> = (0..N_ITEMS).map(|_| model.make_data()).collect();
97
98 for data in datas.iter_mut() {
99 data.joint("sphere").unwrap().view_mut(data).qpos[0] /= 2.0;
100 data.step();
101 }
102 }
103 }
104}