2018-03-30 02:49:46 -03:00
# include "Copter.h"
2019-05-09 23:18:49 -03:00
Mode : : AutoYaw Mode : : auto_yaw ;
2018-03-30 02:49:46 -03:00
// roi_yaw - returns heading towards location held in roi
2019-05-09 23:18:49 -03:00
float Mode : : AutoYaw : : roi_yaw ( )
2018-03-30 02:49:46 -03:00
{
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 ;
}
2019-05-09 23:18:49 -03:00
float Mode : : AutoYaw : : look_ahead_yaw ( )
2018-03-30 02:49:46 -03:00
{
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 ;
}
2019-05-09 23:18:49 -03:00
void Mode : : AutoYaw : : set_mode_to_default ( bool rtl )
2018-03-30 02:49:46 -03:00
{
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
2019-05-09 23:18:49 -03:00
autopilot_yaw_mode Mode : : AutoYaw : : default_mode ( bool rtl ) const
2018-03-30 02:49:46 -03:00
{
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
2019-05-09 23:18:49 -03:00
void Mode : : AutoYaw : : set_mode ( autopilot_yaw_mode yaw_mode )
2018-03-30 02:49:46 -03:00
{
// 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 ;
2020-04-21 08:50:25 -03:00
case AUTO_YAW_CIRCLE :
// no initialisation required
break ;
2018-03-30 02:49:46 -03:00
}
}
// set_fixed_yaw - sets the yaw look at heading for auto mode
2019-05-09 23:18:49 -03:00
void Mode : : AutoYaw : : set_fixed_yaw ( float angle_deg , float turn_rate_dps , int8_t direction , bool relative_angle )
2018-03-30 02:49:46 -03:00
{
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
2019-05-09 23:18:49 -03:00
void Mode : : AutoYaw : : set_roi ( const Location & roi_location )
2018-03-30 02:49:46 -03:00
{
// 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 ) ;
2020-07-24 14:02:40 -03:00
# if HAL_MOUNT_ENABLED
2018-03-30 02:49:46 -03:00
// 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 ( ) ;
}
2020-07-24 14:02:40 -03:00
# endif // HAL_MOUNT_ENABLED
2018-03-30 02:49:46 -03:00
} else {
2020-07-24 14:02:40 -03:00
# if HAL_MOUNT_ENABLED
2018-03-30 02:49:46 -03:00
// check if mount type requires us to rotate the quad
if ( ! copter . camera_mount . has_pan_control ( ) ) {
2019-02-04 18:08:19 -04:00
if ( roi_location . get_vector_from_origin_NEU ( roi ) ) {
auto_yaw . set_mode ( AUTO_YAW_ROI ) ;
}
2018-03-30 02:49:46 -03:00
}
// 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
2019-02-04 18:08:19 -04:00
if ( roi_location . get_vector_from_origin_NEU ( roi ) ) {
auto_yaw . set_mode ( AUTO_YAW_ROI ) ;
}
2020-07-24 14:02:40 -03:00
# endif // HAL_MOUNT_ENABLED
2018-03-30 02:49:46 -03:00
}
}
// set auto yaw rate in centi-degrees per second
2019-05-09 23:18:49 -03:00
void Mode : : AutoYaw : : set_rate ( float turn_rate_cds )
2018-03-30 02:49:46 -03:00
{
set_mode ( AUTO_YAW_RATE ) ;
_rate_cds = turn_rate_cds ;
}
// yaw - returns target heading depending upon auto_yaw.mode()
2019-05-09 23:18:49 -03:00
float Mode : : AutoYaw : : yaw ( )
2018-03-30 02:49:46 -03:00
{
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 ;
2020-04-21 08:50:25 -03:00
case AUTO_YAW_CIRCLE :
2020-10-01 19:30:30 -03:00
# if MODE_CIRCLE_ENABLED
2020-04-21 08:50:25 -03:00
if ( copter . circle_nav - > is_active ( ) ) {
return copter . circle_nav - > get_yaw ( ) ;
}
2020-10-01 19:30:30 -03:00
# endif
2020-04-21 08:50:25 -03:00
// return the current attitude target
return wrap_360_cd ( copter . attitude_control - > get_att_target_euler_cd ( ) . z ) ;
2018-03-30 02:49:46 -03:00
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)
2019-05-09 23:18:49 -03:00
float Mode : : AutoYaw : : rate_cds ( ) const
2018-03-30 02:49:46 -03:00
{
if ( _mode = = AUTO_YAW_RATE ) {
return _rate_cds ;
}
// return zero turn rate (this should never happen)
return 0.0f ;
}