rev |
line source |
nuclear@3
|
1 /************************************************************************************
|
nuclear@3
|
2
|
nuclear@3
|
3 PublicHeader: OVR.h
|
nuclear@3
|
4 Filename : Util_MagCalibration.h
|
nuclear@3
|
5 Content : Procedures for calibrating the magnetometer
|
nuclear@3
|
6 Created : April 16, 2013
|
nuclear@3
|
7 Authors : Steve LaValle, Andrew Reisse
|
nuclear@3
|
8
|
nuclear@3
|
9 Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
|
nuclear@3
|
10
|
nuclear@3
|
11 Use of this software is subject to the terms of the Oculus license
|
nuclear@3
|
12 agreement provided at the time of installation or download, or which
|
nuclear@3
|
13 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@3
|
14
|
nuclear@3
|
15 *************************************************************************************/
|
nuclear@3
|
16
|
nuclear@3
|
17 #ifndef OVR_Util_MagCalibration_h
|
nuclear@3
|
18 #define OVR_Util_MagCalibration_h
|
nuclear@3
|
19
|
nuclear@3
|
20 #include "../OVR_SensorFusion.h"
|
nuclear@3
|
21 #include "../Kernel/OVR_String.h"
|
nuclear@3
|
22 #include "../Kernel/OVR_Log.h"
|
nuclear@3
|
23
|
nuclear@3
|
24 namespace OVR { namespace Util {
|
nuclear@3
|
25
|
nuclear@3
|
26 class MagCalibration
|
nuclear@3
|
27 {
|
nuclear@3
|
28 public:
|
nuclear@3
|
29 enum MagStatus
|
nuclear@3
|
30 {
|
nuclear@3
|
31 Mag_Uninitialized = 0,
|
nuclear@3
|
32 Mag_AutoCalibrating = 1,
|
nuclear@3
|
33 Mag_ManuallyCalibrating = 2,
|
nuclear@3
|
34 Mag_Calibrated = 3
|
nuclear@3
|
35 };
|
nuclear@3
|
36
|
nuclear@3
|
37 MagCalibration() :
|
nuclear@3
|
38 Stat(Mag_Uninitialized),
|
nuclear@3
|
39 MinMagDistance(0.2f), MinQuatDistance(0.5f),
|
nuclear@3
|
40 SampleCount(0)
|
nuclear@3
|
41 {
|
nuclear@3
|
42 MinMagDistanceSq = MinMagDistance * MinMagDistance;
|
nuclear@3
|
43 MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
|
nuclear@3
|
44 MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
|
nuclear@3
|
45 MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
|
nuclear@3
|
46 MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
|
nuclear@3
|
47 MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
|
nuclear@3
|
48 }
|
nuclear@3
|
49
|
nuclear@3
|
50 // Methods that are useful for either auto or manual calibration
|
nuclear@3
|
51 bool IsUnitialized() const { return Stat == Mag_Uninitialized; }
|
nuclear@3
|
52 bool IsCalibrated() const { return Stat == Mag_Calibrated; }
|
nuclear@3
|
53 int NumberOfSamples() const { return SampleCount; }
|
nuclear@3
|
54 int RequiredSampleCount() const { return 4; }
|
nuclear@3
|
55 void AbortCalibration()
|
nuclear@3
|
56 {
|
nuclear@3
|
57 Stat = Mag_Uninitialized;
|
nuclear@3
|
58 SampleCount = 0;
|
nuclear@3
|
59 }
|
nuclear@3
|
60
|
nuclear@3
|
61 void ClearCalibration(SensorFusion& sf)
|
nuclear@3
|
62 {
|
nuclear@3
|
63 Stat = Mag_Uninitialized;
|
nuclear@3
|
64 SampleCount = 0;
|
nuclear@3
|
65 sf.ClearMagCalibration();
|
nuclear@3
|
66 };
|
nuclear@3
|
67
|
nuclear@3
|
68 // Methods for automatic magnetometer calibration
|
nuclear@3
|
69 void BeginAutoCalibration(SensorFusion& sf);
|
nuclear@3
|
70 unsigned UpdateAutoCalibration(SensorFusion& sf);
|
nuclear@3
|
71 bool IsAutoCalibrating() const { return Stat == Mag_AutoCalibrating; }
|
nuclear@3
|
72
|
nuclear@3
|
73 // Methods for building a manual (user-guided) calibraton procedure
|
nuclear@3
|
74 void BeginManualCalibration(SensorFusion& sf);
|
nuclear@3
|
75 bool IsAcceptableSample(const Quatf& q, const Vector3f& m);
|
nuclear@3
|
76 bool InsertIfAcceptable(const Quatf& q, const Vector3f& m);
|
nuclear@3
|
77 // Returns true if successful, requiring that SampleCount = 4
|
nuclear@3
|
78 bool SetCalibration(SensorFusion& sf);
|
nuclear@3
|
79 bool IsManuallyCalibrating() const { return Stat == Mag_ManuallyCalibrating; }
|
nuclear@3
|
80
|
nuclear@3
|
81 // This is the minimum acceptable distance (Euclidean) between raw
|
nuclear@3
|
82 // magnetometer values to be acceptable for usage in calibration.
|
nuclear@3
|
83 void SetMinMagDistance(float dist)
|
nuclear@3
|
84 {
|
nuclear@3
|
85 MinMagDistance = dist;
|
nuclear@3
|
86 MinMagDistanceSq = MinMagDistance * MinMagDistance;
|
nuclear@3
|
87 }
|
nuclear@3
|
88
|
nuclear@3
|
89 // The minimum acceptable distance (4D Euclidean) between orientations
|
nuclear@3
|
90 // to be acceptable for calibration usage.
|
nuclear@3
|
91 void SetMinQuatDistance(float dist)
|
nuclear@3
|
92 {
|
nuclear@3
|
93 MinQuatDistance = dist;
|
nuclear@3
|
94 MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
|
nuclear@3
|
95 }
|
nuclear@3
|
96
|
nuclear@3
|
97 // A result of the calibration, which is the center of a sphere that
|
nuclear@3
|
98 // roughly approximates the magnetometer data.
|
nuclear@3
|
99 Vector3f GetMagCenter() const { return MagCenter; }
|
nuclear@3
|
100 // Retrieves the full magnetometer calibration matrix
|
nuclear@3
|
101 Matrix4f GetMagCalibration() const;
|
nuclear@3
|
102 // Retrieves the range of each quaternion term during calibration
|
nuclear@3
|
103 Quatf GetCalibrationQuatSpread() const { return QuatSpread; }
|
nuclear@3
|
104 // Retrieves the range of each magnetometer term during calibration
|
nuclear@3
|
105 Vector3f GetCalibrationMagSpread() const { return MagSpread; }
|
nuclear@3
|
106
|
nuclear@3
|
107 private:
|
nuclear@3
|
108 // Determine the unique sphere through 4 non-coplanar points
|
nuclear@3
|
109 Vector3f CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
|
nuclear@3
|
110 const Vector3f& p3, const Vector3f& p4);
|
nuclear@3
|
111
|
nuclear@3
|
112 // Distance from p4 to the nearest point on a plane through p1, p2, p3
|
nuclear@3
|
113 float PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
|
nuclear@3
|
114 const Vector3f& p3, const Vector3f& p4);
|
nuclear@3
|
115
|
nuclear@3
|
116 Vector3f MagCenter;
|
nuclear@3
|
117 unsigned Stat;
|
nuclear@3
|
118 float MinMagDistance;
|
nuclear@3
|
119 float MinQuatDistance;
|
nuclear@3
|
120 float MinMagDistanceSq;
|
nuclear@3
|
121 float MinQuatDistanceSq;
|
nuclear@3
|
122 // For gathering statistics during calibration
|
nuclear@3
|
123 Vector3f MinMagValues;
|
nuclear@3
|
124 Vector3f MaxMagValues;
|
nuclear@3
|
125 Vector3f MagSpread;
|
nuclear@3
|
126 Quatf MinQuatValues;
|
nuclear@3
|
127 Quatf MaxQuatValues;
|
nuclear@3
|
128 Quatf QuatSpread;
|
nuclear@3
|
129
|
nuclear@3
|
130 unsigned SampleCount;
|
nuclear@3
|
131 Vector3f MagSamples[4];
|
nuclear@3
|
132 Quatf QuatSamples[4];
|
nuclear@3
|
133
|
nuclear@3
|
134 };
|
nuclear@3
|
135
|
nuclear@3
|
136 }}
|
nuclear@3
|
137
|
nuclear@3
|
138 #endif
|