mirror of https://github.com/ArduPilot/ardupilot
Plane: Add support for DO_REPOSITION via COMMAND_INT
also allows guided to change loiter directions
This commit is contained in:
parent
bb7cf6c0b6
commit
c17ea21a97
|
@ -1146,6 +1146,82 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MAVLINK_MSG_ID_COMMAND_INT:
|
||||||
|
{
|
||||||
|
// decode
|
||||||
|
mavlink_command_int_t packet;
|
||||||
|
mavlink_msg_command_int_decode(msg, &packet);
|
||||||
|
|
||||||
|
uint8_t result = MAV_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
|
switch(packet.command) {
|
||||||
|
|
||||||
|
case MAV_CMD_DO_REPOSITION:
|
||||||
|
Location requested_position {};
|
||||||
|
requested_position.lat = packet.x;
|
||||||
|
requested_position.lng = packet.y;
|
||||||
|
|
||||||
|
// check the floating representation for overflow of altitude
|
||||||
|
if (abs(packet.z * 100.0f) >= 0x7fffff) {
|
||||||
|
result = MAV_RESULT_FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
requested_position.alt = (int32_t)(packet.z * 100.0f);
|
||||||
|
|
||||||
|
// load option flags
|
||||||
|
if (packet.frame == MAV_FRAME_GLOBAL_RELATIVE_ALT_INT) {
|
||||||
|
requested_position.flags.relative_alt = 1;
|
||||||
|
}
|
||||||
|
else if (packet.frame == MAV_FRAME_GLOBAL_TERRAIN_ALT_INT) {
|
||||||
|
requested_position.flags.terrain_alt = 1;
|
||||||
|
}
|
||||||
|
else if (packet.frame != MAV_FRAME_GLOBAL_INT) {
|
||||||
|
// not a supported frame
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_zero(packet.param4)) {
|
||||||
|
requested_position.flags.loiter_ccw = 0;
|
||||||
|
} else {
|
||||||
|
requested_position.flags.loiter_ccw = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (location_sanitize(plane.current_loc, requested_position)) {
|
||||||
|
// if the location wasn't already sane don't load it
|
||||||
|
result = MAV_RESULT_FAILED; // failed as the location is not valid
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// location is valid load and set
|
||||||
|
if (((int32_t)packet.param2 & MAV_DO_REPOSITION_FLAGS_CHANGE_MODE) ||
|
||||||
|
(plane.control_mode == GUIDED)) {
|
||||||
|
plane.set_mode(GUIDED);
|
||||||
|
plane.guided_WP_loc = requested_position;
|
||||||
|
|
||||||
|
// add home alt if needed
|
||||||
|
if (plane.guided_WP_loc.flags.relative_alt) {
|
||||||
|
plane.guided_WP_loc.alt += plane.home.alt;
|
||||||
|
plane.guided_WP_loc.flags.relative_alt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
plane.set_guided_WP();
|
||||||
|
|
||||||
|
result = MAV_RESULT_ACCEPTED;
|
||||||
|
} else {
|
||||||
|
result = MAV_RESULT_FAILED; // failed as we are not in guided
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mavlink_msg_command_ack_send_buf(
|
||||||
|
msg,
|
||||||
|
chan,
|
||||||
|
packet.command,
|
||||||
|
result);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MAVLINK_MSG_ID_COMMAND_LONG:
|
case MAVLINK_MSG_ID_COMMAND_LONG:
|
||||||
{
|
{
|
||||||
// decode
|
// decode
|
||||||
|
|
|
@ -6,4 +6,5 @@ void Plane::init_capabilities(void)
|
||||||
{
|
{
|
||||||
hal.util->set_capabilities(MAV_PROTOCOL_CAPABILITY_MISSION_FLOAT);
|
hal.util->set_capabilities(MAV_PROTOCOL_CAPABILITY_MISSION_FLOAT);
|
||||||
hal.util->set_capabilities(MAV_PROTOCOL_CAPABILITY_PARAM_FLOAT);
|
hal.util->set_capabilities(MAV_PROTOCOL_CAPABILITY_PARAM_FLOAT);
|
||||||
|
hal.util->set_capabilities(MAV_PROTOCOL_CAPABILITY_COMMAND_INT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ void Plane::set_next_WP(const struct Location &loc)
|
||||||
|
|
||||||
void Plane::set_guided_WP(void)
|
void Plane::set_guided_WP(void)
|
||||||
{
|
{
|
||||||
if (g.loiter_radius < 0) {
|
if (g.loiter_radius < 0 || guided_WP_loc.flags.loiter_ccw) {
|
||||||
loiter.direction = -1;
|
loiter.direction = -1;
|
||||||
} else {
|
} else {
|
||||||
loiter.direction = 1;
|
loiter.direction = 1;
|
||||||
|
|
|
@ -140,7 +140,11 @@ void Plane::update_loiter(uint16_t radius)
|
||||||
if (radius <= 1) {
|
if (radius <= 1) {
|
||||||
// if radius is <=1 then use the general loiter radius. if it's small, use default
|
// if radius is <=1 then use the general loiter radius. if it's small, use default
|
||||||
radius = (abs(g.loiter_radius) <= 1) ? LOITER_RADIUS_DEFAULT : abs(g.loiter_radius);
|
radius = (abs(g.loiter_radius) <= 1) ? LOITER_RADIUS_DEFAULT : abs(g.loiter_radius);
|
||||||
loiter.direction = (g.loiter_radius < 0) ? -1 : 1;
|
if (next_WP_loc.flags.loiter_ccw == 1) {
|
||||||
|
loiter.direction = -1;
|
||||||
|
} else {
|
||||||
|
loiter.direction = (g.loiter_radius < 0) ? -1 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loiter.start_time_ms == 0 &&
|
if (loiter.start_time_ms == 0 &&
|
||||||
|
|
Loading…
Reference in New Issue