贡献我的四轴代码
#include <I2Cdev.h>#include <MPU6050.h>
#include <Wire.h>
//=============mpu6050 declarations===========
MPU6050 accelgyro;
static double Gx_offset = -1.46;//soldered as LENGBEI
static double Gy_offset = -0.07;
static double Ax_offset = -0.21;
static double Ay_offset = -1.7;
int16_t ax,ay,az;
int16_t gx,gy,gz;//raw data from sensors
double aax,aay,aaz,ggx,ggy,ggz;
double Ax,Ay,Az;//单位 g(9.8m/s^2)
double Gx,Gy,Gz;//单位 °/s
//=================mesure declarations=============
double estima_X = 0.2;
double estima_Y = 0.2;
double es_GX;
double es_GY;
double fusion_angle_Y;
double fusion_angle_X;
double now_error_X, last_error_X, error_diff_X, error_int_X;
double now_error_Y, last_error_Y, error_diff_Y, error_int_Y;
double Angel_accX,Angel_accY,Angel_accZ;
//===============control & accuracy declarations========
double basic_power = 5; // z acc balancing, need calibration each time
double rot_power_X, rot_power_Y;
double orientX=0;
double orientY=0;
long tic_1,tic_2,tic_3, duration;
int time_span_milli =20;
float time_span =0.02;
int moterPins;
int moterPowers;
void set_Motors(){
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(6,OUTPUT);
analogWrite(10, 0);
analogWrite(6, 0);
analogWrite(11,0);
analogWrite(9, 0);
delay(100);
}
void setup()
{
Wire.begin();
Serial.begin(9600);
set_Motors();
accelgyro.initialize();
delay(100);
autoCalibration();
delay(100);
}
void autoCalibration(){
Gx_offset=0.0;
Gy_offset=0.0;
double sum_1 =0;
double sum_2 =0;
double sum_3 =0;
double sum_4 =0;
for (int i=0; i<500; i++){
accelgyro.getMotion6(&ax,&ay,&az,&gx,&gy,&gz);
ggx=gx/131.00;
ggy=gy/131.00;
Ax=ax/16384.00;
Ay=ay/16384.00;
Az=az/16384.00;
Angel_accX =atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.14 ;
Angel_accY =-atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.14;
sum_1 = sum_1 + ggx;
sum_2 = sum_2 + ggy;
sum_3 = sum_3 + Angel_accX;
sum_4 = sum_4 + Angel_accY;
delay(1);
}
Gx_offset = sum_1/500;
Gy_offset = sum_2/500;
Ax_offset = sum_3/500;
Ay_offset = sum_4/500;
// Serial.print("Gx_offset= ");
// Serial.print(sum_1/1000);
// Serial.print("Gy_offset= ");
// Serial.println(sum_2/1000);
}
void loop()
{
tic_1=millis();
int emer_stat = 0;
//------------------------command tests-----------------------------------
while (Serial.available()>=1){
char datatype = Serial.read();
if (datatype == 'S'){
digitalWrite(13, HIGH);
delay(1);
digitalWrite(13, LOW);
delay(1);
}else if(datatype == 'M'){
orientX=0;
orientY=0;
}else if(datatype == 'z'){
orientX=0;
}else if(datatype == 'y'){
orientY=0;
}else if(datatype == 'L'){
basic_power = basic_power+10;
}else if(datatype == 'R'){
basic_power = basic_power-10;
}else if(datatype == 'P'){
basic_power = basic_power+1;
}else if(datatype == 'K'){
basic_power = basic_power-1;
}else if(datatype == 'Q'){
if (orientX <=18){
orientX=orientX+2;
}
}else if(datatype == 'W'){
if (orientX >= -18){
orientX=orientX-2;
digitalWrite(13, HIGH);
}
}else if(datatype == 'D'){
if (orientY <= 18){
orientY=orientY+2;
}
}else if(datatype == 'G'){
if (orientY >=-18){
orientY=orientY-2;
}
}else if (datatype == 'V'){
int value = Serial.parseInt();
if ((value<=255)&&(value>=0)){
basic_power = value;
}
}else if (datatype == 'X'){
}else if (datatype == 'Y'){
}else if (datatype == 'j'){
orientY = 10;
}else if (datatype == 'k'){
orientY = 5;
}else if (datatype == 'l'){
orientY = -5;
}else if (datatype == 'm'){
orientY = -10;
}else if (datatype == 'n'){
orientX = -5;
}else if (datatype == 'o'){
orientX = 5;
}else if (datatype == 'p'){
orientX = 10;
}else if (datatype == 'y'){
orientY = 0;
}else if (datatype == 'z'){
orientX = 0;
}
}
//--------------------------do NOT touch-----------------------------------------
// obtaining and filtering Acc angles
accelgyro.getMotion6(&ax,&ay,&az,&gx,&gy,&gz);
Ax=ax/16384.00;
Ay=ay/16384.00;
Az=az/16384.00;
Angel_accX =atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.14 -Ax_offset; //offset
Angel_accY =-atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.14 -Ay_offset; //offset
estima_X = estima_cal(estima_X, Angel_accX, 0.2);
estima_Y = estima_cal(estima_Y, Angel_accY, 0.2);
// Serial.print("estima_X=");
// Serial.print(estima_X);
// Serial.print("estima_Y=");
// Serial.println(estima_Y);
// obtaining Gyro angles without filter simply because I'm lasy
ggx=gx/131.00;
ggy=gy/131.00;
ggz=gz/131.00;
Gx=Gx+(ggx-Gx_offset)*time_span;
Gy=Gy+(ggy-Gy_offset)*time_span;
autoCorrection();
// Serial.print("Gx=");
// Serial.print(Gx);
// Serial.print(" Gy=");
// Serial.println(Gy);
//fusion angles by combining 40% last observe + 30% Acc + 30% Gyro
fusion_angle_X = update_Estimat(fusion_angle_X, estima_X, Gx );
fusion_angle_Y = update_Estimat(fusion_angle_Y, estima_Y, Gy );
// Serial.print("fusion_X=");
// Serial.print(fusion_angle_X);
// Serial.print("fusion_Y=");
// Serial.println(fusion_angle_Y);
// if (fusion_angle_Y>=80){
// digitalWrite(13, HIGH);
// delay(1);
// digitalWrite(13, LOW);
// delay(1);
// }
//---------------------------------PID's----------------------------------------
uodate_error(orientX, orientY ,fusion_angle_X, fusion_angle_Y);
double command_Y_raw = PID_control(now_error_Y, error_diff_Y, error_int_Y);
double command_X_raw = PID_control(now_error_X, error_diff_X, error_int_X);
int command_X = int (command_X_raw);
int command_Y = int (command_Y_raw);
moterPowers =basic_power + command_X;
moterPowers =basic_power - command_X;
moterPowers =basic_power + command_Y;
moterPowers =basic_power - command_Y;
emergency_STOP(emer_stat);
//---------------------------------fuzzy's----------------------------------------
// int command_X = fussy_command (fusion_angle_X);
// int command_Y = fussy_command (fusion_angle_Y);
//moterPowers =basic_power + command_X + int(orientX);
//moterPowers =basic_power - command_X - int(orientX);
//moterPowers =basic_power + command_Y + int(orientY);
//moterPowers =basic_power - command_Y - int(orientY);
//----------------------executing state for time_span_milli------------------------
for (int i=0; i<=3; i++){
if (moterPowers< 0){
moterPowers = 0;
}else if (moterPowers >255){
moterPowers = 255;
}
}
// Serial.print("po 10 = ");
// Serial.print(moterPowers);
// Serial.print(" po 6 = ");
// Serial.print(moterPowers);
// Serial.print(" po 11 = ");
// Serial.print(moterPowers);
// Serial.print(" po 9 = ");
// Serial.println(moterPowers);
analogWrite(10, moterPowers);
analogWrite(6, moterPowers);
analogWrite(11, moterPowers);
analogWrite(9, moterPowers);
tic_2=millis();
duration = tic_2 - tic_1;
if(duration > time_span_milli){
duration=0;
}
//Serial.println(time_span_milli - duration);
delay (time_span_milli - duration);
}
//--------------------------accesory functions----------------------------------------
double estima_cal (double estima, double metron, double KG){
double result1 = estima + KG*(metron - estima);
return result1;
}
double PID_control(double error, double error_diff, double error_int ){
double P=0.7;
double D=0.2;
double I=0;
double command = P*error + I*error_int + D*error_diff;
return command;
}
void uodate_error(double consigne_X, double consigne_Y, double mesure_X, double mesure_Y){
now_error_X = consigne_X - mesure_X;
now_error_Y = consigne_Y - mesure_Y;
error_diff_X = (now_error_X - last_error_X)/time_span;
error_diff_Y = (now_error_Y - last_error_Y)/time_span;
error_int_X = error_int_X + now_error_X*time_span;
error_int_Y = error_int_Y + now_error_Y*time_span;
last_error_X =now_error_X;
last_error_Y =now_error_Y;
}
double update_Estimat(double estimate, double metron_1, double metron_2){
double temp = 0.4* estimate + 0.3*metron_1 + 0.3*metron_2;
return temp;
}
void emergency_STOP(int choice){
if (choice == 0){
//do nothing
}else if(choice == 1){
//brutal descending
basic_power =5;
// moterPowers =5;
// moterPowers =5;
// moterPowers =5;
}else if(choice == 2){
//douce descending
moterPowers = moterPowers-10;
moterPowers = moterPowers-10;
moterPowers = moterPowers-10;
moterPowers = moterPowers-10;
}
}
double PorportionDet(double limA, double limB, double outA, double outB, double x){
double a = (x - limB) / (limA-limB);
double result = a*outA + (1-a)*outB;
return result;
}
int fussy_command(double input){
double PWM_command;
if (input>=45 ){
PWM_command = 30;
}else if(input<45 & input>=25 ){
PWM_command = PorportionDet(45, 25, 30, 10, input );
}else if(input<25 & input>=5){
PWM_command = PorportionDet(25, 5, 10, 3, input );
}else if(input<5 & input>=-5){
PWM_command = PorportionDet(5, -5, 3, -3, input );
}else if(input<-5 &input>=-25){
PWM_command = PorportionDet(-5, -25, -3, -10, input );
}else if(input<-25 & input>=-45){
PWM_command = PorportionDet(-25, -45, -10, -30, input );
}else if(input<-45){
PWM_command =-30;
}
int regu_pwm =int(PWM_command);
return regu_pwm;
}
void autoCorrection (){
if ( Angel_accX > -1.3 & Angel_accX < 1.3 ){
Gx=Angel_accX /2;
}
if ( Angel_accY > -1.3 & Angel_accY < 1.3 ){
Gy=Angel_accY /2;
}
}
除了PID不太稳定,其他还好 /Users/samuel/Desktop/1.jpeg /Users/samuel/Desktop/2.jpg 期待。谢谢分享。设备马上到齐了,调试下看看 谢谢楼主无私的共享,飞得平稳度怎样??? 不好,容易晃,还需要细调PID参数 {:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}
我怎么看不见下面那两张图 这个要必须顶,有没有视频呢 感谢楼主!!能否附上说明呢,新手不会接线。。 能飞不?,如果行,详细教程可以有 感謝樓主無私分享.
可否提供一點硬件的資料, 以及接線方法, 好讓大家學習學習.
感谢楼主分享的代码啊,我用LED灯测试成功了。不过连接电调似乎还要加上空占比发生程序,还有这个代码里面还没有滤波吧,出来的曲线跳动较大。 感谢分享,关注中 赞一个,第一个帖子给你了
页:
[1]