Streaming Accelerometer and Gyroscope data simultaneously using fuser

edited March 2019 in iOS

Hi, I've been trying to figure our how to stream multiple signals on a single device (MetaTracker). I have spent a lot of time looking through blog posts and documentation but I've found it to be quite unclear and not very informative. I've been trying to get
So far I have:

let signalA = mbl_mw_acc_get_acceleration_data_signal(board)
let signalG = mbl_mw_gyro_bmi160_get_rotation_data_signal(board)

let signal = mbl_mw_dataprocessor_fuser_create(board, [signalA, signalG], 2,
    bridge(obj: self)) { (context, data) in
        let _self: NextViewController = bridge(ptr: context!)
        let obj: MblMwCartesianFloat = data!.pointee.valueAs()

        print(obj.accelerometer.x, obj.gyroscope.y)
}

but I get the error -
Cannot convert value of type '[OpaquePointer?]' to expected argument type 'UnsafeMutablePointer<OpaquePointer?>?'
on the third line at [signalA, signalG]

What should I be doing differently? Is there another way to stream 2 signals at once?
When this does work, will that print function get the right values?
Also I recently came across the fuserCreate() function but that doesn't seem to work as I get "Use of unresolved identifier 'fuserCreate':" when I try to use it. Should I be using this somehow?

Thanks in advance for any help, it will be much appreciated.

Comments

  • edited March 2019

    I think I've made some progress, I now have

    var array: [OpaquePointer?] = [signalA, signalG]
    
    let signal = mbl_mw_dataprocessor_fuser_create(board, UnsafeMutablePointer(&array), 2,
    bridge(obj: self)) { (context, data) in
            let _self: NextViewController = bridge(ptr: context!)
            let obj: MblMwCartesianFloat = data!.pointee.valueAs()
    
             print(obj.x, obj.gyroscope.y)
        }
    

    but at data!.pointee (specifically the !) I get the error "Value of type 'OpaquePointer' has no member 'pointee'"
    That line and the line above it was code from the tutorial on setting up the accelerometer streaming, so I'm not sure exactly how to adapt it for this.

  • What version of the iOS SDK are you using?

    Check out the unit tests for Swift examples:
    https://github.com/mbientlab/MetaWear-SDK-iOS-macOS-tvOS/blob/3.2.0/MetaWear/Tests/Integration/Tests.swift#L177

  • Not exactly sure where to find a version number but I only started working with the software like a month ago so it'll be the most recent.
    That looks a lot better and now I'm not getting any errors! But when I run the code, the only outputs i get are Test0 and Test3, so for some reason it is not creating the fuser. Any idea why that could be?

    print("Test0")
        let board = device.board
        let accSignal = mbl_mw_acc_get_acceleration_data_signal(board)!
        let gyroSignal = mbl_mw_gyro_bmi160_get_rotation_data_signal(board)!
    
        accSignal.fuserCreate(with: gyroSignal).continueWith { t in
            guard let fused = t.result else {
                print("Test1")
            return}
    
            print("Test2")
            mbl_mw_datasignal_subscribe(fused,  bridgeRetained(obj: self)) { (context, dataPtr) in
                let this: NextViewController = bridge(ptr: context!)
                let fused: [MblMwData] = dataPtr!.pointee.valueAs()
                let acc: MblMwCartesianFloat = fused[0].valueAs()
                let gyro: MblMwCartesianFloat = fused[1].valueAs()
    
                print("acc: ", acc.x, acc.y, acc.z)
                print("gyro: ", gyro.x, gyro.y, gyro.z)
            }
    
            mbl_mw_acc_set_odr(board, 50)
            mbl_mw_acc_write_acceleration_config(board)
            mbl_mw_acc_enable_acceleration_sampling(board)
            mbl_mw_acc_start(board)
    
            mbl_mw_gyro_bmi160_set_odr(board, MBL_MW_GYRO_BMI160_ODR_50Hz)
            mbl_mw_gyro_bmi160_write_config(board)
            mbl_mw_gyro_bmi160_enable_rotation_sampling(board)
            mbl_mw_gyro_bmi160_start(board)
        }
        print("Test3")
    
  • Did you remove the previously created fusers?

  • What's your board's firmware version?

  • It's 1.3.6. I had another that I tried to update to 1.4.4 but then it got stuck in MetaBoot mode so I'm keeping this one on 1.3.6 to not risk it

  • Firmware v1.4.4 is not for MetaTracker so it does not have fuser support.

  • So it is not possible at all to stream two signals at once using the MetaTracker? Is there a way other than the fuser?

  • edited April 2019

    The fuser isn't used to stream two signals at once, it is used to pack sensor data.

    So by default the APIs and MetaBase App are setup to stream up to 100Hz of sensors at the same time, it could be 25Hz Acc + 25Hz Gyro + 25Hz Mag + 25Hz light OR 50Hz ac + 50Hz Gyro OR 1Hz light + 100Hz euler

    The data comes in the format:
    1. timestamp + acc sensor data
    2. timestamp + gyro sensor data
    3. timestamp + mag sensor data
    4. ... and so on

    The fuser is entirely optional, it is used to pack data so you would get:
    1. timestamp + acc sensor data + gyro sensor data + mag sensor data

    Using the fuser you can sometimes push a bit more data such as 100Hz sensor fusion + 20Hz acc (this would be a typical use case).

    This is only a brief explanation!

  • Okay, that info is good to know thanks! But my main question still stands, is there any way that I can stream data from both the accelerometer and the gyroscope at the same time?

  • edited April 2019

    My answer is still yes.
    www.mbientlab.com/tutorials: You just call startAccelStream() and then startGyroStream()

  • @Laura said:
    The fuser isn't used to stream two signals at once, it is used to pack sensor data.

    So by default the APIs and MetaBase App are setup to stream up to 100Hz of sensors at the same time, it could be 25Hz Acc + 25Hz Gyro + 25Hz Mag + 25Hz light OR 50Hz ac + 50Hz Gyro OR 1Hz light + 100Hz euler

    The data comes in the format:
    1. timestamp + acc sensor data
    2. timestamp + gyro sensor data
    3. timestamp + mag sensor data
    4. ... and so on

    The fuser is entirely optional, it is used to pack data so you would get:
    1. timestamp + acc sensor data + gyro sensor data + mag sensor data

    Using the fuser you can sometimes push a bit more data such as 100Hz sensor fusion + 20Hz acc (this would be a typical use case).

    This is only a brief explanation!

    Hi Laura,
    I am trying to use mbl_mw_dataprocessor_fuser_create for streaming both gyroscope values (degrees/seconds, not quaternions) and gravity (usine sensorfusion with GRAVITY_VECTOR). I try to work at 50 Hz. But I have read in the doc that Gravity is only at 100 Hz. So, with your above explanation, it means that what I am trying to do does not work? As a matter of fact, the call to mbl_mw_dataprocessor_fuser_create is properly triggering the call to the function processor_created() but the pointer is "None" (using Python).
    Can you confirm my understanding?

  • You can't fuse a sensor fusion output.
    Sensor fusion is always at 100Hz.
    You are correct.

  • Very clear, thank you !

Sign In or Register to comment.