Skip to content

Add Unitree J288 actuator - #21

Open
lachlanhurst wants to merge 4 commits into
Rhoban:mainfrom
lachlanhurst:unitree-j288
Open

lachlanhurst wants to merge 4 commits into
Rhoban:mainfrom
lachlanhurst:unitree-j288

Conversation

@lachlanhurst

Copy link
Copy Markdown

The Unitree docs for this servo can be found here for some background.

The J288Actuator has been implemented as a DCMotorActuator reasoning for this was due to its use of a hybrid control mode. In each command it accepts a feedforward torque, target position, target velocity, kp, and kd. These are then used to calculate an output torque, so thecontrol_unit is Nm. The current/voltage control actuators didn't seem to fit this.

Test details

I tested with two arms; 75mm (15g) and 150mm (17g). Weights were made up of large washers.
Test arm setup

Runs

Arm Total weight Position gains (kp / kd) Purpose
75 mm 70 g 0.97 / 0.02, 0.97 / 0.05, 2.01 / 0.02, 2.01 / 0.05 Training
75 mm 246 g 0.97 / 0.02, 0.97 / 0.05, 2.01 / 0.02, 2.01 / 0.05 Training
75 mm 415 g 0.97 / 0.02, 4.03 / 0.05 Validation (not fitted)
75 mm 586 g 0.97 / 0.02, 0.97 / 0.05, 2.01 / 0.02, 2.01 / 0.05 Training
150 mm 108 g 0.97 / 0.02, 0.97 / 0.05, 2.01 / 0.02, 2.01 / 0.05 Training
150 mm 333 g 0.97 / 0.02, 0.97 / 0.05, 2.01 / 0.02, 2.01 / 0.05 Training
150 mm 417 g 0.97 / 0.02, 2.01 / 0.05 Training
  • Position gains were applied to the four BAM trajectories: sin_time_square, sin_sin, lift_and_drop and up_and_down.
  • Torque runs used kp = kd = 0. The speed runs use kp = 0, and the damping runs lift at kp 2.01 and then switch to kp = 0.
  • All runs were on 6S (24.0 to 24.5 V)
  • 100+ training recordings can be found here.

Fit results

For the validation run (75mm, 415g)
image
image
image
image

J288 specific code

Happy to rework any of this. The following points call out some of the changes which I think would raise the most questions. There's some bits of code (eg; helpers in the J288Actuator _round_to, _where, _both) that may be better off elsewhere but I was aiming for a light touch on the existing code.

unitree/actuator.py, J288Pendulum: honestly this was Claude's idea, but I get it. BAM's Pendulum treats the end mass as a point, but a real mass also has inertia about its own centre. My short arm was 75 mm long with a mass about 55 mm in diameter, which adds roughly 7% to the point-mass inertia. J288Pendulum adds this from an optional mass_inertia field in the log. Nothing about it is specific to this servo, so it could be folded into Pendulum if you'd prefer.

unitree/calibrate.py: the servo has no way of setting its zero, but its output encoder is absolute and keeps its position across power cycles. This little app steps you through a rough "hanging down" reading, then the arm horizontal on each side, checked with a level (e.g. a spirit level or phone inclinometer). It checks the two horizontals are 180deg apart and saves the zero offset to a JSON file. record.py reads that file (--zero-file) at the start of every recording, so it only needs doing once per arm.

unitree/digital_servo.py: the comms module for the servo. The Unitree S288 uses the same protocol, so this should work with it too (untested).

unitree/fit_control.py: adds a stage before the usual fit. The servo reports a motor torque (worked out from current) in every reply. Stage 1 fits the firmware and motor parameters (speed_filter_tau, torque_limit, R) directly to that reported torque and speed, with no simulation. Stage 2 is the existing BAM position fit with those parameters held fixed. I think these torque values could be useful as observations in an RL policy later on, so I wanted the BAM model to reproduce them accurately. There's also an eval command that scores a parameter file on both position and reported-torque error.

unitree/mjlab.py: a J288 version of BamActuator. It passes mjlab's velocity and effort targets through to the firmware, lets kp and kd be set per environment, joint and step, and exposes reported_torque and reported_speed. J288Simulator replays J288 logs on mjlab to check a fit at a training timestep.

Thankyou!

includes calibration tool, new actuator class, servo comms protocol, record tools, and a fit + mjlab implementation to cover some of the J288 specifics
pyserial is a dependency of dynamixel_sdk already included, so this would work without this addition. However the Unitree digital servo module does use pyserial direct.
Includes link to raw data used in fit process to generate m1-m6 params

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant