Source Code of DIY Drone - ESP32 [Arduino] Source code
Drone side source code
//参考https://rikoubou.hatenablog.com/entry/2017/10/06/181805 #include<math.h> #define Deg2rad 3.1415 /180 #include <MadgwickAHRS.h> Madgwick MadgwickFilter; float quat[4] = {1.0, 0.0, 0.0 ,0.0}; float rate[3]; ///タイマー割込み 参考https://55life555.blog.fc2.com/blog-entry-3194.html volatile int timeCounter1; hw_timer_t *timer1 = NULL; portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; void IRAM_ATTR onTimer1(){ portENTER_CRITICAL_ISR(&timerMux); timeCounter1++; portEXIT_CRITICAL_ISR(&timerMux); } ////////MPU9250関連//////// //サンプリング周期 const int dt = 3; ///ms //平均値処理のためのサンプリング回数 const int FIFO_order = 5; //PIDにおける微分項に用いる時間の割り算に関する演算子 const int Deno = 1 /dt * FIFO_order; #include <Wire.h> const int MPU_addr=0x68; // I2C address of the MPU-6050 int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ,MgX,MgY,MgZ; ////構造体定義//// //参考https://www.cc.kyoto-su.ac.jp/~yamada/programming/struct.html#declaration typedef struct { float Axis_X; float Axis_Y; float Axis_Z; } structure; //センサー値格納// structure Ac_Sens[FIFO_order];//加速度 structure Gy_Sens[FIFO_order];//角速度 structure Ahrs_Sens[FIFO_order];//姿勢角 //各軸の目標値 //姿勢角(deg) structure Ahrs_Tgt_Front = {-2,0,100};//前方 structure Ahrs_Tgt_Back = {2,0,100};//後方 structure Ahrs_Tgt_Right = {0,2,100};//右 structure Ahrs_Tgt_Left = {0,-2,100};//左 structure Ahrs_Tgt_Keep = {0,0,100};//維持 structure Ahrs_Tgt;//↑受け渡し用 //角速度(deg/s) structure Gy_Tgt; //加速度(m/s^2) structure Ac_Tgt_Up = {0,0,3};//上昇 structure Ac_Tgt_Down = {0,0,-5};//下降 structure Ac_Tgt_Keep = {0,0,0};//維持 structure Ac_Tgt;//↑受け渡し用 //初期速度 m/s structure Vl_Pre = {0,0,0};//ドローンの初速度 structure Vl;//ドローン速度 //誤差 structure error_Vl;//速度(m/s) structure error_Ac;//加速度(m/s^2) structure error_Ac_Pre;//加速度(m/s^2)_1時刻前の値 structure error_Ahrs;//角度(deg) structure error_Ahrs_Pre;//角速度(deg)_1時刻前の値 structure error_Gy;//角速度(deg) structure error_Gy_Pre;//角速度(deg)_1時刻前の値 ////PID制御 ///定数 //速度(m/s) structure Kp_Vl = {1, 1, 1};//Propoptional structure Ki_Vl = {1, 1, 1};//Integral //加速度(m/s^2) structure Kp_Ac = {0, 0, 3};//Propoptional structure Ki_Ac = {0, 0, 3};//Integral structure Kd_Ac = {0, 0, 3};//differential //姿勢角(deg) structure Kp_Ahrs = {0.1, 0.1, 0.1};//Propoptional(参考値{3, 3, 4}) structure Ki_Ahrs = {0.0, 0.0, 0};//Integral(参考値{0, 0, 0}) structure Kd_Ahrs = {0.0, 0.0, 0};//differential //角速度(deg/s) structure Kp_Gy = {3, 3, 3};//Propoptional(参考値{100, 100, 1000}) structure Ki_Gy = {3, 3, 0};//Integral(参考値{100, 100, 0}) structure Kd_Gy = {0.6, 0.6, 0};//differential(参考値{10, 10, 0}) //ループ中更新値 //速度(m/s) structure Pid_Integ_Vl; structure Pid_Integ_Vl_Pre = {0,0,0}; //加速度(m/s^2) structure Pid_Integ_Ac; structure Pid_Integ_Ac_Pre = {0,0,0}; structure Pid_Derive_Ac; structure Pid_Derive_Ac_Pre = {0,0,0}; //姿勢角(deg) structure Pid_Integ_Ahrs; structure Pid_Integ_Ahrs_Pre = {0,0,0}; structure Pid_Derive_Ahrs; structure Pid_Derive_Ahrs_Pre = {0,0,0}; //角速度(deg/s) structure Pid_Integ_Gy; structure Pid_Integ_Gy_Pre = {0,0,0}; structure Pid_Derive_Gy; structure Pid_Derive_Gy_Pre = {0,0,0}; //PID値 structure Pid_Vl; //速度 structure Pid_Ac; //加速度 structure Pid_Ahrs; //姿勢角 structure Pid_Gy; //角速度 //追従偏差微分のノイズフィルタ定数 const float D_Filter_C_Ac = 0.025/(dt*0.001*2*Deg2rad*180);//(/1000*2*Deg2rad*180); //const float D_Filter_C_Ahrs = 0.025/(dt*0.001*2*Deg2rad*180); const float D_Filter_C_Gy = 0.025/(dt*0.001*2*Deg2rad*180);//(dt/1000*2*Deg2rad*180); //積分値の上限値 structure Limit_Vl = {1,1,1};//速度 structure Pid_Integ_Limit_Vl = {2,2,2};//速度 structure Pid_Integ_Limit_Ac = {2,2,2};//加速度 structure Pid_Integ_Limit_Ahrs = {0.05,0.05,0.05};//default{2,2,2} structure Pid_Integ_Limit_Gy = {2,2,2};//default{20,20,2} //PID上限値 structure Pid_Limit_Ac = {0,0,30};//加速度 structure Pid_Limit_Ahrs = {2,2,2};//default記載見つからず structure Pid_Limit_Gy = {20,20,20};//default記載見つからず const int PWM_Motor_Limit = 120; //コマンド分配則調整 float Motor_offset[4] = {-16.3, -8.1, 0, -8.2};//{-16.3, -8.1, 0, -8.2} ////PWM指令//// float PWM_Motor_1; float PWM_Motor_2; float PWM_Motor_3; float PWM_Motor_4; float Motor_th = 1; //Motor_th調整 int i_up = 0; int i_up_num_limit = 5;//機体上昇の際の重力計算の平均値算出におけるサンプル取得回数 float Ac_Hovering = - 3;//機体上昇の際のZ軸方向の加速度(重力は加味) int Motor_th_limit = 85; //スタート後の重力計算 structure g_average = {0,0,0}; int g_k = 0; int g_total_num = 0; int g_total_num_limit = 500;//センサーからの重力値取得までのカウント回数, dt×g_total_num_limit ms→取得時間 float g2mpss_sens; //WiFi関連 #include <WiFi.h> #include <WiFiUdp.h> const char ssid[] = "ESP32_wifi"; // SSID const char pass[] = "esp32pass"; // password const int localPort = 10000; // ポート番号(pythonのポート番号に合わせる) const IPAddress ip(192 ,168, 2 ,14); // IPアドレス(pythonのIPアドレスに合わせる) const IPAddress subnet(255, 255, 255, 0); // サブネットマスク WiFiUDP udp; int val_2; //電源OFF条件 const int time_PWMoff = 5000;//5,000msの間wifiudp入力がなかった場合に切断する int k;// PWM->OFFまでのカウント回数 int k_PWMoff = round(time_PWMoff / dt); int i_th_limit = 5;//offまでのMotor_thの段階 //ESP32からのPWM出力 //https://wak-tech.com/archives/742 const int Motor_1 = 32; const int Motor_2 = 33; const int Motor_3 = 25; const int Motor_4 = 26; //取得データの実単位化スケールファクター float SF_Ac = 16384; //加速度のスケールファクタ (digit/g) float SF_Gy = 131; //#ジャイロのスケールファクタ (digit/dps) float SF_Mg = 500; //磁気のスケールファクタ(500☛0.6かも。。) float SF_Tmp = 333.87; //温度のスケールファクタ float g2mpss = 9.80665; //Gをm/s2に変換 float deg2rad = 3.14159265/180; //ディグリーをラジアンに //センサー値スケール化後数値 float AcX_SF; float AcY_SF; float AcZ_SF; float GyX_SF; float GyY_SF; float GyZ_SF; float ROLL, PITCH, YAW; //サーボ初期値設定 int sv1 = 73; int sv2 = 73; int sv3 = 73; int delta_sv = 1; void setupMPU9255() { Wire.beginTransmission(0x68); Wire.write(0x6B); Wire.write(0x00); Wire.endTransmission(); Wire.beginTransmission(0x68); Wire.write(0x1A); Wire.write(0x05); Wire.endTransmission(); Wire.beginTransmission(0x68); Wire.write(0x37); Wire.write(0x02); Wire.endTransmission(); Wire.beginTransmission(0x0C); Wire.write(0x0A); Wire.write(0x16); Wire.endTransmission(); delay(500); } //MPU9250向け電力供給 void setup() { Serial.begin(115200); //ピンNo5から電力供給 pinMode(5, OUTPUT); digitalWrite(5, HIGH); //MPU9250セットアップ Wire.begin(); Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); setupMPU9255(); //UDP(PC-ESP間)通信関係 //Serial.begin(115200); WiFi.softAP(ssid, pass); // SSIDとパスの設定 //delay(100); // 追記:このdelayを入れないと失敗する場合がある WiFi.softAPConfig(ip, ip, subnet); // IPアドレス、ゲートウェイ、サブネットマスクの設定 Serial.print("AP IP address: "); IPAddress myIP = WiFi.softAPIP(); Serial.println(myIP); Serial.println("Starting UDP"); udp.begin(localPort); // UDP通信の開始(引数はポート番号) Serial.print("Local port: "); Serial.println(localPort); //MadgwickFilter MadgwickFilter.begin(1000/dt);//フィルタリング周波数100Hz //タイマー割込み timer1 = timerBegin(0, 80, true); timerAttachInterrupt(timer1, &onTimer1, true); timerAlarmWrite(timer1, dt*1000, true); //μs timerAlarmEnable(timer1); //LEDC関係 // 使用するタイマーのチャネルと周波数を設定 ledcSetup(0, 12800, 8); ledcSetup(1, 12800, 8); ledcSetup(2, 12800, 8); ledcSetup(3, 12800, 8); // ledPinをチャネル0へ接続 ledcAttachPin(Motor_1, 0); ledcAttachPin(Motor_2, 1); ledcAttachPin(Motor_3, 2); ledcAttachPin(Motor_4, 3); //コントローラ初期値、 Ahrs_Tgt = Ahrs_Tgt_Keep; } //MPU9250セットアップ関連 void readCompass() { Wire.beginTransmission(0x0C); Wire.write(0x02); Wire.endTransmission(); Wire.requestFrom(0x0C, 1); uint8_t ST1 = Wire.read(); if (ST1 & 0x01) { Wire.beginTransmission(0x0C); Wire.write(0x03); Wire.endTransmission(); Wire.requestFrom(0x0C, 7); uint8_t i = 0; uint8_t buf[7]; while (Wire.available()) { buf[i++] = Wire.read(); } if (!(buf[6] & 0x08)) { MgX = ((int16_t)buf[1] << 8) | buf[0]; MgY = ((int16_t)buf[3] << 8) | buf[2]; MgZ = ((int16_t)buf[5] << 8) | buf[4]; } } } //////////// ////Main//// //////////// void loop() { //for(int j; j < 10000000; j++) //{ //if (udp.parsePacket()) { //char val = udp.read(); //val = int(val); //Serial.print(val); //if (val == 57){ //j == 100000000; //} //} //else if(udp.parsePacket() == false){ //delay(10); //Serial.println(j); //} //} //} //} delay(20000); //モーター起動 for(int i; i < 100; i++){ ledcWrite(0, 10); ledcWrite(1, 10); ledcWrite(2, 10); ledcWrite(3, 10); delay(10); ledcWrite(0, 0); ledcWrite(1, 0); ledcWrite(2, 0); ledcWrite(3, 0); delay(10); } //モーターを一旦停止 ledcWrite(0, 0); ledcWrite(1, 0); ledcWrite(2, 0); ledcWrite(3, 0); while(1) //ここからループ開始 { unsigned long time;//「time」をunsigned longで変数宣言 time = millis();//プログラム実行からの経過時間(ms)をtimeに返す //平均値格納// structure Ac_Sens_Ave = {0,0,0};//加速度 structure Gy_Sens_Ave = {0,0,0};//角速度 structure Ahrs_Sens_Ave = {0,0,0};//姿勢角 for(int i = 0; i < FIFO_order; i++){ if (timeCounter1 > 0) { portENTER_CRITICAL(&timerMux); timeCounter1--; portEXIT_CRITICAL(&timerMux); ////MPU9250関連//// //読み出し Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,16,true); // request a total of 14 registers AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) readCompass(); //実単位化(Acc/g->m/s^2,Gy/dps->rad/s)およびマドウィックフィルターによる角度推定 MadgwickFilter.update(GyX/SF_Gy, GyY/SF_Gy, GyZ/SF_Gy, AcX/SF_Ac, AcY/SF_Ac, AcZ/SF_Ac, MgX/SF_Mg, MgY/SF_Mg, MgZ/SF_Mg); //書き出し //加速度について //Serial.print(AcX/SF_Ac*g2mpss);Serial.print(","); //Serial.print(AcY/SF_Ac*g2mpss);Serial.print(","); //Serial.print(AcZ/SF_Ac*g2mpss);Serial.print(","); //姿勢角について //Serial.print(MadgwickFilter.getRoll()); Serial.print(","); //Serial.print(MadgwickFilter.getPitch()); Serial.print(","); //Serial.println(MadgwickFilter.getYaw()); //Serial.print("\n"); //センサー値を格納// //加速度(m/s^2) Ac_Sens[i].Axis_X = AcX/SF_Ac*g2mpss; Ac_Sens[i].Axis_Y = AcY/SF_Ac*g2mpss; if(g_total_num <= g_total_num_limit) { Ac_Sens[i].Axis_Z = AcZ/SF_Ac*g2mpss;//Z軸方向への加速度(重力を差し引く)- g2mpss } else if(g_total_num > g_total_num_limit) { Ac_Sens[i].Axis_Z = AcZ/SF_Ac*g2mpss - g2mpss_sens;//重力センサー値取得後 } //角速度(deg/s) Gy_Sens[i].Axis_X = GyX/SF_Gy*deg2rad; Gy_Sens[i].Axis_Y = GyY/SF_Gy*deg2rad; Gy_Sens[i].Axis_Z = GyZ/SF_Gy*deg2rad; //姿勢角(deg) Ahrs_Sens[i].Axis_X = MadgwickFilter.getRoll(); Ahrs_Sens[i].Axis_Y = MadgwickFilter.getPitch(); Ahrs_Sens[i].Axis_Z = MadgwickFilter.getYaw(); //平均値算出// //加速度(m/s^2) Ac_Sens_Ave.Axis_X += Ac_Sens[i].Axis_X / FIFO_order; Ac_Sens_Ave.Axis_Y += Ac_Sens[i].Axis_Y / FIFO_order; Ac_Sens_Ave.Axis_Z += Ac_Sens[i].Axis_Z / FIFO_order; //角速度(deg/s) Gy_Sens_Ave.Axis_X += Gy_Sens[i].Axis_X / FIFO_order; Gy_Sens_Ave.Axis_Y += Gy_Sens[i].Axis_Y / FIFO_order; Gy_Sens_Ave.Axis_Z += Gy_Sens[i].Axis_Z / FIFO_order; //姿勢角(deg/s) Ahrs_Sens_Ave.Axis_X += Ahrs_Sens[i].Axis_X / FIFO_order; Ahrs_Sens_Ave.Axis_Y += Ahrs_Sens[i].Axis_Y / FIFO_order; Ahrs_Sens_Ave.Axis_Z += Ahrs_Sens[i].Axis_Z / FIFO_order; //重力値取得 if(g_k == 0) { if(g_total_num <= g_total_num_limit) { g_total_num++; g_average.Axis_X = (g_total_num * g_average.Axis_X + Ac_Sens[i].Axis_X) / (g_total_num + 1); g_average.Axis_Y = (g_total_num * g_average.Axis_Y + Ac_Sens[i].Axis_Y) / (g_total_num + 1); g_average.Axis_Z = (g_total_num * g_average.Axis_Z + Ac_Sens[i].Axis_Z) / (g_total_num + 1); g2mpss_sens = sqrt(g_average.Axis_X*g_average.Axis_X + g_average.Axis_Y*g_average.Axis_Y + g_average.Axis_Z*g_average.Axis_Z); } else if(g_total_num > g_total_num_limit) { g_k = 1; } } //自動落下のタイムリミット設定 k ++; //Serial.print(k); if(k > k_PWMoff) { for(int i = i_th_limit - 1; i >= 0 ; i-- ) { if(i > 0) { ledcWrite(0, Motor_th * i / i_th_limit); ledcWrite(1, Motor_th * i / i_th_limit); ledcWrite(2, Motor_th * i / i_th_limit); ledcWrite(3, Motor_th * i / i_th_limit); delay(1000); } else if(i == 0) { ledcWrite(0, Motor_th * i / i_th_limit); ledcWrite(1, Motor_th * i / i_th_limit); ledcWrite(2, Motor_th * i / i_th_limit); ledcWrite(3, Motor_th * i / i_th_limit); delay(1000); //Serial.print("finish"); delay(10000000); } //Serial.print(i); } } if (i = 4){ //推定値// //速度(m/s) Vl.Axis_X += Vl_Pre.Axis_X + Ac_Sens_Ave.Axis_X * dt * FIFO_order; Vl.Axis_Y += Vl_Pre.Axis_Y + Ac_Sens_Ave.Axis_Y * dt * FIFO_order; Vl.Axis_Z += Vl_Pre.Axis_Z + Ac_Sens_Ave.Axis_Z * dt * FIFO_order; if(Vl.Axis_Z > Limit_Vl.Axis_Z) { Vl.Axis_Z = Limit_Vl.Axis_Z; } else if(Vl.Axis_Z < -Limit_Vl.Axis_Z) { Vl.Axis_Z = -Limit_Vl.Axis_Z; } //値の更新 Vl_Pre.Axis_X = Vl.Axis_X; Vl_Pre.Axis_Y = Vl.Axis_Y; Vl_Pre.Axis_Y = Vl.Axis_Z; ////方向指示//// if (udp.parsePacket()) { char val = udp.read(); val = int(val); if (val == 48){//維持 Ahrs_Tgt = Ahrs_Tgt_Keep;//維持 Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt = Ac_Tgt_Keep;//維持 } else if (val == 49){//前 Ahrs_Tgt = Ahrs_Tgt_Front; Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt.Axis_Z = Ac_Tgt_Keep.Axis_Z;//高さのみ維持 } else if (val == 50){//後 Ahrs_Tgt = Ahrs_Tgt_Back; Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt.Axis_Z = Ac_Tgt_Keep.Axis_Z;//高さのみ維持 } else if (val == 51){//右 Ahrs_Tgt = Ahrs_Tgt_Right; Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt.Axis_Z = Ac_Tgt_Keep.Axis_Z;//高さのみ維持 } else if (val == 52){//左 Ahrs_Tgt = Ahrs_Tgt_Left; Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt.Axis_Z = Ac_Tgt_Keep.Axis_Z;//高さのみ維持 } else if (val == 53){//上昇 Ahrs_Tgt = Ahrs_Tgt_Keep; Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt = Ac_Tgt_Up; } else if (val == 54){//下降 Ahrs_Tgt = Ahrs_Tgt_Keep; Ahrs_Tgt.Axis_Z = Ahrs_Sens_Ave.Axis_Z; Ac_Tgt = Ac_Tgt_Down; } else if (val == 57){//スイッチオフ ledcWrite(0, 30); ledcWrite(1, 30); ledcWrite(2, 30); ledcWrite(3, 30); delay(1000); ledcWrite(0, 10); ledcWrite(1, 10); ledcWrite(2, 10); ledcWrite(3, 10); delay(1000); ledcWrite(0, 0); ledcWrite(1, 0); ledcWrite(2, 0); ledcWrite(3, 0); delay(10000000); } val_2 = val; k = 0;//kのリセット } ////誤差//// //姿勢角(deg) error_Ahrs.Axis_X = Ahrs_Tgt.Axis_X - Ahrs_Sens_Ave.Axis_X; error_Ahrs.Axis_Y = Ahrs_Tgt.Axis_Y - Ahrs_Sens_Ave.Axis_Y; error_Ahrs.Axis_Z = Ahrs_Tgt.Axis_Z - Ahrs_Sens_Ave.Axis_Z; //加速度(m/s) error_Ac.Axis_Z = Ac_Tgt.Axis_Z - Ac_Sens_Ave.Axis_Z; //Serial.print(error_Vl.Axis_Z); Serial.print(" ");Serial.print(Vl_Tgt.Axis_Z); Serial.print(" ");Serial.print(Vl.Axis_Z); Serial.print(" "); ////PID制御//// ///PID速度/// //Z Axis //Pid_Integ_Vl.Axis_Z += error_Vl.Axis_Z * dt * FIFO_order; //if (Pid_Integ_Vl.Axis_Z > Pid_Integ_Limit_Vl.Axis_Z){ // Pid_Integ_Vl.Axis_Z = Pid_Integ_Limit_Vl.Axis_Z; // } //else if (Pid_Integ_Vl.Axis_Z < -1 * Pid_Integ_Limit_Vl.Axis_Z){ // Pid_Integ_Vl.Axis_Z = -1 * Pid_Integ_Limit_Vl.Axis_Z; // } //Pid_Vl.Axis_Z = error_Vl.Axis_Z * Kp_Vl.Axis_Z + Pid_Integ_Vl.Axis_Z * Ki_Vl.Axis_Z; ///PID加速度/// //Z Axis Pid_Integ_Ac.Axis_Z += error_Ac.Axis_Z * dt * FIFO_order; if (Pid_Integ_Ac.Axis_Z > Pid_Integ_Limit_Ac.Axis_Z){ Pid_Integ_Ac.Axis_Z = Pid_Integ_Limit_Ac.Axis_Z; } else if (Pid_Integ_Ac.Axis_Z < -1 * Pid_Integ_Limit_Ac.Axis_Z){ Pid_Integ_Ac.Axis_Z = -1 * Pid_Integ_Limit_Ac.Axis_Z; } Pid_Derive_Ac.Axis_Z = (error_Ac.Axis_Z - error_Ac_Pre.Axis_Z) * Deno; error_Ac_Pre.Axis_Z = error_Ac.Axis_Z; Pid_Derive_Ac.Axis_Z = Pid_Derive_Ac_Pre.Axis_Z + (Pid_Derive_Ac.Axis_Z - Pid_Derive_Ac_Pre.Axis_Z) * D_Filter_C_Gy; Pid_Derive_Ac_Pre.Axis_Z = Pid_Derive_Ac.Axis_Z; Pid_Ac.Axis_Z = Kp_Ac.Axis_Z * error_Ac.Axis_Z + Ki_Ac.Axis_Z * Pid_Integ_Ac.Axis_Z + Kd_Ac.Axis_Z * Pid_Derive_Ac.Axis_Z;//PID全体計算 if (Pid_Ac.Axis_Z > Pid_Limit_Ac.Axis_Z){ Pid_Ac.Axis_Z = Pid_Limit_Ac.Axis_Z; } else if (Pid_Ac.Axis_Z < -Pid_Limit_Ac.Axis_Z){ Pid_Ac.Axis_Z = -Pid_Limit_Ac.Axis_Z; } //Motor_th調整 if(i_up == 0) { if(val_2 == 53) { Motor_th += 1; if(Motor_th >= Motor_th_limit) { i_up = 1; if(Ac_Sens_Ave.Axis_Z - g2mpss_sens > Ac_Hovering) { for(int i_up_num = 0; i_up_num < i_up_num_limit ; i_up_num ++) { if(i_up_num >= i_up_num_limit) { i_up = 1; } } } } } } //Motor_th = Pid_Ac.Axis_Z;//「トリム値」もともとMotor_th = Pid_Ac.Axis_Z; //Serial.print(Ac_Sens_Ave.Axis_Z);Serial.print(" "); //Serial.print(error_Ac.Axis_Z);Serial.print(" "); ///PID姿勢角// //X Axis Pid_Integ_Ahrs.Axis_X += error_Ahrs.Axis_X * dt * FIFO_order; if (Pid_Integ_Ahrs.Axis_X > Pid_Integ_Limit_Ahrs.Axis_X){ Pid_Integ_Ahrs.Axis_X = Pid_Integ_Limit_Ahrs.Axis_X; } else if (Pid_Integ_Ahrs.Axis_X < -1 * Pid_Integ_Limit_Ahrs.Axis_X){ Pid_Integ_Ahrs.Axis_X = -1 * Pid_Integ_Limit_Ahrs.Axis_X; } Pid_Derive_Ahrs.Axis_X = (error_Ahrs.Axis_X - error_Ahrs_Pre.Axis_X) * Deno; error_Ahrs_Pre.Axis_X = error_Ahrs.Axis_X; Pid_Derive_Ahrs.Axis_X = Pid_Derive_Ahrs_Pre.Axis_X + (Pid_Derive_Ahrs.Axis_X - Pid_Derive_Ahrs_Pre.Axis_X) * D_Filter_C_Gy; Pid_Derive_Ahrs_Pre.Axis_X = Pid_Derive_Ahrs.Axis_X; Pid_Ahrs.Axis_X = Kp_Ahrs.Axis_X * error_Ahrs.Axis_X + Ki_Ahrs.Axis_X * Pid_Integ_Ahrs.Axis_X + Kd_Ahrs.Axis_X * Pid_Derive_Gy.Axis_X; if (Pid_Ahrs.Axis_X > Pid_Limit_Ahrs.Axis_X){ Pid_Ahrs.Axis_X = Pid_Limit_Ahrs.Axis_X; } else if (Pid_Ahrs.Axis_X < -Pid_Limit_Ahrs.Axis_X){ Pid_Ahrs.Axis_X = -Pid_Limit_Ahrs.Axis_X; } //Y axis Pid_Integ_Ahrs.Axis_Y += error_Ahrs.Axis_Y * dt * FIFO_order; if (Pid_Integ_Ahrs.Axis_Y > Pid_Integ_Limit_Ahrs.Axis_Y){ Pid_Integ_Ahrs.Axis_Y = Pid_Integ_Limit_Ahrs.Axis_Y; } else if (Pid_Integ_Ahrs.Axis_Y < -1 * Pid_Integ_Limit_Ahrs.Axis_Y){ Pid_Integ_Ahrs.Axis_Y = -1 * Pid_Integ_Limit_Ahrs.Axis_Y; } Pid_Derive_Ahrs.Axis_Y = (error_Ahrs.Axis_Y - error_Ahrs_Pre.Axis_Y) * Deno; error_Ahrs_Pre.Axis_Y = error_Ahrs.Axis_Y; Pid_Derive_Ahrs.Axis_Y = Pid_Derive_Ahrs_Pre.Axis_Y + (Pid_Derive_Ahrs.Axis_Y - Pid_Derive_Ahrs_Pre.Axis_Y) * D_Filter_C_Gy; Pid_Derive_Ahrs_Pre.Axis_Y = Pid_Derive_Ahrs.Axis_Y; Pid_Ahrs.Axis_Y = Kp_Ahrs.Axis_Y * error_Ahrs.Axis_Y + Ki_Ahrs.Axis_Y * Pid_Integ_Ahrs.Axis_Y + Kd_Ahrs.Axis_Y * Pid_Derive_Ahrs.Axis_Y; if (Pid_Ahrs.Axis_Y > Pid_Limit_Ahrs.Axis_Y){ Pid_Ahrs.Axis_Y = Pid_Limit_Ahrs.Axis_Y; } else if (Pid_Ahrs.Axis_Y < -Pid_Limit_Ahrs.Axis_Y){ Pid_Ahrs.Axis_Y = -Pid_Limit_Ahrs.Axis_Y; } //Z axis Pid_Integ_Ahrs.Axis_Z += error_Ahrs.Axis_Z * dt * FIFO_order; if (Pid_Integ_Ahrs.Axis_Z > Pid_Integ_Limit_Ahrs.Axis_Z){ Pid_Integ_Ahrs.Axis_Z = Pid_Integ_Limit_Ahrs.Axis_Z; } else if (Pid_Integ_Ahrs.Axis_Z < -1 * Pid_Integ_Limit_Ahrs.Axis_Z){ Pid_Integ_Ahrs.Axis_Z = -1 * Pid_Integ_Limit_Ahrs.Axis_Z; } Pid_Derive_Ahrs.Axis_Z = (error_Ahrs.Axis_Z - error_Ahrs_Pre.Axis_Z) * Deno; error_Ahrs_Pre.Axis_Z = error_Ahrs.Axis_Z; Pid_Derive_Ahrs.Axis_Z = Pid_Derive_Ahrs_Pre.Axis_Z + (Pid_Derive_Ahrs.Axis_Z - Pid_Derive_Ahrs_Pre.Axis_Z) * D_Filter_C_Gy; Pid_Derive_Ahrs_Pre.Axis_Z = Pid_Derive_Ahrs.Axis_Z; Pid_Ahrs.Axis_Z = Kp_Ahrs.Axis_Z * error_Ahrs.Axis_Z + Ki_Ahrs.Axis_Z * Pid_Integ_Ahrs.Axis_Z + Kd_Ahrs.Axis_Z * Pid_Derive_Ahrs.Axis_Z; if (Pid_Ahrs.Axis_Z > Pid_Limit_Ahrs.Axis_Z){ Pid_Ahrs.Axis_Z = Pid_Limit_Ahrs.Axis_Z; } else if (Pid_Ahrs.Axis_Z < -Pid_Limit_Ahrs.Axis_Z){ Pid_Ahrs.Axis_Z = -Pid_Limit_Ahrs.Axis_Z; } ///PID角速度// //X Axis error_Gy.Axis_X = Pid_Ahrs.Axis_X - Gy_Sens_Ave.Axis_X; Pid_Integ_Gy.Axis_X += error_Gy.Axis_X * dt * FIFO_order; if (Pid_Integ_Gy.Axis_X > Pid_Integ_Limit_Gy.Axis_X){ Pid_Integ_Gy.Axis_X = Pid_Integ_Limit_Gy.Axis_X; } else if (Pid_Integ_Gy.Axis_X < -1 * Pid_Integ_Limit_Gy.Axis_X){ Pid_Integ_Gy.Axis_X = -1 * Pid_Integ_Limit_Gy.Axis_X; } Pid_Derive_Gy.Axis_X = (error_Gy.Axis_X - error_Gy_Pre.Axis_X) * Deno; error_Gy_Pre.Axis_X = error_Gy.Axis_X; Pid_Derive_Gy.Axis_X = Pid_Derive_Gy_Pre.Axis_X + (Pid_Derive_Gy.Axis_X - Pid_Derive_Gy_Pre.Axis_X) * D_Filter_C_Gy; Pid_Derive_Gy_Pre.Axis_X = Pid_Derive_Gy.Axis_X; Pid_Gy.Axis_X = Kp_Gy.Axis_X * error_Gy.Axis_X + Ki_Gy.Axis_X * Pid_Integ_Gy.Axis_X + Kd_Gy.Axis_X * Pid_Derive_Gy.Axis_X;//PID全体計算 if (Pid_Gy.Axis_X > Pid_Limit_Gy.Axis_X){ Pid_Gy.Axis_X = Pid_Limit_Gy.Axis_X; } else if (Pid_Gy.Axis_X < -Pid_Limit_Gy.Axis_X){ Pid_Gy.Axis_X = -Pid_Limit_Gy.Axis_X; } //Y Axis error_Gy.Axis_Y = Pid_Ahrs.Axis_Y - Gy_Sens_Ave.Axis_Y; Pid_Integ_Gy.Axis_Y += error_Gy.Axis_Y * dt * FIFO_order; if (Pid_Integ_Gy.Axis_Y > Pid_Integ_Limit_Gy.Axis_Y){ Pid_Integ_Gy.Axis_Y = Pid_Integ_Limit_Gy.Axis_Y; } else if (Pid_Integ_Gy.Axis_Y < -1 * Pid_Integ_Limit_Gy.Axis_Y){ Pid_Integ_Gy.Axis_Y = -1 * Pid_Integ_Limit_Gy.Axis_Y; } Pid_Derive_Gy.Axis_Y = (error_Gy.Axis_Y - error_Gy_Pre.Axis_Y) * Deno; error_Gy_Pre.Axis_Y = error_Gy.Axis_Y; Pid_Derive_Gy.Axis_Y = Pid_Derive_Gy_Pre.Axis_Y + (Pid_Derive_Gy.Axis_Y - Pid_Derive_Gy_Pre.Axis_Y) * D_Filter_C_Gy; Pid_Derive_Gy_Pre.Axis_Y = Pid_Derive_Gy.Axis_Y; Pid_Gy.Axis_Y = Kp_Gy.Axis_Y * error_Gy.Axis_Y + Ki_Gy.Axis_Y * Pid_Integ_Gy.Axis_Y + Kd_Gy.Axis_Y * Pid_Derive_Gy.Axis_Y;//PID全体計算 if (Pid_Gy.Axis_Y > Pid_Limit_Gy.Axis_Y){ Pid_Gy.Axis_Y = Pid_Limit_Gy.Axis_Y; } else if (Pid_Gy.Axis_Y < -Pid_Limit_Gy.Axis_Y){ Pid_Gy.Axis_Y = -Pid_Limit_Gy.Axis_Y; } //Z Axis error_Gy.Axis_Z = Pid_Ahrs.Axis_Z - Gy_Sens_Ave.Axis_Z; Pid_Integ_Gy.Axis_Z += error_Gy.Axis_Z * dt * FIFO_order; if (Pid_Integ_Gy.Axis_Z > Pid_Integ_Limit_Gy.Axis_Z){ Pid_Integ_Gy.Axis_Z = Pid_Integ_Limit_Gy.Axis_Z; } else if (Pid_Integ_Gy.Axis_Z < -1 * Pid_Integ_Limit_Gy.Axis_Z){ Pid_Integ_Gy.Axis_Z = -1 * Pid_Integ_Limit_Gy.Axis_Z; } Pid_Derive_Gy.Axis_Z = (error_Gy.Axis_Z - error_Gy_Pre.Axis_Z) * Deno; error_Gy_Pre.Axis_Z = error_Gy.Axis_Z; Pid_Derive_Gy.Axis_Z = Pid_Derive_Gy_Pre.Axis_Z + (Pid_Derive_Gy.Axis_Z - Pid_Derive_Gy_Pre.Axis_Z) * D_Filter_C_Gy; Pid_Derive_Gy_Pre.Axis_Z = Pid_Derive_Gy.Axis_Z; Pid_Gy.Axis_Z = Kp_Gy.Axis_Z * error_Gy.Axis_Z + Ki_Gy.Axis_Z * Pid_Integ_Gy.Axis_Z + Kd_Gy.Axis_Z * Pid_Derive_Gy.Axis_Z;//PID全体計算 if (Pid_Gy.Axis_Z > Pid_Limit_Gy.Axis_Z){ Pid_Gy.Axis_Z = Pid_Limit_Gy.Axis_Z; } else if (Pid_Gy.Axis_Z < -Pid_Limit_Gy.Axis_Z){ Pid_Gy.Axis_Z = -Pid_Limit_Gy.Axis_Z; } PWM_Motor_1 = (Motor_th + Pid_Ac.Axis_Z) - Pid_Gy.Axis_X - Pid_Gy.Axis_Y + Pid_Gy.Axis_Z + Motor_offset[0]; if(PWM_Motor_1 < 0){ PWM_Motor_1 = 0; } else if(PWM_Motor_1 > PWM_Motor_Limit){ PWM_Motor_1 = PWM_Motor_Limit; } PWM_Motor_2 = (Motor_th + Pid_Ac.Axis_Z) + Pid_Gy.Axis_X - Pid_Gy.Axis_Y - Pid_Gy.Axis_Z + Motor_offset[1]; if(PWM_Motor_2 < 0){ PWM_Motor_2 = 0; } else if(PWM_Motor_2 > PWM_Motor_Limit){ PWM_Motor_2 = PWM_Motor_Limit; } PWM_Motor_3 = (Motor_th + Pid_Ac.Axis_Z) + Pid_Gy.Axis_X + Pid_Gy.Axis_Y + Pid_Gy.Axis_Z + Motor_offset[2]; if(PWM_Motor_3 < 0){ PWM_Motor_3 = 0; } else if(PWM_Motor_3 > PWM_Motor_Limit){ PWM_Motor_3 = PWM_Motor_Limit; } PWM_Motor_4 = (Motor_th + Pid_Ac.Axis_Z) - Pid_Gy.Axis_X + Pid_Gy.Axis_Y - Pid_Gy.Axis_Z + Motor_offset[3]; if(PWM_Motor_4 < 0){ PWM_Motor_4 = 0; } else if(PWM_Motor_4 > PWM_Motor_Limit){ PWM_Motor_4 = PWM_Motor_Limit; } //Serial.print(Motor_th);Serial.print(", "); Serial.print(PWM_Motor_1);Serial.print(", "); Serial.print(PWM_Motor_2);Serial.print(", "); Serial.print(PWM_Motor_3);Serial.print(", "); Serial.print(PWM_Motor_4);Serial.println(", "); //Serial.println(val_2); //モーターへの出力 ledcWrite(0, PWM_Motor_1); ledcWrite(1, PWM_Motor_2); ledcWrite(2, PWM_Motor_3); ledcWrite(3, PWM_Motor_4); } } } } }
PC and Playstation3 controller side source code
#参考https://rikoubou.hatenablog.com/entry/2017/10/06/181805 #参考https://greenhornprofessional.hatenablog.com/entry/2020/09/13/223155 from __future__ import print_function import socket import time from time import sleep from contextlib import closing import pygame from pygame.locals import * ###ジョイスティック側 # ジョイスティックの初期化 pygame.joystick.init() try: # ジョイスティックインスタンスの生成 joystick = pygame.joystick.Joystick(0) joystick.init() print('ジョイスティックの名前:', joystick.get_name()) print('ボタン数 :', joystick.get_numbuttons()) except pygame.error: print('ジョイスティックが接続されていません') # pygameの初期化 pygame.init() # 画面の生成 SCREEN_SIZE = (640, 480) # 画面サイズ (横/縦) STEP = 10 #キーボード/ハットスイッチの反応の良さ X_CENTER = int(SCREEN_SIZE[0]/2) Y_CENTER = int(SCREEN_SIZE[1]/2) screen = pygame.display.set_mode(SCREEN_SIZE) screen2 = pygame.display.set_mode(SCREEN_SIZE) screen.fill((0,0,0)) screen2.fill((0,0,0)) #通信部分 def main(): host = '192.168.4.1' # IPアドレス port = 10000 # ポート番号 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #AFINETは、V4を使うという意味、DGRAMはUDP指定の意味 with closing(sock): while True: # イベントの取得 for e in pygame.event.get(): # 終了ボタン if e.type == QUIT: active = False # ジョイスティックのボタンの入力 if e.type == pygame.locals.JOYAXISMOTION: print(joystick.get_axis(0), -1*joystick.get_axis(1), joystick.get_axis(2), -1*joystick.get_axis(3)) command0 = joystick.get_axis(0)+1 command0 = str(round(command0)) print(command0) print(type(command0)) command1 = -joystick.get_axis(1)+1 command1 = str(round(command1)) print(command1) print(type(command1)) command2 = joystick.get_axis(2)+1 command2 = str(round(command2)) print(command2) print(type(command2)) command3 = -joystick.get_axis(3)+1 command3 = str(round(command3)) print(command3) print(type(command3)) command = command0 + command1 + command2 + command3 if command == "1211": #上 command = "5" elif command == "1011": #下 command = "6" elif command == "2111": # command = "0" elif command == "0111": # command = "0" elif command == "1112": #前 command = "1" elif command == "1110": #後 command = "2" elif command == "1121": #右 command = "3" elif command == "1101": #左 command = "4" elif command == "2101": #スイッチオン(内側コマンド) command = "9" else: #継続 command = "0" print(command) command = str(command).encode("UTF-8") print(command) sock.sendto(command,(host, port)) time.sleep(0.01) #sock.sendto(bytes(command, encoding='ascii'), (host, port)) return """ message = 'A'.encode('utf-8') # 送る文字列(ここでは「A」という文字列を送っている) print(message) sock.sendto(message, (host, port)) time.sleep(1) """ #return if __name__ == '__main__': main()