Changes to dcmotor:

- Remove `lugre:viscous`, should now be added directly to actuator `damping`. Trying to do this for the user was incompatible with default inheritance (compounding instead of overriding).
- Move voltage limiting from the `saturation` to the `controller` attribute.
- Fix indexing issues in default inheritance.

PiperOrigin-RevId: 897087642
Change-Id: I5388c2633e15c7e223992e7eb5d6a28db75a6438
This commit is contained in:
Yuval Tassa
2026-04-09 06:51:57 -07:00
committed by Copybara-Service
parent 26fb65c7a7
commit 81720071b8
14 changed files with 335 additions and 85 deletions
+16 -16
View File
@@ -1122,9 +1122,9 @@ const char* mjs_setToAdhesion(mjsActuator* actuator, double gain) {
const char* mjs_setToDCMotor(mjsActuator* actuator, double motorconst[2], double resistance,
double nominal[3], double saturation[4], double inductance[2],
double cogging[3], double controller[5], double thermal[6],
double lugre[6], int input_mode) {
double nominal[3], double saturation[3], double inductance[2],
double cogging[3], double controller[6], double thermal[6],
double lugre[5], int input_mode) {
double R = resistance; // electrical resistance
double Kt = motorconst ? motorconst[0] : 0; // torque constant
double Ke = motorconst ? motorconst[1] : 0; // back-EMF constant
@@ -1134,9 +1134,8 @@ const char* mjs_setToDCMotor(mjsActuator* actuator, double motorconst[2], double
// derive Ke from nominal: omega0 = vn*Ke / (Ke^2 + R*B)
if (vn > 0 && Ke <= 0 && omega0 > 0) {
// viscous damping (linear), add lugre sigma2 contribution if any
// viscous damping (linear)
double B = actuator->damping[0];
if (lugre && lugre[0] > 0) B += lugre[2];
if (B > 0 && R > 0) {
// R known: solve quadratic Ke^2*omega0 - Ke*vn + R*B*omega0 = 0
@@ -1184,12 +1183,9 @@ const char* mjs_setToDCMotor(mjsActuator* actuator, double motorconst[2], double
actuator->dynprm[7] = controller ? controller[3] : 0; // slewmax
actuator->dynprm[8] = controller ? controller[4] : 0; // Imax
// saturation: [tau_max, i_max, (di/dt)_max, v_max]
if (saturation && saturation[2] > 0) {
actuator->dynprm[1] = saturation[2]; // (di/dt)_max
}
if (saturation && saturation[3] > 0) {
actuator->gainprm[7] = saturation[3]; // v_max
// controller parameters: gainprm[7] for v_max
if (controller && controller[5] > 0) {
actuator->gainprm[7] = controller[5]; // v_max
}
// saturation -> forcerange
@@ -1203,6 +1199,11 @@ const char* mjs_setToDCMotor(mjsActuator* actuator, double motorconst[2], double
actuator->forcelimited = 1;
}
// saturation: [tau_max, i_max, (di/dt)_max]
if (saturation && saturation[2] > 0) {
actuator->dynprm[1] = saturation[2]; // (di/dt)_max
}
// cogging: [amplitude, periodicity, phase] -> biasprm[0:3]
actuator->biasprm[0] = cogging ? cogging[0] : 0; // amplitude
actuator->biasprm[1] = cogging ? cogging[1] : 0; // periodicity
@@ -1258,14 +1259,13 @@ const char* mjs_setToDCMotor(mjsActuator* actuator, double motorconst[2], double
actdim++;
}
// lugre: {stiffness, damping, viscous, coulomb, static, stribeck}
// lugre: {stiffness, damping, coulomb, static, stribeck}
if (lugre && lugre[0] > 0) {
actuator->dynprm[5] = lugre[0]; // stiffness -> sigma0
actuator->dynprm[6] = lugre[1]; // damping -> sigma1
actuator->damping[0] += lugre[2]; // viscous -> sigma2
actuator->biasprm[3] = lugre[3]; // coulomb -> tau_c
actuator->biasprm[4] = lugre[4]; // static -> tau_s
actuator->biasprm[5] = lugre[5]; // stribeck -> omega_s
actuator->biasprm[3] = lugre[2]; // coulomb -> tau_c
actuator->biasprm[4] = lugre[3]; // static -> tau_s
actuator->biasprm[5] = lugre[4]; // stribeck -> omega_s
actdim++;
}
+3 -3
View File
@@ -194,9 +194,9 @@ MJAPI const char* mjs_setToAdhesion(mjsActuator* actuator, double gain);
// Set actuator to DC motor, return error on failure.
MJAPI const char* mjs_setToDCMotor(mjsActuator* actuator, double motorconst[2], double resistance,
double nominal[3], double saturation[4], double inductance[2],
double cogging[3], double controller[5], double thermal[6],
double lugre[6], int input_mode);
double nominal[3], double saturation[3], double inductance[2],
double cogging[3], double controller[6], double thermal[6],
double lugre[5], int input_mode);
//---------------------------------- Add assets ----------------------------------------------------
+11 -12
View File
@@ -2526,14 +2526,14 @@ void mjXReader::OneActuator(XMLElement* elem, mjsActuator* actuator) {
double motorconst[2] = {inherited ? actuator->gainprm[1] : 0, 0};
double resistance = inherited ? actuator->gainprm[0] : 0;
double nominal[3] = {0, 0, 0};
double saturation[4] = {0, 0,
inherited ? actuator->dynprm[1] : 0,
inherited ? actuator->gainprm[8] : 0};
double controller[5] = {inherited ? actuator->gainprm[5] : 0,
double saturation[3] = {0, 0,
inherited ? actuator->dynprm[1] : 0};
double controller[6] = {inherited ? actuator->gainprm[4] : 0,
inherited ? actuator->gainprm[5] : 0,
inherited ? actuator->gainprm[6] : 0,
inherited ? actuator->gainprm[7] : 0,
inherited ? actuator->dynprm[7] : 0,
inherited ? actuator->dynprm[8] : 0};
inherited ? actuator->dynprm[8] : 0,
inherited ? actuator->gainprm[7] : 0};
double inductance[2] = {0, inherited ? actuator->dynprm[0] : 0};
double cogging[3] = {inherited ? actuator->biasprm[0] : 0,
inherited ? actuator->biasprm[1] : 0,
@@ -2544,22 +2544,21 @@ void mjXReader::OneActuator(XMLElement* elem, mjsActuator* actuator) {
inherited ? actuator->gainprm[2] : 0,
inherited ? actuator->gainprm[3] : 0,
inherited ? actuator->dynprm[4] : 0};
double lugre[6] = {inherited ? actuator->dynprm[5] : 0,
double lugre[5] = {inherited ? actuator->dynprm[5] : 0,
inherited ? actuator->dynprm[6] : 0,
inherited ? actuator->damping[0] : 0,
inherited ? actuator->biasprm[3] : 0,
inherited ? actuator->biasprm[4] : 0,
inherited ? actuator->biasprm[5] : 0};
int input_mode = inherited ? (int)actuator->gainprm[9] : 0;
int input_mode = inherited ? (int)actuator->gainprm[8] : 0;
ReadAttr(elem, "motorconst", 2, motorconst, text, false, false);
ReadAttr(elem, "resistance", 1, &resistance, text);
ReadAttr(elem, "nominal", 3, nominal, text, false, false);
ReadAttr(elem, "saturation", 4, saturation, text, false, false);
ReadAttr(elem, "saturation", 3, saturation, text, false, false);
ReadAttr(elem, "inductance", 2, inductance, text, false, false);
ReadAttr(elem, "cogging", 3, cogging, text, false, false);
ReadAttr(elem, "controller", 5, controller, text, false, false);
ReadAttr(elem, "controller", 6, controller, text, false, false);
ReadAttr(elem, "thermal", 6, thermal, text, false, false);
ReadAttr(elem, "lugre", 6, lugre, text, false, false);
ReadAttr(elem, "lugre", 5, lugre, text, false, false);
if (MapValue(elem, "input", &input_mode, dcmotorinput_map, dcmotorinput_sz)) {
// successfully parsed
}