Browse Source

Copter: support SET_GPS_GLOBAL_ORIGIN

also remove setting of origin from DO_SET_HOME command
initialise ekf_origin location when consuming SET_GPS_GLOBAL_ORIGIN
set_ekf_origin performs sanity check on location
master
Randy Mackay 8 years ago
parent
commit
1b3cc9289b
  1. 1
      ArduCopter/Copter.h
  2. 20
      ArduCopter/GCS_Mavlink.cpp
  3. 36
      ArduCopter/commands.cpp

1
ArduCopter/Copter.h

@ -772,6 +772,7 @@ private:
void set_home_to_current_location_inflight(); void set_home_to_current_location_inflight();
bool set_home_to_current_location(bool lock); bool set_home_to_current_location(bool lock);
bool set_home(const Location& loc, bool lock); bool set_home(const Location& loc, bool lock);
void set_ekf_origin(const Location& loc);
bool far_from_EKF_origin(const Location& loc); bool far_from_EKF_origin(const Location& loc);
void set_system_time_from_GPS(); void set_system_time_from_GPS();
void exit_mission(); void exit_mission();

20
ArduCopter/GCS_Mavlink.cpp

@ -742,6 +742,22 @@ void GCS_MAVLINK_Copter::handleMessage(mavlink_message_t* msg)
break; break;
} }
case MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN:
{
mavlink_set_gps_global_origin_t packet;
mavlink_msg_set_gps_global_origin_decode(msg, &packet);
// sanity check location
if (!check_latlng(packet.latitude, packet.longitude)) {
break;
}
Location ekf_origin {};
ekf_origin.lat = packet.latitude;
ekf_origin.lng = packet.longitude;
ekf_origin.alt = packet.altitude / 10;
copter.set_ekf_origin(ekf_origin);
break;
}
case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: // MAV ID: 66 case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: // MAV ID: 66
{ {
handle_request_data_stream(msg, false); handle_request_data_stream(msg, false);
@ -1051,6 +1067,10 @@ void GCS_MAVLINK_Copter::handleMessage(mavlink_message_t* msg)
case MAV_CMD_GET_HOME_POSITION: case MAV_CMD_GET_HOME_POSITION:
if (copter.ap.home_state != HOME_UNSET) { if (copter.ap.home_state != HOME_UNSET) {
send_home(copter.ahrs.get_home()); send_home(copter.ahrs.get_home());
Location ekf_origin;
if (copter.ahrs.get_origin(ekf_origin)) {
send_ekf_origin(ekf_origin);
}
result = MAV_RESULT_ACCEPTED; result = MAV_RESULT_ACCEPTED;
} else { } else {
result = MAV_RESULT_FAILED; result = MAV_RESULT_FAILED;

36
ArduCopter/commands.cpp

@ -55,11 +55,10 @@ bool Copter::set_home(const Location& loc, bool lock)
return false; return false;
} }
// set EKF origin to home if it hasn't been set yet and vehicle is disarmed // check EKF origin has been set
// this is required to allowing flying in AUTO and GUIDED with only an optical flow
Location ekf_origin; Location ekf_origin;
if (!motors->armed() && !ahrs.get_origin(ekf_origin)) { if (!ahrs.get_origin(ekf_origin)) {
ahrs.set_origin(loc); return false;
} }
// check home is close to EKF origin // check home is close to EKF origin
@ -94,13 +93,40 @@ bool Copter::set_home(const Location& loc, bool lock)
// log ahrs home and ekf origin dataflash // log ahrs home and ekf origin dataflash
Log_Write_Home_And_Origin(); Log_Write_Home_And_Origin();
// send new home location to GCS // send new home and ekf origin to GCS
gcs().send_home(loc); gcs().send_home(loc);
gcs().send_ekf_origin(ekf_origin);
// return success // return success
return true; return true;
} }
// sets ekf_origin if it has not been set.
// should only be used when there is no GPS to provide an absolute position
void Copter::set_ekf_origin(const Location& loc)
{
// check location is valid
if (!check_latlng(loc)) {
return;
}
// check EKF origin has already been set
Location ekf_origin;
if (ahrs.get_origin(ekf_origin)) {
return;
}
if (!ahrs.set_origin(loc)) {
return;
}
// log ahrs home and ekf origin dataflash
Log_Write_Home_And_Origin();
// send ekf origin to GCS
gcs().send_ekf_origin(loc);
}
// far_from_EKF_origin - checks if a location is too far from the EKF origin // far_from_EKF_origin - checks if a location is too far from the EKF origin
// returns true if too far // returns true if too far
bool Copter::far_from_EKF_origin(const Location& loc) bool Copter::far_from_EKF_origin(const Location& loc)

Loading…
Cancel
Save