Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HCSR04_2 MPU6050_2 mbed SDFileSystem3
Fork of Autoflight2018_38 by
Diff: main.cpp
- Revision:
- 0:17f575135219
- Child:
- 1:f383708a5a52
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Sep 07 04:11:48 2018 +0000
@@ -0,0 +1,1216 @@
+//mbed
+#include "mbed.h"
+#include "FATFileSystem.h"
+#include "SDFileSystem.h"
+//C
+#include "math.h"
+//sensor
+#include "MPU6050_DMP6.h"
+//#include "MPU9250.h"
+//#include "BMP280.h"
+#include "hcsr04.h"
+//device
+#include "sbus.h"
+//config
+#include "SkipperSv2.h"
+#include "falfalla.h"
+//other
+#include "pid.h"
+
+#define DEBUG_SEMIAUTO 0
+#define DEBUG_PRINT_INLOOP 1
+
+#define KP_ELE 2.0
+#define KI_ELE 0.0
+#define KD_ELE 0.0
+#define KP_RUD 3.0
+#define KI_RUD 0.0
+#define KD_RUD 0.0
+
+#define GAIN_CONTROLVALUE_TO_PWM 3.0
+
+#define RIGHT_ROLL -12.0
+#define RIGHT_PITCH -5.0
+#define LEFT_ROLL 12.0
+#define LEFT_PITCH -5.0
+#define STRAIGHT_ROLL 4.0
+#define STRAIGHT_PITCH 3.0
+#define TAKEOFF_THR 0.8
+#define LOOP_THR 0.6
+
+#define RIGHT_ROLL_SHORT -12.0
+#define RIGHT_PITCH_SHORT -5.0
+#define LEFT_ROLL_SHORT 12.0
+#define LEFT_PITCH_SHORT -5.0
+
+#define GLIDE_ROLL -12.0
+#define GLIDE_PITCH -3.0
+
+//コンパスキャリブレーション
+//SkipperS2基板
+/*
+#define MAGBIAS_X -35.0
+#define MAGBIAS_Y 535.0
+#define MAGBIAS_Z -50.0
+*/
+//S2v2 1番基板
+#define MAGBIAS_X 395.0
+#define MAGBIAS_Y 505.0
+#define MAGBIAS_Z -725.0
+//S2v2 2番基板
+/*
+#define MAGBIAS_X 185.0
+#define MAGBIAS_Y 220.0
+#define MAGBIAS_Z -350.0
+*/
+
+#define ELEMENT 1
+#define LIMIT_STRAIGHT_YAW 5.0
+#define THRESHOLD_TURNINGRADIUS_YAW 60.0
+#define ALLOWHEIGHT 15
+
+#ifndef PI
+#define PI 3.14159265358979
+#endif
+
+const int16_t lengthdivpwm = 320;
+const int16_t changeModeCount = 6;
+
+const float trim[4] = {Trim_Falfalla[0],Trim_Falfalla[1],Trim_Falfalla[2],Trim_Falfalla[3]};
+const float expMax[4] = {ExpMax_Falfalla[0],ExpMax_Falfalla[1],ExpMax_Falfalla[2],ExpMax_Falfalla[3]};
+const float expMin[4] = {ExpMin_Falfalla[0],ExpMin_Falfalla[1],ExpMin_Falfalla[2],ExpMin_Falfalla[3]};
+const int16_t reverce[4] = {ExpMin_Falfalla[0],Reverce_falfalla[1],Reverce_falfalla[2],Reverce_falfalla[3]};
+
+SBUS sbus(PA_9, PA_10); //SBUS
+
+PwmOut servo1(PC_6); // TIM3_CH1 //old echo
+PwmOut servo2(PC_7); // TIM3_CH2 //PC_7
+PwmOut servo3(PB_0); // TIM3_CH3
+PwmOut servo4(PB_1); // TIM3_CH4
+PwmOut servo5(PB_6); // TIM4_CH1
+PwmOut servo6(PB_7); // TIM4_CH2 //old trigger
+//PwmOut servo7(PB_8); // TIM4_CH3 //PB_8 new echo
+//PwmOut servo8(PB_9); // TIM4_CH4 //new trigger
+
+RawSerial pc(PA_2,PA_3, 115200); //tx,rx.baudrate pin;PA_2=UART2_TX, PA_3=UART2_RX
+SDFileSystem sd(PB_15, PB_14, PB_13, PB_12, "sd");
+
+DigitalOut led1(PA_0); //黄色のコネクタ
+DigitalOut led2(PA_1);
+DigitalOut led3(PB_4);
+DigitalOut led4(PB_5);
+
+//InterruptIn switch2(PC_14);
+MPU6050DMP6 mpu6050(PC_0,&pc); //割り込みピン,シリアルポインタ i2cのピン指定は MPU6050>>I2Cdev.h 内のdefine
+HCSR04 usensor(PB_9,PB_8); //trig,echo 9,8
+
+PID pid_ELE(g_kpELE,g_kiELE,g_kdELE);
+PID pid_RUD(g_kpRUD,g_kiRUD,g_kdRUD);
+
+enum Channel{AIL_R, ELE, THR, RUD, DROP, AIL_L, Ch7, Ch8};
+enum Angle{ROLL, PITCH, YAW}; //yaw:北を0とした絶対角度
+enum OperationMode{StartUp, SemiAuto, RightLoop, LeftLoop, GoStraight, BombwithPC, ZERO, Moebius, Glide};
+enum BombingMode{Takeoff, Chicken, Transition, Approach};
+enum OutputStatus{Manual, Auto};
+
+static OutputStatus output_status = Manual;
+OperationMode operation_mode = StartUp;
+BombingMode bombing_mode = Takeoff;
+static int16_t autopwm[8] = {1500,1500,1180,1500,1392,1500};
+static int16_t trimpwm[6] = {1500,1500,1180,1500,1392,1500};
+int16_t maxpwm[6] = {1820,1820,1820,1820,1820,1820};
+int16_t minpwm[6] = {1180,1180,1180,1180,1180,1180};
+int16_t oldTHR = 1000;
+
+static float nowAngle[3] = {0,0,0};
+const float trimAngle[3] = {0.0, 0.0, 0.0};
+const float maxAngle[2] = {90, 90};
+const float minAngle[2] = {-90, -90};
+
+float FirstROLL = 0.0, FirstPITCH = 0.0 ,FirstYAW = 0.0;
+
+unsigned int g_distance;
+Ticker USsensor;
+static char g_buf[16];
+char g_landingcommand;
+float g_SerialTargetYAW;
+
+Timer t;
+Timeout RerurnChickenServo1;
+Timeout RerurnChickenServo2;
+
+/*-----関数のプロトタイプ宣言-----*/
+void setup();
+void loop();
+
+void Init_PWM();
+void Init_servo(); //サーボ初期化
+void Init_sbus(); //SBUS初期化
+void Init_sensors();
+void DisplayClock(); //クロック状態確認
+
+//センサの値取得
+void SensingMPU();
+void UpdateDist();
+
+//void offsetRollPitch(float FirstROLL, float FirstPITCH);
+//void TransYaw(float FirstYAW);
+float TranslateNewYaw(float beforeYaw, float newzeroYaw);
+void UpdateTargetAngle(float targetAngle[3]);
+void CalculateControlValue(float targetAngle[3], float controlValue[3]);
+void UpdateAutoPWM(float controlValue[3]);
+void ConvertPWMintoRAD(float targetAngle[3]);
+inline float CalcRatio(float value, float trim, float limit);
+bool CheckSW_Up(Channel ch);
+int16_t ThresholdMaxMin(int16_t value, int16_t max, int16_t min);
+inline int16_t SetTHRinRatio(float ratio);
+
+//sbus割り込み
+void Update_PWM(); //マニュアル・自動モードのpwmデータを整形しpwm変数に入力
+void Output_PWM(int16_t pwm[6]); //pwmをサーボへ出力
+
+//シリアル割り込み
+void SendSerial(); //1文字きたら送り返す
+void SendArray();
+void getSF_Serial();
+float ConvertByteintoFloat(char high, char low);
+
+//SD設定
+int GetParameter(FILE *fp, const char *paramName,char parameter[]);
+int SetOptions(float *g_kpELE, float *g_kiELE, float *g_kdELE,
+ float *g_kpRUD, float *g_kiRUD, float *g_kdRUD,
+ float *g_rightloopROLL, float *g_rightloopPITCH,
+ float *g_leftloopROLL, float *g_leftloopPITCH,
+ float *g_gostraightROLL, float *g_gostraightPITCH,
+ float *g_takeoffTHR, float *g_loopTHR,
+ float *g_rightloopROLLshort, float *g_rightloopPITCHshort,
+ float *g_leftloopROLLshort, float *g_leftloopPITCHshort,
+ float *g_glideloopROLL, float *g_glideloopPITCH);
+//switch2割り込み
+void ResetTrim();
+
+//自動操縦
+void UpdateTargetAngle_GoStraight(float targetAngle[3]);
+void UpdateTargetAngle_Rightloop(float targetAngle[3]);
+void UpdateTargetAngle_Rightloop_short(float targetAngle[3]);
+void UpdateTargetAngle_Leftloop(float targetAngle[3]);
+void UpdateTargetAngle_Leftloop_short(float targetAngle[3]);
+void UpdateTargetAngle_Moebius(float targetAngle[3]);
+void UpdateTargetAngle_Glide(float targetAngle[3]);
+void UpdateTargetAngle_Takeoff(float targetAngle[3]);
+void UpdateTargetAngle_Approach(float targetAngle[3]);
+void Take_off_and_landing(float targetAngle[3]);
+
+int Rotate(float targetAngle[3], float TargetYAW);
+
+//投下
+void Chicken_Drop();
+void ReturnChickenServo1();
+void ReturnChickenServo2();
+
+//超音波による高度補正
+void checkHeight(float targetAngle[3]);
+void UpdateTargetAngle_NoseUP(float targetAngle[3]);
+void UpdateTargetAngle_NoseDOWN(float targetAngle[3]);
+
+//デバッグ用
+void DebugPrint();
+
+/*---関数のプロトタイプ宣言終わり---*/
+
+int main()
+{
+ setup();
+
+
+ while(1){
+
+ loop();
+
+ if(!CheckSW_Up(Ch7)){
+ led3=0;
+ }else{
+ led3=1;
+ }
+ }
+
+}
+
+void setup(){
+ //buzzer = 0;
+ led1 = 1;
+ led2 = 1;
+ led3 = 1;
+ led4 = 1;
+
+ SetOptions(&g_kpELE, &g_kiELE, &g_kdELE,
+ &g_kpRUD, &g_kiRUD, &g_kdRUD,
+ &g_rightloopROLL, &g_rightloopPITCH,
+ &g_leftloopROLL, &g_leftloopPITCH,
+ &g_gostraightROLL, &g_gostraightPITCH,
+ &g_takeoffTHR, &g_loopTHR,
+ &g_rightloopROLLshort, &g_rightloopPITCHshort,
+ &g_leftloopROLLshort, &g_leftloopPITCHshort,
+ &g_glideloopROLL, &g_glideloopPITCH);
+
+
+ Init_PWM();
+ Init_servo();
+ Init_sbus();
+ Init_sensors();
+ //switch2.rise(ResetTrim);
+ pc.attach(getSF_Serial, Serial::RxIrq);
+ USsensor.attach(&UpdateDist, 0.05);
+
+ NVIC_SetPriority(USART1_IRQn,0);
+ NVIC_SetPriority(EXTI0_IRQn,1);
+ NVIC_SetPriority(TIM5_IRQn,2);
+ NVIC_SetPriority(EXTI9_5_IRQn,3);
+ NVIC_SetPriority(USART2_IRQn,4);
+ DisplayClock();
+ t.start();
+
+
+ pc.printf("MPU calibration start\r\n");
+
+ float offsetstart = t.read();
+ while(t.read() - offsetstart < 26){
+ SensingMPU();
+ for(uint8_t i=0; i<3; i++) pc.printf("%3.2f\t",nowAngle[i]);
+ pc.printf("\r\n");
+ led1 = !led1;
+ led2 = !led2;
+ led3 = !led3;
+ led4 = !led4;
+ }
+
+ FirstROLL = nowAngle[ROLL];
+ FirstPITCH = nowAngle[PITCH];
+ nowAngle[ROLL] -=FirstROLL;
+ nowAngle[PITCH] -=FirstPITCH;
+
+ led1 = 0;
+ led2 = 0;
+ led3 = 0;
+ led4 = 0;
+ wait(0.2);
+
+
+ pc.printf("All initialized\r\n");
+}
+
+void loop(){
+ static float targetAngle[3] = {0.0, 0.0, 0.0}, controlValue[2] = {0.0, 0.0};
+
+ SensingMPU();
+ UpdateTargetAngle(targetAngle);
+ //Rotate(targetAngle, 30.0);
+ CalculateControlValue(targetAngle, controlValue);
+ UpdateAutoPWM(controlValue);
+ wait_ms(23);
+#if DEBUG_PRINT_INLOOP
+ DebugPrint();
+#endif
+}
+
+//サーボ初期化関数
+void Init_servo(){
+
+ servo1.period_ms(14);
+ servo1.pulsewidth_us(trimpwm[AIL_R]);
+
+ servo2.period_ms(14);
+ servo2.pulsewidth_us(trimpwm[ELE]);
+
+ servo3.period_ms(14);
+ servo3.pulsewidth_us(trimpwm[THR]);
+
+ servo4.period_ms(14);
+ servo4.pulsewidth_us(trimpwm[RUD]);
+
+ servo5.period_ms(14);
+ servo5.pulsewidth_us(1392);
+
+ servo6.period_ms(14);
+ servo6.pulsewidth_us(trimpwm[AIL_L]);
+
+ pc.printf("servo initialized\r\n");
+}
+
+//Sbus初期化
+void Init_sbus(){
+ sbus.initialize();
+ sbus.setLastfuncPoint(Update_PWM);
+ sbus.startInterrupt();
+}
+
+void Init_sensors(){
+ if(mpu6050.setup() == -1){
+ pc.printf("failed initialize\r\n");
+ while(1){
+ led1 = 1; led2 = 0; led3 = 1; led4 = 0;
+ wait(1);
+ led1 = 0; led2 = 1; led3 = 0; led4 = 1;
+ wait(1);
+ }
+ }
+}
+
+void Init_PWM(){
+ for (uint8_t i = 0; i < 4; ++i){
+ trimpwm[i] = 1500 + (int16_t)(lengthdivpwm * (trim[i]/100));
+ maxpwm[i] = 1500 + (int16_t)(lengthdivpwm * (expMax[i]/100));
+ minpwm[i] = 1500 - (int16_t)(lengthdivpwm * (expMin[i]/100));
+ }
+ pc.printf("PWM initialized\r\n");
+}
+
+void DisplayClock(){
+ pc.printf("System Clock = %d[MHz]\r\n", HAL_RCC_GetSysClockFreq()/1000000);
+ pc.printf("HCLK Clock = %d[MHz]\r\n", HAL_RCC_GetHCLKFreq()/1000000);
+ pc.printf("PCLK1 Clock = %d[MHz]\r\n", HAL_RCC_GetPCLK1Freq()/1000000);
+ pc.printf("PCLK2 Clock = %d[MHz]\r\n", HAL_RCC_GetPCLK2Freq()/1000000);
+ pc.printf("\r\n");
+}
+
+void UpdateTargetAngle(float targetAngle[3]){
+ static int16_t count_op = 0;
+#if DEBUG_SEMIAUTO
+ switch(operation_mode){
+ case StartUp:
+ if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = SemiAuto;
+ pc.printf("Goto SemiAuto mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ break;
+
+ case SemiAuto:
+ /* 大会用では以下のif文を入れてoperation_modeを変える
+ if(CheckSW_Up(Ch6)){
+ count_op++;
+ if(count_op>changeModeCount){
+ output_status = XXX;
+ led2 = 0;
+ pc.printf("Goto XXX mode\r\n");
+ count_op = 0;
+ }else count_op = 0;
+ ConvertPWMintoRAD(targetAngle);
+ }
+ */
+ ConvertPWMintoRAD(targetAngle);
+ break;
+
+ default:
+ operation_mode = SemiAuto;
+ break;
+ }
+
+#else
+
+ switch(operation_mode){
+ case StartUp:
+ if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){ //ch7;自動・手動切り替え ch8;自動操縦モード切替
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = RightLoop;
+ pc.printf("Goto RightLoop mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ break;
+
+ case RightLoop:
+ if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = LeftLoop;
+ pc.printf("Goto LeftLoop mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ UpdateTargetAngle_Rightloop(targetAngle);
+
+ break;
+
+ case LeftLoop:
+ if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = GoStraight;
+ pc.printf("Goto GoStraight mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ UpdateTargetAngle_Leftloop(targetAngle);
+ break;
+
+ case GoStraight:
+ if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = Moebius;
+ pc.printf("Goto Moebius mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ UpdateTargetAngle_GoStraight(targetAngle);
+ break;
+
+ case Moebius:
+ if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = Glide;
+ pc.printf("Goto Glide mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ UpdateTargetAngle_Moebius(targetAngle);
+ break;
+
+ case Glide:
+ if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = BombwithPC;
+ pc.printf("Goto Bombing mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ UpdateTargetAngle_Glide(targetAngle);
+ break;
+
+ case BombwithPC:
+ if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){
+ count_op++;
+ if(count_op > changeModeCount){
+ operation_mode = RightLoop;
+ pc.printf("Goto RightLoop mode\r\n");
+ count_op = 0;
+ }
+ }else count_op = 0;
+ Take_off_and_landing(targetAngle);
+ break;
+
+ default:
+ operation_mode = StartUp;
+ break;
+ }
+#endif
+
+ if(CheckSW_Up(Ch7)){
+ output_status = Auto;
+ led1 = 1;
+ }else{
+ output_status = Manual;
+ led1 = 0;
+ }
+}
+
+int GetParameter(FILE *fp, const char *paramName,char parameter[]){
+ int i=0, j=0;
+ int strmax = 200;
+ char str[strmax];
+
+ rewind(fp); //ファイル位置を先頭に
+ while(1){
+ if (fgets(str, strmax, fp) == NULL) {
+ return 0;
+ }
+ if (!strncmp(str, paramName, strlen(paramName))) {
+ while (str[i++] != '=') {}
+ while (str[i] != '\n') {
+ parameter[j++] = str[i++];
+ }
+ parameter[j] = '\0';
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+//sdによる設定
+int SetOptions(float *g_kpELE, float *g_kiELE, float *g_kdELE,
+ float *g_kpRUD, float *g_kiRUD, float *g_kdRUD,
+ float *g_rightloopROLL, float *g_rightloopPITCH,
+ float *g_leftloopROLL, float *g_leftloopPITCH,
+ float *g_gostraightROLL, float *g_gostraightPITCH,
+ float *g_takeoffTHR, float *g_loopTHR,
+ float *g_rightloopROLLshort, float *g_rightloopPITCHshort,
+ float *g_leftloopROLLshort, float *g_leftloopPITCHshort,
+ float *g_glideloopROLL, float *g_glideloopPITCH
+ ){
+
+ pc.printf("SDsetup start.\r\n");
+
+ FILE *fp;
+ char parameter[30]; //文字列渡す用の配列
+ int SDerrorcount = 0; //取得できなかった数を返す
+ const char *paramNames[] = {
+ "KP_ELEVATOR",
+ "KI_ELEVATOR",
+ "KD_ELEVATOR",
+ "KP_RUDDER",
+ "KI_RUDDER",
+ "KD_RUDDER",
+ "RIGHTLOOP_ROLL",
+ "RIGHTLOOP_PITCH",
+ "LEFTLOOP_ROLL",
+ "LEFTLOOP_PITCH",
+ "GOSTRAIGHT_ROLL",
+ "GOSTRAIGHT_PITCH",
+ "TAKEOFF_THR_RATE",
+ "LOOP_THR_RATE",
+ "RIGHTLOOP_ROLL_SHORT",
+ "RIGHTLOOP_PITCH_SHORT",
+ "LEFTLOOP_ROLL_SHORT",
+ "LEFTLOOP_PITCH_SHORT",
+ "AUTOGLIDE_ROLL",
+ "AUTOGLIDE PITCH"
+ };
+
+ fp = fopen("/sd/option.txt","r");
+
+ if(fp != NULL){ //開けたら
+ pc.printf("File was openned.\r\n");
+ if(GetParameter(fp,paramNames[0],parameter)) *g_kpELE = atof(parameter);
+ else{ *g_kpELE = KP_ELE;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[1],parameter)) *g_kiELE = atof(parameter);
+ else{ *g_kiELE = KI_ELE;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[2],parameter)) *g_kdELE = atof(parameter);
+ else{ *g_kdELE = KD_ELE;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[3],parameter)) *g_kpRUD = atof(parameter);
+ else{ *g_kpRUD = KP_RUD;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[4],parameter)) *g_kiRUD = atof(parameter);
+ else{ *g_kiRUD = KI_RUD;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[5],parameter)) *g_kdRUD = atof(parameter);
+ else{ *g_kdRUD = KD_RUD;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[6],parameter)) *g_rightloopROLL = atof(parameter);
+ else{ *g_rightloopROLL = RIGHT_ROLL;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[7],parameter)) *g_rightloopPITCH = atof(parameter);
+ else{ *g_rightloopPITCH = RIGHT_PITCH;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[8],parameter)) *g_leftloopROLL = atof(parameter);
+ else{ *g_leftloopROLL = LEFT_ROLL;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[9],parameter)) *g_leftloopPITCH = atof(parameter);
+ else{ *g_leftloopPITCH = LEFT_PITCH;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[10],parameter)) *g_gostraightROLL = atof(parameter);
+ else{ *g_gostraightROLL = STRAIGHT_ROLL;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[11],parameter)) *g_gostraightPITCH = atof(parameter);
+ else{ *g_gostraightPITCH = STRAIGHT_PITCH;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[12],parameter)) *g_takeoffTHR = atof(parameter);
+ else{ *g_takeoffTHR = TAKEOFF_THR;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[13],parameter)) *g_loopTHR = atof(parameter);
+ else{ *g_loopTHR = LOOP_THR;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[14],parameter)) *g_rightloopROLLshort = atof(parameter);
+ else{ *g_rightloopROLLshort = RIGHT_ROLL_SHORT;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[15],parameter)) *g_rightloopPITCHshort = atof(parameter);
+ else{ *g_rightloopPITCHshort = RIGHT_PITCH_SHORT;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[16],parameter)) *g_leftloopROLLshort = atof(parameter);
+ else{ *g_leftloopROLLshort = LEFT_ROLL_SHORT;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[17],parameter)) *g_leftloopPITCHshort = atof(parameter);
+ else{ *g_leftloopPITCHshort = LEFT_PITCH_SHORT;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[18],parameter)) *g_glideloopROLL = atof(parameter);
+ else{ *g_glideloopROLL = GLIDE_ROLL;
+ SDerrorcount++;
+ }
+ if(GetParameter(fp,paramNames[19],parameter)) *g_glideloopPITCH = atof(parameter);
+ else{ *g_glideloopPITCH = GLIDE_PITCH;
+ SDerrorcount++;
+ }
+ fclose(fp);
+
+ }else{ //ファイルがなかったら
+ pc.printf("fp was null.\r\n");
+ *g_kpELE = KP_ELE;
+ *g_kiELE = KI_ELE;
+ *g_kdELE = KD_ELE;
+ *g_kpRUD = KP_RUD;
+ *g_kiRUD = KI_RUD;
+ *g_kdRUD = KD_RUD;
+ *g_rightloopROLL = RIGHT_ROLL;
+ *g_rightloopPITCH = RIGHT_PITCH;
+ *g_leftloopROLL = LEFT_ROLL;
+ *g_leftloopPITCH = LEFT_PITCH;
+ *g_gostraightROLL = STRAIGHT_ROLL;
+ *g_gostraightPITCH = STRAIGHT_PITCH;
+ *g_takeoffTHR = TAKEOFF_THR;
+ *g_loopTHR = LOOP_THR;
+ SDerrorcount = -1;
+ }
+ pc.printf("SDsetup finished.\r\n");
+ if(SDerrorcount == 0) pc.printf("setting option is success\r\n");
+ else if(SDerrorcount == -1) pc.printf("ERROR 1. cannot open option\r\n");
+ else if(SDerrorcount > 0) pc.printf("ERROR 2. reading parameter is failed[%d]\r\n",SDerrorcount);
+
+ pc.printf("kpELE = %f, kiELE = %f, kdELE = %f\r\n", *g_kpRUD, *g_kiRUD, *g_kdRUD);
+ pc.printf("kpRUD = %f, kiRUD = %f, kdRUD = %f\r\n", *g_kpELE, *g_kiELE, *g_kdELE);
+ pc.printf("rightloopROLL = %f, rightloopPITCH = %f\r\n", *g_rightloopROLL, *g_rightloopPITCH);
+ pc.printf("leftloopROLL = %f, g_leftloopPITCH = %f\r\n", *g_leftloopROLL, *g_leftloopPITCH);
+ pc.printf("gostraightROLL = %f, g_gostraightPITCH = %f\r\n", *g_gostraightROLL, *g_gostraightPITCH);
+ pc.printf("g_takeoffTHR = %f, g_loopTHR = %f\r\n", *g_takeoffTHR, *g_loopTHR);
+ pc.printf("rightloopROLLshort = %f, rightloopPITCHshort = %f\r\n", *g_rightloopROLLshort, *g_rightloopPITCHshort);
+ pc.printf("leftloopROLLshort = %f, g_leftloopPITCHshort = %f\r\n", *g_leftloopROLLshort, *g_leftloopPITCHshort);
+ pc.printf("glideROLL = %f, glidePITCH = %f\r\n", *g_glideloopROLL, *g_glideloopPITCH);
+
+ return SDerrorcount;
+}
+
+void CalculateControlValue(float targetAngle[3], float controlValue[3]){
+ static int t_last;
+ int t_now;
+ float dt;
+
+ t_now = t.read_us();
+ dt = (float)((t_now - t_last)/1000000.0f) ;
+ t_last = t_now;
+
+ controlValue[ROLL] = pid_RUD.calcPID(nowAngle[ROLL], targetAngle[ROLL], dt);
+ controlValue[PITCH] = pid_ELE.calcPID(nowAngle[PITCH], targetAngle[PITCH], dt);
+}
+
+void UpdateAutoPWM(float controlValue[3]){
+ int16_t addpwm[2]; //-500~500
+ addpwm[PITCH] = (float)GAIN_CONTROLVALUE_TO_PWM * controlValue[PITCH]; //センサ:機首下げ正 レバー:機首上げ正
+ addpwm[ROLL] = (float)GAIN_CONTROLVALUE_TO_PWM * controlValue[ROLL]; //センサ:右回転正(8月13日時点;左回転が正!) レバー:右回転正
+
+ autopwm[ELE] = trimpwm[ELE] + reverce[ELE] * addpwm[PITCH];
+ autopwm[RUD] = trimpwm[RUD] + reverce[RUD] * addpwm[ROLL];
+ //autopwm[THR] = oldTHR;
+
+ autopwm[ELE] = ThresholdMaxMin(autopwm[ELE], maxpwm[ELE], minpwm[ELE]);
+ autopwm[RUD] = ThresholdMaxMin(autopwm[RUD], maxpwm[RUD], minpwm[RUD]);
+}
+
+inline float CalcRatio(float value, float trim, float limit){
+ return (value - trim) / (limit - trim);
+}
+
+bool CheckSW_Up(Channel ch){
+ if(SWITCH_CHECK < sbus.manualpwm[ch]){
+ return true;
+ }else{
+ return false;
+ }
+}
+
+int16_t ThresholdMaxMin(int16_t value, int16_t max, int16_t min){
+ if(value > max) return max;
+ if(value < min) return min;
+ return value;
+}
+
+inline int16_t SetTHRinRatio(float ratio){
+ return minpwm[THR] + (int16_t)(2 * lengthdivpwm * ratio);
+}
+
+/*---SBUS割り込み処理---*/
+
+//udate_Inputで抽出したpwmデータを整形して各変数に代入する。(マニュアルモード)
+//各stabiGylo関数で算出したpwmを各変数に代入する(自動モード)
+void Update_PWM()
+{
+ static int16_t pwm[6];
+ static int16_t temppwm[6]={trimpwm[0],trimpwm[1],trimpwm[2],trimpwm[3],trimpwm[4],trimpwm[5]};
+ if(sbus.flg_ch_update == true){
+ switch(output_status){ //マニュアルモード,自動モード,自動着陸もモードを切替
+ case Manual:
+ for(uint8_t i=0;i<6;i++){
+ pwm[i] = sbus.manualpwm[i];
+ pc.printf("%d ,",pwm[i]);
+ }
+ oldTHR = sbus.manualpwm[THR];
+ //pc.printf("update_manual\r\n");
+ break;
+
+ case Auto:
+ pwm[AIL_R] = autopwm[AIL_R]; //sbus.manualpwm[AIL];
+ pwm[ELE] = autopwm[ELE];
+ pwm[THR] = autopwm[THR];
+ pwm[RUD] = autopwm[RUD];
+ pwm[DROP] = autopwm[DROP];
+ pwm[AIL_L] = autopwm[AIL_L];
+ //pc.printf("update_auto\r\n");
+ break;
+
+ default:
+ for(uint8_t i=0;i<6;i++){
+ pwm[i] = sbus.manualpwm[i];
+ } //pc.printf("update_manual\r\n");
+ break;
+ }
+ for(uint8_t i=0;i<6;i++){
+ if(pwm[i]<1000 || pwm[i]>2000) pwm[i]=temppwm[i];
+ temppwm[i]=pwm[i];
+ }
+ }else{
+ pc.printf("0\r\n");
+ }
+ sbus.flg_ch_update = false;
+ Output_PWM(pwm);
+}
+
+
+//pwmをサーボに出力。
+void Output_PWM(int16_t pwm[5])
+{
+ servo1.pulsewidth_us(pwm[0]);
+ servo2.pulsewidth_us(pwm[1]);
+ servo3.pulsewidth_us(pwm[2]);
+ servo4.pulsewidth_us(pwm[3]);
+ servo5.pulsewidth_us(pwm[4]);
+ servo6.pulsewidth_us(pwm[5]);
+
+}
+
+void ResetTrim(){
+ for(uint8_t i=0; i<6; i++){ //i=4から書き換え_投下サーボは入ってない模様
+ trimpwm[i] = sbus.manualpwm[i];
+ }
+ pc.printf("reset PWM trim\r\n");
+}
+
+
+void SensingMPU(){
+ //static int16_t deltaT = 0, t_start = 0;
+ //t_start = t.read_us();
+
+ float rpy[3] = {0}, oldrpy[3] = {0};
+ static uint16_t count_changeRPY = 0;
+ static bool flg_checkoutlier = false;
+ NVIC_DisableIRQ(USART1_IRQn);
+ NVIC_DisableIRQ(USART2_IRQn);
+ NVIC_DisableIRQ(TIM5_IRQn);
+ NVIC_DisableIRQ(EXTI0_IRQn);
+ NVIC_DisableIRQ(EXTI9_5_IRQn);
+
+ mpu6050.getRollPitchYaw_Skipper(rpy);
+
+ NVIC_EnableIRQ(USART1_IRQn);
+ NVIC_EnableIRQ(USART2_IRQn);
+ NVIC_EnableIRQ(TIM5_IRQn);
+ NVIC_EnableIRQ(EXTI0_IRQn);
+ NVIC_EnableIRQ(EXTI9_5_IRQn);
+
+
+ //外れ値対策
+ for(uint8_t i=0; i<3; i++) rpy[i] *= 180.0f/PI;
+ rpy[ROLL] -= FirstROLL;
+ rpy[PITCH] -= FirstPITCH;
+ rpy[YAW] -= FirstYAW;
+
+ for(uint8_t i=0; i<3; i++) {if(rpy[i] < nowAngle[i]-10 || rpy[i] > nowAngle[i]+10) {flg_checkoutlier = true;}}
+ if(!flg_checkoutlier || count_changeRPY >= 2){
+ for(uint8_t i=0; i<3; i++){
+ nowAngle[i] = (rpy[i] + nowAngle[i])/2.0f; //2つの移動平均
+ }
+ count_changeRPY = 0;
+ }else count_changeRPY++;
+ flg_checkoutlier = false;
+
+}
+
+float TranslateNewYaw(float beforeYaw, float newzeroYaw){
+ float newYaw = beforeYaw - newzeroYaw;
+
+ if(newYaw<-180.0f) newYaw += 360.0f;
+ else if(newYaw>180.0f) newYaw -= 360.0f;
+ return newYaw;
+}
+
+
+void getSF_Serial(){
+
+ static char SFbuf[16];
+ static int bufcounter=0;
+
+ SFbuf[bufcounter]=pc.getc();
+ if(SFbuf[0]=='S'&&bufcounter<5) bufcounter++;
+
+ if(bufcounter==5 && SFbuf[4]=='F'){
+ g_landingcommand = SFbuf[1];
+ if(g_landingcommand=='Y')g_SerialTargetYAW = ConvertByteintoFloat(SFbuf[2], SFbuf[3]);
+ bufcounter = 0;
+ memset(SFbuf, 0, strlen(SFbuf));
+ pc.printf("command = %c, commandYAW = %f\r\n", g_landingcommand, g_SerialTargetYAW);
+ }
+ else if(bufcounter>=5 && g_buf[4]!='F'){
+ pc.printf("Communication Falsed.\r\n");
+ bufcounter = 0;
+ }
+ }
+
+float ConvertByteintoFloat(char high, char low){
+
+ //int16_t intvalue = (int16_t)high*256 + (int16_t)low;
+ int16_t intvalue = (int16_t)(((int16_t)high << 8) | low); // Turn the MSB and LSB into a signed 16-bit value
+ float floatvalue = (float)intvalue;
+ return floatvalue;
+}
+
+
+//超音波割り込み
+void UpdateDist(){
+ g_distance = usensor.get_dist_cm();
+ usensor.start();
+}
+
+//8の字旋回
+void UpdateTargetAngle_Moebius(float targetAngle[3]){
+ static uint8_t RotateCounter=0;
+ static bool flg_setInStartAuto = false;
+ static float FirstYAW_Moebius = 0.0;
+ float newYaw_Moebius;
+
+ if(!flg_setInStartAuto && CheckSW_Up(Ch7)){
+ FirstYAW_Moebius = nowAngle[YAW];
+ RotateCounter = 0;
+ flg_setInStartAuto = true;
+ }else if(!CheckSW_Up(Ch7)){
+ flg_setInStartAuto = false;
+ led2 = 0;
+ }
+
+ newYaw_Moebius = TranslateNewYaw(nowAngle[YAW], FirstYAW_Moebius);
+
+ if(RotateCounter == 0 && newYaw_Moebius >90.0 && newYaw_Moebius < 180.0) {RotateCounter++; led2 = 1; pc.printf("Rotate 90\r\n");}
+ if(RotateCounter == 1 && newYaw_Moebius >-180.0 && newYaw_Moebius < -90.0) {RotateCounter++; led2 = 0; pc.printf("Rotate 180\r\n");}
+ if(RotateCounter == 2 && newYaw_Moebius >-90.0 && newYaw_Moebius < 10.0f) {RotateCounter++; led2 = 1; pc.printf("Rotate 270\r\n");}
+ if(RotateCounter == 3 && newYaw_Moebius >20.0 && newYaw_Moebius < 180.0f) {RotateCounter++; led2 = 0; pc.printf("Change Rotate direction\r\n");}
+
+
+ if(RotateCounter <= 3) UpdateTargetAngle_Rightloop_short(targetAngle);
+ else UpdateTargetAngle_Leftloop_short(targetAngle); //左旋回
+
+}
+
+//自動滑空
+void UpdateTargetAngle_Glide(float targetAngle[3]){
+ static int THRcount = 0;
+ static int t_start = 0;
+ static bool flg_tstart = false;
+ int t_diff = 0;
+
+ targetAngle[ROLL] = g_glideloopROLL;
+ targetAngle[PITCH] = g_glideloopPITCH;
+
+ //時間計測開始設定
+ if(!flg_tstart && CheckSW_Up(Ch7)){
+ t_start = t.read();
+ flg_tstart = true;
+ pc.printf("timer start\r\n");
+ }else if(flg_tstart && !CheckSW_Up(Ch7)){
+ t_start = 0;
+ flg_tstart = false;
+ }
+
+ //フラグが偽であれば計測は行わない
+ if(flg_tstart){
+ t_diff = t.read() - t_start;
+ //一定高度or15秒でled点灯
+ if((g_distance<200 && g_distance>0) || t_diff > 15){
+ led2 = 1;
+ //pc.printf("Call [Stop!] calling!\r\n");
+ }
+ }else{
+ t_diff = 0;
+ led2 = 0;
+ }
+
+ if(t_diff > 18){
+ autopwm[THR] = SetTHRinRatio(0.5);
+ }else{
+ if(g_distance<150 && g_distance>0 ){
+ THRcount++;
+ if(THRcount>5){
+ autopwm[THR] = SetTHRinRatio(0.5);
+ //pc.printf("throttle ON\r\n");
+ }
+ }else{
+ autopwm[THR] = 1180;
+ THRcount = 0;
+ }
+ }
+}
+
+//離陸-投下-着陸一連
+void Take_off_and_landing(float targetAngle[3]){
+ if(!CheckSW_Up(Ch7)) bombing_mode = Takeoff;
+
+ switch(bombing_mode){
+ case Takeoff:
+ static bool flg_setFirstYaw = false;
+ static int TakeoffCount = 0;
+
+ if(!flg_setFirstYaw && CheckSW_Up(Ch7)){
+ FirstYAW = nowAngle[YAW];
+ flg_setFirstYaw = true;
+ }else if(flg_setFirstYaw && !CheckSW_Up(Ch7)){
+ flg_setFirstYaw = false;
+ }
+
+ UpdateTargetAngle_Takeoff(targetAngle);
+
+ if(g_distance>150) TakeoffCount++;
+ else TakeoffCount = 0;
+ if(TakeoffCount>5){
+ autopwm[THR] = 1180+320*2*0.5;
+ pc.printf("Now go to Approach mode!!");
+ bombing_mode = Approach;
+ }
+ break;
+ /*
+ case Chicken:
+ break;
+ */
+ case Transition:
+ static int ApproachCount = 0;
+ targetAngle[YAW]=180.0;
+ int Judge = Rotate(targetAngle, g_SerialTargetYAW);
+
+ if(Judge==0) ApproachCount++;
+ if(ApproachCount>5) bombing_mode = Approach;
+ break;
+
+ case Approach:
+ UpdateTargetAngle_Approach(targetAngle);
+ break;
+
+ default:
+ bombing_mode = Takeoff;
+ break;
+ }
+}
+
+//離陸モード
+void UpdateTargetAngle_Takeoff(float targetAngle[3]){
+ //pc.printf("%d \r\n",g_distance);
+ targetAngle[ROLL] = g_gostraightROLL;
+ targetAngle[PITCH] = g_loopTHR;
+ autopwm[THR] = SetTHRinRatio(g_takeoffTHR); //0.7;スロットルの割合
+}
+
+//ヨーを目標値にして許容角度になるまで水平旋回
+int Rotate(float targetAngle[3], float TargetYAW){
+ float diffYaw = TranslateNewYaw(TargetYAW, nowAngle[YAW]);
+
+ if(diffYaw > LIMIT_STRAIGHT_YAW){
+ /*
+ if(diffYaw > THRESHOLD_TURNINGRADIUS_YAW) UpdateTargetAngle_Rightloop_short(targetAngle);
+ else UpdateTargetAngle_Rightloop(targetAngle);
+ */
+ UpdateTargetAngle_Rightloop_short(targetAngle);
+ return 1;
+ }else if(diffYaw < -LIMIT_STRAIGHT_YAW){
+ UpdateTargetAngle_Leftloop_short(targetAngle);
+ /*
+ if(diffYaw < -THRESHOLD_TURNINGRADIUS_YAW) UpdateTargetAngle_Leftloop_short(targetAngle);
+ else UpdateTargetAngle_Leftloop(targetAngle);
+ */
+ return 1;
+ }else{
+ UpdateTargetAngle_GoStraight(targetAngle);
+ return 0;
+ }
+}
+
+//チキラー投下
+void Chicken_Drop(){
+ if(CheckSW_Up(Ch7)){
+ autopwm[DROP] = 1512;
+ pc.printf("Bombed!\r\n");
+ RerurnChickenServo1.attach(&ReturnChickenServo1, 3);
+ //operation_mode = Approach;
+ //buzzer = 0;
+ pc.printf("Goto LeftLoop mode\r\n");
+ }
+}
+
+void ReturnChickenServo1(){
+ autopwm[DROP] = 1344;
+ pc.printf("first reverse\r\n");
+ RerurnChickenServo2.attach(&ReturnChickenServo2, 1);
+}
+
+void ReturnChickenServo2(){
+ autopwm[DROP] = 1392;
+ pc.printf("second reverse\r\n");
+}
+
+//着陸モード(PCからの指令に従う)
+void UpdateTargetAngle_Approach(float targetAngle[3]){
+ pc.putc(g_buf[0]);
+ switch(g_buf[0]){
+ case 'R': //右旋回セヨ
+ UpdateTargetAngle_Rightloop(targetAngle);
+ break;
+
+ case 'L': //左旋回セヨ
+ UpdateTargetAngle_Leftloop(targetAngle);
+ break;
+
+ case 'G': //直進セヨ
+ UpdateTargetAngle_GoStraight(targetAngle);
+ break;
+
+ case 'Y': //指定ノヨー方向ニ移動セヨ
+ Rotate(targetAngle, g_SerialTargetYAW);
+ break;
+
+ case 'B': //ブザーヲ鳴ラセ
+ //buzzer = 1;
+ break;
+
+ case 'D': //物資ヲ落トセ
+ Chicken_Drop();
+ break;
+
+ case 'C': //停止セヨ
+ targetAngle[ROLL] = 0.0;
+ targetAngle[PITCH] = -3.0;
+ autopwm[THR] = minpwm[THR];
+ break;
+ }
+}
+
+void checkHeight(float targetAngle[3]){
+
+ static int targetHeight = 200;
+
+ if(g_distance < targetHeight + ALLOWHEIGHT){
+ UpdateTargetAngle_NoseUP(targetAngle);
+ if(CheckSW_Up(Ch7)) led2 = 1;
+ }
+ else if(g_distance > targetHeight - ALLOWHEIGHT){
+ UpdateTargetAngle_NoseDOWN(targetAngle);
+ if(CheckSW_Up(Ch7)) led2 = 1;
+ }
+ else led2=0;
+}
+
+void UpdateTargetAngle_NoseUP(float targetAngle[3]){
+
+ //targetAngle[PITCH] += 2.0f;
+ //if(nowAngle[PITCH]<targetAngle[PITCH]) autopwm[THR] = SetTHRinRatio(0.6);
+ autopwm[THR] = SetTHRinRatio(g_loopTHR+0.05);
+ //pc.printf("nose UP");
+}
+
+void UpdateTargetAngle_NoseDOWN(float targetAngle[3]){
+
+ //targetAngle[PITCH] -= 2.0f;
+ autopwm[THR] = SetTHRinRatio(g_loopTHR-0.05);
+ //pc.printf("nose DOWN");
+}
+
+//直進
+void UpdateTargetAngle_GoStraight(float targetAngle[3]){
+
+ targetAngle[ROLL] = g_gostraightROLL;
+ targetAngle[PITCH] = g_gostraightPITCH;
+ autopwm[THR] = SetTHRinRatio(g_loopTHR);
+
+ //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
+}
+
+//右旋回
+void UpdateTargetAngle_Rightloop(float targetAngle[3]){ //右旋回
+
+ targetAngle[ROLL] = g_rightloopROLL;
+ targetAngle[PITCH] = g_rightloopPITCH ;
+ autopwm[THR] = SetTHRinRatio(g_loopTHR);
+ //checkHeight(targetAngle);
+ //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
+}
+
+void UpdateTargetAngle_Rightloop_short(float targetAngle[3]){ //右旋回
+
+ targetAngle[ROLL] = g_rightloopROLLshort;
+ targetAngle[PITCH] = g_rightloopPITCHshort;
+ autopwm[THR] = SetTHRinRatio(g_loopTHR);
+
+
+ //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
+}
+
+//左旋回
+void UpdateTargetAngle_Leftloop(float targetAngle[3]){
+
+ targetAngle[ROLL] = g_leftloopROLL;
+ targetAngle[PITCH] = g_leftloopPITCH;
+ autopwm[THR] = SetTHRinRatio(g_loopTHR);
+ //checkHeight(targetAngle);
+
+ //printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
+}
+
+void UpdateTargetAngle_Leftloop_short(float targetAngle[3]){
+
+ targetAngle[ROLL] = g_leftloopROLLshort;
+ targetAngle[PITCH] = g_leftloopPITCHshort;
+ autopwm[THR] = SetTHRinRatio(g_loopTHR);
+
+ //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
+}
+
+//デバッグ用
+void DebugPrint(){
+ /*
+ static int16_t deltaT = 0, t_start = 0;
+ deltaT = t.read_u2s() - t_start;
+ pc.printf("t:%d us, ",deltaT);
+ pc.printf("\r\n");
+ t_start = t.read_us();
+ */
+ //for(uint8_t i=0; i<8; i++) pc.printf("%d ",sbus.manualpwm[i]);
+ //for(uint8_t i=1; i<4; i++) pc.printf("%d ",sbus.manualpwm[i]);
+ //pc.printf("\r\n");
+ for(uint8_t i=0; i<3; i++) pc.printf("%3.2f\t",nowAngle[i]);
+ //for(uint8_t i=0; i<2; i++) pc.printf("%3.2f\t",nowAngle[i]); //ロール、ピッチのみ 小数点以下2ケタ
+ //pc.printf("%d\t",autopwm[ELE]); pc.printf("%d\t",autopwm[RUD]);
+ //pc.printf("%d",g_distance);
+
+ //pc.printf("Mode: %c: ",g_buf[0]);
+ //if(g_buf[0] == 'Y') pc.printf(" %3.1f",g_SerialTargetYAW);
+ pc.printf("\r\n");
+}
\ No newline at end of file
