ardupilot/ArduCopter/autoyaw.cpp
Peter Barker 676d75c391 Copter: correct namespacing of Copter modes
This makes us look like Rover and Plane in terms of namespacing for the
Mode classes, and removes a wart where we #include mode.h in the middle
of the Mode class.

This was done mechanically for the most part.

I've had to remove the convenience reference for ap as part of this.
2019-06-11 09:18:22 +09:00

219 lines
6.7 KiB
C++

#include "Copter.h"
Mode::AutoYaw Mode::auto_yaw;
// roi_yaw - returns heading towards location held in roi
float Mode::AutoYaw::roi_yaw()
{
roi_yaw_counter++;
if (roi_yaw_counter >= 4) {
roi_yaw_counter = 0;
_roi_yaw = get_bearing_cd(copter.inertial_nav.get_position(), roi);
}
return _roi_yaw;
}
float Mode::AutoYaw::look_ahead_yaw()
{
const Vector3f& vel = copter.inertial_nav.get_velocity();
float speed = norm(vel.x,vel.y);
// Commanded Yaw to automatically look ahead.
if (copter.position_ok() && (speed > YAW_LOOK_AHEAD_MIN_SPEED)) {
_look_ahead_yaw = degrees(atan2f(vel.y,vel.x))*100.0f;
}
return _look_ahead_yaw;
}
void Mode::AutoYaw::set_mode_to_default(bool rtl)
{
set_mode(default_mode(rtl));
}
// default_mode - returns auto_yaw.mode() based on WP_YAW_BEHAVIOR parameter
// set rtl parameter to true if this is during an RTL
autopilot_yaw_mode Mode::AutoYaw::default_mode(bool rtl) const
{
switch (copter.g.wp_yaw_behavior) {
case WP_YAW_BEHAVIOR_NONE:
return AUTO_YAW_HOLD;
case WP_YAW_BEHAVIOR_LOOK_AT_NEXT_WP_EXCEPT_RTL:
if (rtl) {
return AUTO_YAW_HOLD;
} else {
return AUTO_YAW_LOOK_AT_NEXT_WP;
}
case WP_YAW_BEHAVIOR_LOOK_AHEAD:
return AUTO_YAW_LOOK_AHEAD;
case WP_YAW_BEHAVIOR_LOOK_AT_NEXT_WP:
default:
return AUTO_YAW_LOOK_AT_NEXT_WP;
}
}
// set_mode - sets the yaw mode for auto
void Mode::AutoYaw::set_mode(autopilot_yaw_mode yaw_mode)
{
// return immediately if no change
if (_mode == yaw_mode) {
return;
}
_mode = yaw_mode;
// perform initialisation
switch (_mode) {
case AUTO_YAW_LOOK_AT_NEXT_WP:
// wpnav will initialise heading when wpnav's set_destination method is called
break;
case AUTO_YAW_ROI:
// look ahead until we know otherwise
_roi_yaw = copter.ahrs.yaw_sensor;
break;
case AUTO_YAW_FIXED:
// keep heading pointing in the direction held in fixed_yaw
// caller should set the fixed_yaw
break;
case AUTO_YAW_LOOK_AHEAD:
// Commanded Yaw to automatically look ahead.
_look_ahead_yaw = copter.ahrs.yaw_sensor;
break;
case AUTO_YAW_RESETTOARMEDYAW:
// initial_armed_bearing will be set during arming so no init required
break;
case AUTO_YAW_RATE:
// initialise target yaw rate to zero
_rate_cds = 0.0f;
break;
}
}
// set_fixed_yaw - sets the yaw look at heading for auto mode
void Mode::AutoYaw::set_fixed_yaw(float angle_deg, float turn_rate_dps, int8_t direction, bool relative_angle)
{
const int32_t curr_yaw_target = copter.attitude_control->get_att_target_euler_cd().z;
// calculate final angle as relative to vehicle heading or absolute
if (!relative_angle) {
// absolute angle
_fixed_yaw = wrap_360_cd(angle_deg * 100);
} else {
// relative angle
if (direction < 0) {
angle_deg = -angle_deg;
}
_fixed_yaw = wrap_360_cd((angle_deg * 100) + curr_yaw_target);
}
// get turn speed
if (is_zero(turn_rate_dps)) {
// default to regular auto slew rate
_fixed_yaw_slewrate = AUTO_YAW_SLEW_RATE;
} else {
const int32_t turn_rate = (wrap_180_cd(_fixed_yaw - curr_yaw_target) / 100) / turn_rate_dps;
_fixed_yaw_slewrate = constrain_int32(turn_rate, 1, 360); // deg / sec
}
// set yaw mode
set_mode(AUTO_YAW_FIXED);
// TO-DO: restore support for clockwise and counter clockwise rotation held in cmd.content.yaw.direction. 1 = clockwise, -1 = counterclockwise
}
// set_roi - sets the yaw to look at roi for auto mode
void Mode::AutoYaw::set_roi(const Location &roi_location)
{
// if location is zero lat, lon and altitude turn off ROI
if (roi_location.alt == 0 && roi_location.lat == 0 && roi_location.lng == 0) {
// set auto yaw mode back to default assuming the active command is a waypoint command. A more sophisticated method is required to ensure we return to the proper yaw control for the active command
auto_yaw.set_mode_to_default(false);
#if MOUNT == ENABLED
// switch off the camera tracking if enabled
if (copter.camera_mount.get_mode() == MAV_MOUNT_MODE_GPS_POINT) {
copter.camera_mount.set_mode_to_default();
}
#endif // MOUNT == ENABLED
} else {
#if MOUNT == ENABLED
// check if mount type requires us to rotate the quad
if (!copter.camera_mount.has_pan_control()) {
if (roi_location.get_vector_from_origin_NEU(roi)) {
auto_yaw.set_mode(AUTO_YAW_ROI);
}
}
// send the command to the camera mount
copter.camera_mount.set_roi_target(roi_location);
// TO-DO: expand handling of the do_nav_roi to support all modes of the MAVLink. Currently we only handle mode 4 (see below)
// 0: do nothing
// 1: point at next waypoint
// 2: point at a waypoint taken from WP# parameter (2nd parameter?)
// 3: point at a location given by alt, lon, lat parameters
// 4: point at a target given a target id (can't be implemented)
#else
// if we have no camera mount aim the quad at the location
if (roi_location.get_vector_from_origin_NEU(roi)) {
auto_yaw.set_mode(AUTO_YAW_ROI);
}
#endif // MOUNT == ENABLED
}
}
// set auto yaw rate in centi-degrees per second
void Mode::AutoYaw::set_rate(float turn_rate_cds)
{
set_mode(AUTO_YAW_RATE);
_rate_cds = turn_rate_cds;
}
// yaw - returns target heading depending upon auto_yaw.mode()
float Mode::AutoYaw::yaw()
{
switch (_mode) {
case AUTO_YAW_ROI:
// point towards a location held in roi
return roi_yaw();
case AUTO_YAW_FIXED:
// keep heading pointing in the direction held in fixed_yaw
// with no pilot input allowed
return _fixed_yaw;
case AUTO_YAW_LOOK_AHEAD:
// Commanded Yaw to automatically look ahead.
return look_ahead_yaw();
case AUTO_YAW_RESETTOARMEDYAW:
// changes yaw to be same as when quad was armed
return copter.initial_armed_bearing;
case AUTO_YAW_LOOK_AT_NEXT_WP:
default:
// point towards next waypoint.
// we don't use wp_bearing because we don't want the copter to turn too much during flight
return copter.wp_nav->get_yaw();
}
}
// returns yaw rate normally set by SET_POSITION_TARGET mavlink
// messages (positive is clockwise, negative is counter clockwise)
float Mode::AutoYaw::rate_cds() const
{
if (_mode == AUTO_YAW_RATE) {
return _rate_cds;
}
// return zero turn rate (this should never happen)
return 0.0f;
}