LCOV - code coverage report
Current view: top level - AP_Common - Location.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 16 16 100.0 %
Date: 2026-09-09 11:02:08 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <AP_Math/AP_Math.h>
       4             : 
       5             : #define LOCATION_ALT_MAX_M  83000   // maximum altitude (in meters) that can be fit into Location structure's alt field
       6             : 
       7             : class Location
       8             : {
       9             : public:
      10             : 
      11             :     uint8_t relative_alt : 1;           // 1 if altitude is relative to home
      12             :     uint8_t loiter_ccw   : 1;           // 0 if clockwise, 1 if counter clockwise
      13             :     uint8_t terrain_alt  : 1;           // this altitude is above terrain
      14             :     uint8_t origin_alt   : 1;           // this altitude is above ekf origin
      15             :     uint8_t loiter_xtrack : 1;          // 0 to crosstrack from center of waypoint, 1 to crosstrack from tangent exit location
      16             : 
      17             :     // note that mission storage only stores 24 bits of altitude (~ +/- 83km)
      18             :     int32_t alt; // in cm
      19             :     int32_t lat; // in 1E7 degrees
      20             :     int32_t lng; // in 1E7 degrees
      21             : 
      22             :     /// enumeration of possible altitude types
      23             :     enum class AltFrame {
      24             :         ABSOLUTE = 0,
      25             :         ABOVE_HOME = 1,
      26             :         ABOVE_ORIGIN = 2,
      27             :         ABOVE_TERRAIN = 3
      28             :     };
      29             : 
      30             :     /// constructors
      31  2113597493 :     Location() { zero(); }
      32             :     Location(int32_t latitude, int32_t longitude, int32_t alt_in_cm, AltFrame frame);
      33             :     Location(const Vector3f &ekf_offset_neu_cm, AltFrame frame);
      34             :     Location(const Vector3d &ekf_offset_neu_cm, AltFrame frame);
      35             : 
      36             :     // named constructors
      37             :     static Location from_ekf_offset_NED_m(const Vector3f& ekf_offset_ned_m, AltFrame frame);
      38             :     static Location from_ekf_offset_NED_m(const Vector3d& ekf_offset_ned_m, AltFrame frame);
      39             : 
      40             :     // set altitude
      41             :     void set_alt_cm(int32_t alt_cm, AltFrame frame);
      42             :     // set_alt_m - set altitude in metres
      43    31422645 :     void set_alt_m(float alt_m, AltFrame frame) {
      44    31422645 :         set_alt_cm(alt_m*100, frame);
      45    31422645 :     }
      46             : 
      47             :     // get altitude (in cm) in the desired frame
      48             :     // does not modify ret_alt_cm unless true is returned
      49             :     // returns false on failure to get altitude in the desired frame which can only happen if the original frame or desired frame is:
      50             :     // - above-terrain and the terrain database can't supply terrain height amsl
      51             :     // - above-home and home is not set
      52             :     // - above-origin and origin is not set
      53             :     bool get_alt_cm(AltFrame desired_frame, int32_t &ret_alt_cm) const WARN_IF_UNUSED;
      54             :     // same as get_alt_cm but in metres:
      55             :     bool get_alt_m(AltFrame desired_frame, float &ret_alt) const WARN_IF_UNUSED;
      56             : 
      57             :     // get altitude frame
      58             :     AltFrame get_alt_frame() const;
      59             : 
      60             :     // converts altitude to new frame
      61             :     // returns false on failure to convert which can only happen if the original frame or desired frame is:
      62             :     // - above-terrain and the terrain database can't supply terrain height amsl
      63             :     // - above-home and home is not set
      64             :     // - above-origin and origin is not set
      65             :     bool change_alt_frame(AltFrame desired_frame);
      66             : 
      67             :     // copy altitude and its frame of other Location object:
      68             :     void copy_alt_from(const Location &other);
      69             : 
      70             :     // get position as a vector (in cm) from origin (x,y only or
      71             :     // x,y,z) return false on failure to get the vector which can only
      72             :     // happen if the EKF origin has not been set yet x, y and z are in
      73             :     // centimetres.  If this method returns false then vec_ne is
      74             :     // unmodified.
      75             :     template<typename T>
      76             :     bool get_vector_xy_from_origin_NE_cm(T &vec_ne) const WARN_IF_UNUSED;
      77             :     // converts location to a vector from origin; if this method returns
      78             :     // false then vec_neu is unmodified
      79             :     template<typename T>
      80             :     bool get_vector_from_origin_NEU_cm(T &vec_neu) const WARN_IF_UNUSED;
      81             :     // same as get_vector_from_origin_NEU_cm, but only here so we can
      82             :     // continue to use it in LUA scripts:
      83             :     template<typename T>
      84             :     bool get_vector_from_origin_NEU(T &vec_neu) const WARN_IF_UNUSED;
      85             : 
      86             :     // get position as a vector (in metres) from origin (x,y only or
      87             :     // x,y,z) return false on failure to get the vector which can only
      88             :     // happen if the EKF origin has not been set yet x, y and z are in
      89             :     // metres.  If this method returns false then vec_ne is
      90             :     // unmodified.
      91             :     template<typename T>
      92             :     bool get_vector_xy_from_origin_NE_m(T &vec_ne) const;
      93             :     template<typename T>
      94             :     bool get_vector_from_origin_NEU_m(T &vec_neu) const;
      95             :     template<typename T>
      96             :     bool get_vector_from_origin_NED_m(T &vec_ned) const;
      97             : 
      98             :     // return horizontal distance in meters between two locations
      99             :     ftype get_distance(const Location &loc2) const;
     100             : 
     101             :     // return the altitude difference in meters taking into account
     102             :     // alt frame.  if loc2 is below this location then "distance" will
     103             :     // be positive.  ie. this method returns how far above loc2 this
     104             :     // location is.
     105             :     bool get_height_above(const Location &loc2, ftype &distance) const WARN_IF_UNUSED;
     106             : 
     107             :     // return the distance in meters in North/East/Down plane as a N/E/D vector to loc2
     108             :     // NOT CONSIDERING ALT FRAME!
     109             :     Vector3f get_distance_NED(const Location &loc2) const;
     110             :     Vector3p get_distance_NED_postype(const Location &loc2) const;
     111             :     Vector3d get_distance_NED_double(const Location &loc2) const;
     112             : 
     113             :     // return the distance in meters in North/East/Down plane as a N/E/D vector to loc2 considering alt frame, if altitude cannot be resolved down distance is 0
     114             :     Vector3f get_distance_NED_alt_frame(const Location &loc2) const;
     115             : 
     116             :     // return the distance in meters in North/East plane as a N/E vector to loc2
     117             :     Vector2f get_distance_NE(const Location &loc2) const;
     118             :     Vector2p get_distance_NE_postype(const Location &loc2) const;
     119             :     Vector2d get_distance_NE_double(const Location &loc2) const;
     120             :     Vector2F get_distance_NE_ftype(const Location &loc2) const;
     121             : 
     122             :     // extrapolate latitude/longitude given distances (in meters) north and east
     123             :     static void offset_latlng(int32_t &lat, int32_t &lng, ftype ofs_north, ftype ofs_east);
     124             :     void offset(ftype ofs_north, ftype ofs_east);
     125             :     // extrapolate latitude/longitude given distances (in meters) north
     126             :     // and east. Note that this is metres, *even for the altitude*.
     127             :     void offset(const Vector3p &ofs_ned);
     128       16024 :     void offset_up_cm(int32_t alt_offset_cm) {
     129       16024 :         alt += alt_offset_cm;
     130       16024 :     }
     131      190055 :     void offset_up_m(float alt_offset_m) {
     132      190055 :         alt += alt_offset_m * 100;
     133      190055 :     }
     134             : 
     135             :     // extrapolate latitude/longitude given bearing and distance
     136             :     void offset_bearing(ftype bearing_deg, ftype distance);
     137             :     
     138             :     // extrapolate latitude/longitude given bearing, pitch and distance
     139             :     void offset_bearing_and_pitch(ftype bearing_deg, ftype pitch_deg, ftype distance);
     140             : 
     141             :     // longitude_scale - returns the scaler to compensate for
     142             :     // shrinking longitude as you move north or south from the equator
     143             :     // Note: this does not include the scaling to convert
     144             :     // longitude/latitude points to meters or centimeters
     145             :     static ftype longitude_scale(int32_t lat);
     146             : 
     147             :     bool is_zero(void) const WARN_IF_UNUSED;
     148             : 
     149             :     void zero(void);
     150             : 
     151             :     // return the bearing in radians, from 0 to 2*Pi
     152             :     ftype get_bearing(const Location &loc2) const;
     153             : 
     154             :     // return bearing in centi-degrees from location to loc2, return is 0 to 35999
     155     1506264 :     int32_t get_bearing_to(const Location &loc2) const {
     156     1506264 :         return int32_t(rad_to_cd(get_bearing(loc2)) + 0.5);
     157             :     }
     158             : 
     159             :     // check if lat and lng match. Ignore altitude and options
     160             :     bool same_latlon_as(const Location &loc2) const;
     161             : 
     162             :     // check if altitude matches.
     163             :     bool same_alt_as(const Location &loc2) const;
     164             : 
     165             :     // check if lat, lng, and alt match.
     166       33471 :     bool same_loc_as(const Location &loc2) const {
     167       33471 :         return same_latlon_as(loc2) && same_alt_as(loc2);
     168             :     }
     169             : 
     170             :     /*
     171             :      * convert invalid waypoint with useful data. return true if location changed
     172             :      */
     173             :     bool sanitize(const Location &defaultLoc);
     174             : 
     175             :     // return true when lat and lng are within range
     176             :     bool check_latlng() const;
     177             : 
     178             :     // see if location is past a line perpendicular to
     179             :     // the line between point1 and point2 and passing through point2.
     180             :     // If point1 is our previous waypoint and point2 is our target waypoint
     181             :     // then this function returns true if we have flown past
     182             :     // the target waypoint
     183             :     bool past_interval_finish_line(const Location &point1, const Location &point2) const;
     184             : 
     185             :     /*
     186             :       return the proportion we are along the path from point1 to
     187             :       point2, along a line parallel to point1<->point2.
     188             :       This will be more than 1 if we have passed point2
     189             :      */
     190             :     float line_path_proportion(const Location &point1, const Location &point2) const;
     191             : 
     192             :     // update altitude and alt-frame base on this location's horizontal position between point1 and point2
     193             :     // this location's lat,lon is used to calculate the alt of the closest point on the line between point1 and point2
     194             :     // origin and destination's altitude frames must be the same
     195             :     // this alt-frame will be updated to match the destination alt frame
     196             :     void linearly_interpolate_alt(const Location &point1, const Location &point2);
     197             : 
     198   127425144 :     bool initialised() const { return (lat !=0 || lng != 0 || alt != 0); }
     199             :     // return true if alt is *exactly* zero.  This is not intended to
     200             :     // be used for anything except magically changing a 0-altitude
     201             :     // passed via mavlink into the current vehicle's altitude
     202        2644 :     bool alt_is_zero() const { return alt == 0; }
     203             : 
     204             :     // wrap longitude at -180e7 to 180e7
     205             :     static int32_t wrap_longitude(int64_t lon);
     206             : 
     207             :     // limit latitude to -90e7 to 90e7
     208             :     static int32_t limit_lattitude(int32_t lat);
     209             :     
     210             :     // get lon1-lon2, wrapping at -180e7 to 180e7
     211             :     static int32_t diff_longitude(int32_t lon1, int32_t lon2);
     212             : 
     213             : private:
     214             : 
     215             :     // scaling factor from 1e-7 degrees to meters at equator
     216             :     // == 1.0e-7 * DEG_TO_RAD * RADIUS_OF_EARTH
     217             :     static constexpr float LOCATION_SCALING_FACTOR = LATLON_TO_M;
     218             :     // inverse of LOCATION_SCALING_FACTOR
     219             :     static constexpr float LOCATION_SCALING_FACTOR_INV = LATLON_TO_M_INV;
     220             : };

Generated by: LCOV version 1.14