Skip to main content
Up and Coming
May 11, 2013

Tracker DK magnetometer 2-axis, or 3?

UPDATE: I have received a replacement Rift DK, and all three magnetometer axes change as expected.

I am reading Tracker DK raw HID packets with my Raspberry Pi.

Speculation from the i-fixit teardown suggests that the Tracker DK contains a 3-axis magnetometer, and the HID packets sent from the Rift DK contain storage space for three magnetometer axes.
- Invensense MPU-6000 six-axis (gyro + accelerometer) motion tracking controller
- A983 2206—we suspect this is a three-axis magnetometer, used in conjunction with the accelerometer to correct for gyroscope drift

I like how the MPU-6000 (Tracker DK accel/gyro) has built-in sensor fusion. :D
The MPU-6000/6050 devices combine a 3-axis gyroscope and a 3-axis accelerometer on the same silicon die together with an onboard Digital Motion Processor™ (DMP™) capable of processing complex 9-axis MotionFusion algorithms. The parts’ integrated 9-axis MotionFusion algorithms access external magnetometers or other sensors through an auxiliary master I²C bus, allowing the devices to gather a full set of sensor data without intervention from the system processor

My magnetometer values in the Tracker DK HID packets have a fixed value for one axis (roll). The values only change for pitch (elevation) and yaw (heading). I am curious why one magnetometer axis contains a fixed (non-changing) value. Is that normal?

    41 replies

    Up and Coming
    May 20, 2013
    From your reply I gather that you still don't understand what a magnetometer is. You don't get geographical coordinates from that sensor ... what you get is the strength of the magnetic field around the sensor. A simple heading can be derived by calculating atan2(Mx, My) (the sensor needs to be level for this to work). For a tilt compensated calculation see the tutorial I posted earlier.

    Calibration is necessary in EVERY case for a working compass implementation, because of local disturbances. An easy calibration would be to turn the sensor around in every direction and note down the max/min values of each axis. Calibrate so that the center is 0 and you should be good. A more advanced calibration would be the one posted by homersimpson.


    P.S.: There is also a magnetic declination you have to compensate for if you want your compass to show true north. The declination depends on your location on the planet (can be found here: http://magnetic-declination.com/)
    Up and Coming
    May 21, 2013
    "Sebbi" wrote:
    From your reply I gather that you still don't understand what a magnetometer is. You don't get geographical coordinates from that sensor ...

    I *do* understand that a magnetometer measures the same magnetic field flux lines that a compass aligns to. I understand declination]magnetic declination, and how the magnetic field drifts over time. Notice how you need to enter your location AND A DATE into the NOAA declination calculator (which I have used before):
    http://www.ngdc.noaa.gov/geomag-web/#declination
    Interestingly, that calculator shows that my declination is zero-degrees (to the nearest degree)...

    My Tracker DK HID packets return numbers that are zero for both Y and Z when I point my Rift DK North, and tilt it down at 45-degrees (which corresponds to my lattitude). That is all I am saying. They sure look close enough to "geographical coordinates" to be useful for my purposes. Whether they are accurate is not so important, as long as they are continuous and predictable enough...

    I *could* adjust for offsets and scaling ranges and spherical distortion and nearby magnetic anomalies, but I just want to write some tiny and simple head-tracked demos, without needing to link to the full SDK. How can using the uncalibrated mag sensor values directly be a *bad* thing, if they are close enough, and they prevent gyro drift? It is not like I plan to navigate an extended sea voyage using the Rift as my only compass.

    Perhaps the mag sensors behave differently after they are calibrated. But on power up, my Rift DK returns Tracker DK HID packets as I described, with magY and magZ that closely match my geographical coordinates, and with a useless magX.

    I showed my relevant code, and the output results. I described what I have observed. But my (thread title) question is still unanswered for MY Rift DK, which is still only returning TWO useful axes (in its uncalibrated state). I read your link. I understand it. I plan to use it in the future when I need more accuracy. But for my immediate purposes, I do not think I need to do all that calibration. That is an informed choice on my part, not a lack of understanding. And I still do not know why only two axes of my Tracker DK are returned useful (geographical) data, and the third axis is returning an unchanging constant value.
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    Up and Coming
    May 21, 2013
    Do you have access to a windows PC or mac? You could try out the official SDK if those values change there. Regarding geographic coordinates no matter how close you think those outputs might be ... they *are* magnetic field strength measured in Tesla (or Gauss) and nothing else ;-)

    If it doesn't work with the official SDK than maybe your sensor has a defect.
    Up and Coming
    May 21, 2013
    "Sebbi" wrote:
    ... Regarding geographic coordinates no matter how close you think those outputs might be ... they *are* magnetic field strength measured in Tesla (or Gauss) and nothing else ;-)

    Yes, I understand that they are not accurate compass readings. However, they are continuous, and they are zero at (approximately) North, and the numeric values are anchored to the geographic coordinates, which makes them perfectly useful for gyro drift compensate (which is the reason WHY they are in the Tracker DK).

    If this IMU were to be used for navigation in drone aircraft, then of course you would need to convert the values to true heading values. But that is not what we are doing for games, where we only need to use these magnetic field values to compensate for gyro drift.

    I want all my code to run on my Raspberry Pi, but I will migrate part of it into an SDK-based PC app to try reading magnetic coordinates from the SDK (which initializes and calibrates the IMU). I was planning to do that anyway, after I finish my current task (adding constrained positional head tracking to MY Rift "SDK").
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    Up and Coming
    May 21, 2013
    Please tell us how you would compensate for drift with the just the raw values (without calculating a heading from them), I would be very interested in that algorithm.

    Sensor fusion gives pitch/roll/yaw in degrees and drift is usually compensated for by comparison with a source for absolute values. Pitch and roll can get those references from the accelerometer and yaw would need a heading from the magnetometer. With just the raw values - no matter how continous - there could only be some kind of reset position when the same raw values are measured again (obviously pitch/roll of the Rift have to be also the same as before), but no actual drift compensation.
    Up and Coming
    May 21, 2013
    "Sebbi" wrote:
    Please tell us how you would compensate for drift with the just the raw values (without calculating a heading from them), I would be very interested in that algorithm. ...

    Our brains can adapt to the nonlinearities (if they are even perceived). I am just anchoring my VR coordinates to mag sensor numbers at the startup position, and expecting that the mag sensor values will not drift. Plain and simple. I do not care about "real world" coordinates (yet). They can be used as anchor points for drift compensation no matter WHAT coordinate system you map them to (or even if you just use their raw unmapped values). When I get into AR, then such things will become important to me, but for now, just raw anchor points will suffice.
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    Up and Coming
    May 21, 2013
    Wouldn't that cause the yaw to be "corrected" when you tilt the Rift?
    Up and Coming
    May 21, 2013
    "Sebbi" wrote:
    Wouldn't that cause the yaw to be "corrected" when you tilt the Rift?

    I just tried that. What I discovered was VERY interesting. There is a small point in the southern sky where my magX value drops below 27958 (down to about 18000) and starts dithering like the other values. So it looks like my magX value may be getting clamped to some high value to prevent overflow. It looks like range calibration may indeed be required.

    Also, I was not concerned with roll (tilt), which many stereoscopic apps do not support. I do see that my roll does not seem to affect my magY value, but it does affect magZ, and pitch affects magY, so I can see where roll support would need that third axis. And unwanted roll could move make things get complicated with those magZ changes...

    It seems that there are no universal simple solutions here. I am glad to see that my magX value does work (at least for one very small portion of the sky). Although the magY and magZ seem to be mostly useful in their uncalibrated state, magX will certainly require calibration to stop returning that frozen (clamped) value for most of its range.

    EDIT: I am unable to repeat my experiment. I cannot find that tiny spot again, where my magX value changes. Either it is smaller than I remember, or it is intermittent.

    EDIT2: Hmm... the "active point" for my magX has shifted. Now it is north-east, pointed at the horizon, and I am confused... I think it is time to abandon this quest, and go use the calibration procedure used in the OculusVR SDK.

    EDIT3: My magX "active" point has shifted again. Now it is north at 45-degree elevation. All other directions return that reported fixed value. This drift seems strange. Why would the direction at which my magX is clamped to 27958 keep drifting?

    :?:
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    Up and Coming
    May 22, 2013
    All three axes should be varying in almost any movement. When you rotate the Rift about the vertical axis in an ideal magnetic-field-is-parallel-to-the-ground scenario, two axes will vary while one remains constant. But if you turn your Rift sideways then rotate around vertical again, two axes will vary and one will stay constant, but it will be a different axis! And in any movement which is not about an axis perfectly orthogonal to the geomagnetic field, all three axes should vary.

    That you have only two axes that vary no mater what orientation, sounds like you might have either a hardware issue (including some calibration error), or you might be pulling the wrong bits from the tracker, probably an endian and/or bit order issue (if you are using the MSB and padding values and reading them as the data for an axis, that would explain an axis that stays constant except for varying slightly when at an extreme value). Even if you were in a massive naturally occurring magnetic field, the axis that clamps would always be different depending on the orientation of the Rift.
    Up and Coming
    May 22, 2013
    "edzieba" wrote:
    ... That you have only two axes that vary no mater what orientation, sounds like you might have either a hardware issue (including some calibration error), or you might be pulling the wrong bits from the tracker, probably an endian and/or bit order issue (if you are using the MSB and padding values and reading them as the data for an axis, that would explain an axis that stays constant except for varying slightly when at an extreme value). Even if you were in a massive naturally occurring magnetic field, the axis that clamps would always be different depending on the orientation of the Rift.

    I posted the relevant code snippet above. It looks correct, and I also tested another method just like the SDK uses and it returns the same values. My Rift actually DOES return varying magX in some (rare) cases, so I think it is a magnetometer calibration issue. I am just using it after a fresh power up with no initialization. Just open the device and request HID frames...

    I will end up doing the full initialization and calibration sequence in my code later. I am struggling with accelerometer gravity vector subtraction at the moment. The Veresano "simple gravity compensation" method is not working for me at the moment (when inserted into the OculusWorldDemo app):
    http://www.varesano.net/blog/fabio/simple-gravity-compensation-9-dom-imus

    I will probably need to subtract the Euler angle gravity vector instead of the quaternion. Dealing with this quaternion stuff is new to me. I have been heavily into 2D graphics and animation (and some orthographic 2.5-D+depth map) over the years, but full 3D is teaching me some new things here. Learning new stuff is always a good thing, and helps keep the brain young and healthy...
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.