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}