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
+5
View File
@@ -113,6 +113,9 @@ void mj_defaultSolRefImp(mjtNum* solref, mjtNum* solimp) {
// set model options to default values
void mj_defaultOption(mjOption* opt) {
// fill opt with zeros in case struct is padded
memset(opt, 0, sizeof(mjOption));
// timing parameters
opt->timestep = 0.002;
opt->apirate = 100;
@@ -120,6 +123,7 @@ void mj_defaultOption(mjOption* opt) {
// solver parameters
opt->impratio = 1;
opt->tolerance = 1e-8;
opt->ls_tolerance = 0.01;
opt->noslip_tolerance = 1e-6;
opt->mpr_tolerance = 1e-6;
@@ -147,6 +151,7 @@ void mj_defaultOption(mjOption* opt) {
opt->jacobian = mjJAC_AUTO;
opt->solver = mjSOL_NEWTON;
opt->iterations = 100;
opt->ls_iterations = 50;
opt->noslip_iterations = 0;
opt->mpr_iterations = 50;
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) {
mjCGPnt p0, p1, p2, pmid, p1next, p2next;
const int LSmaxiter = 50;
const mjtNum LStolscl = 0.01;
// clear results
ctx->LSiter = 0;
ctx->LSresult = 0;
@@ -1109,7 +1106,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
}
// 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));
// compute Mv, Jv
@@ -1180,7 +1177,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
// one-sided search
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
p2 = p1;
p2update = 1;
@@ -1197,7 +1194,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
}
// check for failure to bracket
if (ctx->LSiter >= LSmaxiter) {
if (ctx->LSiter >= m->opt.ls_iterations) {
ctx->LSresult = 3; // could not bracket
ctx->LSslope = mju_abs(p1.deriv[0])*slopescl;
return p1.alpha;
@@ -1216,7 +1213,7 @@ static mjtNum CGsearch(const mjModel* m, mjData* d, mjCGContext* ctx) {
CGeval(m, d, ctx, &p1next);
// bracketed search
while (ctx->LSiter < LSmaxiter) {
while (ctx->LSiter < m->opt.ls_iterations) {
// evaluate at midpoint
pmid.alpha = 0.5*(p1.alpha + p2.alpha);
CGeval(m, d, ctx, &pmid);
+6 -4
View File
@@ -95,12 +95,12 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
"inttotal", "interval", "tolrange"},
{">"},
{"option", "*", "24",
"timestep", "apirate", "impratio", "tolerance", "noslip_tolerance", "mpr_tolerance",
"gravity", "wind", "magnetic", "density", "viscosity",
{"option", "*", "26",
"timestep", "apirate", "impratio", "tolerance", "ls_tolerance", "noslip_tolerance",
"mpr_tolerance", "gravity", "wind", "magnetic", "density", "viscosity",
"o_margin", "o_solref", "o_solimp",
"integrator", "collision", "cone", "jacobian",
"solver", "iterations", "noslip_iterations", "mpr_iterations",
"solver", "iterations", "ls_iterations", "noslip_iterations", "mpr_iterations",
"sdf_iterations", "sdf_initpoints"},
{"<"},
{"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, "impratio", 1, &opt->impratio, 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, "mpr_tolerance", 1, &opt->mpr_tolerance, 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, "solver", &opt->solver, solver_map, solver_sz);
ReadAttrInt(section, "iterations", &opt->iterations);
ReadAttrInt(section, "ls_iterations", &opt->ls_iterations);
ReadAttrInt(section, "noslip_iterations", &opt->noslip_iterations);
ReadAttrInt(section, "mpr_iterations", &opt->mpr_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, "impratio", 1, &model->option.impratio, &opt.impratio);
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, "mpr_tolerance", 1, &model->option.mpr_tolerance, &opt.mpr_tolerance);
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,
model->option.solver, opt.solver);
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, "mpr_iterations", model->option.mpr_iterations, opt.mpr_iterations);
WriteAttrInt(section, "sdf_iterations", model->option.sdf_iterations, opt.sdf_iterations);