AP_Scripting: Add Location get_distance_NED and get_distance_NE
Fixes a regression with nil punning which broke Location:offset() and adds a test script that is suitable for CI to test this sort of thing
This commit is contained in:
parent
8c413d3c09
commit
38e17e2068
48
libraries/AP_Scripting/examples/scripting_test.lua
Normal file
48
libraries/AP_Scripting/examples/scripting_test.lua
Normal file
@ -0,0 +1,48 @@
|
||||
-- this is a script which is primarily intended to test the scripting bindings and be used with autotest
|
||||
-- however it may be useful to some as a demo of how the API's can be used, this example is much less
|
||||
-- heavily commented, and may require quite a bit more RAM to run in
|
||||
|
||||
local loop_time = 500 -- number of ms between runs
|
||||
|
||||
function is_equal(v1, v2, tolerance)
|
||||
return math.abs(v1 - v2) < (tolerance or 0.0001)
|
||||
end
|
||||
|
||||
function test_offset(ofs_e, ofs_n)
|
||||
local manipulated_pos = Location()
|
||||
manipulated_pos:offset(ofs_e, ofs_n)
|
||||
local distance_offset = manipulated_pos:get_distance(Location())
|
||||
if distance_offset < 0 then
|
||||
gcs:send_text(0, "Location:get_distance() returned a negative number")
|
||||
return false
|
||||
end
|
||||
local error_dist = distance_offset - math.sqrt((ofs_e*ofs_e)+(ofs_n*ofs_n))
|
||||
if error_dist > 0.1 then
|
||||
gcs:send_text(0, string.format("Failed offset %.1f, %.1f with an error of %f", ofs_e, ofs_n, error_dist))
|
||||
return false
|
||||
end
|
||||
local from_origin_NE = Location():get_distance_NE(manipulated_pos)
|
||||
if (not is_equal(ofs_e, from_origin_NE:x(), 0.01)) or (not is_equal(ofs_n, from_origin_NE:y(), 0.01)) then
|
||||
gcs:send_text(0, string.format("Failed to offset %.1f, %.1f %.1f %.1f", ofs_e, ofs_n, from_origin_NE:x(), from_origin_NE:y()))
|
||||
return false
|
||||
end
|
||||
local from_origin_NED = Location():get_distance_NED(manipulated_pos)
|
||||
if (not is_equal(from_origin_NED:x(), from_origin_NE:x())) or (not is_equal(from_origin_NED:y(), from_origin_NE:y())) then
|
||||
gcs:send_text(0, string.format("Distance NED != NE %.1f, %.1f %.1f %.1f", from_origin_NED:x(), from_origin_NED:y(), from_origin_NE:x(), from_origin_NE:y()))
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function update()
|
||||
local all_tests_passed = true
|
||||
-- each test should run then and it's result with the previous ones
|
||||
all_tests_passed = test_offset(500, 200) and all_tests_passed
|
||||
|
||||
if all_tests_passed then
|
||||
gcs:send_text(3, "Internal tests passed")
|
||||
end
|
||||
return update, loop_time
|
||||
end
|
||||
|
||||
return update() -- run immediately before starting to reschedule
|
@ -13,6 +13,8 @@ userdata Location method get_distance float Location
|
||||
userdata Location method offset void float -FLT_MAX FLT_MAX float -FLT_MAX FLT_MAX
|
||||
userdata Location method get_vector_from_origin_NEU boolean Vector3f'Null
|
||||
userdata Location method get_bearing float Location
|
||||
userdata Location method get_distance_NED Vector3f Location
|
||||
userdata Location method get_distance_NE Vector2f Location
|
||||
|
||||
include AP_AHRS/AP_AHRS.h
|
||||
|
||||
|
@ -1191,7 +1191,7 @@ void emit_userdata_method(const struct userdata *data, const struct method *meth
|
||||
emit_checker(arg->type, arg_count, skipped, " ", "argument");
|
||||
arg_count++;
|
||||
}
|
||||
if (arg->type.type != TYPE_LITERAL || arg->type.flags & TYPE_FLAGS_NULLABLE) {
|
||||
if (arg->type.type == TYPE_LITERAL || arg->type.flags & TYPE_FLAGS_NULLABLE) {
|
||||
skipped++;
|
||||
}
|
||||
arg = arg->next;
|
||||
|
@ -390,6 +390,30 @@ static int Vector3f___sub(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Location_get_distance_NE(lua_State *L) {
|
||||
binding_argcheck(L, 2);
|
||||
Location * ud = check_Location(L, 1);
|
||||
Location & data_2 = *check_Location(L, 2);
|
||||
const Vector2f &data = ud->get_distance_NE(
|
||||
data_2);
|
||||
|
||||
new_Vector2f(L);
|
||||
*check_Vector2f(L, -1) = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Location_get_distance_NED(lua_State *L) {
|
||||
binding_argcheck(L, 2);
|
||||
Location * ud = check_Location(L, 1);
|
||||
Location & data_2 = *check_Location(L, 2);
|
||||
const Vector3f &data = ud->get_distance_NED(
|
||||
data_2);
|
||||
|
||||
new_Vector3f(L);
|
||||
*check_Vector3f(L, -1) = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Location_get_bearing(lua_State *L) {
|
||||
binding_argcheck(L, 2);
|
||||
Location * ud = check_Location(L, 1);
|
||||
@ -423,7 +447,7 @@ static int Location_offset(lua_State *L) {
|
||||
const float raw_data_2 = luaL_checknumber(L, 2);
|
||||
luaL_argcheck(L, ((raw_data_2 >= MAX(-FLT_MAX, -INFINITY)) && (raw_data_2 <= MIN(FLT_MAX, INFINITY))), 2, "argument out of range");
|
||||
const float data_2 = raw_data_2;
|
||||
const float raw_data_3 = luaL_checknumber(L, 2);
|
||||
const float raw_data_3 = luaL_checknumber(L, 3);
|
||||
luaL_argcheck(L, ((raw_data_3 >= MAX(-FLT_MAX, -INFINITY)) && (raw_data_3 <= MIN(FLT_MAX, INFINITY))), 3, "argument out of range");
|
||||
const float data_3 = raw_data_3;
|
||||
ud->offset(
|
||||
@ -478,6 +502,8 @@ const luaL_Reg Location_meta[] = {
|
||||
{"relative_alt", Location_relative_alt},
|
||||
{"lng", Location_lng},
|
||||
{"lat", Location_lat},
|
||||
{"get_distance_NE", Location_get_distance_NE},
|
||||
{"get_distance_NED", Location_get_distance_NED},
|
||||
{"get_bearing", Location_get_bearing},
|
||||
{"get_vector_from_origin_NEU", Location_get_vector_from_origin_NEU},
|
||||
{"offset", Location_offset},
|
||||
@ -513,10 +539,10 @@ static int GCS_set_message_interval(lua_State *L) {
|
||||
const lua_Integer raw_data_2 = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, ((raw_data_2 >= MAX(0, 0)) && (raw_data_2 <= MIN(MAVLINK_COMM_NUM_BUFFERS, UINT8_MAX))), 2, "argument out of range");
|
||||
const uint8_t data_2 = static_cast<uint8_t>(raw_data_2);
|
||||
const uint32_t raw_data_3 = *check_uint32_t(L, 2);
|
||||
const uint32_t raw_data_3 = *check_uint32_t(L, 3);
|
||||
luaL_argcheck(L, ((raw_data_3 >= MAX(0U, 0U)) && (raw_data_3 <= MIN(UINT32_MAX, UINT32_MAX))), 3, "argument out of range");
|
||||
const uint32_t data_3 = static_cast<uint32_t>(raw_data_3);
|
||||
const lua_Integer raw_data_4 = luaL_checkinteger(L, 2);
|
||||
const lua_Integer raw_data_4 = luaL_checkinteger(L, 4);
|
||||
luaL_argcheck(L, ((raw_data_4 >= MAX(-1, INT32_MIN)) && (raw_data_4 <= MIN(INT32_MAX, INT32_MAX))), 4, "argument out of range");
|
||||
const int32_t data_4 = raw_data_4;
|
||||
const MAV_RESULT &data = ud->set_message_interval(
|
||||
|
Loading…
Reference in New Issue
Block a user