35bf288abd
Before: -> After Stabilize P –> Stabilize P (Use NG values, or 8.3 x the older AC2 value) Stabilize I –> Stabilize I (Stays same value) Stabilize D –> Rate P (Stays same value) –> Rate I (new) Added a new value – an I term for rate. The old stabilization routines did not use this term. Please refer to the config.h file to read more about the new PIDs. Added framework for using DCM corrected Accelerometer rates. Code is commented out for now. Added set home at Arming. Crosstrack is now a full PID loop, rather than just a P gain for more control. Throttle now slews when switching out of Alt hold or Auto modes for less jarring transitions Sonar and Baro PIDs are now combined into a throttle PID Yaw control is completely re-written. Added Octa_Quad support - Max git-svn-id: https://arducopter.googlecode.com/svn/trunk@2836 f9c3cf11-9bcb-44bc-f272-b75c42450872
209 lines
4.8 KiB
Plaintext
209 lines
4.8 KiB
Plaintext
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
|
|
//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 init_rc_in()
|
|
{
|
|
// set rc channel ranges
|
|
g.rc_1.set_angle(4500);
|
|
g.rc_2.set_angle(4500);
|
|
g.rc_3.set_range(0,1000);
|
|
g.rc_3.scale_output = .9;
|
|
g.rc_4.set_angle(4500);
|
|
|
|
g.rc_1.set_type(RC_CHANNEL_ANGLE_RAW);
|
|
g.rc_2.set_type(RC_CHANNEL_ANGLE_RAW);
|
|
g.rc_4.set_type(RC_CHANNEL_ANGLE_RAW);
|
|
|
|
// set rc dead zones
|
|
g.rc_1.dead_zone = 60; // 60 = .6 degrees
|
|
g.rc_2.dead_zone = 60;
|
|
g.rc_3.dead_zone = 60;
|
|
g.rc_4.dead_zone = 500;// 0 = hybrid rate approach
|
|
|
|
//set auxiliary ranges
|
|
g.rc_5.set_range(0,1000);
|
|
g.rc_5.set_filter(false);
|
|
g.rc_6.set_range(0,1000);
|
|
g.rc_7.set_range(0,1000);
|
|
g.rc_8.set_range(0,1000);
|
|
|
|
#if CHANNEL_6_TUNING == CH6_RATE_KP
|
|
g.rc_6.set_range(0,300); // 0 t0 .3
|
|
|
|
#elif CHANNEL_6_TUNING == CH6_RATE_KI
|
|
g.rc_6.set_range(0,300); // 0 t0 .3
|
|
|
|
#elif CHANNEL_6_TUNING == CH6_STABILIZE_KP
|
|
g.rc_6.set_range(0,8000); // 0 t0 .3
|
|
|
|
#elif CHANNEL_6_TUNING == CH6_STABILIZE_KI
|
|
g.rc_6.set_range(0,300); // 0 t0 .3
|
|
|
|
#elif CHANNEL_6_TUNING == CH6_THROTTLE_KP
|
|
g.rc_6.set_range(0,800); // 0 to .8
|
|
|
|
#elif CHANNEL_6_TUNING == CH6_THROTTLE_KD
|
|
g.rc_6.set_range(0,500); // 0 to .5
|
|
|
|
#elif CHANNEL_6_TUNING == CH6_TOP_BOTTOM_RATIO
|
|
g.rc_6.set_range(800,1000); // .8 to 1
|
|
#endif
|
|
}
|
|
|
|
void init_rc_out()
|
|
{
|
|
#if ARM_AT_STARTUP == 1
|
|
motor_armed = 1;
|
|
#endif
|
|
|
|
|
|
APM_RC.Init(); // APM Radio initialization
|
|
|
|
// fix for crazy output
|
|
OCR1B = 0xFFFF; // PB6, OUT3
|
|
OCR1C = 0xFFFF; // PB7, OUT4
|
|
OCR5B = 0xFFFF; // PL4, OUT1
|
|
OCR5C = 0xFFFF; // PL5, OUT2
|
|
OCR4B = 0xFFFF; // PH4, OUT6
|
|
OCR4C = 0xFFFF; // PH5, OUT5
|
|
|
|
// don't fuss if we are calibrating
|
|
if(g.esc_calibrate == 1)
|
|
return;
|
|
|
|
if(g.rc_3.radio_min <= 1200){
|
|
output_min();
|
|
}
|
|
|
|
for(byte i = 0; i < 5; i++){
|
|
delay(20);
|
|
read_radio();
|
|
}
|
|
|
|
// sanity check
|
|
if(g.rc_3.radio_min >= 1300){
|
|
g.rc_3.radio_min = g.rc_3.radio_in;
|
|
output_min();
|
|
}
|
|
}
|
|
|
|
void output_min()
|
|
{
|
|
#if FRAME_CONFIG == HELI_FRAME
|
|
heli_move_servos_to_mid();
|
|
#else
|
|
APM_RC.OutputCh(CH_1, g.rc_3.radio_min); // Initialization of servo outputs
|
|
APM_RC.OutputCh(CH_2, g.rc_3.radio_min);
|
|
APM_RC.OutputCh(CH_3, g.rc_3.radio_min);
|
|
APM_RC.OutputCh(CH_4, g.rc_3.radio_min);
|
|
#endif
|
|
|
|
APM_RC.OutputCh(CH_7, g.rc_3.radio_min);
|
|
APM_RC.OutputCh(CH_8, g.rc_3.radio_min);
|
|
|
|
#if FRAME_CONFIG == OCTA_FRAME
|
|
APM_RC.OutputCh(CH_10, g.rc_3.radio_min);
|
|
APM_RC.OutputCh(CH_11, g.rc_3.radio_min);
|
|
#endif
|
|
|
|
}
|
|
void read_radio()
|
|
{
|
|
if (APM_RC.GetState() == 1){
|
|
|
|
g.rc_1.set_pwm(APM_RC.InputCh(CH_1));
|
|
g.rc_2.set_pwm(APM_RC.InputCh(CH_2));
|
|
g.rc_3.set_pwm(APM_RC.InputCh(CH_3));
|
|
g.rc_4.set_pwm(APM_RC.InputCh(CH_4));
|
|
g.rc_5.set_pwm(APM_RC.InputCh(CH_5));
|
|
g.rc_6.set_pwm(APM_RC.InputCh(CH_6));
|
|
g.rc_7.set_pwm(APM_RC.InputCh(CH_7));
|
|
g.rc_8.set_pwm(APM_RC.InputCh(CH_8));
|
|
|
|
#if FRAME_CONFIG != HELI_FRAME
|
|
// limit our input to 800 so we can still pitch and roll
|
|
g.rc_3.control_in = min(g.rc_3.control_in, 800);
|
|
#endif
|
|
|
|
//throttle_failsafe(g.rc_3.radio_in);
|
|
|
|
/*
|
|
Serial.printf_P(PSTR("OUT 1: %d\t2: %d\t3: %d\t4: %d \n"),
|
|
g.rc_1.control_in,
|
|
g.rc_2.control_in,
|
|
g.rc_3.control_in,
|
|
g.rc_4.control_in);
|
|
*/
|
|
}
|
|
}
|
|
|
|
void throttle_failsafe(uint16_t pwm)
|
|
{
|
|
if(g.throttle_fs_enabled == 0)
|
|
return;
|
|
|
|
//check for failsafe and debounce funky reads
|
|
// ------------------------------------------
|
|
if (pwm < g.throttle_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_radio()
|
|
{
|
|
for (byte i = 0; i < 30; i++){
|
|
read_radio();
|
|
}
|
|
|
|
g.rc_1.trim(); // roll
|
|
g.rc_2.trim(); // pitch
|
|
g.rc_4.trim(); // yaw
|
|
|
|
g.rc_1.save_eeprom();
|
|
g.rc_2.save_eeprom();
|
|
g.rc_4.save_eeprom();
|
|
}
|
|
|
|
void trim_yaw()
|
|
{
|
|
for (byte i = 0; i < 30; i++){
|
|
read_radio();
|
|
}
|
|
g.rc_4.trim(); // yaw
|
|
}
|
|
|