Subversion Repositories FlightCtrl

Compare Revisions

Regard whitespace Rev 2167 → Rev 2570

/branches/Proxy sensor - tempolo/eeprom.c
572,7 → 572,7
if(ee_default || !ParamSet_ReadFromEEProm(i)) // could not read paramset from eeprom
{
bad_params = 1;
printf("\n\rGenerating default Parameter Set %d",i);
printf("\n\rGenerating default Parm Set %d",i);
switch(i)
{
case 1:
609,7 → 609,7
// read active parameter set to ParamSet stucture
i = GetActiveParamSet();
ParamSet_ReadFromEEProm(i);
printf("\n\rUsing Parameter Set %d", i);
printf("\n\rUsing Parm Set %d", i);
 
// load mixer table
if(GetParamByte(PID_EE_REVISION) == 0xff || !MixerTable_ReadFromEEProm() )
/branches/Proxy sensor - tempolo/fc.c
174,8 → 174,10
signed int KopplungsteilNickRoll,KopplungsteilRollNick;
signed int tmp_motorwert[MAX_MOTORS];
char VarioCharacter = ' ';
unsigned int HooverGasEmergencyPercent = 0; // The gas value for Emergency landing
unsigned int HoverGasEmergencyPercent = 0; // The gas value for Emergency landing
 
static int HoehenRegelung(int GasMischanteil);
 
#define LIMIT_MIN(value, min) {if(value <= min) value = min;}
#define LIMIT_MAX(value, max) {if(value >= max) value = max;}
#define LIMIT_MIN_MAX(value, min, max) {if(value <= min) value = min; else if(value >= max) value = max;}
645,11 → 647,15
if(carefree_old < 3)
{
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(CareFree) { beeptime = 1500; if(!SpeakHoTT) SpeakHoTT = SPEAK_CF_ON; }
else { beeptime = 200; if(!SpeakHoTT) SpeakHoTT = SPEAK_CF_OFF; }
if(CareFree)
{ beeptime = 1500; if(!SpeakHoTT) SpeakHoTT = SPEAK_CF_ON; }
else
{ beeptime = 200; if(!SpeakHoTT) SpeakHoTT = SPEAK_CF_OFF; }
#else
if(CareFree) beeptime = 1500;
else beeptime = 200;
if(CareFree)
beeptime = 1500;
else
beeptime = 200;
#endif
NeueKompassRichtungMerken = 5;
carefree_old = CareFree;
677,9 → 683,9
void MotorRegler(void)
//############################################################################
{
int pd_ergebnis_nick,pd_ergebnis_roll,tmp_int, tmp_int2;
int pd_ergebnis_nick,pd_ergebnis_roll;
int GierMischanteil,GasMischanteil;
static long sollGier = 0,tmp_long,tmp_long2;
static long sollGier = 0;
static long IntegralFehlerNick = 0;
static long IntegralFehlerRoll = 0;
static unsigned int RcLostTimer;
697,18 → 703,19
{
if(HoverGas && HoverGas < 150 * STICK_GAIN)
{
HooverGasEmergencyPercent = (HoverGas/(STICK_GAIN) * EE_Parameter.NotGas) / 100; // i.e. 80% of Hovergas
HoverGasEmergencyPercent = (HoverGas/(STICK_GAIN) * EE_Parameter.NotGas) / 100; // i.e. 80% of Hovergas
}
else HooverGasEmergencyPercent = 45; // default if the Hoovergas was could not calculated yet
} else HooverGasEmergencyPercent = EE_Parameter.NotGas;
else HoverGasEmergencyPercent = 45; // default if the Hovergas was could not calculated yet
} else HoverGasEmergencyPercent = EE_Parameter.NotGas;
 
GasMischanteil = StickGas;
if(GasMischanteil < MIN_GAS + 10) GasMischanteil = MIN_GAS + 10;
 
if(SenderOkay < 100 && !(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE))
{
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Empfang schlecht
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(SenderOkay < 100 && !(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE))
{
if(RcLostTimer) RcLostTimer--;
else
{
719,7 → 726,7
ROT_ON;
if(modell_fliegt > 1000 && Capacity.MinOfMaxPWM > 100) // wahrscheinlich in der Luft --> langsam absenken
{
GasMischanteil = HooverGasEmergencyPercent;
GasMischanteil = HoverGasEmergencyPercent;
FC_StatusFlags |= FC_STATUS_EMERGENCY_LANDING;
PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] = 0;
PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] = 0;
750,7 → 757,8
SummeRoll = 0;
sollGier = 0;
Mess_Integral_Gier = 0;
} else FC_StatusFlags |= FC_STATUS_FLY;
} else
FC_StatusFlags |= FC_STATUS_FLY;
 
if((PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] > 80) && MotorenEin == 0)
{
1033,8 → 1041,7
Parameter_ExtraConfig &= ~(CFG2_HEIGHT_LIMIT | CFG_LEARNABLE_CAREFREE | CFG2_VARIO_BEEP);
Parameter_HoehenSchalter = 200; // switch on
}
else
if(FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING)
else if(FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING)
{
StickGier = 0;
StickNick = 0;
1093,10 → 1100,11
tmp_long /= 3;
tmp_long2 /= 3;
}
if(tmp_long > (long) FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long = (long) FromNaviCtrl_Value.Kalman_MaxFusion;
if(tmp_long < (long)-FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long = (long)-FromNaviCtrl_Value.Kalman_MaxFusion;
if(tmp_long2 > (long) FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long2 = (long) FromNaviCtrl_Value.Kalman_MaxFusion;
if(tmp_long2 < (long)-FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long2 = (long)-FromNaviCtrl_Value.Kalman_MaxFusion;
long kmf = FromNaviCtrl_Value.Kalman_MaxFusion;
if(tmp_long > (long) kmf) tmp_long = (long) kmf;
if(tmp_long < (long)-kmf) tmp_long = (long)-kmf;
if(tmp_long2 > (long) kmf) tmp_long2 = (long) kmf;
if(tmp_long2 < (long)-kmf) tmp_long2 = (long)-kmf;
}
else
{
1160,8 → 1168,8
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MittelIntegralNick2 /= ABGLEICH_ANZAHL;
MittelIntegralRoll2 /= ABGLEICH_ANZAHL;
tmp_long = IntegralNick2 - IntegralNick;
tmp_long2 = IntegralRoll2 - IntegralRoll;
long tmp_long = IntegralNick2 - IntegralNick;
long tmp_long2 = IntegralRoll2 - IntegralRoll;
 
IntegralFehlerNick = tmp_long;
IntegralFehlerRoll = tmp_long2;
1287,7 → 1295,7
NeueKompassRichtungMerken = 50; // eine Sekunde zum Einloggen
};
}
tmp_int = (long) EE_Parameter.StickGier_P * ((long)StickGier * abs(StickGier)) / 512L; // expo y = ax + bx²
int tmp_int = (long) EE_Parameter.StickGier_P * ((long)StickGier * abs(StickGier)) / 512L; // expo y = ax + bx²
tmp_int += (EE_Parameter.StickGier_P * StickGier) / 4;
tmp_int += CompassGierSetpoint;
sollGier = tmp_int;
1376,7 → 1384,149
GasMischanteil *= STICK_GAIN;
// if height control is activated
if((Parameter_GlobalConfig & CFG_HOEHENREGELUNG) && !(Looping_Roll || Looping_Nick)) // Höhenregelung
GasMischanteil = HoehenRegelung(GasMischanteil);
else
{
// set undefined state to indicate vario off
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN);
} // EOF no height control
// Linits the maximum gas in case of "Out of Range emergency landing"
if(NC_To_FC_Flags & NC_TO_FC_EMERGENCY_LANDING)
{
if(GasMischanteil/STICK_GAIN > HoverGasEmergencyPercent && HoverGas) GasMischanteil = HoverGasEmergencyPercent * STICK_GAIN;
SollHoehe = HoehenWert; // update setpoint to current heigth
beeptime = 15000;
BeepMuster = 0x0E00;
}
// limit gas to parameter setting
LIMIT_MIN(GasMischanteil, (MIN_GAS + 10) * STICK_GAIN);
if(GasMischanteil > (MAX_GAS - 20) * STICK_GAIN) GasMischanteil = (MAX_GAS - 20) * STICK_GAIN;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// all BL-Ctrl connected?
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(MissingMotor || Capacity.MinOfMaxPWM != 255 || NC_ErrorCode) // wait until all BL-Ctrls started and no Errors
if(modell_fliegt > 1 && modell_fliegt < 50 && GasMischanteil > 0) // only during start-phase
{
modell_fliegt = 1;
GasMischanteil = (MIN_GAS + 10) * STICK_GAIN;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Mischer und PI-Regler
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DebugOut.Analog[7] = GasMischanteil;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gier-Anteil
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GierMischanteil = MesswertGier - sollGier * STICK_GAIN; // Regler für Gier
#define MIN_GIERGAS (40*STICK_GAIN) // unter diesem Gaswert trotzdem Gieren
if(GasMischanteil > MIN_GIERGAS)
{
if(GierMischanteil > (GasMischanteil / 2)) GierMischanteil = GasMischanteil / 2;
if(GierMischanteil < -(GasMischanteil / 2)) GierMischanteil = -(GasMischanteil / 2);
}
else
{
if(GierMischanteil > (MIN_GIERGAS / 2)) GierMischanteil = MIN_GIERGAS / 2;
if(GierMischanteil < -(MIN_GIERGAS / 2)) GierMischanteil = -(MIN_GIERGAS / 2);
}
tmp_int = MAX_GAS*STICK_GAIN;
if(GierMischanteil > ((tmp_int - GasMischanteil))) GierMischanteil = ((tmp_int - GasMischanteil));
if(GierMischanteil < -((tmp_int - GasMischanteil))) GierMischanteil = -((tmp_int - GasMischanteil));
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Nick-Achse
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffNick = MesswertNick - StickNick; // Differenz bestimmen
if(IntegralFaktor) SummeNick += IntegralNickMalFaktor - StickNick; // I-Anteil bei Winkelregelung
else SummeNick += DiffNick; // I-Anteil bei HH
if(SummeNick > (STICK_GAIN * 16000L)) SummeNick = (STICK_GAIN * 16000L);
if(SummeNick < -(16000L * STICK_GAIN)) SummeNick = -(16000L * STICK_GAIN);
if(EE_Parameter.Gyro_Stability <= 8)
pd_ergebnis_nick = (EE_Parameter.Gyro_Stability * DiffNick) / 8; // PI-Regler für Nick
else
pd_ergebnis_nick = ((EE_Parameter.Gyro_Stability / 2) * DiffNick) / 4; // Überlauf verhindern
pd_ergebnis_nick += SummeNick / Ki;
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64;
if(pd_ergebnis_nick > tmp_int) pd_ergebnis_nick = tmp_int;
if(pd_ergebnis_nick < -tmp_int) pd_ergebnis_nick = -tmp_int;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Roll-Achse
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffRoll = MesswertRoll - StickRoll; // Differenz bestimmen
if(IntegralFaktor) SummeRoll += IntegralRollMalFaktor - StickRoll;// I-Anteil bei Winkelregelung
else SummeRoll += DiffRoll; // I-Anteil bei HH
if(SummeRoll > (STICK_GAIN * 16000L)) SummeRoll = (STICK_GAIN * 16000L);
if(SummeRoll < -(16000L * STICK_GAIN)) SummeRoll = -(16000L * STICK_GAIN);
if(EE_Parameter.Gyro_Stability <= 8)
pd_ergebnis_roll = (EE_Parameter.Gyro_Stability * DiffRoll) / 8; // PI-Regler für Roll
else
pd_ergebnis_roll = ((EE_Parameter.Gyro_Stability / 2) * DiffRoll) / 4; // Überlauf verhindern
pd_ergebnis_roll += SummeRoll / Ki;
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64;
if(pd_ergebnis_roll > tmp_int) pd_ergebnis_roll = tmp_int;
if(pd_ergebnis_roll < -tmp_int) pd_ergebnis_roll = -tmp_int;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Universal Mixer
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
for(i=0; i<MAX_MOTORS; i++)
{
signed int tmp_int;
if(Mixer.Motor[i][0] > 0)
{
// Gas
if(Mixer.Motor[i][0] == 64) tmp_int = GasMischanteil; else tmp_int = ((long)GasMischanteil * Mixer.Motor[i][0]) / 64L;
// Nick
if(Mixer.Motor[i][1] == 64) tmp_int += pd_ergebnis_nick;
else if(Mixer.Motor[i][1] == -64) tmp_int -= pd_ergebnis_nick;
else tmp_int += ((long)pd_ergebnis_nick * Mixer.Motor[i][1]) / 64L;
// Roll
if(Mixer.Motor[i][2] == 64) tmp_int += pd_ergebnis_roll;
else if(Mixer.Motor[i][2] == -64) tmp_int -= pd_ergebnis_roll;
else tmp_int += ((long)pd_ergebnis_roll * Mixer.Motor[i][2]) / 64L;
// Gier
if(Mixer.Motor[i][3] == 64) tmp_int += GierMischanteil;
else if(Mixer.Motor[i][3] == -64) tmp_int -= GierMischanteil;
else tmp_int += ((long)GierMischanteil * Mixer.Motor[i][3]) / 64L;
if(tmp_int > tmp_motorwert[i]) tmp_int = (tmp_motorwert[i] + tmp_int) / 2; // MotorSmoothing
// else tmp_int = 2 * tmp_int - tmp_motorwert[i]; // original MotorSmoothing
else
{
if(EE_Parameter.MotorSmooth == 0)
{
tmp_int = 2 * tmp_int - tmp_motorwert[i]; // original MotorSmoothing
}
else // 1 means tmp_int = tmp_int;
if(EE_Parameter.MotorSmooth > 1)
{
// If >= 2 then allow >= 50% of the intended step down to rapidly reach the intended value.
tmp_int = tmp_int + ((tmp_motorwert[i] - tmp_int)/EE_Parameter.MotorSmooth);
}
}
LIMIT_MIN_MAX(tmp_int,(int) MIN_GAS * 4,(int) MAX_GAS * 4);
Motor[i].SetPoint = tmp_int / 4;
Motor[i].SetPointLowerBits = (tmp_int % 4)<<1; // (3 bits total)
tmp_motorwert[i] = tmp_int;
}
else
{
Motor[i].SetPoint = 0;
Motor[i].SetPointLowerBits = 0;
}
}
}
 
static int HoehenRegelung(int GasMischanteil)
{
#define HOVER_GAS_AVERAGE 16384L // 16384 * 2ms = 32s averaging
#define HC_GAS_AVERAGE 4 // 4 * 2ms= 8ms averaging
 
1385,14 → 1535,13
#else
#define OPA_OFFSET_STEP 10
#endif
int HCGas, HeightDeviation = 0,GasReduction = 0;
static int HeightTrimming = 0; // rate for change of height setpoint
static int FilterHCGas = 0;
static unsigned long HoverGasFilter = 0;
static unsigned char delay = 100, BaroAtUpperLimit = 0, BaroAtLowerLimit = 0;
int CosAttitude; // for projection of hoover gas
 
// get the current hooverpoint
static int sHeightTrimming = 0; // rate for change of height setpoint
static int sFilterHCGas = 0;
static unsigned long sHoverGasFilter = 0;
static unsigned char sDelay = 100, sBaroAtUpperLimit = 0, sBaroAtLowerLimit = 0;
// get the current hoverpoint
DebugOut.Analog[21] = HoverGas;
 
// Expand the measurement
1410,7 → 1559,7
}
else
{
BaroAtLowerLimit = 1;
sBaroAtLowerLimit = 1;
}
}
// measurement of air pressure close to lower limit and
1426,13 → 1575,13
}
else
{
BaroAtUpperLimit = 1;
sBaroAtUpperLimit = 1;
}
}
else
{
BaroAtUpperLimit = 0;
BaroAtLowerLimit = 0;
sBaroAtUpperLimit = 0;
sBaroAtLowerLimit = 0;
}
}
else // delay, because of expanding the Baro-Range
1448,7 → 1597,7
{ // check if parameter is less than activation threshold
if(Parameter_HoehenSchalter < 50) // for 3 or 2-state switch height control is disabled in lowest position
{ //height control not active
if(!delay--)
if(!sDelay--)
{
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(HoehenReglerAktiv && !SpeakHoTT) SpeakHoTT = SPEAK_ALTITUDE_OFF;
1455,7 → 1604,7
#endif
HoehenReglerAktiv = 0; // disable height control
SollHoehe = HoehenWert; // update SetPoint with current reading
delay = 1;
sDelay = 1;
}
}
else
1465,7 → 1614,7
if(!HoehenReglerAktiv && !SpeakHoTT) SpeakHoTT = SPEAK_ALTITUDE_ON;
#endif
HoehenReglerAktiv = 1; // enable height control
delay = 200;
sDelay = 200;
}
}
else // no switchable height control
1474,10 → 1623,10
HoehenReglerAktiv = 1;
}
 
// calculate cos of nick and roll angle used for projection of the vertical hoover gas
tmp_int = (int)(IntegralNick/GIER_GRAD_FAKTOR); // nick angle in deg
tmp_int2 = (int)(IntegralRoll/GIER_GRAD_FAKTOR); // roll angle in deg
CosAttitude = (int16_t)ihypot(tmp_int, tmp_int2); // phytagoras gives effective attitude angle in deg
// calculate cos of nick and roll angle used for projection of the vertical hover gas
int tmp_int = (int)(IntegralNick/GIER_GRAD_FAKTOR); // nick angle in deg
int tmp_int2 = (int)(IntegralRoll/GIER_GRAD_FAKTOR); // roll angle in deg
int CosAttitude = (int16_t)ihypot(tmp_int, tmp_int2); // phytagoras gives effective attitude angle in deg
LIMIT_MAX(CosAttitude, 60); // limit effective attitude angle
CosAttitude = c_cos_8192(CosAttitude); // cos of actual attitude
VarioCharacter = ' ';
1489,12 → 1638,13
// start of height control algorithm
// the height control is only an attenuation of the actual gas stick.
// I.e. it will work only if the gas stick is higher than the hover gas
// and the hover height will be allways larger than height setpoint.
// and the hover height will always be larger than height setpoint.
int HCGas;
FC_StatusFlags2 |= FC_STATUS2_ALTITUDE_CONTROL;
if((Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT) || !(Parameter_GlobalConfig & CFG_HOEHEN_SCHALTER)) // Regler wird über Schalter gesteuert)
{ // old version
HCGas = GasMischanteil; // take current stick gas as neutral point for the height control
HeightTrimming = 0;
sHeightTrimming = 0;
AltitudeSetpointTrimming = 0;
// set both flags to indicate no vario mode
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN);
1502,12 → 1652,12
else
{
// alternative height control
// PD-Control with respect to hoover point
// PD-Control with respect to hover point
// the thrust loss out of horizontal attitude is compensated
// the setpoint will be fine adjusted with the gas stick position
if(FC_StatusFlags & FC_STATUS_FLY) // trim setpoint only when flying
{ // gas stick is above hoover point
if(StickGas > (StickGasHover + HEIGHT_CONTROL_STICKTHRESHOLD) && !BaroAtUpperLimit)
{ // gas stick is above hover point
if(StickGas > (StickGasHover + HEIGHT_CONTROL_STICKTHRESHOLD) && !sBaroAtUpperLimit)
{
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_DOWN)
{
1520,13 → 1670,13
else
{
// SollHoehe = (long) Parameter_MaximumAltitude * 100L;
// HeightTrimming += abs(StickGas - (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD));
// sHeightTrimming += abs(StickGas - (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD));
AltitudeSetpointTrimming = abs(StickGas - (StickGasHover + HEIGHT_CONTROL_STICKTHRESHOLD));
VarioCharacter = '+';
}
WaypointTrimming = 0;
} // gas stick is below hoover point
else if(StickGas < (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD) && !BaroAtLowerLimit )
} // gas stick is below hover point
else if(StickGas < (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD) && !sBaroAtLowerLimit )
{
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_UP)
{
1535,7 → 1685,7
}
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_DOWN;
AltitudeSetpointTrimming = -abs(StickGas - (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD));
// HeightTrimming -= abs(StickGas - (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD));
// sHeightTrimming -= abs(StickGas - (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD));
VarioCharacter = '-';
WaypointTrimming = 0;
}
1546,7 → 1696,7
{
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_UP;
AltitudeSetpointTrimming = FromNC_AltitudeSpeed;
//HeightTrimming += FromNC_AltitudeSpeed;
//sHeightTrimming += FromNC_AltitudeSpeed;
WaypointTrimming = 10;
VarioCharacter = '^';
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_DOWN) // changed from sinking to rising
1560,7 → 1710,7
{
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_DOWN;
AltitudeSetpointTrimming = -FromNC_AltitudeSpeed;
//HeightTrimming -= FromNC_AltitudeSpeed;
//sHeightTrimming -= FromNC_AltitudeSpeed;
WaypointTrimming = -10;
VarioCharacter = 'v';
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_UP) // changed from rising to sinking
1572,11 → 1722,14
else
if(FC_StatusFlags & (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN))
{
if(!WaypointTrimming) LIMIT_MIN_MAX(SollHoehe, (HoehenWert-128), (HoehenWert+128)) // max. 1m Unterschied
else WaypointTrimming = 0;
if(!WaypointTrimming)
LIMIT_MIN_MAX(SollHoehe, (HoehenWert-128), (HoehenWert+128)) // max. 1m Unterschied
else
WaypointTrimming = 0;
FC_StatusFlags &= ~(FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN);
HeightTrimming = 0;
if(Parameter_ExtraConfig & CFG2_VARIO_BEEP) beeptime = 500;
sHeightTrimming = 0;
if(Parameter_ExtraConfig & CFG2_VARIO_BEEP)
beeptime = 500;
if(!StartTrigger && HoehenWert > 50)
{
StartTrigger = 1;
1584,23 → 1737,25
}
}
// Trim height set point
HeightTrimming += AltitudeSetpointTrimming;
if(abs(HeightTrimming) > 500) // bei Waypoint-Flug ist das ca. die 500Hz
sHeightTrimming += AltitudeSetpointTrimming;
if(abs(sHeightTrimming) > 500) // bei Waypoint-Flug ist das ca. die 500Hz
{
if(WaypointTrimming)
{
if(abs(FromNC_AltitudeSetpoint - SollHoehe) < 10) SollHoehe = FromNC_AltitudeSetpoint;
else SollHoehe += WaypointTrimming;
if(abs(FromNC_AltitudeSetpoint - SollHoehe) < 10)
SollHoehe = FromNC_AltitudeSetpoint;
else
SollHoehe += WaypointTrimming;
}
else
{
if(HeightTrimming > 0) SollHoehe += EE_Parameter.Hoehe_Verstaerkung / 3;
if(sHeightTrimming > 0) SollHoehe += EE_Parameter.Hoehe_Verstaerkung / 3;
else SollHoehe -= EE_Parameter.Hoehe_Verstaerkung / 3;
}
HeightTrimming = 0;
sHeightTrimming = 0;
LIMIT_MIN_MAX(SollHoehe, (HoehenWert-1024), (HoehenWert+1024)); // max. 10m Unterschied
if(Parameter_ExtraConfig & CFG2_VARIO_BEEP) beeptime = 100;
//update hoover gas stick value when setpoint is shifted
//update hover gas stick value when setpoint is shifted
if(!EE_Parameter.Hoehe_StickNeutralPoint && FromNC_AltitudeSpeed == 0)
{
StickGasHover = HoverGas/STICK_GAIN; //rescale back to stick value
1624,15 → 1779,15
if(HoehenWert > SollHoehe || !(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT))
{
// from this point the Heigth Control Algorithm is identical for both versions
int HeightDeviation = 0, GasReduction = 0;
if(BaroExpandActive) // baro range expanding active
{
HCGas = HoverGas; // hover while expanding baro adc range
HeightDeviation = 0;
} // EOF // baro range expanding active
else // valid data from air pressure sensor
{
// ------------------------- P-Part ----------------------------
tmp_long = (HoehenWert - SollHoehe); // positive when too high
int32_t tmp_long = (HoehenWert - SollHoehe); // positive when too high
LIMIT_MIN_MAX(tmp_long, -32767L, 32767L); // avoid overflov when casting to int16_t
HeightDeviation = (int)(tmp_long); // positive when too high
tmp_long = (tmp_long * (long)Parameter_Hoehe_P) / 32L; // p-part
1643,7 → 1798,8
LIMIT_MIN_MAX(tmp_int, -127, 128);
tmp_int = (tmp_int * (long)Parameter_Luftdruck_D) / 4L; // scale to d-gain parameter
LIMIT_MIN_MAX(tmp_int,-64 * STICK_GAIN, 64 * STICK_GAIN);
if(FC_StatusFlags & (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN)) tmp_int /= 4; // reduce d-part while trimming setpoint
if(FC_StatusFlags & (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN))
tmp_int /= 4; // reduce d-part while trimming setpoint
else
if(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT) tmp_int /= 8; // reduce d-part in "Deckel" mode
GasReduction += tmp_int;
1651,7 → 1807,7
// ------------------------ D-Part 2: ACC-Z Integral ------------------------
if(Parameter_Hoehe_ACC_Wirkung)
{
tmp_long = ((Mess_Integral_Hoch / 128L) * (int32_t) Parameter_Hoehe_ACC_Wirkung) / (128L / STICK_GAIN);
int32_t tmp_long = ((Mess_Integral_Hoch / 128L) * (int32_t) Parameter_Hoehe_ACC_Wirkung) / (128L / STICK_GAIN);
LIMIT_MIN_MAX(tmp_long, -32 * STICK_GAIN, 64 * STICK_GAIN);
GasReduction += tmp_long;
}
1659,17 → 1815,17
tmp_int = (Parameter_Hoehe_GPS_Z * (int)FromNaviCtrl_Value.GpsZ)/128L;
LIMIT_MIN_MAX(tmp_int, -32 * STICK_GAIN, 64 * STICK_GAIN);
GasReduction += tmp_int;
GasReduction = (long)((long)GasReduction * HoverGas) / 512; // scale to the gas value
GasReduction = ((long)GasReduction * HoverGas) / 512; // scale to the gas value
// ------------------------ ----------------------------------
HCGas -= GasReduction;
// limit deviation from hoover point within the target region
if(!AltitudeSetpointTrimming && HoverGas > 0) // height setpoint is not changed and hoover gas not zero
// limit deviation from hover point within the target region
if(!AltitudeSetpointTrimming && HoverGas > 0) // height setpoint is not changed and hover gas not zero
{
unsigned int tmp;
tmp = abs(HeightDeviation);
if(tmp <= 60)
{
LIMIT_MIN_MAX(HCGas, HoverGasMin, HoverGasMax); // limit gas around the hoover point
LIMIT_MIN_MAX(HCGas, HoverGasMin, HoverGasMax); // limit gas around the hover point
}
else
{
1678,37 → 1834,37
if(HeightDeviation > 0)
{
tmp = (HoverGasMin * (16 - tmp)) / 16;
LIMIT_MIN_MAX(HCGas, tmp, HoverGasMax); // limit gas around the hoover point
LIMIT_MIN_MAX(HCGas, tmp, HoverGasMax); // limit gas around the hover point
}
else
{
tmp = (HoverGasMax * (tmp + 16)) / 16;
LIMIT_MIN_MAX(HCGas, HoverGasMin, tmp); // limit gas around the hoover point
LIMIT_MIN_MAX(HCGas, HoverGasMin, tmp); // limit gas around the hover point
}
}
}
// strech control output by inverse attitude projection 1/cos
// + 1/cos(angle) ++++++++++++++++++++++++++
tmp_long2 = (int32_t)HCGas;
int32_t tmp_long2 = (int32_t)HCGas;
tmp_long2 *= 8192L;
tmp_long2 /= CosAttitude;
HCGas = (int16_t)tmp_long2;
// update height control gas averaging
FilterHCGas = (FilterHCGas * (HC_GAS_AVERAGE - 1) + HCGas) / HC_GAS_AVERAGE;
sFilterHCGas = (sFilterHCGas * (HC_GAS_AVERAGE - 1) + HCGas) / HC_GAS_AVERAGE;
// limit height control gas pd-control output
LIMIT_MIN_MAX(FilterHCGas, EE_Parameter.Hoehe_MinGas * STICK_GAIN, (MAX_GAS - 20) * STICK_GAIN);
LIMIT_MIN_MAX(sFilterHCGas, EE_Parameter.Hoehe_MinGas * STICK_GAIN, (MAX_GAS - 20) * STICK_GAIN);
// set GasMischanteil to HeightControlGasFilter
if(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT)
{ // old version
LIMIT_MAX(FilterHCGas, GasMischanteil); // nicht mehr als Gas
GasMischanteil = FilterHCGas;
LIMIT_MAX(sFilterHCGas, GasMischanteil); // nicht mehr als Gas
GasMischanteil = sFilterHCGas;
}
else GasMischanteil = FilterHCGas + (GasMischanteil - HoverGas) / 4; // only in Vario-Mode
else GasMischanteil = sFilterHCGas + (GasMischanteil - HoverGas) / 4; // only in Vario-Mode
}
}// EOF height control active
else // HC not active
{
//update hoover gas stick value when HC is not active
//update hover gas stick value when HC is not active
if(!EE_Parameter.Hoehe_StickNeutralPoint)
{
StickGasHover = HoverGas/STICK_GAIN; // rescale back to stick value
1716,38 → 1872,38
}
else StickGasHover = EE_Parameter.Hoehe_StickNeutralPoint;
LIMIT_MIN_MAX(StickGasHover, 70, 150); // reserve some range for trim up and down
FilterHCGas = GasMischanteil;
sFilterHCGas = GasMischanteil;
// set both flags to indicate no vario mode
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN);
FC_StatusFlags2 &= ~FC_STATUS2_ALTITUDE_CONTROL;
}
// Hover gas estimation by averaging gas control output on small z-velocities
// this is done only if height contol option is selected in global config and aircraft is flying
if((FC_StatusFlags & FC_STATUS_FLY))// && !(FC_SatusFlags & FC_STATUS_EMERGENCY_LANDING))
{
if(HoverGasFilter == 0 || StartTrigger == 1) HoverGasFilter = HOVER_GAS_AVERAGE * (unsigned long)(GasMischanteil); // init estimation
if((FC_StatusFlags & FC_STATUS_FLY)) {
if(sHoverGasFilter == 0 || StartTrigger == 1) sHoverGasFilter = HOVER_GAS_AVERAGE * (unsigned long)(GasMischanteil); // init estimation
if(StartTrigger == 1) StartTrigger = 2;
tmp_long2 = (int32_t)GasMischanteil; // take current thrust
int32_t tmp_long2 = (int32_t)GasMischanteil; // take current thrust
tmp_long2 *= CosAttitude; // apply attitude projection
tmp_long2 /= 8192;
// average vertical projected thrust
if(modell_fliegt < 4000) // the first 8 seconds
{ // reduce the time constant of averaging by factor of 4 to get much faster a stable value
HoverGasFilter -= HoverGasFilter/(HOVER_GAS_AVERAGE/16L);
HoverGasFilter += 16L * tmp_long2;
sHoverGasFilter -= sHoverGasFilter/(HOVER_GAS_AVERAGE/16L);
sHoverGasFilter += 16L * tmp_long2;
}
if(modell_fliegt < 8000) // the first 16 seconds
{ // reduce the time constant of averaging by factor of 2 to get much faster a stable value
HoverGasFilter -= HoverGasFilter/(HOVER_GAS_AVERAGE/4L);
HoverGasFilter += 4L * tmp_long2;
sHoverGasFilter -= sHoverGasFilter/(HOVER_GAS_AVERAGE/4L);
sHoverGasFilter += 4L * tmp_long2;
}
else //later
if(abs(VarioMeter) < 100 && abs(HoehenWert - SollHoehe) < 256) // only on small vertical speed & difference is small (only descending)
{
HoverGasFilter -= HoverGasFilter/HOVER_GAS_AVERAGE;
HoverGasFilter += tmp_long2;
sHoverGasFilter -= sHoverGasFilter/HOVER_GAS_AVERAGE;
sHoverGasFilter += tmp_long2;
}
HoverGas = (int16_t)(HoverGasFilter/HOVER_GAS_AVERAGE);
HoverGas = (int16_t)(sHoverGasFilter/HOVER_GAS_AVERAGE);
if(EE_Parameter.Hoehe_HoverBand)
{
int16_t band;
1763,144 → 1919,11
}
else
{
// not flying
StartTrigger = 0;
HoverGasFilter = 0;
sHoverGasFilter = 0;
HoverGas = 0;
}
}// EOF Parameter_GlobalConfig & CFG_HEIGHT_CONTROL
else
{
// set undefined state to indicate vario off
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN);
} // EOF no height control
 
// Linits the maximum gas in case of "Out of Range emergency landing"
if(NC_To_FC_Flags & NC_TO_FC_EMERGENCY_LANDING)
{
if(GasMischanteil/STICK_GAIN > HooverGasEmergencyPercent && HoverGas) GasMischanteil = HooverGasEmergencyPercent * STICK_GAIN;
SollHoehe = HoehenWert; // update setpoint to current heigth
beeptime = 15000;
BeepMuster = 0x0E00;
return GasMischanteil;
}
// limit gas to parameter setting
LIMIT_MIN(GasMischanteil, (MIN_GAS + 10) * STICK_GAIN);
if(GasMischanteil > (MAX_GAS - 20) * STICK_GAIN) GasMischanteil = (MAX_GAS - 20) * STICK_GAIN;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// all BL-Ctrl connected?
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(MissingMotor || Capacity.MinOfMaxPWM != 255 || NC_ErrorCode) // wait until all BL-Ctrls started and no Errors
if(modell_fliegt > 1 && modell_fliegt < 50 && GasMischanteil > 0) // only during start-phase
{
modell_fliegt = 1;
GasMischanteil = (MIN_GAS + 10) * STICK_GAIN;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Mischer und PI-Regler
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DebugOut.Analog[7] = GasMischanteil;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gier-Anteil
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GierMischanteil = MesswertGier - sollGier * STICK_GAIN; // Regler für Gier
#define MIN_GIERGAS (40*STICK_GAIN) // unter diesem Gaswert trotzdem Gieren
if(GasMischanteil > MIN_GIERGAS)
{
if(GierMischanteil > (GasMischanteil / 2)) GierMischanteil = GasMischanteil / 2;
if(GierMischanteil < -(GasMischanteil / 2)) GierMischanteil = -(GasMischanteil / 2);
}
else
{
if(GierMischanteil > (MIN_GIERGAS / 2)) GierMischanteil = MIN_GIERGAS / 2;
if(GierMischanteil < -(MIN_GIERGAS / 2)) GierMischanteil = -(MIN_GIERGAS / 2);
}
tmp_int = MAX_GAS*STICK_GAIN;
if(GierMischanteil > ((tmp_int - GasMischanteil))) GierMischanteil = ((tmp_int - GasMischanteil));
if(GierMischanteil < -((tmp_int - GasMischanteil))) GierMischanteil = -((tmp_int - GasMischanteil));
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Nick-Achse
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffNick = MesswertNick - StickNick; // Differenz bestimmen
if(IntegralFaktor) SummeNick += IntegralNickMalFaktor - StickNick; // I-Anteil bei Winkelregelung
else SummeNick += DiffNick; // I-Anteil bei HH
if(SummeNick > (STICK_GAIN * 16000L)) SummeNick = (STICK_GAIN * 16000L);
if(SummeNick < -(16000L * STICK_GAIN)) SummeNick = -(16000L * STICK_GAIN);
 
if(EE_Parameter.Gyro_Stability <= 8) pd_ergebnis_nick = (EE_Parameter.Gyro_Stability * DiffNick) / 8; // PI-Regler für Nick
else pd_ergebnis_nick = ((EE_Parameter.Gyro_Stability / 2) * DiffNick) / 4; // Überlauf verhindern
pd_ergebnis_nick += SummeNick / Ki;
 
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64;
if(pd_ergebnis_nick > tmp_int) pd_ergebnis_nick = tmp_int;
if(pd_ergebnis_nick < -tmp_int) pd_ergebnis_nick = -tmp_int;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Roll-Achse
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffRoll = MesswertRoll - StickRoll; // Differenz bestimmen
if(IntegralFaktor) SummeRoll += IntegralRollMalFaktor - StickRoll;// I-Anteil bei Winkelregelung
else SummeRoll += DiffRoll; // I-Anteil bei HH
if(SummeRoll > (STICK_GAIN * 16000L)) SummeRoll = (STICK_GAIN * 16000L);
if(SummeRoll < -(16000L * STICK_GAIN)) SummeRoll = -(16000L * STICK_GAIN);
 
if(EE_Parameter.Gyro_Stability <= 8) pd_ergebnis_roll = (EE_Parameter.Gyro_Stability * DiffRoll) / 8; // PI-Regler für Roll
else pd_ergebnis_roll = ((EE_Parameter.Gyro_Stability / 2) * DiffRoll) / 4; // Überlauf verhindern
pd_ergebnis_roll += SummeRoll / Ki;
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64;
if(pd_ergebnis_roll > tmp_int) pd_ergebnis_roll = tmp_int;
if(pd_ergebnis_roll < -tmp_int) pd_ergebnis_roll = -tmp_int;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Universal Mixer
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
for(i=0; i<MAX_MOTORS; i++)
{
signed int tmp_int;
if(Mixer.Motor[i][0] > 0)
{
// Gas
if(Mixer.Motor[i][0] == 64) tmp_int = GasMischanteil; else tmp_int = ((long)GasMischanteil * Mixer.Motor[i][0]) / 64L;
// Nick
if(Mixer.Motor[i][1] == 64) tmp_int += pd_ergebnis_nick;
else if(Mixer.Motor[i][1] == -64) tmp_int -= pd_ergebnis_nick;
else tmp_int += ((long)pd_ergebnis_nick * Mixer.Motor[i][1]) / 64L;
// Roll
if(Mixer.Motor[i][2] == 64) tmp_int += pd_ergebnis_roll;
else if(Mixer.Motor[i][2] == -64) tmp_int -= pd_ergebnis_roll;
else tmp_int += ((long)pd_ergebnis_roll * Mixer.Motor[i][2]) / 64L;
// Gier
if(Mixer.Motor[i][3] == 64) tmp_int += GierMischanteil;
else if(Mixer.Motor[i][3] == -64) tmp_int -= GierMischanteil;
else tmp_int += ((long)GierMischanteil * Mixer.Motor[i][3]) / 64L;
 
if(tmp_int > tmp_motorwert[i]) tmp_int = (tmp_motorwert[i] + tmp_int) / 2; // MotorSmoothing
// else tmp_int = 2 * tmp_int - tmp_motorwert[i]; // original MotorSmoothing
else
{
if(EE_Parameter.MotorSmooth == 0)
{
tmp_int = 2 * tmp_int - tmp_motorwert[i]; // original MotorSmoothing
}
else // 1 means tmp_int = tmp_int;
if(EE_Parameter.MotorSmooth > 1)
{
// If >= 2 then allow >= 50% of the intended step down to rapidly reach the intended value.
tmp_int = tmp_int + ((tmp_motorwert[i] - tmp_int)/EE_Parameter.MotorSmooth);
}
}
 
LIMIT_MIN_MAX(tmp_int,(int) MIN_GAS * 4,(int) MAX_GAS * 4);
Motor[i].SetPoint = tmp_int / 4;
Motor[i].SetPointLowerBits = (tmp_int % 4)<<1; // (3 bits total)
tmp_motorwert[i] = tmp_int;
}
else
{
Motor[i].SetPoint = 0;
Motor[i].SetPointLowerBits = 0;
}
}
}
//DebugOut.Analog[16]
/branches/Proxy sensor - tempolo/main.c
300,10 → 300,10
 
if(!UpdateMotor)
{
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
//#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(NewSBusData) ProcessSBus();
else
#endif
//#endif
{
if(CalculateServoSignals) CalculateServo();
DatenUebertragung();
/branches/Proxy sensor - tempolo/makefile
1,12 → 1,12
#--------------------------------------------------------------------
# MCU name
MCU = atmega1284p
#MCU = atmega644p
#MCU = atmega1284p
MCU = atmega644p
F_CPU = 20000000
#-------------------------------------------------------------------
VERSION_MAJOR = 0
VERSION_MINOR = 88
VERSION_PATCH = 12
VERSION_PATCH = 13
VERSION_SERIAL_MAJOR = 11 # Serial Protocol
VERSION_SERIAL_MINOR = 0 # Serial Protocol
NC_SPI_COMPATIBLE = 51 # Navi-Kompatibilität
/branches/Proxy sensor - tempolo/sbus.c
57,7 → 57,8
#include "sbus.h"
#include "main.h"
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
// #if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
unsigned char NewSBusData = 0, sBusBuffer[25];
 
//############################################################################
196,4 → 197,4
NewSBusData = 0;
}
 
#endif
//#endif
/branches/Proxy sensor - tempolo/sbus.h
1,11 → 1,13
#ifndef _SBUS_H
#define _SBUS_H
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
//#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
extern unsigned char NewSBusData, sBusBuffer[25];
extern void SbusParser(unsigned char);
extern void SbusUartInit(void);
extern void ProcessSBus(void);
 
//#endif
 
#endif
#endif
/branches/Proxy sensor - tempolo/user_receiver.c
2,6 → 2,7
// Implement your own RC-decoding routines here
//############################################################################
 
#include "sbus.h"
 
//############################################################################
// Initialize the UART here
8,7 → 9,7
//############################################################################
void User_Receiver_Init(void)
{
// SpektrumUartInit(); // or use an existing routine like this
SbusUartInit();
};
 
 
18,6 → 19,6
//############################################################################
void User_RX_Parser(unsigned char udr)
{
SbusParser(udr);
};