Sample timestamp and sensor alignment on 50Hz

Hi all,

I have a situation in which I want to use the gyroscope and accelerometer at the same time. To be able to use the sensor data in my algorithms both sensors need to be aligned in some way. Currently the only way I see is to give each incoming sample a timestamp, but that is where I run into some issues:

First of all, adding a real timestamp in ms does not work, the incoming data rate fluctuates quite a bit, and some samples arrive within a few ms, while sometimes the time difference is near 30ms. (I assume this is due to the Bluetooth connection). Since I need to read the data at 50Hz, I need the timestamps to be near 20ms between each sample.
Second, I tried adding a simple counter so that each sample is given an exact 20ms increased timestamp, but since both sensors work independently, aligning the data is a problem.

Is it possible to start the gyro and accelerometer at once, and/or have 1 combined data message that is being send to my mobile phone? And is it possible to add a timestamp to the sample on the board, instead of on the mobile phone?

Thanks for the feedback!

Comments

  • Since the sensors produce data at very consistent time intervals, your counter method is all you need to sync data.  If you need accurate timestamps, then you will have to use the logger and even then, there will always been a time difference between two data points created at the "same time".

    We could add a timestamp for streaming however that will occupy another 4 bytes which will prevent people from using the high frequency streams.  Again, nothing will ever have the same timestamp so you will still need to do some post processing.  It is also unnecessary since you have a live connection which means you know when you started the stream.
  • Hi Eric,

    Thanks for the feedback, this is useful and probably useable for what we intend to do.

    I do, however, still have one question. How can I align the gyro and accelerometer using a simple counter? Since the stream for both is not started at the same time, there will be a difference between the first samples of one sensor and of the other sensor.

    What I do now is wait with my own "counter" and only start tagging samples after both sensors have started. Does that make any sense, or is there a simpler way to do this?

    Thanks again.
  • Match the nth accelerometer data with the nth gyro data.  The time difference between the two sensors is probably milliseconds so I highly doubt that will negatively impact your algorithm if at all.
  • edited October 2016
    Further to this discussion, the CPRO uses the Bosch BMI160 Accelerometer and Gyro which the spec sheet indicates the following two pieces of information:

    High performance accelerometer and gyroscope (hardware synchronized)
    Hardware sensor time-stamps for accurate sensor data fusion

    Is it possible to have the combined information delivered in a single data packet which marries the Accelerometer reading with the synchronized Gyro reading? Is it also possible to include a counter (8 or 16 bit) containing the sample number in order to determine if all samples are being received (and in the correct order due to the asynchronous nature of BTLE communcations). With such a counter and a know sampling frequency it would be much easier to calculate the Delta Time which is extremely important when using a gyroscope that measures in degrees per second.
  • @Alex

    Regarding correlating a specific Accelerometer and Gyroscope sample, I would recommend using the timestamps received with the responses from the OS.  There is a feature of BLE which will make it work quite nicely.  The radio communicates on a fixed interval, and transfers multiple data packets at every interval.  What you can do to match the samples, is look for the last two samples received in any interval.  Those will be the two samples that correspond to a simultaneous measurement.

    A point brought up by MichaelG also assists in making this process easier: the Accelerometer and Gyroscope share the same clock source in hardware.  With this we know that the sampling frequencies are synchronized.

    If you are feeding the data points into another algorithm with time stamps, you will want to reconstruct the timestamps based on the sampling rate.  The real world sampling rate can be calculated from the total number of samples over a sufficiently long time interval -- perhaps the chuck of data being fed into the algorithm.  If the algorithm does not depend on the absolute timing of events you could just feed in fixed time increments.

    @MichaelG

    We might consider data packing accelerometer and gyroscope data together in the future but we do not currently support it.  The upcoming MetaMotion series will have the data points correlated in firmware and will run sensor fusion on the device.

    Regarding the "asynchronous" nature of BTLE: BLE notifications which transfer all data from the device are acknowledged at the radio level on each transmission.  If there is a disruption to any data packet it is retransmitted by the stack -- in short, notifications are guaranteed to be delivered in order by our firmware design (everything is FIFO) and the BLE GATT protocols. 

    Dropped packets can still be an issue where a counter would help, but only when the data rate significantly exceeds the bandwidth of the radio link.  There is enough buffering on the device side that short term drops in bandwidth, such as brief reception problems or radio interference, can be mitigated.  With reasonable data rates, counting received packets on the client side is sufficient.

    We are working on a different solution for detection of non fatal exception such as dropped packets, and a reporting mechanism for the firmware.  Part of this solution may also include a rate limiter with a fairness algorithm to handle multiple high data rate stream sources.
  • While your explanation was encouraging, experemental evidence seems to suggest otherwise.

    I created a routine to output a row to a CSV file when it has obtained a packet of accelerometer data and a packet of gyroscope data (captured at 50Hz). In order to verify that there was a 1:1 relationship I added a counter of how many times data was captured by a particular sensor before it was output to the CSV file. I have pasted the output below.

    As can be seen (if you paste into a CSV and open in a spreadsheet), there can be up to three readings from the accelerometer for every one reading from the gyroscope even though these devices are both set to 50Hz and the occurences are irregular. Likewise, the magnetometer readings are irregular.

    So either sensor readings are being lost or BTLE is not delivering a reading because the value hasn't changed, either way, it is impossible to calculate DeltaT by counting samples or use sensor fusion.

    DeltaT,AccelX,AccelY,AccelZ,GyroX,GyroY,GyroZ,MagX,MagY,MagZ,AclCount,GyrCount,MagCount
    0.02,-0.12445068359375,0.06890869140625,-0.95794677734375,-0.426829278469086,-0.243902444839478,-0.121951222419739,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.122314453125,0.068115234375,-0.9591064453125,-0.426829278469086,-0.182926833629608,-0.0609756112098694,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.123779296875,0.06854248046875,-0.95672607421875,-0.426829278469086,-0.182926833629608,-0.121951222419739,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.12408447265625,0.0679931640625,-0.95849609375,-0.365853667259216,-0.182926833629608,-0.121951222419739,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.12457275390625,0.0679931640625,-0.95977783203125,-0.426829278469086,-0.182926833629608,-0.121951222419739,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.12591552734375,0.06988525390625,-0.95953369140625,-0.487804889678955,-0.0609756112098694,-0.121951222419739,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.124267578125,0.06964111328125,-0.9581298828125,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.875,91.5625,253.8125,1,1,0
    0.02,-0.1259765625,0.06951904296875,-0.95947265625,-0.426829278469086,-0.121951222419739,-0.121951222419739,-43.25,92.3125,253.8125,2,1,1
    0.02,-0.12591552734375,0.06903076171875,-0.95849609375,-0.426829278469086,-0.0609756112098694,-0.121951222419739,-43.25,92.3125,253.8125,1,1,0
    0.02,-0.12274169921875,0.0697021484375,-0.95977783203125,-0.426829278469086,-0.182926833629608,-0.121951222419739,-43.25,92.3125,253.8125,1,1,0
    0.02,-0.12396240234375,0.0682373046875,-0.95819091796875,-0.487804889678955,-0.182926833629608,-0.182926833629608,-43.25,92.3125,253.8125,1,1,0
    0.02,-0.1240234375,0.068115234375,-0.95928955078125,-0.426829278469086,-0.182926833629608,-0.121951222419739,-43.25,92.3125,253.8125,1,1,0
    0.02,-0.12347412109375,0.06884765625,-0.9593505859375,-0.426829278469086,-0.182926833629608,-0.121951222419739,-43.625,91.9375,252.375,2,1,1
    0.02,-0.124267578125,0.06817626953125,-0.95965576171875,-0.548780500888824,-0.121951222419739,-0.121951222419739,-43.625,91.9375,252.375,1,1,0
    0.02,-0.12420654296875,0.06829833984375,-0.95928955078125,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.5,91.9375,253.875,1,1,1
    0.02,-0.12384033203125,0.06817626953125,-0.9576416015625,-0.426829278469086,-0.182926833629608,-0.121951222419739,-42.5,91.9375,253.875,2,1,0
    0.02,-0.12530517578125,0.06866455078125,-0.95989990234375,-0.487804889678955,-0.121951222419739,-0.182926833629608,-42.5,91.9375,253.875,1,1,0
    0.02,-0.12432861328125,0.06854248046875,-0.958251953125,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.5,91.9375,253.875,1,1,0
    0.02,-0.12445068359375,0.06951904296875,-0.95849609375,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.5,91.9375,253.875,1,1,0
    0.02,-0.1260986328125,0.0687255859375,-0.9598388671875,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.5,91.9375,253.875,1,1,0
    0.02,-0.12371826171875,0.0677490234375,-0.9580078125,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.5,91.1875,253.4375,2,1,1
    0.02,-0.12445068359375,0.06793212890625,-0.9576416015625,-0.426829278469086,-0.182926833629608,-0.0609756112098694,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.12255859375,0.068359375,-0.95770263671875,-0.426829278469086,-0.121951222419739,-0.121951222419739,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.123779296875,0.06744384765625,-0.95892333984375,-0.426829278469086,-0.121951222419739,-0.121951222419739,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.12493896484375,0.06866455078125,-0.9610595703125,-0.487804889678955,-0.0609756112098694,-0.121951222419739,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.12548828125,0.06878662109375,-0.9605712890625,-0.426829278469086,-0.121951222419739,-0.0609756112098694,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.1241455078125,0.06982421875,-0.9586181640625,-0.426829278469086,-0.121951222419739,-0.121951222419739,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.12347412109375,0.0689697265625,-0.95721435546875,-0.487804889678955,-0.121951222419739,-0.121951222419739,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.12530517578125,0.0684814453125,-0.96002197265625,-0.487804889678955,-0.182926833629608,-0.0609756112098694,-42.5,91.1875,253.4375,1,1,0
    0.02,-0.12603759765625,0.067626953125,-0.96527099609375,-0.426829278469086,-0.0609756112098694,-0.121951222419739,-42.875,92.3125,252.75,1,1,1
    0.02,-0.12554931640625,0.06884765625,-0.959716796875,-0.304878056049347,0.0609756112098694,-0.121951222419739,-42.875,92.3125,252.75,1,1,0
    0.02,-0.1229248046875,0.06964111328125,-0.953369140625,-0.487804889678955,-0.121951222419739,-0.182926833629608,-42.875,92.3125,252.75,1,1,0
    0.02,-0.125732421875,0.07049560546875,-0.96282958984375,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.875,92.3125,252.75,1,1,0
    0.02,-0.123291015625,0.0684814453125,-0.95574951171875,-0.487804889678955,-0.121951222419739,-0.182926833629608,-42.875,92.3125,252.75,1,1,0
    0.02,-0.12384033203125,0.06939697265625,-0.95880126953125,-0.487804889678955,-0.182926833629608,-0.0609756112098694,-42.875,92.3125,252.75,1,1,0
    0.02,-0.126220703125,0.06768798828125,-0.9573974609375,-0.487804889678955,-0.121951222419739,-0.182926833629608,-42.875,92.3125,252.75,1,1,0
    0.02,-0.12646484375,0.06787109375,-0.9581298828125,-0.487804889678955,-0.121951222419739,-0.121951222419739,-42.875,92.3125,252.75,1,1,0
    0.02,-0.1224365234375,0.06939697265625,-0.96136474609375,-0.548780500888824,-0.182926833629608,-0.121951222419739,-43.625,92.3125,254.1875,1,1,1
    0.02,-0.1248779296875,0.06903076171875,-0.9599609375,-0.426829278469086,-0.121951222419739,-0.0609756112098694,-43.625,92.3125,254.1875,1,1,0
    0.02,-0.123291015625,0.06939697265625,-0.9599609375,-0.487804889678955,-0.182926833629608,-0.121951222419739,-43.625,92.3125,254.1875,2,1,0
    0.02,-0.12396240234375,0.07025146484375,-0.9605712890625,-0.487804889678955,-0.121951222419739,-0.121951222419739,-43.625,92.3125,254.1875,1,1,0
    0.02,-0.1236572265625,0.06805419921875,-0.95880126953125,-0.426829278469086,-0.121951222419739,-0.121951222419739,-43.625,92.3125,254.1875,1,1,0
    0.02,-0.12371826171875,0.06878662109375,-0.95855712890625,-0.487804889678955,-0.121951222419739,-0.182926833629608,-42.875,91.1875,253,2,1,1
    0.02,-0.12457275390625,0.0699462890625,-0.959228515625,-0.487804889678955,-0.182926833629608,-0.121951222419739,-42.875,91.1875,253,1,1,0
    0.02,-0.125,0.06854248046875,-0.95599365234375,-0.487804889678955,-0.0609756112098694,-0.121951222419739,-42.5,92.3125,253,1,1,1
    0.02,-0.12451171875,0.06854248046875,-0.95947265625,-0.487804889678955,-0.0609756112098694,-0.121951222419739,-42.5,92.3125,253,2,1,0
    0.02,-0.12353515625,0.0684814453125,-0.95831298828125,-0.426829278469086,-0.0609756112098694,-0.0609756112098694,-42.5,92.3125,253,1,1,0
    0.02,-0.12408447265625,0.068603515625,-0.95977783203125,-0.487804889678955,-0.121951222419739,-0.121951222419739,-42.5,92.3125,253,1,1,0

  • Do you get the same results of you are using the MetaHub app?  What's the code you are using to enable the stream?  I tested an RPro board last night running firmware 1.2.5 using the Windows app and the # of samples collected only differed by 3 and 6 (1 hr and 2 hr session respectively) between the acc and gyro.


    1 hour session csv

    https://dl.dropboxusercontent.com/u/16251678/MetaWear_2016-10-28T00.05.56.658_D57BB97DCE0E_Accelerometer.csv

    2 hour session csv

  • Hi all,
    I've the same problem I also working at 50Hz.
    When  I use the logger and then download data from accelerometer and gyroscope, the logger adds a timestamp for each sensor ang I can process correctly the data.
    But I need longs times, so I need to acquire both sensor in streaming and record in a .csv file. When I try to synchronize both sensors it is impossible, I can not detect losts packets, and I haven't timestamp, so, data processing is not correct.

    Do you add to the firmware the timestamp or a counter for each sensor in streaming mode?
    Do you propose any solution?

    Thanks
  • Counting the packets as described in this thread is sufficient to match acc & gyro data provided you have a stable and properly configured connection for streaming data at a combined 100Hz.
This discussion has been closed.