Quaternons, different values for same orientation
I am using a MetaMotionR to determine the direction my sensor is facing. I am trying to use quaternions to determine this, but I am not getting consisten values. It feels like the sensor decides on a set of values that it should relate to and keeps them for a while, and then it changes randomly and keeps those values. Sometimes it returns to the same values it seems. I am making my own app in visualstudio with c#, but I’ve used metabase to make some tests and I got the same problem there.
For the same setup between computer and sensor in the same gathering session in metabase I got values of (w,x,y,z)=(0.3, -0.65, 0.3, 0.65) and just a minute after I got (w,x,y,z)=(0.68, -0.26, 0.64, 0.29), after moving the sensor around some and then putting it back into the same position.
Am I doing something wrong or have I perhaps missinterpreted the function of quaternions?
Comments
I have now calibrated the board.
Is it not possible to have an absolute orientation? I want to be able to connect to different boards, and each board should always point me in a known offset from north. Not only the relative offset from the time I connect to that board.
What sensor fusion mode are you using
I am using Ndof, I've also tried with Imuplus.
Stick with NDoF.
It's possible you saturated the acc and gyro data. What are the acc and gyro data ranges?
I am using "sensorFusionBosch.Configure(Mode.Ndof, AccRange._2g, GyroRange._2000dps);"
So acc range should be 2g and gyro range 2000dps.
Try the higher modes (16g), as Eric mentioned, you are likely saturating the data.
I tried with 16g, still not working. I will add some additional information what I am doing and experiencing, hopefully it will help in figuring out what my problem is.
I am using a switch button to start and stop the data streaming, like such:
sensorFusionBosch.Quaternion.Start();
sensorFusionBosch.Start();
to start and
sensorFusionBosch.Stop();
sensorFusionBosch.Quaternion.Stop();
to stop.
Whenever I stop, change the orientation of the sensor and then start again, the new orientation will have the same values as prior to stop and start if I only rotated around the gravitational axis. However, if I rotate it any other way, the values will change. Whatever I do, a horizontal state will always be shown that it is horizontal, but north direction will vary. I use the "double"s:
front_y = 2 * (y * z - w * x);
front_z = -(1 - 2 * (x * x + y * y));
left_z = -(2 * (y * z + w * x));
"Compass like orientation" is represented by"front_y" and tilting of the horizontal plane is represented by "front_z" and "left_z".
If I leave the streaming on and change the oriention of the sensor, the "front_y" value will take somewhere around 10-30 seconds to stabilize, while "front_z" and "left_z" will stabilize practically immediatly. I have understood that the magnetometer has a maximum stream frequency of 25 Hz and the acc/gyro 100 Hz.
Can you do something simple and post data? Turn on the sensor fusion, rotate the device on a flat surface 360 and share the data you get.
You are trying to troubleshoot your sensor doing something too complicated. Make sure it works in idle and doing simple things first. Then you can try to do something more complicated after that.
The textfile contains values which are collected from my app using c# in visual studio. I rotate the device 90 degrees and then wait abit for it to stabilze and take those values, and then rotate another 90 degrees and so on until 360 degrees. The other two files are collected with MetaBase, one rotating the same way as my app, 90 degrees and waiting for stabilization for a few seconds until 360 degrees total and the other one an as smooth 360 degree spin as I could manage with my hand.
This looks fine, what is the issue?
In the 2 excel files I last posted the sensor is going throught the same motion, a full 360 degree spin around the gravitional axis. The only difference is that one is paused every 90 degrees and the other one is not. What I would expect is similar values for all four w, x, y and z. They start and end at similar values, but in between they are very different.
If I look at for example the x signal, it goes smoothly from +0.7 to -0.7 during the smooth spin. Looking at the signal, I would say a value of either +0.7 or -0.7 corresponds to the start position and something close to 0 would correspond to a 180 degree rotation, while values of roughly +0.35 would be facing left and -0.35 would be facing right. Also positive values are facing somewhat left and negative values are facing more right.
During the paused spin it spikes down to at the lowest +0.25, which by my theory says it never looks right at all. In the paused state it returns to values between +0.6 and +0.7, which is close to the starting value.
Doesn't a specific set of the 4 quaternion values correspond to a single specific orientation?
I seem to have a related issue. Possibly the same. See: https://mbientlab.com/community/discussion/3183/sensor-fusion-reference-frame
Using NDoF, 2000dps, 16G. Really slow movements only.
https://blog.mide.com/quaternions-for-orientation
Hi @jonteberg,
What process are you using to calibrate the sensor fusion? When starting and stopping the sensor fusion subsystem, the calibration will be lost if it is not explicitly read out and loaded in.
Could you share some raw magnetometer from your sensor, in the configuration used with NDoF? It appears that on a short time interval the rotation is correct (most likely using gyroscope data), but over longer intervals the values fall back. This seems related the the magnetometer, and could be raw data or calibration related.
How are the peripherals on your MMR set up?
Regards,
Matt
First I connect then: IMacro.EraseAll(), then disconnect. I then connect again and do the following:
var cts = new CancellationTokenSource();
ImuCalibrationData caliData = await sensorFusionBosch.Calibrate(cts.Token);
ImuCalibrationState caliState = await sensorFusionBosch.ReadCalibrationStateAsync();
Debug.WriteLine(caliData);
Debug.WriteLine(caliState);
sensorFusionBosch.Stop();
macro.StartRecord(true);
sensorFusionBosch.WriteCalibrationData(caliData);
await macro.EndRecordAsync();
sensorFusionBosch.Start();
I assume then that the macro is read automatically when I connect again.
I use the following code snippet to collect raw data in the file I add as magnet_spin, I am rotating the device 90 degrees at a time with a small pause until 360 degrees then I am doing some "smooth" 360 degrees spíns.
await magnet.PackedMagneticField.AddRouteAsync(source => source.Stream(async data => {
var value = data.Value();
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
double aX = value.X;
double aY = value.Y;
double aZ = value.Z;
Debug.WriteLine(aX + "," + aY + "," +
});
}));
I also recorded using MetaBase app, and got similar results. I add the file with the produced name by MetaBase.
I've used double sided tape to attach the MMR to a wooden cube, it should be a standard MMR with no extra attachments. See picture.
Hey @Matt,
I still do get different oriention of the sensor for a quaternion of (w,x,y,z) = (1,0,0,0).
This is my current calibration code:
var cts = new CancellationTokenSource();
ImuCalibrationData caliData = await sensorFusionBosch.Calibrate(cts.Token);
sensorFusionBosch.Stop();
sensorFusionBosch.Quaternion.Stop();
(exluding the part where I eraseAll and disconnect/reconnect). If I for example get a 1 in the output, then there should be 2 macro commands saved on the unit, correct? (The first one would be editing the advertising name of the device "settings.EditBleAdConfig(newName);")
If I then call after each time I stop the streaming and would like to start it again, I can call:
sensorFusionBosch.Quaternion.Start();
sensorFusionBosch.Start();
macro.Execute(1);
so that the calibration will be explicitly read in after I start the streaming?
Then if you have a look at the magnetometer data in my last post, I would guess that the data is in the order of magnitude of earth magnetic field so there shouldn't be any major disturbances?
Regards,
Jonathan