Fz loadcell spikes and calibration issue

Hi all,

I’m a graduate student using the OSL v2 with the Dephy loadcell amplifier for a prosthetic leg control project. I’m the 4-state FSM impedance controller for walking (e_stance → l_stance → e_swing → l_swing) and I’m having issues with the Fz signal quality.

Setup

  • OSL v2, Dephy loadcell amplifier (I2C, address 0x66)

  • dephy_mode=False

  • Calibration matrix provided by Humotech (6×6)

  • Controller running at 200 Hz

  • Subject body weight: 77 kg (755 N)

The matrix I’m using (provided by Humotech):

LOADCELL_MATRIX = np.array([ ( 10.20795, -1901.89602, 16.85019, 9.67683, -12.77685, 1906.68221), (-31.13847, 1116.35626, 0.84145, -2169.94287, 28.12897, 1087.04464), (-978.61535, -18.14306, -972.91833, -0.27002, -978.56302, 4.66927), ( 20.75524, -0.15063, 0.74038, 0.73137, -19.65852, -0.52249), (-11.77535, -0.93868, 22.96369, -0.08801, -11.74901, 0.83425), ( -0.20234, -27.56313, -0.27517, -24.07953, 0.03453, -26.39461), ])

Problem 1 — Fz spikes during walking

During a walking trial (848 samples, ~4.2 s, 200 Hz), I observe isolated but extreme spikes in osl.loadcell.fz:

  • Expected range during stance: roughly −400 to −800 N (body weight fraction)

  • Observed spikes: down to −5933 N at isolated samples (< 1% of data)

  • During swing (foot in air): mean ≈ −123 N, std ≈ 288 N — should be near 0 N

The spikes appear to be single-sample glitches, not sustained. After removing them (thresholding

  • interpolation) and applying a low-pass filter (Butterworth 4th order, 8 Hz), the signal looks qualitatively reasonable but the absolute scale is wrong (see Problem 2).

Question: Are these spikes a known issue with the Dephy amplifier? Could they be caused by I2C read errors, ADC saturation, or vibration artifacts? Is there any built-in spike rejection in newer versions of the OSL loadcell driver?

Problem 2 — Fz scale does not match body weight

After spike removal, the Fz values during late stance are far too small:

Phase Expected Fz (N) Observed Fz mean (N)
l_stance ~ −600 to −800 ~ −160
swing ~ 0 ~ −83

The ratio is roughly 0.2× of the expected body weight. This suggests the calibration matrix does not match my physical sensor.

I suspect the matrix provided by Humotech was calibrated on a specific sensor unit and may not be valid for my unit.

Questions:

  1. Is the Humotech matrix a generic/default matrix, or is it unit-specific?

  2. What is the correct procedure to recalibrate the Fz channel for a specific sensor unit?

  3. The calibrate() method in DephyLoadcellAmplifier performs zeroing (offset subtraction) but does not update the calibration matrix coefficients. Is there a recommended workflow for full matrix recalibration?

What I’ve tried

  • Zeroing the sensor before each trial (offset subtraction via calibrate())

  • Spike removal with threshold [−1500, +200] N + linear interpolation

  • Butterworth low-pass filter (4 Hz, 8 Hz, 10 Hz) — does not recover the correct scale

  • Subtracting the swing-phase mean as offset — Fz in stance still only ~−80 N after correction

Any guidance on whether the Humotech matrix is unit-specific, and how to perform a proper Fz recalibration, would be greatly appreciated.

Thanks

Minimal reproducible code

import numpy as np from opensourceleg.osl import OpenSourceLeg

LOADCELL_MATRIX = np.array([…]) # as above

osl = OpenSourceLeg(frequency=200) osl.add_joint(name=“knee”, gear_ratio=41.4999, port=“/dev/ttyACM0”) osl.add_joint(name=“ankle”, gear_ratio=41.4999, port=“/dev/ttyACM1”) osl.add_loadcell(dephy_mode=False, offline_mode=False, loadcell_matrix=LOADCELL_MATRIX)

with osl: osl.home() for t in osl.clock: osl.update() print(f"Fz: {osl.loadcell.fz:.2f} N", end=“\r”)