Signals for dynamic parameter identification

Hi everyone,

I’m opening a new thread to better explain my use case and ask for guidance on dynamic parameter identification with the OpenSourceLeg 2.0 (knee + ankle, Dephy Actpack).

Context

My final goal is offline inverse-dynamics / least-squares identification of the leg dynamics. For this reason, I need to reliably acquire:

  • joint position qqq

  • joint velocity q˙\dot{q}q˙​

  • joint acceleration q¨\ddot{q}q¨​ (offline estimation is fine)

  • joint torque τ\tauτ

I’m currently using position control only (no impedance / current control), with excitation trajectories designed to be LS-friendly (multisine, chirp, decoupled motions, etc.).

One source of confusion for me is that some of the scripts I started from were shown to us directly during a lab demo of the OpenSourceLeg 2.0 (by Humotech), while the repository examples sometimes use slightly different APIs or signal names. So I’m not fully confident about which signals are measured, which are estimated, and which are recommended for identification. Below is a minimal version of the acquisition code, stripped down to only the essential control commands and logged signals.

My doubts are mainly about signal meaning and best practices:

  1. Joint torque

    • What exactly is joint_torque?

    • Is it:

      • computed from motor current?

      • model-based?

      • filtered / estimated internally?

    • Is this the recommended torque signal for inverse dynamics identification?

  2. Gear ratio

    • Why is the gear ratio explicitly specified when adding a joint?

    • Does it affect:

      • output_position?

      • output_velocity?

      • joint_torque?

    • In other words: are these quantities already expressed at the joint side, or partially motor-side?

  3. Joint velocity

    • What is output_velocity exactly?

      • encoder-based differentiation?

      • observer?

      • filtered signal?

    • For identification purposes, is it better to use this signal, or to numerically differentiate output_position offline?

  4. Acceleration

    • Is the standard approach to estimate q¨\ddot{q}q¨​ offline (e.g. Savitzky–Golay on velocity), or is there any internal signal that should be preferred?

Any advice, clarification, or reference to recommended practices for system identification with OSL + Dephy Actpack would be extremely valuable for me.

Thanks very much in advance for your time and help — any suggestion is genuinely useful.

import time import numpy as np from opensourceleg.osl import OpenSourceLeg from opensourceleg.tools import units

frequency = 200 # Hz run_seconds = 40.0

Simple excitation trajectories

def knee_traj(t): return 40.0 * np.sin(1.2 * t) + 40.0 # deg

def ankle_traj(t): return 20.0 * np.sin(1.0 * t) # deg

-------------------- OSL INIT --------------------

osl = OpenSourceLeg(frequency=frequency) osl.add_joint(“knee”, gear_ratio=9 * 83 / 18, port=“/dev/ttyACM0”) osl.add_joint(“ankle”, gear_ratio=9 * 83 / 18, port=“/dev/ttyACM1”)

t_log = qk_log = ; qa_log = qkp_log = ; qap_log = tau_k_log = ; tau_a_log = ik_log = ; ia_log =

with osl: osl.home() input(“Homing complete. Press ENTER to start.”)

osl.knee.set_mode(osl.knee.control_modes.position)
osl.ankle.set_mode(osl.ankle.control_modes.position)

osl.knee.set_position_gains(kp=10)
osl.ankle.set_position_gains(kp=10)

# Warm-up
for _ in range(20):
    osl.update()
    time.sleep(0.01)

t0 = time.time()

for t in osl.clock:
    if time.time() - t0 > run_seconds:
        break

    osl.update()

    # Commanded positions
    qk_cmd = units.convert_to_default(knee_traj(t),  units.position.deg)
    qa_cmd = units.convert_to_default(ankle_traj(t), units.position.deg)

    osl.knee.set_output_position(qk_cmd)
    osl.ankle.set_output_position(qa_cmd)

    # ---------------- Measurements ----------------
    qk  = float(osl.knee.output_position)
    qa  = float(osl.ankle.output_position)

    qkp = float(getattr(osl.knee,  "output_velocity", np.nan))
    qap = float(getattr(osl.ankle, "output_velocity", np.nan))

    tau_k = float(getattr(osl.knee,  "joint_torque", np.nan))
    tau_a = float(getattr(osl.ankle, "joint_torque", np.nan))

    ik = float(getattr(osl.knee,  "motor_current", np.nan))
    ia = float(getattr(osl.ankle, "motor_current", np.nan))

    # Log
    t_log.append(t)
    qk_log.append(qk);   qa_log.append(qa)
    qkp_log.append(qkp); qap_log.append(qap)
    tau_k_log.append(tau_k); tau_a_log.append(tau_a)
    ik_log.append(ik); ia_log.append(ia)

Hi @mioki,

The best way to start would be the documentation: opensourceleg. Looking at the source code can also be a great help.

The joint_torque is computed from the current: opensourceleg/opensourceleg/actuators/dephy.py at main · neurobionics/opensourceleg · GitHub

The gear ratio is specified to have a generic library to allow people to modify their OSL or create other robot with the same library.

When there is output in the name of the variable is should be in the joint frame. I don’t really know which joint_torque do you speak about. However, there is the output_torque variable.

There is a 14-bit encoder inside the dephy actuator so the velocity is probably measured from it.

thank you so much for your help!