Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BufferedSerial FatFileSystemCpp mbed
GeoPosition.h
- Committer:
- AndyA
- Date:
- 2022-11-15
- Revision:
- 83:f0d1d948c306
- Parent:
- 82:ee6eed2a51bd
File content as of revision 83:f0d1d948c306:
/****************************************************************************************
/  GeoPosition.h
/  (c) 2014 Racelogic Ltd.
/
/  A class to convert between LLA (latitude, longitude, altitude), ECEF (Earth centered, earth fixed) and ENU (East, north, up).
/
/  Conversions are only calculated when requested. Converted to LLA is EXPENSIVE, don't do it for fun.
/  All conversions are to WGS84.
/  LLA altitude, ECEF and ENU are all in meters.
/  ENU calculations require a reference point with a valid ECEF or LLA location in order to work.
/  Conversion code based on these sources:
/  http://www.gmat.unsw.edu.au/snap/gps/clynch_pdfs/coordcvt.pdf
/  http://en.wikipedia.org/wiki/Geodetic_datum#From_ECEF_to_ENU
/
****************************************************************************************/
#ifndef __GEOPOSITION_H__
#define __GEOPOSITION_H__
// structures to hold position data as a convenience.
struct LLA {
  double longitude;
  double latitude;
  double altitude;
};
struct ECEF {
  double X;
  double Y;
  double Z;
};
struct ENU {
  double E;
  double N;
  double U;
};
class GeoPosition {
public:
  // constructor
  GeoPosition();
  GeoPosition(GeoPosition *posToClone);
  ~GeoPosition();
  // sets position in LLA
  void SetDecimalDegrees(double latitude, double longitude, double altitude = 0);
  // for degrees and decimal minutes set seconds to 0.
  void SetDegreesMinutesSeconds(int latitudeDegrees, double latitudeMinutes, float latitudeSeconds, int longitudeDegrees, double longitudeMinutes, float longitudeSeconds, double altitude = 0.0);
  void SetLLA(struct LLA llaStruct);
  // sets position in ECEF in m
  void SetECEF(double x, double y, double z);
  void SetECEF(struct ECEF ecefStruct);
  // sets position in ENU. ENU conversions MUST have a reference position set to work.
  void SetENU(double east, double north, double up);
  void SetENU(double east, double north, double up, GeoPosition *refPos);
  void SetENU(struct ENU enuStruct);
  void SetENU(struct ENU enuStruct, GeoPosition *refPos);
  // Sets the reference 0,0,0 position for ENU conversions.
  // Changing reference position will flag ENU as invalid if LLA or ECEF are known
  // If you want to manitain ENU then first call SetENU(GetENU());
  // this will flag LLA and ECEF as invalid and maintain the ENU over a reference change.
  // Changing the values of the GeoPosition being used as a reference after setting it as reference will give invalid results due to speed optimisations.
  void SetReferancePosition(GeoPosition *refPos);
  
  // get the location. Conversions will be done as needed. Will return false if conversion wasn't possible.
  bool GetENU(double *east, double *north, double *up);
  bool GetECEF(double *x, double *y, double *z);
  bool GetLLA(double *latitude, double *longitude, double *altitude = 0);
  
  // NOTE - functions below could result in invalid data if there is no refernce position and ENUs are involved.
  // Check the known flag after a call to verify data is valid.
  struct ENU GetENU();
  struct ECEF GetECEF();
  struct LLA GetLLA();
  
  double GetLatitude();
  double GetLongitude();
  double GetAltitude();
  // Checks to see if various formats have already been calculated or not.
  bool LLAKnown() { return llaValid; };
  bool ECEFKnown() { return ecefValid; };
  bool ENUKnown() { return enuValid; };
  
  void ClearLocation() {
    llaValid = false;
    ecefValid = false;
    enuValid = false;
};
  // returns a const pointer to the reference position being used.
  GeoPosition *GetReferancePosition() { return referencePosition; };
private:
  bool calcLLA();
  bool calcECEF();
  bool calcENU();
  void LLA2ECEF();
  void ECEF2LLA();
  void ENU2ECEF();
  void ECEF2ENU();
  GeoPosition *referencePosition;
  double sinRefLong;
  double cosRefLong;
  double sinRefLat;
  double cosRefLat;
  struct LLA  llaPosition;
  struct ECEF ecefPosition;
  struct ENU  enuPosition;
  bool llaValid;
  bool ecefValid;
  bool enuValid;
};
#endif