ardupilot/Tools/ArduTracker/radio.pde

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