Jump to content

IMU 2.0 Magnetometer Problems


Recommended Posts

Dear all,
I am using the IMU 2.0 for a project and I found that the magnetometer has a weird behavior at least during All Data Callback function in MATLAB. I didn't check using getters or any other callback, but that shouldn't be an impediment for proper functioning anyways. The IMU is supposed to be calibrated although the problem may still be related to that. When the sensor is operated with the fusion mode by default (no explicit fusion mode command is written in the computer) the magnetometer gives values that are constant with respect of time (no noise at all). When the fusion mode is set to 0 (OFF) the sensor gives reasonable data with some noise in it. Finally, when the fusion mode is set to 1, 2 or 3 (either of the ON modes) the magnetometer gives perfect zeroes.
 
I don't think that should be the actual behavior of the sensor. First, the default mode must coincide with the fusion mode 1, but that doesn't happen. Second, when the sensor is operating in any of the ON fusion modes I would generally expect to see some non-zero values with slightly random fluctuations when the sensor is stationary and there are no other magnetic disturbances in the environment.
 
Does anyone have a clue on what would be happening here?
Link to post
Share on other sites

I wrote a small test program (in Python) to try this out and i can't reproduce it. There is no magnetometer data in the "SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER"-mode (mode 2). Which is expected. With all other modes there is magnetometer data.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

HOST = "localhost"
PORT = 4223
UID = "6KSLMN"

import time
from tinkerforge.ip_connection import IPConnection
from tinkerforge.brick_imu_v2 import BrickIMUV2

def cb_all_data(acceleration, magnetic_field, angular_velocity, euler_angle, quaternion,
                linear_acceleration, gravity_vector, temperature, calibration_status):
    print("Magnetic Field [X]: " + str(magnetic_field[0]/16.0) + " µT")
    print("Magnetic Field [Y]: " + str(magnetic_field[1]/16.0) + " µT")
    print("Magnetic Field [Z]: " + str(magnetic_field[2]/16.0) + " µT")
    print("")

if __name__ == "__main__":
    ipcon = IPConnection()
    imu = BrickIMUV2(UID, ipcon)

    ipcon.connect(HOST, PORT)


    imu.register_callback(imu.CALLBACK_ALL_DATA, cb_all_data)
    imu.set_all_data_period(250)

    imu.set_sensor_fusion_mode(imu.SENSOR_FUSION_OFF)
    print('Sensor Fusion Mode: SENSOR_FUSION_OFF')

    time.sleep(1)

    imu.set_sensor_fusion_mode(imu.SENSOR_FUSION_ON)
    print('Sensor Fusion Mode: SENSOR_FUSION_ON')

    time.sleep(1)

    imu.set_sensor_fusion_mode(imu.SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER)
    print('Sensor Fusion Mode: SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER')

    time.sleep(1)

    imu.set_sensor_fusion_mode(imu.SENSOR_FUSION_ON_WITHOUT_FAST_MAGNETOMETER_CALIBRATION)
    print('Sensor Fusion Mode: SENSOR_FUSION_ON_WITHOUT_FAST_MAGNETOMETER_CALIBRATION')

    time.sleep(1)

    ipcon.disconnect()

Output:

Zitat

olaf@pc2:~/tf/imu-v2-brick/software/tests$ ./example_callback.py
Sensor Fusion Mode: SENSOR_FUSION_OFF
Magnetic Field [X]: 31.6875 µT
Magnetic Field [Y]: -12.6875 µT
Magnetic Field [Z]: -21.9375 µT

Magnetic Field [X]: 32.4375 µT
Magnetic Field [Y]: -13.0625 µT
Magnetic Field [Z]: -23.125 µT

Magnetic Field [X]: 32.4375 µT
Magnetic Field [Y]: -13.8125 µT
Magnetic Field [Z]: -22.75 µT

Sensor Fusion Mode: SENSOR_FUSION_ON
Magnetic Field [X]: 32.375 µT
Magnetic Field [Y]: -12.25 µT
Magnetic Field [Z]: -22.25 µT

Magnetic Field [X]: 32.75 µT
Magnetic Field [Y]: -12.25 µT
Magnetic Field [Z]: -21.1875 µT

Magnetic Field [X]: 30.875 µT
Magnetic Field [Y]: -11.875 µT
Magnetic Field [Z]: -22.25 µT

Magnetic Field [X]: 32.375 µT
Magnetic Field [Y]: -12.6875 µT
Magnetic Field [Z]: -21.5625 µT

Sensor Fusion Mode: SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER
Magnetic Field [X]: 0.0 µT
Magnetic Field [Y]: 0.0 µT
Magnetic Field [Z]: 0.0 µT

Magnetic Field [X]: 0.0 µT
Magnetic Field [Y]: 0.0 µT
Magnetic Field [Z]: 0.0 µT

Magnetic Field [X]: 0.0 µT
Magnetic Field [Y]: 0.0 µT
Magnetic Field [Z]: 0.0 µT

Magnetic Field [X]: 0.0 µT
Magnetic Field [Y]: 0.0 µT
Magnetic Field [Z]: 0.0 µT

Sensor Fusion Mode: SENSOR_FUSION_ON_WITHOUT_FAST_MAGNETOMETER_CALIBRATION
Magnetic Field [X]: 30.875 µT
Magnetic Field [Y]: -12.25 µT
Magnetic Field [Z]: -23.875 µT

Magnetic Field [X]: 32.75 µT
Magnetic Field [Y]: -11.875 µT
Magnetic Field [Z]: -22.6875 µT

Magnetic Field [X]: 30.5625 µT
Magnetic Field [Y]: -11.5625 µT
Magnetic Field [Z]: -21.1875 µT

Magnetic Field [X]: 30.875 µT
Magnetic Field [Y]: -11.5625 µT
Magnetic Field [Z]: -21.1875 µT

 

 

Can you post a small example program that we can use to reproduce the problem?

Link to post
Share on other sites
  • 2 weeks later...

I couldn't replicate it either. However, after reading the forum again I wrote the following script.

function imu_offset_measurement()
    clear ALL
    clear callback_workspace %to clear its persistent variables
    clear global
    clc
    close ALL
    
    import com.tinkerforge.IPConnection;
    import com.tinkerforge.BrickIMUV2;
    
    global arrayElapsedTime;
    global arrayRawAcceleration;
    global arrayAngularVelocity;
    global arrayMagneticField;
    
    disp('START');
    
    HOST = 'localhost';
    PORT = 4223;
    UID = '6467RG'; % Change XXYYZZ to the UID of your IMU Brick 2.0

    ipcon = IPConnection(); % Create IP connection
    imu = handle(BrickIMUV2(UID, ipcon), 'CallbackProperties'); % Create device object

    ipcon.connect(HOST, PORT); % Connect to brickd
    % Don't use device before ipcon is connected
    
    bias = [0;0;0]; %[0.0055;0.0168;-0.2722]; %this constant has been previously calculated
    
    imu.setSensorConfiguration(7,4,2,0,4);%set sensor range and filter bandwidth
    
    %imu.setSensorFusionMode(0); %Fusion Mode OFF (uncalibrated output)
    
    % Set period for all data callback to 0.1s (100ms)
    imu.setAllDataPeriod(10);
    
    % Register all data callback to function cb_all_data
    set(imu, 'AllDataCallback', @(h, e) callback_workspace(e, bias));
    %readings not reliable during first miliseconds
    
    %all the experiment is stationary
    pause(1);%recording time
    
    imu.setSensorFusionMode(0);
    pause(1);%second period
    imu.setSensorFusionMode(1);
    pause(1);
    imu.setSensorFusionMode(2);
    pause(1);
    imu.setSensorFusionMode(3);
    pause(1);
    
    ipcon.disconnect(); %stop capturing data
        
    %POST-PROCESSING
    xlswrite('results_imu_offset_measurement_test_magnetometer.xls',[arrayElapsedTime,arrayRawAcceleration,arrayAngularVelocity,arrayMagneticField]);
    disp('FINISH');
end

with callback function

function callback_workspace(e, bias)

    persistent callbackTimer; %to remove persistent variables remember to clear the right function in the main
    global arrayElapsedTime;
    global arrayRawAcceleration;
    global arrayAngularVelocity;
    global arrayMagneticField;

    %if it is the first call return inicial values.
    %the persistent variables must be cleared before calling this function for the first time
    if isempty(callbackTimer)
        callbackTimer=tic;
        return
    elseif toc(callbackTimer)>0.07 %readings not reliable during first miliseconds
        arrayElapsedTime = [arrayElapsedTime; toc(callbackTimer)];
        arrayRawAcceleration = [arrayRawAcceleration;double(e.acceleration.')/100.0];
        arrayAngularVelocity = [arrayAngularVelocity;double(e.angularVelocity.')/16.0];
        arrayMagneticField = [arrayMagneticField;double(e.magneticField.')/16.0];
        return
    else
        %left empty purposefully
    end
end

This gave me the attached output file, which does not behave in the same way I described the first time, but still quite funky. It does not make much sense since the total recorded time is 10 seconds not 5 seconds as it should by adding all pauses! In this case, the "by default" period gives zeroes, and the rest behave as expected despite the additional recorded 5 seconds. However, any subsequent execution of the script gives reasonable outcome.

Is it possible that something happens just at the beginning while setting up the IP connection to the device?

results_imu_offset_measurement_test_magnetometer.xls

Edited by chris.nieto
Link to post
Share on other sites

About the extra 5 seconds of data: From the output file it seems that there are full zero output line every full second when the fusion mode is changed. The extra 5 seconds of data don't have that. Also the recorded data has the expected sample timing of 10 milliseconds. To get this extra 5 seconds would require that the ipcon.disconnect() call is delayed by 5 seconds. But I don't see how that should happen.

Could you record the value of the callbackTimer directly before and after the ipcon.disconnect() call to see when it's called and how long it takes in relation to the extra 5 seconds of data?

Is this fixed 5 seconds of extra data, or is this times 2 of extra data? Could you replace the pause(1) calls with pause(2) calls to see if this gives you 15 or 20 seconds of recorded data in total?

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...