Add <dcmotor> actuator and related docs and tests.

PiperOrigin-RevId: 892927987
Change-Id: I38ed6412801341ba03ddf5fe7b93a6081df24d37
This commit is contained in:
Yuval Tassa
2026-04-01 07:49:53 -07:00
committed by Copybara-Service
parent 6da210c794
commit 70a7647ad9
31 changed files with 3994 additions and 55 deletions
+6 -3
View File
@@ -263,7 +263,8 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjDYN_FILTER', 2),
('mjDYN_FILTEREXACT', 3),
('mjDYN_MUSCLE', 4),
('mjDYN_USER', 5),
('mjDYN_DCMOTOR', 5),
('mjDYN_USER', 6),
]),
)),
('mjtGain',
@@ -274,7 +275,8 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjGAIN_FIXED', 0),
('mjGAIN_AFFINE', 1),
('mjGAIN_MUSCLE', 2),
('mjGAIN_USER', 3),
('mjGAIN_DCMOTOR', 3),
('mjGAIN_USER', 4),
]),
)),
('mjtBias',
@@ -285,7 +287,8 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjBIAS_NONE', 0),
('mjBIAS_AFFINE', 1),
('mjBIAS_MUSCLE', 2),
('mjBIAS_USER', 3),
('mjBIAS_DCMOTOR', 3),
('mjBIAS_USER', 4),
]),
)),
('mjtObj',
+80
View File
@@ -10786,6 +10786,86 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Set actuator to active adhesion; return error if any.',
)),
('mjs_setToDCMotor',
FunctionDecl(
name='mjs_setToDCMotor',
return_type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
parameters=(
FunctionParameterDecl(
name='actuator',
type=PointerType(
inner_type=ValueType(name='mjsActuator'),
),
),
FunctionParameterDecl(
name='motorconst',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(2,),
),
),
FunctionParameterDecl(
name='resistance',
type=ValueType(name='double'),
),
FunctionParameterDecl(
name='nominal',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(3,),
),
),
FunctionParameterDecl(
name='saturation',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(4,),
),
),
FunctionParameterDecl(
name='inductance',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(2,),
),
),
FunctionParameterDecl(
name='cogging',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(3,),
),
),
FunctionParameterDecl(
name='controller',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(5,),
),
),
FunctionParameterDecl(
name='thermal',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(6,),
),
),
FunctionParameterDecl(
name='lugre',
type=ArrayType(
inner_type=ValueType(name='double'),
extents=(6,),
),
),
FunctionParameterDecl(
name='input_mode',
type=ValueType(name='int'),
),
),
doc='Set actuator to DC motor; return error if any.',
)),
('mjs_addMesh',
FunctionDecl(
name='mjs_addMesh',
+25
View File
@@ -1303,6 +1303,31 @@ PYBIND11_MODULE(_specs, m) {
}
},
py::arg("gain"));
mjsActuator.def(
"set_to_dcmotor",
[](raw::MjsActuator* self, std::array<double, 2> motorconst,
double resistance,
std::array<double, 3> nominal, std::array<double, 4> saturation,
std::array<double, 2> inductance, std::array<double, 3> cogging,
std::array<double, 5> controller, std::array<double, 6> thermal,
std::array<double, 6> lugre, int input_mode) {
std::string err = mjs_setToDCMotor(
self, motorconst.data(), resistance, nominal.data(),
saturation.data(), inductance.data(), cogging.data(),
controller.data(), thermal.data(), lugre.data(), input_mode);
if (!err.empty()) {
throw pybind11::value_error(err);
}
},
py::arg("motorconst"), py::arg("resistance"),
py::arg("nominal") = std::array<double, 3>{0, 0, 0},
py::arg("saturation") = std::array<double, 4>{0, 0, 0, 0},
py::arg("inductance") = std::array<double, 2>{0, 0},
py::arg("cogging") = std::array<double, 3>{0, 0, 0},
py::arg("controller") = std::array<double, 5>{0, 0, 0, 0, 0},
py::arg("thermal") = std::array<double, 6>{0, 0, 0, 0, 0, 0},
py::arg("lugre") = std::array<double, 6>{0, 0, 0, 0, 0, 0},
py::arg("input_mode") = 0);
// ============================= MJSTENDONPATH ===============================
// helper struct for tendon path indexing
+7
View File
@@ -1557,6 +1557,13 @@ class SpecsTest(absltest.TestCase):
self.assertEqual(actuator.gaintype, mujoco.mjtGain.mjGAIN_FIXED)
self.assertEqual(actuator.biastype, mujoco.mjtBias.mjBIAS_NONE)
actuator.set_to_dcmotor(motorconst=[0.05, 0.05], resistance=2.0)
self.assertEqual(actuator.gainprm[0], 2.0)
self.assertEqual(actuator.gainprm[1], 0.05)
self.assertEqual(actuator.dyntype, mujoco.mjtDyn.mjDYN_DCMOTOR)
self.assertEqual(actuator.gaintype, mujoco.mjtGain.mjGAIN_DCMOTOR)
self.assertEqual(actuator.biastype, mujoco.mjtBias.mjBIAS_DCMOTOR)
def test_bad_contact_sensor(self):
test_cases = [
dict(