0,0 → 1,1277 |
/*####################################################################################### |
Flight Control |
#######################################################################################*/ |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Copyright (c) 04.2007 Holger Buss |
// + Nur für den privaten Gebrauch |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), |
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. |
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt |
// + bzgl. der Nutzungsbedingungen aufzunehmen. |
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen, |
// + Verkauf von Luftbildaufnahmen, usw. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht, |
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts |
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de" |
// + eindeutig als Ursprung verlinkt werden |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion |
// + Benutzung auf eigene Gefahr |
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur |
// + mit unserer Zustimmung zulässig |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Redistributions of source code (with or without modifications) must retain the above copyright notice, |
// + this list of conditions and the following disclaimer. |
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived |
// + from this software without specific prior written permission. |
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet |
// + for non-commercial use (directly or indirectly) |
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted |
// + with our written permission |
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be |
// + clearly linked as origin |
// + * porting to systems other than hardware from www.mikrokopter.de is not allowed |
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
// + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
// + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
// + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
// + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
// + POSSIBILITY OF SUCH DAMAGE. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
#include "main.h" |
#include "parameter.h" |
#include "pitch.h" |
#include "altcon.h" |
#include "eeprom.c" |
|
unsigned char h, m, s; |
volatile unsigned int I2CTimeout = 100; |
volatile int MesswertNick, MesswertRoll, MesswertGier, MesswertGierBias; |
int AdNeutralGierBias; |
int AdNeutralNick = 0, AdNeutralRoll = 0, AdNeutralGier = 0, StartNeutralRoll = 0, StartNeutralNick = 0; |
int Mittelwert_AccNick, Mittelwert_AccRoll, Mittelwert_AccHoch, NeutralAccX = 0, NeutralAccY = 0; |
int NaviAccNick, NaviAccRoll, NaviCntAcc = 0; |
volatile float NeutralAccZ = 0; |
unsigned char CosinusNickWinkel = 0, CosinusRollWinkel = 0; |
long IntegralNick = 0, IntegralNick2 = 0; |
long IntegralRoll = 0, IntegralRoll2 = 0; |
long IntegralAccNick = 0, IntegralAccRoll = 0, IntegralAccZ = 0; |
long Integral_Gier = 0; |
long Mess_IntegralNick = 0, Mess_IntegralNick2 = 0; |
long Mess_IntegralRoll = 0, Mess_IntegralRoll2 = 0; |
long Mess_Integral_Gier = 0, Mess_Integral_Gier2 = 0; |
long MittelIntegralNick, MittelIntegralRoll, MittelIntegralNick2, MittelIntegralRoll2; |
volatile long Mess_Integral_Hoch = 0; |
volatile int KompassValue = 0; |
volatile int KompassStartwert = 0; |
volatile int KompassRichtung = 0; |
unsigned int KompassSignalSchlecht = 500; |
unsigned char MAX_GAS, MIN_GAS; |
unsigned char Notlandung = 0; |
unsigned char HoehenReglerAktiv = 0; |
unsigned char TrichterFlug = 0; |
long Umschlag180Nick = 250000L, Umschlag180Roll = 250000L; |
long ErsatzKompass; |
int ErsatzKompassInGrad; // Kompasswert in Grad |
int GierGyroFehler = 0; |
float GyroFaktor; |
float IntegralFaktor; |
volatile int DiffNick, DiffRoll; |
int Poti1 = 0, Poti2 = 0, Poti3 = 0, Poti4 = 0; |
volatile unsigned char Motor_Vorne, Motor_Hinten, Motor_Rechts, Motor_Links, Count; |
volatile unsigned char SenderOkay = 0; |
int StickNick = 0, StickRoll = 0, StickGier = 0, StickGas = 0; |
char MotorenEin = 0; |
int HoehenWert = 0; |
int SollHoehe = 0; |
int LageKorrekturRoll = 0, LageKorrekturNick = 0; |
float Ki = FAKTOR_I; |
unsigned char Looping_Nick = 0, Looping_Roll = 0; |
unsigned char Looping_Links = 0, Looping_Rechts = 0, Looping_Unten = 0, Looping_Oben = 0; |
|
unsigned char Parameter_Luftdruck_D = 48; // Wert : 0-250 |
unsigned char Parameter_MaxHoehe = 251; // Wert : 0-250 |
unsigned char Parameter_Hoehe_P = 16; // Wert : 0-32 |
unsigned char Parameter_Hoehe_ACC_Wirkung = 58; // Wert : 0-250 |
unsigned char Parameter_KompassWirkung = 64; // Wert : 0-250 |
unsigned char Parameter_Gyro_P = 150; // Wert : 10-250 |
unsigned char Parameter_Gyro_I = 150; // Wert : 0-250 |
unsigned char Parameter_Gier_P = 2; // Wert : 1-20 |
unsigned char Parameter_I_Faktor = 10; // Wert : 1-20 |
unsigned char Parameter_UserParam1 = 0; |
unsigned char Parameter_UserParam2 = 0; |
unsigned char Parameter_UserParam3 = 0; |
unsigned char Parameter_UserParam4 = 0; |
unsigned char Parameter_UserParam5 = 0; |
unsigned char Parameter_UserParam6 = 0; |
unsigned char Parameter_UserParam7 = 0; |
unsigned char Parameter_UserParam8 = 0; |
unsigned char Parameter_ServoNickControl = 100; |
unsigned char Parameter_LoopGasLimit = 70; |
unsigned char Parameter_AchsKopplung1 = 0; |
unsigned char Parameter_AchsGegenKopplung1 = 0; |
unsigned char Parameter_DynamicStability = 100; |
unsigned char Parameter_J16Bitmask; // for the J16 Output |
unsigned char Parameter_J16Timing; // for the J16 Output |
unsigned char Parameter_J16Brightness; // for the J16 Output |
unsigned char Parameter_J17Bitmask; // for the J17 Output |
unsigned char Parameter_J17Timing; // for the J17 Output |
unsigned char Parameter_J17Brightness; // for the J17 Output |
unsigned char Parameter_NaviGpsModeControl; // Parameters for the Naviboard |
unsigned char Parameter_NaviGpsGain; |
unsigned char Parameter_NaviGpsP; |
unsigned char Parameter_NaviGpsI; |
unsigned char Parameter_NaviGpsD; |
unsigned char Parameter_NaviGpsACC; |
unsigned char Parameter_NaviOperatingRadius; |
unsigned char Parameter_NaviWindCorrection; |
unsigned char Parameter_NaviSpeedCompensation; |
unsigned char Parameter_ExternalControl; |
struct mk_param_struct EE_Parameter; |
signed int ExternStickNick = 0, ExternStickRoll = 0, ExternStickGier = 0, ExternHoehenValue = -20; |
int MaxStickNick = 0, MaxStickRoll = 0; |
unsigned int modell_fliegt = 0; |
unsigned char MikroKopterFlags = 0; |
|
void Piep(unsigned char Anzahl) { |
while (Anzahl--) { |
if (MotorenEin) return; //auf keinen Fall im Flug! |
beeptime = 100; |
Delay_ms(250); |
} |
} |
|
//############################################################################ |
// Nullwerte ermitteln |
|
void SetNeutral(void) |
//############################################################################ |
{ |
NeutralAccX = 0; |
NeutralAccY = 0; |
NeutralAccZ = 0; |
AdNeutralNick = 0; |
AdNeutralRoll = 0; |
AdNeutralGier = 0; |
AdNeutralGierBias = 0; |
Parameter_AchsKopplung1 = 0; |
Parameter_AchsGegenKopplung1 = 0; |
ExpandBaro = 0; |
CalibrierMittelwert(); |
Delay_ms_Mess(100); |
CalibrierMittelwert(); |
if ((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung aktiviert? |
{ |
if ((MessLuftdruck > 950) || (MessLuftdruck < 750)) SucheLuftruckOffset(); |
} |
|
AdNeutralNick = AdWertNick; |
AdNeutralRoll = AdWertRoll; |
AdNeutralGier = AdWertGier; |
AdNeutralGierBias = AdWertGier; |
StartNeutralRoll = AdNeutralRoll; |
StartNeutralNick = AdNeutralNick; |
if (eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) > 4) { |
NeutralAccY = abs(Mittelwert_AccRoll) / ACC_AMPLIFY; |
NeutralAccX = abs(Mittelwert_AccNick) / ACC_AMPLIFY; |
NeutralAccZ = Aktuell_az; |
} else { |
NeutralAccX = (int) eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) * 256 + (int) eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK + 1]); |
NeutralAccY = (int) eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL]) * 256 + (int) eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL + 1]); |
NeutralAccZ = (int) eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_Z]) * 256 + (int) eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_Z + 1]); |
} |
|
Mess_IntegralNick = 0; |
Mess_IntegralNick2 = 0; |
Mess_IntegralRoll = 0; |
Mess_IntegralRoll2 = 0; |
Mess_Integral_Gier = 0; |
MesswertNick = 0; |
MesswertRoll = 0; |
MesswertGier = 0; |
Delay_ms_Mess(100); |
StartLuftdruck = Luftdruck; |
HoeheD = 0; |
Mess_Integral_Hoch = 0; |
KompassStartwert = KompassValue; |
GPS_Neutral(); |
beeptime = 50; |
Umschlag180Nick = ((long) EE_Parameter.WinkelUmschlagNick * 2500L) + 15000L; |
Umschlag180Roll = ((long) EE_Parameter.WinkelUmschlagRoll * 2500L) + 15000L; |
ExternHoehenValue = 0; |
ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR; |
GierGyroFehler = 0; |
SendVersionToNavi = 1; |
LED_Init(); |
MikroKopterFlags |= FLAG_CALIBRATE; |
FromNaviCtrl_Value.Kalman_K = -1; |
FromNaviCtrl_Value.Kalman_MaxDrift = EE_Parameter.Driftkomp * 16; |
FromNaviCtrl_Value.Kalman_MaxFusion = 32; |
} |
|
void LesePotis(void) { |
/* Warum 110? Knüppel geht von -125 bis 125! |
if(Poti1 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110) Poti1++; else if(Poti1 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110 && Poti1) Poti1--; |
if(Poti2 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110) Poti2++; else if(Poti2 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110 && Poti2) Poti2--; |
if(Poti3 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110) Poti3++; else if(Poti3 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110 && Poti3) Poti3--; |
if(Poti4 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110) Poti4++; else if(Poti4 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110 && Poti4) Poti4--; |
*/ |
if (Poti1 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 125) Poti1++; |
else if (Poti1 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 125 && Poti1) Poti1--; |
if (Poti2 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 125) Poti2++; |
else if (Poti2 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 125 && Poti2) Poti2--; |
if (Poti3 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 125) Poti3++; |
else if (Poti3 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 125 && Poti3) Poti3--; |
if (Poti4 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 125) Poti4++; |
else if (Poti4 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 125 && Poti4) Poti4--; |
if (Poti1 < 0) Poti1 = 0; |
else if (Poti1 > 255) Poti1 = 255; |
if (Poti2 < 0) Poti2 = 0; |
else if (Poti2 > 255) Poti2 = 255; |
if (Poti3 < 0) Poti3 = 0; |
else if (Poti3 > 255) Poti3 = 255; |
if (Poti4 < 0) Poti4 = 0; |
else if (Poti4 > 255) Poti4 = 255; |
} |
|
//############################################################################ |
// Bearbeitet die Messwerte |
|
void Mittelwert(void) |
//############################################################################ |
{ |
static signed long tmpl, tmpl2; |
MesswertGier = (signed int) AdNeutralGier - AdWertGier; |
MesswertGierBias = (signed int) AdNeutralGierBias - AdWertGier; |
MesswertRoll = (signed int) AdWertRoll - AdNeutralRoll; |
MesswertNick = (signed int) AdWertNick - AdNeutralNick; |
|
//DebugOut.Analog[26] = MesswertNick; |
// DebugOut.Analog[28] = MesswertRoll; |
|
// Beschleunigungssensor ++++++++++++++++++++++++++++++++++++++++++++++++ |
Mittelwert_AccNick = ((long) Mittelwert_AccNick * 1 + ((ACC_AMPLIFY * (long) AdWertAccNick))) / 2L; |
Mittelwert_AccRoll = ((long) Mittelwert_AccRoll * 1 + ((ACC_AMPLIFY * (long) AdWertAccRoll))) / 2L; |
Mittelwert_AccHoch = ((long) Mittelwert_AccHoch * 1 + ((long) AdWertAccHoch)) / 2L; |
IntegralAccNick += ACC_AMPLIFY * AdWertAccNick; |
IntegralAccRoll += ACC_AMPLIFY * AdWertAccRoll; |
NaviAccNick += AdWertAccNick; |
NaviAccRoll += AdWertAccRoll; |
NaviCntAcc++; |
IntegralAccZ += Aktuell_az - NeutralAccZ; |
// Gier ++++++++++++++++++++++++++++++++++++++++++++++++ |
ErsatzKompass += MesswertGier; |
Mess_Integral_Gier += MesswertGier; |
// Mess_Integral_Gier2 += MesswertGier; |
if (ErsatzKompass >= (360L * GIER_GRAD_FAKTOR)) ErsatzKompass -= 360L * GIER_GRAD_FAKTOR; // 360° Umschlag |
if (ErsatzKompass < 0) ErsatzKompass += 360L * GIER_GRAD_FAKTOR; |
// Kopplungsanteil +++++++++++++++++++++++++++++++++++++ |
if (!Looping_Nick && !Looping_Roll && (EE_Parameter.GlobalConfig & CFG_ACHSENKOPPLUNG_AKTIV)) { |
tmpl = (MesswertGierBias * Mess_IntegralNick) / 2048L; |
tmpl *= Parameter_AchsKopplung1; //125 |
tmpl /= 4096L; |
tmpl2 = (MesswertGierBias * Mess_IntegralRoll) / 2048L; |
tmpl2 *= Parameter_AchsKopplung1; |
tmpl2 /= 4096L; |
if (labs(tmpl) > 128 || labs(tmpl2) > 128) TrichterFlug = 1; |
} else tmpl = tmpl2 = 0; |
// Roll ++++++++++++++++++++++++++++++++++++++++++++++++ |
MesswertRoll += tmpl; |
MesswertRoll += (tmpl2 * Parameter_AchsGegenKopplung1) / 512L; //109 |
Mess_IntegralRoll2 += MesswertRoll; |
Mess_IntegralRoll += MesswertRoll - LageKorrekturRoll; |
if (Mess_IntegralRoll > Umschlag180Roll) { |
Mess_IntegralRoll = -(Umschlag180Roll - 25000L); |
Mess_IntegralRoll2 = Mess_IntegralRoll; |
} |
if (Mess_IntegralRoll <-Umschlag180Roll) { |
Mess_IntegralRoll = (Umschlag180Roll - 25000L); |
Mess_IntegralRoll2 = Mess_IntegralRoll; |
} |
if (AdWertRoll < 15) MesswertRoll = -1000; |
if (AdWertRoll < 7) MesswertRoll = -2000; |
if (PlatinenVersion == 10) { |
if (AdWertRoll > 1010) MesswertRoll = +1000; |
if (AdWertRoll > 1017) MesswertRoll = +2000; |
} else { |
if (AdWertRoll > 2020) MesswertRoll = +1000; |
if (AdWertRoll > 2034) MesswertRoll = +2000; |
} |
// Nick ++++++++++++++++++++++++++++++++++++++++++++++++ |
MesswertNick -= tmpl2; |
MesswertNick -= (tmpl * Parameter_AchsGegenKopplung1) / 512L; |
Mess_IntegralNick2 += MesswertNick; |
Mess_IntegralNick += MesswertNick - LageKorrekturNick; |
|
if (Mess_IntegralNick > Umschlag180Nick) { |
Mess_IntegralNick = -(Umschlag180Nick - 25000L); |
Mess_IntegralNick2 = Mess_IntegralNick; |
} |
if (Mess_IntegralNick <-Umschlag180Nick) { |
Mess_IntegralNick = (Umschlag180Nick - 25000L); |
Mess_IntegralNick2 = Mess_IntegralNick; |
} |
if (AdWertNick < 15) MesswertNick = -1000; |
if (AdWertNick < 7) MesswertNick = -2000; |
if (PlatinenVersion == 10) { |
if (AdWertNick > 1010) MesswertNick = +1000; |
if (AdWertNick > 1017) MesswertNick = +2000; |
} else { |
if (AdWertNick > 2020) MesswertNick = +1000; |
if (AdWertNick > 2034) MesswertNick = +2000; |
} |
//++++++++++++++++++++++++++++++++++++++++++++++++ |
// ADC einschalten |
ANALOG_ON; |
//++++++++++++++++++++++++++++++++++++++++++++++++ |
|
Integral_Gier = Mess_Integral_Gier; |
IntegralNick = Mess_IntegralNick; |
IntegralRoll = Mess_IntegralRoll; |
IntegralNick2 = Mess_IntegralNick2; |
IntegralRoll2 = Mess_IntegralRoll2; |
|
if (EE_Parameter.GlobalConfig & CFG_DREHRATEN_BEGRENZER && !Looping_Nick && !Looping_Roll) { |
if (MesswertNick > 200) MesswertNick += 4 * (MesswertNick - 200); |
else if (MesswertNick < -200) MesswertNick += 4 * (MesswertNick + 200); |
if (MesswertRoll > 200) MesswertRoll += 4 * (MesswertRoll - 200); |
else if (MesswertRoll < -200) MesswertRoll += 4 * (MesswertRoll + 200); |
} |
LesePotis(); |
} |
|
//############################################################################ |
// Messwerte beim Ermitteln der Nullage |
|
void CalibrierMittelwert(void) |
//############################################################################ |
{ |
if (PlatinenVersion == 13) SucheGyroOffset(); |
// ADC auschalten, damit die Werte sich nicht während der Berechnung ändern |
ANALOG_OFF; |
MesswertNick = AdWertNick; |
MesswertRoll = AdWertRoll; |
MesswertGier = AdWertGier; |
Mittelwert_AccNick = ACC_AMPLIFY * (long) AdWertAccNick; |
Mittelwert_AccRoll = ACC_AMPLIFY * (long) AdWertAccRoll; |
Mittelwert_AccHoch = (long) AdWertAccHoch; |
// ADC einschalten |
ANALOG_ON; |
|
LesePotis(); |
|
Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L; |
Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L; |
} |
|
//############################################################################ |
// Senden der Motorwerte per I2C-Bus |
|
void SendMotorData(void) |
//############################################################################ |
{ |
DebugOut.Analog[12] = Motor_Vorne; |
DebugOut.Analog[13] = Motor_Hinten; |
DebugOut.Analog[14] = Motor_Links; |
DebugOut.Analog[15] = Motor_Rechts; |
|
if (!(MotorenEin && PARAM_ENGINE_ENABLED)) { |
Motor_Hinten = 0; |
Motor_Vorne = 0; |
Motor_Rechts = 0; |
Motor_Links = 0; |
if (MotorTest[0]) Motor_Vorne = MotorTest[0]; |
if (MotorTest[1]) Motor_Hinten = MotorTest[1]; |
if (MotorTest[2]) Motor_Links = MotorTest[2]; |
if (MotorTest[3]) Motor_Rechts = MotorTest[3]; |
MikroKopterFlags &= ~(FLAG_MOTOR_RUN | FLAG_FLY); |
} else MikroKopterFlags |= FLAG_MOTOR_RUN; |
|
//Start I2C Interrupt Mode |
twi_state = 0; |
motor = 0; |
i2c_start(); |
} |
|
|
|
//############################################################################ |
// Trägt ggf. das Poti als Parameter ein |
|
void ParameterZuordnung(void) |
//############################################################################ |
{ |
#define CHK_POTI_MM(b,a,min,max) { if(a > 250) { if(a == 251) b = Poti1; else if(a == 252) b = Poti2; else if(a == 253) b = Poti3; else if(a == 254) b = Poti4;} else b = a; if(b <= min) b = min; else if(b >= max) b = max;} |
#define CHK_POTI(b,a,min,max) { if(a > 250) { if(a == 251) b = Poti1; else if(a == 252) b = Poti2; else if(a == 253) b = Poti3; else if(a == 254) b = Poti4;} else b = a; } |
CHK_POTI(Parameter_MaxHoehe, EE_Parameter.MaxHoehe, 0, 255); |
CHK_POTI_MM(Parameter_Luftdruck_D, EE_Parameter.Luftdruck_D, 0, 100); |
CHK_POTI_MM(Parameter_Hoehe_P, EE_Parameter.Hoehe_P, 0, 100); |
CHK_POTI(Parameter_Hoehe_ACC_Wirkung, EE_Parameter.Hoehe_ACC_Wirkung, 0, 255); |
CHK_POTI(Parameter_KompassWirkung, EE_Parameter.KompassWirkung, 0, 255); |
CHK_POTI_MM(Parameter_Gyro_P, EE_Parameter.Gyro_P, 10, 255); |
CHK_POTI(Parameter_Gyro_I, EE_Parameter.Gyro_I, 0, 255); |
CHK_POTI(Parameter_I_Faktor, EE_Parameter.I_Faktor, 0, 255); |
CHK_POTI(Parameter_UserParam1, EE_Parameter.UserParam1, 0, 255); |
CHK_POTI(Parameter_UserParam2, EE_Parameter.UserParam2, 0, 255); |
CHK_POTI(Parameter_UserParam3, EE_Parameter.UserParam3, 0, 255); |
CHK_POTI(Parameter_UserParam4, EE_Parameter.UserParam4, 0, 255); |
CHK_POTI(Parameter_UserParam5, EE_Parameter.UserParam5, 0, 255); |
CHK_POTI(Parameter_UserParam6, EE_Parameter.UserParam6, 0, 255); |
CHK_POTI(Parameter_UserParam7, EE_Parameter.UserParam7, 0, 255); |
CHK_POTI(Parameter_UserParam8, EE_Parameter.UserParam8, 0, 255); |
CHK_POTI(Parameter_ServoNickControl, EE_Parameter.ServoNickControl, 0, 255); |
CHK_POTI(Parameter_LoopGasLimit, EE_Parameter.LoopGasLimit, 0, 255); |
CHK_POTI(Parameter_AchsKopplung1, EE_Parameter.AchsKopplung1, 0, 255); |
CHK_POTI(Parameter_AchsGegenKopplung1, EE_Parameter.AchsGegenKopplung1, 0, 255); |
CHK_POTI(Parameter_DynamicStability, EE_Parameter.DynamicStability, 0, 255); |
|
CHK_POTI_MM(Parameter_J16Timing, EE_Parameter.J16Timing, 1, 255); |
CHK_POTI_MM(Parameter_J16Brightness, PARAM_LED_BRIGHTNESS_J16, 0, 250); |
CHK_POTI_MM(Parameter_J17Timing, EE_Parameter.J17Timing, 1, 255); |
CHK_POTI_MM(Parameter_J17Brightness, PARAM_LED_BRIGHTNESS_J17, 0, 250); |
|
// CHK_POTI(Parameter_NaviGpsModeControl,EE_Parameter.NaviGpsModeControl,0,255); |
//CHK_POTI(Parameter_NaviGpsGain,EE_Parameter.NaviGpsGain,0,255); |
// CHK_POTI(Parameter_NaviGpsP,EE_Parameter.NaviGpsP,0,255); |
// CHK_POTI(Parameter_NaviGpsI,EE_Parameter.NaviGpsI,0,255); |
// CHK_POTI(Parameter_NaviGpsD,EE_Parameter.NaviGpsD,0,255); |
// CHK_POTI(Parameter_NaviGpsACC,EE_Parameter.NaviGpsACC,0,255); |
// CHK_POTI_MM(Parameter_NaviOperatingRadius,EE_Parameter.NaviOperatingRadius,10,255); |
// CHK_POTI(Parameter_NaviWindCorrection,EE_Parameter.NaviWindCorrection,0,255); |
// CHK_POTI(Parameter_NaviSpeedCompensation,EE_Parameter.NaviSpeedCompensation,0,255); |
|
CHK_POTI(Parameter_ExternalControl, EE_Parameter.ExternalControl, 0, 255); |
|
Ki = (float) Parameter_I_Faktor * 0.0001; |
MAX_GAS = EE_Parameter.Gas_Max; |
MIN_GAS = EE_Parameter.Gas_Min; |
} |
|
|
|
//############################################################################ |
// |
|
void MotorRegler(void) |
//############################################################################ |
{ |
int motorwert, pd_ergebnis, tmp_int; |
int GierMischanteil, GasMischanteil; |
static long SummeNick = 0, SummeRoll = 0; |
static long sollGier = 0, tmp_long, tmp_long2; |
static long IntegralFehlerNick = 0; |
static long IntegralFehlerRoll = 0; |
static unsigned int RcLostTimer; |
static unsigned char delay_neutral = 0; |
static unsigned char delay_einschalten = 0, delay_ausschalten = 0; |
static char TimerWerteausgabe = 0; |
static char NeueKompassRichtungMerken = 0; |
static long ausgleichNick, ausgleichRoll; |
|
Mittelwert(); |
|
GRN_ON; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gaswert ermitteln |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
GasMischanteil = StickGas; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Empfang schlecht |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (SenderOkay < 100) { |
if (!PcZugriff) { |
if (BeepMuster == 0xffff) { |
beeptime = 15000; |
BeepMuster = 0x0c00; |
} |
} |
if (RcLostTimer) RcLostTimer--; |
else { |
MotorenEin = 0; |
Notlandung = 0; |
} |
ROT_ON; |
if (modell_fliegt > 1000) // wahrscheinlich in der Luft --> langsam absenken |
{ |
GasMischanteil = EE_Parameter.NotGas; |
Notlandung = 1; |
PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] = 0; |
PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] = 0; |
} else MotorenEin = 0; |
} else |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Emfang gut |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (SenderOkay > 140) { |
Notlandung = 0; |
RcLostTimer = EE_Parameter.NotGasZeit * 50; |
if (GasMischanteil > 40 && MotorenEin) { |
if (modell_fliegt < 0xffff) modell_fliegt++; |
} |
if ((modell_fliegt < 256)) { |
SummeNick = 0; |
SummeRoll = 0; |
if (modell_fliegt == 250) { |
NeueKompassRichtungMerken = 1; |
sollGier = 0; |
Mess_Integral_Gier = 0; |
// Mess_Integral_Gier2 = 0; |
} |
} else MikroKopterFlags |= FLAG_FLY; |
|
if ((PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] > 80) && MotorenEin == 0) { |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// auf Nullwerte kalibrieren |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75) // Neutralwerte |
{ |
if (++delay_neutral > 200) // nicht sofort |
{ |
GRN_OFF; |
MotorenEin = 0; |
delay_neutral = 0; |
modell_fliegt = 0; |
if (PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70 || abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]) > 70) { |
unsigned char setting = 1; |
if (PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > 70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < 70) setting = 1; |
if (PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > 70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70) setting = 2; |
if (PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < 70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70) setting = 3; |
if (PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] <-70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70) setting = 4; |
if (PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] <-70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < 70) setting = 5; |
SetActiveParamSetNumber(setting); // aktiven Datensatz merken |
} |
// else |
if (abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]) < 30 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -70) { |
WinkelOut.CalcState = 1; |
beeptime = 1000; |
} else { |
ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) & EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE); |
if ((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung aktiviert? |
{ |
if ((MessLuftdruck > 950) || (MessLuftdruck < 750)) SucheLuftruckOffset(); |
} |
SetNeutral(); |
Piep(GetActiveParamSetNumber()); |
} |
} |
} else |
if (PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] < -75) // ACC Neutralwerte speichern |
{ |
if (++delay_neutral > 200) // nicht sofort |
{ |
GRN_OFF; |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_NICK], 0xff); // Werte löschen |
MotorenEin = 0; |
delay_neutral = 0; |
modell_fliegt = 0; |
SetNeutral(); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_NICK], NeutralAccX / 256); // ACC-NeutralWerte speichern |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_NICK + 1], NeutralAccX % 256); // ACC-NeutralWerte speichern |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL], NeutralAccY / 256); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL + 1], NeutralAccY % 256); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_Z], (int) NeutralAccZ / 256); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_Z + 1], (int) NeutralAccZ % 256); |
Piep(GetActiveParamSetNumber()); |
} |
} else delay_neutral = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gas ist unten |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] < 35 - 125) { |
// Starten |
if (!MotorenEin && PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] < -75) { |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Einschalten |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (++delay_einschalten > 200) { |
delay_einschalten = 200; |
modell_fliegt = 1; |
MotorenEin = 1; |
sollGier = 0; |
Mess_Integral_Gier = 0; |
Mess_Integral_Gier2 = 0; |
Mess_IntegralNick = 0; |
Mess_IntegralRoll = 0; |
Mess_IntegralNick2 = IntegralNick; |
Mess_IntegralRoll2 = IntegralRoll; |
SummeNick = 0; |
SummeRoll = 0; |
MikroKopterFlags |= FLAG_START; |
|
// Beim Einschalten automatisch kalibrieren |
if (PARAM_CAL_ON_START) { |
if ((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) { |
if ((MessLuftdruck > 950) || (MessLuftdruck < 750)) { |
SucheLuftruckOffset(); |
} |
} |
|
SetNeutral(); |
} |
} |
} else delay_einschalten = 0; |
//Auf Neutralwerte setzen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Auschalten |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75) { |
if (++delay_ausschalten > 200) // nicht sofort |
{ |
MotorenEin = 0; |
delay_ausschalten = 200; |
modell_fliegt = 0; |
} |
} else delay_ausschalten = 0; |
} |
} |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// neue Werte von der Funke |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (!NewPpmData-- || Notlandung) { |
static int chanNickPrev = 0; |
static int chanRollPrev = 0; |
|
static int stick_nick, stick_roll; |
|
ParameterZuordnung(); |
|
#define MAX_CHAN_VAL 125L |
#define COS45 7071L // cos( -45 ) * 10000 |
|
long chanNick = PPM_in[EE_Parameter.Kanalbelegung[K_NICK]]; |
long chanRoll = PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]; |
|
int chanNickDiff; |
int chanRollDiff; |
|
/* Über Parameter läßt sich zwischen "+" und "X" - Formations |
* umschalten (sh. parameter.h) |
*/ |
if (PARAM_X_FORMATION) { |
|
chanRoll = -chanRoll; |
|
// Stick-Koordinatensystem um -45° (rechts) drehen |
chanNick *= COS45; |
chanRoll *= COS45; |
|
int chanNickTemp = (chanNick - chanRoll) / 10000L; |
int chanRollTemp = (chanRoll + chanNick) / 10000L; |
|
chanNick = chanNickTemp; |
chanRoll = -chanRollTemp; |
|
if (chanNick > MAX_CHAN_VAL) |
chanNick = MAX_CHAN_VAL; |
if (chanNick < -MAX_CHAN_VAL) |
chanNick = -MAX_CHAN_VAL; |
if (chanRoll > MAX_CHAN_VAL) |
chanRoll = MAX_CHAN_VAL; |
if (chanRoll < -MAX_CHAN_VAL) |
chanRoll = -MAX_CHAN_VAL; |
} |
|
chanNickDiff = ((chanNick - chanNickPrev) / 3) * 3; |
chanRollDiff = ((chanRoll - chanRollPrev) / 3) * 3; |
|
chanNickPrev = chanNick; |
chanRollPrev = chanRoll; |
|
stick_nick = (stick_nick * 3 + ((int) chanNick) * EE_Parameter.Stick_P) / 4; |
stick_nick += chanNickDiff * EE_Parameter.Stick_D; |
StickNick = stick_nick - GPS_Nick; |
|
stick_roll = (stick_roll * 3 + ((int) chanRoll) * EE_Parameter.Stick_P) / 4; |
stick_roll += chanRollDiff * EE_Parameter.Stick_D; |
StickRoll = stick_roll - GPS_Roll; |
|
StickGier = -PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]; |
|
// Gaswert übernehmen |
StickGas = pitch_value(); |
|
GyroFaktor = ((float) Parameter_Gyro_P + 10.0) / (256 / STICK_GAIN); |
IntegralFaktor = ((float) Parameter_Gyro_I) / (44000 / STICK_GAIN); |
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//+ Analoge Steuerung per Seriell |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (ExternControl.Config & 0x01 && Parameter_ExternalControl > 128) { |
StickNick += (int) ExternControl.Nick * (int) EE_Parameter.Stick_P; |
StickRoll += (int) ExternControl.Roll * (int) EE_Parameter.Stick_P; |
StickGier += ExternControl.Gier; |
ExternHoehenValue = (int) ExternControl.Hight * (int) EE_Parameter.Hoehe_Verstaerkung; |
if (ExternControl.Gas < StickGas) StickGas = ExternControl.Gas; |
} |
if (StickGas < 0) StickGas = 0; |
|
if (EE_Parameter.GlobalConfig & CFG_HEADING_HOLD) IntegralFaktor = 0; |
if (GyroFaktor < 0) GyroFaktor = 0; |
if (IntegralFaktor < 0) IntegralFaktor = 0; |
|
if (abs(StickNick / STICK_GAIN) > MaxStickNick) { |
MaxStickNick = abs(StickNick) / STICK_GAIN; |
if (MaxStickNick > 100) MaxStickNick = 100; |
} else MaxStickNick--; |
if (abs(StickRoll / STICK_GAIN) > MaxStickRoll) { |
MaxStickRoll = abs(StickRoll) / STICK_GAIN; |
if (MaxStickRoll > 100) MaxStickRoll = 100; |
} else MaxStickRoll--; |
if (Notlandung) { |
MaxStickNick = 0; |
MaxStickRoll = 0; |
} |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Looping? |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if ((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_LINKS) Looping_Links = 1; |
else { |
{ |
if ((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < (EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese))) Looping_Links = 0; |
} |
} |
if ((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < -EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_RECHTS) Looping_Rechts = 1; |
else { |
if (Looping_Rechts) // Hysterese |
{ |
if (PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > -(EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese)) Looping_Rechts = 0; |
} |
} |
|
if ((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_OBEN) Looping_Oben = 1; |
else { |
if (Looping_Oben) // Hysterese |
{ |
if ((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < (EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese))) Looping_Oben = 0; |
} |
} |
if ((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_UNTEN) Looping_Unten = 1; |
else { |
if (Looping_Unten) // Hysterese |
{ |
if (PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > -(EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese)) Looping_Unten = 0; |
} |
} |
|
if (Looping_Links || Looping_Rechts) Looping_Roll = 1; |
else Looping_Roll = 0; |
if (Looping_Oben || Looping_Unten) { |
Looping_Nick = 1; |
Looping_Roll = 0; |
Looping_Links = 0; |
Looping_Rechts = 0; |
} else Looping_Nick = 0; |
} // Ende neue Funken-Werte |
|
if (Looping_Roll || Looping_Nick) { |
if (GasMischanteil > EE_Parameter.LoopGasLimit) GasMischanteil = EE_Parameter.LoopGasLimit; |
} |
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bei Empfangsausfall im Flug |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (Notlandung) { |
StickGier = 0; |
StickNick = 0; |
StickRoll = 0; |
GyroFaktor = (float) 100 / (256.0 / STICK_GAIN); |
IntegralFaktor = (float) 120 / (44000 / STICK_GAIN); |
Looping_Roll = 0; |
Looping_Nick = 0; |
} |
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Integrale auf ACC-Signal abgleichen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#define ABGLEICH_ANZAHL 256L |
|
MittelIntegralNick += IntegralNick; // Für die Mittelwertbildung aufsummieren |
MittelIntegralRoll += IntegralRoll; |
MittelIntegralNick2 += IntegralNick2; |
MittelIntegralRoll2 += IntegralRoll2; |
|
if (Looping_Nick || Looping_Roll) { |
IntegralAccNick = 0; |
IntegralAccRoll = 0; |
MittelIntegralNick = 0; |
MittelIntegralRoll = 0; |
MittelIntegralNick2 = 0; |
MittelIntegralRoll2 = 0; |
Mess_IntegralNick2 = Mess_IntegralNick; |
Mess_IntegralRoll2 = Mess_IntegralRoll; |
ZaehlMessungen = 0; |
LageKorrekturNick = 0; |
LageKorrekturRoll = 0; |
} |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (!Looping_Nick && !Looping_Roll) { |
long tmp_long, tmp_long2; |
if (FromNaviCtrl_Value.Kalman_K != -1) { |
tmp_long = (long) (IntegralNick / EE_Parameter.GyroAccFaktor - (long) Mittelwert_AccNick); |
tmp_long2 = (long) (IntegralRoll / EE_Parameter.GyroAccFaktor - (long) Mittelwert_AccRoll); |
tmp_long = (tmp_long * FromNaviCtrl_Value.Kalman_K) / (32 * 16); |
tmp_long2 = (tmp_long2 * FromNaviCtrl_Value.Kalman_K) / (32 * 16); |
if ((MaxStickNick > 64) || (MaxStickRoll > 64)) { |
tmp_long /= 2; |
tmp_long2 /= 2; |
} |
if (abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]) > 25) { |
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; |
} else { |
tmp_long = (long) (IntegralNick / EE_Parameter.GyroAccFaktor - (long) Mittelwert_AccNick); |
tmp_long2 = (long) (IntegralRoll / EE_Parameter.GyroAccFaktor - (long) Mittelwert_AccRoll); |
tmp_long /= 16; |
tmp_long2 /= 16; |
if ((MaxStickNick > 64) || (MaxStickRoll > 64)) { |
tmp_long /= 3; |
tmp_long2 /= 3; |
} |
if (abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]) > 25) { |
tmp_long /= 3; |
tmp_long2 /= 3; |
} |
#define AUSGLEICH 32 |
if (tmp_long > AUSGLEICH) tmp_long = AUSGLEICH; |
if (tmp_long < -AUSGLEICH) tmp_long = -AUSGLEICH; |
if (tmp_long2 > AUSGLEICH) tmp_long2 = AUSGLEICH; |
if (tmp_long2 <-AUSGLEICH) tmp_long2 = -AUSGLEICH; |
} |
|
Mess_IntegralNick -= tmp_long; |
Mess_IntegralRoll -= tmp_long2; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (ZaehlMessungen >= ABGLEICH_ANZAHL) { |
static int cnt = 0; |
static char last_n_p, last_n_n, last_r_p, last_r_n; |
static long MittelIntegralNick_Alt, MittelIntegralRoll_Alt; |
if (!Looping_Nick && !Looping_Roll && !TrichterFlug) { |
MittelIntegralNick /= ABGLEICH_ANZAHL; |
MittelIntegralRoll /= ABGLEICH_ANZAHL; |
IntegralAccNick = (EE_Parameter.GyroAccFaktor * IntegralAccNick) / ABGLEICH_ANZAHL; |
IntegralAccRoll = (EE_Parameter.GyroAccFaktor * IntegralAccRoll) / ABGLEICH_ANZAHL; |
IntegralAccZ = IntegralAccZ / ABGLEICH_ANZAHL; |
#define MAX_I 0//(Poti2/10) |
// Nick ++++++++++++++++++++++++++++++++++++++++++++++++ |
IntegralFehlerNick = (long) (MittelIntegralNick - (long) IntegralAccNick); |
ausgleichNick = IntegralFehlerNick / EE_Parameter.GyroAccAbgleich; |
// Roll ++++++++++++++++++++++++++++++++++++++++++++++++ |
IntegralFehlerRoll = (long) (MittelIntegralRoll - (long) IntegralAccRoll); |
ausgleichRoll = IntegralFehlerRoll / EE_Parameter.GyroAccAbgleich; |
|
LageKorrekturNick = ausgleichNick / ABGLEICH_ANZAHL; |
LageKorrekturRoll = ausgleichRoll / ABGLEICH_ANZAHL; |
|
if (((MaxStickNick > 64) || (MaxStickRoll > 64) || (abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]) > 25)) && (FromNaviCtrl_Value.Kalman_K == -1)) { |
LageKorrekturNick /= 2; |
LageKorrekturRoll /= 2; |
} |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gyro-Drift ermitteln |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
MittelIntegralNick2 /= ABGLEICH_ANZAHL; |
MittelIntegralRoll2 /= ABGLEICH_ANZAHL; |
tmp_long = IntegralNick2 - IntegralNick; |
tmp_long2 = IntegralRoll2 - IntegralRoll; |
//DebugOut.Analog[25] = MittelIntegralRoll2 / 26; |
|
IntegralFehlerNick = tmp_long; |
IntegralFehlerRoll = tmp_long2; |
Mess_IntegralNick2 -= IntegralFehlerNick; |
Mess_IntegralRoll2 -= IntegralFehlerRoll; |
|
// IntegralFehlerNick = (IntegralFehlerNick * 1 + tmp_long) / 2; |
// IntegralFehlerRoll = (IntegralFehlerRoll * 1 + tmp_long2) / 2; |
if (GierGyroFehler > ABGLEICH_ANZAHL / 2) { |
AdNeutralGier++; |
AdNeutralGierBias++; |
} |
if (GierGyroFehler <-ABGLEICH_ANZAHL / 2) { |
AdNeutralGier--; |
AdNeutralGierBias--; |
} |
|
DebugOut.Analog[22] = MittelIntegralRoll / 26; |
//DebugOut.Analog[24] = GierGyroFehler; |
GierGyroFehler = 0; |
|
|
/*DebugOut.Analog[17] = IntegralAccNick / 26; |
DebugOut.Analog[18] = IntegralAccRoll / 26; |
DebugOut.Analog[19] = IntegralFehlerNick;// / 26; |
DebugOut.Analog[20] = IntegralFehlerRoll;// / 26; |
*/ |
//DebugOut.Analog[21] = MittelIntegralNick / 26; |
//MittelIntegralRoll = MittelIntegralRoll; |
//DebugOut.Analog[28] = ausgleichNick; |
/* |
DebugOut.Analog[29] = ausgleichRoll; |
DebugOut.Analog[30] = LageKorrekturRoll * 10; |
*/ |
|
#define FEHLER_LIMIT (ABGLEICH_ANZAHL * 4) |
#define FEHLER_LIMIT2 (ABGLEICH_ANZAHL * 16) |
#define BEWEGUNGS_LIMIT 20000 |
// Nick +++++++++++++++++++++++++++++++++++++++++++++++++ |
cnt = 1; // + labs(IntegralFehlerNick) / 4096; |
if (labs(MittelIntegralNick_Alt - MittelIntegralNick) < BEWEGUNGS_LIMIT || (FromNaviCtrl_Value.Kalman_MaxDrift > 3 * 16)) { |
if (IntegralFehlerNick > FEHLER_LIMIT2) { |
if (last_n_p) { |
cnt += labs(IntegralFehlerNick) / FEHLER_LIMIT2; |
ausgleichNick = IntegralFehlerNick / 8; |
if (ausgleichNick > 5000) ausgleichNick = 5000; |
LageKorrekturNick += ausgleichNick / ABGLEICH_ANZAHL; |
} else last_n_p = 1; |
} else last_n_p = 0; |
if (IntegralFehlerNick < -FEHLER_LIMIT2) { |
if (last_n_n) { |
cnt += labs(IntegralFehlerNick) / FEHLER_LIMIT2; |
ausgleichNick = IntegralFehlerNick / 8; |
if (ausgleichNick < -5000) ausgleichNick = -5000; |
LageKorrekturNick += ausgleichNick / ABGLEICH_ANZAHL; |
} else last_n_n = 1; |
} else last_n_n = 0; |
} else { |
cnt = 0; |
KompassSignalSchlecht = 1000; |
} |
if (cnt > EE_Parameter.Driftkomp) cnt = EE_Parameter.Driftkomp; |
if (cnt * 16 > FromNaviCtrl_Value.Kalman_MaxDrift) cnt = FromNaviCtrl_Value.Kalman_MaxDrift / 16; |
if (IntegralFehlerNick > FEHLER_LIMIT) AdNeutralNick += cnt; |
if (IntegralFehlerNick < -FEHLER_LIMIT) AdNeutralNick -= cnt; |
|
// Roll +++++++++++++++++++++++++++++++++++++++++++++++++ |
cnt = 1; // + labs(IntegralFehlerNick) / 4096; |
|
ausgleichRoll = 0; |
if (labs(MittelIntegralRoll_Alt - MittelIntegralRoll) < BEWEGUNGS_LIMIT || (FromNaviCtrl_Value.Kalman_MaxDrift > 3 * 16)) { |
if (IntegralFehlerRoll > FEHLER_LIMIT2) { |
if (last_r_p) { |
cnt += labs(IntegralFehlerRoll) / FEHLER_LIMIT2; |
ausgleichRoll = IntegralFehlerRoll / 8; |
if (ausgleichRoll > 5000) ausgleichRoll = 5000; |
LageKorrekturRoll += ausgleichRoll / ABGLEICH_ANZAHL; |
} else last_r_p = 1; |
} else last_r_p = 0; |
if (IntegralFehlerRoll < -FEHLER_LIMIT2) { |
if (last_r_n) { |
cnt += labs(IntegralFehlerRoll) / FEHLER_LIMIT2; |
ausgleichRoll = IntegralFehlerRoll / 8; |
if (ausgleichRoll < -5000) ausgleichRoll = -5000; |
LageKorrekturRoll += ausgleichRoll / ABGLEICH_ANZAHL; |
} else last_r_n = 1; |
} else last_r_n = 0; |
} else { |
cnt = 0; |
KompassSignalSchlecht = 1000; |
} |
if (cnt > EE_Parameter.Driftkomp) cnt = EE_Parameter.Driftkomp; |
if (cnt * 16 > FromNaviCtrl_Value.Kalman_MaxDrift) cnt = FromNaviCtrl_Value.Kalman_MaxDrift / 16; |
if (IntegralFehlerRoll > FEHLER_LIMIT) AdNeutralRoll += cnt; |
if (IntegralFehlerRoll < -FEHLER_LIMIT) AdNeutralRoll -= cnt; |
} else { |
LageKorrekturRoll = 0; |
LageKorrekturNick = 0; |
TrichterFlug = 0; |
} |
|
if (!IntegralFaktor) { |
LageKorrekturRoll = 0; |
LageKorrekturNick = 0; |
} // z.B. bei HH |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
MittelIntegralNick_Alt = MittelIntegralNick; |
MittelIntegralRoll_Alt = MittelIntegralRoll; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
IntegralAccNick = 0; |
IntegralAccRoll = 0; |
IntegralAccZ = 0; |
MittelIntegralNick = 0; |
MittelIntegralRoll = 0; |
MittelIntegralNick2 = 0; |
MittelIntegralRoll2 = 0; |
ZaehlMessungen = 0; |
} |
//DebugOut.Analog[31] = StickRoll / (26*IntegralFaktor); |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gieren |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// if(GasMischanteil < 35) { if(StickGier > 10) StickGier = 10; else if(StickGier < -10) StickGier = -10;}; |
if (abs(StickGier) > 15) // war 35 |
{ |
KompassSignalSchlecht = 1000; |
if (!(EE_Parameter.GlobalConfig & CFG_KOMPASS_FIX)) { |
NeueKompassRichtungMerken = 1; |
}; |
} |
tmp_int = (long) EE_Parameter.Gier_P * ((long) StickGier * abs(StickGier)) / 512L; // expo y = ax + bx² |
tmp_int += (EE_Parameter.Gier_P * StickGier) / 4; |
sollGier = tmp_int; |
Mess_Integral_Gier -= tmp_int; |
if (Mess_Integral_Gier > 50000) Mess_Integral_Gier = 50000; // begrenzen |
if (Mess_Integral_Gier <-50000) Mess_Integral_Gier = -50000; |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Kompass |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//DebugOut.Analog[29] = (MaxStickNick + MaxStickRoll); |
|
if (KompassValue && (EE_Parameter.GlobalConfig & CFG_KOMPASS_AKTIV)) { |
int w, v, r, fehler, korrektur; |
w = abs(IntegralNick / 512); // mit zunehmender Neigung den Einfluss drosseln |
v = abs(IntegralRoll / 512); |
if (v > w) w = v; // grösste Neigung ermitteln |
korrektur = w / 8 + 1; |
fehler = ((540 + KompassValue - (ErsatzKompass / GIER_GRAD_FAKTOR)) % 360) - 180; |
if (NeueKompassRichtungMerken) { |
fehler = 0; |
ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR; |
} |
if (!KompassSignalSchlecht && w < 25) { |
GierGyroFehler += fehler; |
if (NeueKompassRichtungMerken) { |
beeptime = 200; |
// KompassStartwert = KompassValue; |
KompassStartwert = (ErsatzKompass / GIER_GRAD_FAKTOR); |
NeueKompassRichtungMerken = 0; |
} |
} |
ErsatzKompass += (fehler * 8) / korrektur; |
w = (w * Parameter_KompassWirkung) / 32; // auf die Wirkung normieren |
w = Parameter_KompassWirkung - w; // Wirkung ggf drosseln |
if (w >= 0) { |
if (!KompassSignalSchlecht) { |
v = 64 + ((MaxStickNick + MaxStickRoll)) / 8; |
r = ((540 + (ErsatzKompass / GIER_GRAD_FAKTOR) - KompassStartwert) % 360) - 180; |
// r = KompassRichtung; |
v = (r * w) / v; // nach Kompass ausrichten |
w = 3 * Parameter_KompassWirkung; |
if (v > w) v = w; // Begrenzen |
else |
if (v < -w) v = -w; |
Mess_Integral_Gier += v; |
} |
if (KompassSignalSchlecht) KompassSignalSchlecht--; |
} else KompassSignalSchlecht = 500; // so lange das Signal taub stellen --> ca. 1 sek |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Debugwerte zuordnen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (!TimerWerteausgabe--) { |
TimerWerteausgabe = 24; |
|
DebugOut.Analog[0] = IntegralNick / EE_Parameter.GyroAccFaktor; |
DebugOut.Analog[1] = IntegralRoll / EE_Parameter.GyroAccFaktor; |
DebugOut.Analog[2] = Mittelwert_AccNick; |
DebugOut.Analog[3] = Mittelwert_AccRoll; |
DebugOut.Analog[4] = MesswertGier; |
DebugOut.Analog[5] = HoehenWert; |
DebugOut.Analog[6] = (Mess_Integral_Hoch / 512); |
DebugOut.Analog[8] = KompassValue; |
DebugOut.Analog[9] = UBat; |
DebugOut.Analog[11] = ErsatzKompass / GIER_GRAD_FAKTOR; |
DebugOut.Analog[10] = SenderOkay; |
//DebugOut.Analog[16] = Mittelwert_AccHoch; |
DebugOut.Analog[17] = FromNaviCtrl_Value.Distance; |
DebugOut.Analog[18] = (int) FromNaviCtrl_Value.OsdBar; |
DebugOut.Analog[19] = WinkelOut.CalcState; |
DebugOut.Analog[20] = ServoValue; |
// DebugOut.Analog[27] = (int)FromNaviCtrl_Value.Kalman_MaxDrift; |
// DebugOut.Analog[29] = (int)FromNaviCtrl_Value.Kalman_K; |
// DebugOut.Analog[30] = GPS_Nick; |
// DebugOut.Analog[31] = GPS_Roll; |
|
|
// DebugOut.Analog[19] -= DebugOut.Analog[19]/128; |
// if(DebugOut.Analog[19] > 0) DebugOut.Analog[19]--; else DebugOut.Analog[19]++; |
|
/* DebugOut.Analog[16] = motor_rx[0]; |
DebugOut.Analog[17] = motor_rx[1]; |
DebugOut.Analog[18] = motor_rx[2]; |
DebugOut.Analog[19] = motor_rx[3]; |
DebugOut.Analog[20] = motor_rx[0] + motor_rx[1] + motor_rx[2] + motor_rx[3]; |
DebugOut.Analog[20] /= 14; |
DebugOut.Analog[21] = motor_rx[4]; |
DebugOut.Analog[22] = motor_rx[5]; |
DebugOut.Analog[23] = motor_rx[6]; |
DebugOut.Analog[24] = motor_rx[7]; |
DebugOut.Analog[25] = motor_rx[4] + motor_rx[5] + motor_rx[6] + motor_rx[7]; |
*/ |
// DebugOut.Analog[9] = MesswertNick; |
// DebugOut.Analog[9] = SollHoehe; |
// DebugOut.Analog[10] = Mess_Integral_Gier / 128; |
// DebugOut.Analog[11] = KompassStartwert; |
// DebugOut.Analog[10] = Parameter_Gyro_I; |
// DebugOut.Analog[10] = EE_Parameter.Gyro_I; |
// DebugOut.Analog[9] = KompassRichtung; |
// DebugOut.Analog[10] = GasMischanteil; |
// DebugOut.Analog[3] = HoeheD * 32; |
// DebugOut.Analog[4] = hoehenregler; |
} |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Drehgeschwindigkeit und -winkel zu einem Istwert zusammenfassen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
if (Looping_Nick) MesswertNick = MesswertNick * GyroFaktor; |
else MesswertNick = IntegralNick * IntegralFaktor + MesswertNick * GyroFaktor; |
if (Looping_Roll) MesswertRoll = MesswertRoll * GyroFaktor; |
else MesswertRoll = IntegralRoll * IntegralFaktor + MesswertRoll * GyroFaktor; |
MesswertGier = MesswertGier * (2 * GyroFaktor) + Integral_Gier * IntegralFaktor / 2; |
|
DebugOut.Analog[21] = MesswertNick; |
DebugOut.Analog[22] = MesswertRoll; |
|
// Maximalwerte abfangen |
#define MAX_SENSOR (4096*STICK_GAIN) |
if (MesswertNick > MAX_SENSOR) MesswertNick = MAX_SENSOR; |
if (MesswertNick < -MAX_SENSOR) MesswertNick = -MAX_SENSOR; |
if (MesswertRoll > MAX_SENSOR) MesswertRoll = MAX_SENSOR; |
if (MesswertRoll < -MAX_SENSOR) MesswertRoll = -MAX_SENSOR; |
if (MesswertGier > MAX_SENSOR) MesswertGier = MAX_SENSOR; |
if (MesswertGier < -MAX_SENSOR) MesswertGier = -MAX_SENSOR; |
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gas-Mischanteil |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
// Zur besseren Auflösung hochskalieren |
GasMischanteil *= STICK_GAIN; |
|
// Fehlerwert der Höhenregelung einmischen |
GasMischanteil -= altcon_error(); |
|
// Mindestens auf Minimalgas stellen |
if( GasMischanteil < MIN_GAS ) |
GasMischanteil = MIN_GAS; |
|
// Begrenzung des Gasmischanteils auf MAX_GAS - 20 (Reserve für Motoren) |
if( GasMischanteil > ( MAX_GAS - 20 ) * STICK_GAIN ) |
GasMischanteil = ( MAX_GAS - 20 ) * STICK_GAIN; |
|
// Mindestens auf Minimalgas stellen |
if (GasMischanteil < MIN_GAS) |
GasMischanteil = MIN_GAS; |
|
// Begrenzung des Gasmischanteils auf MAX_GAS - 20 (Reserve für Motoren) |
if (GasMischanteil > (MAX_GAS - 20) * STICK_GAIN) |
GasMischanteil = (MAX_GAS - 20) * STICK_GAIN; |
|
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 |
|
// Reduzierten Gieranteil berechnen |
if (GasMischanteil < MIN_GIERGAS) { |
GierMischanteil = (GierMischanteil * GasMischanteil) / MIN_GIERGAS; |
} |
|
// Gieranteil darf nicht größer als der halbe Gasanteil sein |
if (GierMischanteil > (GasMischanteil >> 1)) |
GierMischanteil = GasMischanteil >> 1; |
if (GierMischanteil < -(GasMischanteil >> 1)) |
GierMischanteil = -(GasMischanteil >> 1); |
|
tmp_int = MAX_GAS * STICK_GAIN; |
|
// Gieranteil darf die Gasreserve nicht überschreiten |
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 += IntegralNick * IntegralFaktor - 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); |
pd_ergebnis = DiffNick + Ki * SummeNick; // PI-Regler für Nick |
// Motor Vorn |
tmp_int = (long) ((long) Parameter_DynamicStability * (long) (GasMischanteil + abs(GierMischanteil) / 2)) / 64; |
if (pd_ergebnis > tmp_int) pd_ergebnis = tmp_int; |
if (pd_ergebnis < -tmp_int) pd_ergebnis = -tmp_int; |
|
motorwert = GasMischanteil + pd_ergebnis + GierMischanteil; // Mischer |
motorwert /= STICK_GAIN; |
if ((motorwert < 0)) motorwert = 0; |
else if (motorwert > MAX_GAS) motorwert = MAX_GAS; |
if (motorwert < MIN_GAS) motorwert = MIN_GAS; |
Motor_Vorne = motorwert; |
// Motor Heck |
motorwert = GasMischanteil - pd_ergebnis + GierMischanteil; |
motorwert /= STICK_GAIN; |
if ((motorwert < 0)) motorwert = 0; |
else if (motorwert > MAX_GAS) motorwert = MAX_GAS; |
if (motorwert < MIN_GAS) motorwert = MIN_GAS; |
Motor_Hinten = motorwert; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Roll-Achse |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
DiffRoll = MesswertRoll - StickRoll; // Differenz bestimmen |
if (IntegralFaktor) SummeRoll += IntegralRoll * IntegralFaktor - 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); |
pd_ergebnis = DiffRoll + Ki * SummeRoll; // PI-Regler für Roll |
tmp_int = (long) ((long) Parameter_DynamicStability * (long) (GasMischanteil + abs(GierMischanteil) / 2)) / 64; |
if (pd_ergebnis > tmp_int) pd_ergebnis = tmp_int; |
if (pd_ergebnis < -tmp_int) pd_ergebnis = -tmp_int; |
// Motor Links |
motorwert = GasMischanteil + pd_ergebnis - GierMischanteil; |
motorwert /= STICK_GAIN; |
if ((motorwert < 0)) motorwert = 0; |
else if (motorwert > MAX_GAS) motorwert = MAX_GAS; |
if (motorwert < MIN_GAS) motorwert = MIN_GAS; |
Motor_Links = motorwert; |
// Motor Rechts |
motorwert = GasMischanteil - pd_ergebnis - GierMischanteil; |
motorwert /= STICK_GAIN; |
if ((motorwert < 0)) motorwert = 0; |
else if (motorwert > MAX_GAS) motorwert = MAX_GAS; |
if (motorwert < MIN_GAS) motorwert = MIN_GAS; |
Motor_Rechts = motorwert; |
// +++++++++++++++++++++++++++++++++++++++++++++++ |
} |
|