Import upstream snapshot 57d13ead53206a6bf0db3d66f86506ae8c2ce01a

Upstream: https://github.com/pollen-robotics/bam
Upstream-Commit: 57d13ead53206a6bf0db3d66f86506ae8c2ce01a
Upstream-Branch: mjlab_frictionloss
This commit is contained in:
Upstream Snapshot
2026-08-28 15:42:08 +08:00
commit 8be13016bc
131 changed files with 12114 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
DC Motor
========
In BAM, servomotor sources are modeled using DC motors dynamics. A DC motor turns current into torque, according
to the following equation:
.. math::
\tau = k_t i
where :math:`\tau` is the torque, :math:`k_t` is the torque constant, and :math:`i` is the current. When a motor
rotates at a velocity of :math:`\omega`, it generates a back electromotive voltage of :math:`k_t \omega`.
As a result, if you apply a voltage :math:`V` to the motor, the current is given by:
.. math::
i = \frac{V - k_t \omega}{R}
where :math:`R` is the motor resistance. Thus, the torque generated by a DC motor is given by:
.. math::
\tau = k_t \frac{V}{R} - k_t^2 \frac{\omega}{R}
Torque vs speed limit
---------------------
There are typically two limits in play in a DC motor:
* The maximum **voltage** you can apply, this is typically limited because of your battery that, for example,
can only provide 12V
* The maximum **current** you can apply, this is typically enforced by firmwares to avoid overheating the motor.
Let's first look at the voltage limit, using above equation, we get:
.. image:: ../_static/velocity_vs_torque.svg
:alt: Torque vs speed limit
:width: 400
:align: center
The feasible green area here is depicting the limit caused by **voltage** limit. Note that the torque you can apply actually depends on the current speed of the motor. At a given velocity :math:`\omega_0`, you will not even be
able to apply positive torque (this is the no-load speed of the motor). Conversely, at zero speed, there is a
maximum torque :math:`\tau_{stall}` you can apply (this is the stall torque of the motor).
It is in general a good idea to use voltages as high as possible. Firstly because it allows to use smaller wires,
but also because it can make the voltage-related limit less restrictive. However, many servo-actuators run with
low-voltage batteries and fall into that functioning regime.
The second limit is the **current** limit, that is typically enforced by the firmware of the motor. Since the torque
is proportional to current, this limit can be seen as a maximum torque limit :math:`\tau_{max}`:
.. image:: ../_static/velocity_vs_torque_custom_tau_max.svg
:alt: Torque vs speed limit
:width: 400
:align: center
Note that this is, however a *soft* limit. The firmware will *attempt* to limit the current, but it is not guaranteed that it will always be able to do so.
For example, if the motor rotates at a very high speed, the best strategy to provide the less torque is to provide
as much volt as possible. However, your voltage supply is limited, and you might have no choice that to provide a voltage that will generate a current above the limit.
+55
View File
@@ -0,0 +1,55 @@
Theory
======
This section covers the theoretical foundations behind BAM: the pendulum
bench dynamics, the friction-budget formulation used in simulation, and the
six friction model variants M1–M6.
It follows the modeling and identification approach introduced
in the paper `"Extended Friction Models for the Physics Simulation of Servo
Actuators" <https://arxiv.org/pdf/2410.08650>`_ by Marc Duclusaud, Gregoire Passault, Vincent Padois, and Olivier
Ly .
.. grid:: 1 2 2 2
:gutter: 3
:class-container: bam-getting-started
.. grid-item-card:: 📐 Theoretical framework
:link: theory
:link-type: doc
:class-card: bam-card
The pendulum test bench dynamics and the friction-budget formulation
used to apply BAM models in simulation.
+++
:doc:`Theoretical framework → <theory>`
.. grid-item-card:: 🧮 Friction models (M1–M6)
:link: models
:link-type: doc
:class-card: bam-card
The six friction models of increasing expressiveness, from Coulomb
friction to load-dependent and Stribeck effects.
+++
:doc:`Friction models → <models>`
.. grid-item-card:: ⚙️ DC motor
:link: dc_motor
:link-type: doc
:class-card: bam-card
How servomotor sources are modeled as DC motors, turning current into
torque.
+++
:doc:`DC motor → <dc_motor>`
.. toctree::
:hidden:
theory
models
dc_motor
+183
View File
@@ -0,0 +1,183 @@
Friction Models (M1-M6)
=======================
BAM supports six friction models of increasing expressiveness, denoted
:math:`\mathcal{M}_1` to :math:`\mathcal{M}_6`.
They are ordered from the simplest Coulomb-Viscous approximation to a richer
directional and quadratic formulation that better captures gearbox behavior.
- :math:`\mathcal{M}_1`: Coulomb-Viscous
- :math:`\mathcal{M}_2`: Stribeck
- :math:`\mathcal{M}_3`: Load-dependent
- :math:`\mathcal{M}_4`: Stribeck + load-dependent
- :math:`\mathcal{M}_5`: Directional load-dependent
- :math:`\mathcal{M}_6`: Quadratic directional variant
Notation
--------
In the equations below:
- :math:`\dot{\theta}` is joint velocity
- :math:`\tau_m` is motor torque
- :math:`\tau_e` is external/load torque
- :math:`\tau_{fm}` is the maximum resistive friction torque (friction budget)
The simulation then applies friction by clipping the stopping torque in
:math:`[-\tau_{fm},\tau_{fm}]`.
Drive/backdrive diagrams
------------------------
The drive/backdrive diagrams help to visualize the effect of friction. Let's for example consider the :math:`\mathcal{M}_6` model:
.. image:: ../_static/drive_backdrive_m6.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
Here:
- Below the blue line, the motor is driving the system
- Above the red line, the system is backdriving the motor
- On the black dashed line, motor torque and external torque exacttly cancel out
- In the middle, the friction budget is preventing motion in the system
- The lines with less opacity depicts what happens when the system is moving (1 rad/s per step). As you can notice, the faster the system is moving, the less friction appears here.
They can be obtained using ``bam.drive_backdrive`` command from the repository:
.. code-block:: bash
uv run -m bam.drive_backdrive --params bam/params/erob80_100/m1.json --max_torque 100
Model :math:`\mathcal{M}_1`: Coulomb-Viscous
--------------------------------------------
.. image:: ../_static/drive_backdrive_m1.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
.. math::
\mathcal{M}_1:\quad
\tau_{fm} = K_v|\dot{\theta}| + K_c
This is the baseline model used in most physics simulators.
It keeps only viscous damping and a constant Coulomb term.
Model :math:`\mathcal{M}_2`: Stribeck
-------------------------------------
.. image:: ../_static/drive_backdrive_m2.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
.. math::
\mathcal{M}_2:\quad
\tau_{fm} = K_v|\dot{\theta}| + K_c +
\exp\left(-\left|\frac{\dot{\theta}}{\dot{\theta}_s}\right|^{\alpha}\right)K_{cs}
This adds higher friction near zero speed and smooth transition to sliding.
It models the fact that static friction is usually stronger than sliding friction.
Model :math:`\mathcal{M}_3`: Load-dependent
-------------------------------------------
.. image:: ../_static/drive_backdrive_m3.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
.. math::
\mathcal{M}_3:\quad
\tau_{fm} = K_v|\dot{\theta}| + K_c + K_l|\tau_m - \tau_e|
This captures the increase of friction with transmitted gearbox load.
It is useful when the apparent resistance depends on how hard the transmission is loaded.
Model :math:`\mathcal{M}_4`: Stribeck + load-dependent
------------------------------------------------------
.. image:: ../_static/drive_backdrive_m4.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
.. math::
\mathcal{M}_4:\quad
\tau_{fm} = K_v|\dot{\theta}| + K_c + K_l|\tau_m-\tau_e|
+ \exp\left(-\left|\frac{\dot{\theta}}{\dot{\theta}_s}\right|^{\alpha}\right)
\left(K_{cs} + K_{ls}|\tau_m-\tau_e|\right)
This combines presliding dynamics with load dependence.
It adds Stribeck smoothing on top of a load-sensitive friction budget.
Model :math:`\mathcal{M}_5`: Directional load-dependent
-------------------------------------------------------
.. image:: ../_static/drive_backdrive_m5.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
.. math::
\mathcal{M}_5:\quad
\tau_{fm} = K_v|\dot{\theta}| + K_c + |K_m\tau_m - K_e\tau_e|
+ \exp\left(-\left|\frac{\dot{\theta}}{\dot{\theta}_s}\right|^{\alpha}\right)
\left(K_{cs} + |K_{ms}\tau_m - K_{es}\tau_e|\right)
This separates motor-side and external-side contributions, which helps model
directional efficiency/backdrivability asymmetry.
It is appropriate when the gearbox behaves differently depending on the torque direction.
Model :math:`\mathcal{M}_6`: Quadratic directional
--------------------------------------------------
.. image:: ../_static/drive_backdrive_m6.png
:alt: Drive/backdrive diagram
:width: 500
:align: center
.. math::
\mathcal{M}_6:\quad
\tau_{fm} = K_v|\dot{\theta}| + K_c + |K_m\tau_m - K_e\tau_e|
+ \exp\left(-\left|\frac{\dot{\theta}}{\dot{\theta}_s}\right|^{\alpha}\right)
\left(K_{cs} + |K_{ms}\tau_m - K_{es}\tau_e| + Q\right)
with piecewise quadratic contribution:
.. math::
Q =
\begin{cases}
K_{eq}\tau_e^2 & \text{if } |\tau_m| > |\tau_e| \\
K_{mq}\tau_m^2 & \text{otherwise}
\end{cases}
This is useful for actuators where harmonic-drive-like effects create nonlinear
load-friction coupling.
It extends the directional model with a quadratic load term.
Modeling hierarchy
------------------
The sequence :math:`\mathcal{M}_1 \rightarrow \mathcal{M}_6` reflects increasing
expressiveness and parameter count. In practice, BAM fits all candidates and
selects the best trade-off from validation error.
Implementation in BAM
---------------------
Model behaviors are implemented in :mod:`bam.model`, notably:
- :class:`bam.model.Model`
- :func:`bam.model.load_model`
- :func:`bam.model.load_model_from_dict`
+66
View File
@@ -0,0 +1,66 @@
Theoretical Framework
=====================
Pendulum test bench dynamics
----------------------------
For a single-axis pendulum test bench:
.. math::
\tau_m + \tau_e(\theta) + \tau_f = J\ddot{\theta}
where:
- :math:`\theta` is the joint position
- :math:`\tau_m` is the actuator torque
- :math:`\tau_e(\theta) = mgl\sin(\theta)` is the gravity torque
- :math:`\tau_f` is the friction torque
- :math:`J` is the apparent inertia (load + actuator side)
Friction as a torque budget
---------------------------
The Coulomb-Viscous form is typically written as a force opposed to velocity.
In BAM, friction is handled through a maximum available resistive torque
:math:`\tau_{fm}`.
For a discrete simulator with time step :math:`\Delta t`, stopping at next step
requires:
.. math::
\dot{\theta}_{k+1} = 0
which yields the stopping torque:
.. math::
\tau_{f,stop} = -\left(\frac{J}{\Delta t}\dot{\theta} + \tau_m + \tau_e\right)
The applied friction is then this stopping torque clipped to the available friction budget:
.. math::
\tau_f = \mathrm{clip}(\tau_{f,stop}, -\tau_{fm}, \tau_{fm})
Each model :math:`\mathcal{M}_i` defines :math:`\tau_{fm}` with a different level
of expressiveness.
Servo model + friction model coupling
-------------------------------------
In BAM, simulation combines:
- a servo model :math:`\mathcal{S}` that maps state and target to motor torque
- a friction model :math:`\mathcal{M}` that computes the friction budget
At each step:
1. compute :math:`\tau_m` from control law and motor model
2. compute :math:`\tau_{fm}` from chosen friction model
3. compute :math:`\tau_f` by clipping :math:`\tau_{f,stop}`
4. integrate acceleration from bench dynamics
This makes the framework both identifiable from logs and directly usable in
simulation.