Skip to content

Clarification about using TRICAL_estimate_update() #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
RafigRzayev opened this issue Aug 11, 2022 · 13 comments
Open

Clarification about using TRICAL_estimate_update() #8

RafigRzayev opened this issue Aug 11, 2022 · 13 comments

Comments

@RafigRzayev
Copy link

Hi,

I am getting X, Y, Z values from magnetometer in uT units.

I am using following tool to identify magnetic field in my location, and the value is 50uT (though my calibrated reading are usually around ~55uT).

I don't understand which value should be used for expected_field argument in TRICAL_estimate_update(&global_instance, sensor_reading, expected_field). Can you please tell me what values should be put there?

Below is the pseudocode that I am using, can you please check that the usage is correct?

TRICAL_instance_t global_instance;

int main(void) {
  TRICAL_init(&global_instance);
  TRICAL_norm_set(&global_instance, 50.0);
  TRICAL_noise_set(&global_instance, 1.5);

  float bias_estimate[3];
  float scale_estimate[9];
  float sensor_reading[3];
  float expected_field[3];

  // for holding data received from magnetometer, in uT.
  float mag_x, mag_y, mag_z;

  while(true) {
    // get the latest sensor reading
    read_magnetometer(mag_x, mag_y, mag_z);
    sensor_reading[0] = mag_x;
    sensor_reading[1] = mag_y;
    sensor_reading[2] = mag_z;

    // What should be passed to expected field?
    TRICAL_estimate_update(&global_instance, sensor_reading, expected_field);

    TRICAL_estimate_get(&global_instance, bias_estimate, scale_estimate);

    printf("[%f %f %f]\n", bias_estimate[0], bias_estimate[1], bias_estimate[2]);
   }

return 0;
}
@RafigRzayev
Copy link
Author

@bobayka can you please help? Looks like the repository is not very active.

Here you wrote that your input range is [-1,1]. Did you scale the input by the maximum?

Also, you said that no zeros are allowed in the input. It is strange :( . Did you write if statement to avoid zeros?

@RafigRzayev
Copy link
Author

@Lelelo1 Maybe you can help? Do you know which values to pass to the function?

@Lelelo1
Copy link

Lelelo1 commented Aug 12, 2022

As far as I came to understand it. The expected field is from world magnetic model. You can check what the earth magnetic field is supposed to be in your location with Launch Single Point Calculator

If you point your device to north it should print that vector when there is none or little magnetic distortion. The coordinate system of the vector from world magnetic model and the measurement in the application needs to match.

Its used in a kalman filter, in _trical_measurement_calibrate method in filter.c. It means deviating values are filtered out.

@RafigRzayev
Copy link
Author

RafigRzayev commented Aug 12, 2022

Thank you very much for your help. I was using the same calculator and for me the "Total field" is calculated as 50,325.0 nT, which is ~50uT.

That's why I did following:
TRICAL_norm_set(&global_instance, 50.0);

But in the TRICAL_estimate_update function, it expects a 3-element vector, not a single value:

/*
TRICAL_estimate_update
Updates the calibration estimate of `instance` based on the new data in
`measurement`, and the current field direction estimate `reference_field`.
Call this function with each reading you receive from your sensor.
*/
void TRICAL_estimate_update(TRICAL_instance_t *instance,
float measurement[3], float reference_field[3]);

I tried with reference_field = {50,50,50}, but the calculated bias was always [0,0,0].

I found one repo which uses the function, but is really difficult to understand what is going on there.

Which values did you use for the reference_field[3](expected field)?

@Lelelo1
Copy link

Lelelo1 commented Aug 12, 2022

X: North Component
Y: East Component
Z: Vertical Component

√(x2 + y2 + z2). Is same as norm (50)

It could look like this the vector:
16,505.3, -1,509.8, 47,844.4
total field (norm) 50,611.4

For latitude: 57.698745, longitude: 11.966936

@RafigRzayev
Copy link
Author

So I can make up any combination of 3 values which by formula will provide 50?

Can I use fixed vector always? Or should it be updated according to something else?

@RafigRzayev
Copy link
Author

In the repository mentioned above, they use following:

TRICAL_estimate_update(instance, mag_value_f, expected_field_f);

Where expected_field_f comes from:

    float mag_value_f[3], expected_field_f[3];
...
    quaternion_vector3_multiply_d(expected_field, attitude, wmm_field);
    vector_f_from_d(expected_field_f, expected_field, 3u);

@Lelelo1
Copy link

Lelelo1 commented Aug 12, 2022

So I can make up any combination of 3 values which by formula will provide 50?

No

That vector represent a arrow pointing the direction earths magnetic field in 3d. For instance ENU coordinate system means east component is x, north component is y, and vertical component is z.

When there is no distortion all measurements become like a sphere, all of them having length(norm) of 50. The norm depend on how near earth's poles you are

I recommend you collect the first measurement and use it as expected field instead. It assumes you are in spot with little magnetic distortion. Then you can test to distort measurement with some metal near sensor of the device. The kalman filter should block those values and application should still be accurate depending how well the Kalman is made

@RafigRzayev
Copy link
Author

Thank you for clarification. Then, if I understood correctly, I will do following:

  • Adjust sensor so that its axes are aligned according to ENU coordinate system(one of the magnetometer axes will point to geographic north).
  • Place sensor in low distortion area(away from buildings and etc.)
  • Record the measured value and always use it for the expected_field

Can you confirm?

@RafigRzayev
Copy link
Author

I tried with your values for demo purposes, the bias doesn't change. It is always 0, 0, 0.

I wrote an example which you can run on your pc. I recorded the magnetometer values, and saved them in a header file to be used as an input for the TRICAL.

Here is the link

I am sorry for taking your time. I would appreciate if you can take a look. The program output is not normal: it prints NaN and ones .

@Lelelo1
Copy link

Lelelo1 commented Aug 12, 2022

I have stopped programming this kind of stuff. So I can’t look at it in detail.

But I can tell you that bias is distortion

@RafigRzayev
Copy link
Author

Ok, I understand :)

Thank you very much for your help.

If I will get it working I will post updates here.

@RafigRzayev
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants