mirror of https://github.com/ArduPilot/ardupilot
AP_Common: added double methods for SITL
This commit is contained in:
parent
c1012d69ab
commit
9246442482
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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']
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue