Remove cloth and rope composites and deprecate loop.
PiperOrigin-RevId: 568168329 Change-Id: Ida4a5236bef74828c7bf59affdc28adea3db53b1
This commit is contained in:
committed by
Copybara-Service
parent
cbb07a4c32
commit
d3d46e16a4
+14
-10
@@ -84,35 +84,39 @@ General
|
||||
:ref:`conaffinity<body-geom-conaffinity>` attributes in the model and then setting them globally to ``0`` using
|
||||
|br| ``<default> <geom contype="0" conaffinity="0"/> </default>``.
|
||||
|
||||
11. Added a new :ref:`dyntype<actuator-general-dyntype>`, ``filterexact``, which updates first-order filter states with
|
||||
11. Removed the :at:`rope` and :at:`cloth` composite objects.
|
||||
|
||||
**Migration:** Users should use the :at:`cable` and :at:`shell` elasticity plugins.
|
||||
|
||||
12. Added a new :ref:`dyntype<actuator-general-dyntype>`, ``filterexact``, which updates first-order filter states with
|
||||
the exact formula rather than with Euler integration.
|
||||
12. Added an actuator attribute, :ref:`actearly<actuator-general-actearly>`, which uses semi-implicit integration for
|
||||
13. Added an actuator attribute, :ref:`actearly<actuator-general-actearly>`, which uses semi-implicit integration for
|
||||
actuator forces: using the next step's actuator state to compute the current actuator forces at the current timestep.
|
||||
13. Renamed ``actuatorforcerange`` and ``actuatorforcelimited``, introduced in the previous version to
|
||||
14. Renamed ``actuatorforcerange`` and ``actuatorforcelimited``, introduced in the previous version to
|
||||
:ref:`actuatorfrcrange<body-joint-actuatorfrcrange>` and
|
||||
:ref:`actuatorfrclimited<body-joint-actuatorfrclimited>`, respectively.
|
||||
14. Added the flag :ref:`eulerdamp<option-flag-eulerdamp>`, which disables implicit integration of joint damping in the
|
||||
15. Added the flag :ref:`eulerdamp<option-flag-eulerdamp>`, which disables implicit integration of joint damping in the
|
||||
Euler integrator. See the :ref:`Numerical Integration<geIntegration>` section for more details.
|
||||
15. Added the flag :ref:`invdiscrete<option-flag-invdiscrete>`, which enables discrete-time inverse dynamics for all
|
||||
16. Added the flag :ref:`invdiscrete<option-flag-invdiscrete>`, which enables discrete-time inverse dynamics for all
|
||||
:ref:`integrators<option-integrator>` other than ``RK4``. See the flag documentation for more details.
|
||||
16. Added :ref:`ls_iterations<option-ls_iterations>` and :ref:`ls_tolerance<option-ls_tolerance>` options for adjusting
|
||||
17. Added :ref:`ls_iterations<option-ls_iterations>` and :ref:`ls_tolerance<option-ls_tolerance>` options for adjusting
|
||||
linesearch stopping criteria in CG and Newton solvers. These can be useful for performance tuning.
|
||||
17. Added ``mesh_pos`` and ``mesh_quat`` fields to :ref:`mjModel` to store the normalizing transformation applied to
|
||||
18. Added ``mesh_pos`` and ``mesh_quat`` fields to :ref:`mjModel` to store the normalizing transformation applied to
|
||||
mesh assets. Fixes `#409 <https://github.com/google-deepmind/mujoco/issues/409>`__ .
|
||||
18. Added camera :ref:`resolution<body-camera-resolution>` attribute and :ref:`camprojection<sensor-camprojection>`
|
||||
19. Added camera :ref:`resolution<body-camera-resolution>` attribute and :ref:`camprojection<sensor-camprojection>`
|
||||
sensor. If camera resolution is set to positive values, the camera projection sensor will report the location of a
|
||||
target site, projected onto the camera image, in pixel coordinates.
|
||||
|
||||
Python bindings
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
19. Fixed `#870 <https://github.com/google-deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
|
||||
20. Fixed `#870 <https://github.com/google-deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
|
||||
camera name used the default camera.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
|
||||
20. Fixed a bug that was causing :ref:`geom margin<body-geom-margin>` to be ignored during the construction of
|
||||
21. Fixed a bug that was causing :ref:`geom margin<body-geom-margin>` to be ignored during the construction of
|
||||
midphase collision trees.
|
||||
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<!-- Copyright 2021 DeepMind Technologies Limited
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<mujoco model="Cloth">
|
||||
<include file="scene.xml"/>
|
||||
|
||||
<option timestep="0.002" solver="CG" tolerance="1e-6"/>
|
||||
|
||||
<size memory="10M"/>
|
||||
|
||||
<worldbody>
|
||||
|
||||
<body name="B3_5" pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
|
||||
<joint kind="main" damping="0.001"/>
|
||||
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
|
||||
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -1,32 +0,0 @@
|
||||
<!-- Copyright 2021 DeepMind Technologies Limited
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<mujoco model="Loop">
|
||||
<include file="scene.xml"/>
|
||||
|
||||
<option timestep="0.002" jacobian="dense"/>
|
||||
|
||||
<size memory="2M"/>
|
||||
|
||||
<worldbody>
|
||||
<body name="B0" pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="loop" count="20 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -23,22 +23,33 @@
|
||||
-->
|
||||
<statistic center=".4 0 .8" extent="1.3"/>
|
||||
|
||||
<option wind="5 5 0" density="10">
|
||||
<flag constraint="disable"/>
|
||||
<option wind="5 5 0" density="10" solver="CG" tolerance="1e-6">
|
||||
</option>
|
||||
|
||||
<extension>
|
||||
<plugin plugin="mujoco.elasticity.shell"/>
|
||||
</extension>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" type="plane" size="0 0 .1"/>
|
||||
<light diffuse=".6 .6 .6" specular="0.2 0.2 0.2" pos="0 0 4" dir="0 0 -1"/>
|
||||
<body name="B0_0" pos="0 0 1">
|
||||
<composite type="cloth" count="9 19 1" spacing="0.05" flatinertia="0.01">
|
||||
<joint kind="main" damping="0.001" stiffness=".1"/>
|
||||
<body pos="0 0 1">
|
||||
<composite type="particle" count="9 19 1" spacing="0.05" flatinertia="0.01">
|
||||
<skin texcoord="true" inflate="0.005" subgrid="4"/>
|
||||
<geom type="ellipsoid" size="0.025 0.01 0.025" rgba=".8 .2 .1 1"/>
|
||||
<tendon kind="main" stiffness="100" damping=".001"/>
|
||||
<tendon kind="shear" stiffness="100" damping=".001"/>
|
||||
<geom type="ellipsoid" size="0.025 0.01 0.025" rgba=".8 .2 .1 1" group="4"/>
|
||||
<plugin plugin="mujoco.elasticity.shell">
|
||||
<config key="poisson" value="0"/>
|
||||
<config key="damping" value="0.001"/>
|
||||
<config key="thickness" value="1e-2"/>
|
||||
<!--Units are in Pa (SI)-->
|
||||
<config key="young" value="3e6"/>
|
||||
</plugin>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
|
||||
<equality>
|
||||
<connect body1="B0_0_0" anchor="0 0 0" solref="0.0002 1"/>
|
||||
</equality>
|
||||
</mujoco>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<composite type="particle" count="16 16 1" spacing="0.05" offset="0 0 1">
|
||||
<geom size=".02" rgba=".8 .2 .1 1" group="4" density="1000"
|
||||
condim="3" solref="0.01 1" solimp=".95 .99 .0001"/>
|
||||
<skin inflate="0.01" rgba=".4 0 .3 1" subgrid="4"/>
|
||||
<skin inflate="0.0001" rgba=".4 0 .3 1" subgrid="1"/>
|
||||
<plugin plugin="mujoco.elasticity.shell">
|
||||
<config key="poisson" value="0"/>
|
||||
<config key="damping" value="0.001"/>
|
||||
|
||||
+74
-314
@@ -293,16 +293,25 @@ bool mjCComposite::Make(mjCModel* model, mjCBody* body, char* error, int error_s
|
||||
return MakeGrid(model, body, error, error_sz);
|
||||
|
||||
case mjCOMPTYPE_ROPE:
|
||||
mju_warning("The \"rope\" composite type is deprecated. Please use \"cable\" instead.");
|
||||
[[fallthrough]];
|
||||
return comperr(error,
|
||||
"The \"rope\" composite type is deprecated. Please use "
|
||||
"\"cable\" instead.",
|
||||
error_sz);
|
||||
|
||||
case mjCOMPTYPE_LOOP:
|
||||
mju_warning(
|
||||
"The \"loop\" composite type is deprecated. Please use \"cable\" "
|
||||
"instead.");
|
||||
return MakeRope(model, body, error, error_sz);
|
||||
|
||||
case mjCOMPTYPE_CABLE:
|
||||
return MakeCable(model, body, error, error_sz);
|
||||
|
||||
case mjCOMPTYPE_CLOTH:
|
||||
return MakeCloth(model, body, error, error_sz);
|
||||
return comperr(error,
|
||||
"The \"cloth\" composite type is deprecated. Please use "
|
||||
"\"shell\" instead.",
|
||||
error_sz);
|
||||
|
||||
case mjCOMPTYPE_BOX:
|
||||
case mjCOMPTYPE_CYLINDER:
|
||||
@@ -531,10 +540,18 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
||||
}
|
||||
}
|
||||
|
||||
if (skin) {
|
||||
if (skin && dim==3) {
|
||||
MakeSkin3(model);
|
||||
}
|
||||
|
||||
if (skin && dim==2) {
|
||||
if (skinsubgrid>0) {
|
||||
MakeSkin2Subgrid(model, skininflate);
|
||||
} else {
|
||||
MakeSkin2(model, skininflate);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1019,273 +1036,6 @@ mjCBody* mjCComposite::AddRopeBody(mjCModel* model, mjCBody* body, int ix, int i
|
||||
|
||||
|
||||
|
||||
// make 2d cloth
|
||||
bool mjCComposite::MakeCloth(mjCModel* model, mjCBody* body, char* error, int error_sz) {
|
||||
// check dim
|
||||
if (dim!=2) {
|
||||
return comperr(error, "Cloth must be two-dimensional", error_sz);
|
||||
}
|
||||
|
||||
// check root body name prefix
|
||||
char txt[200];
|
||||
mju::sprintf_arr(txt, "%sB", prefix.c_str());
|
||||
if (std::strncmp(txt, body->name.substr(0, strlen(txt)).c_str(), mju::sizeof_arr(txt))) {
|
||||
mju::strcat_arr(txt, " must be the beginning of root body name");
|
||||
return comperr(error, txt, error_sz);
|
||||
}
|
||||
|
||||
// read origin coordinate from root body
|
||||
mju::strcpy_arr(txt, body->name.substr(strlen(txt)).c_str());
|
||||
int ox = -1, oy = -1;
|
||||
char c;
|
||||
if (sscanf(txt, "%d%c%d", &ox, &c, &oy)!=3 || c!='_') {
|
||||
return comperr(error, "Root body name must contain X_Y coordinates", error_sz);
|
||||
}
|
||||
if (ox<0 || ox>=count[0] || oy<0 || oy>=count[1]) {
|
||||
return comperr(error, "Root body coordinates out of range", error_sz);
|
||||
}
|
||||
|
||||
// add origin
|
||||
AddClothBody(model, body, ox, oy, ox, oy);
|
||||
|
||||
// add row: both directions
|
||||
for (int i=-2; i<=2; i+=2) {
|
||||
// init at origin
|
||||
int ix = ox;
|
||||
|
||||
// process row to end
|
||||
mjCBody* pbodyx = body;
|
||||
while (1) {
|
||||
// candidate neighbor
|
||||
int ix1 = ix;
|
||||
if (i==0) {
|
||||
ix1 = mjMIN(count[0]-1, ix+1);
|
||||
} else if (i==2) {
|
||||
ix1 = mjMAX(0, ix-1);
|
||||
}
|
||||
|
||||
// regular column
|
||||
if (i!=-2) {
|
||||
// stop if same
|
||||
if (ix1==ix) {
|
||||
break;
|
||||
}
|
||||
|
||||
// add body, assign counter
|
||||
pbodyx = AddClothBody(model, pbodyx, ix, oy, ix1, oy);
|
||||
ix = ix1;
|
||||
}
|
||||
|
||||
// add column: regular or center
|
||||
for (int j=1; j<=3; j+=2) {
|
||||
// init at row
|
||||
int iy = oy;
|
||||
|
||||
// process column to end
|
||||
mjCBody* pbodyy = pbodyx;
|
||||
while (1) {
|
||||
// candidate neighbor
|
||||
int iy1;
|
||||
if (j==1) {
|
||||
iy1 = mjMIN(count[1]-1, iy+1);
|
||||
} else {
|
||||
iy1 = mjMAX(0, iy-1);
|
||||
}
|
||||
|
||||
// stop if same
|
||||
if (iy1==iy) {
|
||||
break;
|
||||
}
|
||||
|
||||
// add body, assign counter
|
||||
pbodyy = AddClothBody(model, pbodyy, ix, iy, ix, iy1);
|
||||
iy = iy1;
|
||||
}
|
||||
}
|
||||
|
||||
// center column added
|
||||
if (i==-2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add main tendons
|
||||
for (int iy=0; iy<count[1]; iy++) {
|
||||
if (iy!=oy) {
|
||||
for (int ix=0; ix<count[0]-1; ix++) {
|
||||
char txt1[100], txt2[100];
|
||||
|
||||
// recover site names
|
||||
mju::sprintf_arr(txt1, "%sS%d_%d", prefix.c_str(), ix, iy);
|
||||
mju::sprintf_arr(txt2, "%sS%d_%d", prefix.c_str(), ix+1, iy);
|
||||
|
||||
// create tendon
|
||||
mjCTendon* ten = model->AddTendon(def + mjCOMPKIND_TENDON);
|
||||
ten->def = model->defaults[0];
|
||||
mju::sprintf_arr(txt, "%sT%d_%d", prefix.c_str(), ix, iy);
|
||||
ten->name = txt;
|
||||
ten->WrapSite(txt1);
|
||||
ten->WrapSite(txt2);
|
||||
|
||||
// add equality constraint
|
||||
mjCEquality* eq = model->AddEquality(def + mjCOMPKIND_TENDON);
|
||||
eq->def = model->defaults[0];
|
||||
eq->type = mjEQ_TENDON;
|
||||
eq->name1 = ten->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shear for 2D
|
||||
if (add[mjCOMPKIND_SHEAR]) {
|
||||
MakeShear(model);
|
||||
}
|
||||
|
||||
// skin
|
||||
if (skin) {
|
||||
if (skinsubgrid>0) {
|
||||
MakeSkin2Subgrid(model, skininflate);
|
||||
} else {
|
||||
MakeSkin2(model, skininflate);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// add child body for cloth
|
||||
mjCBody* mjCComposite::AddClothBody(mjCModel* model, mjCBody* body,
|
||||
int ix, int iy, int ix1, int iy1) {
|
||||
char txt[100];
|
||||
bool isroot = (ix==ix1 && iy==iy1);
|
||||
double dx = spacing*(ix1-ix);
|
||||
double dy = spacing*(iy1-iy);
|
||||
|
||||
// add child if not root
|
||||
if (!isroot) {
|
||||
body = body->AddBody();
|
||||
mju::sprintf_arr(txt, "%sB%d_%d", prefix.c_str(), ix1, iy1);
|
||||
body->name = txt;
|
||||
mjuu_setvec(body->pos, dx, dy, 0);
|
||||
}
|
||||
|
||||
// add geom, alternating rotations
|
||||
mjCGeom* geom = body->AddGeom(def);
|
||||
geom->def = body->def;
|
||||
mju::sprintf_arr(txt, "%sG%d_%d", prefix.c_str(), ix1, iy1);
|
||||
geom->name = txt;
|
||||
mjuu_setvec(geom->pos, 0, 0, 0);
|
||||
if ((ix1+iy1)%2) {
|
||||
mjuu_setvec(geom->quat, sqrt(0.5), sqrt(0.5), 0, 0);
|
||||
} else {
|
||||
mjuu_setvec(geom->quat, 0.5, 0.5, 0.5, 0.5);
|
||||
}
|
||||
|
||||
// make inertia flat
|
||||
if (flatinertia>0) {
|
||||
// set body mass = geom mass
|
||||
body->mass = mjuu_defined(geom->_mass) ? geom->_mass :
|
||||
geom->density * geom->GetVolume();
|
||||
|
||||
// set body i-frame
|
||||
mjuu_setvec(body->ipos, 0, 0, 0);
|
||||
mjuu_setvec(body->iquat, 1, 0, 0, 0);
|
||||
|
||||
// desired equivalent inertia box
|
||||
double size[3] = {0.5*spacing, 0.5*spacing, 0.5*spacing*flatinertia};
|
||||
|
||||
// convert to inertia
|
||||
body->inertia[0] = body->mass*(size[1]*size[1]+size[2]*size[2])/3;
|
||||
body->inertia[1] = body->mass*(size[0]*size[0]+size[2]*size[2])/3;
|
||||
body->inertia[2] = body->mass*(size[0]*size[0]+size[1]*size[1])/3;
|
||||
|
||||
body->MakeInertialExplicit();
|
||||
}
|
||||
|
||||
// add site
|
||||
mjCSite* site = body->AddSite(def);
|
||||
site->def = body->def;
|
||||
site->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sS%d_%d", prefix.c_str(), ix1, iy1);
|
||||
site->name = txt;
|
||||
mjuu_setvec(site->pos, 0, 0, 0);
|
||||
mjuu_setvec(site->quat, 1, 0, 0, 0);
|
||||
|
||||
// root: no joints
|
||||
if (isroot) {
|
||||
return body;
|
||||
}
|
||||
|
||||
// add main joint
|
||||
for (int i=0; i<2; i++) {
|
||||
// add joint
|
||||
mjCJoint* jnt = body->AddJoint(&defjoint[mjCOMPKIND_JOINT][0]);
|
||||
jnt->def = body->def;
|
||||
mju::sprintf_arr(txt, "%sJ%d_%d_%d", prefix.c_str(), i, ix1, iy1);
|
||||
jnt->name = txt;
|
||||
jnt->type = mjJNT_HINGE;
|
||||
mjuu_setvec(jnt->pos, -dx, -dy, 0);
|
||||
|
||||
// set universal axis depending on parent direction
|
||||
mjuu_setvec(jnt->axis, 0, 0, 0);
|
||||
if (ix!=ix1) {
|
||||
jnt->axis[i+1] = 1;
|
||||
} else {
|
||||
jnt->axis[2*i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// add twist joint
|
||||
if (add[mjCOMPKIND_TWIST]) {
|
||||
mjCJoint* jnt = body->AddJoint(&defjoint[mjCOMPKIND_TWIST][0]);
|
||||
jnt->def = body->def;
|
||||
mju::sprintf_arr(txt, "%sJT%d_%d", prefix.c_str(), ix1, iy1);
|
||||
jnt->name = txt;
|
||||
jnt->type = mjJNT_HINGE;
|
||||
mjuu_setvec(jnt->pos, -dx, -dy, 0);
|
||||
if (ix!=ix1) {
|
||||
mjuu_setvec(jnt->axis, 1, 0, 0);
|
||||
} else {
|
||||
mjuu_setvec(jnt->axis, 0, 1, 0);
|
||||
}
|
||||
|
||||
// add constraint
|
||||
mjCEquality* eq = model->AddEquality(def + mjCOMPKIND_TWIST);
|
||||
eq->def = model->defaults[0];
|
||||
eq->type = mjEQ_JOINT;
|
||||
eq->name1 = jnt->name;
|
||||
}
|
||||
|
||||
// add stretch joint
|
||||
if (add[mjCOMPKIND_STRETCH]) {
|
||||
// add joint
|
||||
mjCJoint* jnt = body->AddJoint(&defjoint[mjCOMPKIND_STRETCH][0]);
|
||||
jnt->def = body->def;
|
||||
mju::sprintf_arr(txt, "%sJS%d_%d", prefix.c_str(), ix1, iy1);
|
||||
jnt->name = txt;
|
||||
jnt->type = mjJNT_SLIDE;
|
||||
mjuu_setvec(jnt->pos, -dx, -dy, 0);
|
||||
if (ix!=ix1) {
|
||||
mjuu_setvec(jnt->axis, 1, 0, 0);
|
||||
} else {
|
||||
mjuu_setvec(jnt->axis, 0, 1, 0);
|
||||
}
|
||||
|
||||
// add constraint
|
||||
mjCEquality* eq = model->AddEquality(def + mjCOMPKIND_STRETCH);
|
||||
eq->def = model->defaults[0];
|
||||
eq->type = mjEQ_JOINT;
|
||||
eq->name1 = jnt->name;
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// project from box to other shape
|
||||
void mjCComposite::BoxProject(double* pos) {
|
||||
// determine sizes
|
||||
@@ -1490,6 +1240,46 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) {
|
||||
skin->inflate = inflate;
|
||||
skin->group = skingroup;
|
||||
|
||||
// copy skin from existing mesh
|
||||
if (type==mjCOMPTYPE_PARTICLE && username.empty()) {
|
||||
std::vector<int> face;
|
||||
mjXUtil::String2Vector(userface, face);
|
||||
int nvert = uservert.size()/3;
|
||||
|
||||
for (int j=0; j<2; j++) {
|
||||
for (int i=0; i<nvert; i++) {
|
||||
skin->vert.push_back(0);
|
||||
skin->vert.push_back(0);
|
||||
skin->vert.push_back(0);
|
||||
|
||||
mju::sprintf_arr(txt, "%sB%d", prefix.c_str(), i);
|
||||
skin->bodyname.push_back(txt);
|
||||
skin->bindpos.push_back(0);
|
||||
skin->bindpos.push_back(0);
|
||||
skin->bindpos.push_back(0);
|
||||
skin->bindquat.push_back(1);
|
||||
skin->bindquat.push_back(0);
|
||||
skin->bindquat.push_back(0);
|
||||
skin->bindquat.push_back(0);
|
||||
|
||||
vector<int> vertid;
|
||||
vector<float> vertweight;
|
||||
vertid.push_back(j*nvert+i);
|
||||
vertweight.push_back(1);
|
||||
skin->vertid.push_back(vertid);
|
||||
skin->vertweight.push_back(vertweight);
|
||||
}
|
||||
|
||||
for (int i=0; i<face.size()/3; i++) {
|
||||
skin->face.push_back(j*nvert+face[3*i]-1);
|
||||
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 1 : 2)]-1);
|
||||
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 2 : 1)]-1);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// populate mesh: two sides
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int ix=0; ix<count[0]; ix++) {
|
||||
@@ -1564,7 +1354,7 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) {
|
||||
}
|
||||
|
||||
// couple with bones
|
||||
if (type==mjCOMPTYPE_CLOTH || type==mjCOMPTYPE_GRID) {
|
||||
if (type==mjCOMPTYPE_PARTICLE || type==mjCOMPTYPE_GRID) {
|
||||
MakeClothBones(model, skin);
|
||||
} else if (type==mjCOMPTYPE_CABLE) {
|
||||
MakeCableBones(model, skin);
|
||||
@@ -1582,7 +1372,11 @@ void mjCComposite::MakeClothBones(mjCModel* model, mjCSkin* skin) {
|
||||
for (int ix=0; ix<count[0]; ix++) {
|
||||
for (int iy=0; iy<count[1]; iy++) {
|
||||
// body name
|
||||
mju::sprintf_arr(txt, "%sB%d_%d", prefix.c_str(), ix, iy);
|
||||
if (type==mjCOMPTYPE_GRID) {
|
||||
mju::sprintf_arr(txt, "%sB%d_%d", prefix.c_str(), ix, iy);
|
||||
} else {
|
||||
mju::sprintf_arr(txt, "%sB%d_%d_0", prefix.c_str(), ix, iy);
|
||||
}
|
||||
|
||||
// bind pose
|
||||
skin->bodyname.push_back(txt);
|
||||
@@ -1616,7 +1410,11 @@ void mjCComposite::MakeClothBonesSubgrid(mjCModel* model, mjCSkin* skin) {
|
||||
for (int ix=0; ix<count[0]; ix++) {
|
||||
for (int iy=0; iy<count[1]; iy++) {
|
||||
// body name
|
||||
mju::sprintf_arr(txt, "%sB%d_%d", prefix.c_str(), ix, iy);
|
||||
if (type==mjCOMPTYPE_GRID) {
|
||||
mju::sprintf_arr(txt, "%sB%d_%d", prefix.c_str(), ix, iy);
|
||||
} else {
|
||||
mju::sprintf_arr(txt, "%sB%d_%d_0", prefix.c_str(), ix, iy);
|
||||
}
|
||||
|
||||
// bind pose
|
||||
skin->bodyname.push_back(txt);
|
||||
@@ -2121,7 +1919,7 @@ void mjCComposite::MakeSkin2Subgrid(mjCModel* model, mjtNum inflate) {
|
||||
skin->face.push_back(NN + iy+1 + (C0-1)*C1);
|
||||
}
|
||||
|
||||
if (type==mjCOMPTYPE_CLOTH || type==mjCOMPTYPE_GRID) {
|
||||
if (type==mjCOMPTYPE_PARTICLE || type==mjCOMPTYPE_GRID) {
|
||||
MakeClothBonesSubgrid(model, skin);
|
||||
} else if (type==mjCOMPTYPE_CABLE) {
|
||||
MakeCableBonesSubgrid(model, skin);
|
||||
@@ -2197,46 +1995,8 @@ void mjCComposite::MakeSkin3(mjCModel* model) {
|
||||
skin->inflate = skininflate;
|
||||
skin->group = skingroup;
|
||||
|
||||
// copy skin from existing mesh
|
||||
if (type==mjCOMPTYPE_PARTICLE && username.empty()) {
|
||||
std::vector<int> face;
|
||||
mjXUtil::String2Vector(userface, face);
|
||||
int nvert = uservert.size()/3;
|
||||
|
||||
for (int j=0; j<2; j++) {
|
||||
for (int i=0; i<nvert; i++) {
|
||||
skin->vert.push_back(0);
|
||||
skin->vert.push_back(0);
|
||||
skin->vert.push_back(0);
|
||||
|
||||
mju::sprintf_arr(txt, "%sB%d", prefix.c_str(), i);
|
||||
skin->bodyname.push_back(txt);
|
||||
skin->bindpos.push_back(0);
|
||||
skin->bindpos.push_back(0);
|
||||
skin->bindpos.push_back(0);
|
||||
skin->bindquat.push_back(1);
|
||||
skin->bindquat.push_back(0);
|
||||
skin->bindquat.push_back(0);
|
||||
skin->bindquat.push_back(0);
|
||||
|
||||
vector<int> vertid;
|
||||
vector<float> vertweight;
|
||||
vertid.push_back(j*nvert+i);
|
||||
vertweight.push_back(1);
|
||||
skin->vertid.push_back(vertid);
|
||||
skin->vertweight.push_back(vertweight);
|
||||
}
|
||||
|
||||
for (int i=0; i<face.size()/3; i++) {
|
||||
skin->face.push_back(j*nvert+face[3*i]-1);
|
||||
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 1 : 2)]-1);
|
||||
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 2 : 1)]-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// box
|
||||
else if (type==mjCOMPTYPE_BOX || type==mjCOMPTYPE_PARTICLE) {
|
||||
if (type==mjCOMPTYPE_BOX || type==mjCOMPTYPE_PARTICLE) {
|
||||
// z-faces
|
||||
MakeSkin3Box(skin, count[0], count[1], 1, vcnt, "%sB%d_%d_0");
|
||||
fmt = "%sB%d_%d_" + string(cnt2);
|
||||
|
||||
@@ -74,7 +74,6 @@ class mjCComposite {
|
||||
bool MakeGrid(mjCModel* model, mjCBody* body, char* error, int error_sz);
|
||||
bool MakeRope(mjCModel* model, mjCBody* body, char* error, int error_sz);
|
||||
bool MakeCable(mjCModel* model, mjCBody* body, char* error, int error_sz);
|
||||
bool MakeCloth(mjCModel* model, mjCBody* body, char* error, int error_sz);
|
||||
bool MakeBox(mjCModel* model, mjCBody* body, char* error, int error_sz);
|
||||
void MakeShear(mjCModel* model);
|
||||
|
||||
@@ -138,7 +137,6 @@ class mjCComposite {
|
||||
|
||||
private:
|
||||
mjCBody* AddRopeBody(mjCModel* model, mjCBody* body, int ix, int ix1);
|
||||
mjCBody* AddClothBody(mjCModel* model, mjCBody* body, int ix, int iy, int ix1, int iy1);
|
||||
mjCBody* AddCableBody(mjCModel* model, mjCBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]);
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace mujoco {
|
||||
namespace {
|
||||
|
||||
// number of steps to roll out before benhmarking
|
||||
static const int kNumWarmupSteps = 500;
|
||||
static const int kNumWarmupSteps = 200;
|
||||
|
||||
// number of steps to benchmark
|
||||
static const int kNumBenchmarkSteps = 50;
|
||||
@@ -102,7 +102,7 @@ void solveM_baseline(const mjModel* m, mjData* d, mjtNum* x, const mjtNum* y) {
|
||||
// ----------------------------- benchmark ------------------------------------
|
||||
|
||||
static void BM_solveLD(benchmark::State& state, bool new_function) {
|
||||
static mjModel* m = LoadModelFromPath("composite/cloth.xml");
|
||||
static mjModel* m = LoadModelFromPath("plugin/elasticity/coil.xml");
|
||||
mjData* d = mj_makeData(m);
|
||||
|
||||
// warm-up rollout to get a typical state
|
||||
|
||||
@@ -348,7 +348,7 @@ void ABSL_ATTRIBUTE_NOINLINE mulMatVecSparse_8(mjtNum* res,
|
||||
// ----------------------------- benchmark ------------------------------------
|
||||
|
||||
static void BM_MatVecSparse(benchmark::State& state, int unroll) {
|
||||
static mjModel* m = LoadModelFromPath("composite/cloth.xml");
|
||||
static mjModel* m = LoadModelFromPath("plugin/elasticity/flag.xml");
|
||||
mjData* d = mj_makeData(m);
|
||||
|
||||
// warm-up rollout to get a typical state
|
||||
|
||||
@@ -48,13 +48,14 @@ static void run_parse_benchmark(const std::string xml_path, benchmark::State& st
|
||||
// separately in CPU profiles (and don't get replaced with raw calls to
|
||||
// run_parse_benchmark).
|
||||
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_ParseCloth(benchmark::State& state) {
|
||||
run_parse_benchmark(GetModelPath("composite/cloth.xml"), state);
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_ParseCable(benchmark::State& state) {
|
||||
run_parse_benchmark(GetModelPath("plugin/elasticity/flag.xml"), state);
|
||||
}
|
||||
BENCHMARK(BM_ParseCloth);
|
||||
BENCHMARK(BM_ParseCable);
|
||||
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_ParseFlag(benchmark::State& state) {
|
||||
run_parse_benchmark(GetModelPath("flag/flag.xml"), state);
|
||||
run_parse_benchmark(GetModelPath("../test/benchmark/testdata/flag.xml"),
|
||||
state);
|
||||
}
|
||||
BENCHMARK(BM_ParseFlag);
|
||||
|
||||
|
||||
@@ -79,12 +79,12 @@ static void run_step_benchmark(const mjModel* model, benchmark::State& state) {
|
||||
// separately in CPU profiles (and don't get replaced with raw calls to
|
||||
// run_step_benchmark).
|
||||
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_StepCloth(benchmark::State& state) {
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_StepCable(benchmark::State& state) {
|
||||
MujocoErrorTestGuard guard;
|
||||
static mjModel* model = LoadModelFromPath("composite/cloth.xml");
|
||||
static mjModel* model = LoadModelFromPath("plugin/elasticity/flag.xml");
|
||||
run_step_benchmark(model, state);
|
||||
}
|
||||
BENCHMARK(BM_StepCloth);
|
||||
BENCHMARK(BM_StepCable);
|
||||
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_StepParticle(benchmark::State& state) {
|
||||
MujocoErrorTestGuard guard;
|
||||
@@ -95,7 +95,8 @@ BENCHMARK(BM_StepParticle);
|
||||
|
||||
void ABSL_ATTRIBUTE_NO_TAIL_CALL BM_StepFlag(benchmark::State& state) {
|
||||
MujocoErrorTestGuard guard;
|
||||
static mjModel* model = LoadModelFromPath("flag/flag.xml");
|
||||
static mjModel* model =
|
||||
LoadModelFromPath("../test/benchmark/testdata/flag.xml");
|
||||
run_step_benchmark(model, state);
|
||||
}
|
||||
BENCHMARK(BM_StepFlag);
|
||||
|
||||
Vendored
+5582
File diff suppressed because one or more lines are too long
@@ -57,34 +57,6 @@ TEST_F(UserCompositeTest, MultipleJointsNotAllowedUnlessParticle) {
|
||||
HasSubstr("Only particles are allowed to have multiple joints"));
|
||||
}
|
||||
|
||||
TEST_F(UserCompositeTest, StretchAndTwistAllowed) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body name="B10">
|
||||
<freejoint/>
|
||||
<composite type="rope" count="21 1 1" spacing="0.04">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<joint kind="stretch" damping="0.005"/>
|
||||
<joint kind="twist" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
)";
|
||||
static char warning[1024];
|
||||
warning[0] = '\0';
|
||||
mju_user_warning = [](const char* msg) {
|
||||
util::strcpy_arr(warning, msg);
|
||||
};
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = LoadModelFromString(xml, error.data(), error.size());
|
||||
EXPECT_THAT(m, NotNull());
|
||||
EXPECT_THAT(warning, HasSubstr("deprecated"));
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
TEST_F(UserCompositeTest, SpacingGreaterThanGeometry) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
|
||||
@@ -795,12 +795,10 @@ TEST_F(XMLWriterTest, WritesSkin) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body name="B0_0" pos="0 0 0">
|
||||
<composite type="cloth" count="2 2 1" spacing="0.05">
|
||||
<skin texcoord="true"/>
|
||||
<geom type="ellipsoid" size="1 1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
<composite type="grid" count="2 2 1" spacing="0.05">
|
||||
<skin texcoord="true"/>
|
||||
<geom size=".01"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
)";
|
||||
@@ -1085,7 +1083,8 @@ TEST_F(PluginTest, WriteReadCompare) {
|
||||
|
||||
if (!mtemp) {
|
||||
// if failing because assets are missing, accept the test
|
||||
ASSERT_THAT(error.data(), HasSubstr("file")) << error.data();
|
||||
ASSERT_THAT(error.data(), HasSubstr("file"))
|
||||
<< error.data() << " from " << xml.c_str();
|
||||
} else {
|
||||
// for a particularly difficult example, relax the tolerance
|
||||
mjtNum tol =
|
||||
|
||||
Reference in New Issue
Block a user