mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 06:28:27 -04:00
Rover: support guided-within-auto
also adds support for sending position targets to offboard controller which is assumed to return velocity commands
This commit is contained in:
parent
066a443e5f
commit
721c200bcc
@ -525,7 +525,7 @@ bool GCS_MAVLINK_Rover::in_hil_mode() const
|
|||||||
|
|
||||||
bool GCS_MAVLINK_Rover::handle_guided_request(AP_Mission::Mission_Command &cmd)
|
bool GCS_MAVLINK_Rover::handle_guided_request(AP_Mission::Mission_Command &cmd)
|
||||||
{
|
{
|
||||||
if (rover.control_mode != &rover.mode_guided) {
|
if (!rover.control_mode->in_guided_mode()) {
|
||||||
// only accept position updates when in GUIDED mode
|
// only accept position updates when in GUIDED mode
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -666,7 +666,7 @@ MAV_RESULT GCS_MAVLINK_Rover::handle_command_long_packet(const mavlink_command_l
|
|||||||
// param2 : Speed - normalized to 0 .. 1
|
// param2 : Speed - normalized to 0 .. 1
|
||||||
|
|
||||||
// exit if vehicle is not in Guided mode
|
// exit if vehicle is not in Guided mode
|
||||||
if (rover.control_mode != &rover.mode_guided) {
|
if (!rover.control_mode->in_guided_mode()) {
|
||||||
return MAV_RESULT_FAILED;
|
return MAV_RESULT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,7 +750,7 @@ void GCS_MAVLINK_Rover::handleMessage(mavlink_message_t* msg)
|
|||||||
mavlink_msg_set_attitude_target_decode(msg, &packet);
|
mavlink_msg_set_attitude_target_decode(msg, &packet);
|
||||||
|
|
||||||
// exit if vehicle is not in Guided mode
|
// exit if vehicle is not in Guided mode
|
||||||
if (rover.control_mode != &rover.mode_guided) {
|
if (!rover.control_mode->in_guided_mode()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +782,7 @@ void GCS_MAVLINK_Rover::handleMessage(mavlink_message_t* msg)
|
|||||||
mavlink_msg_set_position_target_local_ned_decode(msg, &packet);
|
mavlink_msg_set_position_target_local_ned_decode(msg, &packet);
|
||||||
|
|
||||||
// exit if vehicle is not in Guided mode
|
// exit if vehicle is not in Guided mode
|
||||||
if (rover.control_mode != &rover.mode_guided) {
|
if (!rover.control_mode->in_guided_mode()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -899,7 +899,7 @@ void GCS_MAVLINK_Rover::handleMessage(mavlink_message_t* msg)
|
|||||||
mavlink_msg_set_position_target_global_int_decode(msg, &packet);
|
mavlink_msg_set_position_target_global_int_decode(msg, &packet);
|
||||||
|
|
||||||
// exit if vehicle is not in Guided mode
|
// exit if vehicle is not in Guided mode
|
||||||
if (rover.control_mode != &rover.mode_guided) {
|
if (!rover.control_mode->in_guided_mode()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// check for supported coordinate frames
|
// check for supported coordinate frames
|
||||||
|
@ -37,6 +37,10 @@ bool ModeAuto::start_command(const AP_Mission::Mission_Command& cmd)
|
|||||||
do_nav_wp(cmd, true);
|
do_nav_wp(cmd, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAV_CMD_NAV_GUIDED_ENABLE: // accept navigation commands from external nav computer
|
||||||
|
do_nav_guided_enable(cmd);
|
||||||
|
break;
|
||||||
|
|
||||||
case MAV_CMD_NAV_SET_YAW_SPEED:
|
case MAV_CMD_NAV_SET_YAW_SPEED:
|
||||||
do_nav_set_yaw_speed(cmd);
|
do_nav_set_yaw_speed(cmd);
|
||||||
break;
|
break;
|
||||||
@ -158,6 +162,9 @@ bool ModeAuto::verify_command(const AP_Mission::Mission_Command& cmd)
|
|||||||
case MAV_CMD_NAV_LOITER_TIME:
|
case MAV_CMD_NAV_LOITER_TIME:
|
||||||
return verify_loiter_time(cmd);
|
return verify_loiter_time(cmd);
|
||||||
|
|
||||||
|
case MAV_CMD_NAV_GUIDED_ENABLE:
|
||||||
|
return verify_nav_guided_enable(cmd);
|
||||||
|
|
||||||
case MAV_CMD_CONDITION_DELAY:
|
case MAV_CMD_CONDITION_DELAY:
|
||||||
return verify_wait_delay();
|
return verify_wait_delay();
|
||||||
|
|
||||||
@ -219,6 +226,16 @@ void ModeAuto::do_nav_wp(const AP_Mission::Mission_Command& cmd, bool always_sto
|
|||||||
set_desired_location(cmdloc, next_leg_bearing_cd);
|
set_desired_location(cmdloc, next_leg_bearing_cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModeAuto::do_nav_guided_enable(const AP_Mission::Mission_Command& cmd)
|
||||||
|
{
|
||||||
|
if (cmd.p1 > 0) {
|
||||||
|
// initialise guided limits
|
||||||
|
//rover.mode_guided.limit_init_time_and_pos();
|
||||||
|
|
||||||
|
start_guided(cmd.content.location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// do_set_yaw_speed - turn to a specified heading and achieve and given speed
|
// do_set_yaw_speed - turn to a specified heading and achieve and given speed
|
||||||
void ModeAuto::do_nav_set_yaw_speed(const AP_Mission::Mission_Command& cmd)
|
void ModeAuto::do_nav_set_yaw_speed(const AP_Mission::Mission_Command& cmd)
|
||||||
{
|
{
|
||||||
@ -295,6 +312,12 @@ bool ModeAuto::verify_loiter_time(const AP_Mission::Mission_Command& cmd)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if guided has completed
|
||||||
|
bool ModeAuto::verify_nav_guided_enable(const AP_Mission::Mission_Command& cmd)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// verify_yaw - return true if we have reached the desired heading
|
// verify_yaw - return true if we have reached the desired heading
|
||||||
bool ModeAuto::verify_nav_set_yaw_speed()
|
bool ModeAuto::verify_nav_set_yaw_speed()
|
||||||
{
|
{
|
||||||
|
@ -67,6 +67,9 @@ public:
|
|||||||
// return if in non-manual mode : Auto, Guided, RTL, SmartRTL
|
// return if in non-manual mode : Auto, Guided, RTL, SmartRTL
|
||||||
virtual bool is_autopilot_mode() const { return false; }
|
virtual bool is_autopilot_mode() const { return false; }
|
||||||
|
|
||||||
|
// return if external control is allowed in this mode (Guided or Guided-within-Auto)
|
||||||
|
virtual bool in_guided_mode() const { return false; }
|
||||||
|
|
||||||
// returns true if vehicle can be armed or disarmed from the transmitter in this mode
|
// returns true if vehicle can be armed or disarmed from the transmitter in this mode
|
||||||
virtual bool allows_arming_from_transmitter() { return !is_autopilot_mode(); }
|
virtual bool allows_arming_from_transmitter() { return !is_autopilot_mode(); }
|
||||||
|
|
||||||
@ -254,6 +257,9 @@ public:
|
|||||||
// attributes of the mode
|
// attributes of the mode
|
||||||
bool is_autopilot_mode() const override { return true; }
|
bool is_autopilot_mode() const override { return true; }
|
||||||
|
|
||||||
|
// return if external control is allowed in this mode (Guided or Guided-within-Auto)
|
||||||
|
bool in_guided_mode() const override { return _submode == Auto_Guided; }
|
||||||
|
|
||||||
// return distance (in meters) to destination
|
// return distance (in meters) to destination
|
||||||
float get_distance_to_destination() const override;
|
float get_distance_to_destination() const override;
|
||||||
|
|
||||||
@ -282,7 +288,8 @@ protected:
|
|||||||
Auto_WP, // drive to a given location
|
Auto_WP, // drive to a given location
|
||||||
Auto_HeadingAndSpeed, // turn to a given heading
|
Auto_HeadingAndSpeed, // turn to a given heading
|
||||||
Auto_RTL, // perform RTL within auto mode
|
Auto_RTL, // perform RTL within auto mode
|
||||||
Auto_Loiter // perform Loiter within auto mode
|
Auto_Loiter, // perform Loiter within auto mode
|
||||||
|
Auto_Guided // handover control to external navigation system from within auto mode
|
||||||
} _submode;
|
} _submode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -301,11 +308,13 @@ private:
|
|||||||
bool verify_command(const AP_Mission::Mission_Command& cmd);
|
bool verify_command(const AP_Mission::Mission_Command& cmd);
|
||||||
void do_RTL(void);
|
void do_RTL(void);
|
||||||
void do_nav_wp(const AP_Mission::Mission_Command& cmd, bool always_stop_at_destination);
|
void do_nav_wp(const AP_Mission::Mission_Command& cmd, bool always_stop_at_destination);
|
||||||
|
void do_nav_guided_enable(const AP_Mission::Mission_Command& cmd);
|
||||||
void do_nav_set_yaw_speed(const AP_Mission::Mission_Command& cmd);
|
void do_nav_set_yaw_speed(const AP_Mission::Mission_Command& cmd);
|
||||||
bool verify_nav_wp(const AP_Mission::Mission_Command& cmd);
|
bool verify_nav_wp(const AP_Mission::Mission_Command& cmd);
|
||||||
bool verify_RTL();
|
bool verify_RTL();
|
||||||
bool verify_loiter_unlimited(const AP_Mission::Mission_Command& cmd);
|
bool verify_loiter_unlimited(const AP_Mission::Mission_Command& cmd);
|
||||||
bool verify_loiter_time(const AP_Mission::Mission_Command& cmd);
|
bool verify_loiter_time(const AP_Mission::Mission_Command& cmd);
|
||||||
|
bool verify_nav_guided_enable(const AP_Mission::Mission_Command& cmd);
|
||||||
bool verify_nav_set_yaw_speed();
|
bool verify_nav_set_yaw_speed();
|
||||||
void do_wait_delay(const AP_Mission::Mission_Command& cmd);
|
void do_wait_delay(const AP_Mission::Mission_Command& cmd);
|
||||||
void do_within_distance(const AP_Mission::Mission_Command& cmd);
|
void do_within_distance(const AP_Mission::Mission_Command& cmd);
|
||||||
@ -316,6 +325,8 @@ private:
|
|||||||
void do_set_reverse(const AP_Mission::Mission_Command& cmd);
|
void do_set_reverse(const AP_Mission::Mission_Command& cmd);
|
||||||
|
|
||||||
bool start_loiter();
|
bool start_loiter();
|
||||||
|
void start_guided(const Location& target_loc);
|
||||||
|
void send_guided_position_target();
|
||||||
|
|
||||||
enum Mis_Done_Behave {
|
enum Mis_Done_Behave {
|
||||||
MIS_DONE_BEHAVE_HOLD = 0,
|
MIS_DONE_BEHAVE_HOLD = 0,
|
||||||
@ -328,6 +339,11 @@ private:
|
|||||||
uint32_t loiter_start_time; // How long have we been loitering - The start time in millis
|
uint32_t loiter_start_time; // How long have we been loitering - The start time in millis
|
||||||
bool previously_reached_wp; // set to true if we have EVER reached the waypoint
|
bool previously_reached_wp; // set to true if we have EVER reached the waypoint
|
||||||
|
|
||||||
|
// Guided variables
|
||||||
|
Location guided_target; // location target sent to external navigation
|
||||||
|
bool guided_target_valid; // true if guided_target is valid
|
||||||
|
uint32_t guided_target_sent_ms; // system time that target was last sent to offboard navigation
|
||||||
|
|
||||||
// Conditional command
|
// Conditional command
|
||||||
// A value used in condition commands (eg delay, change alt, etc.)
|
// A value used in condition commands (eg delay, change alt, etc.)
|
||||||
// For example in a change altitude command, it is the altitude to change to.
|
// For example in a change altitude command, it is the altitude to change to.
|
||||||
@ -352,9 +368,15 @@ public:
|
|||||||
// attributes of the mode
|
// attributes of the mode
|
||||||
bool is_autopilot_mode() const override { return true; }
|
bool is_autopilot_mode() const override { return true; }
|
||||||
|
|
||||||
|
// return if external control is allowed in this mode (Guided or Guided-within-Auto)
|
||||||
|
bool in_guided_mode() const override { return true; }
|
||||||
|
|
||||||
// return distance (in meters) to destination
|
// return distance (in meters) to destination
|
||||||
float get_distance_to_destination() const override;
|
float get_distance_to_destination() const override;
|
||||||
|
|
||||||
|
// return true if vehicle has reached destination
|
||||||
|
bool reached_destination() override;
|
||||||
|
|
||||||
// set desired location, heading and speed
|
// set desired location, heading and speed
|
||||||
void set_desired_location(const struct Location& destination, float next_leg_bearing_cd = MODE_NEXT_HEADING_UNKNOWN) override;
|
void set_desired_location(const struct Location& destination, float next_leg_bearing_cd = MODE_NEXT_HEADING_UNKNOWN) override;
|
||||||
void set_desired_heading_and_speed(float yaw_angle_cd, float target_speed) override;
|
void set_desired_heading_and_speed(float yaw_angle_cd, float target_speed) override;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
#include "Rover.h"
|
#include "Rover.h"
|
||||||
|
|
||||||
|
#define AUTO_GUIDED_SEND_TARGET_MS 1000
|
||||||
|
|
||||||
bool ModeAuto::_enter()
|
bool ModeAuto::_enter()
|
||||||
{
|
{
|
||||||
// fail to enter auto if no mission commands
|
// fail to enter auto if no mission commands
|
||||||
@ -89,6 +91,14 @@ void ModeAuto::update()
|
|||||||
case Auto_Loiter:
|
case Auto_Loiter:
|
||||||
rover.mode_loiter.update();
|
rover.mode_loiter.update();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Auto_Guided:
|
||||||
|
{
|
||||||
|
// send location target to offboard navigation system
|
||||||
|
send_guided_position_target();
|
||||||
|
rover.mode_guided.update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,12 +123,25 @@ void ModeAuto::set_desired_location(const struct Location& destination, float ne
|
|||||||
// return true if vehicle has reached or even passed destination
|
// return true if vehicle has reached or even passed destination
|
||||||
bool ModeAuto::reached_destination()
|
bool ModeAuto::reached_destination()
|
||||||
{
|
{
|
||||||
if (_submode == Auto_WP) {
|
switch (_submode) {
|
||||||
|
case Auto_WP:
|
||||||
return _reached_destination;
|
return _reached_destination;
|
||||||
}
|
break;
|
||||||
if (_submode == Auto_RTL) {
|
case Auto_HeadingAndSpeed:
|
||||||
|
// always return true because this is the safer option to allow missions to continue
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case Auto_RTL:
|
||||||
return rover.mode_rtl.reached_destination();
|
return rover.mode_rtl.reached_destination();
|
||||||
|
break;
|
||||||
|
case Auto_Loiter:
|
||||||
|
return rover.mode_loiter.reached_destination();
|
||||||
|
break;
|
||||||
|
case Auto_Guided:
|
||||||
|
return rover.mode_guided.reached_destination();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should never reach here but just in case, return true to allow missions to continue
|
// we should never reach here but just in case, return true to allow missions to continue
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -151,6 +174,50 @@ void ModeAuto::start_RTL()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hand over control to external navigation controller in AUTO mode
|
||||||
|
void ModeAuto::start_guided(const Location& loc)
|
||||||
|
{
|
||||||
|
if (rover.mode_guided.enter()) {
|
||||||
|
_submode = Auto_Guided;
|
||||||
|
|
||||||
|
// initialise guided start time and position as reference for limit checking
|
||||||
|
//rover.mode_guided.limit_init_time_and_pos();
|
||||||
|
|
||||||
|
// sanity check target location
|
||||||
|
Location loc_sanitised = loc;
|
||||||
|
if ((loc_sanitised.lat != 0) || (loc_sanitised.lng != 0)) {
|
||||||
|
location_sanitize(rover.current_loc, loc_sanitised);
|
||||||
|
guided_target = loc_sanitised;
|
||||||
|
guided_target_valid = true;
|
||||||
|
} else {
|
||||||
|
guided_target_valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send latest position target to offboard navigation system
|
||||||
|
void ModeAuto::send_guided_position_target()
|
||||||
|
{
|
||||||
|
if (!guided_target_valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send at maximum of 1hz
|
||||||
|
uint32_t now_ms = AP_HAL::millis();
|
||||||
|
if ((guided_target_sent_ms == 0) || (now_ms - guided_target_sent_ms > AUTO_GUIDED_SEND_TARGET_MS)) {
|
||||||
|
guided_target_sent_ms = now_ms;
|
||||||
|
|
||||||
|
// get system id and component id of offboard navigation system
|
||||||
|
uint8_t sysid = 0;
|
||||||
|
uint8_t compid = 0;
|
||||||
|
mavlink_channel_t chan;
|
||||||
|
if (GCS_MAVLINK::find_by_mavtype(MAV_TYPE_ONBOARD_CONTROLLER, sysid, compid, chan)) {
|
||||||
|
gcs().chan(chan-MAVLINK_COMM_0).send_set_position_target_global_int(sysid, compid, guided_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
check for triggering of start of auto mode
|
check for triggering of start of auto mode
|
||||||
*/
|
*/
|
||||||
|
@ -116,6 +116,24 @@ float ModeGuided::get_distance_to_destination() const
|
|||||||
return _distance_to_destination;
|
return _distance_to_destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return true if vehicle has reached or even passed destination
|
||||||
|
bool ModeGuided::reached_destination()
|
||||||
|
{
|
||||||
|
switch (_guided_mode) {
|
||||||
|
case Guided_WP:
|
||||||
|
return _reached_destination;
|
||||||
|
break;
|
||||||
|
case Guided_HeadingAndSpeed:
|
||||||
|
case Guided_TurnRateAndSpeed:
|
||||||
|
case Guided_Loiter:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we should never reach here but just in case, return true is the safer option
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// set desired location
|
// set desired location
|
||||||
void ModeGuided::set_desired_location(const struct Location& destination,
|
void ModeGuided::set_desired_location(const struct Location& destination,
|
||||||
float next_leg_bearing_cd)
|
float next_leg_bearing_cd)
|
||||||
|
Loading…
Reference in New Issue
Block a user