SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
MagnetometerUtils.hpp
Go to the documentation of this file.
1
31#pragma once
32
33#include "SensorDefs.hpp"
34
35
36// *INDENT-OFF*
38{
46 inline float dmsToDecimalDegrees(int degrees, int minutes, float seconds = 0.0f)
47 {
48 float sign = (degrees < 0 || (degrees == 0 && (minutes < 0 || seconds < 0))) ? -1.0f : 1.0f;
49 return sign * (abs(degrees) + minutes / 60.0f + seconds / 3600.0f);
50 }
51
55 inline float dmsToRadians(int degrees, int minutes, float seconds = 0.0f)
56 {
57 return dmsToDecimalDegrees(degrees, minutes, seconds) * M_PI / 180.0f;
58 }
59
74 inline float calculateHeading(const MagnetometerData& data, float declination = 0.0f)
75 {
76 const auto& mag = data.magnetic_field;
77
78 // Handle edge case when magnetic field is zero or aligned vertically
79 if (mag.x == 0.0f && mag.y == 0.0f) {
80 return 0.0f;
81 }
82
83 // Calculate angle from x-axis (east) using arctangent of y/x
84 // atan2 returns angle in range [-π, π]
85 float heading = atan2f(mag.y, mag.x);
86
87 // Convert to [0, 2π) range (0 to 2π radians)
88 if (heading < 0) {
89 heading += 2 * M_PI;
90 }
91
92 // Apply magnetic declination correction
93 // Positive declination adds to heading (east declination)
94 heading += declination;
95
96 // Normalize to [0, 2π) range after declination adjustment
97 if (heading > 2 * M_PI) {
98 heading -= 2 * M_PI;
99 } else if (heading < 0) {
100 heading += 2 * M_PI;
101 }
102
103 return heading;
104 }
105
115 inline float calculateHeadingDegrees(const MagnetometerData& data, float declination_deg = 0.0f)
116 {
117 const auto& mag = data.magnetic_field;
118 if (mag.x == 0.0f && mag.y == 0.0f) {
119 return 0.0f;
120 }
121 float heading_deg = atan2f(mag.y, mag.x) * 180.0f / M_PI;
122 if (heading_deg < 0) {
123 heading_deg += 360.0f;
124 }
125 heading_deg += declination_deg;
126 if (heading_deg >= 360.0f) {
127 heading_deg -= 360.0f;
128 } else if (heading_deg < 0) {
129 heading_deg += 360.0f;
130 }
131 return heading_deg;
132 }
133
144 {
145 const auto& mag = data.magnetic_field;
146
147 // Compute Euclidean norm of the magnetic field vector
148 return sqrtf(mag.x * mag.x + mag.y * mag.y + mag.z * mag.z);
149 }
150
157 inline float gaussToMicroTesla(float gauss)
158 {
159 return gauss * 100.0f; // 1 Gauss = 100 μT
160 }
161
168 inline float microTeslaToGauss(float ut)
169 {
170 return ut * 0.01f; // 1 μT = 0.01 Gauss
171 }
172
173
174 inline float rangeToGauss(MagFullScaleRange range)
175 {
176 switch (range) {
178 return 4.0f;
180 return 8.0f;
182 return 12.0f;
184 return 16.0f;
186 return 25.0f;
188 return 30.0f;
190 return 32.0f;
191 default:
192 return 0.0f;
193 }
194 return 0.0f;
195 }
196}
197// *INDENT-ON*
@license MIT License
MagFullScaleRange
Enumeration defining full-scale range settings for the sensor.
#define M_PI
SensorMagnetometer mag(bhy)
float calculateHeadingDegrees(const MagnetometerData &data, float declination_deg=0.0f)
Calculate heading (yaw) angle from magnetometer data in degrees.
float dmsToDecimalDegrees(int degrees, int minutes, float seconds=0.0f)
Convert degrees-minutes-seconds to decimal degrees.
float dmsToRadians(int degrees, int minutes, float seconds=0.0f)
Convert degrees-minutes-seconds to radians.
float microTeslaToGauss(float ut)
Converts microTesla to Gauss.
float calculateMagneticStrength(const MagnetometerData &data)
Calculate total magnetic field strength.
float rangeToGauss(MagFullScaleRange range)
float gaussToMicroTesla(float gauss)
Converts Gauss to microTesla.
float calculateHeading(const MagnetometerData &data, float declination=0.0f)
Calculate heading (yaw) angle from magnetometer data in radians.
Structure representing magnetometer data.
SensorVector magnetic_field
magnetic field strength (Gauss)