Location.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #pragma once
  2. #include <AP_Math/AP_Math.h>
  3. class AP_Terrain;
  4. #define LOCATION_ALT_MAX_M 83000 // maximum altitude (in meters) that can be fit into Location structure's alt field
  5. class Location
  6. {
  7. public:
  8. uint8_t relative_alt : 1; // 1 if altitude is relative to home
  9. uint8_t loiter_ccw : 1; // 0 if clockwise, 1 if counter clockwise
  10. uint8_t terrain_alt : 1; // this altitude is above terrain
  11. uint8_t origin_alt : 1; // this altitude is above ekf origin
  12. uint8_t loiter_xtrack : 1; // 0 to crosstrack from center of waypoint, 1 to crosstrack from tangent exit location
  13. // note that mission storage only stores 24 bits of altitude (~ +/- 83km)
  14. int32_t alt;
  15. int32_t lat;
  16. int32_t lng;
  17. /// enumeration of possible altitude types
  18. enum class AltFrame {
  19. ABSOLUTE = 0,
  20. ABOVE_HOME = 1,
  21. ABOVE_ORIGIN = 2,
  22. ABOVE_TERRAIN = 3
  23. };
  24. /// constructors
  25. Location();
  26. Location(int32_t latitude, int32_t longitude, int32_t alt_in_cm, AltFrame frame);
  27. Location(const Vector3f &ekf_offset_neu);
  28. static void set_terrain(AP_Terrain* terrain) { _terrain = terrain; }
  29. // set altitude
  30. void set_alt_cm(int32_t alt_cm, AltFrame frame);
  31. // get altitude (in cm) in the desired frame
  32. // returns false on failure to get altitude in the desired frame which
  33. // can only happen if the original frame or desired frame is above-terrain
  34. bool get_alt_cm(AltFrame desired_frame, int32_t &ret_alt_cm) const WARN_IF_UNUSED;
  35. // get altitude frame
  36. AltFrame get_alt_frame() const;
  37. // converts altitude to new frame
  38. // returns false on failure to convert which can only happen if
  39. // the original frame or desired frame is above-terrain
  40. bool change_alt_frame(AltFrame desired_frame);
  41. // get position as a vector from origin (x,y only or x,y,z)
  42. // return false on failure to get the vector which can only
  43. // happen if the EKF origin has not been set yet
  44. // x, y and z are in centimetres
  45. bool get_vector_xy_from_origin_NE(Vector2f &vec_ne) const WARN_IF_UNUSED;
  46. bool get_vector_from_origin_NEU(Vector3f &vec_neu) const WARN_IF_UNUSED;
  47. // return distance in meters between two locations
  48. float get_distance(const struct Location &loc2) const;
  49. // return the distance in meters in North/East/Down plane as a N/E/D vector to loc2
  50. Vector3f get_distance_NED(const Location &loc2) const;
  51. // return the distance in meters in North/East plane as a N/E vector to loc2
  52. Vector2f get_distance_NE(const Location &loc2) const;
  53. // extrapolate latitude/longitude given distances (in meters) north and east
  54. void offset(float ofs_north, float ofs_east);
  55. // extrapolate latitude/longitude given bearing and distance
  56. void offset_bearing(float bearing, float distance);
  57. // longitude_scale - returns the scaler to compensate for
  58. // shrinking longitude as you move north or south from the equator
  59. // Note: this does not include the scaling to convert
  60. // longitude/latitude points to meters or centimeters
  61. float longitude_scale() const;
  62. bool is_zero(void) const WARN_IF_UNUSED;
  63. void zero(void);
  64. // return bearing in centi-degrees from location to loc2
  65. int32_t get_bearing_to(const struct Location &loc2) const;
  66. // check if lat and lng match. Ignore altitude and options
  67. bool same_latlon_as(const Location &loc2) const;
  68. /*
  69. * convert invalid waypoint with useful data. return true if location changed
  70. */
  71. bool sanitize(const struct Location &defaultLoc);
  72. // return true when lat and lng are within range
  73. bool check_latlng() const;
  74. // see if location is past a line perpendicular to
  75. // the line between point1 and point2 and passing through point2.
  76. // If point1 is our previous waypoint and point2 is our target waypoint
  77. // then this function returns true if we have flown past
  78. // the target waypoint
  79. bool past_interval_finish_line(const Location &point1, const Location &point2) const;
  80. /*
  81. return the proportion we are along the path from point1 to
  82. point2, along a line parallel to point1<->point2.
  83. This will be more than 1 if we have passed point2
  84. */
  85. float line_path_proportion(const Location &point1, const Location &point2) const;
  86. bool initialised() const { return (lat !=0 || lng != 0); }
  87. private:
  88. static AP_Terrain *_terrain;
  89. // scaling factor from 1e-7 degrees to meters at equator
  90. // == 1.0e-7 * DEG_TO_RAD * RADIUS_OF_EARTH
  91. static constexpr float LOCATION_SCALING_FACTOR = 0.011131884502145034f;
  92. // inverse of LOCATION_SCALING_FACTOR
  93. static constexpr float LOCATION_SCALING_FACTOR_INV = 89.83204953368922f;
  94. };