AP_Common: added double methods for SITL

This commit is contained in:
Andrew Tridgell 2021-06-21 12:01:59 +10:00
parent d698987070
commit 425c8aafb1
4 changed files with 74 additions and 12 deletions

View File

@ -253,22 +253,34 @@ Vector3d Location::get_distance_NED_double(const Location &loc2) const
(alt - loc2.alt) * 0.01); (alt - loc2.alt) * 0.01);
} }
Vector2d Location::get_distance_NE_double(const Location &loc2) const
{
return Vector2d((loc2.lat - lat) * double(LOCATION_SCALING_FACTOR),
diff_longitude(loc2.lng,lng) * double(LOCATION_SCALING_FACTOR) * longitude_scale());
}
Vector2F Location::get_distance_NE_ftype(const Location &loc2) const
{
return Vector2F((loc2.lat - lat) * ftype(LOCATION_SCALING_FACTOR),
diff_longitude(loc2.lng,lng) * ftype(LOCATION_SCALING_FACTOR) * longitude_scale());
}
// extrapolate latitude/longitude given distances (in meters) north and east // extrapolate latitude/longitude given distances (in meters) north and east
void Location::offset(float ofs_north, float ofs_east) void Location::offset(float ofs_north, float ofs_east)
{ {
const int32_t dlat = ofs_north * LOCATION_SCALING_FACTOR_INV; const int32_t dlat = ofs_north * LOCATION_SCALING_FACTOR_INV;
const int32_t dlng = (ofs_east * LOCATION_SCALING_FACTOR_INV) / longitude_scale(); const int64_t dlng = (ofs_east * LOCATION_SCALING_FACTOR_INV) / longitude_scale();
lat += dlat; lat += dlat;
lng += dlng; lat = limit_lattitude(lat);
lng = wrap_longitude(lng); lng = wrap_longitude(dlng+lng);
} }
void Location::offset_double(double ofs_north, double ofs_east) void Location::offset_double(double ofs_north, double ofs_east)
{ {
const int32_t dlat = ofs_north * double(LOCATION_SCALING_FACTOR_INV); const int64_t dlat = ofs_north * double(LOCATION_SCALING_FACTOR_INV);
const int32_t dlng = (ofs_east * double(LOCATION_SCALING_FACTOR_INV)) / longitude_scale(); const int64_t dlng = (ofs_east * double(LOCATION_SCALING_FACTOR_INV)) / longitude_scale();
lat += dlat; lat = limit_lattitude(int64_t(lat)+dlat);
lng += dlng; lng = wrap_longitude(int64_t(lng)+dlng);
} }
/* /*
@ -393,14 +405,14 @@ float Location::line_path_proportion(const Location &point1, const Location &poi
/* /*
wrap longitude for -180e7 to 180e7 wrap longitude for -180e7 to 180e7
*/ */
int32_t Location::wrap_longitude(int32_t lon) int32_t Location::wrap_longitude(int64_t lon)
{ {
if (lon > 1800000000L) { if (lon > 1800000000L) {
lon = int32_t(int64_t(lon)-3600000000LL); lon = int32_t(lon-3600000000LL);
} else if (lon < -1800000000L) { } else if (lon < -1800000000L) {
lon = int32_t(int64_t(lon)+3600000000LL); lon = int32_t(lon+3600000000LL);
} }
return lon; return int32_t(lon);
} }
/* /*
@ -420,3 +432,16 @@ int32_t Location::diff_longitude(int32_t lon1, int32_t lon2)
} }
return int32_t(dlon); return int32_t(dlon);
} }
/*
limit lattitude to -90e7 to 90e7
*/
int32_t Location::limit_lattitude(int32_t lat)
{
if (lat > 900000000L) {
lat = 1800000000LL - lat;
} else if (lat < -900000000L) {
lat = -(1800000000LL + lat);
}
return lat;
}

View File

@ -68,6 +68,8 @@ public:
// return the distance in meters in North/East plane as a N/E vector to loc2 // return the distance in meters in North/East plane as a N/E vector to loc2
Vector2f get_distance_NE(const Location &loc2) const; Vector2f get_distance_NE(const Location &loc2) const;
Vector2d get_distance_NE_double(const Location &loc2) const;
Vector2F get_distance_NE_ftype(const Location &loc2) const;
// extrapolate latitude/longitude given distances (in meters) north and east // extrapolate latitude/longitude given distances (in meters) north and east
void offset(float ofs_north, float ofs_east); void offset(float ofs_north, float ofs_east);
@ -122,7 +124,10 @@ public:
bool initialised() const { return (lat !=0 || lng != 0 || alt != 0); } bool initialised() const { return (lat !=0 || lng != 0 || alt != 0); }
// wrap longitude at -180e7 to 180e7 // wrap longitude at -180e7 to 180e7
static int32_t wrap_longitude(int32_t lon); static int32_t wrap_longitude(int64_t lon);
// limit lattitude to -90e7 to 90e7
static int32_t limit_lattitude(int32_t lat);
// get lon1-lon2, wrapping at -180e7 to 180e7 // get lon1-lon2, wrapping at -180e7 to 180e7
static int32_t diff_longitude(int32_t lon1, int32_t lon2); static int32_t diff_longitude(int32_t lon1, int32_t lon2);

View File

@ -127,6 +127,33 @@ TEST(Location, LatLngWrapping)
} }
} }
TEST(Location, LocOffsetDouble)
{
struct {
int32_t home_lat;
int32_t home_lng;
Vector2d delta_metres_ne1;
Vector2d delta_metres_ne2;
Vector2d expected_pos_change;
} tests[] {
-353632620, 1491652373,
Vector2d{4682795.4576701336, 5953662.7673837934},
Vector2d{4682797.1904749088, 5953664.1586009059},
Vector2d{1.7365739867091179,1.7025913001452864},
};
for (auto &test : tests) {
Location home{test.home_lat, test.home_lng, 0, Location::AltFrame::ABOVE_HOME};
Location loc1 = home;
Location loc2 = home;
loc1.offset_double(test.delta_metres_ne1.x, test.delta_metres_ne1.y);
loc2.offset_double(test.delta_metres_ne2.x, test.delta_metres_ne2.y);
Vector2d diff = loc1.get_distance_NE_double(loc2);
EXPECT_FLOAT_EQ(diff.x, test.expected_pos_change.x);
EXPECT_FLOAT_EQ(diff.y, test.expected_pos_change.y);
}
}
TEST(Location, Tests) TEST(Location, Tests)
{ {
Location test_location; Location test_location;

View File

@ -5,3 +5,8 @@ def build(bld):
bld.ap_find_tests( bld.ap_find_tests(
use='ap', use='ap',
) )
# location test needs double precision
def configure(cfg):
cfg.env.DOUBLE_PRECISION_SOURCES['AP_Common'] = ['tests/test_location.cpp']