Plane: Add support for DO_REPOSITION via COMMAND_INT

also allows guided to change loiter directions
This commit is contained in:
Michael du Breuil 2016-04-11 14:09:08 -07:00
parent bb7cf6c0b6
commit c17ea21a97
4 changed files with 83 additions and 2 deletions

View File

@ -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

View File

@ -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);
} }

View File

@ -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;

View File

@ -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 &&