Version 2.1: documentation, public API headers, and sample programs.

PiperOrigin-RevId: 403900419
This commit is contained in:
Saran Tunyasuvunakool
2021-10-18 12:23:02 +01:00
commit 1f7eaae62e
96 changed files with 28272 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
sphinx:
builder: html
configuration: doc/conf.py
fail_on_warning: false
python:
version: 3.7
install:
- requirements: doc/requirements.txt
+26
View File
@@ -0,0 +1,26 @@
# How to Contribute
We are in the process of preparing the MuJoCo codebase for open-sourcing.
When that happens, we will be grateful to receive your contributions.
Until then, you are welcome to participate in discussions, post
issues on our tracker, or send us pull requests to improve the sample program
code or documentation.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution,
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions require review. Please use GitHub pull requests for this
purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on pull requests.
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+106
View File
@@ -0,0 +1,106 @@
# MuJoCo Physics
**MuJoCo** stands for **Mu**lti-**Jo**int dynamics with **Co**ntact. It is a
general purpose physics engine that aims to facilitate research and development
in robotics, biomechanics, graphics and animation, machine learning, and other
areas which demand fast and accurate simulation of articulated structures
interacting with their environment.
DeepMind has acquired MuJoCo, and we are currently making preparations to open
source the codebase. In the meantime, MuJoCo is available for download as a free
and unrestricted precompiled binary under the Apache 2.0 license from
[mujoco.org](https://mujoco.org/).
MuJoCo's source code will be released through this GitHub repository once it is
ready. In the meantime, the repository hosts MuJoCo's documentation, C header
files for its public API, and sample program code. If you wish to report bugs or
make feature requests, please file them as [GitHub Issues]. You are also
welcome to make pull requests for the [documentation source files].
## Overview
MuJoCo is a C/C++ library with a C API, intended for researchers and developers.
The runtime simulation module is tuned to maximize performance and operates on
low-level data structures which are preallocated by the built-in XML parser and
compiler. The user defines models in the native MJCF scene description language
-- an XML file format designed to be as human readable and editable as possible.
URDF model files can also be loaded. The library includes interactive
visualization with a native GUI, rendered in OpenGL. MuJoCo further exposes a
large number of utility functions for computing physics-related quantities, not
necessarily in a simulation loop. Features include
- Simulation in generalized coordinates, avoiding joint violations.
- Inverse dynamics that are well-defined even in the presence of contacts.
- Unified continuous-time formulation of constraints via convex optimization.
- Constraints include soft contacts, limits, dry friction, equality
constraints.
- Simulation of particle systems, cloth, rope and soft objects.
- Actuators including motors, cylinders, muscles, tendons, slider-cranks.
- Choice of Newton, Conjugate Gradient, or Projected Gauss-Seidel solvers.
- Choice of pyramidal or elliptic friction cones, dense or sparse Jacobians.
- Choice of Euler or Runge-Kutta numerical integrators.
- Multi-threaded sampling and finite-difference approximations.
- Intuitive XML model format (called MJCF) and built-in model compiler.
- Cross-platform GUI with interactive 3D visualization in OpenGL.
- Run-time module written in ANSI C and hand-tuned for performance.
## Requirements
MuJoCo binaries are currently built for Linux, macOS (Intel), and Windows.
## Documentation
MuJoco's current documentation is available at [mujoco.org/book], which is
serving Sphinx-based webpages derived from the ReStructuredText
[documentation source files].
## Citation
If you use MuJoCo for published research, please cite:
```
@inproceedings{todorov2012mujoco,
title={Mujoco: A physics engine for model-based control},
author={Todorov, Emanuel and Erez, Tom and Tassa, Yuval},
booktitle={2012 IEEE/RSJ International Conference on Intelligent Robots and Systems},
pages={5026--5033},
year={2012},
organization={IEEE}
}
```
## License and Disclaimer
Copyright 2021 DeepMind Technologies Limited
ReStructuredText documents, images, and videos in the `doc` directory are made
available under the terms of the Creative Commons Attribution 4.0 (CC BY 4.0)
license. You may obtain a copy of the License at
https://creativecommons.org/licenses/by/4.0/legalcode.
Source code is licensed under the Apache License, Version 2.0. You may obtain a
copy of the License at https://www.apache.org/licenses/LICENSE-2.0.
This is not an officially supported Google product.
[GitHub Issues]: https://github.com/deepmind/mujoco/issues
[documentation source files]: https://github.com/deepmind/mujoco/tree/main/doc
[mujoco.org/book]: https://mujoco.org/book
+6545
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
# Minimal makefile for Sphinx documentation
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+4956
View File
File diff suppressed because it is too large Load Diff
+130
View File
@@ -0,0 +1,130 @@
% Force-Length-Velocity function of MuJoCo muscle model
% Defaults: FLV(0.5, 1.6, 1.5, 1.3, 1.2)
function FLV(lmin, lmax, vmax, fpmax, fvmax)
% derived quantities
a = 0.5*(lmin+1);
b = 0.5*(1+lmax);
c = fvmax-1;
% length and velocity ranges to plot
LL = linspace(lmin, lmax, 51);
VV = linspace(-vmax, vmax, 51);
% length-passive
FP = zeros(size(LL));
for i=1:length(LL)
L = LL(i);
if L<=1
FP(i) = 0;
elseif L<=b
x = (L-1)/(b-1);
FP(i) = 0.25*fpmax*x*x*x;
else
x = (L-b)/(b-1);
FP(i) = 0.25*fpmax*(1+3*x);
end
end
% length-active
FL = zeros(size(LL));
for i=1:length(LL)
L = LL(i);
FL(i) = bump(L, lmin, 1, lmax) + 0.15*bump(L, lmin, 0.5*(lmin+0.95), 0.95);
end
% velocity-active
FV = zeros(size(VV));
for i=1:length(VV)
V = VV(i)/vmax;
if V<=-1
FV(i) = 0;
elseif V<=0
FV(i) = (V+1)*(V+1);
elseif V<=c
FV(i) = fvmax - (c-V)*(c-V)/c;
else
FV(i) = fvmax;
end
end
% plot length
figure(1);
clf;
subplot(2,2,1);
plot(LL, FL, 'r', 'linewidth', 1);
hold on;
plot(LL, 0.5*FL, 'b', 'linewidth', 1);
plot(LL, FP, 'k', 'linewidth', 1);
axis tight;
xlabel('length (L0)');
ylabel('force (F0)');
text(0.9, 0.85, 'act = 1.0');
text(0.9, 0.4, 'act = 0.5');
text(1.3, 1.2, 'passive');
box off;
grid on;
set(gca, 'xtick', [lmin 1 lmax], 'xticklabel', {'lmin', '1', 'lmax'}, ...
'ytick', [0 1 fpmax], 'yticklabel', {'0', '1', 'fpmax'});
% plot velocity
subplot(2,2,2);
set( plot(VV, FV, 'linewidth', 1), 'color', [.1 .5 .1]);
axis tight;
xlabel('velocity (L0/s)');
ylabel('force (F0)');
box off;
grid on;
set(gca, 'xtick', [-vmax 0 vmax], 'xticklabel', {'-vmax', '0', 'vmax'}, ...
'ytick', [0 1 fvmax], 'yticklabel', {'0', '1', 'fvmax'});
% plot full activation
subplot(2,2,3);
surf(LL, VV, FV'*FL + ones(size(VV))'*FP);
axis tight;
xlabel('length');
ylabel('velocity');
zlabel('force');
title('act = 1.0');
box off;
set(gca, 'xtick', [lmin, 1, lmax], 'ytick', [-vmax, 0, vmax], 'ztick', [0, 1]);
% plot half activation
subplot(2,2,4);
surf(LL, VV, 0.5*FV'*FL + ones(size(VV))'*FP);
axis tight;
xlabel('length');
ylabel('velocity');
zlabel('force');
title('act = 0.5');
box off;
set(gca, 'xtick', [lmin, 1, lmax], 'ytick', [-vmax, 0, vmax], 'ztick', [0, 1]);
end
% skewed bump function: quadratic spline
function y = bump(L, A, mid, B)
left = 0.5*(A+mid);
right = 0.5*(mid+B);
if (L<=A) || (L>=B)
y = 0;
elseif L<left
x = (L-A)/(left-A);
y = 0.5*x*x;
elseif L<mid
x = (mid-L)/(mid-left);
y = 1-0.5*x*x;
elseif L<right
x = (L-mid)/(right-mid);
y = 1-0.5*x*x;
else
x = (B-L)/(B-right);
y = 0.5*x*x;
end
end
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
View File
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
<mujoco model="example">
<compiler coordinate="global"/>
<default>
<geom rgba=".8 .6 .4 1"/>
</default>
<asset>
<texture type="skybox" builtin="gradient" rgb1="1 1 1" rgb2=".6 .8 1" width="256" height="256"/>
</asset>
<worldbody>
<light pos="0 1 1" dir="0 -1 -1" diffuse="1 1 1"/>
<body>
<geom type="capsule" fromto="0 0 1 0 0 0.6" size="0.06"/>
<joint type="ball" pos="0 0 1"/>
<body>
<geom type="capsule" fromto="0 0 0.6 0.3 0 0.6" size="0.04"/>
<joint type="hinge" pos="0 0 0.6" axis="0 1 0"/>
<joint type="hinge" pos="0 0 0.6" axis="1 0 0"/>
<body>
<geom type="ellipsoid" pos="0.4 0 0.6" size="0.1 0.08 0.02"/>
<site name="end1" pos="0.5 0 0.6" type="sphere" size="0.01"/>
<joint type="hinge" pos="0.3 0 0.6" axis="0 1 0"/>
<joint type="hinge" pos="0.3 0 0.6" axis="0 0 1"/>
</body>
</body>
</body>
<body>
<geom type="cylinder" fromto="0.5 0 0.2 0.5 0 0" size="0.07"/>
<site name="end2" pos="0.5 0 0.2" type="sphere" size="0.01"/>
<joint type="free"/>
</body>
</worldbody>
<tendon>
<spatial limited="true" range="0 0.6" width="0.005">
<site site="end1"/>
<site site="end2"/>
</spatial>
</tendon>
</mujoco>
+678
View File
@@ -0,0 +1,678 @@
MuJoCo version 2.10
model name example
nq 15
nv 13
nu 0
na 0
nbody 5
njnt 6
ngeom 4
nsite 2
ncam 0
nlight 1
nmesh 0
nmeshvert 0
nmeshface 0
nmeshtexvert 0
nmeshgraph 0
nskin 0
nskinvert 0
nskintexvert 0
nskinface 0
nskinbone 0
nskinbonevert 0
nhfield 0
nhfielddata 0
ntex 1
ntexdata 1179648
nmat 0
npair 0
nexclude 0
neq 0
ntendon 1
nwrap 2
nsensor 0
nnumeric 0
nnumericdata 0
ntext 0
ntextdata 0
ntuple 0
ntupledata 0
nkey 0
nuser_body 0
nuser_jnt 0
nuser_geom 0
nuser_site 0
nuser_cam 0
nuser_tendon 0
nuser_actuator 0
nuser_sensor 0
nnames 41
nM 49
nemax 0
njmax 500
nconmax 100
nstack 1316805
nuserdata 0
nmocap 0
nsensordata 0
nbuffer 1185209
timestep 0.002
apirate 1e+02
impratio 1
tolerance 1e-08
noslip_tolerance 1e-06
mpr_tolerance 1e-06
gravity 0 0 -9.8
wind 0 0 0
magnetic 0 -0.5 0
density 0
viscosity 0
o_margin 0
o_solref 0.02 1
o_solimp 0.9 0.95 0.001 0.5 2
integrator 0
collision 0
collision 0
cone 0
jacobian 2
solver 2
iterations 100
noslip_iterations 0
mpr_iterations 50
disableflags 0
enableflags 0
totalmass 11
meaninertia 0.86
meanmass 2.7
meansize 0.17
extent 1.1
center 0.18 0 0.52
qpos0 1 0 0 0 0 0 0 0 0.5 0 0.1 1 0 0 0
qpos_spring 1 0 0 0 0 0 0 0 0.5 0 0.1 1 0 0 0
BODY 0:
name world
parentid 0
rootid 0
weldid 0
mocapid -1
jntnum 0
jntadr -1
dofnum 0
dofadr -1
geomnum 0
geomadr -1
simple 1
sameframe 1
pos 0 0 0
quat 1 0 0 0
ipos 0 0 0
iquat 1 0 0 0
mass 0
subtreemass 11
inertia 0 0 0
invweight0 0 0
BODY 1:
name
parentid 0
rootid 1
weldid 1
mocapid -1
jntnum 1
jntadr 0
dofnum 3
dofadr 0
geomnum 1
geomadr 0
simple 0
sameframe 1
pos 0 0 0.8
quat 1 0 0 0
ipos 0 0 0
iquat 1 0 0 0
mass 5.2
subtreemass 7.6
inertia 0.096 0.096 0.0094
invweight0 0.051 7.3
BODY 2:
name
parentid 1
rootid 1
weldid 2
mocapid -1
jntnum 2
jntadr 1
dofnum 2
dofadr 3
geomnum 1
geomadr 1
simple 0
sameframe 1
pos 0.15 0 -0.2
quat 0.71 0 -0.71 0
ipos 0 0 0
iquat 1 0 0 0
mass 1.7
subtreemass 2.4
inertia 0.017 0.017 0.0014
invweight0 0.31 1.6e+02
BODY 3:
name
parentid 2
rootid 1
weldid 3
mocapid -1
jntnum 2
jntadr 3
dofnum 2
dofadr 5
geomnum 1
geomadr 2
simple 0
sameframe 1
pos 5.6e-17 0 -0.25
quat 0.71 0 0.71 0
ipos 0 0 0
iquat 1 0 0 0
mass 0.67
subtreemass 0.67
inertia 0.00091 0.0014 0.0022
invweight0 0.9 2.8e+02
BODY 4:
name
parentid 0
rootid 4
weldid 4
mocapid -1
jntnum 1
jntadr 5
dofnum 6
dofadr 7
geomnum 1
geomadr 3
simple 1
sameframe 1
pos 0.5 0 0.1
quat 1 0 0 0
ipos 0 0 0
iquat 1 0 0 0
mass 3.1
subtreemass 3.1
inertia 0.014 0.014 0.0075
invweight0 0.32 92
JOINT 0:
name
type 1
qposadr 0
dofadr 0
bodyid 1
group 0
limited 0
pos 0 0 0.2
axis 0 0 1
stiffness 0
range 0 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
margin 0
JOINT 1:
name
type 3
qposadr 4
dofadr 3
bodyid 2
group 0
limited 0
pos -3.3e-17 0 0.15
axis 0 1 0
stiffness 0
range 0 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
margin 0
JOINT 2:
name
type 3
qposadr 5
dofadr 4
bodyid 2
group 0
limited 0
pos -3.3e-17 0 0.15
axis 2.2e-16 0 -1
stiffness 0
range 0 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
margin 0
JOINT 3:
name
type 3
qposadr 6
dofadr 5
bodyid 3
group 0
limited 0
pos -0.1 0 0
axis 0 1 0
stiffness 0
range 0 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
margin 0
JOINT 4:
name
type 3
qposadr 7
dofadr 6
bodyid 3
group 0
limited 0
pos -0.1 0 0
axis 0 0 1
stiffness 0
range 0 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
margin 0
JOINT 5:
name
type 0
qposadr 8
dofadr 7
bodyid 4
group 0
limited 0
pos 0 0 0
axis 0 0 1
stiffness 0
range 0 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
margin 0
DOF 0:
bodyid 1
jntid 0
parentid -1
Madr 0
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 7.3
M0 0.69
DOF 1:
bodyid 1
jntid 0
parentid 0
Madr 1
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 7.3
M0 0.85
DOF 2:
bodyid 1
jntid 0
parentid 1
Madr 3
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 7.3
M0 0.17
DOF 3:
bodyid 2
jntid 1
parentid 2
Madr 6
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 17
M0 0.16
DOF 4:
bodyid 2
jntid 2
parentid 3
Madr 10
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 4.4e+02
M0 0.0023
DOF 5:
bodyid 3
jntid 3
parentid 4
Madr 15
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 3.1e+02
M0 0.0081
DOF 6:
bodyid 3
jntid 4
parentid 5
Madr 21
simplenum 0
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 2.5e+02
M0 0.0089
DOF 7:
bodyid 4
jntid 5
parentid -1
Madr 28
simplenum 6
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 0.32
M0 3.1
DOF 8:
bodyid 4
jntid 5
parentid 7
Madr 29
simplenum 5
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 0.32
M0 3.1
DOF 9:
bodyid 4
jntid 5
parentid 8
Madr 31
simplenum 4
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 0.32
M0 3.1
DOF 10:
bodyid 4
jntid 5
parentid 9
Madr 34
simplenum 3
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 92
M0 0.014
DOF 11:
bodyid 4
jntid 5
parentid 10
Madr 38
simplenum 2
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 92
M0 0.014
DOF 12:
bodyid 4
jntid 5
parentid 11
Madr 43
simplenum 1
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
frictionloss 0
armature 0
damping 0
invweight0 92
M0 0.0075
GEOM 0:
name
type 3
contype 1
conaffinity 1
condim 3
bodyid 1
dataid -1
matid -1
group 0
priority 0
sameframe 1
solmix 1
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
size 0.06 0.2 0
rbound 0.26
pos 0 0 0
quat 1 0 0 0
friction 1 0.005 0.0001
margin 0
gap 0
rgba 0.8 0.6 0.4 1
GEOM 1:
name
type 3
contype 1
conaffinity 1
condim 3
bodyid 2
dataid -1
matid -1
group 0
priority 0
sameframe 1
solmix 1
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
size 0.04 0.15 0
rbound 0.19
pos 0 0 0
quat 1 0 0 0
friction 1 0.005 0.0001
margin 0
gap 0
rgba 0.8 0.6 0.4 1
GEOM 2:
name
type 4
contype 1
conaffinity 1
condim 3
bodyid 3
dataid -1
matid -1
group 0
priority 0
sameframe 1
solmix 1
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
size 0.1 0.08 0.02
rbound 0.1
pos 0 0 0
quat 1 0 0 0
friction 1 0.005 0.0001
margin 0
gap 0
rgba 0.8 0.6 0.4 1
GEOM 3:
name
type 5
contype 1
conaffinity 1
condim 3
bodyid 4
dataid -1
matid -1
group 0
priority 0
sameframe 1
solmix 1
solref 0.02 1
solimp 0.9 0.95 0.001 0.5 2
size 0.07 0.1 0
rbound 0.12
pos 0 0 0
quat 1 0 0 0
friction 1 0.005 0.0001
margin 0
gap 0
rgba 0.8 0.6 0.4 1
SITE 0:
name end1
type 2
bodyid 3
matid -1
group 0
sameframe 0
size 0.01 0.005 0.005
pos 0.1 0 0
quat 1 0 0 0
rgba 0.5 0.5 0.5 1
SITE 1:
name end2
type 2
bodyid 4
matid -1
group 0
sameframe 0
size 0.01 0.005 0.005
pos 0 0 0.1
quat 1 0 0 0
rgba 0.5 0.5 0.5 1
LIGHT 0:
name
mode 0
bodyid 0
targetbodyid -1
directional 0
castshadow 1
active 1
pos 0 1 1
dir 0 -0.71 -0.71
poscom0 -0.19 1 0.45
pos0 0 1 1
dir0 0 -0.71 -0.71
attenuation 1 0 0
cutoff 45
exponent 10
ambient 0 0 0
diffuse 1 1 1
specular 0.3 0.3 0.3
TEXTURE 0:
name
type 2
height 1536
width 256
adr 0
TENDON 0:
name
num 2
limited 1
matid -1
group 0
width 0.005
solreflimit 0.02 1
solimplimit 0.9 0.95 0.001 0.5 2
solreffrctn 0.02 1
solimpfrctn 0.9 0.95 0.001 0.5 2
range 0 0.6
margin 0
stiffness 0
damping 0
frictionloss 0
lengthspring 0.4
length0 0.4
invweight0 5.9
rgba 0.5 0.5 0.5 1
path
3 0 0
3 1 0
+44
View File
@@ -0,0 +1,44 @@
<mujoco model="example">
<compiler angle="radian" />
<size njmax="500" nconmax="100" />
<default class="main">
<geom size="0" rgba="0.8 0.6 0.4 1" />
<site size="0" />
</default>
<asset>
<texture type="skybox" builtin="gradient" rgb1="1 1 1" rgb2="0.6 0.8 1" width="256" height="1536" />
</asset>
<worldbody>
<light pos="0 1 1" dir="0 -0.707107 -0.707107" diffuse="1 1 1" />
<body pos="0 0 0.8">
<inertial pos="0 0 0" mass="5.20248" diaginertia="0.0964192 0.0964192 0.00936446" />
<joint pos="0 0 0.2" type="ball" />
<geom type="capsule" size="0.06 0.2" />
<body pos="0.15 0 -0.2" quat="0.707107 0 -0.707107 0">
<inertial pos="0 0 0" mass="1.70903" diaginertia="0.0171472 0.0171472 0.00136722" />
<joint pos="0 0 0.15" axis="0 1 0" />
<joint pos="0 0 0.15" axis="0 0 -1" />
<geom type="capsule" size="0.04 0.15" />
<body pos="0 0 -0.25" quat="0.707107 0 0.707107 0">
<inertial pos="0 0 0" mass="0.670206" diaginertia="0.000911481 0.00139403 0.00219828" />
<joint pos="-0.1 0 0" axis="0 1 0" />
<joint pos="-0.1 0 0" axis="0 0 1" />
<geom type="ellipsoid" size="0.1 0.08 0.02" />
<site name="end1" pos="0.1 0 0" size="0.01" />
</body>
</body>
</body>
<body pos="0.5 0 0.1">
<inertial pos="0 0 0" mass="3.07876" diaginertia="0.014034 0.014034 0.00754296" />
<joint type="free" />
<geom type="cylinder" size="0.07 0.1" />
<site name="end2" pos="0 0 0.1" size="0.01" />
</body>
</worldbody>
<tendon>
<spatial limited="true" width="0.005" range="0 0.6">
<site site="end1" />
<site site="end2" />
</spatial>
</tendon>
</mujoco>
+34
View File
@@ -0,0 +1,34 @@
#include "mujoco.h"
#include "stdio.h"
char error[1000];
mjModel* m;
mjData* d;
int main(void)
{
// activate MuJoCo Pro
mj_activate("mjkey.txt");
// load model from file and check for errors
m = mj_loadXML("hello.xml", NULL, error, 1000);
if( !m )
{
printf("%s\n", error);
return 1;
}
// make data corresponding to model
d = mj_makeData(m);
// run simulation for 10 seconds
while( d->time<10 )
mj_step(m, d);
// free model and data, deactivate
mj_deleteData(d);
mj_deleteModel(m);
mj_deactivate();
return 0;
}
+10
View File
@@ -0,0 +1,10 @@
<mujoco>
<worldbody>
<light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
<body pos="0 0 1">
<joint type="free"/>
<geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
</body>
</worldbody>
</mujoco>
+72
View File
@@ -0,0 +1,72 @@
<mujoco model="test">
<compiler coordinate="global"/>
<default>
<geom rgba=".9 .7 .1 1" size="0.01"/>
<site type="sphere" rgba=".9 .9 .9 1" size="0.005"/>
<joint type="hinge" axis="0 1 0" limited="true" range="0 60" solimplimit="0.95 0.95 0.1"/>
</default>
<visual>
<headlight diffuse=".7 .7 .7"/>
</visual>
<worldbody>
<body>
<geom type="cylinder" fromto="-0.03 0 0.2 -0.03 0 0.15"
size="0.03" rgba=".2 .2 .5 1" density="5000"/>
<joint type="slide" pos="-0.03 0 0.2" axis="0 0 1" limited="false"/>
<site name="s1" pos="-0.03 0 0.2"/>
</body>
<site name="s2" pos="-0.03 0 0.32"/>
<body>
<geom type="capsule" fromto="0 0 0.3 0.1 0 0.3"/>
<geom name="g1" type="cylinder" fromto="0.0 0.015 0.3 0.0 -0.015 0.3"
size="0.02" rgba=".3 .9 .3 .4"/>
<joint pos="0 0 0.3"/>
<site name="s3" pos="0.02 0 0.32"/>
<body>
<geom type="capsule" fromto="0.1 0 0.3 0.2 0 0.3"/>
<geom name="g2" type="cylinder" fromto="0.1 0.015 0.3 0.1 -0.015 0.3"
size="0.02" rgba=".3 .9 .3 .4"/>
<joint pos="0.1 0 0.3"/>
<site name="s4" pos="0.13 0 0.31"/>
<site name="s5" pos="0.15 0 0.32"/>
<site name="side2" pos="0.1 0 0.33"/>
<body>
<geom type="capsule" fromto="0.2 0 0.3 0.27 0 0.3"/>
<geom name="g3" type="cylinder" fromto="0.2 0.015 0.3 0.2 -0.015 0.3"
size="0.02" rgba=".3 .9 .3 .4"/>
<joint pos="0.2 0 0.3"/>
<site name="s6" pos="0.23 0 0.31"/>
<site name="side3" pos="0.2 0 0.33"/>
</body>
</body>
</body>
</worldbody>
<tendon>
<spatial width="0.002" rgba=".95 .3 .3 1" limited="true" range="0 0.33">
<site site="s1"/>
<site site="s2"/>
<geom geom="g1"/>
<site site="s3"/>
<pulley divisor="2"/>
<site site="s3"/>
<geom geom="g2" sidesite="side2"/>
<site site="s4"/>
<pulley divisor="2"/>
<site site="s3"/>
<geom geom="g2" sidesite="side2"/>
<site site="s5"/>
<geom geom="g3" sidesite="side3"/>
<site site="s6"/>
</spatial>
</tendon>
</mujoco>
+65
View File
@@ -0,0 +1,65 @@
.. include:: includes/macros.rst
.. include:: includes/roles.rst
=========
Changelog
=========
Version 2.1 (Oct. 18, 2021)
---------------------------
New features
^^^^^^^^^^^^
1. Keyframes now have ``mocap_pos`` and ``mocap_quat`` fields (mpos and quat attributes in the XML) allowing mocap
poses to be stored in keyframes.
2. New utility functions: ``mju_insertionSortInt`` (integer insertion sort) and ``mju_sigmoid`` (constructing a
sigmoid from two half-quadratics).
General
^^^^^^^
3. The pre-allocated sizes in the virtual file system (VFS) increased to 2000 and 1000, to allow for larger projects.
#. The C structs in the ``mjuiItem`` union are now named, for compatibility.
#. Fixed: ``mjcb_contactfilter`` type is ``mjfConFilt`` (was ``mjfGeneric``).
#. Fixed: The array of sensors in ``mjCModel`` was not cleared.
#. Cleaned up cross-platform code (internal changes, not visible via the API).
#. Fixed a bug in parsing of XML ``texcoord`` data (related to number of vertices).
#. Fixed a bug in `simulate.cc <https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ related to ``nkey``
(the number of keyframes).
#. Accelerated collision detection in the presence of large numbers of non-colliding geoms (with ``contype==0 and
conaffinity==0``).
UI
^^
11. Figure selection type changed from ``int`` to ``float``.
#. Figures now show data coordinates, when selection and highlight are enabled.
#. Changed ``mjMAXUIMULTI`` to 35, ``mjMAXUITEXT`` to 300, ``mjMAXUIRECT`` to 25.
#. Added collapsable sub-sections, implemented as separators with state: ``mjSEPCLOSED`` collapsed, ``mjSEPCLOSED+1``
expanded.
#. Added ``mjITEM_RADIOLINE`` item type.
#. Added function ``mjui_addToSection`` to simplify UI section construction.
#. Added subplot titles to ``mjvFigure``.
Rendering
^^^^^^^^^
18. ``render_gl2`` guards against non-finite floating point data in the axis range computation.
#. ``render_gl2`` draws lines from back to front for better visibility.
#. Added function ``mjr_label`` (for text labels).
#. ``mjr_render`` exits immediately if ``ngeom==0``, to avoid errors from uninitialized scenes (e.g. ``frustrum==0``).
#. Added scissor box in ``mjr_render``, so we don't clear the entire window at every frame.
License manager
^^^^^^^^^^^^^^^
23. Removed the entire license manager. The functions ``mj_activate`` and ``mj_deactivate`` are still there for
backward compabitibily, but now they do nothing and it is no longer necessary to call them.
#. Removed the remote license certificate functions ``mj_certXXX``.
Earlier Versions
----------------
For changelogs of earlier versions please see `roboti.us <https://www.roboti.us/download.html>`_.
+1420
View File
File diff suppressed because it is too large Load Diff
+104
View File
@@ -0,0 +1,104 @@
## Copyright 2021 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Configuration file for the Sphinx documentation builder."""
import doctest
import inspect
import os
import sys
# -- Path setup --------------------------------------------------------------
#
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../'))
sys.path.append(os.path.abspath('ext'))
import sphinxcontrib.katex as katex # pylint: disable=g-import-not-at-top
# -- Project information -----------------------------------------------------
project = 'MuJoCo'
copyright = 'DeepMind Technologies Limited' # pylint: disable=redefined-builtin
author = 'DeepMind'
# -- General configuration ---------------------------------------------------
master_doc = 'index'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinxcontrib.katex',
'sphinx_reredirects',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'includes/*']
redirects = {
# index.rst just contains the table of contents definition.
'index': 'overview.html',
}
# -- Options for autodoc -----------------------------------------------------
autodoc_default_options = {
'member-order': 'bysource',
'special-members': True,
'exclude-members': '__repr__, __str__, __weakref__',
}
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = [
'_static',
'css',
'favicons',
]
html_css_files = [
'theme_overrides.css',
]
html_favicon = 'favicons/favicon-32x32.png'
# -- Options for katex ------------------------------------------------------
# See: https://sphinxcontrib-katex.readthedocs.io/en/0.4.1/macros.html
latex_macros = r"""
\def \d #1{\operatorname{#1}}
"""
# Translate LaTeX macros to KaTeX and add to options for HTML builder
katex_macros = katex.latex_defs_to_katex_macros(latex_macros)
katex_options = 'macros: {' + katex_macros + '}'
# Add LaTeX macros for LATEX builder
latex_elements = {'preamble': latex_macros}
+179
View File
@@ -0,0 +1,179 @@
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=DM+Serif+Text:ital,wght@0,400;1,400&display=swap');
@import url('https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital,wght@0,400;1,400&display=swap');
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,400;0,500;1,400;1,500&display=swap');
body {
font-family: 'DM Sans', 'Helvetica Neue', 'Arial', sans-serif;
-webkit-font-smoothing: antialiased;
color: rgb(20, 35, 75);
}
.rst-content .toctree-wrapper>p.caption,h1 {
font-size: 250%;
font-family: 'DM Serif Display', 'Times New Roman', serif;
font-weight: 400;
color: rgb(0, 83, 214);
}
.rst-content .toctree-wrapper>p.caption,h2,h3,h4,h5,h6,legend {
font-family: 'DM Sans', 'Helvetica Neue', 'Arial', sans-serif;
-webkit-font-smoothing: antialiased;
font-weight: 700;
color: rgb(18, 54, 147);
}
/* Adjust paragraph margins to make top and bottom of images more symmetric. */
p {
margin: 20px 0px 20px 0px;
}
/* Paragraph margins don't apply to table cell contents. */
.rst-content table.docutils td>p {
margin-top: 0px;
}
/* Set padding of in-line highlighted text. */
.rst-content div[class^=highlight] pre {
padding: 6px;
}
/* Don't change color of visited links. */
.rst-content a.reference:visited {
color: #2980b9;
}
.rst-content code, .rst-content tt {
font-size: 90%;
padding: inherit;
border: inherit;
}
.rst-content table.align-default {
margin-left: auto;
margin-right: auto;
}
ul.simple {
list-style: disc;
margin-left: 24px;
}
ul.simple li {
list-style: disc;
}
/* Change background color of the nav bars. */
.wy-side-nav-search,
.wy-nav-top,
.wy-nav-side {
background-color: rgb(0, 83, 214);
}
/* Make text wrap in table cells. */
.wy-table-responsive table td,
.wy-table-responsive table th {
white-space: normal;
}
html.writer-html5 .rst-content table.docutils td>p,
html.writer-html5 .rst-content table.docutils th>p {
line-height: normal;
}
.wy-menu-vertical li.toctree-l1>a {
font-size: 115%;
}
.wy-menu-vertical li.toctree-l1.current>a {
font-weight: 700;
}
/* Change color of TOC text. */
.wy-menu-vertical a,
.wy-menu-vertical li.current a,
.wy-menu-vertical li.current a:hover,
.wy-menu-vertical li>a span.toctree-expand,
.wy-menu-vertical li>a:hover span.toctree-expand,
.wy-menu-vertical li.current>a span.toctree-expand,
.wy-menu-vertical li.current>a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l2 a span.toctree-expand,
.wy-menu-vertical li.toctree-l3 a span.toctree-expand,
.wy-menu-vertical li.toctree-l4 a span.toctree-expand,
.wy-menu-vertical li.toctree-l5 a span.toctree-expand,
.wy-menu-vertical li.toctree-l6 a span.toctree-expand,
.wy-menu-vertical li.toctree-l7 a span.toctree-expand,
.wy-menu-vertical li.toctree-l8 a span.toctree-expand,
.wy-menu-vertical li.toctree-l9 a span.toctree-expand,
.wy-menu-vertical li.toctree-l10 a span.toctree-expand,
.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,
.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand {
color: white;
}
/* Change color of TOC background. */
.wy-menu-vertical li a:hover,
.wy-menu-vertical li.current,
.wy-menu-vertical li.current>a,
.wy-menu-vertical li.current a:hover,
.wy-menu-vertical li.toctree-l1.current>a,
.wy-menu-vertical li.toctree-l2.current>a,
.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,
.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,
.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,
.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,
.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,
.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,
.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,
.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a {
background-color: rgb(0, 83, 214);
border: none;
}
/* MJCF attributes table. */
.rst-content table.mjcf-attributes {
border-style: none;
margin-left: 0px;
margin-right: 0px;
width: 100%;
}
.rst-content table.mjcf-attributes:not(.field-list) tr td,
.rst-content table.mjcf-attributes:not(.field-list) tr:nth-child(2n-1) td {
border-style: none;
background-color: rgba(255, 255, 255, 0);
padding: 0px 0px 0px 0px;
width: 33%;
}
table td > div.wy-table-responsive {
margin-bottom: 0px;
}
/* MJCF element names. */
.el {
font-weight: bold;
}
/* MJCF attribute names. */
.at {
color: darkred;
}
/* MJCF attribute value specs. */
.at-val {
color: darkred;
font-weight: normal;
}
/* Hide the prefix for XML element names, but only in toctree */
.toctree-l1 .el-prefix {
display: none;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+214
View File
@@ -0,0 +1,214 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 559.62 245.71">
<defs>
<style>
.cls-1, .cls-4, .cls-6 {
fill: none;
}
.cls-1, .cls-6 {
stroke: #b3b3b3;
}
.cls-1 {
stroke-width: 2px;
}
.cls-2 {
font-size: 12px;
}
.cls-2, .cls-8 {
font-family: ArialMT, Arial;
}
.cls-3 {
font-size: 9px;
}
.cls-4, .cls-5 {
stroke: #000;
}
.cls-6 {
stroke-dasharray: 5 5;
}
.cls-7 {
font-size: 8px;
}
.cls-8 {
font-size: 24px;
}
</style>
</defs>
<line class="cls-1" x1="28.52" y1="139.62" x2="79.67" y2="174.04"/>
<line class="cls-1" x1="28.52" y1="139.62" x2="72.1" y2="113.9"/>
<line class="cls-1" x1="28.52" y1="139.62" x2="28.52" y2="69.94"/>
<text class="cls-2" transform="translate(25.61 10.3)">e<tspan class="cls-3" x="6.67" y="3">1</tspan></text>
<text class="cls-2" transform="translate(126 209.44)">e<tspan class="cls-3" x="6.67" y="3">2</tspan></text>
<text class="cls-2" transform="translate(123.42 85.94)">e<tspan class="cls-3" x="6.67" y="3">3</tspan></text>
<g>
<path class="cls-4" d="M-316.59,62.5c0-11,6.36-20,14.2-20s14.19,9,14.19,20" transform="translate(373.33 55.94)"/>
<path d="M-288.2,61.73l2.7-1.64.06.09-1.75,4.41c-.34,1.53-.67,3.07-1,4.61-.34-1.54-.68-3.08-1-4.61L-291,60.18l0-.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<path class="cls-4" d="M-283,124.1c0-11-6.35-20-14.19-20s-14.19,9-14.19,20" transform="translate(373.33 55.94)"/>
<path d="M-311.39,123.33l2.7-1.64.06.09-1.75,4.41c-.34,1.53-.68,3.07-1,4.6l-1-4.6-1.75-4.41.05-.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<path class="cls-4" d="M-351.84,27.29c14.25,0,25.8-5.49,25.8-12.26s-11.55-12.26-25.8-12.26" transform="translate(373.33 55.94)"/>
<path d="M-351.08,2.77l1.64,2.71-.09.06-4.41-1.75-4.6-1,4.6-1L-349.53,0l.09,0Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(0 62.46)">e<tspan class="cls-3" x="6.67" y="3">4</tspan></text>
<text class="cls-2" transform="translate(58.77 199.36)">e<tspan class="cls-3" x="6.67" y="3">5</tspan></text>
<text class="cls-2" transform="translate(81.16 136.09)">e<tspan class="cls-3" x="6.67" y="3">6</tspan></text>
<text class="cls-2" transform="translate(18.39 122.2)">x</text>
<text class="cls-2" transform="translate(41.29 162.53)">y</text>
<text class="cls-2" transform="translate(50.31 137.92)">z</text>
<path class="cls-5" d="M-341.33,83.63a3.48,3.48,0,0,1-3.48,3.48,3.48,3.48,0,0,1-3.49-3.48,3.48,3.48,0,0,1,3.49-3.48A3.48,3.48,0,0,1-341.33,83.63Z" transform="translate(373.33 55.94)"/>
<g>
<line class="cls-4" x1="28.52" y1="48.07" x2="28.52" y2="22.19"/>
<path d="M-344.81-33l-2.71,1.64-.06-.09,1.75-4.41,1-4.61c.33,1.54.67,3.07,1,4.61l1.75,4.41-.05.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="94.7" y1="184.06" x2="115.42" y2="198"/>
<path d="M-258.54,141.63l.14-3.16h.11l2.68,3.91c1.09,1.14,2.17,2.28,3.26,3.41l-4.39-1.73-4.63-1-.05-.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="88.95" y1="104.87" x2="110.74" y2="92.01"/>
<path d="M-263.25,36.46-266,35l.05-.1,4.68-.74,4.48-1.46-3.45,3.21-2.9,3.75h-.11Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(265.54 123.6)">e<tspan class="cls-3" x="6.67" y="3">1</tspan></text>
<text class="cls-2" transform="translate(229.69 111.4)">e<tspan class="cls-3" x="6.67" y="3">2</tspan></text>
<text class="cls-2" transform="translate(307.66 91.78)">e<tspan class="cls-3" x="6.67" y="3">3</tspan></text>
<text class="cls-2" transform="translate(188.06 133.82)">e<tspan class="cls-3" x="6.67" y="3">4</tspan></text>
<line class="cls-1" x1="255.21" y1="174.82" x2="303.2" y2="207.11"/>
<line class="cls-1" x1="255.21" y1="174.82" x2="298.79" y2="149.1"/>
<line class="cls-1" x1="255.21" y1="174.82" x2="255.21" y2="105.14"/>
<path class="cls-5" d="M-114.63,118.83a3.48,3.48,0,0,1-3.49,3.48,3.48,3.48,0,0,1-3.48-3.48,3.48,3.48,0,0,1,3.48-3.48A3.48,3.48,0,0,1-114.63,118.83Z" transform="translate(373.33 55.94)"/>
<g>
<path class="cls-6" d="M-72,36.44c7.4,10.56-7.74,29.27-33.83,41.8s-53.24,14.14-60.65,3.59,7.74-29.27,33.83-41.8S-79.41,25.89-72,36.44Z" transform="translate(373.33 55.94)"/>
<g>
<line class="cls-4" x1="209.77" y1="140.36" x2="255.21" y2="174.82"/>
<path d="M-162.95,84.88l-.33,3.15h-.11L-165.84,84l-3.06-3.59,4.28,2,4.57,1.27.05.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="267.54" y1="136.09" x2="255.21" y2="174.82"/>
<path d="M-106,80.87l-3.07.75,0-.11,3-3.66,2.36-4.09c-.14,1.57-.28,3.14-.43,4.7l.33,4.73-.07.07Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="242.89" y1="100.97" x2="255.21" y2="174.82"/>
<path d="M-130.32,45.78l-2.39,2.07-.08-.08,1-4.64.24-4.71q.88,2.19,1.76,4.38l2.45,4.06,0,.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="300.66" y1="96.7" x2="255.21" y2="174.82"/>
<path d="M-73,41.41l-3.17.07v-.11l3.72-2.93c1.07-1.16,2.13-2.32,3.2-3.47l-1.44,4.49-.71,4.68-.08.06Z" transform="translate(373.33 55.94)"/>
</g>
</g>
<text class="cls-2" transform="translate(70.45 14.72)">elliptic basis: E = I<tspan class="cls-3" x="96.38" y="3">6</tspan></text>
<text class="cls-2" transform="translate(312.5 17.19)">pyramidal basis: E = </text>
<g>
<g>
<line class="cls-4" x1="255.97" y1="83.27" x2="255.97" y2="57.39"/>
<path d="M-117.36,2.21l-2.7,1.64-.06-.09,1.75-4.41c.34-1.53.67-3.07,1-4.6l1,4.6,1.75,4.41,0,.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<path class="cls-4" d="M-130.39,31.48c14.26,0,25.81-5.49,25.81-12.26S-116.13,7-130.39,7" transform="translate(373.33 55.94)"/>
<path d="M-129.62,7l1.64,2.7-.09.06L-132.48,8l-4.6-1,4.6-1,4.41-1.75.09,0Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(239.43 76.17)">e<tspan class="cls-3" x="6.67" y="3">5</tspan></text>
</g>
<g>
<g>
<line class="cls-4" x1="255.97" y1="40.49" x2="255.97" y2="14.61"/>
<path d="M-117.36-40.57l-2.7,1.65-.06-.1,1.75-4.4c.34-1.54.67-3.07,1-4.61l1,4.61,1.75,4.4,0,.1Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<path class="cls-4" d="M-104.58-10.29c-14.25,0-25.81-5.49-25.81-12.26s11.56-12.26,25.81-12.26" transform="translate(373.33 55.94)"/>
<path d="M-105.35-34.81l-1.64-2.7.09-.06,4.41,1.75,4.61,1-4.61,1L-106.9-32l-.09-.05Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(260.75 35.64)">e<tspan class="cls-3" x="6.67" y="3">6</tspan></text>
</g>
<g>
<g>
<path class="cls-4" d="M-50.09,157.37c0-11-6.36-20-14.2-20s-14.19,9-14.19,20" transform="translate(373.33 55.94)"/>
<path d="M-78.48,156.61l2.7-1.65.07.1-1.75,4.4-1,4.61c-.34-1.54-.67-3.07-1-4.61l-1.75-4.4,0-.1Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="309.01" y1="211" x2="309.01" y2="185.12"/>
<path d="M-64.32,129.94-67,131.58l-.06-.09,1.75-4.4,1-4.61c.33,1.54.67,3.07,1,4.61l1.75,4.4,0,.09Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(301.82 221.38)">e<tspan class="cls-3" x="6.67" y="3">7</tspan></text>
</g>
<g>
<g>
<path class="cls-4" d="M-49.09,174.8c0-11.05,6.35-20,14.19-20s14.19,8.95,14.19,20" transform="translate(373.33 55.94)"/>
<path d="M-20.71,174l2.71-1.65.06.09-1.75,4.41-1,4.61c-.33-1.54-.67-3.07-1-4.61l-1.75-4.41,0-.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="338.39" y1="228.43" x2="338.39" y2="202.55"/>
<path d="M-34.94,147.37l-2.7,1.64-.06-.09,1.75-4.4c.34-1.54.67-3.07,1-4.61l1,4.61,1.75,4.4,0,.09Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(331.21 238.81)">e<tspan class="cls-3" x="6.67" y="3">8</tspan></text>
</g>
<g>
<g>
<path class="cls-4" d="M-79.48,91.21c0-11,6.36-20,14.19-20s14.2,9,14.2,20" transform="translate(373.33 55.94)"/>
<path d="M-51.09,90.45l2.7-1.65.06.09-1.75,4.41c-.34,1.54-.67,3.07-1,4.61l-1-4.61-1.75-4.41,0-.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="308.01" y1="144.84" x2="308.01" y2="118.96"/>
<path d="M-65.32,63.78-68,65.42l-.06-.09,1.75-4.4,1-4.61c.33,1.53.67,3.07,1,4.61l1.75,4.4,0,.09Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(300.82 155.22)">e<tspan class="cls-3" x="6.67" y="3">9</tspan></text>
</g>
<g>
<g>
<path class="cls-4" d="M-20.25,72.12c0-11.05-6.36-20-14.2-20s-14.19,9-14.19,20" transform="translate(373.33 55.94)"/>
<path d="M-48.64,71.35l2.7-1.64.06.09-1.75,4.41c-.33,1.54-.67,3.07-1,4.61-.34-1.54-.67-3.07-1-4.61L-51.4,69.8l0-.09Z" transform="translate(373.33 55.94)"/>
</g>
<g>
<line class="cls-4" x1="338.85" y1="125.75" x2="338.85" y2="99.87"/>
<path d="M-34.48,44.69l-2.71,1.64-.06-.09,1.75-4.41,1-4.6c.33,1.53.67,3.07,1,4.6l1.75,4.41-.05.09Z" transform="translate(373.33 55.94)"/>
</g>
<text class="cls-2" transform="translate(331.66 136.13)">e<tspan class="cls-3" x="6.67" y="3">10</tspan></text>
</g>
<text class="cls-2" transform="translate(378.74 44.29)">1</text>
<text class="cls-2" transform="translate(373.33 65.99)">+m<tspan class="cls-7" x="17" y="3">1</tspan></text>
<text class="cls-2" transform="translate(378.74 89.16)">0</text>
<text class="cls-2" transform="translate(378.74 111.6)">0</text>
<text class="cls-2" transform="translate(378.74 134.03)">0</text>
<text class="cls-2" transform="translate(378.74 157.91)">0</text>
<text class="cls-2" transform="translate(407.55 44.29)">1</text>
<text class="cls-2" transform="translate(407.55 89.16)">0</text>
<text class="cls-2" transform="translate(407.55 111.6)">0</text>
<text class="cls-2" transform="translate(407.55 134.03)">0</text>
<text class="cls-2" transform="translate(407.55 157.91)">0</text>
<text class="cls-2" transform="translate(402.13 65.99)">-m<tspan class="cls-7" x="13.99" y="3">1</tspan></text>
<text class="cls-2" transform="translate(435.2 44.29)">1</text>
<text class="cls-2" transform="translate(429.78 88.42)">+m<tspan class="cls-7" x="17" y="3">2</tspan></text>
<text class="cls-2" transform="translate(435.2 66.73)">0</text>
<text class="cls-2" transform="translate(435.2 111.6)">0</text>
<text class="cls-2" transform="translate(435.2 134.03)">0</text>
<text class="cls-2" transform="translate(435.2 157.91)">0</text>
<text class="cls-2" transform="translate(463 44.29)">1</text>
<text class="cls-2" transform="translate(463 66.73)">0</text>
<text class="cls-2" transform="translate(463 111.6)">0</text>
<text class="cls-2" transform="translate(463 134.03)">0</text>
<text class="cls-2" transform="translate(463 157.91)">0</text>
<text class="cls-2" transform="translate(457.59 88.42)">-m<tspan class="cls-7" x="13.99" y="3">2</tspan></text>
<text class="cls-2" transform="translate(517.79 44.29)">1</text>
<text class="cls-2" transform="translate(512.37 157.17)">+m<tspan class="cls-7" x="17" y="3">5</tspan></text>
<text class="cls-2" transform="translate(517.79 66.73)">0</text>
<text class="cls-2" transform="translate(517.79 89.16)">0</text>
<text class="cls-2" transform="translate(517.79 111.6)">0</text>
<text class="cls-2" transform="translate(517.79 134.03)">0</text>
<text class="cls-2" transform="translate(546.59 44.29)">1</text>
<text class="cls-2" transform="translate(546.59 66.73)">0</text>
<text class="cls-2" transform="translate(546.59 89.16)">0</text>
<text class="cls-2" transform="translate(546.59 111.6)">0</text>
<text class="cls-2" transform="translate(546.59 134.03)">0</text>
<text class="cls-2" transform="translate(541.18 157.17)">-m<tspan class="cls-7" x="13.99" y="3">5</tspan></text>
<text class="cls-8" transform="translate(485.39 98.39)">...</text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

+72
View File
@@ -0,0 +1,72 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 455.01 171.24">
<defs>
<style>
.cls-1, .cls-10, .cls-4, .cls-5, .cls-6, .cls-7 {
fill: none;
}
.cls-1, .cls-9 {
stroke: #999;
}
.cls-10, .cls-2, .cls-4, .cls-5, .cls-7 {
stroke: #231f20;
}
.cls-3 {
font-size: 12px;
font-family: ArialMT, Arial;
}
.cls-4 {
stroke-dasharray: 5 5;
}
.cls-5 {
stroke-dasharray: 5;
}
.cls-6 {
stroke: #000;
stroke-width: 3px;
}
.cls-8 {
fill: #231f20;
}
.cls-9 {
fill: #f3f3f3;
}
.cls-10 {
stroke-dasharray: 4 4;
}
</style>
</defs>
<line class="cls-1" x1="68" y1="151.26" x2="133.33" y2="67.93"/>
<line class="cls-1" x1="68" y1="151.26" x2="2.67" y2="67.93"/>
<circle class="cls-2" cx="122.19" cy="116.89" r="2.67" transform="translate(-32.08 186.75) rotate(-67.5)"/>
<text class="cls-3" transform="translate(0 45.93)">cone<tspan x="0" y="14.4">constraint</tspan></text>
<text class="cls-3" transform="translate(133.33 134.6)">unconstrained<tspan x="0" y="14.4">minimum</tspan></text>
<line class="cls-4" x1="122.67" y1="118.6" x2="122.67" y2="81.54"/>
<line class="cls-5" x1="125.33" y1="118.6" x2="93.61" y2="118.6"/>
<line class="cls-6" x1="93.14" y1="119.2" x2="122.67" y2="81.54"/>
<g>
<line class="cls-7" x1="104" y1="53.93" x2="104" y2="88.93"/>
<path class="cls-8" d="M103.52,86.46l2.7-1.64.06.09-1.75,4.4c-.33,1.54-.67,3.07-1,4.61-.34-1.54-.67-3.07-1-4.61l-1.75-4.4,0-.09Z" transform="translate(0.48 1.71)"/>
</g>
<text class="cls-3" transform="translate(85.81 35.63)">continuum of<tspan x="0" y="14.4">PGS local minima</tspan></text>
<line class="cls-1" x1="387.29" y1="170.93" x2="452.62" y2="87.6"/>
<line class="cls-1" x1="387.29" y1="170.93" x2="321.96" y2="87.6"/>
<path class="cls-9" d="M454,76c0,19.83-30.19,35.9-67.44,35.9S319.14,95.82,319.14,76s30.2-35.9,67.45-35.9S454,56.16,454,76Z" transform="translate(0.48 1.71)"/>
<path class="cls-2" d="M417.37,68.73a1.86,1.86,0,1,1-1.86-1.86A1.85,1.85,0,0,1,417.37,68.73Z" transform="translate(0.48 1.71)"/>
<text class="cls-3" transform="translate(402.51 10.3)">search<tspan x="0" y="14.4">ray</tspan></text>
<text class="cls-3" transform="translate(297.84 33.33)">search<tspan x="0" y="14.4">ellipsoid</tspan></text>
<g>
<line class="cls-7" x1="416.79" y1="68.24" x2="429.11" y2="25.33"/>
<path class="cls-8" d="M428.42,24.36l-3.05.83,0-.1,2.89-3.75,2.25-4.15-.3,4.71.47,4.71-.07.08Z" transform="translate(0.48 1.71)"/>
</g>
<line class="cls-10" x1="403.95" y1="112.94" x2="416.79" y2="68.24"/>
<line class="cls-7" x1="387.29" y1="170.93" x2="403.95" y2="112.94"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

+11
View File
@@ -0,0 +1,11 @@
..
Macro for adding non-breaking spaces for indentation.
.. |_| unicode:: 0xA0 0xA0
:trim:
.. |_2| unicode:: 0xA0 0xA0 0xA0 0xA0
:trim:
.. |_3| unicode:: 0xA0 0xA0 0xA0 0xA0 0xA0 0xA0
:trim:
+15
View File
@@ -0,0 +1,15 @@
..
Role for XML elements in the MJCF spec.
.. role:: el
..
Role for the prefix of XML element names in the MJCF spec.
.. role:: el-prefix
..
Role for XML attribute names in the MJCF spec.
.. role:: at
..
Role for attribute value specs in MJCF spec.
.. role:: at-val
+16
View File
@@ -0,0 +1,16 @@
..
This file is not used as index.html, but only to define the toctree.
This is because toctree cannot contain a reference to the page where it's
defined (https://github.com/sphinx-doc/sphinx/issues/4602).
The `redirects` setting in conf.py makes this page redirect to overview.html.
.. toctree::
:hidden:
overview
computation
modeling
XMLreference
programming
APIreference
changelog
+1371
View File
File diff suppressed because it is too large Load Diff
+813
View File
@@ -0,0 +1,813 @@
Overview
========
Introduction
------------
**MuJoCo** stands for **Mu**\ lti-**Jo**\ int dynamics with **Co**\ ntact. It is a general purpose physics engine that
aims to facilitate research and development in robotics, biomechanics, graphics and animation, machine learning, and
other areas that demand fast and accurate simulation of articulated structures interacting with their environment.
Initially developed by Roboti LLC, it was acquired and made `freely available
<https://www.github.com/deepmind/mujoco/LICENSE>`__ by DeepMind in October 2021, with the goal of making MuJoCo an
open-source project. The MuJoCo codebase will be made available at the `deepmind/mujoco
<https://github.com/deepmind/mujoco>`__ repository on GitHub.
MuJoCo is a C/C++ library with a C API, intended for researchers and developers. The runtime simulation module is tuned
to maximize performance and operates on low-level data structures which are preallocated by the built-in XML parser and
compiler. The user defines models in the native MJCF scene description language -- an XML file format designed to be as
human readable and editable as possible. URDF model files can also be loaded. The library includes interactive
visualization with a native GUI, rendered in OpenGL. MuJoCo further exposes a large number of utility functions for
computing physics-related quantities.
MuJoCo can be used to implement model-based computations such as control synthesis, state estimation, system
identification, mechanism design, data analysis through inverse dynamics, and parallel sampling for machine learning
applications. It can also be used as a more traditional simulator, including for gaming and interactive virtual
environments.
.. _Features:
Key features
~~~~~~~~~~~~
MuJoCo has a long list of features. Here we outline the most notable ones.
Generalized coordinates combined with modern contact dynamics
Physics engines have traditionally separated in two categories. Robotics and biomechanics engines use efficient and
accurate recursive algorithms in generalized or joint coordinates. However they either leave out contact dynamics, or
rely on the earlier spring-damper approach which requires very small time-steps. Gaming engines use a more modern
approach where contact forces are found by solving an optimization problem. However, they often resort to the
over-specified Cartesian representation where joint constraints are imposed numerically, causing inaccuracies and
instabilities when elaborate kinematic structures are involved. MuJoCo was the first general-purpose engine to
combine the best of both worlds: simulation in generalized coordinates and optimization-based contact dynamics. Other
simulators have more recently been adapted to use MuJoCo's approach, but that is not usually compatible with all of
their functionality because they were not designed to do this from the start. Users accustomed to gaming engines may
find the generalized coordinates counterintuitive at first; see :ref:`Clarifications` section below.
Soft, convex and analytically-invertible contact dynamics
In the modern approach to contact dynamics, the forces or impulses caused by frictional contacts are usually defined
as the solution to a linear or non-linear complementarity problem (LCP or NCP), both of which are NP-hard. MuJoCo is
based on a different formulation of the physics of contact which reduces to a convex optimization problem, as
explained in detail in the :doc:`computation` chapter. Our model allows soft contacts and other constraints, and has
a uniquely-defined inverse facilitating data analysis and control applications. There is a choice of optimization
algorithms, including a generalization to the projected Gauss-Siedel method that can handle elliptic friction cones.
The solver provides unified treatment of frictional contacts including torsional and rolling friction, frictionless
contacts, joint and tendon limits, dry friction in joints and tendons, as well as a variety of equality constraints.
Tendon geometry
MuJoCo can model the 3D geometry of tendons - which are minimum-path-length strings obeying wrapping and via-point
constraints. The mechanism is similar to the one in OpenSim but implements a more restricted, closed-form set of
wrapping options to speed up computation. It also offers robotics-specific structures such as pulleys and coupled
degrees of freedom. Tendons can be used for actuation as well as to impose inequality or equality constraints on the
tendon length.
General actuation model
Designing a sufficiently rich actuation model while using a model-agnostic API is challenging. MuJoCo achieves this
goal by adopting an abstract actuation model that can have different types of transmission, force generation, and
internal dynamics (i.e. state variables which make the overall dynamics 3rd order). These components can be
instantiated so as to model motors, pneumatic and hydraulic cylinders, PD controllers, biological muscles and many
other actuators in a unified way.
Reconfigurable computation pipeline
MuJoCo has a top-level stepper function :ref:`mj_step` which runs the entire forward dynamics and advances the state
of the simulation. In many applications beyond simulation, however, it is beneficial to be able to run selected parts
of the computation pipeline. To this end MuJoCo provides a large number of :ref:`flags <option-flag>` which can be
set in any combination, allowing the user to reconfigure the pipeline as needed, beyond the selection of algorithms
and algorithm parameters via :ref:`options <option>`. Furthermore many lower-level functions can be called directly.
User-defined callbacks can implement custom force fields, actuators, collision routines, and feedback controllers.
Model compilation
As mentioned above, the user defines a MuJoCo model in an XML file format called MJCF. This model is then compiled by
the built-in compiler into the low-level data structure :ref:`mjModel`, which is cross-indexed and optimized for
runtime computation. The compiled model can also be saved in a binary MJB file.
Separation of model and data
MuJoCo separates simulation parameters into two data structures (C structs) at runtime:
- ``mjModel`` contains the model description and is expected to remain constant. There are other structures embedded
in it that contain simulation and visualization options, and those options need to be changed occasionally, but
this is done by the user.
- ``mjData`` contains all dynamic variables and intermediate results. It is used as a scratch pad where all
functions read their inputs and write their outputs -- which then become the inputs to subsequent stages in the
simulation pipeline. It also contains a pre-allocated and internally managed stack, so that the runtime module
does not need to call memory allocation functions after the model is initialized.
``mjModel`` is constructed by the compiler. :ref:`mjData` is constructed at runtime, given
``mjModel``. This separation makes it easy to simulate multiple models as well as multiple states and controls for
each model, in turn facilitating :ref:`multi-threading <siMultithread>` for sampling and :ref:`finite
differences <saDerivative>`. The top-level API functions reflect this basic separation, and have
the format:
.. code:: C
void mj_step(const mjModel* m, mjData* d);
Interactive simulation and visualization
The native :ref:`3D visualizer <Visualization>` provides rendering of meshes and geometric primitives, textures,
reflections, shadows, fog, transparency, wireframes, skyboxes, stereoscopic visualization (on video cards supporting
quad-buffered OpenGL). This functionality is used to generate 3D rendering that helps the user gain insight into the
physics simulation, including visual aids such as automatically generated model skeletons, equivalent inertia boxes,
contact positions and normals, contact forces that can be separated into normal and tangential components, external
perturbation forces, local frames, joint and actuator axes, and text labels. The visualizer expects a generic window
with an OpenGL rendering context, thereby allowing users to adopt a GUI library of their choice. The code sample
:ref:`simulate.cc <saSimulate>` distributed with MuJoCo shows how to do that with the GLFW library. A related
usability feature is the ability to "reach into" the simulation, push objects around and see how the physics respond.
The user selects the body to which the external forces and torques will be applied, and sees a real-time rendering of
the perturbations together with their dynamic consequences. This can be used to debug the model visually, to test the
response of a feedback controller, or to configure the model into a desired pose.
Powerful yet intuitive modeling language
MuJoCo has its own modeling language called MJCF. The goal of MJCF is to provide access to all of MuJoCo's compute
capabilities, and at the same time enable users to develop new models quickly and experiment with them. This goal is
achieved in large part due to an extensive :ref:`default setting <CDefault>` mechanism that resembles Cascading Style
Sheets (CSS) in HTML. While MJCF has many elements and attributes, the user needs to set surprisingly few of them in
any given model. This makes MJCF files shorter and more readable than many other formats.
Automated generation of composite flexible objects
MuJoCo's soft constraints can be used to model ropes, cloth, and deformable 3D objects. This requires a large
collection of regular bodies, joint, tendons and constraints to work together. The modeling language has high-level
macros which are automatically expanded by the model compiler into the necessary collections of standard model
elements. Importantly, these resulting flexible objects are able to fully interact with the rest of the simulation.
.. _Instance:
Model instances
~~~~~~~~~~~~~~~
There are several entities called "model" in MuJoCo. The user defines the model in an XML file written in MJCF or URDF.
The software can then create multiple instances of the same model in different media (file or memory) and on different
levels of description (high or low). All combinations are possible as shown in the following table:
+------------+----------------------+----------------------+
| | High level | Low level |
+============+======================+======================+
| **File** | MJCF/URDF (XML) | MJB (binary) |
+------------+----------------------+----------------------+
| **Memory** | mjCModel (C++ class) | mjModel (C struct) |
+------------+----------------------+----------------------+
All runtime computations are performed with ``mjModel`` which is too complex to create manually. This is why we have two
levels of modeling. The high level exists for user convenience: its sole purpose is to be compiled into a low level
model on which computations can be performed. The resulting ``mjModel`` can be loaded and saved into a binary file
(MJB), however those are version-specific and cannot be decompiled, thus models should always be maintained as XML
files.
The (internal) C++ class ``mjCModel`` is roughly in one-to-one correspondence with the MJCF file format. The XML parser
interprets the MJCF or URDF file and creates the corresponding ``mjCModel``. In principle the user can create
``mjCModel`` programmatically and then save it to MJCF or compile it. However this functionality is not yet exposed
because a C++ API cannot be exported from a compiler-independent library. There is a plan to develop a C wrapper around
it, but for the time being the parser and compiler are always invoked together, and models can only be created in XML.
The following diagram shows the different paths to obtaining an ``mjModel`` (again, the second bullet point is not yet
available):
- (text editor) → MJCF/URDF file → (MuJoCo parser → mjCModel → MuJoCo compiler) → mjModel
- (user code) → mjCModel → (MuJoCo compiler) → mjModel
- MJB file → (MuJoCo loader) → mjModel
.. _Examples:
Examples
~~~~~~~~
Here is a simple model in MuJoCo's MJCF format. It defines a plane fixed to the world, a light to better illuminate
objects and cast shadows, and a floating box with 6 DOFs (this is what the "free" joint does).
`hello.xml <_static/hello.xml>`__:
.. code:: xml
<mujoco>
<worldbody>
<light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
<body pos="0 0 1">
<joint type="free"/>
<geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
</body>
</worldbody>
</mujoco>
The built-in OpenGL visualizer renders this model as:
.. image:: images/overview/hello.png
:width: 300px
:align: center
If this model is simulated, the box will fall on the ground. Basic simulation code for the passive dynamics, without
rendering, is given below.
`hello.c <_static/hello.c>`__:
.. code:: c
#include "mujoco.h"
#include "stdio.h"
char error[1000];
mjModel* m;
mjData* d;
int main(void)
{
// load model from file and check for errors
m = mj_loadXML("hello.xml", NULL, error, 1000);
if( !m )
{
printf("%s\n", error);
return 1;
}
// make data corresponding to model
d = mj_makeData(m);
// run simulation for 10 seconds
while( d->time<10 )
mj_step(m, d);
// free model and data
mj_deleteData(d);
mj_deleteModel(m);
return 0;
}
This is technically a C file, but it is also a legitimate C++ file. Indeed the MuJoCo API is compatible with both C and
C++. Normally user code would be written in C++ because it adds convenience, and does not sacrifice efficiency because
the computational bottlenecks are in the simulator which is already highly optimized.
The function :ref:`mj_step` is the top-level function which advances the simulation state by one time step. This example
of course is just a passive dynamical system. Things get more interesting when the user specifies controls or applies
forces and starts interacting with the system.
Next we provide a more elaborate example illustrating several features of MJCF.
`example.xml <_static/example.xml>`__:
.. code:: xml
<mujoco model="example">
<compiler coordinate="global"/>
<default>
<geom rgba=".8 .6 .4 1"/>
</default>
<asset>
<texture type="skybox" builtin="gradient" rgb1="1 1 1" rgb2=".6 .8 1"
width="256" height="256"/>
</asset>
<worldbody>
<light pos="0 1 1" dir="0 -1 -1" diffuse="1 1 1"/>
<body>
<geom type="capsule" fromto="0 0 1 0 0 0.6" size="0.06"/>
<joint type="ball" pos="0 0 1"/>
<body>
<geom type="capsule" fromto="0 0 0.6 0.3 0 0.6" size="0.04"/>
<joint type="hinge" pos="0 0 0.6" axis="0 1 0"/>
<joint type="hinge" pos="0 0 0.6" axis="1 0 0"/>
<body>
<geom type="ellipsoid" pos="0.4 0 0.6" size="0.1 0.08 0.02"/>
<site name="end1" pos="0.5 0 0.6" type="sphere" size="0.01"/>
<joint type="hinge" pos="0.3 0 0.6" axis="0 1 0"/>
<joint type="hinge" pos="0.3 0 0.6" axis="0 0 1"/>
</body>
</body>
</body>
<body>
<geom type="cylinder" fromto="0.5 0 0.2 0.5 0 0" size="0.07"/>
<site name="end2" pos="0.5 0 0.2" type="sphere" size="0.01"/>
<joint type="free"/>
</body>
</worldbody>
<tendon>
<spatial limited="true" range="0 0.6" width="0.005">
<site site="end1"/>
<site site="end2"/>
</spatial>
</tendon>
</mujoco>
.. raw:: html
<figure class="align-right">
<video width="200" height="295" muted autoplay loop>
<source src="_static/example.mp4" type="video/mp4">
</video>
</figure>
This model is a 7 degree-of-freedom arm "holding" a string with a cylinder attached at the other end. The string is
implemented as a tendon with length limits. There is ball joint at the shoulder and pairs of hinge joints at the elbow
and wrist. The box inside the cylinder indicates a free "joint". The outer body element in the XML is the required
:el:`worldbody`. Note that using multiple joints between two bodies does not require creating dummy bodies.
The MJCF file contains the minimum information needed to specify the model. Capsules are defined by line-segments in
space -- in which case only the radius of the capsule is needed. The positions and orientations of body frames are
inferred from the geoms belonging to them. Inertial properties are inferred from the geom shape under a uniform density
assumption. The two sites are named because the tendon definition needs to reference them, but nothing else is named.
Joint axes are defined only for the hinge joints but not the ball joint. Collision rules are defined automatically.
Friction properties, gravity, simulation time step etc. are set to their defaults. The default geom color specified at
the top applies to all geoms.
Apart from saving the compiled model in the binary MJB format, we can save it as MJCF or as human-readable text; see
`example_saved.xml <_static/example_saved.xml>`__ and `example_saved.txt <_static/example_saved.txt>`__
respectively. The XML version is similar to the original, while the text version contains all information from
``mjModel``. Comparing the text version to the XML version reveals how much work the model compiler did for us.
.. _Elements:
Model elements
--------------
This section provides brief descriptions of all elements that can be included in a MuJoCo model. Later we explain in
more detail the underlying computations, the way elements are specified in MJCF, and their representation in
``mjModel``.
.. _Options:
Options
~~~~~~~
Each model has three sets of options listed below. They are always included. If their values are not specified in the
XML file, default values are used. The options are designed such that the user can change their values before each
simulation time step. Within a time step however none of the options should be changed.
``mjOption``
This structure contains all options that affect the physics simulation. It is used to select algorithms and set their
parameters, enable and disable different portions of the simulation pipeline, and adjust system-level physical
properties such as gravity.
``mjVisual``
This structure contains all visualization options. There are additional OpenGL rendering options, but these are
session-dependent and are not part of the model.
``mjStatistic``
This structure contains statistics about the model which are computed by the compiler: average body mass, spatial
extent of the model etc. It is included for information purposes, and also because the visualizer uses it for
automatic scaling.
.. _Assets:
Assets
~~~~~~
Assets are not in themselves model elements. Model elements can reference them, in which case the asset somehow changes
the properties of the referencing element. One asset can be referenced by multiple model elements. Since the sole
purpose of including an asset is to reference it, and referencing can only be done by name, every asset has a name
(which may be inferred from a file name when applicable). In contrast, the names of regular elements can be left
undefined.
Mesh
MuJoCo can load triangulated meshes from binary STL files. Software such as `MeshLab <https://www.meshlab.net/>`__
can be used to convert from other formats. While any collection of triangles can be loaded and visualized as a mesh,
the collision detector works with the convex hull. There are compile-time options for scaling the mesh, as well as
fitting a primitive geometric shape to it. The mesh can also be used to automatically infer inertial properties - by
treating it as a union of triangular pyramids and combining their masses and inertias. Note that the STL format does
not support color; some software packages write color information in unused fields but this is not consistent.
Instead the mesh is colored using the material properties of the referencing geom. In contrast, all spatial
properties are determined by the mesh data. MuJoCo supports a custom binary file format that can additionally specify
normals and texture coordinates. Meshes can also be embedded directly in the XML.
Skin
Skinned meshes (or skins) are meshes whose shape can deform at runtime. Their vertices are attached to rigid bodies
(called bones in this context) and each vertex can belong to multiple bones, resulting in smooth deformations of the
skin. Skins are purely visualization objects and do not affect the physics, but nevertheless they can enhance visual
realism significantly. Skins can be loaded from custom binary files, or embedded directly in the XML, similar to
meshes. When generating composite flexible objects automatically, the model compiler also generates skins for these
objects.
Height field
Height fields can be loaded from PNG files (converted to gray-scale internally) or from files in a custom binary
format described later. A height field is a rectangular grid of elevation data. The compiler normalizes the data to
the range [0-1]. The actual spatial extent of the height field is then determined by the size parameters of the
referencing geom. Height fields can only be referenced from geoms that are attached to the world body. For rendering
and collision detection purposes, the grid rectangles are automatically triangulated, thus the height field is treated
as a union of triangular prisms. Collision detection with such a composite object can in principle generate a large
number of contact points for a single geom pair. If that happens, only the first 64 contact points are kept. The
rationale is that height fields should be used to model terrain maps whose spatial features are large compared to the
other objects in the simulation, so the number of contacts will be small for well-designed models.
Texture
Textures can be loaded from PNG files or synthesized by the compiler based on user-defined procedural parameters.
There is also the option to leave the texture empty at model creation time and change it later at runtime -- so as to
render video in a MuJoCo simulation, or create other dynamic effects. The visualizer supports two types of texture
mapping: 2D and cube. 2D mapping is useful for planes and height fields. Cube mapping is useful for "shrink-wrapping"
textures around 3D objects without having to specify texture coordinates. It is also used to create a skybox. The six
sides of a cube maps can be loaded from separate image files, or from one composite image file, or generated by
repeating the same image. Unlike all other assets which are referenced directly from model elements, textures can
only be referenced from another asset (namely material) which is then referenced from model elements.
Material
Materials are used to control the appearance of geoms, sites and tendons. This is done by referencing the material
from the corresponding model element. Appearance includes texture mapping as well as other properties that interact
with OpenGL lights below: RGBA, specularity, shininess, emission. Materials can also be used to make objects
reflective. Currently reflections are rendered only on planes and on the Z+ faces of boxes. Note that model elements
can also have their local RGBA parameter for setting color. If both material and local RGBA are specified, the local
definition has precedence.
.. _Kinematic:
Kinematic tree
~~~~~~~~~~~~~~
MuJoCo simulates the dynamics of a collection of rigid bodies whose motion is usually constrained. The system state is
represented in joint coordinates and the bodies are explicitly organized into kinematic trees. Each body except for the
top-level "world" body has a unique parent. Kinematic loops are not allowed; if loop joints are needed they should be
modeled with equality constraints. Thus the backbone of a MuJoCo model is one or several kinematic trees formed by
nested body definitions; an isolated floating body counts as a tree. Several other elements listed below are defined
within a body and belong to that body. This is in contrast with the stand-alone elements listed later which cannot be
associated with a single body.
Body
Bodies have mass and inertial properties but do not have any geometric properties. Instead geometric shapes (or
geoms) are attached to the bodies. Each body has two coordinate frames: the frame used to define it as well as to
position other elements relative to it, and an inertial frame centered at the body's center of mass and aligned with
its principal axes of inertia. The body inertia matrix is therefore diagonal in this frame. At each time step MuJoCo
computes the forward kinematics recursively, yielding all body positions and orientations in global Cartesian
coordinates. This provides the basis for all subsequent computations.
Joint
Joints are defined within bodies. They create motion degrees of freedom (DOFs) between the body and its parent. In
the absence of joints the body is welded to its parent. This is the opposite of gaming engines which use
over-complete Cartesian coordinates, where joints remove DOFs instead of adding them. There are four types of joints:
ball, slide, hinge, and a "free joint" which creates floating bodies. A single body can have multiple joints. In this
way composite joints are created automatically, without having to define dummy bodies. The orientation components of
ball and free joints are represented as unit quaternions, and all computations in MuJoCo respect the properties of
quaternions.
DOF
Degrees of freedom are closely related to joints, but are not in one-to-one correspondence because ball and free
joints have multiple DOFs. Think of joints as specifying positional information, and of DOFs as specifying velocity
and force information. More formally, the joint positions are coordinates over the configuration manifold of the
system, while the joint velocities are coordinates over the tangent space to this manifold at the current position.
DOFs have velocity-related properties such as friction loss, damping, armature inertia. All generalized forces acting
on the system are expressed in the space of DOFs. In contrast, joints have position-related properties such as limits
and spring stiffness. DOFs are not specified directly by the user. Instead they are created by the compiler given the
joints.
Geom
Geoms are 3D shapes rigidly attached to the bodies. Multiple geoms can be attached to the same body. This is
particularly useful in light of the fact that MuJoCo only supports convex geom-geom collisions, and the only way to
create non-convex objects is to represent them as a union of convex geoms. Apart from collision detection and
subsequent computation of contact forces, geoms are used for rendering, as well as automatic inference of body masses
and inertias when the latter are omitted. MuJoCo supports several primitive geometric shapes: plane, sphere, capsule,
ellipsoid, cylinder, box. A geom can also be a mesh or a height field; this is done by referencing the corresponding
asset. Geoms have a number of material properties that affect the simulation and visualization.
Site
Sites are essentially light geoms. They represent locations of interest within the body frame. Sites do not
participate in collision detection or automated computation of inertial properties, however they can be used to
specify the spatial properties of other objects like sensors, tendon routing, and slider-crank endpoints.
Camera
Multiple cameras can be defined in a model. There is always a default camera which the user can freely move with the
mouse in the interactive visualizer. However it is often convenient to define additional cameras that are either
fixed to the world, or are attached to one of the bodies and move with it. In addition to the camera position and
orientation, the user can adjust the field of view and the inter-pupilary distance for stereoscopic rendering, as
well as create oblique projections needed for stereoscopic virtual environments.
Light
Lights can be fixed to the world body or attached to moving bodies. The visualizer provides access to the full
lighting model in OpenGL (fixed function) including ambient, diffuse and specular components, attenuation and cutoff,
positional and directional lighting, fog. Lights, or rather the objects illuminated by them, can also cast shadows.
However, similar to material reflections, each shadow-casting light adds one rendering pass so this feature should be
used with caution. Documenting the lighting model in detail is beyond the scope of this chapter; see `OpenGL
documentation <http://www.glprogramming.com/red/chapter05.html>`__ instead. Note that in addition to lights defined
by the user in the kinematic tree, there is a default headlight that moves with the camera. Its properties are
adjusted through the mjVisual options.
.. _Standalone:
Stand-alone elements
~~~~~~~~~~~~~~~~~~~~
Here we describe the model elements which do not belong to an individual body, and therefore are described outside the
kinematic tree.
Reference pose
The reference pose is a vector of joint positions stored in ``mjModel.qpos0``. It corresponds to the numeric values
of the joints when the model is in its initial configuration. In our earlier example the elbow was created in a bent
configuration at 90° angle. But MuJoCo does not know what an elbow is, and so by default it treats this joint
configuration as having numeric value of 0. We can override the default behavior and specify that the initial
configuration corresponds to 90°, using the ref attribute of :ref:`joint <joint>`. The reference values of all joints
are assembled into the vector ``mjModel.qpos0``. Whenever the simulation is reset, the joint configuration
``mjData.qpos`` is set to ``mjModel.qpos0``. At runtime the joint position vector is interpreted relative to the
reference pose. In particular, the amount of spatial transformation applied by the joints is ``mjData.qpos -
mjModel.qpos0``. This transformation is in addition to the parent-child translation and rotation offsets stored in
the body elements of ``mjModel``. The ref attribute only applies to scalar joints (slide and hinge). For ball joints,
the quaternion saved in ``mjModel.qpos0`` is always (1,0,0,0) which corresponds to the null rotation. For free
joints, the global 3D position and quaternion of the floating body are saved in ``mjModel.qpos0``.
Spring reference pose
This is the pose in which all joint and tendon springs achieve their resting length. Spring forces are generated
when the joint configuration deviates from the spring reference pose, and are linear in the amount of deviation. The
spring reference pose is saved in ``mjModel.qpos_spring``. For slide and hinge joints, the spring reference is
specified with the attribute springref. For ball and free joints, the spring reference corresponds to the initial
model configuration.
Tendon
Tendons are scalar length elements that can be used for actuation, imposing limits and equality constraints, or
creating spring-dampers and friction loss. There are two types of tendons: fixed and spatial. Fixed tendons are
linear combinations of (scalar) joint positions. They are useful for modeling mechanical coupling. Spatial tendons
are defined as the shortest path that passes through a sequence of specified sites (or via-points) or wraps around
specified geoms. Only spheres and cylinders are supported as wrapping geoms, and cylinders are treated as having
infinite length for wrapping purposes. To avoid abrupt jumps of the tendon from one side of the wrapping geom to the
other, the user can also specify the preferred side. If there are multiple wrapping geoms in the tendon path they
must be separated by sites, so as to avoid the need for an iterative solver. Spatial tendons can also be split into
multiple branches using pulleys.
Actuator
MuJoCo provides a flexible actuator model, with three components that can be specified independently. Together they
determine how the actuator works. Common actuator types are obtained by specifying these components in a coordinated
way. The three components are transmission, activation dynamics, and force generation. The transmission specifies how
the actuator is attached to the rest of the system; available types are joint, tendon and slider-crank. The
activation dynamics can be used to model internal activation states of pneumatic or hydraulic cylinders as well as
biological muscles; using such actuators makes the overall system dynamics 3rd-order. The force generation mechanism
determines how the scalar control signal provided as input to the actuator is mapped into a scalar force, which is in
turn mapped into a generalized force by the moment arms inferred from the transmission.
Sensor
MuJoCo can generate simulated sensor data which is saved in the global array ``mjData.sensordata``. The result is not
used in any internal computations; instead it is provided because the user presumably needs it for custom computation
or data analysis. Available sensor types include touch sensors, inertial measurement units (IMUs), force-torque
sensors, joint and tendon position and velocity sensors, actuator position, velocity and force sensors, motion
capture marker positions and quaternions, and magnetometers. Some of these require extra computation, while others
are copied from the corresponding fields of ``mjData``. There is also a user sensor, allowing user code to insert any
other quantity of interest in the sensor data array. MuJoCo also has off-screen rendering capabilities, making it
straightforward to simulate both color and depth camera sensors. This is not included in the standard sensor model
and instead has to be done programmatically, as illustrated in the code sample `simulate.cc
<https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_.
Equality
Equality constraints can impose additional constraints beyond those already imposed by the kinematic tree structure
and the joints/DOFs defined in it. They can be used to create loop joints, or in general model mechanical coupling.
The internal forces that enforce these constraints are computed together with all other constraint forces. The
available equality constraint types are: connect two bodies at a point (creating a ball joint outside the kinematic
tree); weld two bodies together; make two surfaces slide on each other; fix the position of a joint or tendon; couple
the positions of two joints or two tendons via a cubic polynomial.
Contact pair
Contact generation in MuJoCo is an elaborate process. Geom pairs that are checked for contact can come from two
sources: automated proximity tests and other filters collectively called "dynamic", as well as an explicit list of
geom pairs provided in the model. The latter is a separate type of model element. Because a contact involves a
combination of two geoms, the explicit specification allows the user to define contact parameters in ways that cannot
be done with the dynamic mechanism. It is also useful for fine-tuning the contact model, in particular adding contact
pairs that were removed by an aggressive filtering scheme.
Contact exclude
This is the opposite of contact pairs: it specifies pairs of bodies (rather than geoms) which should be excluded from
the generation of candidate contact pairs. It is useful for disabling contacts between bodies whose geometry causes
an undesirable permanent contact. Note that MuJoCo has other mechanisms for dealing with this situation (in
particular geoms cannot collide if they belong to the same body or to a parent and a child body), but sometimes these
automated mechanisms are not sufficient and explicit exclusion becomes necessary.
Custom numeric
There are three ways to enter custom numbers in a MuJoCo simulation. First, global numeric fields can be defined in
the XML. They have a name and an array of real values. Second, the definition of certain model elements can be
extended with element-specific custom arrays. This is done by setting the attributes ``nuser_XXX`` in the XML element
``size``. Third, there is the array ``mjData.userdata`` which is not used by any MuJoCo computations. The user can
store results from custom computations there; recall that everything that changes over time should be stored in
``mjData`` and not in ``mjModel``.
Custom text
Custom text fields can be saved in the model. They can be used in custom computations - either to specify keyword
commands, or to provide some other textual information. Do not use them for comments though; there is no benefit to
saving comments in a compiled model. XML has its own commenting mechanism (ignored by MuJoCo's parser and compiler)
which is more suitable.
Custom tuple
Custom tuples are lists of MuJoCo model elements, possibly including other tuples. They are not used by the
simulator, but are available for specifying groups of elements that are needed for user code. For example, one can
use tuples to define pairs of bodies for custom contact processing.
Keyframe
A keyframe is a snapshot of the simulation state variables. It contains the vectors of joint positions, joint
velocities, actuator activations when present, and the simulation time. The model can contain a library of keyframes.
They are useful for resetting the state of the system to a point of interest. Note that keyframes are not intended
for storing trajectory data in the model; external files should be used for this purpose.
.. _Clarifications:
Clarifications
--------------
The reader is likely to have experience with other physics simulators and related conventions, as well as general
programming practices that are not aligned with MuJoCo. This has the potential to cause confusion. The goal of this
section is to preemptively clarify the aspects that are most likely to be confusing; it is somewhere in-between a FAQ
and a tutorial on selected topics. We will need to refer to material covered later in the documentation, but
nevertheless the text below is as self-contained and introductory as possible.
.. _NotObject:
Not object-oriented
~~~~~~~~~~~~~~~~~~~
Object-oriented programming is a very useful abstraction, built on top of the more fundamental (and closer-to-hardware)
notion of data structures vs. functions that operate on them. An object is a collection of data structures and functions
that correspond to one semantic entity, and thereby have stronger dependencies among them than with the rest of the
application. The reason we are not using this here is because the dependency structure is such that the natural entity
is the entire physics simulator. Instead of objects, we have a small number of data structures and a large number of
functions that operate on them.
We still use a type of grouping, but it is different from the object-oriented approach. We separate the model
(``mjModel``) from the data (``mjData``). These are both data structures. The model contains everything needed to
describe the constant properties of the physical system being modeled, while the data contains the time-varying state
and the reusable intermediate results of internal computations. All top-level functions expect pointers to ``mjModel``
and ``mjData`` as arguments. In this way we avoid global variables which pollute the workspace and interfere with
multi-threading, but we do so in a way that is different from how object-oriented programming achieves the same effect.
.. _Soft:
Softness and slip
~~~~~~~~~~~~~~~~~
As we will explain at length in the :doc:`computation` chapter, MuJoCo is based on a mathematical model of the physics
of contact and other constraints. This model is inherently soft, in the sense that pushing harder against a constraint
will always result in larger acceleration, and so the inverse dynamics can be uniquely defined. This is desirable
because it yields a convex optimization problem and enables analyses that rely on inverse dynamics, and furthermore,
most contacts that we need to model in practice have some softness. However once we allow soft constraints, we are
effectively creating a new type of dynamics -- namely deformation dynamics -- and now we must specify how these dynamics
behave. This calls for elaborate parameterization of contacts and other constraints, involving the attributes
:at:`solref` and :at:`solimp` that can be set per constraints and will be described later.
An often confusing aspect of this soft model is that gradual contact slip cannot be avoided. Similarly, frictional
joints will gradually yield under gravity. This is not because the solver is unable to prevent slip, in the sense of
reaching the friction cone or friction loss limit, but because it is not trying to prevent slip in the first place.
Recall that larger force against a given constraint must result in larger acceleration. If slip were to be fully
suppressed, this key property would have to be violated. So if you see gradual slip in your simulation, the intuitive
explanation may be that the friction is insufficient, but that is rarely the case in MuJoCo. Instead the ``solref`` and
``solimp`` parameter vectors need to be adjusted in order to reduce this effect. Increasing constraint impedance (first
two elements of ``solimp``) as well as the global ``mjModel.opt.impratio`` setting can be particularly effective. Such
adjustment often requires smaller time steps to keep the simulation stable, because they make the nonlinear dynamics
more difficult to integrate numerically. Slip is also reduced by the Newton solver which is more accurate in general.
For situations where it is desirable to suppress slip completely, there is a second ``noslip`` solver which runs after
the main solver. It updates the contact forces in friction dimensions by disregarding constraint softness. When this
option is used however, MuJoCo is no longer solving the convex optimization problem it was designed to solve, and the
simulation may become less robust. Thus using the Newton solver with elliptic friction cones and large value of
``impratio`` is the recommended way of reducing slip.
.. _TypeNameId:
Types, names, ids
~~~~~~~~~~~~~~~~~
MuJoCo supports a large number of model elements, as summarized earlier. Each element type has a corresponding section
in ``mjModel`` listing its various properties. For example the joint limit data is in the array
.. code:: C
mjtNum* jnt_range; // joint limits (njnt x 2)
The size of each array (``njnt`` in this case) is also given in ``mjModel``. The limits of the first joint are included
first, followed by the limits of the second joint etc. This ordering reflects the fact that all matrices in MuJoCo have
row-major format.
The available element types are defined in
`mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h#L243>`_, in the enum type :ref:`mjtObj`.
These enums are mostly used internally. One exception are the functions :ref:`mj_name2id` and :ref:`mj_id2name` in the
MuJoCo API, which map element names to integer ids and vice versa. These functions take an element type as input.
Naming model elements in the XML is optional. Two elements of the same type (e.g. two joints) cannot have the same name.
Naming is required only when a given element needs to be referenced elsewhere in the model; referencing in the XML can
only be done by name. Once the model is compiled, the names are still stored in ``mjModel`` for user convenience,
although they have no further effect on the simulation. Names are useful for finding the corresponding integer ids, as
well as rendering: if you enable joint labels for example, a string will be shown next to each joint (elements with
undefined names are labeled as "joint N" where N is the id).
The integer ids of the elements are essential for indexing the MuJoCo data arrays. The ids are 0-based, following the C
convention. Suppose we already have ``mjModel* m``. To print the range of a joint named "elbow", do:
.. code:: C
int jntid = mj_name2id(m, mjOBJ_JOINT, "elbow");
if( jntid>=0 )
printf("(%f, %f)\n", m->jnt_range[2*jntid], m->jnt_range[2*jntid+1]);
If the name is not found the function returns -1, which is why one should always check for id>=0.
.. _BodyGeomSite:
Bodies, geoms, sites
~~~~~~~~~~~~~~~~~~~~
Bodies, geoms and sites are MuJoCo elements which roughly correspond to rigid bodies in the physical world. So why are
they separate? For semantic as well as computational reasons explained here.
First the similarities. Bodies, geoms and sites all have spatial frames attached to them (although bodies also have a
second frame which is centered at the body center of mass and aligned with the principal axes of inertia). The positions
and orientations of these frames are computed at each time step from ``mjData.qpos`` via forward kinematics. The results
of forward kinematics are availabe in ``mjData`` as xpos, xquat and xmat for bodies, geom_xpos and geom_xmat for geoms,
site_xpos and site_xmat for sites.
Now the differences. Bodies are used to construct the kinematic tree and are containers for other elements, including
geoms and sites. Bodies have a spatial frame, inertial properties, but no properties related to appearance or collision
geometry. This is because such properties do not affect the physics (except for contacts of course, but these are
handled separately). If you have seen diagrams of kinematic trees in robotics textbooks, the bodies are usually drawn as
amorphous shapes - to make the point that their actual shape is irrelevant to the physics.
Geoms (short for geometric primitive) are used to specify appearance and collision geometry. Each geom belongs to a body
and is rigidly attached to that body. Multiple geoms can be attached to the same body. This is particularly useful in
light of the fact that MuJoCo's collision detector assumes that all geoms are convex (it internally replaces meshes with
their convex hulls if the meshes are not convex). Thus if you want to model a non-convex shape, you have to decompose it
into a union of convex geoms and attach all of them to the same body. Geoms can also have mass and inertia in the XML
model (or rather material density which is used to compute the mass and inertia), but that is only used to compute the
body mass and inertia in the model compiler. In the actual ``mjModel`` being simulated geoms do not have inertial
properties.
Sites are light geoms. They have the same appearance properties but cannot participate in collisions and cannot be used
to infer body masses. On the other hand sites can do things that geoms cannot do: they can specify the volumes of touch
sensors, the attachment of IMU sensors, the routing of spatial tendons, the end-points of slider-crank actuators. These
are all spatial quantities, and yet they do not correspond to entities that should have mass or collide other entities -
which is why the site element was created. Sites can also be used to specify points (or rather frames) of interest to
the user.
The following example illustrates the point that multiple sites and geoms can be attached to the same body: two sites
and two geoms to one body in this case.
.. code:: XML
<mujoco>
<worldbody>
<body pos="0 0 0">
<geom type="sphere" size=".1" rgba=".9 .9 .1 1"/>
<geom type="capsule" pos="0 0 .1" size=".05 .1" rgba=".9 .9 .1 1"/>
<site type="box" pos="0 -.1 .3" size=".02 .02 .02" rgba=".9 .1 .9 1"/>
<site type="ellipsoid" pos="0 .1 .3" size=".02 .03 .04" rgba=".9 .1 .9 1"/>
</body>
</worldbody>
</mujoco>
.. figure:: images/overview/bodygeomsite.png
:width: 200px
:align: right
This model is rendered by the OpenGL visualizer as:
Note the red box. This is an equivalent-inertia box rendering of the body inertial properties, and is generated by
MuJoCo internally. The box is over the geoms but not over the sites. This is because only the geoms were used to
(automatically) infer the inertial properties of the body. If we happen to know the latter, we can of course specify
them directly. But it is often more convenient to let the model compiler infer these body properties from the geoms
attached to it, using the assumption of uniform density (geom density can be specified in the XML; the default is the
density of water).
.. _JointCo:
Joint coordinates
~~~~~~~~~~~~~~~~~
One of the key distinctions between MuJoCo and gaming engines (such as ODE, Bullet, Havoc, PhysX) is that MuJoCo
operates in generalized or joint coordinates, while gaming engines operate in Cartesian coordinates, although Bullet now
supports generalized coordinates. The differences between these two approaches can be summarized as follows:
Joint coordinates:
- Best suited for elaborate kinematic structures such as robots;
- Joints add degrees of freedom among bodies that would be welded together by default;
- Joint constraints are implicit in the representation and cannot be violated;
- The positions and orientations of the simulated bodies are obtained from the generalized coordinates via forward
kinematics, and cannot be manipulated directly (except for root bodies).
Cartesian coordinates:
- Best suited for many bodies that bounce off each other, as in molecular dynamics and box stacking;
- Joints remove degrees of freedom among bodies that would be free-floating by default;
- Joint constraints are enforced numerically and can be violated;
- The positions and orientations of the simulated bodies are represented explicitly and can be manipulated directly,
although this can introduce further joint constraint violations.
Joint coordinates can be particularly confusing when working with free-floating bodies that are part of a model which
also contains kinematic trees. This is clarified below.
.. _Floating:
Floating objects
~~~~~~~~~~~~~~~~
When working in joint coordinates, you cannot simply set the position and orientation of an arbitrary body to whatever
you want. To achieve that effect you would have to implement some form of inverse kinematics, which computes a (not
necessarily unique) set of joint coordinates for which the forward kinematics place the body where you want it to be.
The situation is different for floating bodies, i.e. bodies that are connected to the world with a free joint. The
positions and orientations as well as the linear and angular velocities of such bodies are explicitly represented in
``mjData.qpos`` and ``mjData.qvel``, and can therefore be manipulated directly. The general approach is to find the
addresses in qpos and qvel where the body's data are. Of course qpos and qvel represents joints and not bodies, so you
need the corresponding joint addresses. Suppose the body was named "myfloatingbody" in the XML. The necessary addresses
can be obtained as:
.. code:: C
int bodyid = mj_name2id(m, mjOBJ_BODY, "myfloatingbody");
int qposadr = -1, qveladr = -1;
// make sure we have a floating body: it has a single free joint
if( bodyid>=0 && m->body_jntnum[bodyid]==1 &&
m->jnt_type[m->body_jntadr[bodyid]]==mjJNT_FREE )
{
// extract the addresses from the joint specification
qposadr = m->jnt_qposadr[m->body_jntadr[bodyid]];
qveladr = m->jnt_dofadr[m->body_jntadr[bodyid]];
}
Now if everything went well (i.e. "myfloatingbody" was indeed a floating body), qposadr and qveladr are the addresses in
qpos and qvel where the data for our floating body/joint lives. The position data is 7 numbers (3D position followed by
unit quaternion) while the velocity data is 6 numbers (3D linear velocity followed by 3D angular velocity). These
numbers can now be set to the desired pose and velocity of the body.
+1986
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
sphinx==3.5.4
sphinx_rtd_theme==0.5.2
sphinxcontrib-katex==0.8.6
sphinx-reredirects==0.0.1
nbsphinx==0.8.0
pandoc==1.0.2
pygments==2.7.4
jq==1.1.1
Jinja2==2.11.3
wheel
+21
View File
@@ -0,0 +1,21 @@
{% extends "!layout.html" %}
{% block htmltitle %}
<link rel=“preconnect” href=“https://fonts.googleapis.com“ crossorigin>
<link rel=“preconnect” href=“https://fonts.gstatic.com” crossorigin>
{{ super() }}
{% endblock %}
{% block scripts %}
{{ super() }}
{# Override home link to point to MuJoCo homepage.
Ideally this would be done as part of the theme rather than in JS.
#}
<script>
document.addEventListener('DOMContentLoaded', (event) => {
let home_link = document.querySelector('a.icon');
{# Be extra safe and don't break the page if theme changes and querySelector can't match. #}
if (home_link) {
home_link.href="https://mujoco.org";
}
});
</script>
{% endblock %}
+342
View File
@@ -0,0 +1,342 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MJDATA_H_
#define MUJOCO_MJDATA_H_
//---------------------------- primitive types (mjt) ------------------------------------
typedef enum _mjtWarning // warning types
{
mjWARN_INERTIA = 0, // (near) singular inertia matrix
mjWARN_CONTACTFULL, // too many contacts in contact list
mjWARN_CNSTRFULL, // too many constraints
mjWARN_VGEOMFULL, // too many visual geoms
mjWARN_BADQPOS, // bad number in qpos
mjWARN_BADQVEL, // bad number in qvel
mjWARN_BADQACC, // bad number in qacc
mjWARN_BADCTRL, // bad number in ctrl
mjNWARNING // number of warnings
} mjtWarning;
typedef enum _mjtTimer
{
// main api
mjTIMER_STEP = 0, // step
mjTIMER_FORWARD, // forward
mjTIMER_INVERSE, // inverse
// breakdown of step/forward
mjTIMER_POSITION, // fwdPosition
mjTIMER_VELOCITY, // fwdVelocity
mjTIMER_ACTUATION, // fwdActuation
mjTIMER_ACCELERATION, // fwdAcceleration
mjTIMER_CONSTRAINT, // fwdConstraint
// breakdown of fwdPosition
mjTIMER_POS_KINEMATICS, // kinematics, com, tendon, transmission
mjTIMER_POS_INERTIA, // inertia computations
mjTIMER_POS_COLLISION, // collision detection
mjTIMER_POS_MAKE, // make constraints
mjTIMER_POS_PROJECT, // project constraints
mjNTIMER // number of timers
} mjtTimer;
//------------------------------ mjContact ----------------------------------------------
struct _mjContact // result of collision detection functions
{
// contact parameters set by geom-specific collision detector
mjtNum dist; // distance between nearest points; neg: penetration
mjtNum pos[3]; // position of contact point: midpoint between geoms
mjtNum frame[9]; // normal is in [0-2]
// contact parameters set by mj_collideGeoms
mjtNum includemargin; // include if dist<includemargin=margin-gap
mjtNum friction[5]; // tangent1, 2, spin, roll1, 2
mjtNum solref[mjNREF]; // constraint solver reference
mjtNum solimp[mjNIMP]; // constraint solver impedance
// internal storage used by solver
mjtNum mu; // friction of regularized cone, set by mj_makeConstraint
mjtNum H[36]; // cone Hessian, set by mj_updateConstraint
// contact descriptors set by mj_collideGeoms
int dim; // contact space dimensionality: 1, 3, 4 or 6
int geom1; // id of geom 1
int geom2; // id of geom 2
// flag set by mj_fuseContact or mj_instantianteEquality
int exclude; // 0: include, 1: in gap, 2: fused, 3: equality, 4: no dofs
// address computed by mj_instantiateContact
int efc_address; // address in efc; -1: not included, -2-i: distance constraint i
};
typedef struct _mjContact mjContact;
//------------------------------ diagnostics --------------------------------------------
struct _mjWarningStat // warning statistics
{
int lastinfo; // info from last warning
int number; // how many times was warning raised
};
typedef struct _mjWarningStat mjWarningStat;
struct _mjTimerStat // timer statistics
{
mjtNum duration; // cumulative duration
int number; // how many times was timer called
};
typedef struct _mjTimerStat mjTimerStat;
struct _mjSolverStat // per-iteration solver statistics
{
mjtNum improvement; // cost reduction, scaled by 1/trace(M(qpos0))
mjtNum gradient; // gradient norm (primal only, scaled)
mjtNum lineslope; // slope in linesearch
int nactive; // number of active constraints
int nchange; // number of constraint state changes
int neval; // number of cost evaluations in line search
int nupdate; // number of Cholesky updates in line search
};
typedef struct _mjSolverStat mjSolverStat;
//---------------------------------- mjData ---------------------------------------------
struct _mjData
{
// constant sizes
int nstack; // number of mjtNums that can fit in stack
int nbuffer; // size of main buffer in bytes
// stack pointer
int pstack; // first available mjtNum address in stack
// memory utilization stats
int maxuse_stack; // maximum stack allocation
int maxuse_con; // maximum number of contacts
int maxuse_efc; // maximum number of scalar constraints
// diagnostics
mjWarningStat warning[mjNWARNING]; // warning statistics
mjTimerStat timer[mjNTIMER]; // timer statistics
mjSolverStat solver[mjNSOLVER]; // solver statistics per iteration
int solver_iter; // number of solver iterations
int solver_nnz; // number of non-zeros in Hessian or efc_AR
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
// variable sizes
int ne; // number of equality constraints
int nf; // number of friction constraints
int nefc; // number of constraints
int ncon; // number of detected contacts
// global properties
mjtNum time; // simulation time
mjtNum energy[2]; // potential, kinetic energy
//-------------------------------- end of info header
// buffers
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
mjtNum* stack; // stack buffer (nstack mjtNums)
//-------------------------------- main inputs and outputs of the computation
// state
mjtNum* qpos; // position (nq x 1)
mjtNum* qvel; // velocity (nv x 1)
mjtNum* act; // actuator activation (na x 1)
mjtNum* qacc_warmstart; // acceleration used for warmstart (nv x 1)
// control
mjtNum* ctrl; // control (nu x 1)
mjtNum* qfrc_applied; // applied generalized force (nv x 1)
mjtNum* xfrc_applied; // applied Cartesian force/torque (nbody x 6)
// dynamics
mjtNum* qacc; // acceleration (nv x 1)
mjtNum* act_dot; // time-derivative of actuator activation (na x 1)
// mocap data
mjtNum* mocap_pos; // positions of mocap bodies (nmocap x 3)
mjtNum* mocap_quat; // orientations of mocap bodies (nmocap x 4)
// user data
mjtNum* userdata; // user data, not touched by engine (nuserdata x 1)
// sensors
mjtNum* sensordata; // sensor data array (nsensordata x 1)
//-------------------------------- POSITION dependent
// computed by mj_fwdPosition/mj_kinematics
mjtNum* xpos; // Cartesian position of body frame (nbody x 3)
mjtNum* xquat; // Cartesian orientation of body frame (nbody x 4)
mjtNum* xmat; // Cartesian orientation of body frame (nbody x 9)
mjtNum* xipos; // Cartesian position of body com (nbody x 3)
mjtNum* ximat; // Cartesian orientation of body inertia (nbody x 9)
mjtNum* xanchor; // Cartesian position of joint anchor (njnt x 3)
mjtNum* xaxis; // Cartesian joint axis (njnt x 3)
mjtNum* geom_xpos; // Cartesian geom position (ngeom x 3)
mjtNum* geom_xmat; // Cartesian geom orientation (ngeom x 9)
mjtNum* site_xpos; // Cartesian site position (nsite x 3)
mjtNum* site_xmat; // Cartesian site orientation (nsite x 9)
mjtNum* cam_xpos; // Cartesian camera position (ncam x 3)
mjtNum* cam_xmat; // Cartesian camera orientation (ncam x 9)
mjtNum* light_xpos; // Cartesian light position (nlight x 3)
mjtNum* light_xdir; // Cartesian light direction (nlight x 3)
// computed by mj_fwdPosition/mj_comPos
mjtNum* subtree_com; // center of mass of each subtree (nbody x 3)
mjtNum* cdof; // com-based motion axis of each dof (nv x 6)
mjtNum* cinert; // com-based body inertia and mass (nbody x 10)
// computed by mj_fwdPosition/mj_tendon
int* ten_wrapadr; // start address of tendon's path (ntendon x 1)
int* ten_wrapnum; // number of wrap points in path (ntendon x 1)
int* ten_J_rownnz; // number of non-zeros in Jacobian row (ntendon x 1)
int* ten_J_rowadr; // row start address in colind array (ntendon x 1)
int* ten_J_colind; // column indices in sparse Jacobian (ntendon x nv)
mjtNum* ten_length; // tendon lengths (ntendon x 1)
mjtNum* ten_J; // tendon Jacobian (ntendon x nv)
int* wrap_obj; // geom id; -1: site; -2: pulley (nwrap*2 x 1)
mjtNum* wrap_xpos; // Cartesian 3D points in all path (nwrap*2 x 3)
// computed by mj_fwdPosition/mj_transmission
mjtNum* actuator_length; // actuator lengths (nu x 1)
mjtNum* actuator_moment; // actuator moments (nu x nv)
// computed by mj_fwdPosition/mj_crb
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
mjtNum* qM; // total inertia (nM x 1)
// computed by mj_fwdPosition/mj_factorM
mjtNum* qLD; // L'*D*L factorization of M (nM x 1)
mjtNum* qLDiagInv; // 1/diag(D) (nv x 1)
mjtNum* qLDiagSqrtInv; // 1/sqrt(diag(D)) (nv x 1)
// computed by mj_fwdPosition/mj_collision
mjContact* contact; // list of all detected contacts (nconmax x 1)
// computed by mj_fwdPosition/mj_makeConstraint
int* efc_type; // constraint type (mjtConstraint) (njmax x 1)
int* efc_id; // id of object of specified type (njmax x 1)
int* efc_J_rownnz; // number of non-zeros in Jacobian row (njmax x 1)
int* efc_J_rowadr; // row start address in colind array (njmax x 1)
int* efc_J_rowsuper; // number of subsequent rows in supernode (njmax x 1)
int* efc_J_colind; // column indices in Jacobian (njmax x nv)
int* efc_JT_rownnz; // number of non-zeros in Jacobian row T (nv x 1)
int* efc_JT_rowadr; // row start address in colind array T (nv x 1)
int* efc_JT_rowsuper; // number of subsequent rows in supernode T (nv x 1)
int* efc_JT_colind; // column indices in Jacobian T (nv x njmax)
mjtNum* efc_J; // constraint Jacobian (njmax x nv)
mjtNum* efc_JT; // constraint Jacobian transposed (nv x njmax)
mjtNum* efc_pos; // constraint position (equality, contact) (njmax x 1)
mjtNum* efc_margin; // inclusion margin (contact) (njmax x 1)
mjtNum* efc_frictionloss; // frictionloss (friction) (njmax x 1)
mjtNum* efc_diagApprox; // approximation to diagonal of A (njmax x 1)
mjtNum* efc_KBIP; // stiffness, damping, impedance, imp' (njmax x 4)
mjtNum* efc_D; // constraint mass (njmax x 1)
mjtNum* efc_R; // inverse constraint mass (njmax x 1)
// computed by mj_fwdPosition/mj_projectConstraint
int* efc_AR_rownnz; // number of non-zeros in AR (njmax x 1)
int* efc_AR_rowadr; // row start address in colind array (njmax x 1)
int* efc_AR_colind; // column indices in sparse AR (njmax x njmax)
mjtNum* efc_AR; // J*inv(M)*J' + R (njmax x njmax)
//-------------------------------- POSITION, VELOCITY dependent
// computed by mj_fwdVelocity
mjtNum* ten_velocity; // tendon velocities (ntendon x 1)
mjtNum* actuator_velocity; // actuator velocities (nu x 1)
// computed by mj_fwdVelocity/mj_comVel
mjtNum* cvel; // com-based velocity [3D rot; 3D tran] (nbody x 6)
mjtNum* cdof_dot; // time-derivative of cdof (nv x 6)
// computed by mj_fwdVelocity/mj_rne (without acceleration)
mjtNum* qfrc_bias; // C(qpos,qvel) (nv x 1)
// computed by mj_fwdVelocity/mj_passive
mjtNum* qfrc_passive; // passive force (nv x 1)
// computed by mj_fwdVelocity/mj_referenceConstraint
mjtNum* efc_vel; // velocity in constraint space: J*qvel (njmax x 1)
mjtNum* efc_aref; // reference pseudo-acceleration (njmax x 1)
// computed by mj_sensorVel/mj_subtreeVel if needed
mjtNum* subtree_linvel; // linear velocity of subtree com (nbody x 3)
mjtNum* subtree_angmom; // angular momentum about subtree com (nbody x 3)
//-------------------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
// computed by mj_fwdActuation
mjtNum* actuator_force; // actuator force in actuation space (nu x 1)
mjtNum* qfrc_actuator; // actuator force (nv x 1)
// computed by mj_fwdAcceleration
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
// computed by mj_fwdConstraint/mj_inverse
mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1)
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
mjtNum* qfrc_constraint; // constraint force (nv x 1)
// computed by mj_inverse
mjtNum* qfrc_inverse; // net external force; should equal: (nv x 1)
// qfrc_applied + J'*xfrc_applied + qfrc_actuator
// computed by mj_sensorAcc/mj_rnePostConstraint if needed; rotation:translation format
mjtNum* cacc; // com-based acceleration (nbody x 6)
mjtNum* cfrc_int; // com-based interaction force with parent (nbody x 6)
mjtNum* cfrc_ext; // com-based external force on body (nbody x 6)
};
typedef struct _mjData mjData;
//---------------------------------- callback function types ----------------------------
// generic MuJoCo function
typedef void (*mjfGeneric)(const mjModel* m, mjData* d);
// contact filter: 1- discard, 0- collide
typedef int (*mjfConFilt)(const mjModel* m, mjData* d, int geom1, int geom2);
// sensor simulation
typedef void (*mjfSensor)(const mjModel* m, mjData* d, int stage);
// timer
typedef mjtNum (*mjfTime)(void);
// actuator dynamics, gain, bias
typedef mjtNum (*mjfAct)(const mjModel* m, const mjData* d, int id);
// collision detection
typedef int (*mjfCollision)(const mjModel* m, const mjData* d,
mjContact* con, int g1, int g2, mjtNum margin);
#endif // MUJOCO_MJDATA_H_
+957
View File
@@ -0,0 +1,957 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MJMODEL_H_
#define MUJOCO_MJMODEL_H_
//---------------------------- floating-point definitions -------------------------------
// compile-time configuration options
#define mjUSEDOUBLE // single or double precision for mjtNum
#define mjUSEAVX // C or AVX intrinsics for custom BLAS
// floating point data type and minval
#ifdef mjUSEDOUBLE
typedef double mjtNum;
#define mjMINVAL 1E-15 // minimum value in any denominator
#else
typedef float mjtNum;
#define mjMINVAL 1E-15f
#endif
// global constants
#define mjPI 3.14159265358979323846
#define mjMAXVAL 1E+10 // maximum value in qpos, qvel, qacc
#define mjMINMU 1E-5 // minimum friction coefficient
#define mjMINIMP 0.0001 // minimum constraint impedance
#define mjMAXIMP 0.9999 // maximum constraint impedance
#define mjMAXCONPAIR 50 // maximum number of contacts per geom pair
#define mjMAXVFS 2000 // maximum number of files in virtual file system
#define mjMAXVFSNAME 1000 // maximum filename size in virtual file system
//---------------------------- sizes ----------------------------------------------------
#define mjNEQDATA 7 // number of eq_data fields
#define mjNDYN 10 // number of actuator dynamics parameters
#define mjNGAIN 10 // number of actuator gain parameters
#define mjNBIAS 10 // number of actuator bias parameters
#define mjNREF 2 // number of solver reference parameters
#define mjNIMP 5 // number of solver impedance parameters
#define mjNSOLVER 1000 // size of mjData.solver_XXX arrays
//---------------------------- primitive types (mjt) ------------------------------------
typedef unsigned char mjtByte; // used for true/false
typedef enum _mjtDisableBit // disable default feature bitflags
{
mjDSBL_CONSTRAINT = 1<<0, // entire constraint solver
mjDSBL_EQUALITY = 1<<1, // equality constraints
mjDSBL_FRICTIONLOSS = 1<<2, // joint and tendon frictionloss constraints
mjDSBL_LIMIT = 1<<3, // joint and tendon limit constraints
mjDSBL_CONTACT = 1<<4, // contact constraints
mjDSBL_PASSIVE = 1<<5, // passive forces
mjDSBL_GRAVITY = 1<<6, // gravitational forces
mjDSBL_CLAMPCTRL = 1<<7, // clamp control to specified range
mjDSBL_WARMSTART = 1<<8, // warmstart constraint solver
mjDSBL_FILTERPARENT = 1<<9, // remove collisions with parent body
mjDSBL_ACTUATION = 1<<10, // apply actuation forces
mjDSBL_REFSAFE = 1<<11, // integrator safety: make ref[0]>=2*timestep
mjNDISABLE = 12 // number of disable flags
} mjtDisableBit;
typedef enum _mjtEnableBit // enable optional feature bitflags
{
mjENBL_OVERRIDE = 1<<0, // override contact parameters
mjENBL_ENERGY = 1<<1, // energy computation
mjENBL_FWDINV = 1<<2, // record solver statistics
mjENBL_SENSORNOISE = 1<<3, // add noise to sensor data
mjNENABLE = 4 // number of enable flags
} mjtEnableBit;
typedef enum _mjtJoint // type of degree of freedom
{
mjJNT_FREE = 0, // global position and orientation (quat) (7)
mjJNT_BALL, // orientation (quat) relative to parent (4)
mjJNT_SLIDE, // sliding distance along body-fixed axis (1)
mjJNT_HINGE // rotation angle (rad) around body-fixed axis (1)
} mjtJoint;
typedef enum _mjtGeom // type of geometric shape
{
// regular geom types
mjGEOM_PLANE = 0, // plane
mjGEOM_HFIELD, // height field
mjGEOM_SPHERE, // sphere
mjGEOM_CAPSULE, // capsule
mjGEOM_ELLIPSOID, // ellipsoid
mjGEOM_CYLINDER, // cylinder
mjGEOM_BOX, // box
mjGEOM_MESH, // mesh
mjNGEOMTYPES, // number of regular geom types
// rendering-only geom types: not used in mjModel, not counted in mjNGEOMTYPES
mjGEOM_ARROW = 100, // arrow
mjGEOM_ARROW1, // arrow without wedges
mjGEOM_ARROW2, // arrow in both directions
mjGEOM_LINE, // line
mjGEOM_SKIN, // skin
mjGEOM_LABEL, // text label
mjGEOM_NONE = 1001 // missing geom type
} mjtGeom;
typedef enum _mjtCamLight // tracking mode for camera and light
{
mjCAMLIGHT_FIXED = 0, // pos and rot fixed in body
mjCAMLIGHT_TRACK, // pos tracks body, rot fixed in global
mjCAMLIGHT_TRACKCOM, // pos tracks subtree com, rot fixed in body
mjCAMLIGHT_TARGETBODY, // pos fixed in body, rot tracks target body
mjCAMLIGHT_TARGETBODYCOM // pos fixed in body, rot tracks target subtree com
} mjtCamLight;
typedef enum _mjtTexture // type of texture
{
mjTEXTURE_2D = 0, // 2d texture, suitable for planes and hfields
mjTEXTURE_CUBE, // cube texture, suitable for all other geom types
mjTEXTURE_SKYBOX // cube texture used as skybox
} mjtTexture;
typedef enum _mjtIntegrator // integrator mode
{
mjINT_EULER = 0, // semi-implicit Euler
mjINT_RK4 // 4th-order Runge Kutta
} mjtIntegrator;
typedef enum _mjtCollision // collision mode for selecting geom pairs
{
mjCOL_ALL = 0, // test precomputed and dynamic pairs
mjCOL_PAIR, // test predefined pairs only
mjCOL_DYNAMIC // test dynamic pairs only
} mjtCollision;
typedef enum _mjtCone // type of friction cone
{
mjCONE_PYRAMIDAL = 0, // pyramidal
mjCONE_ELLIPTIC // elliptic
} mjtCone;
typedef enum _mjtJacobian // type of constraint Jacobian
{
mjJAC_DENSE = 0, // dense
mjJAC_SPARSE, // sparse
mjJAC_AUTO // dense if nv<60, sparse otherwise
} mjtJacobian;
typedef enum _mjtSolver // constraint solver algorithm
{
mjSOL_PGS = 0, // PGS (dual)
mjSOL_CG, // CG (primal)
mjSOL_NEWTON // Newton (primal)
} mjtSolver;
typedef enum _mjtEq // type of equality constraint
{
mjEQ_CONNECT = 0, // connect two bodies at a point (ball joint)
mjEQ_WELD, // fix relative position and orientation of two bodies
mjEQ_JOINT, // couple the values of two scalar joints with cubic
mjEQ_TENDON, // couple the lengths of two tendons with cubic
mjEQ_DISTANCE // fix the contact distance betweent two geoms
} mjtEq;
typedef enum _mjtWrap // type of tendon wrap object
{
mjWRAP_NONE = 0, // null object
mjWRAP_JOINT, // constant moment arm
mjWRAP_PULLEY, // pulley used to split tendon
mjWRAP_SITE, // pass through site
mjWRAP_SPHERE, // wrap around sphere
mjWRAP_CYLINDER // wrap around (infinite) cylinder
} mjtWrap;
typedef enum _mjtTrn // type of actuator transmission
{
mjTRN_JOINT = 0, // force on joint
mjTRN_JOINTINPARENT, // force on joint, expressed in parent frame
mjTRN_SLIDERCRANK, // force via slider-crank linkage
mjTRN_TENDON, // force on tendon
mjTRN_SITE, // force on site
mjTRN_UNDEFINED = 1000 // undefined transmission type
} mjtTrn;
typedef enum _mjtDyn // type of actuator dynamics
{
mjDYN_NONE = 0, // no internal dynamics; ctrl specifies force
mjDYN_INTEGRATOR, // integrator: da/dt = u
mjDYN_FILTER, // linear filter: da/dt = (u-a) / tau
mjDYN_MUSCLE, // piece-wise linear filter with two time constants
mjDYN_USER // user-defined dynamics type
} mjtDyn;
typedef enum _mjtGain // type of actuator gain
{
mjGAIN_FIXED = 0, // fixed gain
mjGAIN_MUSCLE, // muscle FLV curve computed by mju_muscleGain()
mjGAIN_USER // user-defined gain type
} mjtGain;
typedef enum _mjtBias // type of actuator bias
{
mjBIAS_NONE = 0, // no bias
mjBIAS_AFFINE, // const + kp*length + kv*velocity
mjBIAS_MUSCLE, // muscle passive force computed by mju_muscleBias()
mjBIAS_USER // user-defined bias type
} mjtBias;
typedef enum _mjtObj // type of MujoCo object
{
mjOBJ_UNKNOWN = 0, // unknown object type
mjOBJ_BODY, // body
mjOBJ_XBODY, // body, used to access regular frame instead of i-frame
mjOBJ_JOINT, // joint
mjOBJ_DOF, // dof
mjOBJ_GEOM, // geom
mjOBJ_SITE, // site
mjOBJ_CAMERA, // camera
mjOBJ_LIGHT, // light
mjOBJ_MESH, // mesh
mjOBJ_SKIN, // skin
mjOBJ_HFIELD, // heightfield
mjOBJ_TEXTURE, // texture
mjOBJ_MATERIAL, // material for rendering
mjOBJ_PAIR, // geom pair to include
mjOBJ_EXCLUDE, // body pair to exclude
mjOBJ_EQUALITY, // equality constraint
mjOBJ_TENDON, // tendon
mjOBJ_ACTUATOR, // actuator
mjOBJ_SENSOR, // sensor
mjOBJ_NUMERIC, // numeric
mjOBJ_TEXT, // text
mjOBJ_TUPLE, // tuple
mjOBJ_KEY // keyframe
} mjtObj;
typedef enum _mjtConstraint // type of constraint
{
mjCNSTR_EQUALITY = 0, // equality constraint
mjCNSTR_FRICTION_DOF, // dof friction
mjCNSTR_FRICTION_TENDON, // tendon friction
mjCNSTR_LIMIT_JOINT, // joint limit
mjCNSTR_LIMIT_TENDON, // tendon limit
mjCNSTR_CONTACT_FRICTIONLESS, // frictionless contact
mjCNSTR_CONTACT_PYRAMIDAL, // frictional contact, pyramidal friction cone
mjCNSTR_CONTACT_ELLIPTIC // frictional contact, elliptic friction cone
} mjtConstraint;
typedef enum _mjtConstraintState // constraint state
{
mjCNSTRSTATE_SATISFIED = 0, // constraint satisfied, zero cost (limit, contact)
mjCNSTRSTATE_QUADRATIC, // quadratic cost (equality, friction, limit, contact)
mjCNSTRSTATE_LINEARNEG, // linear cost, negative side (friction)
mjCNSTRSTATE_LINEARPOS, // linear cost, positive side (friction)
mjCNSTRSTATE_CONE // squared distance to cone cost (elliptic contact)
} mjtConstraintState;
typedef enum _mjtSensor // type of sensor
{
// common robotic sensors, attached to a site
mjSENS_TOUCH = 0, // scalar contact normal forces summed over sensor zone
mjSENS_ACCELEROMETER, // 3D linear acceleration, in local frame
mjSENS_VELOCIMETER, // 3D linear velocity, in local frame
mjSENS_GYRO, // 3D angular velocity, in local frame
mjSENS_FORCE, // 3D force between site's body and its parent body
mjSENS_TORQUE, // 3D torque between site's body and its parent body
mjSENS_MAGNETOMETER, // 3D magnetometer
mjSENS_RANGEFINDER, // scalar distance to nearest geom or site along z-axis
// sensors related to scalar joints, tendons, actuators
mjSENS_JOINTPOS, // scalar joint position (hinge and slide only)
mjSENS_JOINTVEL, // scalar joint velocity (hinge and slide only)
mjSENS_TENDONPOS, // scalar tendon position
mjSENS_TENDONVEL, // scalar tendon velocity
mjSENS_ACTUATORPOS, // scalar actuator position
mjSENS_ACTUATORVEL, // scalar actuator velocity
mjSENS_ACTUATORFRC, // scalar actuator force
// sensors related to ball joints
mjSENS_BALLQUAT, // 4D ball joint quaterion
mjSENS_BALLANGVEL, // 3D ball joint angular velocity
// joint and tendon limit sensors, in constraint space
mjSENS_JOINTLIMITPOS, // joint limit distance-margin
mjSENS_JOINTLIMITVEL, // joint limit velocity
mjSENS_JOINTLIMITFRC, // joint limit force
mjSENS_TENDONLIMITPOS, // tendon limit distance-margin
mjSENS_TENDONLIMITVEL, // tendon limit velocity
mjSENS_TENDONLIMITFRC, // tendon limit force
// sensors attached to an object with spatial frame: (x)body, geom, site, camera
mjSENS_FRAMEPOS, // 3D position
mjSENS_FRAMEQUAT, // 4D unit quaternion orientation
mjSENS_FRAMEXAXIS, // 3D unit vector: x-axis of object's frame
mjSENS_FRAMEYAXIS, // 3D unit vector: y-axis of object's frame
mjSENS_FRAMEZAXIS, // 3D unit vector: z-axis of object's frame
mjSENS_FRAMELINVEL, // 3D linear velocity
mjSENS_FRAMEANGVEL, // 3D angular velocity
mjSENS_FRAMELINACC, // 3D linear acceleration
mjSENS_FRAMEANGACC, // 3D angular acceleration
// sensors related to kinematic subtrees; attached to a body (which is the subtree root)
mjSENS_SUBTREECOM, // 3D center of mass of subtree
mjSENS_SUBTREELINVEL, // 3D linear velocity of subtree
mjSENS_SUBTREEANGMOM, // 3D angular momentum of subtree
// user-defined sensor
mjSENS_USER // sensor data provided by mjcb_sensor callback
} mjtSensor;
typedef enum _mjtStage // computation stage
{
mjSTAGE_NONE = 0, // no computations
mjSTAGE_POS, // position-dependent computations
mjSTAGE_VEL, // velocity-dependent computations
mjSTAGE_ACC // acceleration/force-dependent computations
} mjtStage;
typedef enum _mjtDataType // data type for sensors
{
mjDATATYPE_REAL = 0, // real values, no constraints
mjDATATYPE_POSITIVE, // positive values; 0 or negative: inactive
mjDATATYPE_AXIS, // 3D unit vector
mjDATATYPE_QUATERNION // unit quaternion
} mjtDataType;
typedef enum _mjtLRMode // mode for actuator length range computation
{
mjLRMODE_NONE = 0, // do not process any actuators
mjLRMODE_MUSCLE, // process muscle actuators
mjLRMODE_MUSCLEUSER, // process muscle and user actuators
mjLRMODE_ALL // process all actuators
} mjtLRMode;
//------------------------------ mjLROpt ------------------------------------------------
struct _mjLROpt // options for mj_setLengthRange()
{
// flags
int mode; // which actuators to process (mjtLRMode)
int useexisting; // use existing length range if available
int uselimit; // use joint and tendon limits if available
// algorithm parameters
mjtNum accel; // target acceleration used to compute force
mjtNum maxforce; // maximum force; 0: no limit
mjtNum timeconst; // time constant for velocity reduction; min 0.01
mjtNum timestep; // simulation timestep; 0: use mjOption.timestep
mjtNum inttotal; // total simulation time interval
mjtNum inteval; // evaluation time interval (at the end)
mjtNum tolrange; // convergence tolerance (relative to range)
};
typedef struct _mjLROpt mjLROpt;
//------------------------------ mjVFS --------------------------------------------------
struct _mjVFS // virtual file system for loading from memory
{
int nfile; // number of files present
char filename[mjMAXVFS][mjMAXVFSNAME]; // file name without path
int filesize[mjMAXVFS]; // file size in bytes
void* filedata[mjMAXVFS]; // buffer with file data
};
typedef struct _mjVFS mjVFS;
//------------------------------ mjOption -----------------------------------------------
struct _mjOption // physics options
{
// timing parameters
mjtNum timestep; // timestep
mjtNum apirate; // update rate for remote API (Hz)
// solver parameters
mjtNum impratio; // ratio of friction-to-normal contact impedance
mjtNum tolerance; // main solver tolerance
mjtNum noslip_tolerance; // noslip solver tolerance
mjtNum mpr_tolerance; // MPR solver tolerance
// physical constants
mjtNum gravity[3]; // gravitational acceleration
mjtNum wind[3]; // wind (for lift, drag and viscosity)
mjtNum magnetic[3]; // global magnetic flux
mjtNum density; // density of medium
mjtNum viscosity; // viscosity of medium
// override contact solver parameters (if enabled)
mjtNum o_margin; // margin
mjtNum o_solref[mjNREF]; // solref
mjtNum o_solimp[mjNIMP]; // solimp
// discrete settings
int integrator; // integration mode (mjtIntegrator)
int collision; // collision mode (mjtCollision)
int cone; // type of friction cone (mjtCone)
int jacobian; // type of Jacobian (mjtJacobian)
int solver; // solver algorithm (mjtSolver)
int iterations; // maximum number of main solver iterations
int noslip_iterations; // maximum number of noslip solver iterations
int mpr_iterations; // maximum number of MPR solver iterations
int disableflags; // bit flags for disabling standard features
int enableflags; // bit flags for enabling optional features
};
typedef struct _mjOption mjOption;
//------------------------------ mjVisual -----------------------------------------------
struct _mjVisual // visualization options
{
struct // global parameters
{
float fovy; // y-field of view (deg) for free camera
float ipd; // inter-pupilary distance for free camera
float linewidth; // line width for wireframe and ray rendering
float glow; // glow coefficient for selected body
int offwidth; // width of offscreen buffer
int offheight; // height of offscreen buffer
} global;
struct // rendering quality
{
int shadowsize; // size of shadowmap texture
int offsamples; // number of multisamples for offscreen rendering
int numslices; // number of slices for builtin geom drawing
int numstacks; // number of stacks for builtin geom drawing
int numquads; // number of quads for box rendering
} quality;
struct // head light
{
float ambient[3]; // ambient rgb (alpha=1)
float diffuse[3]; // diffuse rgb (alpha=1)
float specular[3]; // specular rgb (alpha=1)
int active; // is headlight active
} headlight;
struct // mapping
{
float stiffness; // mouse perturbation stiffness (space->force)
float stiffnessrot; // mouse perturbation stiffness (space->torque)
float force; // from force units to space units
float torque; // from torque units to space units
float alpha; // scale geom alphas when transparency is enabled
float fogstart; // OpenGL fog starts at fogstart * mjModel.stat.extent
float fogend; // OpenGL fog ends at fogend * mjModel.stat.extent
float znear; // near clipping plane = znear * mjModel.stat.extent
float zfar; // far clipping plane = zfar * mjModel.stat.extent
float haze; // haze ratio
float shadowclip; // directional light: shadowclip * mjModel.stat.extent
float shadowscale; // spot light: shadowscale * light.cutoff
float actuatortendon; // scale tendon width
} map;
struct // scale of decor elements relative to mean body size
{
float forcewidth; // width of force arrow
float contactwidth; // contact width
float contactheight; // contact height
float connect; // autoconnect capsule width
float com; // com radius
float camera; // camera object
float light; // light object
float selectpoint; // selection point
float jointlength; // joint length
float jointwidth; // joint width
float actuatorlength; // actuator length
float actuatorwidth; // actuator width
float framelength; // bodyframe axis length
float framewidth; // bodyframe axis width
float constraint; // constraint width
float slidercrank; // slidercrank width
} scale;
struct // color of decor elements
{
float fog[4]; // fog
float haze[4]; // haze
float force[4]; // external force
float inertia[4]; // inertia box
float joint[4]; // joint
float actuator[4]; // actuator, neutral
float actuatornegative[4]; // actuator, negative limit
float actuatorpositive[4]; // actuator, positive limit
float com[4]; // center of mass
float camera[4]; // camera object
float light[4]; // light object
float selectpoint[4]; // selection point
float connect[4]; // auto connect
float contactpoint[4]; // contact point
float contactforce[4]; // contact force
float contactfriction[4]; // contact friction force
float contacttorque[4]; // contact torque
float contactgap[4]; // contact point in gap
float rangefinder[4]; // rangefinder ray
float constraint[4]; // constraint
float slidercrank[4]; // slidercrank
float crankbroken[4]; // used when crank must be stretched/broken
} rgba;
};
typedef struct _mjVisual mjVisual;
//------------------------------ mjStatistic --------------------------------------------
struct _mjStatistic // model statistics (in qpos0)
{
mjtNum meaninertia; // mean diagonal inertia
mjtNum meanmass; // mean body mass
mjtNum meansize; // mean body size
mjtNum extent; // spatial extent
mjtNum center[3]; // center of model
};
typedef struct _mjStatistic mjStatistic;
//---------------------------------- mjModel --------------------------------------------
struct _mjModel
{
// ------------------------------- sizes
// sizes needed at mjModel construction
int nq; // number of generalized coordinates = dim(qpos)
int nv; // number of degrees of freedom = dim(qvel)
int nu; // number of actuators/controls = dim(ctrl)
int na; // number of activation states = dim(act)
int nbody; // number of bodies
int njnt; // number of joints
int ngeom; // number of geoms
int nsite; // number of sites
int ncam; // number of cameras
int nlight; // number of lights
int nmesh; // number of meshes
int nmeshvert; // number of vertices in all meshes
int nmeshtexvert; // number of vertices with texcoords in all meshes
int nmeshface; // number of triangular faces in all meshes
int nmeshgraph; // number of ints in mesh auxiliary data
int nskin; // number of skins
int nskinvert; // number of vertices in all skins
int nskintexvert; // number of vertiex with texcoords in all skins
int nskinface; // number of triangular faces in all skins
int nskinbone; // number of bones in all skins
int nskinbonevert; // number of vertices in all skin bones
int nhfield; // number of heightfields
int nhfielddata; // number of data points in all heightfields
int ntex; // number of textures
int ntexdata; // number of bytes in texture rgb data
int nmat; // number of materials
int npair; // number of predefined geom pairs
int nexclude; // number of excluded geom pairs
int neq; // number of equality constraints
int ntendon; // number of tendons
int nwrap; // number of wrap objects in all tendon paths
int nsensor; // number of sensors
int nnumeric; // number of numeric custom fields
int nnumericdata; // number of mjtNums in all numeric fields
int ntext; // number of text custom fields
int ntextdata; // number of mjtBytes in all text fields
int ntuple; // number of tuple custom fields
int ntupledata; // number of objects in all tuple fields
int nkey; // number of keyframes
int nmocap; // number of mocap bodies
int nuser_body; // number of mjtNums in body_user
int nuser_jnt; // number of mjtNums in jnt_user
int nuser_geom; // number of mjtNums in geom_user
int nuser_site; // number of mjtNums in site_user
int nuser_cam; // number of mjtNums in cam_user
int nuser_tendon; // number of mjtNums in tendon_user
int nuser_actuator; // number of mjtNums in actuator_user
int nuser_sensor; // number of mjtNums in sensor_user
int nnames; // number of chars in all names
// sizes set after mjModel construction (only affect mjData)
int nM; // number of non-zeros in sparse inertia matrix
int nemax; // number of potential equality-constraint rows
int njmax; // number of available rows in constraint Jacobian
int nconmax; // number of potential contacts in contact list
int nstack; // number of fields in mjData stack
int nuserdata; // number of extra fields in mjData
int nsensordata; // number of fields in sensor data vector
int nbuffer; // number of bytes in buffer
// ------------------------------- options and statistics
mjOption opt; // physics options
mjVisual vis; // visualization options
mjStatistic stat; // model statistics
// ------------------------------- buffers
// main buffer
void* buffer; // main buffer; all pointers point in it (nbuffer)
// default generalized coordinates
mjtNum* qpos0; // qpos values at default pose (nq x 1)
mjtNum* qpos_spring; // reference pose for springs (nq x 1)
// bodies
int* body_parentid; // id of body's parent (nbody x 1)
int* body_rootid; // id of root above body (nbody x 1)
int* body_weldid; // id of body that this body is welded to (nbody x 1)
int* body_mocapid; // id of mocap data; -1: none (nbody x 1)
int* body_jntnum; // number of joints for this body (nbody x 1)
int* body_jntadr; // start addr of joints; -1: no joints (nbody x 1)
int* body_dofnum; // number of motion degrees of freedom (nbody x 1)
int* body_dofadr; // start addr of dofs; -1: no dofs (nbody x 1)
int* body_geomnum; // number of geoms (nbody x 1)
int* body_geomadr; // start addr of geoms; -1: no geoms (nbody x 1)
mjtByte* body_simple; // body is simple (has diagonal M) (nbody x 1)
mjtByte* body_sameframe; // inertial frame is same as body frame (nbody x 1)
mjtNum* body_pos; // position offset rel. to parent body (nbody x 3)
mjtNum* body_quat; // orientation offset rel. to parent body (nbody x 4)
mjtNum* body_ipos; // local position of center of mass (nbody x 3)
mjtNum* body_iquat; // local orientation of inertia ellipsoid (nbody x 4)
mjtNum* body_mass; // mass (nbody x 1)
mjtNum* body_subtreemass; // mass of subtree starting at this body (nbody x 1)
mjtNum* body_inertia; // diagonal inertia in ipos/iquat frame (nbody x 3)
mjtNum* body_invweight0; // mean inv inert in qpos0 (trn, rot) (nbody x 2)
mjtNum* body_user; // user data (nbody x nuser_body)
// joints
int* jnt_type; // type of joint (mjtJoint) (njnt x 1)
int* jnt_qposadr; // start addr in 'qpos' for joint's data (njnt x 1)
int* jnt_dofadr; // start addr in 'qvel' for joint's data (njnt x 1)
int* jnt_bodyid; // id of joint's body (njnt x 1)
int* jnt_group; // group for visibility (njnt x 1)
mjtByte* jnt_limited; // does joint have limits (njnt x 1)
mjtNum* jnt_solref; // constraint solver reference: limit (njnt x mjNREF)
mjtNum* jnt_solimp; // constraint solver impedance: limit (njnt x mjNIMP)
mjtNum* jnt_pos; // local anchor position (njnt x 3)
mjtNum* jnt_axis; // local joint axis (njnt x 3)
mjtNum* jnt_stiffness; // stiffness coefficient (njnt x 1)
mjtNum* jnt_range; // joint limits (njnt x 2)
mjtNum* jnt_margin; // min distance for limit detection (njnt x 1)
mjtNum* jnt_user; // user data (njnt x nuser_jnt)
// dofs
int* dof_bodyid; // id of dof's body (nv x 1)
int* dof_jntid; // id of dof's joint (nv x 1)
int* dof_parentid; // id of dof's parent; -1: none (nv x 1)
int* dof_Madr; // dof address in M-diagonal (nv x 1)
int* dof_simplenum; // number of consecutive simple dofs (nv x 1)
mjtNum* dof_solref; // constraint solver reference:frictionloss (nv x mjNREF)
mjtNum* dof_solimp; // constraint solver impedance:frictionloss (nv x mjNIMP)
mjtNum* dof_frictionloss; // dof friction loss (nv x 1)
mjtNum* dof_armature; // dof armature inertia/mass (nv x 1)
mjtNum* dof_damping; // damping coefficient (nv x 1)
mjtNum* dof_invweight0; // diag. inverse inertia in qpos0 (nv x 1)
mjtNum* dof_M0; // diag. inertia in qpos0 (nv x 1)
// geoms
int* geom_type; // geometric type (mjtGeom) (ngeom x 1)
int* geom_contype; // geom contact type (ngeom x 1)
int* geom_conaffinity; // geom contact affinity (ngeom x 1)
int* geom_condim; // contact dimensionality (1, 3, 4, 6) (ngeom x 1)
int* geom_bodyid; // id of geom's body (ngeom x 1)
int* geom_dataid; // id of geom's mesh/hfield (-1: none) (ngeom x 1)
int* geom_matid; // material id for rendering (ngeom x 1)
int* geom_group; // group for visibility (ngeom x 1)
int* geom_priority; // geom contact priority (ngeom x 1)
mjtByte* geom_sameframe; // same as body frame (1) or iframe (2) (ngeom x 1)
mjtNum* geom_solmix; // mixing coef for solref/imp in geom pair (ngeom x 1)
mjtNum* geom_solref; // constraint solver reference: contact (ngeom x mjNREF)
mjtNum* geom_solimp; // constraint solver impedance: contact (ngeom x mjNIMP)
mjtNum* geom_size; // geom-specific size parameters (ngeom x 3)
mjtNum* geom_rbound; // radius of bounding sphere (ngeom x 1)
mjtNum* geom_pos; // local position offset rel. to body (ngeom x 3)
mjtNum* geom_quat; // local orientation offset rel. to body (ngeom x 4)
mjtNum* geom_friction; // friction for (slide, spin, roll) (ngeom x 3)
mjtNum* geom_margin; // detect contact if dist<margin (ngeom x 1)
mjtNum* geom_gap; // include in solver if dist<margin-gap (ngeom x 1)
mjtNum* geom_user; // user data (ngeom x nuser_geom)
float* geom_rgba; // rgba when material is omitted (ngeom x 4)
// sites
int* site_type; // geom type for rendering (mjtGeom) (nsite x 1)
int* site_bodyid; // id of site's body (nsite x 1)
int* site_matid; // material id for rendering (nsite x 1)
int* site_group; // group for visibility (nsite x 1)
mjtByte* site_sameframe; // same as body frame (1) or iframe (2) (nsite x 1)
mjtNum* site_size; // geom size for rendering (nsite x 3)
mjtNum* site_pos; // local position offset rel. to body (nsite x 3)
mjtNum* site_quat; // local orientation offset rel. to body (nsite x 4)
mjtNum* site_user; // user data (nsite x nuser_site)
float* site_rgba; // rgba when material is omitted (nsite x 4)
// cameras
int* cam_mode; // camera tracking mode (mjtCamLight) (ncam x 1)
int* cam_bodyid; // id of camera's body (ncam x 1)
int* cam_targetbodyid; // id of targeted body; -1: none (ncam x 1)
mjtNum* cam_pos; // position rel. to body frame (ncam x 3)
mjtNum* cam_quat; // orientation rel. to body frame (ncam x 4)
mjtNum* cam_poscom0; // global position rel. to sub-com in qpos0 (ncam x 3)
mjtNum* cam_pos0; // global position rel. to body in qpos0 (ncam x 3)
mjtNum* cam_mat0; // global orientation in qpos0 (ncam x 9)
mjtNum* cam_fovy; // y-field of view (deg) (ncam x 1)
mjtNum* cam_ipd; // inter-pupilary distance (ncam x 1)
mjtNum* cam_user; // user data (ncam x nuser_cam)
// lights
int* light_mode; // light tracking mode (mjtCamLight) (nlight x 1)
int* light_bodyid; // id of light's body (nlight x 1)
int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1)
mjtByte* light_directional; // directional light (nlight x 1)
mjtByte* light_castshadow; // does light cast shadows (nlight x 1)
mjtByte* light_active; // is light on (nlight x 1)
mjtNum* light_pos; // position rel. to body frame (nlight x 3)
mjtNum* light_dir; // direction rel. to body frame (nlight x 3)
mjtNum* light_poscom0; // global position rel. to sub-com in qpos0 (nlight x 3)
mjtNum* light_pos0; // global position rel. to body in qpos0 (nlight x 3)
mjtNum* light_dir0; // global direction in qpos0 (nlight x 3)
float* light_attenuation; // OpenGL attenuation (quadratic model) (nlight x 3)
float* light_cutoff; // OpenGL cutoff (nlight x 1)
float* light_exponent; // OpenGL exponent (nlight x 1)
float* light_ambient; // ambient rgb (alpha=1) (nlight x 3)
float* light_diffuse; // diffuse rgb (alpha=1) (nlight x 3)
float* light_specular; // specular rgb (alpha=1) (nlight x 3)
// meshes
int* mesh_vertadr; // first vertex address (nmesh x 1)
int* mesh_vertnum; // number of vertices (nmesh x 1)
int* mesh_texcoordadr; // texcoord data address; -1: no texcoord (nmesh x 1)
int* mesh_faceadr; // first face address (nmesh x 1)
int* mesh_facenum; // number of faces (nmesh x 1)
int* mesh_graphadr; // graph data address; -1: no graph (nmesh x 1)
float* mesh_vert; // vertex positions for all meshe (nmeshvert x 3)
float* mesh_normal; // vertex normals for all meshes (nmeshvert x 3)
float* mesh_texcoord; // vertex texcoords for all meshes (nmeshtexvert x 2)
int* mesh_face; // triangle face data (nmeshface x 3)
int* mesh_graph; // convex graph data (nmeshgraph x 1)
// skins
int* skin_matid; // skin material id; -1: none (nskin x 1)
float* skin_rgba; // skin rgba (nskin x 4)
float* skin_inflate; // inflate skin in normal direction (nskin x 1)
int* skin_vertadr; // first vertex address (nskin x 1)
int* skin_vertnum; // number of vertices (nskin x 1)
int* skin_texcoordadr; // texcoord data address; -1: no texcoord (nskin x 1)
int* skin_faceadr; // first face address (nskin x 1)
int* skin_facenum; // number of faces (nskin x 1)
int* skin_boneadr; // first bone in skin (nskin x 1)
int* skin_bonenum; // number of bones in skin (nskin x 1)
float* skin_vert; // vertex positions for all skin meshes (nskinvert x 3)
float* skin_texcoord; // vertex texcoords for all skin meshes (nskintexvert x 2)
int* skin_face; // triangle faces for all skin meshes (nskinface x 3)
int* skin_bonevertadr; // first vertex in each bone (nskinbone x 1)
int* skin_bonevertnum; // number of vertices in each bone (nskinbone x 1)
float* skin_bonebindpos; // bind pos of each bone (nskinbone x 3)
float* skin_bonebindquat; // bind quat of each bone (nskinbone x 4)
int* skin_bonebodyid; // body id of each bone (nskinbone x 1)
int* skin_bonevertid; // mesh ids of vertices in each bone (nskinbonevert x 1)
float* skin_bonevertweight; // weights of vertices in each bone (nskinbonevert x 1)
// height fields
mjtNum* hfield_size; // (x, y, z_top, z_bottom) (nhfield x 4)
int* hfield_nrow; // number of rows in grid (nhfield x 1)
int* hfield_ncol; // number of columns in grid (nhfield x 1)
int* hfield_adr; // address in hfield_data (nhfield x 1)
float* hfield_data; // elevation data (nhfielddata x 1)
// textures
int* tex_type; // texture type (mjtTexture) (ntex x 1)
int* tex_height; // number of rows in texture image (ntex x 1)
int* tex_width; // number of columns in texture image (ntex x 1)
int* tex_adr; // address in rgb (ntex x 1)
mjtByte* tex_rgb; // rgb (alpha = 1) (ntexdata x 1)
// materials
int* mat_texid; // texture id; -1: none (nmat x 1)
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
float* mat_emission; // emission (x rgb) (nmat x 1)
float* mat_specular; // specular (x white) (nmat x 1)
float* mat_shininess; // shininess coef (nmat x 1)
float* mat_reflectance; // reflectance (0: disable) (nmat x 1)
float* mat_rgba; // rgba (nmat x 4)
// predefined geom pairs for collision detection; has precedence over exclude
int* pair_dim; // contact dimensionality (npair x 1)
int* pair_geom1; // id of geom1 (npair x 1)
int* pair_geom2; // id of geom2 (npair x 1)
int* pair_signature; // (body1+1)<<16 + body2+1 (npair x 1)
mjtNum* pair_solref; // constraint solver reference: contact (npair x mjNREF)
mjtNum* pair_solimp; // constraint solver impedance: contact (npair x mjNIMP)
mjtNum* pair_margin; // detect contact if dist<margin (npair x 1)
mjtNum* pair_gap; // include in solver if dist<margin-gap (npair x 1)
mjtNum* pair_friction; // tangent1, 2, spin, roll1, 2 (npair x 5)
// excluded body pairs for collision detection
int* exclude_signature; // (body1+1)<<16 + body2+1 (nexclude x 1)
// equality constraints
int* eq_type; // constraint type (mjtEq) (neq x 1)
int* eq_obj1id; // id of object 1 (neq x 1)
int* eq_obj2id; // id of object 2 (neq x 1)
mjtByte* eq_active; // enable/disable constraint (neq x 1)
mjtNum* eq_solref; // constraint solver reference (neq x mjNREF)
mjtNum* eq_solimp; // constraint solver impedance (neq x mjNIMP)
mjtNum* eq_data; // numeric data for constraint (neq x mjNEQDATA)
// tendons
int* tendon_adr; // address of first object in tendon's path (ntendon x 1)
int* tendon_num; // number of objects in tendon's path (ntendon x 1)
int* tendon_matid; // material id for rendering (ntendon x 1)
int* tendon_group; // group for visibility (ntendon x 1)
mjtByte* tendon_limited; // does tendon have length limits (ntendon x 1)
mjtNum* tendon_width; // width for rendering (ntendon x 1)
mjtNum* tendon_solref_lim; // constraint solver reference: limit (ntendon x mjNREF)
mjtNum* tendon_solimp_lim; // constraint solver impedance: limit (ntendon x mjNIMP)
mjtNum* tendon_solref_fri; // constraint solver reference: friction (ntendon x mjNREF)
mjtNum* tendon_solimp_fri; // constraint solver impedance: friction (ntendon x mjNIMP)
mjtNum* tendon_range; // tendon length limits (ntendon x 2)
mjtNum* tendon_margin; // min distance for limit detection (ntendon x 1)
mjtNum* tendon_stiffness; // stiffness coefficient (ntendon x 1)
mjtNum* tendon_damping; // damping coefficient (ntendon x 1)
mjtNum* tendon_frictionloss; // loss due to friction (ntendon x 1)
mjtNum* tendon_lengthspring; // tendon length in qpos_spring (ntendon x 1)
mjtNum* tendon_length0; // tendon length in qpos0 (ntendon x 1)
mjtNum* tendon_invweight0; // inv. weight in qpos0 (ntendon x 1)
mjtNum* tendon_user; // user data (ntendon x nuser_tendon)
float* tendon_rgba; // rgba when material is omitted (ntendon x 4)
// list of all wrap objects in tendon paths
int* wrap_type; // wrap object type (mjtWrap) (nwrap x 1)
int* wrap_objid; // object id: geom, site, joint (nwrap x 1)
mjtNum* wrap_prm; // divisor, joint coef, or site id (nwrap x 1)
// actuators
int* actuator_trntype; // transmission type (mjtTrn) (nu x 1)
int* actuator_dyntype; // dynamics type (mjtDyn) (nu x 1)
int* actuator_gaintype; // gain type (mjtGain) (nu x 1)
int* actuator_biastype; // bias type (mjtBias) (nu x 1)
int* actuator_trnid; // transmission id: joint, tendon, site (nu x 2)
int* actuator_group; // group for visibility (nu x 1)
mjtByte* actuator_ctrllimited; // is control limited (nu x 1)
mjtByte* actuator_forcelimited;// is force limited (nu x 1)
mjtNum* actuator_dynprm; // dynamics parameters (nu x mjNDYN)
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
mjtNum* actuator_forcerange; // range of forces (nu x 2)
mjtNum* actuator_gear; // scale length and transmitted force (nu x 6)
mjtNum* actuator_cranklength; // crank length for slider-crank (nu x 1)
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nu x 1)
mjtNum* actuator_length0; // actuator length in qpos0 (nu x 1)
mjtNum* actuator_lengthrange; // feasible actuator length range (nu x 2)
mjtNum* actuator_user; // user data (nu x nuser_actuator)
// sensors
int* sensor_type; // sensor type (mjtSensor) (nsensor x 1)
int* sensor_datatype; // numeric data type (mjtDataType) (nsensor x 1)
int* sensor_needstage; // required compute stage (mjtStage) (nsensor x 1)
int* sensor_objtype; // type of sensorized object (mjtObj) (nsensor x 1)
int* sensor_objid; // id of sensorized object (nsensor x 1)
int* sensor_dim; // number of scalar outputs (nsensor x 1)
int* sensor_adr; // address in sensor array (nsensor x 1)
mjtNum* sensor_cutoff; // cutoff for real and positive; 0: ignore (nsensor x 1)
mjtNum* sensor_noise; // noise standard deviation (nsensor x 1)
mjtNum* sensor_user; // user data (nsensor x nuser_sensor)
// custom numeric fields
int* numeric_adr; // address of field in numeric_data (nnumeric x 1)
int* numeric_size; // size of numeric field (nnumeric x 1)
mjtNum* numeric_data; // array of all numeric fields (nnumericdata x 1)
// custom text fields
int* text_adr; // address of text in text_data (ntext x 1)
int* text_size; // size of text field (strlen+1) (ntext x 1)
char* text_data; // array of all text fields (0-terminated) (ntextdata x 1)
// custom tuple fields
int* tuple_adr; // address of text in text_data (ntuple x 1)
int* tuple_size; // number of objects in tuple (ntuple x 1)
int* tuple_objtype; // array of object types in all tuples (ntupledata x 1)
int* tuple_objid; // array of object ids in all tuples (ntupledata x 1)
mjtNum* tuple_objprm; // array of object params in all tuples (ntupledata x 1)
// keyframes
mjtNum* key_time; // key time (nkey x 1)
mjtNum* key_qpos; // key position (nkey x nq)
mjtNum* key_qvel; // key velocity (nkey x nv)
mjtNum* key_act; // key activation (nkey x na)
mjtNum* key_mpos; // key mocap position (nkey x 3*nmocap)
mjtNum* key_mquat; // key mocap quaternion (nkey x 4*nmocap)
// names
int* name_bodyadr; // body name pointers (nbody x 1)
int* name_jntadr; // joint name pointers (njnt x 1)
int* name_geomadr; // geom name pointers (ngeom x 1)
int* name_siteadr; // site name pointers (nsite x 1)
int* name_camadr; // camera name pointers (ncam x 1)
int* name_lightadr; // light name pointers (nlight x 1)
int* name_meshadr; // mesh name pointers (nmesh x 1)
int* name_skinadr; // skin name pointers (nskin x 1)
int* name_hfieldadr; // hfield name pointers (nhfield x 1)
int* name_texadr; // texture name pointers (ntex x 1)
int* name_matadr; // material name pointers (nmat x 1)
int* name_pairadr; // geom pair name pointers (npair x 1)
int* name_excludeadr; // exclude name pointers (nexclude x 1)
int* name_eqadr; // equality constraint name pointers (neq x 1)
int* name_tendonadr; // tendon name pointers (ntendon x 1)
int* name_actuatoradr; // actuator name pointers (nu x 1)
int* name_sensoradr; // sensor name pointers (nsensor x 1)
int* name_numericadr; // numeric name pointers (nnumeric x 1)
int* name_textadr; // text name pointers (ntext x 1)
int* name_tupleadr; // tuple name pointers (ntuple x 1)
int* name_keyadr; // keyframe name pointers (nkey x 1)
char* names; // names of all objects, 0-terminated (nnames x 1)
};
typedef struct _mjModel mjModel;
#endif // MUJOCO_MJMODEL_H_
+151
View File
@@ -0,0 +1,151 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MJRENDER_H_
#define MUJOCO_MJRENDER_H_
#define mjNAUX 10 // number of auxiliary buffers
#define mjMAXTEXTURE 1000 // maximum number of textures
typedef enum _mjtGridPos // grid position for overlay
{
mjGRID_TOPLEFT = 0, // top left
mjGRID_TOPRIGHT, // top right
mjGRID_BOTTOMLEFT, // bottom left
mjGRID_BOTTOMRIGHT // bottom right
} mjtGridPos;
typedef enum _mjtFramebuffer // OpenGL framebuffer option
{
mjFB_WINDOW = 0, // default/window buffer
mjFB_OFFSCREEN // offscreen buffer
} mjtFramebuffer;
typedef enum _mjtFontScale // font scale, used at context creation
{
mjFONTSCALE_50 = 50, // 50% scale, suitable for low-res rendering
mjFONTSCALE_100 = 100, // normal scale, suitable in the absence of DPI scaling
mjFONTSCALE_150 = 150, // 150% scale
mjFONTSCALE_200 = 200, // 200% scale
mjFONTSCALE_250 = 250, // 250% scale
mjFONTSCALE_300 = 300 // 300% scale
} mjtFontScale;
typedef enum _mjtFont // font type, used at each text operation
{
mjFONT_NORMAL = 0, // normal font
mjFONT_SHADOW, // normal font with shadow (for higher contrast)
mjFONT_BIG // big font (for user alerts)
} mjtFont;
struct _mjrRect // OpenGL rectangle
{
int left; // left (usually 0)
int bottom; // bottom (usually 0)
int width; // width (usually buffer width)
int height; // height (usually buffer height)
};
typedef struct _mjrRect mjrRect;
struct _mjrContext // custom OpenGL context
{
// parameters copied from mjVisual
float lineWidth; // line width for wireframe rendering
float shadowClip; // clipping radius for directional lights
float shadowScale; // fraction of light cutoff for spot lights
float fogStart; // fog start = stat.extent * vis.map.fogstart
float fogEnd; // fog end = stat.extent * vis.map.fogend
float fogRGBA[4]; // fog rgba
int shadowSize; // size of shadow map texture
int offWidth; // width of offscreen buffer
int offHeight; // height of offscreen buffer
int offSamples; // number of offscreen buffer multisamples
// parameters specified at creation
int fontScale; // font scale
int auxWidth[mjNAUX]; // auxiliary buffer width
int auxHeight[mjNAUX]; // auxiliary buffer height
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
// offscreen rendering objects
unsigned int offFBO; // offscreen framebuffer object
unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples
unsigned int offColor; // offscreen color buffer
unsigned int offColor_r; // offscreen color buffer for resolving multisamples
unsigned int offDepthStencil; // offscreen depth and stencil buffer
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for resolving multisamples
// shadow rendering objects
unsigned int shadowFBO; // shadow map framebuffer object
unsigned int shadowTex; // shadow map texture
// auxiliary buffers
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
// texture objects and info
int ntexture; // number of allocated textures
int textureType[100]; // type of texture (mjtTexture)
unsigned int texture[100]; // texture names
// displaylist starting positions
unsigned int basePlane; // all planes from model
unsigned int baseMesh; // all meshes from model
unsigned int baseHField; // all hfields from model
unsigned int baseBuiltin; // all buildin geoms, with quality from model
unsigned int baseFontNormal; // normal font
unsigned int baseFontShadow; // shadow font
unsigned int baseFontBig; // big font
// displaylist ranges
int rangePlane; // all planes from model
int rangeMesh; // all meshes from model
int rangeHField; // all hfields from model
int rangeBuiltin; // all builtin geoms, with quality from model
int rangeFont; // all characters in font
// skin VBOs
int nskin; // number of skins
unsigned int* skinvertVBO; // skin vertex position VBOs
unsigned int* skinnormalVBO; // skin vertex normal VBOs
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs
unsigned int* skinfaceVBO; // skin face index VBOs
// character info
int charWidth[127]; // character widths: normal and shadow
int charWidthBig[127]; // chacarter widths: big
int charHeight; // character heights: normal and shadow
int charHeightBig; // character heights: big
// capabilities
int glewInitialized; // is glew initialized
int windowAvailable; // is default/window framebuffer available
int windowSamples; // number of samples for default/window framebuffer
int windowStereo; // is stereo available for default/window framebuffer
int windowDoublebuffer; // is default/window framebuffer double buffered
// framebuffer
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
};
typedef struct _mjrContext mjrContext;
#endif // MUJOCO_MJRENDER_H_
Executable
+309
View File
@@ -0,0 +1,309 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MJUI_H_
#define MUJOCO_MJUI_H_
#define mjMAXUISECT 10 // maximum number of sections
#define mjMAXUIITEM 80 // maximum number of items per section
#define mjMAXUITEXT 300 // maximum number of chars in edittext and other
#define mjMAXUINAME 40 // maximum number of chars in name
#define mjMAXUIMULTI 35 // maximum number of radio/select items in group
#define mjMAXUIEDIT 7 // maximum number of elements in edit list
#define mjMAXUIRECT 25 // maximum number of rectangles
#define mjSEPCLOSED 1000 // closed state of adjustable separator
// key codes matching GLFW (user must remap for other frameworks)
#define mjKEY_ESCAPE 256
#define mjKEY_ENTER 257
#define mjKEY_TAB 258
#define mjKEY_BACKSPACE 259
#define mjKEY_INSERT 260
#define mjKEY_DELETE 261
#define mjKEY_RIGHT 262
#define mjKEY_LEFT 263
#define mjKEY_DOWN 264
#define mjKEY_UP 265
#define mjKEY_PAGE_UP 266
#define mjKEY_PAGE_DOWN 267
#define mjKEY_HOME 268
#define mjKEY_END 269
#define mjKEY_F1 290
#define mjKEY_F2 291
#define mjKEY_F3 292
#define mjKEY_F4 293
#define mjKEY_F5 294
#define mjKEY_F6 295
#define mjKEY_F7 296
#define mjKEY_F8 297
#define mjKEY_F9 298
#define mjKEY_F10 299
#define mjKEY_F11 300
#define mjKEY_F12 301
typedef enum _mjtButton // mouse button
{
mjBUTTON_NONE = 0, // no button
mjBUTTON_LEFT, // left button
mjBUTTON_RIGHT, // right button
mjBUTTON_MIDDLE // middle button
} mjtButton;
typedef enum _mjtEvent // mouse and keyboard event type
{
mjEVENT_NONE = 0, // no event
mjEVENT_MOVE, // mouse move
mjEVENT_PRESS, // mouse button press
mjEVENT_RELEASE, // mouse button release
mjEVENT_SCROLL, // scroll
mjEVENT_KEY, // key press
mjEVENT_RESIZE // resize
} mjtEvent;
typedef enum _mjtItem // UI item type
{
mjITEM_END = -2, // end of definition list (not an item)
mjITEM_SECTION = -1, // section (not an item)
mjITEM_SEPARATOR = 0, // separator
mjITEM_STATIC, // static text
mjITEM_BUTTON, // button
// the rest have data pointer
mjITEM_CHECKINT, // check box, int value
mjITEM_CHECKBYTE, // check box, mjtByte value
mjITEM_RADIO, // radio group
mjITEM_RADIOLINE, // radio group, single line
mjITEM_SELECT, // selection box
mjITEM_SLIDERINT, // slider, int value
mjITEM_SLIDERNUM, // slider, mjtNum value
mjITEM_EDITINT, // editable array, int values
mjITEM_EDITNUM, // editable array, mjtNum values
mjITEM_EDITTXT, // editable text
mjNITEM // number of item types
} mjtItem;
// predicate function: set enable/disable based on item category
typedef int (*mjfItemEnable)(int category, void* data);
struct _mjuiState // mouse and keyboard state
{
// constants set by user
int nrect; // number of rectangles used
mjrRect rect[mjMAXUIRECT]; // rectangles (index 0: entire window)
void* userdata; // pointer to user data (for callbacks)
// event type
int type; // (type mjtEvent)
// mouse buttons
int left; // is left button down
int right; // is right button down
int middle; // is middle button down
int doubleclick; // is last press a double click
int button; // which button was pressed (mjtButton)
double buttontime; // time of last button press
// mouse position
double x; // x position
double y; // y position
double dx; // x displacement
double dy; // y displacement
double sx; // x scroll
double sy; // y scroll
// keyboard
int control; // is control down
int shift; // is shift down
int alt; // is alt down
int key; // which key was pressed
double keytime; // time of last key press
// rectangle ownership and dragging
int mouserect; // which rectangle contains mouse
int dragrect; // which rectangle is dragged with mouse
int dragbutton; // which button started drag (mjtButton)
};
typedef struct _mjuiState mjuiState;
struct _mjuiThemeSpacing // UI visualization theme spacing
{
int total; // total width
int scroll; // scrollbar width
int label; // label width
int section; // section gap
int itemside; // item side gap
int itemmid; // item middle gap
int itemver; // item vertical gap
int texthor; // text horizontal gap
int textver; // text vertical gap
int linescroll; // number of pixels to scroll
int samples; // number of multisamples
};
typedef struct _mjuiThemeSpacing mjuiThemeSpacing;
struct _mjuiThemeColor // UI visualization theme color
{
float master[3]; // master background
float thumb[3]; // scrollbar thumb
float secttitle[3]; // section title
float sectfont[3]; // section font
float sectsymbol[3]; // section symbol
float sectpane[3]; // section pane
float shortcut[3]; // shortcut background
float fontactive[3]; // font active
float fontinactive[3]; // font inactive
float decorinactive[3]; // decor inactive
float decorinactive2[3]; // inactive slider color 2
float button[3]; // button
float check[3]; // check
float radio[3]; // radio
float select[3]; // select
float select2[3]; // select pane
float slider[3]; // slider
float slider2[3]; // slider color 2
float edit[3]; // edit
float edit2[3]; // edit invalid
float cursor[3]; // edit cursor
};
typedef struct _mjuiThemeColor mjuiThemeColor;
struct _mjuiItemSingle // check and button-related
{
int modifier; // 0: none, 1: control, 2: shift; 4: alt
int shortcut; // shortcut key; 0: undefined
};
struct _mjuiItemMulti // static, radio and select-related
{
int nelem; // number of elements in group
char name[mjMAXUIMULTI][mjMAXUINAME]; // element names
};
struct _mjuiItemSlider // slider-related
{
double range[2]; // slider range
double divisions; // number of range divisions
};
struct _mjuiItemEdit // edit-related
{
int nelem; // number of elements in list
double range[mjMAXUIEDIT][2]; // element range (min>=max: ignore)
};
struct _mjuiItem // UI item
{
// common properties
int type; // type (mjtItem)
char name[mjMAXUINAME]; // name
int state; // 0: disable, 1: enable, 2+: use predicate
void *pdata; // data pointer (type-specific)
int sectionid; // id of section containing item
int itemid; // id of item within section
// type-specific properties
union
{
struct _mjuiItemSingle single; // check and button
struct _mjuiItemMulti multi; // static, radio and select
struct _mjuiItemSlider slider; // slider
struct _mjuiItemEdit edit; // edit
};
// internal
mjrRect rect; // rectangle occupied by item
};
typedef struct _mjuiItem mjuiItem;
struct _mjuiSection // UI section
{
// properties
char name[mjMAXUINAME]; // name
int state; // 0: closed, 1: open
int modifier; // 0: none, 1: control, 2: shift; 4: alt
int shortcut; // shortcut key; 0: undefined
int nitem; // number of items in use
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
// internal
mjrRect rtitle; // rectangle occupied by title
mjrRect rcontent; // rectangle occupied by content
};
typedef struct _mjuiSection mjuiSection;
struct _mjUI // entire UI
{
// constants set by user
mjuiThemeSpacing spacing; // UI theme spacing
mjuiThemeColor color; // UI theme color
mjfItemEnable predicate; // callback to set item state programmatically
void* userdata; // pointer to user data (passed to predicate)
int rectid; // index of this ui rectangle in mjuiState
int auxid; // aux buffer index of this ui
int radiocol; // number of radio columns (0 defaults to 2)
// UI sizes (framebuffer units)
int width; // width
int height; // current heigth
int maxheight; // height when all sections open
int scroll; // scroll from top of UI
// mouse focus
int mousesect; // 0: none, -1: scroll, otherwise 1+section
int mouseitem; // item within section
int mousehelp; // help button down: print shortcuts
// keyboard focus and edit
int editsect; // 0: none, otherwise 1+section
int edititem; // item within section
int editcursor; // cursor position
int editscroll; // horizontal scroll
char edittext[mjMAXUITEXT]; // current text
mjuiItem* editchanged; // pointer to changed edit in last mjui_event
// sections
int nsect; // number of sections in use
mjuiSection sect[mjMAXUISECT]; // preallocated array of sections
};
typedef struct _mjUI mjUI;
struct _mjuiDef // table passed to mjui_add()
{
int type; // type (mjtItem); -1: section
char name[mjMAXUINAME]; // name
int state; // state
void* pdata; // pointer to data
char other[mjMAXUITEXT]; // string with type-specific properties
};
typedef struct _mjuiDef mjuiDef;
#endif // MUJOCO_MJUI_H_
+350
View File
@@ -0,0 +1,350 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MJVISUALIZE_H_
#define MUJOCO_MJVISUALIZE_H_
#define mjNGROUP 6 // number of geom, site, joint groups with visflags
#define mjMAXOVERLAY 500 // maximum number of characters in overlay text
#define mjMAXLINE 100 // maximum number of lines per plot
#define mjMAXLINEPNT 1000 // maximum number points per line
#define mjMAXPLANEGRID 200 // maximum number of grid divisions for plane
typedef enum _mjtCatBit // bitflags for mjvGeom category
{
mjCAT_STATIC = 1, // model elements in body 0
mjCAT_DYNAMIC = 2, // model elements in all other bodies
mjCAT_DECOR = 4, // decorative geoms
mjCAT_ALL = 7 // select all categories
} mjtCatBit;
typedef enum _mjtMouse // mouse interaction mode
{
mjMOUSE_NONE = 0, // no action
mjMOUSE_ROTATE_V, // rotate, vertical plane
mjMOUSE_ROTATE_H, // rotate, horizontal plane
mjMOUSE_MOVE_V, // move, vertical plane
mjMOUSE_MOVE_H, // move, horizontal plane
mjMOUSE_ZOOM, // zoom
mjMOUSE_SELECT // selection
} mjtMouse;
typedef enum _mjtPertBit // mouse perturbations
{
mjPERT_TRANSLATE = 1, // translation
mjPERT_ROTATE = 2 // rotation
} mjtPertBit;
typedef enum _mjtCamera // abstract camera type
{
mjCAMERA_FREE = 0, // free camera
mjCAMERA_TRACKING, // tracking camera; uses trackbodyid
mjCAMERA_FIXED, // fixed camera; uses fixedcamid
mjCAMERA_USER // user is responsible for setting OpenGL camera
} mjtCamera;
typedef enum _mjtLabel // object labeling
{
mjLABEL_NONE = 0, // nothing
mjLABEL_BODY, // body labels
mjLABEL_JOINT, // joint labels
mjLABEL_GEOM, // geom labels
mjLABEL_SITE, // site labels
mjLABEL_CAMERA, // camera labels
mjLABEL_LIGHT, // light labels
mjLABEL_TENDON, // tendon labels
mjLABEL_ACTUATOR, // actuator labels
mjLABEL_CONSTRAINT, // constraint labels
mjLABEL_SKIN, // skin labels
mjLABEL_SELECTION, // selected object
mjLABEL_SELPNT, // coordinates of selection point
mjLABEL_CONTACTFORCE, // magnitude of contact force
mjNLABEL // number of label types
} mjtLabel;
typedef enum _mjtFrame // frame visualization
{
mjFRAME_NONE = 0, // no frames
mjFRAME_BODY, // body frames
mjFRAME_GEOM, // geom frames
mjFRAME_SITE, // site frames
mjFRAME_CAMERA, // camera frames
mjFRAME_LIGHT, // light frames
mjFRAME_WORLD, // world frame
mjNFRAME // number of visualization frames
} mjtFrame;
typedef enum _mjtVisFlag // flags enabling model element visualization
{
mjVIS_CONVEXHULL = 0, // mesh convex hull
mjVIS_TEXTURE, // textures
mjVIS_JOINT, // joints
mjVIS_ACTUATOR, // actuators
mjVIS_CAMERA, // cameras
mjVIS_LIGHT, // lights
mjVIS_TENDON, // tendons
mjVIS_RANGEFINDER, // rangefinder sensors
mjVIS_CONSTRAINT, // point constraints
mjVIS_INERTIA, // equivalent inertia boxes
mjVIS_SCLINERTIA, // scale equivalent inertia boxes with mass
mjVIS_PERTFORCE, // perturbation force
mjVIS_PERTOBJ, // perturbation object
mjVIS_CONTACTPOINT, // contact points
mjVIS_CONTACTFORCE, // contact force
mjVIS_CONTACTSPLIT, // split contact force into normal and tanget
mjVIS_TRANSPARENT, // make dynamic geoms more transparent
mjVIS_AUTOCONNECT, // auto connect joints and body coms
mjVIS_COM, // center of mass
mjVIS_SELECT, // selection point
mjVIS_STATIC, // static bodies
mjVIS_SKIN, // skin
mjNVISFLAG // number of visualization flags
} mjtVisFlag;
typedef enum _mjtRndFlag // flags enabling rendering effects
{
mjRND_SHADOW = 0, // shadows
mjRND_WIREFRAME, // wireframe
mjRND_REFLECTION, // reflections
mjRND_ADDITIVE, // additive transparency
mjRND_SKYBOX, // skybox
mjRND_FOG, // fog
mjRND_HAZE, // haze
mjRND_SEGMENT, // segmentation with random color
mjRND_IDCOLOR, // segmentation with segid color
mjNRNDFLAG // number of rendering flags
} mjtRndFlag;
typedef enum _mjtStereo // type of stereo rendering
{
mjSTEREO_NONE = 0, // no stereo; use left eye only
mjSTEREO_QUADBUFFERED, // quad buffered; revert to side-by-side if no hardware support
mjSTEREO_SIDEBYSIDE // side-by-side
} mjtStereo;
struct _mjvPerturb // object selection and perturbation
{
int select; // selected body id; non-positive: none
int skinselect; // selected skin id; negative: none
int active; // perturbation bitmask (mjtPertBit)
int active2; // secondary perturbation bitmask (mjtPertBit)
mjtNum refpos[3]; // desired position for selected object
mjtNum refquat[4]; // desired orientation for selected object
mjtNum localpos[3]; // selection point in object coordinates
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
};
typedef struct _mjvPerturb mjvPerturb;
struct _mjvCamera // abstract camera
{
// type and ids
int type; // camera type (mjtCamera)
int fixedcamid; // fixed camera id
int trackbodyid; // body id to track
// abstract camera pose specification
mjtNum lookat[3]; // lookat point
mjtNum distance; // distance to lookat point or tracked body
mjtNum azimuth; // camera azimuth (deg)
mjtNum elevation; // camera elevation (deg)
};
typedef struct _mjvCamera mjvCamera;
struct _mjvGLCamera // OpenGL camera
{
// camera frame
float pos[3]; // position
float forward[3]; // forward direction
float up[3]; // up direction
// camera projection
float frustum_center; // hor. center (left,right set to match aspect)
float frustum_bottom; // bottom
float frustum_top; // top
float frustum_near; // near
float frustum_far; // far
};
typedef struct _mjvGLCamera mjvGLCamera;
struct _mjvGeom // abstract geom
{
// type info
int type; // geom type (mjtGeom)
int dataid; // mesh, hfield or plane id; -1: none
int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
int objid; // mujoco object id; -1 for decor
int category; // visual category
int texid; // texture id; -1: no texture
int texuniform; // uniform cube mapping
int texcoord; // mesh geom has texture coordinates
int segid; // segmentation id; -1: not shown
// OpenGL info
float texrepeat[2]; // texture repetition for 2D mapping
float size[3]; // size parameters
float pos[3]; // Cartesian position
float mat[9]; // Cartesian orientation
float rgba[4]; // color and transparency
float emission; // emission coef
float specular; // specular coef
float shininess; // shininess coef
float reflectance; // reflectance coef
char label[100]; // text label
// transparency rendering (set internally)
float camdist; // distance to camera (used by sorter)
float modelrbound; // geom rbound from model, 0 if not model geom
mjtByte transparent; // treat geom as transparent
};
typedef struct _mjvGeom mjvGeom;
struct _mjvLight // OpenGL light
{
float pos[3]; // position rel. to body frame
float dir[3]; // direction rel. to body frame
float attenuation[3]; // OpenGL attenuation (quadratic model)
float cutoff; // OpenGL cutoff
float exponent; // OpenGL exponent
float ambient[3]; // ambient rgb (alpha=1)
float diffuse[3]; // diffuse rgb (alpha=1)
float specular[3]; // specular rgb (alpha=1)
mjtByte headlight; // headlight
mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows
};
typedef struct _mjvLight mjvLight;
struct _mjvOption // abstract visualization options
{
int label; // what objects to label (mjtLabel)
int frame; // which frame to show (mjtFrame)
mjtByte geomgroup[mjNGROUP]; // geom visualization by group
mjtByte sitegroup[mjNGROUP]; // site visualization by group
mjtByte jointgroup[mjNGROUP]; // joint visualization by group
mjtByte tendongroup[mjNGROUP]; // tendon visualization by group
mjtByte actuatorgroup[mjNGROUP]; // actuator visualization by group
mjtByte flags[mjNVISFLAG]; // visualization flags (indexed by mjtVisFlag)
};
typedef struct _mjvOption mjvOption;
struct _mjvScene // abstract scene passed to OpenGL renderer
{
// abstract geoms
int maxgeom; // size of allocated geom buffer
int ngeom; // number of geoms currently in buffer
mjvGeom* geoms; // buffer for geoms
int* geomorder; // buffer for ordering geoms by distance to camera
// skin data
int nskin; // number of skins
int* skinfacenum; // number of faces in skin
int* skinvertadr; // address of skin vertices
int* skinvertnum; // number of vertices in skin
float* skinvert; // skin vertex data
float* skinnormal; // skin normal data
// OpenGL lights
int nlight; // number of lights currently in buffer
mjvLight lights[8]; // buffer for lights
// OpenGL cameras
mjvGLCamera camera[2]; // left and right camera
// OpenGL model transformation
mjtByte enabletransform; // enable model transformation
float translate[3]; // model translation
float rotate[4]; // model quaternion rotation
float scale; // model scaling
// OpenGL rendering effects
int stereo; // stereoscopic rendering (mjtStereo)
mjtByte flags[mjNRNDFLAG]; // rendering flags (indexed by mjtRndFlag)
// framing
int framewidth; // frame pixel width; 0: disable framing
float framergb[3]; // frame color
};
typedef struct _mjvScene mjvScene;
struct _mjvFigure // abstract 2D figure passed to OpenGL renderer
{
// enable flags
int flg_legend; // show legend
int flg_ticklabel[2]; // show grid tick labels (x,y)
int flg_extend; // automatically extend axis ranges to fit data
int flg_barplot; // isolated line segments (i.e. GL_LINES)
int flg_selection; // vertical selection line
int flg_symmetric; // symmetric y-axis
// style settings
float linewidth; // line width
float gridwidth; // grid line width
int gridsize[2]; // number of grid points in (x,y)
float gridrgb[3]; // grid line rgb
float figurergba[4]; // figure color and alpha
float panergba[4]; // pane color and alpha
float legendrgba[4]; // legend color and alpha
float textrgb[3]; // text color
float linergb[mjMAXLINE][3]; // line colors
float range[2][2]; // axis ranges; (min>=max) automatic
char xformat[20]; // x-tick label format for sprintf
char yformat[20]; // y-tick label format for sprintf
char minwidth[20]; // string used to determine min y-tick width
// text labels
char title[1000]; // figure title; subplots separated with 2+ spaces
char xlabel[100]; // x-axis label
char linename[mjMAXLINE][100]; // line names for legend
// dynamic settings
int legendoffset; // number of lines to offset legend
int subplot; // selected subplot (for title rendering)
int highlight[2]; // if point is in legend rect, highlight line
int highlightid; // if id>=0 and no point, highlight id
float selection; // selection line x-value
// line data
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
// output from renderer
int xaxispixel[2]; // range of x-axis in pixels
int yaxispixel[2]; // range of y-axis in pixels
float xaxisdata[2]; // range of x-axis in data units
float yaxisdata[2]; // range of y-axis in data units
};
typedef struct _mjvFigure mjvFigure;
#endif // MUJOCO_MJVISUALIZE_H_
+511
View File
@@ -0,0 +1,511 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MJXMACRO_H_
#define MUJOCO_MJXMACRO_H_
//-------------------------------- mjOption ---------------------------------------------
// scalar fields of mjOption
#define MJOPTION_SCALARS \
X( mjtNum, timestep ) \
X( mjtNum, apirate ) \
X( mjtNum, impratio ) \
X( mjtNum, tolerance ) \
X( mjtNum, noslip_tolerance ) \
X( mjtNum, mpr_tolerance ) \
X( mjtNum, density ) \
X( mjtNum, viscosity ) \
X( mjtNum, o_margin ) \
X( int, integrator ) \
X( int, collision ) \
X( int, cone ) \
X( int, jacobian ) \
X( int, solver ) \
X( int, iterations ) \
X( int, noslip_iterations ) \
X( int, mpr_iterations ) \
X( int, disableflags ) \
X( int, enableflags )
// vector fields of mjOption
#define MJOPTION_VECTORS \
X( gravity, 3 ) \
X( wind, 3 ) \
X( magnetic, 3 ) \
X( o_solref, mjNREF ) \
X( o_solimp, mjNIMP )
//-------------------------------- mjModel ----------------------------------------------
// int fields of mjModel
#define MJMODEL_INTS \
X( nq ) \
X( nv ) \
X( nu ) \
X( na ) \
X( nbody ) \
X( njnt ) \
X( ngeom ) \
X( nsite ) \
X( ncam ) \
X( nlight ) \
X( nmesh ) \
X( nmeshvert ) \
X( nmeshtexvert ) \
X( nmeshface ) \
X( nmeshgraph ) \
X( nskin ) \
X( nskinvert ) \
X( nskintexvert ) \
X( nskinface ) \
X( nskinbone ) \
X( nskinbonevert ) \
X( nhfield ) \
X( nhfielddata ) \
X( ntex ) \
X( ntexdata ) \
X( nmat ) \
X( npair ) \
X( nexclude ) \
X( neq ) \
X( ntendon ) \
X( nwrap ) \
X( nsensor ) \
X( nnumeric ) \
X( nnumericdata ) \
X( ntext ) \
X( ntextdata ) \
X( ntuple ) \
X( ntupledata ) \
X( nkey ) \
X( nmocap ) \
X( nuser_body ) \
X( nuser_jnt ) \
X( nuser_geom ) \
X( nuser_site ) \
X( nuser_cam ) \
X( nuser_tendon ) \
X( nuser_actuator ) \
X( nuser_sensor ) \
X( nnames ) \
X( nM ) \
X( nemax ) \
X( njmax ) \
X( nconmax ) \
X( nstack ) \
X( nuserdata ) \
X( nsensordata ) \
X( nbuffer )
// pointer fields of mjModel
#define MJMODEL_POINTERS \
X( mjtNum, qpos0, nq, 1 ) \
X( mjtNum, qpos_spring, nq, 1 ) \
X( int, body_parentid, nbody, 1 ) \
X( int, body_rootid, nbody, 1 ) \
X( int, body_weldid, nbody, 1 ) \
X( int, body_mocapid, nbody, 1 ) \
X( int, body_jntnum, nbody, 1 ) \
X( int, body_jntadr, nbody, 1 ) \
X( int, body_dofnum, nbody, 1 ) \
X( int, body_dofadr, nbody, 1 ) \
X( int, body_geomnum, nbody, 1 ) \
X( int, body_geomadr, nbody, 1 ) \
X( mjtByte, body_simple, nbody, 1 ) \
X( mjtByte, body_sameframe, nbody, 1 ) \
X( mjtNum, body_pos, nbody, 3 ) \
X( mjtNum, body_quat, nbody, 4 ) \
X( mjtNum, body_ipos, nbody, 3 ) \
X( mjtNum, body_iquat, nbody, 4 ) \
X( mjtNum, body_mass, nbody, 1 ) \
X( mjtNum, body_subtreemass, nbody, 1 ) \
X( mjtNum, body_inertia, nbody, 3 ) \
X( mjtNum, body_invweight0, nbody, 2 ) \
X( mjtNum, body_user, nbody, nuser_body ) \
X( int, jnt_type, njnt, 1 ) \
X( int, jnt_qposadr, njnt, 1 ) \
X( int, jnt_dofadr, njnt, 1 ) \
X( int, jnt_bodyid, njnt, 1 ) \
X( int, jnt_group, njnt, 1 ) \
X( mjtByte, jnt_limited, njnt, 1 ) \
X( mjtNum, jnt_solref, njnt, mjNREF ) \
X( mjtNum, jnt_solimp, njnt, mjNIMP ) \
X( mjtNum, jnt_pos, njnt, 3 ) \
X( mjtNum, jnt_axis, njnt, 3 ) \
X( mjtNum, jnt_stiffness, njnt, 1 ) \
X( mjtNum, jnt_range, njnt, 2 ) \
X( mjtNum, jnt_margin, njnt, 1 ) \
X( mjtNum, jnt_user, njnt, nuser_jnt ) \
X( int, dof_bodyid, nv, 1 ) \
X( int, dof_jntid, nv, 1 ) \
X( int, dof_parentid, nv, 1 ) \
X( int, dof_Madr, nv, 1 ) \
X( int, dof_simplenum, nv, 1 ) \
X( mjtNum, dof_solref, nv, mjNREF ) \
X( mjtNum, dof_solimp, nv, mjNIMP ) \
X( mjtNum, dof_frictionloss, nv, 1 ) \
X( mjtNum, dof_armature, nv, 1 ) \
X( mjtNum, dof_damping, nv, 1 ) \
X( mjtNum, dof_invweight0, nv, 1 ) \
X( mjtNum, dof_M0, nv, 1 ) \
X( int, geom_type, ngeom, 1 ) \
X( int, geom_contype, ngeom, 1 ) \
X( int, geom_conaffinity, ngeom, 1 ) \
X( int, geom_condim, ngeom, 1 ) \
X( int, geom_bodyid, ngeom, 1 ) \
X( int, geom_dataid, ngeom, 1 ) \
X( int, geom_matid, ngeom, 1 ) \
X( int, geom_group, ngeom, 1 ) \
X( int, geom_priority, ngeom, 1 ) \
X( mjtByte, geom_sameframe, ngeom, 1 ) \
X( mjtNum, geom_solmix, ngeom, 1 ) \
X( mjtNum, geom_solref, ngeom, mjNREF ) \
X( mjtNum, geom_solimp, ngeom, mjNIMP ) \
X( mjtNum, geom_size, ngeom, 3 ) \
X( mjtNum, geom_rbound, ngeom, 1 ) \
X( mjtNum, geom_pos, ngeom, 3 ) \
X( mjtNum, geom_quat, ngeom, 4 ) \
X( mjtNum, geom_friction, ngeom, 3 ) \
X( mjtNum, geom_margin, ngeom, 1 ) \
X( mjtNum, geom_gap, ngeom, 1 ) \
X( mjtNum, geom_user, ngeom, nuser_geom ) \
X( float, geom_rgba, ngeom, 4 ) \
X( int, site_type, nsite, 1 ) \
X( int, site_bodyid, nsite, 1 ) \
X( int, site_matid, nsite, 1 ) \
X( int, site_group, nsite, 1 ) \
X( mjtByte, site_sameframe, nsite, 1 ) \
X( mjtNum, site_size, nsite, 3 ) \
X( mjtNum, site_pos, nsite, 3 ) \
X( mjtNum, site_quat, nsite, 4 ) \
X( mjtNum, site_user, nsite, nuser_site ) \
X( float, site_rgba, nsite, 4 ) \
X( int, cam_mode, ncam, 1 ) \
X( int, cam_bodyid, ncam, 1 ) \
X( int, cam_targetbodyid, ncam, 1 ) \
X( mjtNum, cam_pos, ncam, 3 ) \
X( mjtNum, cam_quat, ncam, 4 ) \
X( mjtNum, cam_poscom0, ncam, 3 ) \
X( mjtNum, cam_pos0, ncam, 3 ) \
X( mjtNum, cam_mat0, ncam, 9 ) \
X( mjtNum, cam_fovy, ncam, 1 ) \
X( mjtNum, cam_ipd, ncam, 1 ) \
X( mjtNum, cam_user, ncam, nuser_cam ) \
X( int, light_mode, nlight, 1 ) \
X( int, light_bodyid, nlight, 1 ) \
X( int, light_targetbodyid, nlight, 1 ) \
X( mjtByte, light_directional, nlight, 1 ) \
X( mjtByte, light_castshadow, nlight, 1 ) \
X( mjtByte, light_active, nlight, 1 ) \
X( mjtNum, light_pos, nlight, 3 ) \
X( mjtNum, light_dir, nlight, 3 ) \
X( mjtNum, light_poscom0, nlight, 3 ) \
X( mjtNum, light_pos0, nlight, 3 ) \
X( mjtNum, light_dir0, nlight, 3 ) \
X( float, light_attenuation, nlight, 3 ) \
X( float, light_cutoff, nlight, 1 ) \
X( float, light_exponent, nlight, 1 ) \
X( float, light_ambient, nlight, 3 ) \
X( float, light_diffuse, nlight, 3 ) \
X( float, light_specular, nlight, 3 ) \
X( int, mesh_vertadr, nmesh, 1 ) \
X( int, mesh_vertnum, nmesh, 1 ) \
X( int, mesh_texcoordadr, nmesh, 1 ) \
X( int, mesh_faceadr, nmesh, 1 ) \
X( int, mesh_facenum, nmesh, 1 ) \
X( int, mesh_graphadr, nmesh, 1 ) \
X( float, mesh_vert, nmeshvert, 3 ) \
X( float, mesh_normal, nmeshvert, 3 ) \
X( float, mesh_texcoord, nmeshtexvert, 2 ) \
X( int, mesh_face, nmeshface, 3 ) \
X( int, mesh_graph, nmeshgraph,1 ) \
X( int, skin_matid, nskin, 1 ) \
X( float, skin_rgba, nskin, 4 ) \
X( float, skin_inflate, nskin, 1 ) \
X( int, skin_vertadr, nskin, 1 ) \
X( int, skin_vertnum, nskin, 1 ) \
X( int, skin_texcoordadr, nskin, 1 ) \
X( int, skin_faceadr, nskin, 1 ) \
X( int, skin_facenum, nskin, 1 ) \
X( int, skin_boneadr, nskin, 1 ) \
X( int, skin_bonenum, nskin, 1 ) \
X( float, skin_vert, nskinvert, 3 ) \
X( float, skin_texcoord, nskintexvert, 2 ) \
X( int, skin_face, nskinface, 3 ) \
X( int, skin_bonevertadr, nskinbone, 1 ) \
X( int, skin_bonevertnum, nskinbone, 1 ) \
X( float, skin_bonebindpos, nskinbone, 3 ) \
X( float, skin_bonebindquat, nskinbone, 4 ) \
X( int, skin_bonebodyid, nskinbone, 1 ) \
X( int, skin_bonevertid, nskinbonevert, 1 ) \
X( float, skin_bonevertweight, nskinbonevert, 1 ) \
X( mjtNum, hfield_size, nhfield, 4 ) \
X( int, hfield_nrow, nhfield, 1 ) \
X( int, hfield_ncol, nhfield, 1 ) \
X( int, hfield_adr, nhfield, 1 ) \
X( float, hfield_data, nhfielddata, 1 ) \
X( int, tex_type, ntex, 1 ) \
X( int, tex_height, ntex, 1 ) \
X( int, tex_width, ntex, 1 ) \
X( int, tex_adr, ntex, 1 ) \
X( mjtByte, tex_rgb, ntexdata, 1 ) \
X( int, mat_texid, nmat, 1 ) \
X( mjtByte, mat_texuniform, nmat, 1 ) \
X( float, mat_texrepeat, nmat, 2 ) \
X( float, mat_emission, nmat, 1 ) \
X( float, mat_specular, nmat, 1 ) \
X( float, mat_shininess, nmat, 1 ) \
X( float, mat_reflectance, nmat, 1 ) \
X( float, mat_rgba, nmat, 4 ) \
X( int, pair_dim, npair, 1 ) \
X( int, pair_geom1, npair, 1 ) \
X( int, pair_geom2, npair, 1 ) \
X( int, pair_signature, npair, 1 ) \
X( mjtNum, pair_solref, npair, mjNREF ) \
X( mjtNum, pair_solimp, npair, mjNIMP ) \
X( mjtNum, pair_margin, npair, 1 ) \
X( mjtNum, pair_gap, npair, 1 ) \
X( mjtNum, pair_friction, npair, 5 ) \
X( int, exclude_signature, nexclude, 1 ) \
X( int, eq_type, neq, 1 ) \
X( int, eq_obj1id, neq, 1 ) \
X( int, eq_obj2id, neq, 1 ) \
X( mjtByte, eq_active, neq, 1 ) \
X( mjtNum, eq_solref, neq, mjNREF ) \
X( mjtNum, eq_solimp, neq, mjNIMP ) \
X( mjtNum, eq_data, neq, mjNEQDATA ) \
X( int, tendon_adr, ntendon, 1 ) \
X( int, tendon_num, ntendon, 1 ) \
X( int, tendon_matid, ntendon, 1 ) \
X( int, tendon_group, ntendon, 1 ) \
X( mjtByte, tendon_limited, ntendon, 1 ) \
X( mjtNum, tendon_width, ntendon, 1 ) \
X( mjtNum, tendon_solref_lim, ntendon, mjNREF ) \
X( mjtNum, tendon_solimp_lim, ntendon, mjNIMP ) \
X( mjtNum, tendon_solref_fri, ntendon, mjNREF ) \
X( mjtNum, tendon_solimp_fri, ntendon, mjNIMP ) \
X( mjtNum, tendon_range, ntendon, 2 ) \
X( mjtNum, tendon_margin, ntendon, 1 ) \
X( mjtNum, tendon_stiffness, ntendon, 1 ) \
X( mjtNum, tendon_damping, ntendon, 1 ) \
X( mjtNum, tendon_frictionloss, ntendon, 1 ) \
X( mjtNum, tendon_lengthspring, ntendon, 1 ) \
X( mjtNum, tendon_length0, ntendon, 1 ) \
X( mjtNum, tendon_invweight0, ntendon, 1 ) \
X( mjtNum, tendon_user, ntendon, nuser_tendon) \
X( float, tendon_rgba, ntendon, 4 ) \
X( int, wrap_type, nwrap, 1 ) \
X( int, wrap_objid, nwrap, 1 ) \
X( mjtNum, wrap_prm, nwrap, 1 ) \
X( int, actuator_trntype, nu, 1 ) \
X( int, actuator_dyntype, nu, 1 ) \
X( int, actuator_gaintype, nu, 1 ) \
X( int, actuator_biastype, nu, 1 ) \
X( int, actuator_trnid, nu, 2 ) \
X( int, actuator_group, nu, 1 ) \
X( mjtByte, actuator_ctrllimited, nu, 1 ) \
X( mjtByte, actuator_forcelimited, nu, 1 ) \
X( mjtNum, actuator_dynprm, nu, mjNDYN ) \
X( mjtNum, actuator_gainprm, nu, mjNGAIN ) \
X( mjtNum, actuator_biasprm, nu, mjNBIAS ) \
X( mjtNum, actuator_ctrlrange, nu, 2 ) \
X( mjtNum, actuator_forcerange, nu, 2 ) \
X( mjtNum, actuator_gear, nu, 6 ) \
X( mjtNum, actuator_cranklength, nu, 1 ) \
X( mjtNum, actuator_acc0, nu, 1 ) \
X( mjtNum, actuator_length0, nu, 1 ) \
X( mjtNum, actuator_lengthrange, nu, 2 ) \
X( mjtNum, actuator_user, nu, nuser_actuator) \
X( int, sensor_type, nsensor, 1 ) \
X( int, sensor_datatype, nsensor, 1 ) \
X( int, sensor_needstage, nsensor, 1 ) \
X( int, sensor_objtype, nsensor, 1 ) \
X( int, sensor_objid, nsensor, 1 ) \
X( int, sensor_dim, nsensor, 1 ) \
X( int, sensor_adr, nsensor, 1 ) \
X( mjtNum, sensor_cutoff, nsensor, 1 ) \
X( mjtNum, sensor_noise, nsensor, 1 ) \
X( mjtNum, sensor_user, nsensor, nuser_sensor) \
X( int, numeric_adr, nnumeric, 1 ) \
X( int, numeric_size, nnumeric, 1 ) \
X( mjtNum, numeric_data, nnumericdata, 1 ) \
X( int, text_adr, ntext, 1 ) \
X( int, text_size, ntext, 1 ) \
X( char, text_data, ntextdata, 1 ) \
X( int, tuple_adr, ntuple, 1 ) \
X( int, tuple_size, ntuple, 1 ) \
X( int, tuple_objtype, ntupledata, 1 ) \
X( int, tuple_objid, ntupledata, 1 ) \
X( mjtNum, tuple_objprm, ntupledata, 1 ) \
X( mjtNum, key_time, nkey, 1 ) \
X( mjtNum, key_qpos, nkey, nq ) \
X( mjtNum, key_qvel, nkey, nv ) \
X( mjtNum, key_act, nkey, na ) \
X( mjtNum, key_mpos, nkey, nmocap3 ) \
X( mjtNum, key_mquat, nkey, nmocap4 ) \
X( int, name_bodyadr, nbody, 1 ) \
X( int, name_jntadr, njnt, 1 ) \
X( int, name_geomadr, ngeom, 1 ) \
X( int, name_siteadr, nsite, 1 ) \
X( int, name_camadr, ncam, 1 ) \
X( int, name_lightadr, nlight, 1 ) \
X( int, name_meshadr, nmesh, 1 ) \
X( int, name_skinadr, nskin, 1 ) \
X( int, name_hfieldadr, nhfield, 1 ) \
X( int, name_texadr, ntex, 1 ) \
X( int, name_matadr, nmat, 1 ) \
X( int, name_pairadr, npair, 1 ) \
X( int, name_excludeadr, nexclude, 1 ) \
X( int, name_eqadr, neq, 1 ) \
X( int, name_tendonadr, ntendon, 1 ) \
X( int, name_actuatoradr, nu, 1 ) \
X( int, name_sensoradr, nsensor, 1 ) \
X( int, name_numericadr, nnumeric, 1 ) \
X( int, name_textadr, ntext, 1 ) \
X( int, name_tupleadr, ntuple, 1 ) \
X( int, name_keyadr, nkey, 1 ) \
X( char, names, nnames, 1 )
//-------------------------------- mjData -----------------------------------------------
// pointer fields of mjData
#define MJDATA_POINTERS \
X( mjtNum, qpos, nq, 1 ) \
X( mjtNum, qvel, nv, 1 ) \
X( mjtNum, act, na, 1 ) \
X( mjtNum, qacc_warmstart, nv, 1 ) \
X( mjtNum, ctrl, nu, 1 ) \
X( mjtNum, qfrc_applied, nv, 1 ) \
X( mjtNum, xfrc_applied, nbody, 6 ) \
X( mjtNum, qacc, nv, 1 ) \
X( mjtNum, act_dot, na, 1 ) \
X( mjtNum, mocap_pos, nmocap, 3 ) \
X( mjtNum, mocap_quat, nmocap, 4 ) \
X( mjtNum, userdata, nuserdata, 1 ) \
X( mjtNum, sensordata, nsensordata,1 ) \
X( mjtNum, xpos, nbody, 3 ) \
X( mjtNum, xquat, nbody, 4 ) \
X( mjtNum, xmat, nbody, 9 ) \
X( mjtNum, xipos, nbody, 3 ) \
X( mjtNum, ximat, nbody, 9 ) \
X( mjtNum, xanchor, njnt, 3 ) \
X( mjtNum, xaxis, njnt, 3 ) \
X( mjtNum, geom_xpos, ngeom, 3 ) \
X( mjtNum, geom_xmat, ngeom, 9 ) \
X( mjtNum, site_xpos, nsite, 3 ) \
X( mjtNum, site_xmat, nsite, 9 ) \
X( mjtNum, cam_xpos, ncam, 3 ) \
X( mjtNum, cam_xmat, ncam, 9 ) \
X( mjtNum, light_xpos, nlight, 3 ) \
X( mjtNum, light_xdir, nlight, 3 ) \
X( mjtNum, subtree_com, nbody, 3 ) \
X( mjtNum, cdof, nv, 6 ) \
X( mjtNum, cinert, nbody, 10 ) \
X( int, ten_wrapadr, ntendon, 1 ) \
X( int, ten_wrapnum, ntendon, 1 ) \
X( int, ten_J_rownnz, ntendon, 1 ) \
X( int, ten_J_rowadr, ntendon, 1 ) \
X( int, ten_J_colind, ntendon, nv ) \
X( mjtNum, ten_length, ntendon, 1 ) \
X( mjtNum, ten_J, ntendon, nv ) \
X( int, wrap_obj, nwrap, 2 ) \
X( mjtNum, wrap_xpos, nwrap, 6 ) \
X( mjtNum, actuator_length, nu, 1 ) \
X( mjtNum, actuator_moment, nu, nv ) \
X( mjtNum, crb, nbody, 10 ) \
X( mjtNum, qM, nM, 1 ) \
X( mjtNum, qLD, nM, 1 ) \
X( mjtNum, qLDiagInv, nv, 1 ) \
X( mjtNum, qLDiagSqrtInv, nv, 1 ) \
X( mjContact, contact, nconmax, 1 ) \
X( int, efc_type, njmax, 1 ) \
X( int, efc_id, njmax, 1 ) \
X( int, efc_J_rownnz, njmax, 1 ) \
X( int, efc_J_rowadr, njmax, 1 ) \
X( int, efc_J_rowsuper, njmax, 1 ) \
X( int, efc_J_colind, njmax, nv ) \
X( int, efc_JT_rownnz, nv, 1 ) \
X( int, efc_JT_rowadr, nv, 1 ) \
X( int, efc_JT_rowsuper, nv, 1 ) \
X( int, efc_JT_colind, nv, njmax ) \
X( mjtNum, efc_J, njmax, nv ) \
X( mjtNum, efc_JT, nv, njmax ) \
X( mjtNum, efc_pos, njmax, 1 ) \
X( mjtNum, efc_margin, njmax, 1 ) \
X( mjtNum, efc_frictionloss, njmax, 1 ) \
X( mjtNum, efc_diagApprox, njmax, 1 ) \
X( mjtNum, efc_KBIP, njmax, 4 ) \
X( mjtNum, efc_D, njmax, 1 ) \
X( mjtNum, efc_R, njmax, 1 ) \
X( int, efc_AR_rownnz, njmax, 1 ) \
X( int, efc_AR_rowadr, njmax, 1 ) \
X( int, efc_AR_colind, njmax, njmax ) \
X( mjtNum, efc_AR, njmax, njmax ) \
X( mjtNum, ten_velocity, ntendon, 1 ) \
X( mjtNum, actuator_velocity, nu, 1 ) \
X( mjtNum, cvel, nbody, 6 ) \
X( mjtNum, cdof_dot, nv, 6 ) \
X( mjtNum, qfrc_bias, nv, 1 ) \
X( mjtNum, qfrc_passive, nv, 1 ) \
X( mjtNum, efc_vel, njmax, 1 ) \
X( mjtNum, efc_aref, njmax, 1 ) \
X( mjtNum, subtree_linvel, nbody, 3 ) \
X( mjtNum, subtree_angmom, nbody, 3 ) \
X( mjtNum, actuator_force, nu, 1 ) \
X( mjtNum, qfrc_actuator, nv, 1 ) \
X( mjtNum, qfrc_unc, nv, 1 ) \
X( mjtNum, qacc_unc, nv, 1 ) \
X( mjtNum, efc_b, njmax, 1 ) \
X( mjtNum, efc_force, njmax, 1 ) \
X( int, efc_state, njmax, 1 ) \
X( mjtNum, qfrc_constraint, nv, 1 ) \
X( mjtNum, qfrc_inverse, nv, 1 ) \
X( mjtNum, cacc, nbody, 6 ) \
X( mjtNum, cfrc_int, nbody, 6 ) \
X( mjtNum, cfrc_ext, nbody, 6 )
// scalar fields of mjData
#define MJDATA_SCALAR \
X( int, nstack ) \
X( int, nbuffer ) \
X( int, pstack ) \
X( int, maxuse_stack ) \
X( int, maxuse_con ) \
X( int, maxuse_efc ) \
X( int, solver_iter ) \
X( int, solver_nnz ) \
X( int, ne ) \
X( int, nf ) \
X( int, nefc ) \
X( int, ncon ) \
X( mjtNum, time )
// vector fields of mjData
#define MJDATA_VECTOR \
X( mjWarningStat, warning, mjNWARNING, 1 ) \
X( mjTimerStat, timer, mjNTIMER, 1 ) \
X( mjSolverStat, solver, mjNSOLVER, 1 ) \
X( mjtNum, solver_fwdinv, 2, 1 ) \
X( mjtNum, energy, 2, 1 )
#endif // MUJOCO_MJXMACRO_H_
+1099
View File
File diff suppressed because it is too large Load Diff
+322
View File
@@ -0,0 +1,322 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "uitools.h"
#include "stdio.h"
#include "string.h"
//-------------------------------- Internal GLFW callbacks ------------------------------
// update state
static void uiUpdateState(GLFWwindow* wnd)
{
// extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state;
// mouse buttons
state->left = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
state->right = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
state->middle = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
// keyboard modifiers
state->control = (glfwGetKey(wnd, GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_CONTROL)==GLFW_PRESS);
state->shift = (glfwGetKey(wnd, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
state->alt = (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS);
// swap left and right if Alt
if( state->alt )
{
int tmp = state->left;
state->left = state->right;
state->right = tmp;
}
// get mouse position, scale by buffer-to-window ratio
double x, y;
glfwGetCursorPos(wnd, &x, &y);
x *= ptr->buffer2window;
y *= ptr->buffer2window;
// invert y to match OpenGL convention
y = state->rect[0].height - y;
// save
state->dx = x - state->x;
state->dy = y - state->y;
state->x = x;
state->y = y;
// find mouse rectangle
state->mouserect = mjr_findRect(mju_round(x), mju_round(y),
state->nrect-1, state->rect+1) + 1;
}
// keyboard
static void uiKeyboard(GLFWwindow* wnd, int key, int scancode, int act, int mods)
{
// release: nothing to do
if( act==GLFW_RELEASE )
return;
// extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state;
// update state
uiUpdateState(wnd);
// set key info
state->type = mjEVENT_KEY;
state->key = key;
state->keytime = glfwGetTime();
// application-specific processing
ptr->uiEvent(state);
}
// mouse button
static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods)
{
// extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state;
// update state
uiUpdateState(wnd);
// translate button
if( button==GLFW_MOUSE_BUTTON_LEFT )
button = mjBUTTON_LEFT;
else if( button==GLFW_MOUSE_BUTTON_RIGHT )
button = mjBUTTON_RIGHT;
else
button = mjBUTTON_MIDDLE;
// swap left and right if Alt
if( glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS )
{
if( button==mjBUTTON_LEFT )
button = mjBUTTON_RIGHT;
else if( button==mjBUTTON_RIGHT )
button = mjBUTTON_LEFT;
}
// press
if( act==GLFW_PRESS )
{
// detect doubleclick: 250 ms
if( button==state->button && glfwGetTime()-state->buttontime<0.25 )
state->doubleclick = 1;
else
state->doubleclick = 0;
// set info
state->type = mjEVENT_PRESS;
state->button = button;
state->buttontime = glfwGetTime();
// start dragging
if( state->mouserect )
{
state->dragbutton = state->button;
state->dragrect = state->mouserect;
}
}
// release
else
state->type = mjEVENT_RELEASE;
// application-specific processing
ptr->uiEvent(state);
// stop dragging after application processing
if( state->type==mjEVENT_RELEASE )
{
state->dragrect = 0;
state->dragbutton = 0;
}
}
// mouse move
static void uiMouseMove(GLFWwindow* wnd, double xpos, double ypos)
{
// extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state;
// no buttons down: nothing to do
if( !state->left && !state->right && !state->middle )
return;
// update state
uiUpdateState(wnd);
// set move info
state->type = mjEVENT_MOVE;
// application-specific processing
ptr->uiEvent(state);
}
// scroll
static void uiScroll(GLFWwindow* wnd, double xoffset, double yoffset)
{
// extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state;
// update state
uiUpdateState(wnd);
// set scroll info, scale by buffer-to-window ratio
state->type = mjEVENT_SCROLL;
state->sx = xoffset * ptr->buffer2window;
state->sy = yoffset * ptr->buffer2window;
// application-specific processing
ptr->uiEvent(state);
}
// resize
static void uiResize(GLFWwindow* wnd, int width, int height)
{
// extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state;
// set layout
ptr->uiLayout(state);
// update state
uiUpdateState(wnd);
// set resize info
state->type = mjEVENT_RESIZE;
// stop dragging
state->dragbutton = 0;
state->dragrect = 0;
// application-specific processing (unless called with 0,0 from uiModify)
if( width && height )
ptr->uiEvent(state);
}
//----------------------------------- Public API ----------------------------------------
// Compute suitable font scale.
int uiFontScale(GLFWwindow* wnd)
{
// compute framebuffer-to-window ratio
int width_win, width_buf, height;
glfwGetWindowSize(wnd, &width_win, &height);
glfwGetFramebufferSize(wnd, &width_buf, &height);
double b2w = (double)width_buf / (double)width_win;
// compute PPI
int width_MM, height_MM;
glfwGetMonitorPhysicalSize(glfwGetPrimaryMonitor(), &width_MM, &height_MM);
int width_vmode = glfwGetVideoMode(glfwGetPrimaryMonitor())->width;
double PPI = 25.4 * b2w * (double)width_vmode / (double)width_MM;
// estimate font scaling, guard against unrealistic PPI
int fs;
if( width_buf>width_win )
fs = mju_round(b2w * 100);
else if( PPI>50 && PPI<350 )
fs = mju_round(PPI);
else
fs = 150;
fs = mju_round(fs * 0.02) * 50;
fs = mjMIN(300, mjMAX(100, fs));
return fs;
}
// Set internal and user-supplied UI callbacks in GLFW window.
void uiSetCallback(GLFWwindow* wnd, mjuiState* state,
uiEventFn uiEvent, uiLayoutFn uiLayout)
{
// make container with user-supplied objects and set window pointer
uiUserPointer* ptr = (uiUserPointer*) mju_malloc(sizeof(uiUserPointer));
ptr->state = state;
ptr->uiEvent = uiEvent;
ptr->uiLayout = uiLayout;
glfwSetWindowUserPointer(wnd, ptr);
// compute framebuffer-to-window pixel ratio
int width_win, width_buf, height;
glfwGetWindowSize(wnd, &width_win, &height);
glfwGetFramebufferSize(wnd, &width_buf, &height);
ptr->buffer2window = (double)width_buf / (double)width_win;
// set internal callbacks
glfwSetKeyCallback(wnd, uiKeyboard);
glfwSetCursorPosCallback(wnd, uiMouseMove);
glfwSetMouseButtonCallback(wnd, uiMouseButton);
glfwSetScrollCallback(wnd, uiScroll);
glfwSetWindowSizeCallback(wnd, uiResize);
}
// Clear UI callbacks in GLFW window.
void uiClearCallback(GLFWwindow* wnd)
{
// clear container
if( glfwGetWindowUserPointer(wnd) )
{
mju_free(glfwGetWindowUserPointer(wnd));
glfwSetWindowUserPointer(wnd, NULL);
}
// clear internal callbacks
glfwSetKeyCallback(wnd, NULL);
glfwSetCursorPosCallback(wnd, NULL);
glfwSetMouseButtonCallback(wnd, NULL);
glfwSetScrollCallback(wnd, NULL);
glfwSetWindowSizeCallback(wnd, NULL);
}
// Modify UI structure.
void uiModify(GLFWwindow* wnd, mjUI* ui, mjuiState* state, mjrContext* con)
{
mjui_resize(ui, con);
mjr_addAux(ui->auxid, ui->width, ui->maxheight, ui->spacing.samples, con);
uiResize(wnd, 0, 0);
mjui_update(-1, -1, ui, state, con);
}
+62
View File
@@ -0,0 +1,62 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_UITOOLS_H_
#define MUJOCO_UITOOLS_H_
#include "mujoco.h"
#include "glfw3.h"
// this is a C-API
#if defined(__cplusplus)
extern "C"
{
#endif
// User-supplied callback function types.
typedef void (*uiEventFn)(mjuiState* state);
typedef void (*uiLayoutFn)(mjuiState* state);
// Container for GLFW window pointer.
struct _uiUserPointer
{
mjuiState* state;
uiEventFn uiEvent;
uiLayoutFn uiLayout;
double buffer2window;
};
typedef struct _uiUserPointer uiUserPointer;
// Set internal and user-supplied UI callbacks in GLFW window.
void uiSetCallback(GLFWwindow* wnd, mjuiState* state,
uiEventFn uiEvent, uiLayoutFn uiLayout);
// Clear UI callbacks in GLFW window.
void uiClearCallback(GLFWwindow* wnd);
// Compute suitable font scale.
int uiFontScale(GLFWwindow* wnd);
// Modify UI structure.
void uiModify(GLFWwindow* wnd, mjUI* ui, mjuiState* state, mjrContext* con);
#if defined(__cplusplus)
}
#endif
#endif // MUJOCO_UITOOLS_H_
+121
View File
@@ -0,0 +1,121 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="2-link 6-muscle arm">
<option timestep="0.005" iterations="50" solver="Newton" tolerance="1e-10"/>
<size njmax="50" nconmax="10" nstack="200"/>
<visual>
<rgba haze=".3 .3 .3 1"/>
</visual>
<default>
<joint type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="0 120" damping="0.1"/>
<muscle ctrllimited="true" ctrlrange="0 1"/>
</default>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.6 0.6 0.6" rgb2="0 0 0" width="512" height="512"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".25 .25 .25" rgb2=".3 .3 .3" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
</asset>
<worldbody>
<geom name="floor" pos="0 0 -0.5" size="0 0 1" type="plane" material="matplane"/>
<light directional="true" diffuse=".8 .8 .8" specular=".2 .2 .2" pos="0 0 5" dir="0 0 -1"/>
<site name="s0" pos="-0.15 0 0" size="0.02"/>
<site name="x0" pos="0 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/>
<body pos="0 0 0">
<geom name="upper arm" type="capsule" size="0.045" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/>
<joint name="shoulder"/>
<geom name="shoulder" type="cylinder" pos="0 0 0" size=".1 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/>
<site name="s1" pos="0.15 0.06 0" size="0.02"/>
<site name="s2" pos="0.15 -0.06 0" size="0.02"/>
<site name="s3" pos="0.4 0.06 0" size="0.02"/>
<site name="s4" pos="0.4 -0.06 0" size="0.02"/>
<site name="s5" pos="0.25 0.1 0" size="0.02"/>
<site name="s6" pos="0.25 -0.1 0" size="0.02"/>
<site name="x1" pos="0.5 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/>
<body pos="0.5 0 0">
<geom name="forearm" type="capsule" size="0.035" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/>
<joint name="elbow"/>
<geom name="elbow" type="cylinder" pos="0 0 0" size=".08 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/>
<site name="s7" pos="0.11 0.05 0" size="0.02"/>
<site name="s8" pos="0.11 -0.05 0" size="0.02"/>
</body>
</body>
</worldbody>
<tendon>
<spatial name="SF" width="0.01">
<site site="s0"/>
<geom geom="shoulder"/>
<site site="s1"/>
</spatial>
<spatial name="SE" width="0.01">
<site site="s0"/>
<geom geom="shoulder" sidesite="x0"/>
<site site="s2"/>
</spatial>
<spatial name="EF" width="0.01">
<site site="s3"/>
<geom geom="elbow"/>
<site site="s7"/>
</spatial>
<spatial name="EE" width="0.01">
<site site="s4"/>
<geom geom="elbow" sidesite="x1"/>
<site site="s8"/>
</spatial>
<spatial name="BF" width="0.009" rgba=".4 .6 .4 1">
<site site="s0"/>
<geom geom="shoulder"/>
<site site="s5"/>
<geom geom="elbow"/>
<site site="s7"/>
</spatial>
<spatial name="BE" width="0.009" rgba=".4 .6 .4 1">
<site site="s0"/>
<geom geom="shoulder" sidesite="x0"/>
<site site="s6"/>
<geom geom="elbow" sidesite="x1"/>
<site site="s8"/>
</spatial>
</tendon>
<actuator>
<muscle name="SF" tendon="SF"/>
<muscle name="SE" tendon="SE"/>
<muscle name="EF" tendon="EF"/>
<muscle name="EE" tendon="EE"/>
<muscle name="BF" tendon="BF"/>
<muscle name="BE" tendon="BE"/>
</actuator>
</mujoco>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+36
View File
@@ -0,0 +1,36 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Cloth">
<include file="scene.xml"/>
<option timestep="0.002" solver="CG" tolerance="1e-6"/>
<size nconmax="300" njmax="1000" nstack="1000000"/>
<worldbody>
<body name="B3_5" pos="0 0 1">
<freejoint/>
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
<joint kind="main" damping="0.001"/>
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
+29
View File
@@ -0,0 +1,29 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="1D grid">
<include file="scene.xml"/>
<size nconmax="50" njmax="300" nstack="50000"/>
<worldbody>
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
<joint kind="main" damping="0.001"/>
<tendon kind="main" width="0.01"/>
<geom size=".02" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
</mujoco>
+31
View File
@@ -0,0 +1,31 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="1D grid with pins">
<include file="scene.xml"/>
<size nconmax="50" njmax="300" nstack="50000"/>
<worldbody>
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
<joint kind="main" damping="0.001"/>
<tendon kind="main" width="0.01"/>
<pin coord="1"/>
<pin coord="13"/>
<geom size=".02" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
</mujoco>
+28
View File
@@ -0,0 +1,28 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="2D grid">
<include file="scene.xml"/>
<size nconmax="300" njmax="1000" nstack="1000000"/>
<worldbody>
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
<geom size=".02"/>
</composite>
</worldbody>
</mujoco>
+30
View File
@@ -0,0 +1,30 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="2D grid with pins">
<include file="scene.xml"/>
<size nconmax="200" njmax="1000" nstack="1000000"/>
<worldbody>
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
<skin rgba=".6 .1 .6 1" inflate="0.001" subgrid="3"/>
<pin coord="0 0"/>
<pin coord="8 0"/>
<geom size=".02"/>
</composite>
</worldbody>
</mujoco>
+165
View File
@@ -0,0 +1,165 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Hammock">
<compiler inertiafromgeom="true" angle="degree"/>
<default>
<default class="humanoid">
<joint limited="true" damping="1" armature="0"/>
<geom condim="1" material="matgeom"/>
</default>
<motor ctrlrange="-.4 .4" ctrllimited="true"/>
</default>
<option timestep="0.005" solver="CG" iterations="30" tolerance="1e-6" jacobian="sparse" cone="pyramidal"/>
<size njmax="1000" nconmax="100" nstack="1000000"/>
<visual>
<map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="2048"/>
<global offwidth="800" offheight="800"/>
</visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<texture name="texhammock" type="2d" builtin="checker" rgb1=".1 .5 .1" rgb2=".5 .1 .1" width="512" height="512" mark="edge" markrgb=".8 .8 .8"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278"
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name="mathammock" texture="texhammock"/>
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
</asset>
<worldbody>
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="matplane" condim="3"/>
<light directional="true" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
<light directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/>
<composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
<skin texcoord="true" material="mathammock" inflate="0.01" subgrid="3"/>
<pin coord="0 0"/>
<pin coord="10 0"/>
<pin coord="0 8"/>
<pin coord="10 8"/>
<geom size=".095"/>
<joint kind="main" damping="10"/>
</composite>
<body name="torso" childclass="humanoid" pos="0 0 1.4">
<freejoint name="root"/>
<geom name="torso1" type="capsule" fromto="0 -.07 0 0 .07 0" size="0.07"/>
<geom name="head" type="sphere" pos="0 0 .19" size=".09"/>
<geom name="uwaist" type="capsule" fromto="-.01 -.06 -.12 -.01 .06 -.12" size="0.06"/>
<body name="lwaist" pos="-.01 0 -0.260" quat="1.000 0 -0.002 0" >
<geom name="lwaist" type="capsule" fromto="0 -.06 0 0 .06 0" size="0.06" />
<joint name="abdomen_z" type="hinge" pos="0 0 0.065" axis="0 0 1" range="-45 45" damping="5" stiffness="20" armature="0.02" />
<joint name="abdomen_y" type="hinge" pos="0 0 0.065" axis="0 1 0" range="-75 30" damping="5" stiffness="10" armature="0.02" />
<body name="pelvis" pos="0 0 -0.165" quat="1.000 0 -0.002 0" >
<joint name="abdomen_x" type="hinge" pos="0 0 0.1" axis="1 0 0" range="-35 35" damping="5" stiffness="10" armature="0.02" />
<geom name="butt" type="capsule" fromto="-.02 -.07 0 -.02 .07 0" size="0.09" />
<body name="right_thigh" pos="0 -0.1 -0.04" >
<joint name="right_hip_x" type="hinge" pos="0 0 0" axis="1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" />
<joint name="right_hip_z" type="hinge" pos="0 0 0" axis="0 0 1" range="-60 35" damping="5" stiffness="10" armature="0.01" />
<joint name="right_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" />
<geom name="right_thigh1" type="capsule" fromto="0 0 0 0 0.01 -.34" size="0.06" />
<body name="right_shin" pos="0 0.01 -0.403" >
<joint name="right_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" />
<geom name="right_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" />
<body name="right_foot" pos="0 0 -.39" >
<joint name="right_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" />
<joint name="right_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" />
<geom name="right_foot_cap1" type="capsule" fromto="-.07 -0.02 0 0.14 -0.04 0" size="0.027" />
<geom name="right_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 0.02 0" size="0.027" />
</body>
</body>
</body>
<body name="left_thigh" pos="0 0.1 -0.04" >
<joint name="left_hip_x" type="hinge" pos="0 0 0" axis="-1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" />
<joint name="left_hip_z" type="hinge" pos="0 0 0" axis="0 0 -1" range="-60 35" damping="5" stiffness="10" armature="0.01" />
<joint name="left_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" />
<geom name="left_thigh1" type="capsule" fromto="0 0 0 0 -0.01 -.34" size="0.06" />
<body name="left_shin" pos="0 -0.01 -0.403" >
<joint name="left_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" />
<geom name="left_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" />
<body name="left_foot" pos="0 0 -.39" >
<joint name="left_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" />
<joint name="left_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" />
<geom name="left_foot_cap1" type="capsule" fromto="-.07 0.02 0 0.14 0.04 0" size="0.027" />
<geom name="left_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 -0.02 0" size="0.027" />
</body>
</body>
</body>
</body>
</body>
<body name="right_upper_arm" pos="0 -0.17 0.06" >
<joint name="right_shoulder1" type="hinge" pos="0 0 0" axis="2 1 1" range="-85 60" stiffness="1" armature="0.0068" />
<joint name="right_shoulder2" type="hinge" pos="0 0 0" axis="0 -1 1" range="-85 60" stiffness="1" armature="0.0051" />
<geom name="right_uarm1" type="capsule" fromto="0 0 0 .16 -.16 -.16" size="0.04 0.16" />
<body name="right_lower_arm" pos=".18 -.18 -.18" >
<joint name="right_elbow" type="hinge" pos="0 0 0" axis="0 -1 1" range="-90 50" stiffness="0" armature="0.0028" />
<geom name="right_larm" type="capsule" fromto="0.01 0.01 0.01 .17 .17 .17" size="0.031" />
<geom name="right_hand" type="sphere" pos=".18 .18 .18" size="0.04"/>
</body>
</body>
<body name="left_upper_arm" pos="0 0.17 0.06" >
<joint name="left_shoulder1" type="hinge" pos="0 0 0" axis="2 -1 1" range="-60 85" stiffness="1" armature="0.0068" />
<joint name="left_shoulder2" type="hinge" pos="0 0 0" axis="0 1 1" range="-60 85" stiffness="1" armature="0.0051" />
<geom name="left_uarm1" type="capsule" fromto="0 0 0 .16 .16 -.16" size="0.04 0.16" />
<body name="left_lower_arm" pos=".18 .18 -.18" >
<joint name="left_elbow" type="hinge" pos="0 0 0" axis="0 -1 -1" range="-90 50" stiffness="0" armature="0.0028" />
<geom name="left_larm" type="capsule" fromto="0.01 -0.01 0.01 .17 -.17 .17" size="0.031" />
<geom name="left_hand" type="sphere" pos=".18 -.18 .18" size="0.04"/>
</body>
</body>
</body>
</worldbody>
<actuator>
<motor name="abdomen_y" gear="200" joint="abdomen_y" />
<motor name="abdomen_z" gear="200" joint="abdomen_z" />
<motor name="abdomen_x" gear="200" joint="abdomen_x" />
<motor name="right_hip_x" gear="200" joint="right_hip_x" />
<motor name="right_hip_z" gear="200" joint="right_hip_z" />
<motor name="right_hip_y" gear="600" joint="right_hip_y" />
<motor name="right_knee" gear="400" joint="right_knee" />
<motor name="right_ankle_x" gear="100" joint="right_ankle_x" />
<motor name="right_ankle_y" gear="100" joint="right_ankle_y" />
<motor name="left_hip_x" gear="200" joint="left_hip_x" />
<motor name="left_hip_z" gear="200" joint="left_hip_z" />
<motor name="left_hip_y" gear="600" joint="left_hip_y" />
<motor name="left_knee" gear="400" joint="left_knee" />
<motor name="left_ankle_x" gear="100" joint="left_ankle_x" />
<motor name="left_ankle_y" gear="100" joint="left_ankle_y" />
<motor name="right_shoulder1" gear="100" joint="right_shoulder1" />
<motor name="right_shoulder2" gear="100" joint="right_shoulder2" />
<motor name="right_elbow" gear="200" joint="right_elbow" />
<motor name="left_shoulder1" gear="100" joint="left_shoulder1" />
<motor name="left_shoulder2" gear="100" joint="left_shoulder2" />
<motor name="left_elbow" gear="200" joint="left_elbow" />
</actuator>
</mujoco>
+149
View File
@@ -0,0 +1,149 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Humanoid">
<compiler inertiafromgeom="true" angle="degree"/>
<default>
<joint limited="true" damping="1" armature="0"/>
<geom condim="1" material="matgeom"/>
<motor ctrlrange="-.4 .4" ctrllimited="true"/>
</default>
<option timestep="0.005" iterations="50" tolerance="1e-10" solver="Newton" jacobian="dense" cone="pyramidal"/>
<size nconmax="50" njmax="200" nstack="10000"/>
<visual>
<map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="2048"/>
<global offwidth="800" offheight="800"/>
</visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278"
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
</asset>
<worldbody>
<geom name="floor" pos="0 0 0" size="0 0 .25" type="plane" material="matplane" condim="3"/>
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
<light mode="targetbodycom" target="torso" directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/>
<body name="torso" pos="0 0 1.4">
<freejoint name="root"/>
<geom name="torso1" type="capsule" fromto="0 -.07 0 0 .07 0" size="0.07"/>
<geom name="head" type="sphere" pos="0 0 .19" size=".09"/>
<geom name="uwaist" type="capsule" fromto="-.01 -.06 -.12 -.01 .06 -.12" size="0.06"/>
<body name="lwaist" pos="-.01 0 -0.260" quat="1.000 0 -0.002 0" >
<geom name="lwaist" type="capsule" fromto="0 -.06 0 0 .06 0" size="0.06" />
<joint name="abdomen_z" type="hinge" pos="0 0 0.065" axis="0 0 1" range="-45 45" damping="5" stiffness="20" armature="0.02" />
<joint name="abdomen_y" type="hinge" pos="0 0 0.065" axis="0 1 0" range="-75 30" damping="5" stiffness="10" armature="0.02" />
<body name="pelvis" pos="0 0 -0.165" quat="1.000 0 -0.002 0" >
<joint name="abdomen_x" type="hinge" pos="0 0 0.1" axis="1 0 0" range="-35 35" damping="5" stiffness="10" armature="0.02" />
<geom name="butt" type="capsule" fromto="-.02 -.07 0 -.02 .07 0" size="0.09" />
<body name="right_thigh" pos="0 -0.1 -0.04" >
<joint name="right_hip_x" type="hinge" pos="0 0 0" axis="1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" />
<joint name="right_hip_z" type="hinge" pos="0 0 0" axis="0 0 1" range="-60 35" damping="5" stiffness="10" armature="0.01" />
<joint name="right_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" />
<geom name="right_thigh1" type="capsule" fromto="0 0 0 0 0.01 -.34" size="0.06" />
<body name="right_shin" pos="0 0.01 -0.403" >
<joint name="right_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" />
<geom name="right_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" />
<body name="right_foot" pos="0 0 -.39" >
<joint name="right_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" />
<joint name="right_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" />
<geom name="right_foot_cap1" type="capsule" fromto="-.07 -0.02 0 0.14 -0.04 0" size="0.027" />
<geom name="right_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 0.02 0" size="0.027" />
</body>
</body>
</body>
<body name="left_thigh" pos="0 0.1 -0.04" >
<joint name="left_hip_x" type="hinge" pos="0 0 0" axis="-1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" />
<joint name="left_hip_z" type="hinge" pos="0 0 0" axis="0 0 -1" range="-60 35" damping="5" stiffness="10" armature="0.01" />
<joint name="left_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" />
<geom name="left_thigh1" type="capsule" fromto="0 0 0 0 -0.01 -.34" size="0.06" />
<body name="left_shin" pos="0 -0.01 -0.403" >
<joint name="left_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" />
<geom name="left_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" />
<body name="left_foot" pos="0 0 -.39" >
<joint name="left_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" />
<joint name="left_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" />
<geom name="left_foot_cap1" type="capsule" fromto="-.07 0.02 0 0.14 0.04 0" size="0.027" />
<geom name="left_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 -0.02 0" size="0.027" />
</body>
</body>
</body>
</body>
</body>
<body name="right_upper_arm" pos="0 -0.17 0.06" >
<joint name="right_shoulder1" type="hinge" pos="0 0 0" axis="2 1 1" range="-85 60" stiffness="1" armature="0.0068" />
<joint name="right_shoulder2" type="hinge" pos="0 0 0" axis="0 -1 1" range="-85 60" stiffness="1" armature="0.0051" />
<geom name="right_uarm1" type="capsule" fromto="0 0 0 .16 -.16 -.16" size="0.04 0.16" />
<body name="right_lower_arm" pos=".18 -.18 -.18" >
<joint name="right_elbow" type="hinge" pos="0 0 0" axis="0 -1 1" range="-90 50" stiffness="0" armature="0.0028" />
<geom name="right_larm" type="capsule" fromto="0.01 0.01 0.01 .17 .17 .17" size="0.031" />
<geom name="right_hand" type="sphere" pos=".18 .18 .18" size="0.04"/>
</body>
</body>
<body name="left_upper_arm" pos="0 0.17 0.06" >
<joint name="left_shoulder1" type="hinge" pos="0 0 0" axis="2 -1 1" range="-60 85" stiffness="1" armature="0.0068" />
<joint name="left_shoulder2" type="hinge" pos="0 0 0" axis="0 1 1" range="-60 85" stiffness="1" armature="0.0051" />
<geom name="left_uarm1" type="capsule" fromto="0 0 0 .16 .16 -.16" size="0.04 0.16" />
<body name="left_lower_arm" pos=".18 .18 -.18" >
<joint name="left_elbow" type="hinge" pos="0 0 0" axis="0 -1 -1" range="-90 50" stiffness="0" armature="0.0028" />
<geom name="left_larm" type="capsule" fromto="0.01 -0.01 0.01 .17 -.17 .17" size="0.031" />
<geom name="left_hand" type="sphere" pos=".18 -.18 .18" size="0.04"/>
</body>
</body>
</body>
</worldbody>
<actuator>
<motor name="abdomen_y" gear="200" joint="abdomen_y" />
<motor name="abdomen_z" gear="200" joint="abdomen_z" />
<motor name="abdomen_x" gear="200" joint="abdomen_x" />
<motor name="right_hip_x" gear="200" joint="right_hip_x" />
<motor name="right_hip_z" gear="200" joint="right_hip_z" />
<motor name="right_hip_y" gear="600" joint="right_hip_y" />
<motor name="right_knee" gear="400" joint="right_knee" />
<motor name="right_ankle_x" gear="100" joint="right_ankle_x" />
<motor name="right_ankle_y" gear="100" joint="right_ankle_y" />
<motor name="left_hip_x" gear="200" joint="left_hip_x" />
<motor name="left_hip_z" gear="200" joint="left_hip_z" />
<motor name="left_hip_y" gear="600" joint="left_hip_y" />
<motor name="left_knee" gear="400" joint="left_knee" />
<motor name="left_ankle_x" gear="100" joint="left_ankle_x" />
<motor name="left_ankle_y" gear="100" joint="left_ankle_y" />
<motor name="right_shoulder1" gear="100" joint="right_shoulder1" />
<motor name="right_shoulder2" gear="100" joint="right_shoulder2" />
<motor name="right_elbow" gear="200" joint="right_elbow" />
<motor name="left_shoulder1" gear="100" joint="left_shoulder1" />
<motor name="left_shoulder2" gear="100" joint="left_shoulder2" />
<motor name="left_elbow" gear="200" joint="left_elbow" />
</actuator>
</mujoco>
+592
View File
@@ -0,0 +1,592 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Humanoid and 100 objects">
<compiler angle="degree"/>
<option timestep="0.005" iterations="50" solver="Newton" jacobian="sparse" cone="pyramidal" tolerance="1e-10"/>
<size njmax="1500" nconmax="500" nstack="5000000"/>
<default>
<geom solimp=".9 .9 .01"/>
<default class="humanoid">
<geom material="humanoid"/>
<joint damping="1" limited="true"/>
</default>
<default class="object1">
<geom type="capsule" material="object1" size="0.1 0.05"/>
</default>
<default class="object2">
<geom type="ellipsoid" material="object2" size="0.15 0.1 0.07"/>
</default>
<default class="object3">
<geom type="box" material="object3" size="0.15 0.1 0.05"/>
</default>
<default class="object4">
<geom type="cylinder" material="object4" size="0.1 0.05" condim="4" friction="1 .01 .01"/>
</default>
<default class="object5">
<geom type="sphere" material="object5" size="0.1"/>
</default>
<default class="border">
<geom type="capsule" size="0.4" rgba=".4 .4 .4 1"/>
</default>
<default class="borderpost">
<geom type="box" size="0.41 0.41 0.41" rgba=".55 .55 .55 1"/>
</default>
</default>
<asset>
<texture type="skybox" builtin="gradient" width="128" height="128" rgb1=".4 .6 .8" rgb2="0 0 0"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="128" height="128"
rgb1="0.6 0.6 0.6" rgb2="0.6 0.6 0.6" markrgb="1 1 1"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".4 .4 .4" rgb2=".6 .6 .6"
width="512" height="512"/>
<material name='MatPlane' reflectance='0.3' texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name='humanoid' texture="texgeom" texuniform="true" rgba="1.2 1.2 0.6 1"/>
<material name='object1' texture="texgeom" texuniform="true" rgba=".4 .9 .6 1" />
<material name='object2' texture="texgeom" texuniform="true" rgba=".4 .6 .9 1" />
<material name='object3' texture="texgeom" texuniform="true" rgba=".4 .9 .9 1" />
<material name='object4' texture="texgeom" texuniform="true" rgba=".8 .6 .8 1" />
<material name='object5' texture="texgeom" texuniform="true" rgba=".9 .1 .1 1" />
</asset>
<visual>
<quality shadowsize="4096" offsamples="8"/>
<map znear="0.1" force="0.05"/>
</visual>
<statistic extent="4"/>
<worldbody>
<light directional="true" diffuse=".8 .8 .8" pos="0 0 10" dir="0 0 -10"/>
<geom pos="0 0 0" type="plane" size="3 3 .5" rgba=".7 .7 .7 1" material="MatPlane"/>
<geom class="border" fromto="-3 3 0 3 3 0" />
<geom class="border" fromto="-3 -3 0 3 -3 0" />
<geom class="border" fromto="3 3 0 3 -3 0" />
<geom class="border" fromto="-3 3 0 -3 -3 0" />
<geom class="borderpost" pos="3 3 0"/>
<geom class="borderpost" pos="-3 3 0"/>
<geom class="borderpost" pos="3 -3 0"/>
<geom class="borderpost" pos="-3 -3 0"/>
<body name='torso' pos='0 0 1.4' childclass="humanoid">
<freejoint name="root"/>
<geom name='torso1' type='capsule' fromto='0 -.07 0 0 .07 0' size='0.07'/>
<geom name='head' type='sphere' pos='0 0 .19' size='.09'/>
<geom name='uwaist' type='capsule' fromto='-.01 -.06 -.12 -.01 .06 -.12' size='0.06'/>
<body name='lwaist' pos='-.01 0 -0.260' quat='1.000 0 -0.002 0' >
<geom name='lwaist' type='capsule' fromto='0 -.06 0 0 .06 0' size='0.06' />
<joint name='abdomen_z' type='hinge' pos='0 0 0.065' axis='0 0 1' range='-45 45' damping='5' stiffness='20' armature='0.02' />
<joint name='abdomen_y' type='hinge' pos='0 0 0.065' axis='0 1 0' range='-75 30' damping='5' stiffness='10' armature='0.02' />
<body name='pelvis' pos='0 0 -0.165' quat='1.000 0 -0.002 0' >
<joint name='abdomen_x' type='hinge' pos='0 0 0.1' axis='1 0 0' range='-35 35' damping='5' stiffness='10' armature='0.02' />
<geom name='butt' type='capsule' fromto='-.02 -.07 0 -.02 .07 0' size='0.09' />
<body name='right_thigh' pos='0 -0.1 -0.04' >
<joint name='right_hip_x' type='hinge' pos='0 0 0' axis='1 0 0' range='-25 5' damping='5' stiffness='10' armature='0.01' />
<joint name='right_hip_z' type='hinge' pos='0 0 0' axis='0 0 1' range='-60 35' damping='5' stiffness='10' armature='0.01' />
<joint name='right_hip_y' type='hinge' pos='0 0 0' axis='0 1 0' range='-120 20' damping='5' stiffness='20' armature='0.01' />
<geom name='right_thigh1' type='capsule' fromto='0 0 0 0 0.01 -.34' size='0.06' />
<body name='right_shin' pos='0 0.01 -0.403' >
<joint name='right_knee' type='hinge' pos='0 0 .02' axis='0 -1 0' range='-160 -2' stiffness='1' armature='0.0060' />
<geom name='right_shin1' type='capsule' fromto='0 0 0 0 0 -.3' size='0.049' />
<body name='right_foot' pos='0 0 -.39' >
<joint name='right_ankle_y' type='hinge' pos='0 0 0.08' axis='0 1 0' range='-50 50' stiffness='4' armature='0.0008' />
<joint name='right_ankle_x' type='hinge' pos='0 0 0.04' axis='1 0 0.5' range='-50 50' stiffness='1' armature='0.0006' />
<geom name='right_foot_cap1' type='capsule' fromto='-.07 -0.02 0 0.14 -0.04 0' size='0.027' />
<geom name='right_foot_cap2' type='capsule' fromto='-.07 0 0 0.14 0.02 0' size='0.027' />
</body>
</body>
</body>
<body name='left_thigh' pos='0 0.1 -0.04' >
<joint name='left_hip_x' type='hinge' pos='0 0 0' axis='-1 0 0' range='-25 5' damping='5' stiffness='10' armature='0.01' />
<joint name='left_hip_z' type='hinge' pos='0 0 0' axis='0 0 -1' range='-60 35' damping='5' stiffness='10' armature='0.01' />
<joint name='left_hip_y' type='hinge' pos='0 0 0' axis='0 1 0' range='-120 20' damping='5' stiffness='20' armature='0.01' />
<geom name='left_thigh1' type='capsule' fromto='0 0 0 0 -0.01 -.34' size='0.06' />
<body name='left_shin' pos='0 -0.01 -0.403' >
<joint name='left_knee' type='hinge' pos='0 0 .02' axis='0 -1 0' range='-160 -2' stiffness='1' armature='0.0060' />
<geom name='left_shin1' type='capsule' fromto='0 0 0 0 0 -.3' size='0.049' />
<body name='left_foot' pos='0 0 -.39' >
<joint name='left_ankle_y' type='hinge' pos='0 0 0.08' axis='0 1 0' range='-50 50' stiffness='4' armature='0.0008' />
<joint name='left_ankle_x' type='hinge' pos='0 0 0.04' axis='1 0 0.5' range='-50 50' stiffness='1' armature='0.0006' />
<geom name='left_foot_cap1' type='capsule' fromto='-.07 0.02 0 0.14 0.04 0' size='0.027' />
<geom name='left_foot_cap2' type='capsule' fromto='-.07 0 0 0.14 -0.02 0' size='0.027' />
</body>
</body>
</body>
</body>
</body>
<body name='right_upper_arm' pos='0 -0.17 0.06' >
<joint name='right_shoulder1' type='hinge' pos='0 0 0' axis='2 1 1' range='-85 60' stiffness='1' armature='0.0068' />
<joint name='right_shoulder2' type='hinge' pos='0 0 0' axis='0 -1 1' range='-85 60' stiffness='1' armature='0.0051' />
<geom name='right_uarm1' type='capsule' fromto='0 0 0 .16 -.16 -.16' size='0.04 0.16' />
<body name='right_lower_arm' pos='.18 -.18 -.18' >
<joint name='right_elbow' type='hinge' pos='0 0 0' axis='0 -1 1' range='-90 50' stiffness='0' armature='0.0028' />
<geom name='right_larm' type='capsule' fromto='0.01 0.01 0.01 .17 .17 .17' size='0.031' />
<geom name='right_hand' type='sphere' pos='.18 .18 .18' size='0.04'/>
</body>
</body>
<body name='left_upper_arm' pos='0 0.17 0.06' >
<joint name='left_shoulder1' type='hinge' pos='0 0 0' axis='2 -1 1' range='-60 85' stiffness='1' armature='0.0068' />
<joint name='left_shoulder2' type='hinge' pos='0 0 0' axis='0 1 1' range='-60 85' stiffness='1' armature='0.0051' />
<geom name='left_uarm1' type='capsule' fromto='0 0 0 .16 .16 -.16' size='0.04 0.16' />
<body name='left_lower_arm' pos='.18 .18 -.18' >
<joint name='left_elbow' type='hinge' pos='0 0 0' axis='0 -1 -1' range='-90 50' stiffness='0' armature='0.0028' />
<geom name='left_larm' type='capsule' fromto='0.01 -0.01 0.01 .17 -.17 .17' size='0.031' />
<geom name='left_hand' type='sphere' pos='.18 -.18 .18' size='0.04'/>
</body>
</body>
</body>
<body pos="-2 -2 1" quat="-0.632456 -0.632456 0.316228 0.316228">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -2 2" quat="-0.5547 -0.5547 0.5547 0.27735">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -2 3" quat="-0.471405 -0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -2 4" quat="-0.471405 -0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -1 1" quat="-0.755929 -0.377964 0.377964 0.377964">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -1 2" quat="-0.632456 -0.316228 0.632456 0.316228">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -1 3" quat="-0.516398 -0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 -1 4" quat="-0.516398 -0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 0 1" quat="-0.816497 0 0.408248 0.408248">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 0 2" quat="-0.666667 0 0.666667 0.333333">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 0 3" quat="-0.534522 0 0.801784 0.267261">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 0 4" quat="-0.534522 0 0.801784 0.267261">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 1 1" quat="-0.755929 0.377964 0.377964 0.377964">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 1 2" quat="-0.632456 0.316228 0.632456 0.316228">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 1 3" quat="-0.516398 0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 1 4" quat="-0.516398 0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 2 1" quat="-0.632456 0.632456 0.316228 0.316228">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 2 2" quat="-0.5547 0.5547 0.5547 0.27735">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 2 3" quat="-0.471405 0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-2 2 4" quat="-0.471405 0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object1"/>
</body>
<body pos="-1 -2 1" quat="-0.377964 -0.755929 0.377964 0.377964">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -2 2" quat="-0.316228 -0.632456 0.632456 0.316228">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -2 3" quat="-0.258199 -0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -2 4" quat="-0.258199 -0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -1 1" quat="-0.5 -0.5 0.5 0.5">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -1 2" quat="-0.377964 -0.377964 0.755929 0.377964">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -1 3" quat="-0.288675 -0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 -1 4" quat="-0.288675 -0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 0 1" quat="-0.57735 0 0.57735 0.57735">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 0 2" quat="-0.408248 0 0.816497 0.408248">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 0 3" quat="-0.301511 0 0.904534 0.301511">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 0 4" quat="-0.301511 0 0.904534 0.301511">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 1 1" quat="-0.5 0.5 0.5 0.5">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 1 2" quat="-0.377964 0.377964 0.755929 0.377964">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 1 3" quat="-0.288675 0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 1 4" quat="-0.288675 0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 2 1" quat="-0.377964 0.755929 0.377964 0.377964">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 2 2" quat="-0.316228 0.632456 0.632456 0.316228">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 2 3" quat="-0.258199 0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="-1 2 4" quat="-0.258199 0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object2"/>
</body>
<body pos="0 -2 1" quat="0 -0.816497 0.408248 0.408248">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -2 2" quat="0 -0.666667 0.666667 0.333333">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -2 3" quat="0 -0.534522 0.801784 0.267261">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -2 4" quat="0 -0.534522 0.801784 0.267261">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -1 1" quat="0 -0.57735 0.57735 0.57735">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -1 2" quat="0 -0.408248 0.816497 0.408248">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -1 3" quat="0 -0.301511 0.904534 0.301511">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 -1 4" quat="0 -0.301511 0.904534 0.301511">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0.3 0 1" quat="0 0 0.707107 0.707107">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 0 2" quat="0 0 0.894427 0.447214">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 0 3" quat="0 0 0.948683 0.316228">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 0 4" quat="0 0 0.948683 0.316228">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 1 1" quat="0 0.57735 0.57735 0.57735">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 1 2" quat="0 0.408248 0.816497 0.408248">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 1 3" quat="0 0.301511 0.904534 0.301511">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 1 4" quat="0 0.301511 0.904534 0.301511">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 2 1" quat="0 0.816497 0.408248 0.408248">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 2 2" quat="0 0.666667 0.666667 0.333333">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 2 3" quat="0 0.534522 0.801784 0.267261">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="0 2 4" quat="0 0.534522 0.801784 0.267261">
<freejoint/>
<geom class="object3"/>
</body>
<body pos="1 -2 1" quat="0.377964 -0.755929 0.377964 0.377964">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -2 2" quat="0.316228 -0.632456 0.632456 0.316228">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -2 3" quat="0.258199 -0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -2 4" quat="0.258199 -0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -1 1" quat="0.5 -0.5 0.5 0.5">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -1 2" quat="0.377964 -0.377964 0.755929 0.377964">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -1 3" quat="0.288675 -0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 -1 4" quat="0.288675 -0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 0 1" quat="0.57735 0 0.57735 0.57735">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 0 2" quat="0.408248 0 0.816497 0.408248">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 0 3" quat="0.301511 0 0.904534 0.301511">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 0 4" quat="0.301511 0 0.904534 0.301511">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 1 1" quat="0.5 0.5 0.5 0.5">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 1 2" quat="0.377964 0.377964 0.755929 0.377964">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 1 3" quat="0.288675 0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 1 4" quat="0.288675 0.288675 0.866025 0.288675">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 2 1" quat="0.377964 0.755929 0.377964 0.377964">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 2 2" quat="0.316228 0.632456 0.632456 0.316228">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 2 3" quat="0.258199 0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="1 2 4" quat="0.258199 0.516398 0.774597 0.258199">
<freejoint/>
<geom class="object4"/>
</body>
<body pos="2 -2 1" quat="0.632456 -0.632456 0.316228 0.316228">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -2 2" quat="0.5547 -0.5547 0.5547 0.27735">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -2 3" quat="0.471405 -0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -2 4" quat="0.471405 -0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -1 1" quat="0.755929 -0.377964 0.377964 0.377964">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -1 2" quat="0.632456 -0.316228 0.632456 0.316228">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -1 3" quat="0.516398 -0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 -1 4" quat="0.516398 -0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 0 1" quat="0.816497 0 0.408248 0.408248">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 0 2" quat="0.666667 0 0.666667 0.333333">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 0 3" quat="0.534522 0 0.801784 0.267261">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 0 4" quat="0.534522 0 0.801784 0.267261">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 1 1" quat="0.755929 0.377964 0.377964 0.377964">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 1 2" quat="0.632456 0.316228 0.632456 0.316228">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 1 3" quat="0.516398 0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 1 4" quat="0.516398 0.258199 0.774597 0.258199">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 2 1" quat="0.632456 0.632456 0.316228 0.316228">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 2 2" quat="0.5547 0.5547 0.5547 0.27735">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 2 3" quat="0.471405 0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object5"/>
</body>
<body pos="2 2 4" quat="0.471405 0.471405 0.707107 0.235702">
<freejoint/>
<geom class="object5"/>
</body>
</worldbody>
</mujoco>
Executable
+33
View File
@@ -0,0 +1,33 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Loop">
<include file="scene.xml"/>
<option timestep="0.002" jacobian="dense"/>
<size nconmax="100" njmax="300" nstack="50000"/>
<worldbody>
<body name="B0" pos="0 0 1">
<freejoint/>
<composite type="loop" count="20 1 1" spacing="0.04" offset="0 0 2">
<joint kind="main" damping="0.005"/>
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

+33
View File
@@ -0,0 +1,33 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Particle">
<include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/>
<size nconmax="3000" njmax="3000" nstack="50000000"/>
<visual>
<map stiffness="100"/>
</visual>
<worldbody>
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
<geom size=".02" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
</mujoco>
Executable
+33
View File
@@ -0,0 +1,33 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Rope">
<include file="scene.xml"/>
<option timestep="0.002" jacobian="dense"/>
<size nconmax="100" njmax="300" nstack="50000"/>
<worldbody>
<body name="B10" pos="0 0 1">
<freejoint/>
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
<joint kind="main" damping="0.005"/>
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
+52
View File
@@ -0,0 +1,52 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco>
<statistic extent="2" meansize=".05"/>
<option timestep="0.005" solver="Newton" iterations="30" tolerance="1e-10" jacobian="sparse" cone="pyramidal"/>
<visual>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="2048"/>
<map stiffness="700" shadowscale="0.5" fogstart="10" fogend="15" zfar="40" haze="0.3"/>
</visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<texture name="texcarpet" type="2d" file="carpet.png"/>
<texture name="texsponge" type="2d" file="sponge.png"/>
<texture name="texmarble" type="cube" file="marble.png"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name="matcarpet" texture="texcarpet"/>
<material name="matsponge" texture="texsponge" specular="0.3"/>
<material name="matmarble" texture="texmarble" rgba=".7 .7 .7 1"/>
</asset>
<worldbody>
<light directional="true" diffuse=".4 .4 .4" specular="0.1 0.1 0.1" pos="0 0 5.0" dir="0 0 -1" castshadow="false"/>
<light directional="true" diffuse=".6 .6 .6" specular="0.2 0.2 0.2" pos="0 0 4" dir="0 0 -1"/>
<geom name="ground" type="plane" size="0 0 1" pos="0 0 0" quat="1 0 0 0" material="matplane" condim="1"/>
<body mocap="true" pos="-.1 .05 0" zaxis=".5 0 1">
<geom type="capsule" size=".1 .1" material="matmarble" group="1" condim="1"/>
</body>
</worldbody>
</mujoco>
+33
View File
@@ -0,0 +1,33 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Soft box">
<include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/>
<size nconmax="500" njmax="5000" nstack="5000000"/>
<worldbody>
<body pos="0 0 1">
<freejoint/>
<composite type="box" count="7 7 7" spacing="0.04">
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
+33
View File
@@ -0,0 +1,33 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Soft cylinder">
<include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/>
<size nconmax="500" njmax="5000" nstack="5000000"/>
<worldbody>
<body pos="0 0 1">
<freejoint/>
<composite type="cylinder" count="5 7 9" spacing="0.05">
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
+33
View File
@@ -0,0 +1,33 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Soft ellipsoid">
<include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/>
<size nconmax="500" njmax="5000" nstack="5000000"/>
<worldbody>
<body pos="0 0 1">
<freejoint/>
<composite type="ellipsoid" count="5 7 9" spacing="0.05">
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

+12
View File
@@ -0,0 +1,12 @@
COMMON=-O2 -I../include -L../bin -std=c++11 -mavx -pthread -Wl,-rpath,'$$ORIGIN'
all:
g++ $(COMMON) testxml.cc -lmujoco210nogl -o ../bin/testxml
g++ $(COMMON) testspeed.cc -lmujoco210nogl -o ../bin/testspeed
g++ $(COMMON) compile.cc -lmujoco210nogl -o ../bin/compile
g++ $(COMMON) derivative.cc -lmujoco210nogl -fopenmp -o ../bin/derivative
g++ $(COMMON) basic.cc -lmujoco210 -lGL -lglew ../bin/libglfw.so.3 -o ../bin/basic
g++ $(COMMON) record.cc -lmujoco210 -lGL -lglew ../bin/libglfw.so.3 -o ../bin/record
gcc -c -O2 -mavx -I../include ../include/uitools.c
g++ $(COMMON) uitools.o simulate.cc -lmujoco210 -lGL -lglew ../bin/libglfw.so.3 -o ../bin/simulate
rm *.o
+12
View File
@@ -0,0 +1,12 @@
COMMON=-O2 -I../include -L../bin -std=c++11 -stdlib=libc++ -mavx -pthread
all:
clang++ $(COMMON) testxml.cc -lmujoco210nogl -o ../bin/testxml
clang++ $(COMMON) testspeed.cc -lmujoco210nogl -o ../bin/testspeed
clang++ $(COMMON) compile.cc -lmujoco210nogl -o ../bin/compile
clang++ $(COMMON) derivative.cc -lmujoco210nogl -o ../bin/derivative
clang++ $(COMMON) basic.cc -lmujoco210 -lglfw.3 -o ../bin/basic
clang++ $(COMMON) record.cc -lmujoco210 -lglfw.3 -o ../bin/record
clang -c -O2 -mavx -I../include ../include/uitools.c
clang++ $(COMMON) uitools.o simulate.cc -lmujoco210 -lglfw.3 -o ../bin/simulate
rm *.o
+11
View File
@@ -0,0 +1,11 @@
COMMON=/O2 /MT /EHsc /arch:AVX /I../include /Fe../bin/
all:
cl $(COMMON) testxml.cc ../bin/mujoco210nogl.lib
cl $(COMMON) testspeed.cc ../bin/mujoco210nogl.lib
cl $(COMMON) compile.cc ../bin/mujoco210nogl.lib
cl $(COMMON) derivative.cc /openmp ../bin/mujoco210nogl.lib
cl $(COMMON) basic.cc ../bin/glfw3.lib ../bin/mujoco210.lib
cl $(COMMON) record.cc ../bin/glfw3.lib ../bin/mujoco210.lib
cl $(COMMON) simulate.cc ../include/uitools.c ../bin/glfw3.lib ../bin/mujoco210.lib
del *.obj
+193
View File
@@ -0,0 +1,193 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mujoco.h"
#include "glfw3.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
// MuJoCo data structures
mjModel* m = NULL; // MuJoCo model
mjData* d = NULL; // MuJoCo data
mjvCamera cam; // abstract camera
mjvOption opt; // visualization options
mjvScene scn; // abstract scene
mjrContext con; // custom GPU context
// mouse interaction
bool button_left = false;
bool button_middle = false;
bool button_right = false;
double lastx = 0;
double lasty = 0;
// keyboard callback
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods)
{
// backspace: reset simulation
if( act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE )
{
mj_resetData(m, d);
mj_forward(m, d);
}
}
// mouse button callback
void mouse_button(GLFWwindow* window, int button, int act, int mods)
{
// update button state
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
// update mouse position
glfwGetCursorPos(window, &lastx, &lasty);
}
// mouse move callback
void mouse_move(GLFWwindow* window, double xpos, double ypos)
{
// no buttons down: nothing to do
if( !button_left && !button_middle && !button_right )
return;
// compute mouse displacement, save
double dx = xpos - lastx;
double dy = ypos - lasty;
lastx = xpos;
lasty = ypos;
// get current window size
int width, height;
glfwGetWindowSize(window, &width, &height);
// get shift key state
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
// determine action based on mouse button
mjtMouse action;
if( button_right )
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
else if( button_left )
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
else
action = mjMOUSE_ZOOM;
// move camera
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
}
// scroll callback
void scroll(GLFWwindow* window, double xoffset, double yoffset)
{
// emulate vertical mouse motion = 5% of window height
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
}
// main function
int main(int argc, const char** argv)
{
// check command-line arguments
if( argc!=2 )
{
printf(" USAGE: basic modelfile\n");
return 0;
}
// load and compile model
char error[1000] = "Could not load binary model";
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") )
m = mj_loadModel(argv[1], 0);
else
m = mj_loadXML(argv[1], 0, error, 1000);
if( !m )
mju_error_s("Load model error: %s", error);
// make data
d = mj_makeData(m);
// init GLFW
if( !glfwInit() )
mju_error("Could not initialize GLFW");
// create window, make OpenGL context current, request v-sync
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// initialize visualization data structures
mjv_defaultCamera(&cam);
mjv_defaultOption(&opt);
mjv_defaultScene(&scn);
mjr_defaultContext(&con);
// create scene and context
mjv_makeScene(m, &scn, 2000);
mjr_makeContext(m, &con, mjFONTSCALE_150);
// install GLFW mouse and keyboard callbacks
glfwSetKeyCallback(window, keyboard);
glfwSetCursorPosCallback(window, mouse_move);
glfwSetMouseButtonCallback(window, mouse_button);
glfwSetScrollCallback(window, scroll);
// run main loop, target real-time simulation and 60 fps rendering
while( !glfwWindowShouldClose(window) )
{
// advance interactive simulation for 1/60 sec
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
// this loop will finish on time for the next frame to be rendered at 60 fps.
// Otherwise add a cpu timer and exit this loop when it is time to render.
mjtNum simstart = d->time;
while( d->time - simstart < 1.0/60.0 )
mj_step(m, d);
// get framebuffer viewport
mjrRect viewport = {0, 0, 0, 0};
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
// update scene and render
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
mjr_render(viewport, &scn, &con);
// swap OpenGL buffers (blocking call due to v-sync)
glfwSwapBuffers(window);
// process pending GUI events, call GLFW callbacks
glfwPollEvents();
}
//free visualization storage
mjv_freeScene(&scn);
mjr_freeContext(&con);
// free MuJoCo model and data
mj_deleteData(d);
mj_deleteModel(m);
// terminate GLFW (crashes with Linux NVidia drivers)
#if defined(__APPLE__) || defined(_WIN32)
glfwTerminate();
#endif
return 1;
}
+146
View File
@@ -0,0 +1,146 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mujoco.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// help
const char helpstring[] =
"\n Usage: compile infile outfile\n"
" infile can be in mjcf, urdf, mjb format\n"
" outfile can be in mjcf, mjb, txt format\n\n"
" Example: compile model.xml model.mjb\n";
// deallocate and print message
int finish(const char* msg = 0, mjModel* m = 0)
{
// deallocated everything
if( m )
mj_deleteModel(m);
// print message
if( msg )
printf("%s\n", msg);
return 0;
}
// possible file types
enum
{
typeUNKNOWN = 0,
typeXML,
typeMJB,
typeTXT
};
// determine file type
int filetype(const char* filename)
{
// convert to lower case for string comparison
char lower[1000];
size_t i=0;
while( i<strlen(filename) && i<999 )
{
lower[i] = (char)tolower(filename[i]);
i++;
}
lower[i] = 0;
// find last dot
int dot = (int)strlen(lower);
while( dot>=0 && lower[dot]!='.' )
dot--;
// no dot found
if( dot<0 )
return typeUNKNOWN;
// check extension
if( !strcmp(lower+dot, ".xml") || !strcmp(lower+dot, ".urdf") )
return typeXML;
else if( !strcmp(lower+dot, ".mjb") )
return typeMJB;
else if( !strcmp(lower+dot, ".txt") )
return typeTXT;
else
return typeUNKNOWN;
}
// main function
int main(int argc, const char** argv)
{
// model and error
mjModel* m = 0;
char error[1000];
// print help if arguments are missing
if( argc!=3 )
return finish(helpstring);
// determine file types
int type1 = filetype(argv[1]);
int type2 = filetype(argv[2]);
// check types
if( type1==typeUNKNOWN || type1==typeTXT ||
type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML) )
return finish("Illegal combination of file formats");
// make sure output file does not exist
FILE* fp = fopen(argv[2], "r");
if( fp )
{
fclose(fp);
return finish("Output file already exists");
}
// load model
if( type1==typeXML )
m = mj_loadXML(argv[1], 0, error, 1000);
else
m = mj_loadModel(argv[1], 0);
// check error
if( !m )
{
if( type1==typeXML )
return finish(error, 0);
else
return finish("Could not load model", 0);
}
// save model
if( type2==typeXML )
{
if( mj_saveLastXML(argv[2], m, error, 1000) )
return finish(error, m);
}
else if( type2==typeMJB )
mj_saveModel(m, argv[2], 0, 0);
else
mj_printModel(m, argv[2]);
// finalize
return finish("Done", m);
}
+443
View File
@@ -0,0 +1,443 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mujoco.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// enable compilation with and without OpenMP support
#if defined(_OPENMP)
#include <omp.h>
#else
// omp timer replacement
#include <chrono>
double omp_get_wtime(void)
{
static std::chrono::system_clock::time_point _start = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - _start;
return elapsed.count();
}
// omp functions used below
void omp_set_dynamic(int) {}
void omp_set_num_threads(int) {}
int omp_get_num_procs(void) {return 1;}
#endif
// gloval variables: internal
const int MAXTHREAD = 64; // maximum number of threads allowed
const int MAXEPOCH = 100; // maximum number of epochs
int isforward = 0; // dynamics mode: forward or inverse
mjtNum* deriv = 0; // dynamics derivatives (6*nv*nv):
// dinv/dpos, dinv/dvel, dinv/dacc, dacc/dpos, dacc/dvel, dacc/dfrc
// global variables: user-defined, with defaults
int nthread = 0; // number of parallel threads (default set later)
int niter = 30; // fixed number of solver iterations for finite-differencing
int nwarmup = 3; // center point repetitions to improve warmstart
int nepoch = 20; // number of timing epochs
int nstep = 500; // number of simulation steps per epoch
double eps = 1e-6; // finite-difference epsilon
// worker function for parallel finite-difference computation of derivatives
void worker(const mjModel* m, const mjData* dmain, mjData* d, int id)
{
int nv = m->nv;
// allocate stack space for result at center
mjMARKSTACK
mjtNum* center = mj_stackAlloc(d, nv);
mjtNum* warmstart = mj_stackAlloc(d, nv);
// prepare static schedule: range of derivative columns to be computed by this thread
int chunk = (m->nv + nthread-1) / nthread;
int istart = id * chunk;
int iend = mjMIN(istart + chunk, m->nv);
// copy state and control from dmain to thread-specific d
d->time = dmain->time;
mju_copy(d->qpos, dmain->qpos, m->nq);
mju_copy(d->qvel, dmain->qvel, m->nv);
mju_copy(d->qacc, dmain->qacc, m->nv);
mju_copy(d->qacc_warmstart, dmain->qacc_warmstart, m->nv);
mju_copy(d->qfrc_applied, dmain->qfrc_applied, m->nv);
mju_copy(d->xfrc_applied, dmain->xfrc_applied, 6*m->nbody);
mju_copy(d->ctrl, dmain->ctrl, m->nu);
// run full computation at center point (usually faster than copying dmain)
if( isforward )
{
mj_forward(m, d);
// extra solver iterations to improve warmstart (qacc) at center point
for( int rep=1; rep<nwarmup; rep++ )
mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
}
else
mj_inverse(m, d);
// select output from forward or inverse dynamics
mjtNum* output = (isforward ? d->qacc : d->qfrc_inverse);
// save output for center point and warmstart (needed in forward only)
mju_copy(center, output, nv);
mju_copy(warmstart, d->qacc_warmstart, nv);
// select target vector and original vector for force or acceleration derivative
mjtNum* target = (isforward ? d->qfrc_applied : d->qacc);
const mjtNum* original = (isforward ? dmain->qfrc_applied : dmain->qacc);
// finite-difference over force or acceleration: skip = mjSTAGE_VEL
for( int i=istart; i<iend; i++ )
{
// perturb selected target
target[i] += eps;
// evaluate dynamics, with center warmstart
if( isforward )
{
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
}
else
mj_inverseSkip(m, d, mjSTAGE_VEL, 1);
// undo perturbation
target[i] = original[i];
// compute column i of derivative 2
for( int j=0; j<nv; j++ )
deriv[(3*isforward+2)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
// finite-difference over velocity: skip = mjSTAGE_POS
for( int i=istart; i<iend; i++ )
{
// perturb velocity
d->qvel[i] += eps;
// evaluate dynamics, with center warmstart
if( isforward )
{
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_POS, 1);
}
else
mj_inverseSkip(m, d, mjSTAGE_POS, 1);
// undo perturbation
d->qvel[i] = dmain->qvel[i];
// compute column i of derivative 1
for( int j=0; j<nv; j++ )
deriv[(3*isforward+1)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
// finite-difference over position: skip = mjSTAGE_NONE
for( int i=istart; i<iend; i++ )
{
// get joint id for this dof
int jid = m->dof_jntid[i];
// get quaternion address and dof position within quaternion (-1: not in quaternion)
int quatadr = -1, dofpos = 0;
if( m->jnt_type[jid]==mjJNT_BALL )
{
quatadr = m->jnt_qposadr[jid];
dofpos = i - m->jnt_dofadr[jid];
}
else if( m->jnt_type[jid]==mjJNT_FREE && i>=m->jnt_dofadr[jid]+3 )
{
quatadr = m->jnt_qposadr[jid] + 3;
dofpos = i - m->jnt_dofadr[jid] - 3;
}
// apply quaternion or simple perturbation
if( quatadr>=0 )
{
mjtNum angvel[3] = {0,0,0};
angvel[dofpos] = eps;
mju_quatIntegrate(d->qpos+quatadr, angvel, 1);
}
else
d->qpos[m->jnt_qposadr[jid] + i - m->jnt_dofadr[jid]] += eps;
// evaluate dynamics, with center warmstart
if( isforward )
{
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_NONE, 1);
}
else
mj_inverseSkip(m, d, mjSTAGE_NONE, 1);
// undo perturbation
mju_copy(d->qpos, dmain->qpos, m->nq);
// compute column i of derivative 0
for( int j=0; j<nv; j++ )
deriv[(3*isforward+0)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
mjFREESTACK
}
// compute relative L1 norm of residual
double relnorm(mjtNum* residual, mjtNum* base, int n)
{
mjtNum L1res = 0, L1base = 0;
for( int i=0; i<n; i++ )
{
L1res += mju_abs(residual[i]);
L1base += mju_abs(base[i]);
}
return (double) mju_log10(mju_max(mjMINVAL,L1res/mju_max(mjMINVAL,L1base)));
}
// names of residuals for accuracy check
const char* accuracy[8] = {
"G2*F2 - I ",
"G2 - G2' ",
"G1 - G1' ",
"F2 - F2' ",
"G1 + G2*F1",
"G0 + G2*F0",
"F1 + F2*G1",
"F0 + F2*G0"
};
// check accuracy of derivatives using known mathematical identities
void checkderiv(const mjModel* m, mjData* d, mjtNum error[7])
{
int nv = m->nv;
// allocate space
mjMARKSTACK
mjtNum* mat = mj_stackAlloc(d, nv*nv);
// get pointers to derivative matrices
mjtNum* G0 = deriv; // dinv/dpos
mjtNum* G1 = deriv + nv*nv; // dinv/dvel
mjtNum* G2 = deriv + 2*nv*nv; // dinv/dacc
mjtNum* F0 = deriv + 3*nv*nv; // dacc/dpos
mjtNum* F1 = deriv + 4*nv*nv; // dacc/dvel
mjtNum* F2 = deriv + 5*nv*nv; // dacc/dfrc
// G2*F2 - I
mju_mulMatMat(mat, G2, F2, nv, nv, nv);
for( int i=0; i<nv; i++ )
mat[i*(nv+1)] -= 1;
error[0] = relnorm(mat, G2, nv*nv);
// G2 - G2'
mju_transpose(mat, G2, nv, nv);
mju_sub(mat, mat, G2, nv*nv);
error[1] = relnorm(mat, G2, nv*nv);
// G1 - G1'
mju_transpose(mat, G1, nv, nv);
mju_sub(mat, mat, G1, nv*nv);
error[2] = relnorm(mat, G1, nv*nv);
// F2 - F2'
mju_transpose(mat, F2, nv, nv);
mju_sub(mat, mat, F2, nv*nv);
error[3] = relnorm(mat, F2, nv*nv);
// G1 + G2*F1
mju_mulMatMat(mat, G2, F1, nv, nv, nv);
mju_addTo(mat, G1, nv*nv);
error[4] = relnorm(mat, G1, nv*nv);
// G0 + G2*F0
mju_mulMatMat(mat, G2, F0, nv, nv, nv);
mju_addTo(mat, G0, nv*nv);
error[5] = relnorm(mat, G0, nv*nv);
// F1 + F2*G1
mju_mulMatMat(mat, F2, G1, nv, nv, nv);
mju_addTo(mat, F1, nv*nv);
error[6] = relnorm(mat, F1, nv*nv);
// F0 + F2*G0
mju_mulMatMat(mat, F2, G0, nv, nv, nv);
mju_addTo(mat, F0, nv*nv);
error[7] = relnorm(mat, F0, nv*nv);
mjFREESTACK
}
// main function
int main(int argc, char** argv)
{
// print help if not enough arguments
if( argc<2 )
{
printf("\n Arguments: modelfile [nthread niter nwarmup nepoch nstep eps]\n\n");
return 1;
}
// default nthread = number of logical cores (usually optimal)
nthread = omp_get_num_procs();
// get numeric command-line arguments
if( argc>2 )
sscanf(argv[2], "%d", &nthread);
if( argc>3 )
sscanf(argv[3], "%d", &niter);
if( argc>4 )
sscanf(argv[4], "%d", &nwarmup);
if( argc>5 )
sscanf(argv[5], "%d", &nepoch);
if( argc>6 )
sscanf(argv[6], "%d", &nstep);
if( argc>7 )
sscanf(argv[7], "%lf", &eps);
// check number of threads
if( nthread<1 || nthread>MAXTHREAD )
{
printf("nthread must be between 1 and %d\n", MAXTHREAD);
return 1;
}
// check number of epochs
if( nepoch<1 || nepoch>MAXEPOCH )
{
printf("nepoch must be between 1 and %d\n", MAXEPOCH);
return 1;
}
// load model
mjModel* m = 0;
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") )
m = mj_loadModel(argv[1], NULL);
else
m = mj_loadXML(argv[1], NULL, NULL, 0);
if( !m )
{
printf("Could not load modelfile '%s'\n", argv[1]);
return 1;
}
// print arguments
#if defined(_OPENMP)
printf("\nnthread : %d (OpenMP)\n", nthread);
#else
printf("\nnthread : %d (serial)\n", nthread);
#endif
printf("niter : %d\n", niter);
printf("nwarmup : %d\n", nwarmup);
printf("nepoch : %d\n", nepoch);
printf("nstep : %d\n", nstep);
printf("eps : %g\n\n", eps);
// make mjData: main, per-thread
mjData* dmain = mj_makeData(m);
mjData* d[MAXTHREAD];
for( int n=0; n<nthread; n++ )
d[n] = mj_makeData(m);
// allocate derivatives
deriv = (mjtNum*) mju_malloc(6*sizeof(mjtNum)*m->nv*m->nv);
// set up OpenMP (if not enabled, this does nothing)
omp_set_dynamic(0);
omp_set_num_threads(nthread);
// save solver options
int save_iterations = m->opt.iterations;
mjtNum save_tolerance = m->opt.tolerance;
// allocate statistics
int nefc = 0;
double cputm[MAXEPOCH][2];
mjtNum error[MAXEPOCH][8];
// run epochs, collect statistics
for( int epoch=0; epoch<nepoch; epoch++ )
{
// set solver options for main simulation
m->opt.iterations = save_iterations;
m->opt.tolerance = save_tolerance;
// advance main simulation for nstep
for( int i=0; i<nstep; i++ )
mj_step(m, dmain);
// count number of active constraints
nefc += dmain->nefc;
// set solver options for finite differences
m->opt.iterations = niter;
m->opt.tolerance = 0;
// test forward and inverse
for( isforward=0; isforward<2; isforward++ )
{
// start timer
double starttm = omp_get_wtime();
// run worker threads in parallel if OpenMP is enabled
#pragma omp parallel for schedule(static)
for( int n=0; n<nthread; n++ )
worker(m, dmain, d[n], n);
// record duration in ms
cputm[epoch][isforward] = 1000*(omp_get_wtime() - starttm);
}
// check derivatives
checkderiv(m, d[0], error[epoch]);
}
// compute statistics
double mcputm[2] = {0,0}, merror[8] = {0,0,0,0,0,0,0,0};
for( int epoch=0; epoch<nepoch; epoch++ )
{
mcputm[0] += cputm[epoch][0];
mcputm[1] += cputm[epoch][1];
for( int ie=0; ie<8; ie++ )
merror[ie] += error[epoch][ie];
}
// print sizes, timing, accuracy
printf("sizes : nv %d, nefc %d\n\n", m->nv, nefc/nepoch);
printf("inverse : %.2f ms\n", mcputm[0]/nepoch);
printf("forward : %.2f ms\n\n", mcputm[1]/nepoch);
printf("accuracy: log10(residual L1 relnorm)\n");
printf("------------------------------------\n");
for( int ie=0; ie<8; ie++ )
printf(" %s : %.2g\n", accuracy[ie], merror[ie]/nepoch);
printf("\n");
// shut down
mju_free(deriv);
mj_deleteData(dmain);
for( int n=0; n<nthread; n++ )
mj_deleteData(d[n]);
mj_deleteModel(m);
return 0;
}
+311
View File
@@ -0,0 +1,311 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mujoco.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
// select EGL, OSMESA or GLFW
#if defined(MJ_EGL)
#include <EGL/egl.h>
#elif defined(MJ_OSMESA)
#include <GL/osmesa.h>
OSMesaContext ctx;
unsigned char buffer[10000000];
#else
#include "glfw3.h"
#endif
//-------------------------------- global data ------------------------------------------
// MuJoCo model and data
mjModel* m = 0;
mjData* d = 0;
// MuJoCo visualization
mjvScene scn;
mjvCamera cam;
mjvOption opt;
mjrContext con;
//-------------------------------- utility functions ------------------------------------
// load model, init simulation and rendering
void initMuJoCo(const char* filename)
{
// load and compile
char error[1000] = "Could not load binary model";
if( strlen(filename)>4 && !strcmp(filename+strlen(filename)-4, ".mjb") )
m = mj_loadModel(filename, 0);
else
m = mj_loadXML(filename, 0, error, 1000);
if( !m )
mju_error_s("Load model error: %s", error);
// make data, run one computation to initialize all fields
d = mj_makeData(m);
mj_forward(m, d);
// initialize visualization data structures
mjv_defaultCamera(&cam);
mjv_defaultOption(&opt);
mjv_defaultScene(&scn);
mjr_defaultContext(&con);
// create scene and context
mjv_makeScene(m, &scn, 2000);
mjr_makeContext(m, &con, 200);
// center and scale view
cam.lookat[0] = m->stat.center[0];
cam.lookat[1] = m->stat.center[1];
cam.lookat[2] = m->stat.center[2];
cam.distance = 1.5 * m->stat.extent;
}
// deallocate everything
void closeMuJoCo(void)
{
mj_deleteData(d);
mj_deleteModel(m);
mjr_freeContext(&con);
mjv_freeScene(&scn);
}
// create OpenGL context/window
void initOpenGL(void)
{
//------------------------ EGL
#if defined(MJ_EGL)
// desired config
const EGLint configAttribs[] ={
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
// get default display
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if( eglDpy==EGL_NO_DISPLAY )
mju_error_i("Could not get EGL display, error 0x%x\n", eglGetError());
// initialize
EGLint major, minor;
if( eglInitialize(eglDpy, &major, &minor)!=EGL_TRUE )
mju_error_i("Could not initialize EGL, error 0x%x\n", eglGetError());
// choose config
EGLint numConfigs;
EGLConfig eglCfg;
if( eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)!=EGL_TRUE )
mju_error_i("Could not choose EGL config, error 0x%x\n", eglGetError());
// bind OpenGL API
if( eglBindAPI(EGL_OPENGL_API)!=EGL_TRUE )
mju_error_i("Could not bind EGL OpenGL API, error 0x%x\n", eglGetError());
// create context
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);
if( eglCtx==EGL_NO_CONTEXT )
mju_error_i("Could not create EGL context, error 0x%x\n", eglGetError());
// make context current, no surface (let OpenGL handle FBO)
if( eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx)!=EGL_TRUE )
mju_error_i("Could not make EGL context current, error 0x%x\n", eglGetError());
//------------------------ OSMESA
#elif defined(MJ_OSMESA)
// create context
ctx = OSMesaCreateContextExt(GL_RGBA, 24, 8, 8, 0);
if( !ctx )
mju_error("OSMesa context creation failed");
// make current
if( !OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, 800, 800) )
mju_error("OSMesa make current failed");
//------------------------ GLFW
#else
// init GLFW
if( !glfwInit() )
mju_error("Could not initialize GLFW");
// create invisible window, single-buffered
glfwWindowHint(GLFW_VISIBLE, 0);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 800, "Invisible window", NULL, NULL);
if( !window )
mju_error("Could not create GLFW window");
// make context current
glfwMakeContextCurrent(window);
#endif
}
// close OpenGL context/window
void closeOpenGL(void)
{
//------------------------ EGL
#if defined(MJ_EGL)
// get current display
EGLDisplay eglDpy = eglGetCurrentDisplay();
if( eglDpy==EGL_NO_DISPLAY )
return;
// get current context
EGLContext eglCtx = eglGetCurrentContext();
// release context
eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
// destroy context if valid
if( eglCtx!=EGL_NO_CONTEXT )
eglDestroyContext(eglDpy, eglCtx);
// terminate display
eglTerminate(eglDpy);
//------------------------ OSMESA
#elif defined(MJ_OSMESA)
OSMesaDestroyContext(ctx);
//------------------------ GLFW
#else
// terminate GLFW (crashes with Linux NVidia drivers)
#if defined(__APPLE__) || defined(_WIN32)
glfwTerminate();
#endif
#endif
}
//-------------------------------- main function ----------------------------------------
int main(int argc, const char** argv)
{
// check command-line arguments
if( argc!=5 )
{
printf(" USAGE: record modelfile duration fps rgbfile\n");
return 0;
}
// parse numeric arguments
double duration = 10, fps = 30;
sscanf(argv[2], "%lf", &duration);
sscanf(argv[3], "%lf", &fps);
// initialize OpenGL and MuJoCo
initOpenGL();
initMuJoCo(argv[1]);
// set rendering to offscreen buffer
mjr_setBuffer(mjFB_OFFSCREEN, &con);
if( con.currentBuffer!=mjFB_OFFSCREEN )
printf("Warning: offscreen rendering not supported, using default/window framebuffer\n");
// get size of active renderbuffer
mjrRect viewport = mjr_maxViewport(&con);
int W = viewport.width;
int H = viewport.height;
// allocate rgb and depth buffers
unsigned char* rgb = (unsigned char*)malloc(3*W*H);
float* depth = (float*)malloc(sizeof(float)*W*H);
if( !rgb || !depth )
mju_error("Could not allocate buffers");
// create output rgb file
FILE* fp = fopen(argv[4], "wb");
if( !fp )
mju_error("Could not open rgbfile for writing");
// main loop
double frametime = 0;
int framecount = 0;
while( d->time<duration )
{
// render new frame if it is time (or first frame)
if( (d->time-frametime)>1/fps || frametime==0 )
{
// update abstract scene
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
// render scene in offscreen buffer
mjr_render(viewport, &scn, &con);
// add time stamp in upper-left corner
char stamp[50];
sprintf(stamp, "Time = %.3f", d->time);
mjr_overlay(mjFONT_NORMAL, mjGRID_TOPLEFT, viewport, stamp, NULL, &con);
// read rgb and depth buffers
mjr_readPixels(rgb, depth, viewport, &con);
// insert subsampled depth image in lower-left corner of rgb image
const int NS = 3; // depth image sub-sampling
for( int r=0; r<H; r+=NS )
for( int c=0; c<W; c+=NS )
{
int adr = (r/NS)*W + c/NS;
rgb[3*adr] = rgb[3*adr+1] = rgb[3*adr+2] =
(unsigned char)((1.0f-depth[r*W+c])*255.0f);
}
// write rgb image to file
fwrite(rgb, 3, W*H, fp);
// print every 10 frames: '.' if ok, 'x' if OpenGL error
if( ((framecount++)%10)==0 )
{
if( mjr_getError() )
printf("x");
else
printf(".");
}
// save simulation time
frametime = d->time;
}
// advance simulation
mj_step(m, d);
}
printf("\n");
// close file, free buffers
fclose(fp);
free(rgb);
free(depth);
// close MuJoCo and OpenGL
closeMuJoCo();
closeOpenGL();
return 1;
}
+2066
View File
File diff suppressed because it is too large Load Diff
+195
View File
@@ -0,0 +1,195 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mujoco.h"
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <string>
#include <chrono>
#include <thread>
using namespace std;
// model and per-thread data
mjModel* m = NULL;
mjData* d[64];
// per-thread statistics
int contacts[64];
int constraints[64];
double simtime[64];
// timer
chrono::system_clock::time_point tm_start;
mjtNum gettm(void)
{
chrono::duration<double> elapsed = chrono::system_clock::now() - tm_start;
return elapsed.count();
}
// deallocate and print message
int finish(const char* msg = NULL, mjModel* m = NULL)
{
// deallocate model
if( m )
mj_deleteModel(m);
// print message
if( msg )
printf("%s\n", msg);
return 0;
}
// thread function
void simulate(int id, int nstep)
{
// clear statistics
contacts[id] = 0;
constraints[id] = 0;
// run and time
double start = gettm();
for( int i=0; i<nstep; i++ )
{
// advance simulation
mj_step(m, d[id]);
// accumulate statistics
contacts[id] += d[id]->ncon;
constraints[id] += d[id]->nefc;
}
simtime[id] = gettm() - start;
}
// main function
int main(int argc, const char** argv)
{
// print help if arguments are missing
if( argc<3 || argc>5 )
return finish("\n Usage: testspeed modelfile nstep [nthread [profile]]\n");
// read nstep and nthread
int nstep = 0, nthread = 0, profile = 0;
if( sscanf(argv[2], "%d", &nstep)!=1 || nstep<=0 )
return finish("Invalid nstep argument");
if( argc>3 )
if( sscanf(argv[3], "%d", &nthread)!=1 )
return finish("Invalid nthread argument");
if( argc>4 )
if( sscanf(argv[4], "%d", &profile)!=1 )
return finish("Invalid profile argument");
// clamp nthread to [1, 64]
nthread = mjMAX(1, mjMIN(64, nthread));
// get filename, determine file type
std::string filename(argv[1]);
bool binary = (filename.find(".mjb")!=std::string::npos);
// load model
char error[1000] = "Could not load binary model";
if( binary )
m = mj_loadModel(argv[1], 0);
else
m = mj_loadXML(argv[1], 0, error, 1000);
if( !m )
return finish(error);
// make per-thread data
int testkey = mj_name2id(m, mjOBJ_KEY, "test");
for( int id=0; id<nthread; id++ )
{
d[id] = mj_makeData(m);
if( !d[id] )
return finish("Could not allocate mjData", m);
// init to keyframe "test" if present
if( testkey>=0 )
{
mju_copy(d[id]->qpos, m->key_qpos + testkey*m->nq, m->nq);
mju_copy(d[id]->qvel, m->key_qvel + testkey*m->nv, m->nv);
mju_copy(d[id]->act, m->key_act + testkey*m->na, m->na);
}
}
// install timer callback for profiling if requested
tm_start = chrono::system_clock::now();
if( profile )
mjcb_time = gettm;
// print start
if( nthread>1 )
printf("\nRunning %d steps per thread at dt = %g ...\n\n", nstep, m->opt.timestep);
else
printf("\nRunning %d steps at dt = %g ...\n\n", nstep, m->opt.timestep);
// run simulation, record total time
thread th[64];
double starttime = gettm();
for( int id=0; id<nthread; id++ )
th[id] = thread(simulate, id, nstep);
for( int id=0; id<nthread; id++ )
th[id].join();
double tottime = gettm() - starttime;
// all-thread summary
if( nthread>1 )
{
printf("Summary for all %d threads\n\n", nthread);
printf(" Total simulation time : %.2f s\n", tottime);
printf(" Total steps per second : %.0f\n", nthread*nstep/tottime);
printf(" Total realtime factor : %.2f x\n", nthread*nstep*m->opt.timestep/tottime);
printf(" Total time per step : %.4f ms\n\n", 1000*tottime/(nthread*nstep));
printf("Details for thread 0\n\n");
}
// details for thread 0
printf(" Simulation time : %.2f s\n", simtime[0]);
printf(" Steps per second : %.0f\n", nstep/simtime[0]);
printf(" Realtime factor : %.2f x\n", nstep*m->opt.timestep/simtime[0]);
printf(" Time per step : %.4f ms\n\n", 1000*simtime[0]/nstep);
printf(" Contacts per step : %d\n", contacts[0]/nstep);
printf(" Constraints per step : %d\n", constraints[0]/nstep);
printf(" Degrees of freedom : %d\n\n", m->nv);
// profiler results for thread 0
if( profile )
{
printf(" Profiler phase (ms per step)\n");
mjtNum tstep = d[0]->timer[mjTIMER_STEP].duration/d[0]->timer[mjTIMER_STEP].number;
for( int i=0; i<mjNTIMER; i++ )
if( d[0]->timer[i].number>0 )
{
mjtNum istep = d[0]->timer[i].duration/d[0]->timer[i].number;
printf(" %16s : %.5f (%6.2f %%)\n", mjTIMERSTRING[i],
1000*istep, 100*istep/tstep);
}
}
// free per-thread data
for( int id=0; id<nthread; id++ )
mj_deleteData(d[id]);
// finalize
return finish();
}
+174
View File
@@ -0,0 +1,174 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mujoco.h"
#include "mjxmacro.h"
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <string>
#include <chrono>
using namespace std;
// help
const char helpstring[] = "\n Usage: testxml modelfile.xml\n";
// deallocate and print message
int finish(const char* msg = 0, mjModel* m = 0, mjData* d = 0)
{
// deallocated everything
if( d )
mj_deleteData(d);
if( m )
mj_deleteModel(m);
// print message
if( msg )
printf("%s\n", msg);
return 0;
}
// return absolute difference if it is below 1, relative difference otherwise
static mjtNum _compare(mjtNum val1, mjtNum val2)
{
mjtNum magnitude = mju_max(mju_abs(val1), mju_abs(val2));
if( magnitude>1.0 )
return mju_abs(val1-val2) / magnitude;
else
return mju_abs(val1-val2);
}
// compare two models, return largest difference and field name
mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field)
{
int r, c;
mjtNum dif, maxdif = 0.0;
// define symbols corresponding to number of columns (needed in MJMODEL_POINTERS)
int nq = m1->nq;
int nv = m1->nv;
int na = m1->na;
int nmocap3 = 3*m1->nmocap;
int nmocap4 = 4*m1->nmocap;
int nuser_body = m1->nuser_body;
int nuser_jnt = m1->nuser_jnt;
int nuser_geom = m1->nuser_geom;
int nuser_site = m1->nuser_site;
int nuser_cam = m1->nuser_cam;
int nuser_tendon = m1->nuser_tendon;
int nuser_actuator = m1->nuser_actuator;
int nuser_sensor = m1->nuser_sensor;
// compare ints
#define X(name) if(m1->name!=m2->name) {strcpy(field, #name); return 1.0;}
MJMODEL_INTS
#undef X
// compare arrays
#define X(type, name, nr, nc) \
for( r=0; r<m1->nr; r++ ) \
for( c=0; c<nc; c++ ) { \
dif = _compare(m1->name[r*nc+c], m2->name[r*nc+c]); \
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} }
MJMODEL_POINTERS
#undef X
// compare scalars in mjOption
#define X(type, name) \
dif = _compare(m1->opt.name, m2->opt.name); \
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);}
MJOPTION_SCALARS
#undef X
// compare arrays in mjOption
#define X(name, n) \
for( c=0; c<n; c++ ) { \
dif = _compare(m1->opt.name[c], m2->opt.name[c]); \
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} }
MJOPTION_VECTORS
#undef X
// mjVisual and mjStatistics ignored for now
return maxdif;
}
// main function
int main(int argc, const char** argv)
{
// print help if arguments are missing
if( argc<2 )
return finish(helpstring);
// get filename, check file type
std::string filename(argv[1]);
if( filename.find(".xml")==std::string::npos )
return finish("xml model file is required");
// load model
char error[1000];
mjModel* m = mj_loadXML(argv[1], 0, error, 1000);
if( !m )
return finish(error);
// make data
mjData* d = mj_makeData(m);
if( !d )
return finish("Could not allocate mjData", m);
// prepare temp filename in the same directory as original (for asset loading)
std::string tempfile;
size_t lastpath = filename.find_last_of("/\\");
if( lastpath==std::string::npos )
tempfile = "_tempfile_.xml";
else
tempfile = filename.substr(0, lastpath+1) + "_tempfile_.xml";
// save
if( !mj_saveLastXML(tempfile.c_str(), m, error, 1000) )
return finish(error, m, d);
// load back
mjModel* mtemp = mj_loadXML(tempfile.c_str(), 0, error, 100);
if( !mtemp )
return finish(error, m, d);
// compare
char field[500] = "";
mjtNum result = compareModel(m, mtemp, field);
printf("\nComparison of original and saved model\n");
printf(" Max difference : %.3g\n", result);
printf(" Field name : %s\n", field);
// delete temp model and file
mj_deleteModel(mtemp);
remove(tempfile.c_str());
// finalize
return finish();
}