mirror of https://github.com/ArduPilot/ardupilot
Plane: apply elevon and vtail mixers after SRV_Channel remap
this is needed to ensure that changes in RCn_MIN/MAX don't cause changes in the output handling for elevon nd vtail planes
This commit is contained in:
parent
4a9ddf52e0
commit
be1109174e
|
@ -1042,6 +1042,7 @@ private:
|
||||||
void set_servos_controlled(void);
|
void set_servos_controlled(void);
|
||||||
void set_servos_old_elevons(void);
|
void set_servos_old_elevons(void);
|
||||||
void set_servos_flaps(void);
|
void set_servos_flaps(void);
|
||||||
|
void servo_output_mixers(void);
|
||||||
void servos_output(void);
|
void servos_output(void);
|
||||||
void throttle_watt_limiter(int8_t &min_throttle, int8_t &max_throttle);
|
void throttle_watt_limiter(int8_t &min_throttle, int8_t &max_throttle);
|
||||||
bool allow_reverse_thrust(void);
|
bool allow_reverse_thrust(void);
|
||||||
|
|
|
@ -76,12 +76,6 @@ void Plane::failsafe_check(void)
|
||||||
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_rudder, rudder);
|
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_rudder, rudder);
|
||||||
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_steering, rudder);
|
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_steering, rudder);
|
||||||
|
|
||||||
if (g.vtail_output != MIXING_DISABLED) {
|
|
||||||
channel_output_mixer(g.vtail_output, channel_pitch, channel_rudder);
|
|
||||||
} else if (g.elevon_output != MIXING_DISABLED) {
|
|
||||||
channel_output_mixer(g.elevon_output, channel_pitch, channel_roll);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is to allow the failsafe module to deliberately crash
|
// this is to allow the failsafe module to deliberately crash
|
||||||
// the plane. Only used in extreme circumstances to meet the
|
// the plane. Only used in extreme circumstances to meet the
|
||||||
// OBC rules
|
// OBC rules
|
||||||
|
|
|
@ -602,6 +602,57 @@ void Plane::set_servos_flaps(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
apply vtail and elevon mixers
|
||||||
|
the rewrites radio_out for the corresponding channels
|
||||||
|
*/
|
||||||
|
void Plane::servo_output_mixers(void)
|
||||||
|
{
|
||||||
|
if (g.vtail_output != MIXING_DISABLED) {
|
||||||
|
channel_output_mixer(g.vtail_output, channel_pitch, channel_rudder);
|
||||||
|
} else if (g.elevon_output != MIXING_DISABLED) {
|
||||||
|
channel_output_mixer(g.elevon_output, channel_pitch, channel_roll);
|
||||||
|
// if (both) differential spoilers setup then apply rudder
|
||||||
|
// control into splitting the two elevons on the side of
|
||||||
|
// the aircraft where we want to induce additional drag:
|
||||||
|
if (RC_Channel_aux::function_assigned(RC_Channel_aux::k_dspoiler1) &&
|
||||||
|
RC_Channel_aux::function_assigned(RC_Channel_aux::k_dspoiler2)) {
|
||||||
|
int16_t ch3 = channel_roll->get_radio_out(); //diff spoiler 1
|
||||||
|
int16_t ch4 = channel_pitch->get_radio_out(); //diff spoiler 2
|
||||||
|
// convert rudder-servo output (-4500 to 4500) to PWM offset
|
||||||
|
// value (-500 to 500) and multiply by DSPOILR_RUD_RATE/100
|
||||||
|
// (rudder->servo_out * 500 / SERVO_MAX * dspoiler_rud_rate/100):
|
||||||
|
int16_t ruddVal = (int16_t)((int32_t)(channel_rudder->get_servo_out()) *
|
||||||
|
g.dspoiler_rud_rate / (SERVO_MAX/5));
|
||||||
|
if (ruddVal != 0) { //if nonzero rudder then apply to spoilers
|
||||||
|
int16_t ch1 = ch3; //elevon 1
|
||||||
|
int16_t ch2 = ch4; //elevon 2
|
||||||
|
if (ruddVal > 0) { //apply rudder to right or left side
|
||||||
|
ch1 += ruddVal;
|
||||||
|
ch3 -= ruddVal;
|
||||||
|
} else {
|
||||||
|
ch2 += ruddVal;
|
||||||
|
ch4 -= ruddVal;
|
||||||
|
}
|
||||||
|
// change elevon 1 & 2 positions; constrain min/max:
|
||||||
|
channel_roll->set_radio_out(constrain_int16(ch1, 900, 2100));
|
||||||
|
channel_pitch->set_radio_out(constrain_int16(ch2, 900, 2100));
|
||||||
|
// constrain min/max for intermediate dspoiler positions:
|
||||||
|
ch3 = constrain_int16(ch3, 900, 2100);
|
||||||
|
ch4 = constrain_int16(ch4, 900, 2100);
|
||||||
|
}
|
||||||
|
// set positions of differential spoilers (convert PWM
|
||||||
|
// 900-2100 range to servo output (-4500 to 4500)
|
||||||
|
// and use function that supports rev/min/max/trim):
|
||||||
|
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_dspoiler1,
|
||||||
|
(ch3-(int16_t)1500) * (int16_t)(SERVO_MAX/300) / (int16_t)2);
|
||||||
|
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_dspoiler2,
|
||||||
|
(ch4-(int16_t)1500) * (int16_t)(SERVO_MAX/300) / (int16_t)2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set the flight control servos based on the current calculated values
|
Set the flight control servos based on the current calculated values
|
||||||
|
|
||||||
|
@ -685,49 +736,6 @@ void Plane::set_servos(void)
|
||||||
channel_rudder->set_radio_out(channel_rudder->get_radio_in());
|
channel_rudder->set_radio_out(channel_rudder->get_radio_in());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g.vtail_output != MIXING_DISABLED) {
|
|
||||||
channel_output_mixer(g.vtail_output, channel_pitch, channel_rudder);
|
|
||||||
} else if (g.elevon_output != MIXING_DISABLED) {
|
|
||||||
channel_output_mixer(g.elevon_output, channel_pitch, channel_roll);
|
|
||||||
// if (both) differential spoilers setup then apply rudder
|
|
||||||
// control into splitting the two elevons on the side of
|
|
||||||
// the aircraft where we want to induce additional drag:
|
|
||||||
if (RC_Channel_aux::function_assigned(RC_Channel_aux::k_dspoiler1) &&
|
|
||||||
RC_Channel_aux::function_assigned(RC_Channel_aux::k_dspoiler2)) {
|
|
||||||
int16_t ch3 = channel_roll->get_radio_out(); //diff spoiler 1
|
|
||||||
int16_t ch4 = channel_pitch->get_radio_out(); //diff spoiler 2
|
|
||||||
// convert rudder-servo output (-4500 to 4500) to PWM offset
|
|
||||||
// value (-500 to 500) and multiply by DSPOILR_RUD_RATE/100
|
|
||||||
// (rudder->servo_out * 500 / SERVO_MAX * dspoiler_rud_rate/100):
|
|
||||||
int16_t ruddVal = (int16_t)((int32_t)(channel_rudder->get_servo_out()) *
|
|
||||||
g.dspoiler_rud_rate / (SERVO_MAX/5));
|
|
||||||
if (ruddVal != 0) { //if nonzero rudder then apply to spoilers
|
|
||||||
int16_t ch1 = ch3; //elevon 1
|
|
||||||
int16_t ch2 = ch4; //elevon 2
|
|
||||||
if (ruddVal > 0) { //apply rudder to right or left side
|
|
||||||
ch1 += ruddVal;
|
|
||||||
ch3 -= ruddVal;
|
|
||||||
} else {
|
|
||||||
ch2 += ruddVal;
|
|
||||||
ch4 -= ruddVal;
|
|
||||||
}
|
|
||||||
// change elevon 1 & 2 positions; constrain min/max:
|
|
||||||
channel_roll->set_radio_out(constrain_int16(ch1, 900, 2100));
|
|
||||||
channel_pitch->set_radio_out(constrain_int16(ch2, 900, 2100));
|
|
||||||
// constrain min/max for intermediate dspoiler positions:
|
|
||||||
ch3 = constrain_int16(ch3, 900, 2100);
|
|
||||||
ch4 = constrain_int16(ch4, 900, 2100);
|
|
||||||
}
|
|
||||||
// set positions of differential spoilers (convert PWM
|
|
||||||
// 900-2100 range to servo output (-4500 to 4500)
|
|
||||||
// and use function that supports rev/min/max/trim):
|
|
||||||
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_dspoiler1,
|
|
||||||
(ch3-(int16_t)1500) * (int16_t)(SERVO_MAX/300) / (int16_t)2);
|
|
||||||
RC_Channel_aux::set_servo_out_for(RC_Channel_aux::k_dspoiler2,
|
|
||||||
(ch4-(int16_t)1500) * (int16_t)(SERVO_MAX/300) / (int16_t)2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arming.is_armed()) {
|
if (!arming.is_armed()) {
|
||||||
//Some ESCs get noisy (beep error msgs) if PWM == 0.
|
//Some ESCs get noisy (beep error msgs) if PWM == 0.
|
||||||
//This little segment aims to avoid this.
|
//This little segment aims to avoid this.
|
||||||
|
@ -804,17 +812,18 @@ void Plane::set_servos(void)
|
||||||
void Plane::servos_output(void)
|
void Plane::servos_output(void)
|
||||||
{
|
{
|
||||||
hal.rcout->cork();
|
hal.rcout->cork();
|
||||||
|
|
||||||
|
if (g.rudder_only != 0) {
|
||||||
|
channel_roll->set_radio_out(channel_roll->get_radio_trim());
|
||||||
|
}
|
||||||
|
|
||||||
// remap servo output to SERVO* ranges if enabled
|
// remap servo output to SERVO* ranges if enabled
|
||||||
g2.servo_channels.remap_servo_output();
|
g2.servo_channels.remap_servo_output();
|
||||||
|
|
||||||
if (g.rudder_only == 0) {
|
// run vtail and elevon mixers
|
||||||
// when in RUDDER_ONLY mode we don't send the channel_roll
|
servo_output_mixers();
|
||||||
// output and instead rely on KFF_RDDRMIX. That allows the yaw
|
|
||||||
// damper to operate.
|
|
||||||
channel_roll->output();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
channel_roll->output();
|
||||||
channel_pitch->output();
|
channel_pitch->output();
|
||||||
channel_throttle->output();
|
channel_throttle->output();
|
||||||
channel_rudder->output();
|
channel_rudder->output();
|
||||||
|
|
Loading…
Reference in New Issue