Version 2.1: documentation, public API headers, and sample programs.
PiperOrigin-RevId: 403900419
@@ -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)
|
||||
@@ -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
|
||||
|
After Width: | Height: | Size: 1.8 MiB |
@@ -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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>`_.
|
||||
@@ -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}
|
||||
@@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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 |
@@ -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 |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 447 KiB |
|
After Width: | Height: | Size: 396 KiB |
|
After Width: | Height: | Size: 482 KiB |
|
After Width: | Height: | Size: 302 KiB |
|
After Width: | Height: | Size: 246 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 426 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 335 KiB |
|
After Width: | Height: | Size: 355 KiB |
|
After Width: | Height: | Size: 405 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 565 KiB |
|
After Width: | Height: | Size: 762 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 328 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 65 KiB |
@@ -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:
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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 %}
|
||||