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
+18 -15
View File
@@ -6446,14 +6446,14 @@ This element has the following custom attributes in addition to the common attri
.. _actuator-dcmotor-saturation:
:at:`saturation`: :at-val:`real(4), "0 0 0 0"`
Limits on the actuator, defined as :at:`saturation` = ":at-val:`torque` :at-val:`current` :at-val:`voltage`
:at:`saturation`: :at-val:`real(3), "0 0 0"`
Limits on the actuator, defined as :at:`saturation` = ":at-val:`torque` :at-val:`current`
:at-val:`current_rate`". :at-val:`torque` and :at-val:`current` are alternative specifications of the maximum
continuous torque: if :at-val:`current` is given, :at-val:`torque` :math:`= K \cdot` :at-val:`current`; if both are
given, :at-val:`torque` takes precedence. Sets :at:`forcerange` to [:math:`-\tau_{\max},\, \tau_{\max}`].
:at-val:`voltage` sets the maximum voltage :math:`V_{\max}`. :at-val:`current_rate` sets the maximum rate of change
of current :math:`(di/dt)_{\max}` (requires :ref:`inductance<actuator-dcmotor-inductance>`). A value of 0 (the
default) for any sub-value disables the respective limit. (see `tech note <_static/dcmotor.pdf>`__, Section 2)
:at-val:`current_rate` sets the maximum rate of change of current :math:`(di/dt)_{\max}` (requires
:ref:`inductance<actuator-dcmotor-inductance>`). A value of 0 (the default) for any sub-value disables the respective
limit. (see `tech note <_static/dcmotor.pdf>`__, Section 2)
.. _actuator-dcmotor-cogging:
@@ -6465,12 +6465,12 @@ This element has the following custom attributes in addition to the common attri
.. _actuator-dcmotor-lugre:
:at:`lugre`: :at-val:`real(6), "0 0 0 0 0 0"`
LuGre friction, defined as :at:`lugre` = ":at-val:`stiffness` :at-val:`damping` :at-val:`viscous` :at-val:`coulomb`
:at-val:`static` :at-val:`stribeck`" (N·m/rad, N·m·s/rad, N·m·s/rad, N·m, N·m, rad/s). Disabled when
:at:`lugre`: :at-val:`real(5), "0 0 0 0 0"`
LuGre friction, defined as :at:`lugre` = ":at-val:`stiffness` :at-val:`damping` :at-val:`coulomb`
:at-val:`static` :at-val:`stribeck`" (N·m/rad, N·m·s/rad, N·m, N·m, rad/s). Disabled when
:at-val:`stiffness` = 0 (the default). Adds one activation variable for bristle deflection. Note that the
:at-val:`viscous` coefficient is mapped directly to the actuator :ref:`damping<actuator-general-damping>` array
(specifically the linear term, :at-val:`damping[0]`). If both are specified, their values are summed.
viscous damping coefficient :math:`\sigma_2` is not part of the :at:`lugre` attribute and should be
added to the standard actuator :ref:`damping<actuator-general-damping>` attribute.
(see `tech note <_static/dcmotor.pdf>`__, Sections 1.4 and 2.4)
.. _actuator-dcmotor-input:
@@ -6482,12 +6482,15 @@ This element has the following custom attributes in addition to the common attri
.. _actuator-dcmotor-controller:
:at:`controller`: :at-val:`real(5), "0 0 0 0 0"`
:at:`controller`: :at-val:`real(6), "0 0 0 0 0 0"`
PID controller parameters, defined as :at:`controller` = ":at-val:`kp` :at-val:`ki` :at-val:`kd`
:at-val:`slewmax` :at-val:`Imax`". Depending on the :at:`input` mode, the controller stabilizes either position or
velocity. If the :at:`input` mode is voltage, this attribute is ignored. A value of 0 (the default) disables the
respective feature: :at-val:`slewmax` = 0 means no slew-rate limiting, :at-val:`Imax` = 0 means no anti-windup
clamping. (see `tech note <_static/dcmotor.pdf>`__, Section 2.5)
:at-val:`slewmax` :at-val:`Imax` :at-val:`Vmax`". Depending on the :at:`input` mode, the controller stabilizes
either position or velocity. If the :at:`input` mode is voltage, :at-val:`kp`, :at-val:`ki`, :at-val:`kd` are
ignored. :at-val:`Vmax` sets the maximum drive voltage :math:`v_{\max}` (Volt); in position/velocity modes it clamps
the controller output, in voltage mode it clamps the control signal (if :at:`ctrlrange` is also set, the tighter
limit wins). A value of 0 (the default) disables the respective feature. When positive, :at-val:`slewmax` limits the
setpoint rate-of-change, :at-val:`Imax` clamps the integrator state (anti-windup), and :at-val:`Vmax` clamps the
drive voltage. (see `tech note <_static/dcmotor.pdf>`__, Section 2.5)
.. _actuator-plugin:
BIN
View File
Binary file not shown.
+12 -14
View File
@@ -81,7 +81,7 @@
\newcommand{\atNLS}{\texttt{nominal:no\_load\_speed}}
\newcommand{\atTMAX}{\texttt{saturation:torque}}
\newcommand{\atIMAX}{\texttt{saturation:current}}
\newcommand{\atVMAX}{\texttt{saturation:voltage}}
\newcommand{\atVMAX}{\texttt{controller:Vmax}}
\newcommand{\atCRATE}{\texttt{saturation:current\_rate}}
\newcommand{\atKP}{\texttt{controller:kp}}
\newcommand{\atKI}{\texttt{controller:ki}}
@@ -104,7 +104,6 @@
\newcommand{\atTAUC}{\texttt{lugre:coulomb}}
\newcommand{\atTAUS}{\texttt{lugre:static}}
\newcommand{\atWS}{\texttt{lugre:stribeck}}
\newcommand{\atSIGV}{\texttt{lugre:viscous}}
\title{MuJoCo DC Motor Model}
\author{Google DeepMind}
@@ -338,7 +337,7 @@ Motor drivers often impose a hard limit on $di/dt$ to protect windings and elect
\subsection{Mechanical Model}
\label{sec:mechanical}
Several purely mechanical phenomena affect the motor's behavior and the effective delivered torque.
Several purely mechanical phenomena affect the motor's behavior and delivered torque, warping the electromagnetic performance envelope.
\paragraph{Mechanical losses.}
These reduce the net torque available at the shaft: $\tau_{\text{net}} = \tau_{\text{elec}} - \tau_{\text{loss}}$.
@@ -355,7 +354,7 @@ These reduce the net torque available at the shaft: $\tau_{\text{net}} = \tau_{\
\end{equation}
This provides one constraint on two unknowns ($\tau_c$ and $B$). Without additional data, the user must either assume one dominates or obtain friction measurements at multiple speeds. In MuJoCo terms, $\tau_c$ maps to \texttt{frictionloss} and $B$ to \texttt{damping}.
\noindent Combining current saturation with both mechanical losses, the net torque is:
Combining current saturation with both mechanical losses, the net torque is:
\begin{equation*}
\tau_{\text{net}} = \text{clip}\!\left( \frac{K}{R}(v - K \, \omega),\;
\pm K\, i_{\max} \right) - B \, \omega - \tau_c \, \text{sgn}(\omega)
@@ -485,7 +484,7 @@ where $A$ is the amplitude, $N_p$ is the number of pole pairs times the number o
Symbol & Description & Formula / Note \\
\midrule
$\tau_c$ & Coulomb friction & $\tau_c\,\text{sgn}(\omega)$ \\
$B$ & Viscous drag (linear) & $B\,\omega$ \\
$B$ & Viscous drag (linear) & $-B\,\omega$ \\
$\omega_0$ & No-load speed &
$\omega_0 = v\,K / (K^2 + R\,B)$ \\
$J_r$ & Rotor inertia & units: kg$\cdot$m$^2$ \\
@@ -496,7 +495,7 @@ $N_p$ & Cogging periodicity & poles $\times$ slots/pole \\
$\phi$ & Cogging phase & offset \\
\bottomrule
\end{tabular}
\caption{Named constants related to mechanical properties. Note that unlike in Table~\ref{tab:electromech_constants}, the non-approximate expression for $\omega_0$ takes into account the linear drag $B$ (assuming no high-order terms).}
\caption{Named constants related to mechanical properties. Unlike in Table~\ref{tab:electromech_constants}, the non-approximate expression for $\omega_0$ takes into account the linear drag $B$ (assuming no high-order terms).}
\label{tab:key_constants}
\end{table}
@@ -795,7 +794,7 @@ Here we describe MuJoCo's \texttt{dcmotor} actuator. Some scalars are grouped in
\begin{table}[H]
\centering
\footnotesize
\begin{tabular}{@{}lll@{}}
\begin{tabular}{@{}llp{5cm}@{}}
\toprule
Attribute & Size & Description \\
\midrule
@@ -804,18 +803,18 @@ Attribute & Size & Description \\
\texttt{nominal} & 3 & Nominal operating point ($v_n, \tau_0, \omega_0$) \\
\texttt{inductance} & 2 & Electrical dynamics ($L, t_e$) \\
\texttt{thermal} & 6 & Thermal model ($R_T, C, t_T, \alpha, T_0, T_a$) \\
\texttt{saturation} & 4 & Limits ($\tau_{\max}, i_{\max}, v_{\max}, (di{/}dt)_{\max}$) \\
\texttt{saturation} & 3 & Limits ($\tau_{\max}, i_{\max}, (di{/}dt)_{\max}$) \\
\midrule
\texttt{cogging} & 3 & Cogging torque ($A, N_p, \phi$) \\
\texttt{lugre} & 6 & LuGre friction ($\sigma_0, \sigma_1, \sigma_2, \tau_c, \tau_s, \omega_s$) \\
\texttt{lugre} & 5 & LuGre friction ($\sigma_0, \sigma_1, \tau_c, \tau_s, \omega_s$) \\
\texttt{damping} & 3 & Viscous damping coefficients \\
\texttt{armature} & 1 & Armature inertia \\
\midrule
\texttt{input} & keyword & Mode (voltage/position/velocity) \\
\texttt{controller} & 5 & Gains and slew ($k_p, k_i, k_d, s, I_{\max}$) \\
\texttt{controller} & 6 & Gains, slew, and voltage saturation ($k_p, k_i, k_d, s, I_{\max}, v_{\max}$) \\
\bottomrule
\end{tabular}
\caption{MJCF attributes for the \texttt{dcmotor} actuator, split into electrical, mechanical and control groupings.}
\caption{MJCF attributes for the \texttt{dcmotor} actuator, split into electrical, mechanical and controller groupings.}
\label{tab:mjcf_attributes}
\end{table}
@@ -1025,7 +1024,7 @@ Iron losses (\S\ref{sec:thermal_losses}), magnet flux derating (\S\ref{sec:magne
A bristle deflection state governed by the LuGre model (\S\ref{sec:lugre}) is added if the bristle stiffness $\sigma_0 > 0$.
The Stribeck function $g(\omega)$, Eq.~\eqref{eq:stribeck}, determines velocity-dependent friction, and the friction force is given by Eq.~\eqref{eq:lugre_force}. The bristle state is integrated using the exact ZOH scheme~\eqref{eq:zoh}. The viscous term $\sigma_2 \omega$ is mapped directly to the standard \texttt{actuator\_damping} attribute to leverage MuJoCo's implicit integration, while maintaining the $\sigma_2$ \texttt{lugre} sub-attribute for convenience.
The Stribeck function $g(\omega)$, Eq.~\eqref{eq:stribeck}, determines velocity-dependent friction, and the friction force is given by Eq.~\eqref{eq:lugre_force}. The bristle state is integrated using the exact ZOH scheme~\eqref{eq:zoh}. The viscous term $\sigma_2 \omega$ is specified by via the standard \texttt{damping} attribute to leverage MuJoCo's implicit integration.
\paragraph{Integration.}
The bristle stiffness $\sigma_0$ is typically very large ($10^5$--$10^6$ N$\cdot$m/rad), creating a stiff ODE. At constant velocity, the state equation~\eqref{eq:lugre_state} has the form $\dot{z} = a z + b \omega$ where $a = -\sigma_0 |\omega| / g(\omega)$ and $b = 1$. Euler integration is unstable unless $|1 + a \Delta t| < 1$, requiring impractically small timesteps ($\Delta t < 2g(\omega)/(\sigma_0 |\omega|)$, on the order of microseconds).
Under a zero-order hold assumption ($\omega$ constant over the timestep), the linear ODE $\dot{z} = az + b\omega$ can be solved exactly:
@@ -1045,7 +1044,6 @@ Attribute & Symbol & Units \\
\midrule
\atSIG{} & $\sigma_0$ & N$\cdot$m/rad \\
\atSIGD{} & $\sigma_1$ & N$\cdot$m$\cdot$s/rad \\
\atSIGV{} & $\sigma_2$ & N$\cdot$m$\cdot$s/rad \\
\atTAUC{} & $\tau_c$ & N$\cdot$m \\
\atTAUS{} & $\tau_s$ & N$\cdot$m \\
\atWS{} & $\omega_s$ & rad/s \\
@@ -1081,7 +1079,7 @@ Attribute & Type & Description \\
\label{tab:controller_attributes}
\end{table}
\noindent Unlike the motor parameters in Table~\ref{tab:datasheet}, controller gains are user-specified firmware settings. Gains are in {\em voltage-space} (e.g., $k_p$ in V/rad) since the output is a voltage $v$. To convert from physical torque-space (N$\cdot$m/rad), multiply by $R/K$.
\noindent Unlike the motor parameters in Table~\ref{tab:datasheet}, controller gains are user-specified firmware settings with units that vary by manufacturer. MuJoCo uses direct {\em voltage-space} units (e.g., $k_p$ in V/rad). Torque-space (N$\cdot$m/rad) gains can be converted by multiplying by $R/K$, though empirical calibration is often necessary due to unknown internal units on real hardware.
The controller computes a target voltage $v$ from the \texttt{ctrl} command. All motor physics --- cogging, saturation, friction, etc. --- apply identically downstream of $v$. The \texttt{input} attribute selects the controller:
+3 -3
View File
@@ -3664,9 +3664,9 @@ const char* mjs_setToMuscle(mjsActuator* actuator, double timeconst[2], double t
double lmax, double vmax, double fpmax, double fvmax);
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);
mjsMesh* mjs_addMesh(mjSpec* s, const mjsDefault* def);
mjsHField* mjs_addHField(mjSpec* s);
mjsSkin* mjs_addSkin(mjSpec* s);