Data Acquisition#
Recording consists of running the actuator through a set of predefined trajectories while logging position, velocity, and control signals at the firmware’s native rate. The result is a collection of JSON files that are then resampled to a fixed timestep before fitting.
Installation#
First, you need to clone the BAM repository.
Then, you can install the extra dependencies for the identification pipeline using
uv (installation instructions):
uv sync --extra identification
Available trajectories#
Each trajectory runs for 6 seconds. The choice of trajectory affects which friction regimes are excited; using several is recommended.
Name |
Description |
|---|---|
|
\(\sin(t^2)\) profile — progressively faster oscillations, good general-purpose trajectory that covers a wide velocity range. |
|
Cubic move to −π/2 over 2 s, then torque disabled — the arm falls under gravity. Particularly useful for identifying backdrivability and Stribeck effects at very low speed. |
|
Cubic path 0 → π/2 → 0.8·π/2 — slower motion, emphasizes static friction and load-dependent effects. |
|
\(\sin(t)\cdot\pi/2 + \sin(5t)\cdot 0.5\cdot\sin(2t)\) — rich multi-frequency content. |
|
Zero torque command for the full duration — pure gravity response, useful to isolate backdrivability. |
Recording scripts#
Dynamixel (MX-64, MX-106, XL-320, XL-330)#
uv run python -m bam.dynamixel.record \
--port /dev/ttyUSB0 \
--motor xl330 \
--mass 0.567 \
--arm-mass 0.016 \
--length 0.17 \
--kp 400 \
--vin 7.5 \
--trajectory sin_time_square \
--logdir data_raw
--port defaults to /dev/ttyUSB0. --kp and --vin should match
the values actually programmed in the firmware.
eRob (erob80_50, erob80_100)#
eRob actuators are driven through an EtherBan server, which must be running
before recording. The communication relies on generated protobuf bindings,
so first compile the .proto files:
cd bam/erob/
bash generate_protobuf.sh
You can then monitor the connected devices, which also reports the angular offset to use for the zero position:
uv run python -m bam.erob.etherban
Pass that value to --offset when recording:
uv run python -m bam.erob.record \
--host 127.0.0.1 \
--motor erob80_100 \
--mass 1.2 \
--arm_mass 0.05 \
--length 0.25 \
--offset 0.0 \
--kp 10.0 \
--damping 2.0 \
--trajectory sin_time_square \
--logdir data_raw
--offset is the angular offset of the zero position in radians, used to
compensate for mounting imprecision.
Feetech (STS3215)#
uv run python -m bam.feetech.record \
--port /dev/ttyUSB0 \
--id 1 \
--motor sts3215 \
--mass 0.3 \
--length 0.12 \
--kp 32 \
--vin 7.4 \
--trajectory sin_time_square \
--logdir data_raw
Batch recording#
To sweep multiple P-gain values and trajectories in one go:
uv run python -m bam.dynamixel.all_record \
--port /dev/ttyUSB0 \
--motor xl330 \
--mass 0.567 \
--arm-mass 0.016 \
--length 0.17 \
--logdir data_raw
This produces several files per combination and is the recommended starting point for a complete identification run.
Recording strategy#
Vary the P-gain across several values (e.g. 8, 16, 32 for Dynamixel). A higher gain increases the motor torque during tracking errors, exciting stronger load-dependent friction. One of these gain values should be set aside as a validation set (see Fitting); the others form the training set.
Record at least two or three different trajectories to cover a broad range
of velocities and load conditions. The lift_and_drop trajectory is
especially informative for identifying Stribeck and backdrive behavior, and
should always be included.
Raw data format#
Each recording produces one JSON file:
{
"mass": 0.567,
"arm_mass": 0.016,
"length": 0.17,
"kp": 400,
"vin": 7.5,
"motor": "xl330",
"trajectory": "sin_time_square",
"entries": [
{
"timestamp": 0.0077,
"position": 0.0015,
"speed": 0.024,
"load": 0.0,
"input_volts": 7.5,
"goal_position": 0.0,
"torque_enable": true
}
]
}
Entries are logged at the firmware’s native rate, which is not necessarily constant. The processing step resamples them to a fixed timestep.
Processing#
Resample raw logs to a constant timestep before fitting:
uv run python -m bam.process \
--raw data_raw \
--logdir data_processed \
--dt 0.005
--dt is the target timestep in seconds (5 ms is a good default). The
script linearly interpolates between consecutive entries and writes one
processed JSON per raw file into data_processed/.