What Is the BAM Actuator Model in Microduck RL? Understanding the BAM M6 Implementation

Microduck RL uses the BAM M6 actuator model to emulate the Dynamixel XL330 servos that power the robot.

The Microduck RL repository from Pollen Robotics implements a physics-based reinforcement learning pipeline for a quadruped robot. At the heart of its simulation fidelity lies a specific actuator model that bridges the gap between idealized physics and real-world hardware behavior. This article explains the BAM M6 actuator model, its configuration, and how it integrates into the broader Microduck RL system according to the source code at pollen-robotics/microduck_rl.

What Is the BAM M6 Actuator Model?

The BAM M6 is a full-voltage-control actuator model designed to replicate the dynamics of the XL330 servo motors used on the physical Microduck robot. BAM stands for "Battery, Actuator, Motor" — a modeling framework that captures the interaction between power supply voltage sag, motor torque generation, and load-dependent friction.

According to the repository's constant definitions in src/mjlab_microduck/robot/microduck_constants.py, the M6 model is selected via the model="m6" parameter:

_BAM_ACTUATOR_KWARGS = dict(
    motor_name="xl330",
    model="m6",                     # ← the BAM M6 model

    target_names_expr=(r"^(?!passive_).*",),
    kp_fw=200.0,
    vin_range=(6.5, 8.2),
    vin_drop_gain_range=(0.0, 0.2),
    vin_min=6.0,
    delay_min_lag=3,
    delay_max_lag=6,
)

The M6 designation refers to a specific firmware-calibrated parameter set derived from real XL330 test-bench measurements, stored in params/xl330/m6_new.json.

Key Features of the BAM M6 Actuator

The BAM M6 actuator model incorporates several physical effects that distinguish it from ideal torque sources:

  • Voltage-controlled torque generation — Torque is computed from commanded voltage using a proportional gain (kp_fw=200.0) rather than direct torque commands

  • Domain-randomized supply voltage — Battery voltage varies per episode within vin_range=(6.5, 8.2) volts, with sag modeling via vin_drop_gain_range

  • Load-dependent friction randomization — Per-joint friction scales are randomized each episode through the FrictionDRBamActuatorCfg class

  • Actuator delay modeling — Response latency is simulated with delay_min_lag=3 to delay_max_lag=6 timesteps of delay

These features combine to create a sim-to-real transferable actuation model that matches the nonlinear, voltage-limited behavior of actual servo hardware.

How the BAM M6 Actuator Is Instantiated in Microduck RL

The repository provides two actuator configurations built from the same M6 parameter kernel. Both use the _BAM_ACTUATOR_KWARGS dictionary defined above.

Standard Friction-Randomized Configuration

from mjlab_microduck.robot.microduck_constants import MICRODUCK_WALK_ROBOT_CFG

# The walk robot config embeds the BAM M6 actuator

robot_cfg = MICRODUCK_WALK_ROBOT_CFG

# Start a simulation with this configuration

import mujoco
spec = robot_cfg.spec_fn()
model = spec.compile()
data = mujoco.MjData(model)

The actuators object is created as:

actuators = FrictionDRBamActuatorCfg(**_BAM_ACTUATOR_KWARGS)

Backlash-Aware Configuration

For variants that model encoder backlash, the same M6 kernel is reused:

backlash_actuators = BacklashEncoderBamActuatorCfg(**_BAM_ACTUATOR_KWARGS)

This design ensures consistent voltage-control dynamics regardless of which encoder model is active.

Validating the BAM M6 Model Against Real Hardware

The repository includes a dedicated validation script that reproduces the BAM M6 kernel logic in a standalone MuJoCo rollout. This script compares simulation predictions against recordings from physical XL330 test-bench experiments.

Run the validation with:

uv run python3 scripts/validate_bam_testbench.py --max-files 3 --plot

The script loads params/xl330/m6_new.json and exercises the identical voltage-control law, friction budget, and delay model used by the FrictionDRBamActuatorCfg class. This validation step confirms that the BAM M6 actuator accurately captures the hardware's dynamic response.

Core Files for the BAM M6 Actuator Implementation

File Purpose
src/mjlab_microduck/robot/microduck_constants.py Defines _BAM_ACTUATOR_KWARGS and instantiates actuators and backlash_actuators
src/mjlab_microduck/actuator/friction_dr_bam.py Implements FrictionDRBamActuatorCfg with per-episode friction randomization
src/mjlab_microduck/actuator/backlash_encoder_bam.py Implements BacklashEncoderBamActuatorCfg for backlash modeling
scripts/validate_bam_testbench.py Validates BAM M6 dynamics against real XL330 test-bench data
src/mjlab_microduck/tasks/mdp.py Contains randomize_joint_friction_bam() for episode-level friction sampling

Summary

  • The BAM M6 actuator model is the core actuation model in Microduck RL, representing XL330 servo dynamics
  • It uses voltage-controlled torque generation with kp_fw=200.0 and domain-randomized battery voltage
  • Two configurations exist: standard FrictionDRBamActuatorCfg and BacklashEncoderBamActuatorCfg, both sharing the same M6 parameter kernel
  • The model is validated against real hardware via scripts/validate_bam_testbench.py
  • All definitions reside in src/mjlab_microduck/robot/microduck_constants.py

Frequently Asked Questions

What does BAM stand for in the actuator model name?

BAM stands for Battery, Actuator, Motor. It describes a modeling framework that couples power supply dynamics (voltage sag), actuator control electronics, and motor physics into a unified simulation model. The M6 variant specifically refers to a parameter set calibrated for XL330 servos with firmware version M6.

How does the BAM M6 model improve sim-to-real transfer?

The BAM M6 improves sim-to-real transfer by replicating voltage-limited torque production, load-dependent friction, and battery voltage sag — effects that dominate real servo behavior but are absent from ideal torque sources. Domain randomization over vin_range, vin_drop_gain_range, and per-joint friction scales during training ensures policies remain robust to these physical variations.

Can I use the BAM M6 actuator with other motors besides the XL330?

While the model="m6" parameter is specifically calibrated for XL330 dynamics, the underlying FrictionDRBamActuatorCfg class can accept different motor parameter files. You would need to provide a compatible JSON parameter file with the same schema as params/xl330/m6_new.json and update motor_name accordingly. The voltage-control architecture remains applicable to other low-impedance servo motors.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →