Can Linear Acceleration stream faster than 25hz in IMU_Plus mode?

edited October 30 in General

Board Information

Hardware version [0.3]
Firmware version [1.4.5]
Model number [5]

Host Device information

Device Model [Raspberry Pi 3 B+]
OS Version [Raspbian GNU/Linux 9 (stretch) ]

Description

I would like to stream Linear Acceleration at 100hz, however, I am constantly getting ~ 25Hz or less.
I am using IMU_Plus as my fusion mode. My raw results, and code is listed below

Streaming Raw Acceleration Data has no problem with sending data at 100Hz.

Thank you kindly,

  • John

Code

from mbientlab.metawear import MetaWear, libmetawear, parse_value
from mbientlab.metawear.cbindings import SensorFusionData, SensorFusionMode, FnVoid_VoidP_DataP
from mbientlab.warble import WarbleException
from threading import Event
import sys
from time import time, sleep, localtime
import os

def timeString():
    result = localtime()
    year = str(result.tm_year)
    month = str(result.tm_mon)
    day = str(result.tm_mday)
    hour = str(result.tm_hour)
    min = str(result.tm_min)
    sec = str(result.tm_sec)
    if int(sec) < 10:
        sec = "0" + str(sec)
    if int(min) < 10:
        min = "0" + str(min)
    if int(hour) < 10:
        hour = "0" + str(hour)
    if int(day) < 10:
        day = "0" + str(day)
    if int(month) < 10:
        month = "0" + str(month)
    time_string = (year + ("_") + month + ("_") + day + '-' + hour + ("_") + min + ("_") + sec)
    return time_string

def create_lin_acc_file():
    ### Create Folder + File for collected data
    path = "./CollectedData/Run_" + timeString()
    access_rights = 0o755
    try:
        os.mkdir(path, access_rights)
    except OSError:
        print("Failed to make %s Directory" % path)
    else:
        print("Successfully created the directory %s " % path)
    file_name_root = path
    file_name_end = str(time()) + ".txt"
    linear_acc_file_name = file_name_root + "/Linear_Acc" + file_name_end
    linear_acc_file = open(linear_acc_file_name, 'a')
    return linear_acc_file

def handle_Linear_Acc(ctx, data):

    linear_acc = parse_value(data)
    time = data.contents.epoch
    xval = linear_acc.x
    yval = linear_acc.y
    zval = linear_acc.z
    #write_string = str(("%d, %d, %d, %d\n" % (time(), xval, yval, zval)))
    write_string = str(str(time()) + ", " + repr(xval) + ", " + repr(yval) + ", " + repr(zval) + '\n')
    linear_acc_file.write(write_string)

    #print(data)
    print("Linear ACC Data : " + write_string)

count = 0
e = Event()

imu_id = 1
addr = 'FA:19:05:96:8B:E4'

if len(sys.argv) > 1:
    addr = "FA:19:05:96:8B:E4"
    imu_id = 2
print(addr)



start_time = None

# Set what type of data we want to collect from the fuser
linear_acc_data_source = SensorFusionData.LINEAR_ACC

max_connect_attempts = 5
linear_acc_file = None


try:
    device = MetaWear(addr)
    device.connect()
    libmetawear.mbl_mw_settings_set_connection_parameters(device.board, 7.5, 7.5, 0, 6000)
    sleep(1.5)
    linear_acc_file = create_lin_acc_file()

except WarbleException as err:
    print('reattempting after warble exception: {}'.format(err))
    exit(1)

try:

    # Set the type of fusion
    libmetawear.mbl_mw_sensor_fusion_clear_enabled_mask(device.board)
    libmetawear.mbl_mw_sensor_fusion_set_mode(device.board, SensorFusionMode.IMU_PLUS)
    libmetawear.mbl_mw_sensor_fusion_write_config(device.board)

    # Set up our Linear ACC and Quaternion processors
    linear_acc_processor = libmetawear.mbl_mw_sensor_fusion_get_data_signal(device.board, linear_acc_data_source)

    # Set up our handlers for our data
    wrapped_handler_linear_acc = FnVoid_VoidP_DataP(handle_Linear_Acc)

    # Subscribe to our data channels
    libmetawear.mbl_mw_datasignal_subscribe(linear_acc_processor, None, wrapped_handler_linear_acc)


    # Enable our data sources
    libmetawear.mbl_mw_sensor_fusion_enable_data(device.board, linear_acc_data_source)


    libmetawear.mbl_mw_sensor_fusion_start(device.board)

    #e.wait()
    # record data for 60 seconds
    sleep(60)

except RuntimeError as err:
    print(err)

finally:
    libmetawear.mbl_mw_sensor_fusion_stop(device.board)
    libmetawear.mbl_mw_sensor_fusion_clear_enabled_mask(device.board)
    libmetawear.mbl_mw_datasignal_unsubscribe(linear_acc_processor)
    libmetawear.mbl_mw_debug_disconnect(device.board)

Raw Results ( snippet)

Comments

  • edited October 30

    It is 100Hz if you have nothing else streaming at the same time. Can you confirm this?

    Also the default = 100Hz for Sensor fusion, so you should be naturally getting this.

    Can you check your BLE? Are you using a dongle?

    Can you please run our example scripts for sensor fusion and see if you get closer to 100Hz (don't run your code, run ours instead):
    1. Use this as the base: https://github.com/mbientlab/MetaWear-SDK-Python/blob/master/examples/stream_acc.py
    2. And replace the signal with a sensor fusion signal: https://github.com/mbientlab/MetaWear-SDK-Cpp/blob/master/test/test_sensor_fusion.py

  • edited October 31

    Hi Laura,

    Thank you for your time.

    It is 100Hz if you have nothing else streaming at the same time. Can you confirm this?

    • I am not currently subscribed to anything else

    Can you check your BLE? Are you using a dongle?

    • No, I am using the onboard radio of the RPi 3B+

    Can you please run our example scripts for sensor fusion and see if you get closer to 100Hz (don't run your code, run ours instead):
    1. Use this as the base: https://github.com/mbientlab/MetaWear-SDK-Python/blob/master/examples/stream_acc.py
    2. And replace the signal with a sensor fusion signal: https://github.com/mbientlab/MetaWear-SDK-Cpp/blob/master/test/test_sensor_fusion.py

    Of course, thank you for the suggestion.

    Running the following script - https://github.com/mbientlab/MetaWear-SDK-Python/blob/master/examples/stream_acc.py
    I am reliably getting ~1230 signals per 30 seconds (41 Hz)

    When I replace the signal portion of the code with the configuration available here - https://github.com/mbientlab/MetaWear-SDK-Cpp/blob/master/test/test_sensor_fusion.py
    I am fairly consistently receiving ~ 760 signals per 30 seconds (22 Hz)

    These results are persistent through reboot of my Linux device(Raspberry Pi 3B+)

    Here are two screenshots of the data, as well as the fusion signal code (created using the above links). I am curious if I am perhaps incorrectly implementing the sensor fusion configuration or callback function.

    Thank you kindly
    - John

    Raw Accel

    Linear Accel / Sensor Fusion, IMU_Plus Mode

    Code

    class State:
        def __init__(self, device):
            self.device = device
            self.samples = 0
            self.callback = FnVoid_VoidP_DataP(self.data_handler)
    
        def data_handler(self, ctx, data):
            print("%s -> %s" % (self.device.address, parse_value(data)))
            self.samples+= 1
    
    states = []
    for i in range(len(sys.argv) - 1):
        d = MetaWear(sys.argv[i + 1])
        d.connect()
        print("Connected to " + d.address)
        states.append(State(d))
    
    for s in states:
        print("Configuring device")
        libmetawear.mbl_mw_settings_set_connection_parameters(s.device.board, 7.5, 7.5, 0, 6000)
        sleep(1.5)
    
        libmetawear.mbl_mw_sensor_fusion_clear_enabled_mask(s.device.board)
        signal = libmetawear.mbl_mw_sensor_fusion_get_data_signal(s.device.board, SensorFusionData.LINEAR_ACC)
        libmetawear.mbl_mw_datasignal_subscribe(signal, None, s.callback)
    
        libmetawear.mbl_mw_sensor_fusion_set_mode(s.device.board, SensorFusionMode.IMU_PLUS)
        libmetawear.mbl_mw_sensor_fusion_enable_data(s.device.board, SensorFusionData.LINEAR_ACC)
        libmetawear.mbl_mw_sensor_fusion_start(s.device.board)
    
    sleep(30.0)
    
    for s in states:
        libmetawear.mbl_mw_sensor_fusion_stop(s.device.board)
    
        signal = libmetawear.mbl_mw_sensor_fusion_get_data_signal(s.device.board, SensorFusionData.LINEAR_ACC)
        libmetawear.mbl_mw_datasignal_unsubscribe(signal)
        libmetawear.mbl_mw_debug_disconnect(s.device.board)
    
    print("Total Samples Received")
    for s in states:
        print("%s -> %d" % (s.device.address, s.samples))
    
    
  • Oh Dear.

    I reset the board using libmetawear.mbl_mw_debug_reset(s.device.board).

    Now, the linear accel data is reading much faster (100Hz!), however, all of the readings are zero. I will have to go back and ensure I am enabling the sensor fusion correctly.

    Thank you for your assistance Laura.

  • edited October 31

    Great news @JMoody.
    Perhaps the sensor was doing other things internally that were eating up bandwidth?
    Glad it worked out :)

Sign In or Register to comment.