Skip to content

Softiron calibration #1

@altineller

Description

@altineller

Hello,

First of all thank you for your work.

I have some questions namely:

I could not reach the raw values from my sensor, which outputs microTeslas for x,y,z as floats. I created the same csv file, but with floats, and the software did indeed work. The generated offsets are in par with previous software, so would providing microteslas as float be ok and if not, could we derive an int like 100x the microteslas? Is scale a problem.

Secondly:

Does this software calibrate for soft iron errors? It generates offsets, and scale values, but I did not see it generate a matrix for softiron calibration. Or would we need another kind of data such as accel and gyro outputs as well to get soft iron calibration.

How could we apply these values to correct the magnetometer values.

In my code I have a:

float mag_offsets[3] = { 11.88f, 10.51f, -4.02f };

float mag_softiron_matrix[3][3] = {{ 0.986f, 0.003f, -0.005f },
{ -0.001f, 1.021f, -0.006f },
{ -0.005f, -0.006f, 0.966f }};

and to correct I do:

float c_mx = magData.float_x - mag_offsets[0];
float c_my = magData.float_y - mag_offsets[1];
float c_mz = magData.float_z - mag_offsets[2];

mx = c_mx * mag_softiron_matrix[0][0] + c_my * mag_softiron_matrix[0][1] + c_mz * mag_softiron_matrix[0][2];
my = c_mx * mag_softiron_matrix[1][0] + c_my * mag_softiron_matrix[1][1] + c_mz * mag_softiron_matrix[1][2];
mz = c_mx * mag_softiron_matrix[2][0] + c_my * mag_softiron_matrix[2][1] + c_mz * mag_softiron_matrix[2][2];

I understand from generic_implementation.h the following code does the scale correction, but I have not fully understood how it does it.
Does it simply multiply each value by the scale factor?

void apply_scale_correction(std::vector& x, std::vector& y, std::vector& z,
float& scale_x, float& scale_y, float& scale_z)
{
long avg_delta_x = (*std::max_element(x.begin(), x.end()) - *std::min_element(x.begin(), x.end())) / 2;
long avg_delta_y = (*std::max_element(y.begin(), y.end()) - *std::min_element(y.begin(), y.end())) / 2;
long avg_delta_z = (*std::max_element(z.begin(), z.end()) - *std::min_element(z.begin(), z.end())) / 2;
long avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3;
scale_x = (float)avg_delta / avg_delta_x;
scale_y = (float)avg_delta / avg_delta_y;
scale_z = (float)avg_delta / avg_delta_z;
for (size_t i = 0; i < x.size(); ++i)
{
x[i] *= scale_x;
y[i] *= scale_y;
z[i] *= scale_z;
}
}

Best Regards,
Can

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions