opensourceleg icon indicating copy to clipboard operation
opensourceleg copied to clipboard

Load cell updates are really slow

Open tkevinbest opened this issue 1 month ago • 0 comments

🐛 Bug Report

Updating from the load cell takes almost 1 ms, which is way too slow. The culprit is the median filter currently in the library. Do we still need this median filter? Is there a more efficient way for us to do error checking? Likely there is.

With median filter:

        avg error: -0.031 milliseconds
        stddev error: 0.050 milliseconds
        percent of time sleeping: 62.8 %
StatProfiler LoadCell: 767 reps, avg: 0.9798425428248756 ms, stddev: 0.16581745437827136 ms, total: 0.7515392303466797 s

Without median filter:

In 565 cycles at 200.00 Hz:
        avg error: 0.009 milliseconds
        stddev error: 0.041 milliseconds
        percent of time sleeping: 75.2 %
StatProfiler LoadCell: 566 reps, avg: 0.5603620104570692 ms, stddev: 0.0667480241175177 ms, total: 0.31716489791870117 s

🔬 How To Reproduce

You can reproduce my test results with the following code:

import numpy as np
from opensourceleg.osl import OpenSourceLeg
import sys
from NeuroLocoMiddleware.StatProfiler import SSProfile
sys.path.append(r'/usr/share/python3-mscl/') 
USER_MASS = 70 # kg
MODE = 1 # Mode for ambulation mode switching. 0) Automatic. 1) Walk Only. 2) Sit/stand only. 
LOADCELL_MATRIX = np.array(
    [
        (-38.72600, -1817.74700, 9.84900, 43.37400, -44.54000, 1824.67000),
        (-8.61600, 1041.14900, 18.86100, -2098.82200, 31.79400, 1058.6230),
        (-1047.16800, 8.63900, -1047.28200, -20.70000, -1073.08800, -8.92300),
        (20.57600, -0.04000, -0.24600, 0.55400, -21.40800, -0.47600),
        (-12.13400, -1.10800, 24.36100, 0.02300, -12.14100, 0.79200),
        (-0.65100, -28.28700, 0.02200, -25.23000, 0.47300, -27.3070),
    ]
)


LOOP_FREQUENCY = 200 # Hz
osl = OpenSourceLeg(frequency=LOOP_FREQUENCY)
osl.clock.report = True

osl.add_joint("knee", gear_ratio=9 * 83 / 18, offline_mode=False)
osl.add_joint("ankle", gear_ratio=9 * 83 / 18, offline_mode=False)
osl.add_loadcell(joint=osl.knee, loadcell_matrix=LOADCELL_MATRIX)

@SSProfile("LoadCell").decorate
def update_loadcell():
    # return osl._loadcell._lc._SMBus.read_i2c_block_data(0x66, 8, 10)
    # return osl._loadcell._lc._read_compressed_strain()
    return osl._loadcell._lc.update()

for t in osl.clock:
    print(update_loadcell())

Code sample

Environment

  • OS: [e.g. Linux / Windows / macOS]
  • Python version, get it with:
python --version

tkevinbest avatar May 15 '24 20:05 tkevinbest