Import upstream snapshot 57d13ead53206a6bf0db3d66f86506ae8c2ce01a
Upstream: https://github.com/pollen-robotics/bam Upstream-Commit: 57d13ead53206a6bf0db3d66f86506ae8c2ce01a Upstream-Branch: mjlab_frictionloss
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
Identified actuators
|
||||
====================
|
||||
|
||||
Each motor below ships with pre-identified friction parameters. Click a motor
|
||||
to browse its JSON parameters, or use the **Use in MuJoCo** / **Use in mjlab**
|
||||
buttons to jump to the integration guide with the code examples pre-filled for
|
||||
that motor.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 14 14 18 28 26
|
||||
:class: actuators-table
|
||||
|
||||
* - Actuator
|
||||
- Image
|
||||
- Name
|
||||
- Description
|
||||
- Use in simulation
|
||||
|
||||
* - **MX-64**
|
||||
- .. image:: ../_static/actuator_mx64.png
|
||||
:width: 120px
|
||||
|
||||
- ``mx64``
|
||||
- ROBOTIS Dynamixel MX-64 servo-actuator
|
||||
(`Parameters <https://github.com/Rhoban/bam/tree/main/bam/params/mx64>`__,
|
||||
`model <https://github.com/Rhoban/bam/blob/main/bam/dynamixel/actuator.py>`__,
|
||||
`raw data <https://huggingface.co/buckets/Gregwar/bam_data/resolve/mx64_raw.tgz?download=true>`__)
|
||||
- .. raw:: html
|
||||
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mujoco_cpu.html?motor=mx64">Use in MuJoCo</a>
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mjlab_gpu.html?motor=mx64">Use in mjlab</a>
|
||||
|
||||
* - **MX-106**
|
||||
- .. image:: ../_static/actuator_mx106.png
|
||||
:width: 120px
|
||||
|
||||
- ``mx106``
|
||||
- ROBOTIS Dynamixel MX-106 servo-actuator
|
||||
(`Parameters <https://github.com/Rhoban/bam/tree/main/bam/params/mx106>`__,
|
||||
`model <https://github.com/Rhoban/bam/blob/main/bam/dynamixel/actuator.py>`__,
|
||||
`raw data <https://huggingface.co/buckets/Gregwar/bam_data/resolve/mx106_raw.tgz?download=true>`__)
|
||||
- .. raw:: html
|
||||
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mujoco_cpu.html?motor=mx106">Use in MuJoCo</a>
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mjlab_gpu.html?motor=mx106">Use in mjlab</a>
|
||||
|
||||
* - **XL-320**
|
||||
- .. image:: ../_static/actuator_xl320.png
|
||||
:width: 120px
|
||||
|
||||
- ``xl320``
|
||||
- ROBOTIS Dynamixel XL-320 servo-actuator
|
||||
(`Parameters <https://github.com/Rhoban/bam/tree/main/bam/params/xl320>`__,
|
||||
`model <https://github.com/Rhoban/bam/blob/main/bam/dynamixel/actuator.py>`__)
|
||||
- .. raw:: html
|
||||
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mujoco_cpu.html?motor=xl320">Use in MuJoCo</a>
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mjlab_gpu.html?motor=xl320">Use in mjlab</a>
|
||||
|
||||
* - **XL-330**
|
||||
- .. image:: ../_static/actuator_xl330.png
|
||||
:width: 120px
|
||||
|
||||
- ``xl330``
|
||||
- ROBOTIS Dynamixel XL-330 servo-actuator
|
||||
(`Parameters <https://github.com/Rhoban/bam/tree/main/bam/params/xl330>`__,
|
||||
`model <https://github.com/Rhoban/bam/blob/main/bam/dynamixel/actuator.py>`__)
|
||||
- .. raw:: html
|
||||
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mujoco_cpu.html?motor=xl330">Use in MuJoCo</a>
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mjlab_gpu.html?motor=xl330">Use in mjlab</a>
|
||||
|
||||
* - **STS3215 (7.4V)**
|
||||
- .. image:: ../_static/actuator_feetech_sts3215_7_4V.png
|
||||
:width: 120px
|
||||
|
||||
- ``feetech_sts3215_7_4V``
|
||||
- Feetech STS3215 servo-actuator (7.4V version)
|
||||
(`Parameters <https://github.com/Rhoban/bam/tree/main/bam/params/feetech_sts3215_7_4V>`__,
|
||||
`model <https://github.com/Rhoban/bam/blob/main/bam/feetech/actuator.py>`__,
|
||||
`raw data <https://huggingface.co/buckets/Gregwar/bam_data/resolve/feetech_sts3215_raw.zip?download=true>`__)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p class="mini-warning">⚠ Only the <code>m1</code> model was identified for this actuator.</p>
|
||||
- .. raw:: html
|
||||
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mujoco_cpu.html?motor=feetech_sts3215_7_4V">Use in MuJoCo</a>
|
||||
<a class="sd-btn sd-btn-outline-primary motor-btn" href="mjlab_gpu.html?motor=feetech_sts3215_7_4V">Use in mjlab</a>
|
||||
@@ -0,0 +1,15 @@
|
||||
Examples
|
||||
========
|
||||
|
||||
BAM is used in real open-source robotics projects. If you are looking for
|
||||
inspiration on how to wire it into a full pipeline, these are good places to
|
||||
start:
|
||||
|
||||
- **mjlab (GPU)** — `MjLab Microban <https://github.com/MarcDcls/mjlab_microban>`_ is an
|
||||
open-source project, in which the fully open-source 30 cm humanoid Microban
|
||||
learns to walk. It shows how to plug :class:`bam.mjlab.BamActuatorCfg` into
|
||||
a vectorized MuJoCo Warp training pipeline.
|
||||
- **MuJoCo (CPU)** — `Microban <https://github.com/MarcDcls/microban>`_ is
|
||||
the repository containing the CAD and codebase for the Microban humanoid.
|
||||
It shows how to use :class:`bam.mujoco.MujocoController` in the MuJoCo
|
||||
simulation of the robot run by ``make sim``.
|
||||
@@ -0,0 +1,60 @@
|
||||
Usage
|
||||
=====
|
||||
|
||||
This section explains how to use identified models in simulation stacks.
|
||||
|
||||
.. grid:: 1 2 2 2
|
||||
:gutter: 3
|
||||
:class-container: bam-getting-started
|
||||
|
||||
.. grid-item-card:: 📇 Identified actuators
|
||||
:link: actuators
|
||||
:link-type: doc
|
||||
:class-card: bam-card
|
||||
|
||||
Browse the bundled library of pre-identified servo-actuators and the
|
||||
friction parameters shipped for each of them.
|
||||
|
||||
+++
|
||||
:doc:`Browse actuators → <actuators>`
|
||||
|
||||
.. grid-item-card:: 🖥️ MuJoCo (CPU)
|
||||
:link: mujoco_cpu
|
||||
:link-type: doc
|
||||
:class-card: bam-card
|
||||
|
||||
Plug BAM friction models into a standard MuJoCo simulation running on
|
||||
CPU with :class:`bam.mujoco.MujocoController`.
|
||||
|
||||
+++
|
||||
:doc:`MuJoCo CPU guide → <mujoco_cpu>`
|
||||
|
||||
.. grid-item-card:: ⚡ mjlab (MuJoCo GPU)
|
||||
:link: mjlab_gpu
|
||||
:link-type: doc
|
||||
:class-card: bam-card
|
||||
|
||||
Integrate BAM into an mjlab pipeline running on GPU with MuJoCo Warp
|
||||
via :class:`bam.mjlab.BamActuatorCfg`.
|
||||
|
||||
+++
|
||||
:doc:`mjlab GPU guide → <mjlab_gpu>`
|
||||
|
||||
.. grid-item-card:: 🤖 Examples
|
||||
:link: examples
|
||||
:link-type: doc
|
||||
:class-card: bam-card
|
||||
|
||||
See BAM wired into real open-source robotics projects for end-to-end
|
||||
inspiration.
|
||||
|
||||
+++
|
||||
:doc:`Browse examples → <examples>`
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
actuators
|
||||
mujoco_cpu
|
||||
mjlab_gpu
|
||||
examples
|
||||
@@ -0,0 +1,212 @@
|
||||
mjlab (MuJoCo GPU)
|
||||
==================
|
||||
|
||||
This page explains how to integrate BAM friction models into an mjlab
|
||||
pipeline running on GPU with MuJoCo Warp. The entry point is
|
||||
:class:`bam.mjlab.BamActuatorCfg`.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
BAM is available on PyPI. Install it with the ``mjlab`` extra, which pulls in
|
||||
mjlab together with mujoco, mujoco-warp and torch:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
pip install better-actuator-models[mjlab]
|
||||
|
||||
Or, with `uv <https://docs.astral.sh/uv/>`_:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
uv add "better-actuator-models[mjlab]"
|
||||
|
||||
BAM is compatible with mjlab 1.3.
|
||||
|
||||
Registering the BAM init event
|
||||
------------------------------
|
||||
|
||||
First, be sure to register the ``bam_init`` function as a startup event in your environment:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from bam.mjlab import bam_init
|
||||
|
||||
# cfg is your mjlab task configuration
|
||||
cfg.events["bam_init"] = EventTermCfg(func=bam_init, mode="startup")
|
||||
|
||||
|
||||
|
||||
Instantiating the config
|
||||
------------------------
|
||||
|
||||
:class:`~bam.mjlab.BamActuatorCfg` is a dataclass that plugs into mjlab's
|
||||
actuator system. When an ``Entity`` is built, it instantiates a
|
||||
:class:`~bam.mjlab.BamActuator` that runs the full BAM pipeline — voltage
|
||||
control law, DC motor torque, and BAM friction budget — fully vectorized
|
||||
over all parallel environments via PyTorch tensors.
|
||||
|
||||
Two approaches are available, mutually exclusive:
|
||||
|
||||
**Bundled motor:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from bam.mjlab import BamActuatorCfg
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
motor_name="{actuator}",
|
||||
model="m6",
|
||||
target_names_expr=(r".*",),
|
||||
)
|
||||
|
||||
**Custom JSON** (parameters produced by ``bam.fit``):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
json_path="params/my_motor/m6.json",
|
||||
target_names_expr=(r".*",),
|
||||
)
|
||||
|
||||
The ``target_names_expr`` field is a tuple of regex patterns that select
|
||||
which actuated joints this config controls.
|
||||
|
||||
- Supported bundled motors: see the :doc:`list of identified actuators <actuators>`.
|
||||
- Supported model variants: ``"m1"`` through ``"m6"`` (see :doc:`../theory/models`).
|
||||
|
||||
Voltage and P-gain overrides
|
||||
-----------------------------
|
||||
|
||||
By default, the supply voltage and firmware P-gain are read from the
|
||||
parameter JSON. They can be overridden at config level:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
motor_name="{actuator}",
|
||||
model="m6",
|
||||
target_names_expr=(r".*",),
|
||||
vin=7.5, # supply voltage [V]
|
||||
kp_fw=125.0, # firmware P-gain
|
||||
)
|
||||
|
||||
Domain randomization
|
||||
--------------------
|
||||
|
||||
:class:`~bam.mjlab.BamActuatorCfg` supports per-environment randomization
|
||||
of two physical quantities that are naturally variable across hardware units
|
||||
or charge states.
|
||||
|
||||
**Battery voltage** — sample a different supply voltage for each environment
|
||||
at startup:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
motor_name="{actuator}",
|
||||
model="m6",
|
||||
target_names_expr=(r".*",),
|
||||
vin_range=(7.0, 8.0), # sampled uniformly at startup [V]
|
||||
)
|
||||
|
||||
``vin_range`` takes precedence over ``vin`` when both are set.
|
||||
|
||||
**Voltage drop resistance** — model battery + cable resistance with a per-env
|
||||
equivalent resistor between the battery and the motors:
|
||||
|
||||
.. math::
|
||||
|
||||
V_\text{eff} = V_\text{in} - R_\text{drop} \, I,
|
||||
\qquad
|
||||
I = \frac{1}{K_t} \sum_i |\tau_i|
|
||||
|
||||
where :math:`R_\text{drop}` (``vin_drop_resistance_range``) is the combined
|
||||
battery + wire resistance in ohms, and the current :math:`I` is estimated from
|
||||
the actuator torques using the torque constant :math:`K_t`. Randomizing this
|
||||
resistance captures variability in cable length or connector quality across
|
||||
units:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
motor_name="{actuator}",
|
||||
model="m6",
|
||||
target_names_expr=(r".*",),
|
||||
vin_range=(7.0, 8.0),
|
||||
vin_drop_resistance_range=(0.05, 0.15), # [Ohm] ~100 mOhms of wire & battery resistance
|
||||
vin_min=6.0, # hard lower bound [V]
|
||||
)
|
||||
|
||||
Both ranges are sampled once at initialization and held constant across
|
||||
episode resets.
|
||||
|
||||
.. warning::
|
||||
|
||||
The voltage drop is computed independently by each
|
||||
:class:`~bam.mjlab.BamActuator` from its own joints' current draw. If several
|
||||
actuator configs share the same physical battery, their currents are **not**
|
||||
summed together, so the modeled drop underestimates the real one. Group all
|
||||
joints powered by the same battery under a single :class:`~bam.mjlab.BamActuatorCfg`
|
||||
if you need the shared-supply behavior. In the current implementation, only one model
|
||||
can be used per actuator config, voltage drop will not function properly if different motors
|
||||
are mixed in the same config.
|
||||
|
||||
Command delay
|
||||
-------------
|
||||
|
||||
BAM inherits mjlab's command delay system, which models the latency between
|
||||
policy output and motor response (e.g. communication bus latency, firmware
|
||||
scheduling). The lag is expressed in simulation steps and can be randomized
|
||||
per environment:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
motor_name="{actuator}",
|
||||
model="m6",
|
||||
target_names_expr=(r".*",),
|
||||
delay_min_lag=1, # always at least 1 step of delay
|
||||
# = 5ms with mjlab's default 200Hz control loop
|
||||
delay_max_lag=3, # up to 3 steps, randomized per env
|
||||
# = 15ms with mjlab's default 200Hz control loop
|
||||
)
|
||||
|
||||
Setting ``delay_min_lag == delay_max_lag`` gives a fixed, deterministic delay.
|
||||
Leave both at ``0`` (default) to disable delay entirely.
|
||||
|
||||
Passing the config to an Entity
|
||||
--------------------------------
|
||||
|
||||
Pass the config to the ``actuator_cfgs`` argument of an mjlab ``Entity``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import mjlab
|
||||
|
||||
actuator_cfg = BamActuatorCfg(
|
||||
motor_name="{actuator}",
|
||||
model="m6",
|
||||
target_names_expr=(r".*",),
|
||||
kp_fw=125,
|
||||
vin_range=(7.0, 8.0),
|
||||
vin_drop_resistance_range=(0.05, 0.15), # [Ohm]
|
||||
vin_min=6.0,
|
||||
delay_min_lag=1,
|
||||
delay_max_lag=3,
|
||||
)
|
||||
|
||||
entity = mjlab.Entity(
|
||||
xml_path="robot.xml",
|
||||
actuator_cfgs=(actuator_cfg,),
|
||||
)
|
||||
|
||||
mjlab calls :meth:`~bam.mjlab.BamActuatorCfg.build` internally to create the
|
||||
:class:`~bam.mjlab.BamActuator` and wire it into the simulation graph.
|
||||
|
||||
API reference
|
||||
-------------
|
||||
|
||||
- :class:`bam.mjlab.BamActuatorCfg`
|
||||
- :class:`bam.mjlab.BamActuator`
|
||||
- :func:`bam.model.load_model`
|
||||
@@ -0,0 +1,218 @@
|
||||
MuJoCo (CPU)
|
||||
============
|
||||
|
||||
This page explains how to plug BAM friction models into a standard MuJoCo
|
||||
simulation running on CPU. The entry point is :class:`bam.mujoco.MujocoController`.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
BAM is available on PyPI. Install it with the ``mujoco`` extra to pull in the
|
||||
MuJoCo dependency:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
pip install better-actuator-models[mujoco]
|
||||
|
||||
Or, with `uv <https://docs.astral.sh/uv/>`_:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
uv add "better-actuator-models[mujoco]"
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
At each simulation step, :class:`~bam.mujoco.MujocoController` does three things:
|
||||
|
||||
1. Optionally lowers the supply voltage by a drop proportional to the previous
|
||||
step's load, to model battery + cable resistance.
|
||||
2. Computes the motor torque from a firmware-like P-controller — optionally
|
||||
clipping it to the firmware current limit — and applies it via
|
||||
``mj_data.ctrl``.
|
||||
3. Evaluates the BAM friction model and writes the result into
|
||||
``mj_model.dof_frictionloss`` and ``mj_model.dof_damping``.
|
||||
|
||||
Loading a model
|
||||
---------------
|
||||
|
||||
Use :func:`bam.model.load_model` to obtain a :class:`~bam.model.Model` object.
|
||||
Two approaches are available.
|
||||
|
||||
**Bundled motor** — the library ships identified parameters for a set of common
|
||||
servos:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from bam.model import load_model
|
||||
|
||||
model = load_model(motor_name="{actuator}", model="m6")
|
||||
|
||||
- Supported motor names: see the :doc:`list of identified actuators <actuators>`.
|
||||
- Supported model variants: ``"m1"`` through ``"m6"`` (see :doc:`../theory/models`).
|
||||
|
||||
**Custom JSON** — parameters produced by your own identification run:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
model = load_model("path/to/params.json")
|
||||
|
||||
XML setup
|
||||
---------
|
||||
|
||||
Each actuator must be declared as a ``motor`` in the MJCF file (not
|
||||
``position`` or ``velocity``). BAM overwrites ``frictionloss``, ``damping``,
|
||||
and ``armature`` at runtime, so any value set in the XML will be ignored.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<actuator>
|
||||
<motor name="joint_1" joint="joint_1" gear="1"/>
|
||||
...
|
||||
<motor name="joint_n" joint="joint_n" gear="1"/>
|
||||
</actuator>
|
||||
|
||||
|
||||
Instantiating the controller
|
||||
-----------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import mujoco
|
||||
from bam.mujoco import MujocoController
|
||||
|
||||
mj_model = mujoco.MjModel.from_xml_file("robot.xml")
|
||||
mj_data = mujoco.MjData(mj_model)
|
||||
|
||||
controller = MujocoController(
|
||||
model=model,
|
||||
actuator=["joint_1", ..., "joint_n"], # must match the motor name in the XML
|
||||
mujoco_model=mj_model,
|
||||
mujoco_data=mj_data,
|
||||
)
|
||||
|
||||
The ``actuator`` argument can take a single string or a list of strings, which
|
||||
allows the same motor model to drive multiple joints. Each string must
|
||||
match the ``name`` attribute of the ``<motor>``.
|
||||
|
||||
Simulation loop
|
||||
---------------
|
||||
|
||||
Inside the loop, call :meth:`~bam.mujoco.MujocoController.set_q_target` to
|
||||
provide the desired joint angle, then :meth:`~bam.mujoco.MujocoController.update`
|
||||
before every ``mj_step``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
mujoco.mj_resetData(mj_model, mj_data)
|
||||
|
||||
joint_names = ["joint_1", ..., "joint_n"]
|
||||
target_angles = [...]
|
||||
|
||||
while True:
|
||||
for joint_name, target_angle in zip(joint_names, target_angles):
|
||||
controller.set_q_target(joint_name, target_angle)
|
||||
controller.update()
|
||||
mujoco.mj_step(mj_model, mj_data)
|
||||
|
||||
Voltage drop (optional)
|
||||
-----------------------
|
||||
|
||||
Real batteries and cables have an internal resistance that causes a voltage
|
||||
drop under load. BAM models this as an equivalent resistor placed between the
|
||||
battery and the motors:
|
||||
|
||||
.. math::
|
||||
|
||||
V_\text{eff} = V_\text{in} - R_\text{drop} \, I,
|
||||
\qquad
|
||||
I = \frac{1}{K_t} \sum_i |\tau_i|
|
||||
|
||||
where ``vin_drop_resistance`` is :math:`R_\text{drop}` (the combined battery +
|
||||
wire resistance, in ohms), and the current :math:`I` is estimated from the
|
||||
actuator torques using the torque constant :math:`K_t`, summed over all
|
||||
controlled joints. A hard lower bound ``vin_min`` can be set to prevent the
|
||||
effective voltage from collapsing under heavy load:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
controller = MujocoController(
|
||||
model=model,
|
||||
actuator=["joint_1", ..., "joint_n"],
|
||||
mujoco_model=mj_model,
|
||||
mujoco_data=mj_data,
|
||||
vin_drop_resistance=0.1, # 100 mOhms of wire & battery resistance
|
||||
vin_min=6.0, # [V]
|
||||
)
|
||||
|
||||
.. warning::
|
||||
|
||||
The voltage drop is computed independently by each
|
||||
:class:`~bam.mujoco.MujocoController` from its own joints' current draw.
|
||||
If several controllers share the same physical battery, their currents are
|
||||
**not** summed together, so the modeled drop underestimates the real one.
|
||||
Group all joints powered by the same battery under a single controller if you
|
||||
need the shared-supply behavior.
|
||||
|
||||
Multi-actuator config file
|
||||
--------------------------
|
||||
|
||||
For robots with many joints, :func:`bam.mujoco.load_config` loads a JSON
|
||||
configuration file that maps each group of joints to a model:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from bam.mujoco import load_config
|
||||
|
||||
controllers, dof_to_controller = load_config(
|
||||
path="config.json",
|
||||
mujoco_model=mj_model,
|
||||
mujoco_data=mj_data,
|
||||
kp=125.0,
|
||||
vin=7.5,
|
||||
)
|
||||
|
||||
The config file has the following structure:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"arm": {
|
||||
"dofs": ["shoulder", "elbow"],
|
||||
"model": {
|
||||
"kt": 1.6224667906987444,
|
||||
"R": 3.949433673232461,
|
||||
"armature": 0.011951238325312509,
|
||||
"friction_base": 0.09038677246291783,
|
||||
"friction_viscous": 0.011691602145974832,
|
||||
"model": "m1",
|
||||
"actuator": "mx64"
|
||||
},
|
||||
"error_gain": 1.0,
|
||||
"max_pwm": 885
|
||||
},
|
||||
"leg": {
|
||||
"dofs": ["hip", "knee", "ankle"],
|
||||
"model": {
|
||||
"kt": 2.1913757006745245,
|
||||
"R": 2.9649903987776804,
|
||||
"armature": 0.026609234235148084,
|
||||
"friction_base": 0.10352026623606064,
|
||||
"friction_viscous": 0.03520238029013507,
|
||||
"model": "m1",
|
||||
"actuator": "mx106"
|
||||
},
|
||||
"error_gain": 1.0,
|
||||
"max_pwm": 885
|
||||
}
|
||||
}
|
||||
|
||||
``controllers`` is a dict keyed by group name; ``dof_to_controller`` maps each
|
||||
DOF name back to its group.
|
||||
|
||||
API reference
|
||||
-------------
|
||||
|
||||
- :class:`bam.mujoco.MujocoController`
|
||||
- :func:`bam.mujoco.load_config`
|
||||
- :func:`bam.model.load_model`
|
||||
Reference in New Issue
Block a user