mirror of https://github.com/ArduPilot/ardupilot
200 lines
5.9 KiB
Plaintext
200 lines
5.9 KiB
Plaintext
|
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*-
|
||
|
|
||
|
//Function that will read the radio data, limit servos and trigger a failsafe
|
||
|
// ----------------------------------------------------------------------------
|
||
|
byte failsafeCounter = 0; // we wait a second to take over the throttle and send the plane circling
|
||
|
|
||
|
void read_radio()
|
||
|
{
|
||
|
ch1_temp = APM_RC.InputCh(CH_ROLL);
|
||
|
ch2_temp = APM_RC.InputCh(CH_PITCH);
|
||
|
|
||
|
if(mix_mode == 0){
|
||
|
radio_in[CH_ROLL] = ch1_temp;
|
||
|
radio_in[CH_PITCH] = ch2_temp;
|
||
|
}else{
|
||
|
radio_in[CH_ROLL] = reverse_elevons * (reverse_ch2_elevon * int(ch2_temp - elevon2_trim) - reverse_ch1_elevon * int(ch1_temp - elevon1_trim)) / 2 + 1500;
|
||
|
radio_in[CH_PITCH] = (reverse_ch2_elevon * int(ch2_temp - elevon2_trim) + reverse_ch1_elevon * int(ch1_temp - elevon1_trim)) / 2 + 1500;
|
||
|
}
|
||
|
|
||
|
for (int y = 2; y < 8; y++)
|
||
|
radio_in[y] = APM_RC.InputCh(y);
|
||
|
|
||
|
#if THROTTLE_REVERSE == 1
|
||
|
radio_in[CH_THROTTLE] = radio_max(CH_THROTTLE) + radio_min(CH_THROTTLE) - radio_in[CH_THROTTLE];
|
||
|
#endif
|
||
|
|
||
|
throttle_failsafe(radio_in[CH_THROTTLE]);
|
||
|
servo_out[CH_THROTTLE] = ((float)(radio_in[CH_THROTTLE] - radio_min(CH_THROTTLE)) /
|
||
|
(float)(radio_max(CH_THROTTLE) - radio_min(CH_THROTTLE))) * 100;
|
||
|
servo_out[CH_THROTTLE] = constrain(servo_out[CH_THROTTLE], 0, 100);
|
||
|
|
||
|
if (servo_out[CH_THROTTLE] > 50) {
|
||
|
if(AIRSPEED_SENSOR == 1) {
|
||
|
airspeed_nudge = (get(PARAM_ARSPD_FBW_MAX) - get(PARAM_TRIM_AIRSPEED)) * ((servo_out[CH_THROTTLE]-50) * 2);
|
||
|
} else {
|
||
|
throttle_nudge = (get(PARAM_THR_MAX) - get(PARAM_TRIM_THROTTLE)) * ((servo_out[CH_THROTTLE]-50) * 2);
|
||
|
}
|
||
|
} else {
|
||
|
airspeed_nudge = 0;
|
||
|
throttle_nudge = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void throttle_failsafe(uint16_t pwm)
|
||
|
{
|
||
|
if(get(PARAM_THR_FAILSAFE)== 0)
|
||
|
return;
|
||
|
|
||
|
//check for failsafe and debounce funky reads
|
||
|
// ------------------------------------------
|
||
|
if (pwm < get(PARAM_THR_FS_VALUE)){
|
||
|
// we detect a failsafe from radio
|
||
|
// throttle has dropped below the mark
|
||
|
failsafeCounter++;
|
||
|
if (failsafeCounter == 9){
|
||
|
SendDebug("MSG FS ON ");
|
||
|
SendDebugln(pwm, DEC);
|
||
|
}else if(failsafeCounter == 10) {
|
||
|
ch3_failsafe = true;
|
||
|
//set_failsafe(true);
|
||
|
//failsafeCounter = 10;
|
||
|
}else if (failsafeCounter > 10){
|
||
|
failsafeCounter = 11;
|
||
|
}
|
||
|
|
||
|
}else if(failsafeCounter > 0){
|
||
|
// we are no longer in failsafe condition
|
||
|
// but we need to recover quickly
|
||
|
failsafeCounter--;
|
||
|
if (failsafeCounter > 3){
|
||
|
failsafeCounter = 3;
|
||
|
}
|
||
|
if (failsafeCounter == 1){
|
||
|
SendDebug("MSG FS OFF ");
|
||
|
SendDebugln(pwm, DEC);
|
||
|
}else if(failsafeCounter == 0) {
|
||
|
ch3_failsafe = false;
|
||
|
//set_failsafe(false);
|
||
|
//failsafeCounter = -1;
|
||
|
}else if (failsafeCounter <0){
|
||
|
failsafeCounter = -1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void trim_control_surfaces()
|
||
|
{
|
||
|
// Store control surface trim values
|
||
|
// ---------------------------------
|
||
|
if(mix_mode == 0){
|
||
|
set_radio_trim(CH_ROLL,radio_in[CH_ROLL]);
|
||
|
set_radio_trim(CH_PITCH,radio_in[CH_PITCH]);
|
||
|
set_radio_trim(CH_RUDDER,radio_in[CH_RUDDER]);
|
||
|
}else{
|
||
|
elevon1_trim = ch1_temp;
|
||
|
elevon2_trim = ch2_temp;
|
||
|
//Recompute values here using new values for elevon1_trim and elevon2_trim
|
||
|
//We cannot use radio_in[CH_ROLL] and radio_in[CH_PITCH] values from read_radio() because the elevon trim values have changed
|
||
|
uint16_t center = 1500;
|
||
|
set_radio_trim(CH_ROLL,center);
|
||
|
set_radio_trim(CH_PITCH,center);
|
||
|
}
|
||
|
// disabled for now
|
||
|
//save_EEPROM_trims();
|
||
|
}
|
||
|
|
||
|
void trim_radio()
|
||
|
{
|
||
|
for (int y = 0; y < 50; y++) {
|
||
|
read_radio();
|
||
|
}
|
||
|
|
||
|
// Store the trim values
|
||
|
// ---------------------
|
||
|
if(mix_mode == 0){
|
||
|
for (int y = 0; y < 8; y++) set_radio_trim(y,radio_in[y]);
|
||
|
}else{
|
||
|
elevon1_trim = ch1_temp;
|
||
|
elevon2_trim = ch2_temp;
|
||
|
uint16_t center = 1500;
|
||
|
set_radio_trim(CH_ROLL,center);
|
||
|
set_radio_trim(CH_PITCH,center);
|
||
|
for (int y = 2; y < 8; y++) set_radio_trim(y,radio_in[y]);
|
||
|
}
|
||
|
//save_EEPROM_trims();
|
||
|
}
|
||
|
|
||
|
|
||
|
#if SET_RADIO_LIMITS == 1
|
||
|
void read_radio_limits()
|
||
|
{
|
||
|
// set initial servo limits for calibration routine
|
||
|
// -------------------------------------------------
|
||
|
set_radio_min(CH_ROLL,radio_in[CH_ROLL] - 150);
|
||
|
set_radio_max(CH_ROLL,radio_in[CH_ROLL] + 150);
|
||
|
|
||
|
set_radio_min(CH_PITCH,radio_in[CH_PITCH] - 150);
|
||
|
set_radio_max(CH_PITCH,radio_in[CH_PITCH] + 150);
|
||
|
|
||
|
// vars for the radio config routine
|
||
|
// ---------------------------------
|
||
|
int counter = 0;
|
||
|
long reminder;
|
||
|
reminder = millis() - 10000;
|
||
|
|
||
|
uint16_t tempMin[2] = {radio_min(CH_ROLL), radio_min(CH_PITCH)} ;
|
||
|
uint16_t tempMax[2] = {radio_max(CH_ROLL), radio_max(CH_PITCH)} ;
|
||
|
|
||
|
// Allows user to set stick limits and calibrate the IR
|
||
|
// ----------------------------------------------------
|
||
|
while(counter < 50){
|
||
|
|
||
|
if (millis() - reminder >= 10000) { // Remind user every 10 seconds what is going on
|
||
|
GCS.send_text(SEVERITY_LOW,"Reading radio limits:");
|
||
|
GCS.send_text(SEVERITY_LOW,"Move sticks to: upper right and lower Left");
|
||
|
GCS.send_text(SEVERITY_LOW,"To Continue, hold the stick in the corner for 2 seconds.");
|
||
|
GCS.send_text(SEVERITY_LOW," ");
|
||
|
//print_radio();
|
||
|
demo_servos(1);
|
||
|
reminder = millis();
|
||
|
}
|
||
|
|
||
|
delay(40);
|
||
|
read_radio();
|
||
|
|
||
|
// AutoSet servo limits
|
||
|
// --------------------
|
||
|
if (radio_in[CH_ROLL] > 1000 && radio_in[CH_ROLL] < 2000){
|
||
|
tempMin[CH_ROLL] = min(radio_in[CH_ROLL], tempMin[CH_ROLL]);
|
||
|
tempMax[CH_ROLL] = max(radio_in[CH_ROLL], tempMax[CH_ROLL]);
|
||
|
}
|
||
|
|
||
|
if (radio_in[CH_PITCH] > 1000 && radio_in[CH_PITCH]< 2000){
|
||
|
tempMin[CH_PITCH] = min(radio_in[CH_PITCH], tempMin[CH_PITCH]);
|
||
|
tempMax[CH_PITCH] = max(radio_in[CH_PITCH], tempMax[CH_PITCH]);
|
||
|
}
|
||
|
if(radio_in[CH_PITCH] < (tempMin[CH_PITCH] + 30) || tempMin[CH_PITCH] > (tempMax[CH_PITCH] -30)){
|
||
|
SendDebug(".");
|
||
|
counter++;
|
||
|
}else{
|
||
|
if (counter > 0)
|
||
|
counter--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// contstrain min values
|
||
|
// ---------------------
|
||
|
set_radio_min(CH_ROLL,constrain(tempMin[CH_ROLL], 800, 2200));
|
||
|
set_radio_max(CH_ROLL,constrain(tempMax[CH_ROLL], 800, 2200));
|
||
|
set_radio_min(CH_PITCH,constrain(tempMin[CH_PITCH], 800, 2200));
|
||
|
set_radio_max(CH_PITCH,constrain(tempMax[CH_PITCH], 800, 2200));
|
||
|
|
||
|
SendDebugln(" ");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|