Quad X Type Multicopter
main.cpp
- Committer:
- komaida424
- Date:
- 2021-02-21
- Revision:
- 8:1db19b529b22
- Parent:
- 7:16bf0085d914
File content as of revision 8:1db19b529b22:
/* PWM Output
type | M1 | M2 | M3 | M4 | M5 | M6
------------+-----------+-----------+-----------+-----------+---------------------
Quad-X |FL Thr ESC |FR Thr ESC |BL Thr ESC |BR Thr ESC | - | -
Quad-H |FL VP Ser |FR VP Ser |BL VP Ser |BR VP Ser |Thr ESC | -
Quad-3D |FL Thr ESC |FR Thr ESC |BL Thr ESC |BR Thr ESC | - | -
Delta |FL Tro ESC |L Alv Ser |R Alv Ser |Rud Ser | - | -
Delta-TW |FL Tro ESC |L Alv Ser |R Alv Ser |Rud Ser |FR Thr ESC | -
Airplane |Thr ESC |Ail Ser |Ele Ser |Rud Ser |Ail Ser | -
F:Front, B:Back, L:Left, R:Right
Ele:Elevator, Rud:Rudder, Ail:Aileron, Thr:Throttle, Alv:Alevon
ESC:for ESC, Ser:for Servo, VP:Variable Pitch
*/
#include "mbed.h"
#include "math.h"
#include "I2cPeripherals.h"
#include "InterruptIn.h"
#include "config.h"
#include "PulseWidthCounter.h"
#include "string"
#include "SerialLcd.h"
//#if defined(TARGET_NUCLEO_FXXXXX)
// #include "eeprom_flash.h"
//#endif
//#include "PID.h"
//#include "SoftPWM.h"
#include "Limiter.h"
#include "IAP.h"
#define DEBUG
//Serial pc(USBTX, USBRX);
//Serial pc(PA_9,PA_10);
#if defined(TARGET_LPC1768)
DigitalInOut pwmpin[] = { p21,p22,p23,p24 };
// #ifdef LPCXpresso
#define LED1 P0_22
// #endif
DigitalOut led1(LED1);
// DigitalOut led2(LED2);
InterruptIn ch1(p5);
PulseWidthCounter ch[6] = { PulseWidthCounter(p6),
PulseWidthCounter(p7),
PulseWidthCounter(p8),
PulseWidthCounter(p9),
PulseWidthCounter(p10),
PulseWidthCounter(p11) };
PwmOut pwm[6] = { p21,p22,p23,p24,p25,p26 };
// SoftPWM buzz(p20);
I2cPeripherals i2c(p28,p27); //sda scl
SerialLcd lcd(p13,p14);
#define PwmNum 6
#define MEM_SIZE 256
#define TARGET_SECTOR 29 // use sector 29 as target sector if it is on LPC1768
IAP iap;
#elif defined(TARGET_STM32F1)
//#define NAZE32BORD
#ifdef NAZE32BORD
DigitalOut led1(PC_13);
InterruptIn ch1(PA_0);
PulseWidthCounter ch[6] = { PA_8,PA_11,PB_6,PB_7,PB_8,PB_9};
PwmOut pwm[6] = { PA_0,PA_1,PA_2,PA_3,PA_6,PA_7 };
// SoftPWM buzz(PA_2);
// I2cPeripherals i2c(I2C_SDA,I2C_SCL); //sda scl
I2cPeripherals i2c(PB_9,PB_8); //sda scl
SerialLcd lcd(PA_2);
#define PwmNum 6
#define MEM_SIZE 256
#define STM32_EEPROM //24AAXX/24LCXX/24FCXX EEPROM
#else
DigitalOut led1(PC_13);
InterruptIn ch1(PA_0);
PulseWidthCounter ch[6] = { PA_11,PA_12,PA_15,PB_3,PB_4,PB_5};
PwmOut pwm[6] = { PA_6,PA_7,PB_0,PB_1,PB_10,PB_11 };
// SoftPWM buzz(PA_2);
// I2cPeripherals i2c(I2C_SDA,I2C_SCL); //sda scl
I2cPeripherals i2c(PB_9,PB_8); //sda scl
SerialLcd lcd(PA_2);
#define PwmNum 6
#define MEM_SIZE 256
#define STM32_EEPROM //24AAXX/24LCXX/24FCXX EEPROM
#endif
#elif defined(TARGET_STM32F3)
DigitalOut led1(PB_3);
InterruptIn ch1(PA_0);
PulseWidthCounter ch[6] = { PA_0,PA_1,PB_11,PB_10,PB_4,PB_5};
PwmOut pwm[6] = { PA_6,PA_7,PA_11,PA_12,PB_8,PB_9 };
// SoftPWM buzz(PA_2);
// I2cPeripherals i2c(I2C_SDA,I2C_SCL); //sda scl
I2cPeripherals i2c(PB_7,PB_6); //sda scl
SerialLcd lcd(PA_9);
#define PwmNum 6
#define MEM_SIZE 256
#define STM32_EEPROM //24AAXX/24LCXX/24FCXX EEPROM
#elif defined(TARGET_NUCLEO_F4)
DigitalOut led1(PA_5);
InterruptIn ch1(PC_2);
// PulseWidthCounter ch[6] = { PA_0,PA_1,PA_4,PB_0,PC_1,PC_0 };
PulseWidthCounter ch[6] = { A0,A1,A2,A3,A4,A5 };
PwmOut pwm[6] = { D3,D5,D6,D9,D11,D12 };
// SoftPWM buzz(PB_13);
// I2cPeripherals i2c(I2C_SDA,I2C_SCL); //sda scl
I2cPeripherals i2c(PB_9,PB_8); //sda scl
SerialLcd lcd(PA_11);
#define PwmNum 6
#define MEM_SIZE 256
#define STM32_EEPROM //24AAXX/24LCXX/24FCXX EEPROM
#elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501)
DigitalInOut pwmpin[] = { P0_14,P0_2,P0_23,P0_17 };
DigitalOut led1(P0_21);
// DigitalOut led2(P0_21);
InterruptIn ch1(P0_9);
PulseWidthCounter ch[5] = { P0_8,P0_10,P0_7,P0_22,P1_15 };
PwmOut pwm[4] = { P0_14,P0_2,P0_23,P0_17 };
// SoftPWM buzz(P1_19);
I2cPeripherals i2c(P0_5,P0_4); //sda scl
SerialLcd lcd(P0_19,P0_18);
#define PwmNum 4
#define MEM_SIZE 256
#define TARGET_EEPROM_ADDRESS 64
#define INTERNAL_EEPROM
IAP iap;
#elif defined(TARGET_LPC1114) // LPC1114
// DigitalInOut pwmpin[] = { dp1,dp2,dp18,dp24 };
DigitalOut led1(dp28);
InterruptIn ch1(dp4);
// PulseWidthCounter ch[5] = { dp9,dp10,dp11,dp13,dp26 };
PwmOut pwm[4] = { dp1,dp2,dp18,dp24 };
// SoftPWM buzz(dp25);
I2cPeripherals i2c(dp5,dp27); //sda scl
SerialLcd lcd(dp16,dp15);
#define PwmNum 4
#define MEM_SIZE 256
#define EXTERNAL_EEPROM
#elif defined(TARGET_TEENSY3_1) // Teensy3.1
DigitalOut led1(D13);
InterruptIn ch1(D2);
PwmOut pwm[6] = { D3,D4,D5,D6,d20,D21 };
I2cPeripherals i2c(D18,D19); //sda scl
SerialLcd lcd(D3,D4); //TX,RX
#define PwmNum 6
#define MEM_SIZE 256
#define EXTERNAL_EEPROM
#endif
Timer CurTime;
//Timer ElapTime;
Timer CycleTime;
//Timer FlyghtTime;
config conf;
//PID pid[4];
//Limiter throLimit = 100;
Limiter gyroLimit[3] = {0.9,0.9,0.9};
Limiter accLimit[3] = {0.95,0.95,0.95};
//Limiter pwmLimit[4] = {50,50,50,50};
//PID height;
float TotalTime = 0;;
int channel = 0;
int Signal[9] = { _THR,_AIL,_ELE,_RUD,_GYRO,_AUX1,_AUX2,_AUX3,_AUX4 };
volatile int CH[9];
volatile int M[6];
volatile float Gyro[3];
volatile float Accel[3]= {0,0,0};
volatile float Accel_Angle[3];
volatile float Accel_Save[3]= {0,0,0};
volatile float Angle[3];
volatile float Gyro_Ref[3];
volatile float Gyro_Save[3];
volatile int Stick[6];
volatile int Stick_Save[6];
int PWM_Init[6][6] = { 1080,1080,1080,1080,1080,1080, //Quad_X
1500,1500,1500,1500,1080,1080, //Quad_VP
1500,1500,1500,1500,1080,1080, //Quad_3D
1080,1500,1500,1500,1500,1080, //Delta
1080,1500,1500,1500,1080,1500, //Delta_TW
1080,1500,1500,1500,1500,1080 //AirPlane
};
char Servo_idx[6][6] = { 0,0,0,0,0,0, //Quad_X
1,1,1,1,0,0, //Quad_VP
0,0,0,0,0,0, //Quad_3D
0,1,1,1,1,1, //Delta
0,1,1,1,0,1, //Delta_TW
0,1,1,1,1,1 //AirPlane
};
//int Stick_Max[3];
float Press;
float Base_Press;
char InPulseMode; //Receiver Signal Type 's':Serial, 'P':Parallel
//volatile bool tick_flag;
//volatile bool buzz_flag;
volatile float interval;
float pid_interval;
//int pid_reg[4];
int loop_cnt;
float target_height;
float cuurent_height;
float base_Throttl;
int Throttl;
bool hov_control;
float Rdata;
void initialize();
void FlashLED(int ,float tm=0.1);
void SetUp();
void SetUpPrompt(config&,I2cPeripherals&);
void PWM_Out(bool);
void Get_Stick_Pos();
void CalibrateGyros(void);
void CalibrateAccel(void);
void Get_Gyro(float);
bool Get_Accel(float);
void Get_Angle(float);
void ReadConfig();
void WriteConfig();
void Interrupt_Check(bool&,int &,DigitalOut &);
void ESC_SetUp(void);
void Flight_SetUp();
//void IMUfilter_Reset(void);
void LCD_printf(char *);
void LCD_cls();
void LCD_locate(int,int);
void wait(float);
void PulseCheck() //cppm信号のチェック
{
channel++;
}
void PulseAnalysis() //cppm信号の解析
{
CurTime.stop();
int PulseWidth = CurTime.read_us();
CurTime.reset();
CurTime.start();
if ( PulseWidth > 3000 ) channel = 0; //reset pulse count
else {
if ( PulseWidth > Pulse_Min && PulseWidth < Pulse_Max && channel < 10 ) {
CH[Signal[channel-1]] = PulseWidth;
}
}
channel++;
}
int main()
{
int i=0;
wait(1.5);
initialize();
Get_Stick_Pos();
#ifdef DEBUG
char str[18];
while ( THR > 1800 ) {
LCD_locate(0,0);
sprintf(str,"TR=%4d,AL=%4d",THR,AIL);
LCD_printf(str);
LCD_locate(0,1);
sprintf(str,"EL=%4d,RD=%4d",ELE,RUD);
LCD_printf(str);
Get_Stick_Pos();
}
#endif
while ( Stick[COL] > Thro_Zero || conf.StartMode == 'C'
|| ( conf.Model_Type == Quad_3D && Stick[GAIN] < 0 ) ) //Shrottol Low
{
// if ( Stick[COL] > 890 && -Stick[YAW] < Stick_Limit ) // Shrottle High
// ESC_SetUp();
if ( Stick[COL] > 890 || conf.StartMode == 'C' ) // Shrottle High
{
loop_cnt = 0;
SetUpPrompt(conf,i2c);
break;
}
FlashLED(2);
wait(0.5);
Get_Stick_Pos();
}
Flight_SetUp();
while (1)
{
if ( Stick[COL] < Thro_Zero )
{
i = 0;
while ( Stick[YAW] < -Stick_Limit && Stick[COL] < Thro_Zero ) //Rudder Left
{
if ( i > 100 ) //wait 2 sec
{
// FlyghtTime.stop();
if ( Stick[PIT] < -Stick_Limit ) { //Elevetor Down
loop_cnt = 0;
FlashLED(5);
for ( int x=0; x<PwmNum; x++ ) {
pwm[x].pulsewidth_us(PWM_Init[conf.Model_Type][x]);
}
i2c.start(conf.LCD_Contrast);
SetUpPrompt(conf,i2c);
}
CalibrateGyros();
Flight_SetUp();
break;
}
wait(0.01); // wait 10 msec
Get_Stick_Pos();
i++;
}
}
PWM_Out(true);
}
}
void initialize()
{
i2c.start(conf.LCD_Contrast);
for ( int i=0;i<PwmNum;i++ ) pwm[i].pulsewidth_us(0);
ReadConfig(); //config.inf file read
channel = 0;
//#if defined(TARGET_LPC1114) // LPC1114
ch1.rise(&PulseCheck); //input pulse count
wait(0.2);
if ( channel > 50 ) {
FlashLED(50,0.02);
ch1.rise(&PulseAnalysis);
InPulseMode = 'S'; }
else InPulseMode = 'P';
//#endif
led1 = 0;
CycleTime.start();
// throLimit.differential(conf.Thro_Limit_Val);
// throLimit.rate(conf.Thro_Limit_Rate);
// Base_Press = (float)i2c.pressure() / 4096;
FlashLED(10,0.05);
}
void FlashLED(int cnt,float tm)
{
for ( int i = 0 ; i < cnt ; i++ ) {
led1 = !led1;
// buzz = 0.5f;
wait(tm);
led1 = !led1;
// buzz = 0.0f;
wait(tm);
}
}
void ReadConfig()
{
#ifdef LocalFileOut
LocalFileSystem local("local"); // Create the local filesystem under the name "local"
FILE *fp = fopen("/local/setup.inf", "rb"); // Open "out.txt" on the local file system for writing
if ( fp != NULL ) {
float rev = conf.Revision;
int len = fread(&conf,1,sizeof(config),fp);
switch ( len ) {
case sizeof(config): // File size ok
if ( rev == conf.Revision ) break;
default:
fclose(fp);
config init;
conf = init;
fp = fopen("/local/setup.inf", "wb");
fwrite(&conf,1,sizeof(config),fp);
}
fclose(fp);
} else {
WriteConfig();
wait(2);
}
#else
char *send;
char *recv;
int i;
char buf[MEM_SIZE];
config *conf_ptr;
if ( sizeof(config) > MEM_SIZE ) {
// pc.printf("config size over");
wait(3);
return;
}
//#if defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501)
#if defined(INTERNAL_EEPROM) || defined(EXTERNAL_EEPROM) || defined(STM32_EEPROM)
#if defined(INTERNAL_EEPROM)
iap.read_eeprom( (char*)TARGET_EEPROM_ADDRESS, buf, MEM_SIZE );
#elif defined(EXTERNAL_EEPROM)
//External Flash Memory Wreite
short pos = 0;
if ( i2c.read_EEPROM(pos,buf,MEM_SIZE) != 0 ) {
while(1) {
FlashLED(3);
wait(0.5);
}
}
#else //STM32 emulate eeprom
// EEPROM_Read(0,buf,MEM_SIZE)
readEEPROM(0,(uint32_t*)buf,sizeof(config));
#endif
send = buf;
conf_ptr = (config*)buf;
//pc.printf("rev=%f",conf_ptr->Revision);
recv = (char*)&conf;
// conf_ptr = (config*)buf;
if ( conf_ptr->Revision == conf.Revision && conf_ptr->Struct_Size == sizeof(config) ) {
for ( i=0;i<sizeof(config);i++ ) recv[i] = send[i];
return;
}
#else
int rc = iap.blank_check( TARGET_SECTOR, TARGET_SECTOR );
if ( rc == SECTOR_NOT_BLANK ) {
send = sector_start_adress[TARGET_SECTOR];
recv = (char*)&conf;
conf_ptr = (config*)sector_start_adress[TARGET_SECTOR];
if ( conf_ptr->Revision == conf.Revision && conf_ptr->Struct_Size == sizeof(config) ) {
for ( i=0;i<sizeof(config);i++ ) recv[i] = send[i];
return;
}
}
#endif
WriteConfig();
#endif
}
void WriteConfig()
{
#ifdef LocalFileOut
LocalFileSystem local("local"); // Create the local filesystem under the name "local"
FILE *fp = fopen("/local/setup.inf", "wb");
fwrite(&conf,1,sizeof(config),fp);
fclose(fp);
#else
char mem[MEM_SIZE]= " ";;
char *send;
int i;
if ( sizeof(config) > MEM_SIZE ) {
// pc.printf("config size over");
wait(3);
return;
}
send = (char*)&conf;
for ( i=0;i<sizeof(config);i++ ) mem[i] = send[i];
for ( i=sizeof(config);i<MEM_SIZE;i++ ) mem[i] = 0x00;
//#if defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501)
#if defined(INTERNAL_EEPROM)
iap.write_eeprom( mem, (char*)TARGET_EEPROM_ADDRESS, MEM_SIZE );
#elif defined(EXTERNAL_EEPROM)
//External Flash Memory Wreite
short pos = 0;
i2c.write_EEPROM( pos,mem,MEM_SIZE) ;
#elif defined(STM32_EEPROM)
// EEPROM_Write(0,buf,MEM_SIZE);
enableEEPROMWriting();
writeEEPROM(0, (uint32_t *)mem,sizeof(config));
disableEEPROMWriting();
// pc.printf("rev=%f,rev=%d",((config*)mem)->Revision,readEEPROMWord(0));
#else
iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
iap.erase( TARGET_SECTOR, TARGET_SECTOR );
iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
#endif
for ( i=0; i<4; i++ ) {
FlashLED(10,0.03);
wait(0.5);
}
#endif
}
void Get_Stick_Pos(void)
{
#ifndef TARGET_LPC1114 // LPC1114
if ( InPulseMode == 'P' ) {
for (int i=0;i<5;i++) CH[i] = ch[i].count;
}
#endif
// Stick_Save[ROL] = Stick[ROL];
// Stick_Save[PIT] = Stick[PIT];
// Stick_Save[YAW] = Stick[YAW];
// Stick_Save[COL] = Stick[COL];
Stick[ROL] = AIL - conf.Stick_Ref[ROL];
Stick[PIT] = ELE - conf.Stick_Ref[PIT];
Stick[YAW] = RUD - conf.Stick_Ref[YAW];
Stick[COL] = THR - conf.Stick_Ref[COL];
Stick[GAIN] = ( AUX - conf.Stick_Ref[GAIN] ) / 4;
Stick[AUX2] = AX2 - conf.Stick_Ref[COL];
}
void Get_Gyro(float interval)
{
float x,y,z;
bool err;
Gyro_Save[ROL] = Gyro[ROL];
Gyro_Save[PIT] = Gyro[PIT];
Gyro_Save[YAW] = Gyro[YAW];
if ( conf.Gyro_Dir[3] ==1 ) err=i2c.angular(&x,&y,&z);
else err=i2c.angular(&y,&x,&z);
if ( err == false ) return;
Gyro[ROL] = gyroLimit[0].calc(x) - Gyro_Ref[0] ;
Gyro[PIT] = gyroLimit[1].calc(y) - Gyro_Ref[1] ;
Gyro[YAW] = gyroLimit[2].calc(z) - Gyro_Ref[2] ;
//pc.printf("%6.1f,%6.1f\r\n",x,Gyro[ROL]);
}
bool Get_Accel(float interval)
{
float x,y,z;
bool err;
// Accel_Save[ROL] = Accel_Angle[ROL];
// Accel_Save[PIT] = Accel_Angle[PIT];
// Accel_Save[YAW] = Accel_Angle[YAW];
if ( conf.Gyro_Dir[3] ==1 ) err=i2c.Acceleration(&x,&y,&z);
else err=i2c.Acceleration(&y,&x,&z);
if ( err == false ) return false;
//pc.printf("%6.4f,%6.4f,%6.4f\r\n",x,y,z);
x = accLimit[0].calc(x) - conf.Accel_Ref[0];
y = accLimit[1].calc(y) - conf.Accel_Ref[1];
z = accLimit[2].calc(z) - conf.Accel_Ref[2];
//pc.printf("%6.4f,%6.4f,%6.4f\r\n",Accel[ROL],Accel[PIT],Accel[YAW]);
Accel[ROL] = atan(x/sqrtf( powf(y,2)+powf(z,2)))*180/3.14f;
Accel[PIT] = atan(y/sqrtf( powf(x,2)+powf(z,2)))*180/3.14f;
Accel[YAW] = atan(sqrtf( powf(x,2)+powf(y,2))/z)*180/3.14f;
return true;
}
void Get_Angle(float interval)
{
float x,y,z;
// Get_Accel(interval);
Get_Gyro(interval);
x = ( Gyro[ROL] + Gyro_Save[ROL] ) * 0.5f;
y = ( Gyro[PIT] + Gyro_Save[PIT] ) * 0.5f;
z = ( Gyro[YAW] + Gyro_Save[YAW] ) * 0.5f;
if ( Get_Accel(interval) == true ) {
float i = 3.14 * 2 * conf.Cutoff_Freq * interval;
Angle[ROL] += -Angle[ROL] * i + Accel[ROL] * i + x * interval;
Angle[PIT] += -Angle[PIT] * i + Accel[PIT] * i + y * interval;
}
else {
Angle[ROL] += x * interval;
Angle[PIT] += y * interval;
}
Angle[YAW] += z * interval;
//pc.printf("%6.1f,%6.1f,%6.3f\r\n",Angle[ROL],Gyro[ROL],Accel[ROL]);
}
void Get_Pressure()
{
float P = (float)i2c.pressure()/4096;
// Press = 153.8 * ( T + 273.2 ) * ( 1.0 - ( P / Base_Press ) ^ 0.1902f );
Press = 8.43f * ( P - Base_Press );
}
void CalibrateGyros(void)
{
int i;
float x,y,z;
float k[3]={0,0,0};
wait(1);
Angle[0]=Angle[1]=Angle[2]=0;
for(i=0; i<16; i++) {
if ( conf.Gyro_Dir[3] ==1 ) i2c.angular(&x,&y,&z);
else i2c.angular(&y,&x,&z);
k[0] += x;
k[1] += y;
k[2] += z;
wait(0.01);
}
for( i=0; i<3; i++ ) Gyro_Ref[i] = k[i]/16;
// FlashLED(3);
}
void CalibrateAccel(void)
{
int i;
float x,y,z;
float k[3]={0,0,0};
conf.Accel_Ref[0]=conf.Accel_Ref[1]=conf.Accel_Ref[2]=0;
for(i=0; i<16; i++) {
if ( conf.Gyro_Dir[3] ==1 ) i2c.Acceleration(&x,&y,&z);
else i2c.Acceleration(&y,&x,&z);
k[0] += x;
k[1] += y;
k[2] += z;
wait(0.01);
}
conf.Accel_Ref[0] = k[0]/16;
conf.Accel_Ref[1] = k[1]/16;
conf.Accel_Ref[2] = k[2]/16-1;
// conf.Accel_Ref[2] = k[2]/16;
// FlashLED(3);
}
void PWM_Out(bool mode)
{
int reg[3];
int i,j,k;
float gain;
// float cur_height;
interval = CycleTime.read();
CycleTime.reset();
if ( interval > 0.005f && mode ) return;
TotalTime += interval;
if ( TotalTime > 0.5f ) {
led1 = !led1;
// if ( ( !buzz ) && ( (float)conf.Flight_Time < FlyghtTime.read() ) ) buzz=0.5;
// else buzz=0.0;
TotalTime = 0;
}
Get_Angle(interval);
pid_interval += interval;
if ( (pid_interval < (float)conf.PWM_Interval/1000000) && (Stick[GAIN] < 0) ) return;
pid_interval = 0;
Get_Stick_Pos();
switch ( conf.Model_Type ) {
case Quad_X:
M1 = M2 = M3 = M4 = THR + conf.Throttl_Trim;
break;
case Quad_VP:
M1 = M2 = M3 = M4 = Stick[AUX2] + conf.Stick_Ref[COL];
M5 = THR + conf.Throttl_Trim;
break;
case Quad_3D:
j = THR + conf.Throttl_Trim;
if ( Stick[GAIN] < 0 ) {
k = THR - conf.Reverse_Point;
if ( abs(k) < THR_MIDRANGE ) {
if ( k > 0 ) j = conf.Reverse_Point + THR_MIDRANGE;
else j = conf.Reverse_Point - THR_MIDRANGE;
}
}
// i = (int)throLimit.calc((float)THR);
// if ( abs(i-conf.Reverse_Point) > 100 ) i = THR;
M1 = M2 = M3 = M4 = j;
break;
case Delta:
case Delta_TW:
case AirPlane:
M1 = THR + conf.Throttl_Trim;
M2 = conf.Stick_Ref[ROL];
M3 = conf.Stick_Ref[PIT];
M4 = conf.Stick_Ref[YAW];
if ( conf.Model_Type == AirPlane )
M5 = conf.Stick_Ref[ROL];
else M5 = M1;
break;
}
for ( i=0;i<3;i++ ) {
// Stick Angle Mixing
if ( conf.Gyro_Gain_Setting == 1 ) gain = conf.Gyro_Gain[i] * conf.Gyro_Dir[i];
else gain = ( (float)fabsf(Stick[GAIN])/100 + conf.Gyro_Gain[i+3] ) * conf.Gyro_Dir[i];
if ( Stick[i] > 0 ) gain -= gain * ( fabsf(Stick[i]) / 400 ) * conf.Active_Gyro_Gain;
if ( Stick[GAIN] > 0
|| i == YAW
|| conf.Model_Type > 0
|| i2c.GetAddr(ACCEL_ADDR) == 0
) {
reg[i] = Stick[i] * conf.Stick_Mix[i];
reg[i] += Gyro[i] * gain * GYRO_ADJUST;
}
else {
reg[i] = ( Angle[i]*conf.Gyro_Dir[i]*400/50 + (float)Stick[i] ) * conf.Stick_Mix[i];
reg[i] += Gyro[i] * gain * GYRO_ADJUST;
}
// pid_reg[i] = reg[i];
}
pid_interval = 0;
// int Reverse = 1;
switch ( conf.Model_Type ) {
case Quad_3D:
// if ( THR < conf.Reverse_Point ) {
// Reverse = -1;
// }
case Quad_X:
case Quad_VP:
//Calculate Roll Pulse Width
M1 += reg[ROL];
M2 -= reg[ROL];
M3 -= reg[ROL];
M4 += reg[ROL];
//Calculate Pitch Pulse Width
M1 += reg[PIT];
M2 += reg[PIT];
M3 -= reg[PIT];
M4 -= reg[PIT];
//Calculate Yaw Pulse Width
M1 -= reg[YAW];
M2 += reg[YAW];
M3 -= reg[YAW];
M4 += reg[YAW];
break;
case Delta:
case Delta_TW:
//Calculate Roll Pulse Width
M2 += reg[ROL];
M3 -= reg[ROL];
//Calculate Pitch Pulse Width
M2 += reg[PIT];
M3 += reg[PIT];
//Calculate Yaw Pulse Width
M4 -= reg[YAW];
//Calculate Yaw Pulse Width
if ( conf.Model_Type == Delta_TW ) {
M1 += reg[YAW];
M5 -= reg[YAW];
}
break;
case AirPlane:
//Calculate Roll Pulse Width
M2 -= reg[ROL];
M5 -= reg[ROL];
//Calculate Pitch Pulse Width
M3 += reg[PIT];
//Calculate Yaw Pulse Width
M4 -= reg[YAW];
break;
}
j = conf.Model_Type;
for ( i=0; i<PwmNum; i++ ) {
if ( M[i] > Pulse_Max ) M[i] = Pulse_Max;
if ( M[i] < Pulse_Min ) M[i] = Pulse_Min;
if ( Servo_idx[j][i] == 1 )
{
M[i] = conf.Stick_Ref[i] + ( ( M[i] - conf.Stick_Ref[i] ) * conf.Servo_Dir[i] );
}
else {
if ( j == Quad_3D ) {
if ( Stick[GAIN] > 0 ) {
if ( THR < conf.Reverse_Point )
M[i] = conf.Reverse_Point;
}
}
else {
if ( Stick[COL] < Thro_Zero ) M[i] = conf.Stick_Ref[COL];
}
}
}
if ( mode ) {
// h = conf.Stick_Ref[THR];
for ( i=0;i<PwmNum;i++ ) {
// while ( !pwmpin[i] );
if ( conf.PWM_Mode == 1 )
pwm[i].pulsewidth_us(M[i]);
else pwm[i].pulsewidth_us(M[i]-conf.Stick_Ref[COL]);
}
}
}
void ESC_SetUp(void) {
while(1) {
Get_Stick_Pos();
for ( int i=0;i<PwmNum;i++ ) pwm[i].pulsewidth_us(conf.Stick_Ref[COL]+Stick[COL]);
wait(0.015);
}
}
void Flight_SetUp(void)
{
int i;
for ( i=0;i<PwmNum;i++ ) pwm[i].pulsewidth_us(0);
for ( i=0;i<PwmNum;i++ ) pwm[i].period_us(conf.PWM_Interval);
for ( i=0; i<PwmNum; i++ ) {
pwm[i].pulsewidth_us(PWM_Init[conf.Model_Type][i]);
}
hov_control = false;
// throLimit.differential(conf.Thro_Limit_Val);
// throLimit.rate(conf.Thro_Limit_Rate);
Angle[ROL]=Angle[PIT]=Angle[YAW]=0;
loop_cnt = 0;
// FlyghtTime.start();
CycleTime.start();
pid_interval = 0;
Stick_Save[COL] = Stick[COL];
FlashLED(5);
}
void LCD_locate(int clm,int row)
{
lcd.locate(clm,row);
i2c.locate(clm,row);
}
void LCD_cls()
{
lcd.cls();
i2c.cls();
}
void LCD_printf(char* str)
{
lcd.write(str);
i2c.write_lcd(str);
}
void wait(float tm)
{
wait_us(tm*1000000);
}
;