|
|
|
@ -67,6 +67,11 @@ void AC_Circle::init(const Vector3f& center)
@@ -67,6 +67,11 @@ void AC_Circle::init(const Vector3f& center)
|
|
|
|
|
|
|
|
|
|
// set start angle from position
|
|
|
|
|
init_start_angle(false); |
|
|
|
|
// 绕8字初始化
|
|
|
|
|
stage = 0; |
|
|
|
|
is_cw_turn = true; |
|
|
|
|
_circle_8_finish = false; |
|
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO, "--- AC_Circle x:%.2f,y:%.2f \n",_center.x,_center.y);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// init - initialise circle controller setting center using stopping point and projecting out based on the copter's heading
|
|
|
|
@ -95,6 +100,10 @@ void AC_Circle::init()
@@ -95,6 +100,10 @@ void AC_Circle::init()
|
|
|
|
|
|
|
|
|
|
// set starting angle from vehicle heading
|
|
|
|
|
init_start_angle(true); |
|
|
|
|
// 绕8字初始化
|
|
|
|
|
stage = 0; |
|
|
|
|
is_cw_turn = true; |
|
|
|
|
_circle_8_finish = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// set_circle_rate - set circle rate in degrees per second
|
|
|
|
@ -106,6 +115,127 @@ void AC_Circle::set_rate(float deg_per_sec)
@@ -106,6 +115,127 @@ void AC_Circle::set_rate(float deg_per_sec)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 执行绕8字 |
|
|
|
|
*
|
|
|
|
|
* @return true
|
|
|
|
|
* @return false
|
|
|
|
|
*/ |
|
|
|
|
bool AC_Circle::turn_2_circle() |
|
|
|
|
{ |
|
|
|
|
// calculate dt
|
|
|
|
|
bool ret = false; |
|
|
|
|
_circle_8_finish = false; |
|
|
|
|
float dt = _pos_control.time_since_last_xy_update();//位置更新时间,单位是s
|
|
|
|
|
if (dt >= 0.2f) { |
|
|
|
|
dt = 0.0f; |
|
|
|
|
} |
|
|
|
|
//斜坡角速度到最大 ramp angular velocity to maximum
|
|
|
|
|
if (_angular_vel < _angular_vel_max) { |
|
|
|
|
_angular_vel += fabsf(_angular_accel) * dt; |
|
|
|
|
_angular_vel = MIN(_angular_vel, _angular_vel_max); |
|
|
|
|
} |
|
|
|
|
if (_angular_vel > _angular_vel_max) { |
|
|
|
|
_angular_vel -= fabsf(_angular_accel) * dt; |
|
|
|
|
_angular_vel = MAX(_angular_vel, _angular_vel_max); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//更新目标角和总的角度 update the target angle and total angle traveled
|
|
|
|
|
float angle_change = _angular_vel * dt; |
|
|
|
|
float _fabs_total; // circle count,float
|
|
|
|
|
// calculate target position
|
|
|
|
|
Vector3f target; |
|
|
|
|
const Vector3f curr_pos = _inav.get_position(); |
|
|
|
|
Vector3f new_pos; |
|
|
|
|
float bearing_rad = atan2f(curr_pos.y-_center.y,curr_pos.x-_center.x); |
|
|
|
|
static float last_bearing_rad ;
|
|
|
|
|
const Vector3f& stopping_point = _pos_control.get_pos_target(); |
|
|
|
|
switch (stage) |
|
|
|
|
{ |
|
|
|
|
case 0: |
|
|
|
|
// _angle = wrap_PI(_ahrs.yaw-M_PI);
|
|
|
|
|
_pos_control.set_desired_accel_xy(0.0f,0.0f); |
|
|
|
|
_pos_control.set_desired_velocity_xy(0.0f,0.0f); |
|
|
|
|
_pos_control.init_xy_controller(); |
|
|
|
|
// set initial position target to reasonable stopping point
|
|
|
|
|
_pos_control.set_target_to_stopping_point_xy(); |
|
|
|
|
_pos_control.set_target_to_stopping_point_z(); |
|
|
|
|
// get stopping point
|
|
|
|
|
// set circle center to circle_radius ahead of stopping point
|
|
|
|
|
_center.x = stopping_point.x + _radius * _ahrs.cos_yaw(); |
|
|
|
|
_center.y = stopping_point.y + _radius * _ahrs.sin_yaw(); |
|
|
|
|
_center.z = stopping_point.z; |
|
|
|
|
// calculate velocities
|
|
|
|
|
calc_velocities(true); |
|
|
|
|
// set starting angle from vehicle heading
|
|
|
|
|
init_start_angle(true); |
|
|
|
|
last_bearing_rad = bearing_rad; |
|
|
|
|
stage = 1; |
|
|
|
|
break; |
|
|
|
|
case 1: |
|
|
|
|
{ |
|
|
|
|
_angle += angle_change; |
|
|
|
|
_angle = wrap_PI(_angle); |
|
|
|
|
_angle_total += angle_change; |
|
|
|
|
_fabs_total = fabsf(get_angle_total()/M_2PI); |
|
|
|
|
target.x = _center.x + _radius * cosf(_angle); |
|
|
|
|
target.y = _center.y - _radius * sinf(_angle); |
|
|
|
|
if(fabs(last_bearing_rad - bearing_rad) < 0.01 && _fabs_total > 0.9){ |
|
|
|
|
_center.x = _center.x + 2 * _radius* cosf(bearing_rad); |
|
|
|
|
_center.y = _center.y + 2 * _radius* sinf(bearing_rad); |
|
|
|
|
last_bearing_rad = atan2f(curr_pos.y-_center.y,curr_pos.x-_center.x); |
|
|
|
|
is_cw_turn = false; |
|
|
|
|
// calculate velocities
|
|
|
|
|
calc_velocities(false); |
|
|
|
|
init_start_angle(false); |
|
|
|
|
_angle_total = 0; |
|
|
|
|
stage = 2; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
{ |
|
|
|
|
_angle += angle_change; |
|
|
|
|
_angle = wrap_PI(_angle); |
|
|
|
|
_angle_total += angle_change; |
|
|
|
|
_fabs_total = fabsf(get_angle_total()/M_2PI); |
|
|
|
|
target.x = _center.x + _radius * cosf(-_angle); |
|
|
|
|
target.y = _center.y - _radius * sinf(-_angle); |
|
|
|
|
if(fabs(last_bearing_rad - bearing_rad) < 0.01 && _fabs_total > 0.9){ |
|
|
|
|
_angle_total = 0; |
|
|
|
|
stage = 3; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
// _angle = wrap_PI(_ahrs.yaw-M_PI);
|
|
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO, "[c]finish angle::%.2f,y:%.2f \n",_angle,_ahrs.yaw);
|
|
|
|
|
stage = 4; |
|
|
|
|
break; |
|
|
|
|
case 4: |
|
|
|
|
ret = true; |
|
|
|
|
_circle_8_finish = true; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
target.z = _pos_control.get_alt_target(); |
|
|
|
|
// update position controller target
|
|
|
|
|
_pos_control.set_xy_target(target.x, target.y); |
|
|
|
|
// heading is from vehicle to center of circle
|
|
|
|
|
_yaw = get_bearing_cd(_inav.get_position(), _center); |
|
|
|
|
if(is_cw_turn){ |
|
|
|
|
_yaw += 9000; |
|
|
|
|
}else{ |
|
|
|
|
_yaw += 27000; |
|
|
|
|
} |
|
|
|
|
// update position controller更新位置控制器
|
|
|
|
|
_pos_control.update_xy_controller(); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// update - update circle controller
|
|
|
|
|
void AC_Circle::update() |
|
|
|
|
{ |
|
|
|
|