|
|
|
@ -10,7 +10,8 @@
@@ -10,7 +10,8 @@
|
|
|
|
|
bool Copter::acro_init(bool ignore_checks) |
|
|
|
|
{ |
|
|
|
|
// if landed and the mode we're switching from does not have manual throttle and the throttle stick is too high
|
|
|
|
|
if (motors.armed() && ap.land_complete && !mode_has_manual_throttle(control_mode) && (get_pilot_desired_throttle(channel_throttle->get_control_in()) > get_non_takeoff_throttle())) { |
|
|
|
|
if (motors.armed() && ap.land_complete && !mode_has_manual_throttle(control_mode) && |
|
|
|
|
(get_pilot_desired_throttle(channel_throttle->get_control_in(), g2.acro_thr_mid) > get_non_takeoff_throttle())) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
// set target altitude to zero for reporting
|
|
|
|
@ -42,7 +43,7 @@ void Copter::acro_run()
@@ -42,7 +43,7 @@ void Copter::acro_run()
|
|
|
|
|
get_pilot_desired_angle_rates(channel_roll->get_control_in(), channel_pitch->get_control_in(), channel_yaw->get_control_in(), target_roll, target_pitch, target_yaw); |
|
|
|
|
|
|
|
|
|
// get pilot's desired throttle
|
|
|
|
|
pilot_throttle_scaled = get_pilot_desired_throttle(channel_throttle->get_control_in()); |
|
|
|
|
pilot_throttle_scaled = get_pilot_desired_throttle(channel_throttle->get_control_in(), g2.acro_thr_mid); |
|
|
|
|
|
|
|
|
|
// run attitude controller
|
|
|
|
|
attitude_control.input_rate_bf_roll_pitch_yaw(target_roll, target_pitch, target_yaw); |
|
|
|
@ -69,7 +70,7 @@ void Copter::get_pilot_desired_angle_rates(int16_t roll_in, int16_t pitch_in, in
@@ -69,7 +70,7 @@ void Copter::get_pilot_desired_angle_rates(int16_t roll_in, int16_t pitch_in, in
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// calculate roll, pitch rate requests
|
|
|
|
|
if (g.acro_expo <= 0) { |
|
|
|
|
if (g.acro_rp_expo <= 0) { |
|
|
|
|
rate_bf_request.x = roll_in * g.acro_rp_p; |
|
|
|
|
rate_bf_request.y = pitch_in * g.acro_rp_p; |
|
|
|
|
} else { |
|
|
|
@ -77,25 +78,42 @@ void Copter::get_pilot_desired_angle_rates(int16_t roll_in, int16_t pitch_in, in
@@ -77,25 +78,42 @@ void Copter::get_pilot_desired_angle_rates(int16_t roll_in, int16_t pitch_in, in
|
|
|
|
|
float rp_in, rp_in3, rp_out; |
|
|
|
|
|
|
|
|
|
// range check expo
|
|
|
|
|
if (g.acro_expo > 1.0f) { |
|
|
|
|
g.acro_expo = 1.0f; |
|
|
|
|
if (g.acro_rp_expo > 1.0f) { |
|
|
|
|
g.acro_rp_expo = 1.0f; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// roll expo
|
|
|
|
|
rp_in = float(roll_in)/ROLL_PITCH_INPUT_MAX; |
|
|
|
|
rp_in3 = rp_in*rp_in*rp_in; |
|
|
|
|
rp_out = (g.acro_expo * rp_in3) + ((1 - g.acro_expo) * rp_in); |
|
|
|
|
rp_out = (g.acro_rp_expo * rp_in3) + ((1.0f - g.acro_rp_expo) * rp_in); |
|
|
|
|
rate_bf_request.x = ROLL_PITCH_INPUT_MAX * rp_out * g.acro_rp_p; |
|
|
|
|
|
|
|
|
|
// pitch expo
|
|
|
|
|
rp_in = float(pitch_in)/ROLL_PITCH_INPUT_MAX; |
|
|
|
|
rp_in3 = rp_in*rp_in*rp_in; |
|
|
|
|
rp_out = (g.acro_expo * rp_in3) + ((1 - g.acro_expo) * rp_in); |
|
|
|
|
rp_out = (g.acro_rp_expo * rp_in3) + ((1.0f - g.acro_rp_expo) * rp_in); |
|
|
|
|
rate_bf_request.y = ROLL_PITCH_INPUT_MAX * rp_out * g.acro_rp_p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// calculate yaw rate request
|
|
|
|
|
if (g.acro_rp_expo <= 0) { |
|
|
|
|
rate_bf_request.z = yaw_in * g.acro_yaw_p; |
|
|
|
|
} else { |
|
|
|
|
// expo variables
|
|
|
|
|
float y_in, y_in3, y_out; |
|
|
|
|
|
|
|
|
|
// range check expo
|
|
|
|
|
if (g2.acro_y_expo > 1.0f || g2.acro_y_expo < 0.5f) { |
|
|
|
|
g2.acro_y_expo = 1.0f; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// yaw expo
|
|
|
|
|
y_in = float(yaw_in)/ROLL_PITCH_INPUT_MAX; |
|
|
|
|
y_in3 = y_in*y_in*y_in; |
|
|
|
|
y_out = (g2.acro_y_expo * y_in3) + ((1.0f - g2.acro_y_expo) * y_in); |
|
|
|
|
rate_bf_request.z = ROLL_PITCH_INPUT_MAX * y_out * g.acro_yaw_p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// calculate earth frame rate corrections to pull the copter back to level while in ACRO mode
|
|
|
|
|
|
|
|
|
|