Add options for controlling early termination criteria of CG/Newton linesearch.

Useful for performance tuning models.

PiperOrigin-RevId: 563175078
Change-Id: Id64a510d6080038ea8d5876dabbf0b2b311435bb
This commit is contained in:
Google DeepMind
2023-09-06 12:02:11 -07:00
committed by Copybara-Service
parent 48d0bfde44
commit 040d3efce2
13 changed files with 61 additions and 19 deletions
+12
View File
@@ -1972,6 +1972,18 @@ adjust it properly through the XML.
improvement between two iterations. For CG and Newton, it is applied to the smaller of the cost improvement and the improvement between two iterations. For CG and Newton, it is applied to the smaller of the cost improvement and the
gradient norm. Set the tolerance to 0 to disable early termination. gradient norm. Set the tolerance to 0 to disable early termination.
.. _option-ls_iterations:
:at:`ls_iterations`: :at-val:`int, "50"`
Maximum number of linesearch iterations performed by CG/Newton constraint solvers. Ensures that at most
:ref:`iterations<option-iterations>` times :ref:`ls_iterations<option-ls_iterations>` linesearch iterations are
performed during each constraint solve.
.. _option-ls_tolerance:
:at:`ls_tolerance`: :at-val:`real, "0.01"`
Tolerance threshold used for early termination of the linesearch algorithm.
.. _option-noslip_iterations: .. _option-noslip_iterations:
:at:`noslip_iterations`: :at-val:`int, "0"` :at:`noslip_iterations`: :at-val:`int, "0"`
+7 -5
View File
@@ -218,15 +218,17 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`timestep<option-timestep>` | :ref:`apirate<option-apirate>` | :ref:`impratio<option-impratio>` | :ref:`tolerance<option-tolerance>` | | | | | | :ref:`timestep<option-timestep>` | :ref:`apirate<option-apirate>` | :ref:`impratio<option-impratio>` | :ref:`tolerance<option-tolerance>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`noslip_tolerance<option-noslip_tolerance>` | :ref:`mpr_tolerance<option-mpr_tolerance>` | :ref:`gravity<option-gravity>` | :ref:`wind<option-wind>` | | | | | | :ref:`ls_tolerance<option-ls_tolerance>` | :ref:`noslip_tolerance<option-noslip_tolerance>` | :ref:`mpr_tolerance<option-mpr_tolerance>` | :ref:`gravity<option-gravity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`magnetic<option-magnetic>` | :ref:`density<option-density>` | :ref:`viscosity<option-viscosity>` | :ref:`o_margin<option-o_margin>` | | | | | | :ref:`wind<option-wind>` | :ref:`magnetic<option-magnetic>` | :ref:`density<option-density>` | :ref:`viscosity<option-viscosity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`o_solref<option-o_solref>` | :ref:`o_solimp<option-o_solimp>` | :ref:`integrator<option-integrator>` | :ref:`collision<option-collision>` | | | | | | :ref:`o_margin<option-o_margin>` | :ref:`o_solref<option-o_solref>` | :ref:`o_solimp<option-o_solimp>` | :ref:`integrator<option-integrator>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`cone<option-cone>` | :ref:`jacobian<option-jacobian>` | :ref:`solver<option-solver>` | :ref:`iterations<option-iterations>` | | | | | | :ref:`collision<option-collision>` | :ref:`cone<option-cone>` | :ref:`jacobian<option-jacobian>` | :ref:`solver<option-solver>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`noslip_iterations<option-noslip_iterations>` | :ref:`mpr_iterations<option-mpr_iterations>` | :ref:`sdf_iterations<option-sdf_iterations>` | :ref:`sdf_initpoints<option-sdf_initpoints>` | | | | | | :ref:`iterations<option-iterations>` | :ref:`ls_iterations<option-ls_iterations>` | :ref:`noslip_iterations<option-noslip_iterations>` | :ref:`mpr_iterations<option-mpr_iterations>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`sdf_iterations<option-sdf_iterations>` | :ref:`sdf_initpoints<option-sdf_initpoints>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| option |br| |_| |L| | | .. table:: | | |_| option |br| |_| |L| | | .. table:: |
+4 -2
View File
@@ -62,17 +62,19 @@ General
Euler integrator. See the :ref:`Numerical Integration<geIntegration>` section for more details. Euler integrator. See the :ref:`Numerical Integration<geIntegration>` section for more details.
11. Added the flag :ref:`invdiscrete<option-flag-invdiscrete>`, which enables discrete-time inverse dynamics for all 11. 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. :ref:`integrators<option-integrator>` other than ``RK4``. See the flag documentation for more details.
12. Added :ref:`ls_iterations<option-ls_iterations>` and :ref:`ls_iterations<option-ls_tolerance>` options for adjusting
linesearch stopping criteria in CG and Newton solvers. This can be useful for performance tuning.
Python bindings Python bindings
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
12. Fixed `#870 <https://github.com/deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid 13. Fixed `#870 <https://github.com/deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
camera name used the default camera. camera name used the default camera.
Bug fixes Bug fixes
^^^^^^^^^ ^^^^^^^^^
13. Fixed a bug that was causing the geom margins to be ignored during the midphase. 14. Fixed a bug that was causing the geom margins to be ignored during the midphase.
Version 2.3.7 (July 20, 2023) Version 2.3.7 (July 20, 2023)
+2
View File
@@ -674,6 +674,7 @@ struct mjOption_ { // physics options
// solver parameters // solver parameters
mjtNum impratio; // ratio of friction-to-normal contact impedance mjtNum impratio; // ratio of friction-to-normal contact impedance
mjtNum tolerance; // main solver tolerance mjtNum tolerance; // main solver tolerance
mjtNum ls_tolerance; // CG/Newton linesearch tolerance
mjtNum noslip_tolerance; // noslip solver tolerance mjtNum noslip_tolerance; // noslip solver tolerance
mjtNum mpr_tolerance; // MPR solver tolerance mjtNum mpr_tolerance; // MPR solver tolerance
@@ -696,6 +697,7 @@ struct mjOption_ { // physics options
int jacobian; // type of Jacobian (mjtJacobian) int jacobian; // type of Jacobian (mjtJacobian)
int solver; // solver algorithm (mjtSolver) int solver; // solver algorithm (mjtSolver)
int iterations; // maximum number of main solver iterations int iterations; // maximum number of main solver iterations
int ls_iterations; // maximum number of CG/Newton linesearch iterations
int noslip_iterations; // maximum number of noslip solver iterations int noslip_iterations; // maximum number of noslip solver iterations
int mpr_iterations; // maximum number of MPR solver iterations int mpr_iterations; // maximum number of MPR solver iterations
int disableflags; // bit flags for disabling standard features int disableflags; // bit flags for disabling standard features
+2
View File
@@ -397,6 +397,7 @@ struct mjOption_ { // physics options
// solver parameters // solver parameters
mjtNum impratio; // ratio of friction-to-normal contact impedance mjtNum impratio; // ratio of friction-to-normal contact impedance
mjtNum tolerance; // main solver tolerance mjtNum tolerance; // main solver tolerance
mjtNum ls_tolerance; // CG/Newton linesearch tolerance
mjtNum noslip_tolerance; // noslip solver tolerance mjtNum noslip_tolerance; // noslip solver tolerance
mjtNum mpr_tolerance; // MPR solver tolerance mjtNum mpr_tolerance; // MPR solver tolerance
@@ -419,6 +420,7 @@ struct mjOption_ { // physics options
int jacobian; // type of Jacobian (mjtJacobian) int jacobian; // type of Jacobian (mjtJacobian)
int solver; // solver algorithm (mjtSolver) int solver; // solver algorithm (mjtSolver)
int iterations; // maximum number of main solver iterations int iterations; // maximum number of main solver iterations
int ls_iterations; // maximum number of CG/Newton linesearch iterations
int noslip_iterations; // maximum number of noslip solver iterations int noslip_iterations; // maximum number of noslip solver iterations
int mpr_iterations; // maximum number of MPR solver iterations int mpr_iterations; // maximum number of MPR solver iterations
int disableflags; // bit flags for disabling standard features int disableflags; // bit flags for disabling standard features
+2
View File
@@ -24,6 +24,7 @@
X( mjtNum, apirate ) \ X( mjtNum, apirate ) \
X( mjtNum, impratio ) \ X( mjtNum, impratio ) \
X( mjtNum, tolerance ) \ X( mjtNum, tolerance ) \
X( mjtNum, ls_tolerance ) \
X( mjtNum, noslip_tolerance ) \ X( mjtNum, noslip_tolerance ) \
X( mjtNum, mpr_tolerance ) \ X( mjtNum, mpr_tolerance ) \
X( mjtNum, density ) \ X( mjtNum, density ) \
@@ -38,6 +39,7 @@
X( int, jacobian ) \ X( int, jacobian ) \
X( int, solver ) \ X( int, solver ) \
X( int, iterations ) \ X( int, iterations ) \
X( int, ls_iterations ) \
X( int, noslip_iterations ) \ X( int, noslip_iterations ) \
X( int, mpr_iterations ) \ X( int, mpr_iterations ) \
X( int, disableflags ) \ X( int, disableflags ) \
+10
View File
@@ -148,6 +148,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=ValueType(name='mjtNum'), type=ValueType(name='mjtNum'),
doc='main solver tolerance', doc='main solver tolerance',
), ),
StructFieldDecl(
name='ls_tolerance',
type=ValueType(name='mjtNum'),
doc='CG/Newton linesearch tolerance',
),
StructFieldDecl( StructFieldDecl(
name='noslip_tolerance', name='noslip_tolerance',
type=ValueType(name='mjtNum'), type=ValueType(name='mjtNum'),
@@ -243,6 +248,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=ValueType(name='int'), type=ValueType(name='int'),
doc='maximum number of main solver iterations', doc='maximum number of main solver iterations',
), ),
StructFieldDecl(
name='ls_iterations',
type=ValueType(name='int'),
doc='maximum number of CG/Newton linesearch iterations',
),
StructFieldDecl( StructFieldDecl(
name='noslip_iterations', name='noslip_iterations',
type=ValueType(name='int'), type=ValueType(name='int'),
+3 -1
View File
@@ -602,9 +602,11 @@ void MakePhysicsSection(mj::Simulate* sim, int oldstate) {
{mjITEM_EDITNUM, "Timestep", 2, &(opt->timestep), "1 0 1"}, {mjITEM_EDITNUM, "Timestep", 2, &(opt->timestep), "1 0 1"},
{mjITEM_EDITINT, "Iterations", 2, &(opt->iterations), "1 0 1000"}, {mjITEM_EDITINT, "Iterations", 2, &(opt->iterations), "1 0 1000"},
{mjITEM_EDITNUM, "Tolerance", 2, &(opt->tolerance), "1 0 1"}, {mjITEM_EDITNUM, "Tolerance", 2, &(opt->tolerance), "1 0 1"},
{mjITEM_EDITINT, "LS Iter", 2, &(opt->ls_iterations), "1 0 100"},
{mjITEM_EDITNUM, "LS Tol", 2, &(opt->ls_tolerance), "1 0 0.1"},
{mjITEM_EDITINT, "Noslip Iter", 2, &(opt->noslip_iterations), "1 0 1000"}, {mjITEM_EDITINT, "Noslip Iter", 2, &(opt->noslip_iterations), "1 0 1000"},
{mjITEM_EDITNUM, "Noslip Tol", 2, &(opt->noslip_tolerance), "1 0 1"}, {mjITEM_EDITNUM, "Noslip Tol", 2, &(opt->noslip_tolerance), "1 0 1"},
{mjITEM_EDITINT, "MRR Iter", 2, &(opt->mpr_iterations), "1 0 1000"}, {mjITEM_EDITINT, "MPR Iter", 2, &(opt->mpr_iterations), "1 0 1000"},
{mjITEM_EDITNUM, "MPR Tol", 2, &(opt->mpr_tolerance), "1 0 1"}, {mjITEM_EDITNUM, "MPR Tol", 2, &(opt->mpr_tolerance), "1 0 1"},
{mjITEM_EDITNUM, "API Rate", 2, &(opt->apirate), "1 0 1000"}, {mjITEM_EDITNUM, "API Rate", 2, &(opt->apirate), "1 0 1000"},
{mjITEM_EDITINT, "SDF Iter", 2, &(opt->sdf_iterations), "1 1 20"}, {mjITEM_EDITINT, "SDF Iter", 2, &(opt->sdf_iterations), "1 1 20"},
+5
View File
@@ -113,6 +113,9 @@ void mj_defaultSolRefImp(mjtNum* solref, mjtNum* solimp) {
// set model options to default values // set model options to default values
void mj_defaultOption(mjOption* opt) { void mj_defaultOption(mjOption* opt) {
// fill opt with zeros in case struct is padded
memset(opt, 0, sizeof(mjOption));
// timing parameters // timing parameters
opt->timestep = 0.002; opt->timestep = 0.002;
opt->apirate = 100; opt->apirate = 100;
@@ -120,6 +123,7 @@ void mj_defaultOption(mjOption* opt) {
// solver parameters // solver parameters
opt->impratio = 1; opt->impratio = 1;
opt->tolerance = 1e-8; opt->tolerance = 1e-8;
opt->ls_tolerance = 0.01;
opt->noslip_tolerance = 1e-6; opt->noslip_tolerance = 1e-6;
opt->mpr_tolerance = 1e-6; opt->mpr_tolerance = 1e-6;
@@ -147,6 +151,7 @@ void mj_defaultOption(mjOption* opt) {
opt->jacobian = mjJAC_AUTO; opt->jacobian = mjJAC_AUTO;
opt->solver = mjSOL_NEWTON; opt->solver = mjSOL_NEWTON;
opt->iterations = 100; opt->iterations = 100;
opt->ls_iterations = 50;
opt->noslip_iterations = 0; opt->noslip_iterations = 0;
opt->mpr_iterations = 50; opt->mpr_iterations = 50;
opt->disableflags = 0; opt->disableflags = 0;
+4 -7
View File
@@ -1093,9 +1093,6 @@ static int updateBracket(const mjModel* m, mjData* d, mjCGContext* ctx,
static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) { static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
mjCGPnt p0, p1, p2, pmid, p1next, p2next; mjCGPnt p0, p1, p2, pmid, p1next, p2next;
const int LSmaxiter = 50;
const mjtNum LStolscl = 0.01;
// clear results // clear results
ctx->LSiter = 0; ctx->LSiter = 0;
ctx->LSresult = 0; ctx->LSresult = 0;
@@ -1109,7 +1106,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
} }
// compute scaled gradtol and slope scaling // compute scaled gradtol and slope scaling
mjtNum gtol = m->opt.tolerance * LStolscl * snorm * m->stat.meaninertia * mjMAX(1, m->nv); mjtNum gtol = m->opt.tolerance * m->opt.ls_tolerance * snorm * m->stat.meaninertia * mjMAX(1, m->nv);
mjtNum slopescl = 1 / (snorm * m->stat.meaninertia * mjMAX(1, m->nv)); mjtNum slopescl = 1 / (snorm * m->stat.meaninertia * mjMAX(1, m->nv));
// compute Mv, Jv // compute Mv, Jv
@@ -1180,7 +1177,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
// one-sided search // one-sided search
int p2update = 0; int p2update = 0;
while (p1.deriv[0]*dir <= -gtol && ctx->LSiter < LSmaxiter) { while (p1.deriv[0]*dir <= -gtol && ctx->LSiter < m->opt.ls_iterations) {
// save current // save current
p2 = p1; p2 = p1;
p2update = 1; p2update = 1;
@@ -1197,7 +1194,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
} }
// check for failure to bracket // check for failure to bracket
if (ctx->LSiter >= LSmaxiter) { if (ctx->LSiter >= m->opt.ls_iterations) {
ctx->LSresult = 3; // could not bracket ctx->LSresult = 3; // could not bracket
ctx->LSslope = mju_abs(p1.deriv[0])*slopescl; ctx->LSslope = mju_abs(p1.deriv[0])*slopescl;
return p1.alpha; return p1.alpha;
@@ -1216,7 +1213,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
CGeval(m, d, ctx, &p1next); CGeval(m, d, ctx, &p1next);
// bracketed search // bracketed search
while (ctx->LSiter < LSmaxiter) { while (ctx->LSiter < m->opt.ls_iterations) {
// evaluate at midpoint // evaluate at midpoint
pmid.alpha = 0.5*(p1.alpha + p2.alpha); pmid.alpha = 0.5*(p1.alpha + p2.alpha);
CGeval(m, d, ctx, &pmid); CGeval(m, d, ctx, &pmid);
+6 -4
View File
@@ -95,12 +95,12 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
"inttotal", "interval", "tolrange"}, "inttotal", "interval", "tolrange"},
{">"}, {">"},
{"option", "*", "24", {"option", "*", "26",
"timestep", "apirate", "impratio", "tolerance", "noslip_tolerance", "mpr_tolerance", "timestep", "apirate", "impratio", "tolerance", "ls_tolerance", "noslip_tolerance",
"gravity", "wind", "magnetic", "density", "viscosity", "mpr_tolerance", "gravity", "wind", "magnetic", "density", "viscosity",
"o_margin", "o_solref", "o_solimp", "o_margin", "o_solref", "o_solimp",
"integrator", "collision", "cone", "jacobian", "integrator", "collision", "cone", "jacobian",
"solver", "iterations", "noslip_iterations", "mpr_iterations", "solver", "iterations", "ls_iterations", "noslip_iterations", "mpr_iterations",
"sdf_iterations", "sdf_initpoints"}, "sdf_iterations", "sdf_initpoints"},
{"<"}, {"<"},
{"flag", "?", "22", "constraint", "equality", "frictionloss", "limit", "contact", {"flag", "?", "22", "constraint", "equality", "frictionloss", "limit", "contact",
@@ -958,6 +958,7 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) {
ReadAttr(section, "apirate", 1, &opt->apirate, text); ReadAttr(section, "apirate", 1, &opt->apirate, text);
ReadAttr(section, "impratio", 1, &opt->impratio, text); ReadAttr(section, "impratio", 1, &opt->impratio, text);
ReadAttr(section, "tolerance", 1, &opt->tolerance, text); ReadAttr(section, "tolerance", 1, &opt->tolerance, text);
ReadAttr(section, "ls_tolerance", 1, &opt->ls_tolerance, text);
ReadAttr(section, "noslip_tolerance", 1, &opt->noslip_tolerance, text); ReadAttr(section, "noslip_tolerance", 1, &opt->noslip_tolerance, text);
ReadAttr(section, "mpr_tolerance", 1, &opt->mpr_tolerance, text); ReadAttr(section, "mpr_tolerance", 1, &opt->mpr_tolerance, text);
ReadAttr(section, "gravity", 3, opt->gravity, text); ReadAttr(section, "gravity", 3, opt->gravity, text);
@@ -976,6 +977,7 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) {
MapValue(section, "jacobian", &opt->jacobian, jac_map, jac_sz); MapValue(section, "jacobian", &opt->jacobian, jac_map, jac_sz);
MapValue(section, "solver", &opt->solver, solver_map, solver_sz); MapValue(section, "solver", &opt->solver, solver_map, solver_sz);
ReadAttrInt(section, "iterations", &opt->iterations); ReadAttrInt(section, "iterations", &opt->iterations);
ReadAttrInt(section, "ls_iterations", &opt->ls_iterations);
ReadAttrInt(section, "noslip_iterations", &opt->noslip_iterations); ReadAttrInt(section, "noslip_iterations", &opt->noslip_iterations);
ReadAttrInt(section, "mpr_iterations", &opt->mpr_iterations); ReadAttrInt(section, "mpr_iterations", &opt->mpr_iterations);
ReadAttrInt(section, "sdf_iterations", &opt->sdf_iterations); ReadAttrInt(section, "sdf_iterations", &opt->sdf_iterations);
+2
View File
@@ -793,6 +793,7 @@ void mjXWriter::Option(XMLElement* root) {
WriteAttr(section, "apirate", 1, &model->option.apirate, &opt.apirate); WriteAttr(section, "apirate", 1, &model->option.apirate, &opt.apirate);
WriteAttr(section, "impratio", 1, &model->option.impratio, &opt.impratio); WriteAttr(section, "impratio", 1, &model->option.impratio, &opt.impratio);
WriteAttr(section, "tolerance", 1, &model->option.tolerance, &opt.tolerance); WriteAttr(section, "tolerance", 1, &model->option.tolerance, &opt.tolerance);
WriteAttr(section, "ls_tolerance", 1, &model->option.ls_tolerance, &opt.ls_tolerance);
WriteAttr(section, "noslip_tolerance", 1, &model->option.noslip_tolerance, &opt.noslip_tolerance); WriteAttr(section, "noslip_tolerance", 1, &model->option.noslip_tolerance, &opt.noslip_tolerance);
WriteAttr(section, "mpr_tolerance", 1, &model->option.mpr_tolerance, &opt.mpr_tolerance); WriteAttr(section, "mpr_tolerance", 1, &model->option.mpr_tolerance, &opt.mpr_tolerance);
WriteAttr(section, "gravity", 3, model->option.gravity, opt.gravity); WriteAttr(section, "gravity", 3, model->option.gravity, opt.gravity);
@@ -816,6 +817,7 @@ void mjXWriter::Option(XMLElement* root) {
WriteAttrKey(section, "solver", solver_map, solver_sz, WriteAttrKey(section, "solver", solver_map, solver_sz,
model->option.solver, opt.solver); model->option.solver, opt.solver);
WriteAttrInt(section, "iterations", model->option.iterations, opt.iterations); WriteAttrInt(section, "iterations", model->option.iterations, opt.iterations);
WriteAttrInt(section, "ls_iterations", model->option.ls_iterations, opt.ls_iterations);
WriteAttrInt(section, "noslip_iterations", model->option.noslip_iterations, opt.noslip_iterations); WriteAttrInt(section, "noslip_iterations", model->option.noslip_iterations, opt.noslip_iterations);
WriteAttrInt(section, "mpr_iterations", model->option.mpr_iterations, opt.mpr_iterations); WriteAttrInt(section, "mpr_iterations", model->option.mpr_iterations, opt.mpr_iterations);
WriteAttrInt(section, "sdf_iterations", model->option.sdf_iterations, opt.sdf_iterations); WriteAttrInt(section, "sdf_iterations", model->option.sdf_iterations, opt.sdf_iterations);
+2
View File
@@ -1769,6 +1769,7 @@ public unsafe struct mjOption_ {
public double apirate; public double apirate;
public double impratio; public double impratio;
public double tolerance; public double tolerance;
public double ls_tolerance;
public double noslip_tolerance; public double noslip_tolerance;
public double mpr_tolerance; public double mpr_tolerance;
public fixed double gravity[3]; public fixed double gravity[3];
@@ -1785,6 +1786,7 @@ public unsafe struct mjOption_ {
public int jacobian; public int jacobian;
public int solver; public int solver;
public int iterations; public int iterations;
public int ls_iterations;
public int noslip_iterations; public int noslip_iterations;
public int mpr_iterations; public int mpr_iterations;
public int disableflags; public int disableflags;