Allow more than 1 activation state per actuator, but only for dyntype user.
Fixes #305. PiperOrigin-RevId: 486597273 Change-Id: I3eb806f60949e68ebe6cbe35a6e66218a167ed45
This commit is contained in:
committed by
Copybara-Service
parent
0514010928
commit
36b30e4500
@@ -234,7 +234,8 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
|
||||
if (m->actuator_actadr[i] == -1) {
|
||||
force[i] = gain * ctrl[i];
|
||||
} else {
|
||||
force[i] = gain * d->act[m->actuator_actadr[i]];
|
||||
// use last activation variable associated with actuator i
|
||||
force[i] = gain * d->act[m->actuator_actadr[i] + m->actuator_actnum[i] - 1];
|
||||
}
|
||||
|
||||
// extract bias info
|
||||
@@ -329,7 +330,13 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
|
||||
|
||||
default: // user dynamics
|
||||
if (mjcb_act_dyn) {
|
||||
d->act_dot[j] = mjcb_act_dyn(m, d, i);
|
||||
if (m->actuator_actnum[i] == 1) {
|
||||
// scalar activation dynamics, get act_dot
|
||||
d->act_dot[j] = mjcb_act_dyn(m, d, i);
|
||||
} else {
|
||||
// higher-order dynamics, mjcb_act_dyn writes into act_dot directly
|
||||
mjcb_act_dyn(m, d, i);
|
||||
}
|
||||
} else {
|
||||
d->act_dot[j] = 0;
|
||||
}
|
||||
@@ -501,7 +508,9 @@ static void mj_advance(const mjModel* m, mjData* d,
|
||||
int j = m->actuator_actadr[i];
|
||||
if (j > -1 && m->actuator_actlimited[i]) {
|
||||
mjtNum* actrange = m->actuator_actrange + 2*i;
|
||||
d->act[j] = mju_clip(d->act[j], actrange[0], actrange[1]);
|
||||
for (int k=0; k<m->actuator_actnum[i]; k++) {
|
||||
d->act[j+k] = mju_clip(d->act[j+k], actrange[0], actrange[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1369,7 +1369,7 @@ const char* mj_validateReferences(const mjModel* m) {
|
||||
X(pair_geom1, npair, ngeom , 0 ) \
|
||||
X(pair_geom2, npair, ngeom , 0 ) \
|
||||
X(actuator_plugin, nu, nplugin , 0 ) \
|
||||
X(actuator_actadr, nu, na , 0 ) \
|
||||
X(actuator_actadr, nu, na , m->actuator_actnum ) \
|
||||
X(sensor_plugin, nsensor, nplugin , 0 ) \
|
||||
X(plugin_stateadr, nplugin, npluginstate , m->plugin_statenum ) \
|
||||
X(plugin_attradr, nplugin, npluginattr , 0 ) \
|
||||
|
||||
@@ -776,7 +776,7 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
|
||||
if (vopt->actuatorgroup[mjMAX(0, mjMIN(mjNGROUP-1, m->actuator_group[i]))]) {
|
||||
// determine extended range
|
||||
mjtNum rng[3] = {-1, 0, +1};
|
||||
mjtNum rmin = -1, rmax = 1, act;
|
||||
mjtNum rmin = -1, rmax = 1, act = 0;
|
||||
if (m->actuator_ctrllimited[i]) {
|
||||
rmin = m->actuator_ctrlrange[2*i];
|
||||
rmax = m->actuator_ctrlrange[2*i+1];
|
||||
@@ -808,7 +808,7 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
|
||||
|
||||
// clamp act to extended range
|
||||
if (vopt->flags[mjVIS_ACTIVATION] && m->actuator_dyntype[i]) {
|
||||
act = mju_clip(d->act[m->actuator_actadr[i]], rng[0], rng[2]);
|
||||
act = mju_clip(d->act[m->actuator_actadr[i] + m->actuator_actnum[i] - 1], rng[0], rng[2]);
|
||||
} else {
|
||||
act = mju_clip(d->ctrl[i], rng[0], rng[2]);
|
||||
}
|
||||
|
||||
@@ -929,7 +929,7 @@ void mjCModel::SetSizes(void) {
|
||||
nu++;
|
||||
} else {
|
||||
nu++;
|
||||
na++;
|
||||
na += actuators[i]->actdim;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1834,7 +1834,9 @@ void mjCModel::CopyObjects(mjModel* m) {
|
||||
m->actuator_biastype[i] = pac->biastype;
|
||||
m->actuator_trnid[2*i] = pac->trnid[0];
|
||||
m->actuator_trnid[2*i+1] = pac->trnid[1];
|
||||
m->actuator_actadr[i] = pac->dyntype == mjDYN_NONE ? -1 : adr++;
|
||||
m->actuator_actadr[i] = pac->dyntype == mjDYN_NONE ? -1 : adr;
|
||||
adr += pac->actdim;
|
||||
m->actuator_actnum[i] = pac->actdim;
|
||||
m->actuator_group[i] = pac->group;
|
||||
m->actuator_ctrllimited[i] = pac->ctrllimited;
|
||||
m->actuator_forcelimited[i] = pac->forcelimited;
|
||||
|
||||
@@ -3390,6 +3390,7 @@ mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) {
|
||||
ctrllimited = 2;
|
||||
forcelimited = 2;
|
||||
actlimited = 2;
|
||||
actdim = -1;
|
||||
trntype = mjTRN_UNDEFINED;
|
||||
dyntype = mjDYN_NONE;
|
||||
gaintype = mjGAIN_FIXED;
|
||||
@@ -3474,6 +3475,23 @@ void mjCActuator::Compile(void) {
|
||||
name.c_str(), id);
|
||||
}
|
||||
|
||||
// check and set actdim
|
||||
if (actdim > 1 && dyntype != mjDYN_USER) {
|
||||
throw mjCError(this, "actdim > 1 is only allowed for dyntype 'user' in actuator '%s' (id = %d)",
|
||||
name.c_str(), id);
|
||||
}
|
||||
if (actdim == 1 && dyntype == mjDYN_NONE) {
|
||||
throw mjCError(this, "invalid actdim 1 in stateless actuator '%s' (id = %d)", name.c_str(), id);
|
||||
}
|
||||
if (actdim == 0 && dyntype != mjDYN_NONE) {
|
||||
throw mjCError(this, "invalid actdim 0 in stateful actuator '%s' (id = %d)", name.c_str(), id);
|
||||
}
|
||||
|
||||
// set actdim
|
||||
if (actdim < 0) {
|
||||
actdim = (dyntype != mjDYN_NONE);
|
||||
}
|
||||
|
||||
// check muscle parameters
|
||||
for (int i=0; i<2; i++) {
|
||||
// select gain or bias
|
||||
|
||||
@@ -873,9 +873,10 @@ class mjCActuator : public mjCBase {
|
||||
public:
|
||||
// variables set by user or API
|
||||
int group; // group for visualization
|
||||
int ctrllimited; // are control limits defined: 0 false, 1 true, 2 auto
|
||||
int forcelimited; // are force limits defined: 0 false, 1 true, 2 auto
|
||||
int actlimited; // are activation limits defined: 0 false, 1 true, 2 auto
|
||||
int ctrllimited; // are control limits defined: 0 false, 1 true, 2 auto
|
||||
int forcelimited; // are force limits defined: 0 false, 1 true, 2 auto
|
||||
int actlimited; // are activation limits defined: 0 false, 1 true, 2 auto
|
||||
int actdim; // dimension of associated activations
|
||||
mjtDyn dyntype; // dynamics type
|
||||
mjtTrn trntype; // transmission type
|
||||
mjtGain gaintype; // gain type
|
||||
|
||||
@@ -159,8 +159,8 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
"solreflimit", "solimplimit", "solreffriction", "solimpfriction",
|
||||
"frictionloss", "springlength", "width", "material",
|
||||
"margin", "stiffness", "damping", "rgba", "user"},
|
||||
{"general", "?", "16", "ctrllimited", "forcelimited", "actlimited", "ctrlrange",
|
||||
"forcerange", "actrange", "gear", "cranklength", "user", "group",
|
||||
{"general", "?", "17", "ctrllimited", "forcelimited", "actlimited", "ctrlrange",
|
||||
"forcerange", "actrange", "gear", "cranklength", "user", "group", "actdim",
|
||||
"dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm"},
|
||||
{"motor", "?", "8", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
|
||||
"gear", "cranklength", "user", "group"},
|
||||
@@ -323,11 +323,11 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
|
||||
{"actuator", "*", "0"},
|
||||
{"<"},
|
||||
{"general", "*", "27", "name", "class", "group",
|
||||
{"general", "*", "28", "name", "class", "group",
|
||||
"ctrllimited", "forcelimited", "actlimited", "ctrlrange", "forcerange", "actrange",
|
||||
"lengthrange", "gear", "cranklength", "user",
|
||||
"joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite",
|
||||
"body", "dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm"},
|
||||
"body", "actdim", "dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm"},
|
||||
{"motor", "*", "18", "name", "class", "group",
|
||||
"ctrllimited", "forcelimited", "ctrlrange", "forcerange",
|
||||
"lengthrange", "gear", "cranklength", "user",
|
||||
@@ -1683,6 +1683,7 @@ void mjXReader::OneActuator(XMLElement* elem, mjCActuator* pact) {
|
||||
ReadAttr(elem, "dynprm", mjNDYN, pact->dynprm, text, false, false);
|
||||
ReadAttr(elem, "gainprm", mjNGAIN, pact->gainprm, text, false, false);
|
||||
ReadAttr(elem, "biasprm", mjNBIAS, pact->biasprm, text, false, false);
|
||||
ReadAttrInt(elem, "actdim", &pact->actdim);
|
||||
}
|
||||
|
||||
// direct drive motor
|
||||
|
||||
@@ -640,6 +640,7 @@ void mjXWriter::OneActuator(XMLElement* elem, mjCActuator* pact, mjCDef* def) {
|
||||
|
||||
// non-plugins: write actuator parameters
|
||||
else {
|
||||
WriteAttrInt(elem, "actdim", pact->actdim, def->actuator.actdim);
|
||||
WriteAttrKey(elem, "dyntype", dyn_map, dyn_sz, pact->dyntype, def->actuator.dyntype);
|
||||
WriteAttrKey(elem, "gaintype", gain_map, gain_sz, pact->gaintype, def->actuator.gaintype);
|
||||
WriteAttrKey(elem, "biastype", bias_map, bias_sz, pact->biastype, def->actuator.biastype);
|
||||
|
||||
Reference in New Issue
Block a user