Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nhz2/xyzgeomag
Lightweight C++ header-only library for calculating the magnetic field on earth given geocentric cartesian coordinates using the World Magnetic Model(WMM). Compatible with Arduino.
https://github.com/nhz2/xyzgeomag
arduino compass
Last synced: 4 months ago
JSON representation
Lightweight C++ header-only library for calculating the magnetic field on earth given geocentric cartesian coordinates using the World Magnetic Model(WMM). Compatible with Arduino.
- Host: GitHub
- URL: https://github.com/nhz2/xyzgeomag
- Owner: nhz2
- License: mit
- Created: 2019-10-24T00:55:04.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-02-13T04:44:32.000Z (almost 2 years ago)
- Last Synced: 2023-03-01T03:36:53.999Z (almost 2 years ago)
- Topics: arduino, compass
- Language: C++
- Homepage:
- Size: 511 KB
- Stars: 5
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# XYZgeomag
[![Build Status](https://github.com/nhz2/XYZgeomag/workflows/test/badge.svg)](https://github.com/nhz2/XYZgeomag/actions)
Lightweight C++ header-only library for calculating the magnetic field on earth given geocentric cartesian coordinates using the [World Magnetic Model(WMM)](https://www.ncei.noaa.gov/products/world-magnetic-model). Compatible with Arduino.
The main function `geomag::GeoMag` calculates the magnetic field around earth in the International Terrestrial Reference System(ITRS) and uses units of decimal year, meter, and tesla.
Unlike most WMM software, which uses latitude, longitude, and altitude inputs to calculate the North East Down components of the magnetic field, `geomag::GeoMag` uses geocentric cartesian coordinates as input, and outputs the magnetic field in the same geocentric cartesian coordinate system as the inputs.
If you want to provide geodetic latitude, longitude, and height, and receive the local North East Down components of the magnetic field and the magnetic declination:
see the `geomag::geodetic2ecef` and `geomag::magField2Elements` example below.
Note that latitude and longitude are in units of degrees, and the seven magnetic elements are in units of nanotesla and degrees.## Error
XYZgeomag is within 0.5 nT of the official WMM software.
For more information on the limitations of the WMM model, see:
## Performance
XYZgeomag uses single precision floating points. It's designed to minimize ram usage for embedded systems.
| Device | Speed |
|-------------|----------|
| Arduino Uno | 52 ms |
| Raspberry Pi Pico | 6.5 ms |
| Teensy 3.6 | 83 µs |
| Teensy 4.0 | 21 µs |## Using XYZgeomag
Just download [XYZgeomag.hpp](https://github.com/nhz2/XYZgeomag/releases/download/v2.0.0/XYZgeomag.hpp) and include it.
Here is an example Arduino sketch:~~~cpp
#include "XYZgeomag.hpp"
void setup() {
// put your setup code here, to run once:
pinMode(1,INPUT);
Serial.begin(9600);
}void loop() {
// put your main code here, to run repeatedly:
int val= digitalRead(1);
geomag::Vector in;
in.x=val+1128529.6885767058f;
in.y=val+0.0;
in.z=val+6358023.736329913f;
geomag::Vector out;
int starttime=micros();
int starttimemil=millis();
out=geomag::GeoMag(2022.5,in,geomag::WMM2020);
int endtime=micros();
int endtimemil=millis();
Serial.print(out.x*1E9);
Serial.println(" nT x");
Serial.print(out.y*1E9);
Serial.println(" nT y");
Serial.print(out.z*1E9);
Serial.println(" nT z");
Serial.print("time in micro seconds: ");
Serial.println(endtime-starttime);
Serial.print("time in milli seconds: ");
Serial.println(endtimemil-starttimemil);
delay(2000);
}
~~~If you have a position in latitude, longitude, and height,
you can convert it to geocentric cartesian coordinates
with `geodetic2ecef`. Note that `geodetic2ecef` uses
single precision floats, so it will only be accurate to about 1 meter.
You can also convert the magnetic field to
the [seven magnetic elements](https://www.ncei.noaa.gov/products/world-magnetic-model)
in units of nanotesla and degrees.
~~~cpp
#include "XYZgeomag.hpp"
void setup() {
// put your setup code here, to run once:
pinMode(1,INPUT);
Serial.begin(9600);
}void loop() {
// put your main code here, to run repeatedly:
int val= digitalRead(1);
float lat = val + 43.0f; // latitude in degrees
float lon = val + 75.0f; // longitude in degrees
float height = val + 305; // height above WGS84 ellipsoid in meters
geomag::Vector position = geomag::geodetic2ecef(lat,lon,height);
geomag::Vector mag_field = geomag::GeoMag(2022.5,position,geomag::WMM2020);
geomag::Elements out = geomag::magField2Elements(mag_field, lat, lon);
Serial.print(out.north);
Serial.println(" nT north");
Serial.print(out.east);
Serial.println(" nT east");
Serial.print(out.down);
Serial.println(" nT down");
Serial.print(out.horizontal);
Serial.println(" nT horizontal");
Serial.print(out.total);
Serial.println(" nT total");
Serial.print(out.inclination);
Serial.println(" deg inclination");
Serial.print(out.declination);
Serial.println(" deg declination");
Serial.println();
delay(2000);
}
~~~## Adding New Coefficents
To add new coefficents, download the new `.COF` file from [https://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml](https://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml)
Add the .COF file to the `extras` directory.
Then run for example
`python wmmcodeupdate.py -f WMM2015.COF -f WMM2015v2.COF -f WMM2020.COF -o ../src/XYZgeomag.hpp -n 12` from the `extras` directory.In this example, `WMM2015.COF` , `WMM2015v2.COF`, and `WMM2020.COF` are the `.COF` files to use in `src/XYZgeomag.hpp`.
## Run Tests
In the `extras` directory.
Compile `geomag_test.cpp` for example with the command `g++ geomag_test.cpp -std=c++14`
Run the tests for example with the command `./a.out`
To add new models to the test update `wmmtestgen.py` and run it.
## References
Using spherical harmonics algorithm, described in sections 3.2.4 and 3.2.5:
Satellite Orbits Models, Methods and Applications,
by Oliver Montenbruck and Eberhard Gill 2000
Using geodetic2ecef algorithm from https://geographiclib.sourceforge.io/Using coefficients and test points from:
NCEI Geomagnetic Modeling Team and British Geological Survey. 2019. World Magnetic Model 2020. NOAA National Centers for Environmental Information. doi: 10.25921/11v3-da71, 2020, [10 DEC 2019].
Chulliat, A., W. Brown, P. Alken, S. Macmillan, M. Nair, C. Beggan, A. Woods, B. Hamilton, B. Meyer and R. Redmon, 2019, Out-of-Cycle Update of the US/UK World Magnetic Model for 2015-2020: Technical Note, National Centers for Environmental Information, NOAA. doi: 10.25921/xhr3-0t19.
Chulliat, A., S. Macmillan, P. Alken, C. Beggan, M. Nair, B. Hamilton, A. Woods, V. Ridley, S. Maus and A. Thomson, 2015. The US/UK World Magnetic Model for 2015-2020: Technical Report, NOAA National Geophysical Data Center, Boulder, CO, doi: 10.7289/V5TB14V7.