Skip to content

Actuator Options

Actuator options describe a physical motor (rotor inertia, gear ratio, effort and velocity limits, ...) so a robot preset can derive its armature and PD gains from the hardware instead of hand-tuned numbers. ActuatorSpecOptions is the base; the presets below model the motors of the built-in Unitree, DAMIAO and LimX robots. The robots guide shows how a robot preset uses them.

from eden.options.actuators import Unitree7520_14

Actuator specification options and motor presets (Unitree, DAMIAO, LimX).

Classes

ActuatorSpecOptions

ActuatorSpecOptions(**data)

Bases: ConfigurableOptions

Specification of a single actuator's physical and control parameters.

PARAMETER DESCRIPTION
STIFFNESS

Stiffness of the actuator (different from control stiffness, i.e., kp) [N*m/rad]

DAMPING

Damping of the actuator (different from control damping, i.e., kd) [Nms/rad]

FULL_TORQUE_SPEED

(X1) Maximum Speed at Full Torque (T-N Curve Knee Point) [rad/s]

NO_LOAD_SPEED

(X2) No-Load Speed Test Result [rad/s]

DRIVING_TORQUE_LIMIT

(Y1) Driving Torque Limit, i.e., Torque and Speed in the Same Direction [N*m]

BRAKING_TORQUE_LIMIT

(Y2) Braking Torque Limit, i.e., Torque and Speed in the Opposite Direction [N*m]

EFFORT_LIMIT

Maximum torque limit to prevent mechanical damage [N*m]

STATIC_FRICTION

Static Friction Coefficient

DYNAMIC_FRICTION

Dynamic Friction Coefficient

FRICTION_ACTIVATION_SPEED

Velocity at which the friction is fully activated [rad/s]

ROTOR_INERTIA

Rotor inertia of the motor [kg*m^2]

GEAR_RATIO

Gear ratio of the gearbox

NOTE

Per-joint motor torque-speed envelope parameters.

The torque-speed curve is defined as follows:

    Torque Limit, N·m
        ^

Y2──────────| |──────────────Y1 | │ | │ | │ | | ------------+--------------|------> velocity: rad/s X1 X2

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

STIFFNESS class-attribute
STIFFNESS: float = 0.0
DAMPING class-attribute
DAMPING: float = 0.0
FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 1000000000.0
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 1000000000.0
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 1000000000.0
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 1000000000.0
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 1000000000.0
STATIC_FRICTION class-attribute
STATIC_FRICTION: float = 0.0
DYNAMIC_FRICTION class-attribute
DYNAMIC_FRICTION: float = 0.0
FRICTION_ACTIVATION_SPEED class-attribute
FRICTION_ACTIVATION_SPEED: float = 0.01
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float | tuple[float, float, float] = 0.0
GEAR_RATIO class-attribute
GEAR_RATIO: float | tuple[float, float, float] = 1.0

Methods:

ARMATURE classmethod
ARMATURE() -> float
Source code in eden/options/actuators.py
@classmethod
def ARMATURE(cls) -> float:
    if isinstance(cls.ROTOR_INERTIA, float):
        assert isinstance(cls.GEAR_RATIO, float), "Expected single-stage gearbox (1 gear ratio)"
        return reflected_inertia(cls.ROTOR_INERTIA, cls.GEAR_RATIO)
    elif isinstance(cls.ROTOR_INERTIA, tuple):
        assert isinstance(cls.GEAR_RATIO, tuple), "Expected two-stage planetary gearbox (3 gear ratios)"
        assert len(cls.ROTOR_INERTIA) == len(cls.GEAR_RATIO)
        assert len(cls.GEAR_RATIO) == 3, "Expected two-stage planetary gearbox (3 gear ratios)"
        return reflected_inertia_from_two_stage_planetary(cls.ROTOR_INERTIA, cls.GEAR_RATIO)
    else:
        return 0.0
RAIBERT_HEURISTIC_KP classmethod
RAIBERT_HEURISTIC_KP() -> float

Return the control stiffness (kp) computed using the Raibert Heuristic [N*m/rad].

Source code in eden/options/actuators.py
@classmethod
def RAIBERT_HEURISTIC_KP(cls) -> float:
    """Return the control stiffness (kp) computed using the Raibert Heuristic [N*m/rad]."""
    return raibert_heuristic_kp(cls)
RAIBERT_HEURISTIC_KD classmethod
RAIBERT_HEURISTIC_KD(damping_ratio: float = 2.0) -> float

Return the control damping (kd) computed using the Raibert Heuristic [Nms/rad].

Source code in eden/options/actuators.py
@classmethod
def RAIBERT_HEURISTIC_KD(cls, damping_ratio: float = 2.0) -> float:
    """Return the control damping (kd) computed using the Raibert Heuristic [N*m*s/rad]."""
    return raibert_heuristic_kd(cls, damping_ratio=damping_ratio)
RAIBERT_HEURISTIC_ACTION_SCALE classmethod
RAIBERT_HEURISTIC_ACTION_SCALE() -> float
Source code in eden/options/actuators.py
@classmethod
def RAIBERT_HEURISTIC_ACTION_SCALE(cls) -> float:
    return raibert_heuristic_action_scale(cls)

Unitree7520_22

Unitree7520_22(**data)

Bases: ActuatorSpecOptions

Unitree N7520-22.5 motor used in G1 robot.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 14.5
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 22.7
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 111.0
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 131.0
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 139.0
STATIC_FRICTION class-attribute
STATIC_FRICTION: float = 2.4
DYNAMIC_FRICTION class-attribute
DYNAMIC_FRICTION: float = 0.24
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: tuple[float, float, float] = (4.89e-05, 1.09e-05, 7.38e-05)
GEAR_RATIO class-attribute
GEAR_RATIO: tuple[float, float, float] = (1.0, 4.5, 5.0)

Unitree7520_14

Unitree7520_14(**data)

Bases: ActuatorSpecOptions

Unitree N7520-14.3 motor used in G1 robot.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 22.63
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 35.52
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 71.0
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 83.3
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 88.0
STATIC_FRICTION class-attribute
STATIC_FRICTION: float = 1.6
DYNAMIC_FRICTION class-attribute
DYNAMIC_FRICTION: float = 0.16
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: tuple[float, float, float] = (4.89e-05, 9.8e-06, 5.33e-05)
GEAR_RATIO class-attribute
GEAR_RATIO: tuple[float, float, float] = (1.0, 4.5, 1.0 + 48 / 22)

Unitree5020_16

Unitree5020_16(**data)

Bases: ActuatorSpecOptions

Unitree N5020-16 motor used in G1 robot.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 30.86
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 40.13
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 24.8
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 31.9
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 25.0
STATIC_FRICTION class-attribute
STATIC_FRICTION: float = 0.6
DYNAMIC_FRICTION class-attribute
DYNAMIC_FRICTION: float = 0.06
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: tuple[float, float, float] = (1.39e-05, 1.7e-06, 1.69e-05)
GEAR_RATIO class-attribute
GEAR_RATIO: tuple[float, float, float] = (1.0, 1.0 + 46 / 18, 1.0 + 56 / 16)

Unitree5020_16_DOUBLE

Unitree5020_16_DOUBLE(**data)

Bases: Unitree5020_16

Two Unitree N5020-16 motors driving a single joint via a 4-bar linkage.

Used for G1 waist pitch/roll and G1 ankle pitch/roll.

Assumes a nominal 1:1 linkage ratio. Under this assumption: - Joint speed limits are identical to a single motor (rotors spin synchronously at joint speed). - Joint torque, friction, and reflected inertia are the sum of both motors' contributions.

Note that the true effective armature is configuration-dependent because of the linkage geometry.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = Unitree5020_16.DRIVING_TORQUE_LIMIT * 2
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = Unitree5020_16.BRAKING_TORQUE_LIMIT * 2
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = Unitree5020_16.EFFORT_LIMIT * 2
STATIC_FRICTION class-attribute
STATIC_FRICTION: float = Unitree5020_16.STATIC_FRICTION * 2
DYNAMIC_FRICTION class-attribute
DYNAMIC_FRICTION: float = Unitree5020_16.DYNAMIC_FRICTION * 2
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: tuple[float, float, float] = tuple(2.0 * r for r in Unitree5020_16.ROTOR_INERTIA)

Unitree4010_25

Unitree4010_25(**data)

Bases: ActuatorSpecOptions

Unitree W4010-25 motor used in G1 robot.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 15.3
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 24.76
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 4.8
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 8.6
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 5.0
STATIC_FRICTION class-attribute
STATIC_FRICTION: float = 0.6
DYNAMIC_FRICTION class-attribute
DYNAMIC_FRICTION: float = 0.06
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: tuple[float, float, float] = (6.8e-06, 0.0, 0.0)
GEAR_RATIO class-attribute
GEAR_RATIO: tuple[float, float, float] = (1.0, 5.0, 5.0)

Unitree8010_6

Unitree8010_6(**data)

Bases: ActuatorSpecOptions

Unitree M8010-6 motor used in Go1 robot.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 13.5
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 30.0
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 20.2
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 23.4
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 23.7
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 0.000111842
GEAR_RATIO class-attribute
GEAR_RATIO: float = 6.33

Unitree8010_6Calf

Unitree8010_6Calf(**data)

Bases: Unitree8010_6

Unitree M8010-6 motor used in Go1 robot with 1.5 gear ratio (linkage ratio) for calf joint.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = Unitree8010_6.FULL_TORQUE_SPEED / 1.5
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = Unitree8010_6.NO_LOAD_SPEED / 1.5
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = Unitree8010_6.DRIVING_TORQUE_LIMIT * 1.5
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = Unitree8010_6.BRAKING_TORQUE_LIMIT * 1.5
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = Unitree8010_6.EFFORT_LIMIT * 1.5
GEAR_RATIO class-attribute
GEAR_RATIO: float = Unitree8010_6.GEAR_RATIO * 1.5

UnitreeGo2HV

UnitreeGo2HV(**data)

Bases: ActuatorSpecOptions

Unitree Go2 HV motor used in Go2 robot (this is a best guess).

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 16.0
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 36.0
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 30.0
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 34.5
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 35.55
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 0.000125
GEAR_RATIO class-attribute
GEAR_RATIO: float = 6.22

UnitreeGo2HVCalf

UnitreeGo2HVCalf(**data)

Bases: UnitreeGo2HV

Unitree Go2 HV motor used in Go2 robot with 1.5 gear ratio (linkage ratio) for calf joint.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = UnitreeGo2HV.FULL_TORQUE_SPEED / 1.5
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = UnitreeGo2HV.NO_LOAD_SPEED / 1.5
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = UnitreeGo2HV.DRIVING_TORQUE_LIMIT * 1.5
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = UnitreeGo2HV.BRAKING_TORQUE_LIMIT * 1.5
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = UnitreeGo2HV.EFFORT_LIMIT * 1.5
GEAR_RATIO class-attribute
GEAR_RATIO: float = UnitreeGo2HV.GEAR_RATIO * 1.5

DamiaoDM4310

DamiaoDM4310(**data)

Bases: ActuatorSpecOptions

DAMIAO DM-J4310-2EC servo motor used as the wrist-joint and gripper motor on the i2rt YAM arm.

24V, 10:1 internal planetary gearbox, gearbox-output peak torque 7 N·m, driving J4-J6 plus the fingers.

Speed/torque values are at the gearbox output shaft per the data sheet; ROTOR_INERTIA is the motor-side rotor inertia and GEAR_RATIO folds in the internal planetary, so :meth:ARMATURE returns the joint-side reflected armature.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 12.57
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 20.94
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 3.0
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 3.0
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 7.0
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 1.8e-05
GEAR_RATIO class-attribute
GEAR_RATIO: float = 10.0

DamiaoDM4340

DamiaoDM4340(**data)

Bases: ActuatorSpecOptions

DAMIAO DM-J4340-2EC servo motor (24V variant).

40:1 internal planetary gearbox, joint-side nominal/peak torque 9 / 27 N·m.

Datasheet (24V): nominal current 2.5 A, peak current 8 A, nominal torque 9 N·m, peak torque 27 N·m, nominal speed 36 rpm, max no-load speed 52 rpm.

Speed/torque values are at the gearbox output shaft per the data sheet; ROTOR_INERTIA is the motor-side rotor inertia and GEAR_RATIO folds in the internal planetary, so :meth:ARMATURE returns the joint-side reflected armature (≈ 0.032 kg·m²).

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

FULL_TORQUE_SPEED class-attribute
FULL_TORQUE_SPEED: float = 3.77
NO_LOAD_SPEED class-attribute
NO_LOAD_SPEED: float = 5.45
DRIVING_TORQUE_LIMIT class-attribute
DRIVING_TORQUE_LIMIT: float = 9.0
BRAKING_TORQUE_LIMIT class-attribute
BRAKING_TORQUE_LIMIT: float = 9.0
EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 27.0
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 2e-05
GEAR_RATIO class-attribute
GEAR_RATIO: float = 40.0

LimxOliActuator

LimxOliActuator(**data)

Bases: ActuatorSpecOptions

LimX Oli (HU_D04) actuator base.

LimX publishes no datasheets, so only EFFORT_LIMIT (the deployed user_torque_limit) and the joint-side reflected armature are set; speed and friction stay at defaults (TODO). The gearbox split is unknown, so the reflected armature (the armature in the RL MJCF HU_D04_01_agmr.xml) is encoded directly as ROTOR_INERTIA with GEAR_RATIO = 1.

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

GEAR_RATIO class-attribute
GEAR_RATIO: float = 1.0

LimxOliHipKnee

LimxOliHipKnee(**data)

Bases: LimxOliActuator

Oli hip + knee actuator (140 N·m class).

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 140.0
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 0.14125

LimxOliAnkleWaist

LimxOliAnkleWaist(**data)

Bases: LimxOliActuator

Oli ankle + waist actuator (42 N·m class).

Ankle (*_achilles push-rods) and waist roll/pitch (waist_A/waist_B) are parallel linkages, so the effective reflected armature (0.09488) is ~14% above the physical single-joint value (0.0835).

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 42.0
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 0.09488

LimxOliShoulderElbow

LimxOliShoulderElbow(**data)

Bases: LimxOliActuator

Oli shoulder + elbow actuator (42 N·m class, direct drive).

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 42.0
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 0.0886706

LimxOliWristHead

LimxOliWristHead(**data)

Bases: LimxOliActuator

Oli wrist + head actuator (19 N·m class).

Source code in eden/options/options.py
def __init__(self, **data):
    # Seed type metadata as construction data so BaseModel validates it into
    # __pydantic_extra__ (no-op for extra="forbid" classes, which use
    # the serialization envelope instead).
    data.update(option_metadata(self))
    # NOTE: all of the option modifications/validations should be done in the __init__ method
    try:
        BaseModel.__init__(self, **data)
    except ValidationError as exc:
        # A misspelled field on an extra="forbid" class should teach the field set, not just
        # name the typo. Only rewritten when every error is extra_forbidden.
        enriched = _enrich_extra_forbidden(type(self), exc)
        if enriched is None:
            raise
        raise enriched from None

Attributes

EFFORT_LIMIT class-attribute
EFFORT_LIMIT: float = 19.0
ROTOR_INERTIA class-attribute
ROTOR_INERTIA: float = 0.0153218

Functions:

The helpers that turn a motor spec into armature and gains (reflected_inertia, raibert_heuristic_kp, ...) are on the robotics utilities page.

See also