tyrex-team / benchmarks-attitude-smartphones

Benchmark on Attitude Estimation with Smartphones (datasets & scripts)
https://tyrex.inria.fr/mobile/benchmarks-attitude
Other
38 stars 27 forks source link

C# implementation in cross platform Xamarin app #1

Open Lelelo1 opened 4 years ago

Lelelo1 commented 4 years ago

Hello!

I am looking to use these set of filters and algorithms to improve the overall accuracy of my navigation app - after having read Attitude Estimation for Indoor Navigation and Augmented Reality with Smartphones. The app currently takes os calibrated acc, gyro and mag readings into madgwick and uses the attitude quaternion that is returned.

Here is a screen recording of the app in i'ts current state.

There is some inaccuracies when indoors, certain areas outside and near house walls - which I believe is caused by magnet perturbations. I have measured the µT and found these to rise or fall in this places. However given from the small discussion at https://github.com/xioTechnologies/Fusion/issues/8 - I learned that all perturbations are not reflected in the µT.

I was hoping I could try the magnetometer calibration with Barz and one of the MichelObs sensor fusion algorithms


My problem right now is I have no knowledge of matlab and also have very little math knowledge - so it is very hard to translate. It also seems difficult to use Matlab code in another languages (C# in this case) - It requires MATLAB Coder

Lelelo1 commented 4 years ago

I decided to translate the code into C#: https://github.com/Lelelo1/AHRS-CSharp AttitudeFilter init consists of both pre exististing code and that found in generateAttitude.m to set up AccRef, MagRef. I have not managed to get working attitude values out yet.

ThibaudM commented 4 years ago

Hello!

I was not comfortable with Matlab when I started to work on AHRS algorithms too, but today, I can confirm this language is designed for these kinds of algorithms thanks to good readability. I translated some parts of this code in Java/Android, and it took me hundreds of lines compared to 30 for Matlab.

About your thoughts on:

There is some inaccuracies when indoors, certain areas outside and near house walls - which I believe is caused by magnet perturbations. I have measured the µT and found these to rise or fall in this places. However given from the small discussion at xioTechnologies/Fusion#8 - I learned that all perturbations are not reflected in the µT. You are right. A detector on the magnitude of the magnetic field is not enough to treat all the cases. I mentioned this part in the State of the Art section of the paper you linked. However, I did not notice a huge difference when I implemented the others (due to the complexity to maintain multiple detectors with false detections).

If I can recommend something to enhance the built-in AHRS filters of iOS and Android devices, it is to control the calibration phase. I have noticed their calibration algorithm seems to be good, but as they do it "on-the-fly" (at least for Android), sometimes, data received by sensors are not well suited for their fitEllipsoid algorithm.

About the comprehension of AccRef and MagRef, I recommend you to have a look at these three files:

Lelelo1 commented 4 years ago

What about the sensor input to the algorithms, gyr, acc, mag - do they also have to be adjusted to fit correctly with the coordinate system - or is it only for the MagRef and AccRef?

Currently I noticed my context.magnetic.* did not pass the check in generateAttitude.m so I will have to make sure I also create those correct. The quaternion value I get out of MichelObs now looks more like AHRS values and I have made sure most of the translated operations are correct after downloading matlab trial and comparing the matlab function's result with C#(Math.Net) methods.

ThibaudM commented 4 years ago

gyr, acc, mag are measurement vectors in the smartphone frame. MagRef and AccRef are the same vectors in the Local Tangent Plane frame (here, East-North-Up, ENU). The quaternion you are looking for is the one that fits the best rotation between the smartphone frame and the ENU frame using respectively the measurements and the references vectors. Have a look at the paragraph 2.3 of the paper.

Currently I noticed my context.magnetic.* did not pass the check in generateAttitude.m so I will have to make sure I also create those correct.

Can you provide a code snippet to understand the problem better?

Lelelo1 commented 4 years ago

I see. Here in the Setup method is the code that currently creates MagRef and AccRef.

ThibaudM commented 4 years ago

Can you give me the value of geoMagRes (at least: X,Y,Z and Declinatation) and QMagneticToTrue? I do not know what Geo.Geomagnetism.IgrfGeomagnetismCalculator is doing, but, if it has the same behavior than wrldmagm in Matlab, your results are in NED coordinates. You have to convert them. You can also compare the results with https://www.ngdc.noaa.gov/geomag/WMM/calculators.shtml.

About the Gravity vector, you can safely use [0, 0, -9.81]. The real value of the local gravity vector is not necessary for this kind of application

Lelelo1 commented 4 years ago

geoMagRes:

geoMagRes

(The date there is old because that particular package hasen't been updated with latest world magnetic model data)


QMagneticTue:

QMagneticToTrue


About the Gravity vector, you can safely use [0, 0, -9.81]. The real value of the local gravity vector is not necessary for this kind of application

Great one less needed external package!

Lelelo1 commented 4 years ago

I have tried to pass that check with matlab trial test project that I have - It still says:

Reference vectors are not well constructed

function main

% Location and date properties properties
location = struct('latitude', 45.187778, 'longitude', 5.726945, 'altitude', 200);
date = struct('year', 2020, 'month', 05, 'day', 31);
% 'enu', 'ned'
coordinateSystem = "enu"; %ned same
    % copy paste of the entire file
    context = createContextFromLocationAndDate(location, date, coordinateSystem);

    % Let's define MagRef and AccRef temporarly in Earth Magnetic Field frame
    qMagneticToTrue = dcm2quat(rotz(context.magnetic.declination));
    qTrueToMagnetic = quatinv(qMagneticToTrue);

    filter.MagRef = quatrotate(qTrueToMagnetic, context.magnetic.vector);
    filter.AccRef = quatrotate(qTrueToMagnetic, context.gravity.vector); % Should do nothing

    filter.MagRef(abs(filter.MagRef) < 1e-12) = 0;
    filter.AccRef(abs(filter.AccRef) < 1e-12) = 0;

    if sum(abs(filter.MagRef) > 0) ~= 2 || sum(abs(filter.AccRef) > 0) ~= 1
        error('Reference vectors are not well constructed'); % This should never happen
    end
end

It is the vector MagRef that ends up being constructed wrong, as I temporarily removed the AccRef condition - the error still happen.

Lelelo1 commented 4 years ago

About that check, I had accidentally forgot to reset the checks after having tested dcm2quat.m dcm2quat


After making some fixes I now get a quiet good attitude with QMichelObs. My visual objects behave almost completely as they should, and tilting up with device to go into camera view works So everything seems to work more for less, with CordinateSystem.ENU.

Putting mock places to 0-2 deg north, these are continuously being shown around 20-30 deg to the right though - with QMichelObs. When I switch back to my previous Madgwick implementation the mock places are shown to the north.

I assume there still could be something wrong in the translation, or I guess the difference could be because I still use the OS calibration on the sensor data?

Putting mock places south, they end up being shown in the west with the QMichelObs translation. (And in south with my previous madwgick implementation). They are displayed correct height wise. Also the text is basically displayed correctly and rotates with the device [protrait] <-> [landscape] as it should.

Lelelo1 commented 4 years ago

About that check my MagRef still don't pass it. It assumes the value of 3, when it should be 2. I have traced it to the declination.

The declination of the matlab source code end up being -2.1241 when it's time to...

% Let's define MagRef and AccRef temporarly in Earth Magnetic Field frame

My declination is -4.19322488655381 at that point. And when the declination in the matlab source code is set to that prior to setting up MagRef - it also end up being a value of 3 in the check.


However I also noticed MagRef is not created with i'ts x-component sufficiently near 0 in my translation - even when using the matlab values as input for the method.

ThibaudM commented 4 years ago

geoMagRes:

geoMagRes

(The date there is old because that particular package hasen't been updated with latest world magnetic model data)

QMagneticTue:

QMagneticToTrue

Regarding your data, it seems your WMM library is reporting values in NED coordinates, so you have to convert them to ENU (at least the vector and the declination) if you want to keep coherence through the project.

To summarize:

Then, in generateAttitude.m:

qMagneticToTrue = [W: 0.9997, X: 0, Y: 0, Z: 0.0248]
qTrueToMagnetic = [W: 0.9997, X: 0, Y: 0, Z: -0.0248]
filter.MagRef = [X: 0, Y: 16.1641, Z: -47.9758]
Lelelo1 commented 4 years ago

So it seems the setup prior to using the algorithm is not the problem.

I found I could use the most recent wmm from the api as well.

I get this MagRef = [-0.8252 22.8256 -41.3634] , (with this location: 57.7027141, 11.916687), both in the c# translation and in the matlab source code

So I end up with this

MagRef  = [-7.2347985380361E-09, 16.1567587391275, -48.267143333836]

Notice E-09 - as it is currently required that the component should be at least 1e-12 or smaller..?

ThibaudM commented 4 years ago

Do not worry, -7.2347985380361E-09 is ok ;) The goal here is to verify if MagRef.x is close to 0. 1e-12 is good for Matlab operations but it seems to be too low for your C# implementation.

Lelelo1 commented 4 years ago

Do not worry, -7.2347985380361E-09 is ok ;)

Ok!

Lelelo1 commented 4 years ago

When it comes to the sensordata I assume these should be given as they are. enu and ned only matter for the ref vectors and for the outputted attitude? Previously using a C# version of Madgwick I had to...

sensorVectorX = y;
sensorVectorY = -x;
sensorVectorZ = z

// ... sensor vector used in algorithm update

But I was not aware of the (2) most common coordinate system you describe. I think that operation in this circumstance resulted in a quaternion in the style of the standard os attitude - which to my understanding must be enu?

It says in visualiseAttitudeOnSpecificDataset.m that the data set is in enu. Presumably no manipulation of the raw sensor data has been made.

Looking at how the native sensor data is extracted in Xamarin.Essentials - it is there for some reason made differently in case of the accelerometer depending on the platform:

Accelorometer

// iOS
var accelData = new AccelerometerData(field.X * -1, field.Y * -1, field.Z * -1);
// Android
var gravity = gravity = 9.81;
var data = new AccelerometerData(e.Values[0] / gravity, e.Values[1] / gravity, e.Values[2] / gravity);

Difference betweenQMichelObs.cs and QMichelObs.m

Running one first row of sensor data as update, and second row into update I get

// w x y z
-0.207312917472391, -0.0444969475212587, 0.196754267945632, 0.957250823269538

with the translated QMichelObs.cs. The matlab QMichelObs.m. with the same data gives

% (w, x, y, z)
-0.2215   -0.0443    0.1978    0.9539

My progress so far

I made sure the projection in my app which uses a game coordinateesystem receives it's attitude in enu - meaning I can swap between the c# version of Madgwick from x-io Technologies which I have used previously and the translation of QMichelObs.m.

Current observed differences between QMichelObs.cs and Madgwick.cs from x-io Technologies

There is instability using QMichelObs where twisting the device around a lot in different axises - displaces my AR objects that are given north bearing, by 50-90 degrees off. It then takes time (roughly 25 seconds) for them to move back to their position. The same twisting does not cause displacement of objects when using Madgwick.

Lelelo1 commented 4 years ago

Its much more stable on my iPhone11, however both the translated QMichelObs - and my newly translated from matlab: Madgwick - drifts right. And the app's visual objects jumps up and down a bit with the translated Madgwick - which I think is related to the beta value.

Lelelo1 commented 4 years ago

I have a question about the datasets. Looking in the android folder, there is calib.acc.device, calib.gyr.device, calib.mag.device. Which can look like...

calib_acc_Nexus5_d2

I don't see accelerometer-calibrated?

ThibaudM commented 4 years ago

When it comes to the sensordata I assume these should be given as they are. enu and ned only matter for the ref vectors and for the outputted attitude?

True

Previously using a C# version of Madgwick I had to...

sensorVectorX = y;
sensorVectorY = -x;
sensorVectorZ = z

// ... sensor vector used in algorithm update

But I was not aware of the (2) most common coordinate system you describe. I think that operation in this circumstance resulted in a quaternion in the style of the standard os attitude - which to my understanding must be enu?

NED is mostly used for aerial vehicles (UAVs, aircrafts, satellite...) whereas ENU is mostly used for ground vehicles/objects (robots, cars, smartphones). The reason is developers prefer to have a positive value on z-axis. Fortunately, smartphone manufacturers use the same coordinates system: ENU.
Madgwick algorithm is not designed for a specific vehicle/object so you can use it with both coordinate systems. However, From what I remember, the public source code of Madgwick algorithm uses NED coordinates system, and you cannot find the reference vectors because the jacobian matrix is optimized for NED. That is why you had to change the sensor output with the sensorVector trick.

It says in visualiseAttitudeOnSpecificDataset.m that the data set is in enu. Presumably no manipulation of the raw sensor data has been made.

Looking at how the native sensor data is extracted in Xamarin.Essentials - it is there for some reason made differently in case of the accelerometer depending on the platform:

Accelorometer

// iOS
var accelData = new AccelerometerData(field.X * -1, field.Y * -1, field.Z * -1);
// Android
var gravity = gravity = 9.81;
var data = new AccelerometerData(e.Values[0] / gravity, e.Values[1] / gravity, e.Values[2] / gravity);

Yeah that is funny too, iOS considers acceleration on the z-axis as its opposite. I do the same trick than Xamarin here

Difference betweenQMichelObs.cs and QMichelObs.m

Running one first row of sensor data as update, and second row into update I get

// w x y z
-0.207312917472391, -0.0444969475212587, 0.196754267945632, 0.957250823269538

with the translated QMichelObs.cs. The matlab QMichelObs.m. with the same data gives

% (w, x, y, z)
-0.2215   -0.0443    0.1978    0.9539

My progress so far

I made sure the projection in my app which uses a game coordinateesystem receives it's attitude in enu - meaning I can swap between the c# version of Madgwick from x-io Technologies which I have used previously and the translation of QMichelObs.m.

Current observed differences between QMichelObs.cs and Madgwick.cs from x-io Technologies

There is instability using QMichelObs where twisting the device around a lot in different axises - displaces my AR objects that are given north bearing, by 50-90 degrees off. It then takes time (roughly 25 seconds) for them to move back to their position. The same twisting does not cause displacement of objects when using Madgwick.

That is not an easy part but all algorithms can be tuned with parameters to get the best of each. The "25-sec convergence" can be reduced if you trust less the gyroscope in the Kalman algorithm.

ThibaudM commented 4 years ago

I have a question about the datasets. Looking in the android folder, there is calib.acc.device, calib.gyr.device, calib.mag.device. Which can look like...

calib_acc_Nexus5_d2

I don't see accelerometer-calibrated?

Because Android does not provide an "accelerometer-calibrated" value. That is why I created a specific dataset each day for the "accelerometer calibration". But, as you can see in this table, accelerometer calibration does not have a huge impact on the output quaternion.

ThibaudM commented 4 years ago

To have an idea of the rendering of MichelObs and a native filter, have a look here: https://www.youtube.com/watch?v=pKCOfHVTwIU and https://www.youtube.com/watch?v=_un8dfGPpNA

Lelelo1 commented 3 years ago

First of all, sorry for being late with this response.

My free trial of matlab has ended. But I am considering getting a license - so that I can continue translating and control existing translated algorithms. Then, to be totally sure - I would have to generate multiple quaternions in matlab and save it as a text file. Then run C# version and see if the quaternions are the same.

About android there is in fact calibrated/uncalibrated accelerometer present . Screenshot 2020-08-19 at 20 59 36 But it might not have been so some years ago.

When it comes to parrying magnetic distortion, I am slightly worried with this procedure: https://github.com/tyrex-team/benchmarks-attitude-smartphones/blob/master/src/Filters/Implementations/QMichelObsExtmagWtRep.m#L44 If there has never been any valid values (yet) it can't replay those, which means a non working ahrs during this period?

ThibaudM commented 3 years ago

About android there is in fact calibrated/uncalibrated accelerometer present . Screenshot 2020-08-19 at 20 59 36 But it might not have been so some years ago.

I just had a look on it and you are right, they "recently" added an "AccelerometerUncalibrated" field

When it comes to parrying magnetic distortion, I am slightly worried with this procedure: https://github.com/tyrex-team/benchmarks-attitude-smartphones/blob/master/src/Filters/Implementations/QMichelObsExtmagWtRep.m#L44 If there has never been any valid values (yet) it can't replay those, which means a non working ahrs during this period?

Not exactly, in fact, during this period (when the value is upper than the threshold), the new quaternion is generated only using the gyroscope and the accelerometer. The trick is here, magUpdate is set to 0, so the magnetometer weight in the prediction is 0 too.

Lelelo1 commented 3 years ago

I've tried turning off the magnetometer. In that situation there is no absolute reference - so the items in my app is shown differently depending on the initial device frame.

Also, I have looked more closely on magnetometer calibration - and I wonder, can't the sphere be constructed with WMM vector? That might lead to a completely pure magnetic measurement: https://github.com/hightower70/MagCal/issues/1 ?

ThibaudM commented 3 years ago

I've tried turning off the magnetometer. In that situation there is no absolute reference - so the items in my app is shown differently depending on the initial device frame.

That is the normal behavior ;)

Also, I have looked more closely on magnetometer calibration - and I wonder, can't the sphere be constructed with WMM vector? That might lead to a completely pure magnetic measurement: hightower70/MagCal#1 ?

The WMM for the magnetometer calibration, as far as I know, can only be used to grow or shrink the sphere. (see src/Calibration/Magnetometer/retrieveParametersFromMagnetometerCalibration.m#L21)

Lelelo1 commented 3 years ago

That is the normal behavior ;)

It is just in my case, there is slight risk that the user will be showed invalid visual UI elements during time using that time:/ (It relies on magnetometer to position them.)

The WMM for the magnetometer calibration, as far as I know, can only be used to grow or shrink the sphere

Should it not be someway that:

var distortion = messuredVector - magRef

and then

It says: https://github.com/kritiksoman/Magnetometer-Calibration

As the user moves the mobile in the specific motion, the data from the magnetometer is fit into a sphere. The center of the sphere is then subtracted from the subsequent sensor data to get the calibrated values.

So constructing a sphere with magRef, and subtracting all magnetometer measurements - could possibly create valid magnetometer values at all time? What I don't understand with the sphere subtracting though is the "center". Is the center half of the magRef vector...?

ThibaudM commented 3 years ago

That is the normal behavior ;)

It is just in my case, there is slight risk that the user will be showed invalid visual UI elements during time using that time:/ (It relies on magnetometer to position them.)

True. Maybe you can provide a feedback to the user until it is not in an area without magnetic distortions. Anyway, the calibration phase (if you want to consider soft distortions and MagRef norm in your model) must be done in a space without magnetic perturbations.

The WMM for the magnetometer calibration, as far as I know, can only be used to grow or shrink the sphere

Should it not be someway that:

var distortion = messuredVector - magRef

I am not sure to understand what you are talking about. Vectors? Vectors' norm? Distortions?

and then

It says: https://github.com/kritiksoman/Magnetometer-Calibration

As the user moves the mobile in the specific motion, the data from the magnetometer is fit into a sphere. The center of the sphere is then subtracted from the subsequent sensor data to get the calibrated values.

So constructing a sphere with magRef, and subtracting all magnetometer measurements - could possibly create valid magnetometer values at all time? What I don't understand with the sphere subtracting though is the "center". Is the center half of the magRef vector...?

You do not construct a sphere with magRef (magRef is fixed by WMM given a {lat, lng, alt, time}) but with the magnetometer measurements. When you obtain your ellipsoid from the magnetometer calibration,

Lelelo1 commented 3 years ago

I am not sure to understand what you are talking about. Vectors? Vectors' norm? Distortions?

It's just that the wmm vector is always present in the measurement. So therefore it should be possible to know where all the distortion is coming from? If I have understood basic physics vector teachings in school, the measurement is a total of all magnetic forces involved:

var total = magRef + distortion

Also, the wmm vector is always present. And it is a sphere. So I I don't really understand why calibration can't be done against the sphere of MagRef instead?

Thank you for the details, the calibration concepts is more understandable now.

ThibaudM commented 3 years ago

Ok, so you cannot do that with vectors directly. Vectors are not coming from the same coordinate system (Local Tangent Plane frame [sometimes called "World frame"] for MagRef vs Device frame for Magnetometer measurements).

However, you can use this formula with vectors norms

Lelelo1 commented 3 years ago

Test directing the device north with as little surrounding magnetic disturbance as possible. I could see magRef(only that the norm of it being a bit different). When I rotated the MagRef vector in code -90 degrees (enU), I got the same values as pointing my device east.

(that was with device os's calibration)


Still, if you have an environment cleared of magnetic disturbance like how the experiments where made - won't the MagRef vector be present somewhere in the raw magnetometer sensor data?

Lelelo1 commented 3 years ago

The WMM for the magnetometer calibration, as far as I know, can only be used to grow or shrink the sphere. (see src/Calibration/Magnetometer/retrieveParametersFromMagnetometerCalibration.m#L21)

Here is an implementation I found with magnetometer calibration and wmm: https://github.com/PX4/Firmware/blob/master/src/modules/commander/mag_calibration.cpp#L904 Inside the second if statement (when mag_earth_available true) it does this:

const Vector3f expected_field = Dcmf(euler).transpose() * mag_earth_pred;

...and mag_earth_predis set up like:

mag_earth_pred = Dcmf(Eulerf(0, -mag_inclination_gps, mag_declination_gps)) * Vector3f(mag_strength_gps, 0, 0);

In the do_mag_calibration_quick method. Could setting up mag_earth_available there could just be a calculation of MagRef?

It uses wmm in more in mag_calibrate_all method as well in the file:

for (size_t cur_mag = 0; cur_mag < MAX_MAGS; cur_mag++) {
sphere_radius[cur_mag] = mag_strength_gps;
}

Which I believe would same the as the shrinking of the sphere you mentioned.

The short calibration method implementation was not very applicable for me though as it requires a prequest (accuarte) heading. I think it is more meant as an on the go calibration - but it still contain some interesting wmm code.


ThibaudM commented 3 years ago

Still, if you have an environment cleared of magnetic disturbance like how the experiments where made - won't the MagRef vector be present somewhere in the raw magnetometer sensor data?

About the hard iron distortions => no because you only remove the values which are in the same frame of the sensor About the soft iron distortions => you try to average your measurements to make a sphere from an ellipsoid, so you have some risks to remove a part of MagRef measurements. Moreover, this part of the calibration is really sensitive to your device position. If you are outdoor, the soft iron distortions vector should be null. If you are indoor and in the presence of magnetic perturbations, your soft calibration will change a lot if you move. That is why I'm not particularly eager to apply soft iron distortions. From my knowledge, the Android calibration only considers the hard iron distortions too.

If you want further information, I recommend this paper: https://www.hindawi.com/journals/js/2010/967245/

Which I believe would same the as the shrinking of the sphere you mentioned.

It seems.

I think it is more meant as an on the go calibration - but it still contain some interesting wmm code.

Do not forget; the WMM is still mandatory to transform your attitude from the Magnetic North Frame to the True North Frame.

Lelelo1 commented 3 years ago

There are a bunch of least squares fit in MathNet (C# lib). But they all return a tuple, with slope and intercept - so I don't understand how to use them (having vectors with x y z). I just connected this to previous learnt basic math y=mx+b where m is slope and b is intercept. (In Sweden it is taught y=kx+m)

Is it any chance any of them are similar to the one mentioned article and could be useful?

ThibaudM commented 3 years ago

I am not sure we are talking about the same thing, but, if you are looking for an algorithm to retrieve the ellipsoid you have to find a code to fit an ellipsoid, e.g. https://skotagiri.wordpress.com/2010/06/19/c-implementation-for-fitting-an-ellipse-for-a-set-of-points (I did not test).

Lelelo1 commented 3 years ago

Thanks I can probably try that out. Something I have not fully understood is using live data with ellipsoid fitting. The construction of the ellipsoid often seem to require a set of data. Is it during calibration (moving device by hand) these are gathered? Also why can't I construct a MagRef sphere and compare against that? Also I have noticed it is 2D points not 3D.

Lelelo1 commented 3 years ago

I have decided that I will move on with my app project without using the most ideal magnetometer and ahrs setup. I lack too much of the scientific expertise and mathematical knowledge to implement special calibrations and some filters. Many android devices don't have a magnetometer, those that do seem be worse than those on iPhone. So I will instead mainly target iPhones instead. Thanks a lot ThibaudM for all you valuable information and help.

Lelelo1 commented 3 years ago

Hello again. I saw a big improvement in the os attitude on iOS and decided to go with it instead. The app has been out for 2 months with 15 unique downloads. So far there have not been any feedback from users. But I have noticed some problems in my own town in certain places with it. The os attitude is ignoring things like a metal fork near the sensor though - which made it temping to use it.

Either way I am looking for a better alternative in case the magnetic disturbances causes to much inaccuracy.

To my question: Do you think machine learning can be used to predict appropriate earth magnetic field measurements in measurements that have disturbance? I stumbled upon this but I might have been written som inaccuracy there - and I don't know for certain if would be of any use.

ThibaudM commented 3 years ago

Hello, and sorry for the late answer

As you noticed, the filter alone is far to be perfect. The magnetometer calibration in a good context is really important if you have a look at the document here: http://tyrex.inria.fr/mobile/benchmarks-attitude/ (Table 4) The proposed filter shows an accuracy of 5.9° with a custom calibration and 15.1° with the system's calibration. So you can almost conclude that a good calibration at a good moment is more important than the design of the filter used.

I do not know in which context you need an AHRS, but in a real app, you often fuse it with other sensors to improve the accuracy. (ie. at Wemap, we need attitude estimation for AR/Map navigation: https://blog.getwemap.com/geo-ar-the-challenges-of-navigation-from-the-web-browser-79eaaf6eab3f)

About ML, I have no idea.

Lelelo1 commented 3 years ago

I spoke to the a ceo of ESPrtk, as I found this video: https://www.youtube.com/watch?v=Udo9jRyJD1A&t=81s He told me they had tried out a machine learning approach for calibration - but it was too expensive for the proccesor of the chip they build. So they ended up with a C algorithm. I have not tried their calibration by their chip yet.

Yea I am suing the ahrs in my app, I forgot to provide a link: https://apps.apple.com/se/app/seeknav/id1537320921. (There is video when opening on an phone, and i'ts only iOS for now) When fusing it will mainly effect the accuracy while in movement, right - or will standing still improve as well, when it comes to heading accuracy?

ThibaudM commented 3 years ago

I just want to clarify a point about the calibration process. From my point of view, using IA or a mathematical approach to calibrate the magnetometer will not solve the whole approach of the AR/Navigation because of :

When fusing it will mainly effect the accuracy while in movement, right - or will standing still improve as well, when it comes to heading accuracy?

You are right, our correction is made if the user does some steps.