Dependencies:   mbed BufferedSerial ConfigFile

Committer:
skyyoungsik
Date:
Wed Nov 28 13:06:23 2018 +0000
Revision:
1:9530746906b6
Parent:
0:3473b92e991e
test1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
skyyoungsik 0:3473b92e991e 1 #include "mbed.h"
skyyoungsik 0:3473b92e991e 2 #include <math.h>
skyyoungsik 1:9530746906b6 3 #include "Function.h"
skyyoungsik 0:3473b92e991e 4 #include "millis.h"
skyyoungsik 0:3473b92e991e 5 #include "SPATIAL.h"
skyyoungsik 0:3473b92e991e 6 #include "ROBOFRIEN_GUI.h"
skyyoungsik 0:3473b92e991e 7 #include "ROBOFRIEN_LED.h"
skyyoungsik 0:3473b92e991e 8 #include "ROBOFRIEN_MOTOR.h"
skyyoungsik 0:3473b92e991e 9 #include "ROBOFRIEN_PID.h"
skyyoungsik 1:9530746906b6 10 #include "ROBOFRIEN_SBUS.h"
skyyoungsik 1:9530746906b6 11 #include "ROBOFRIEN_BAT.h"
skyyoungsik 1:9530746906b6 12
skyyoungsik 1:9530746906b6 13
skyyoungsik 1:9530746906b6 14
skyyoungsik 1:9530746906b6 15 /* ************ USER INTERFACE ************** */
skyyoungsik 1:9530746906b6 16 #define SENSOR_WAIT 1
skyyoungsik 1:9530746906b6 17 #define THROTTLE_MAX 7000
skyyoungsik 1:9530746906b6 18 #define THROTTLE_BASE 4000
skyyoungsik 1:9530746906b6 19 #define THROTTLE_MIN 3000
skyyoungsik 1:9530746906b6 20 #define THROTTLE_CONTROL_LIMIT 1500
skyyoungsik 1:9530746906b6 21 #define LIMIT_PROGRESS_VELOCITY 10
skyyoungsik 1:9530746906b6 22 #define LIMIT_UP_VELOCITY 4
skyyoungsik 1:9530746906b6 23 #define LIMIT_DOWN_VELOCITY 2
skyyoungsik 1:9530746906b6 24 #define LIMIT_PLANE_VEL_INTEG 5 // Degree
skyyoungsik 1:9530746906b6 25 #define LIMIT_VERTICAL_VEL_INTEG 500
skyyoungsik 1:9530746906b6 26 /* ******************************************* */
skyyoungsik 1:9530746906b6 27
skyyoungsik 1:9530746906b6 28 /* *************************** */
skyyoungsik 1:9530746906b6 29 // AutoFlight Sequence
skyyoungsik 1:9530746906b6 30 // 0. Wait to Start
skyyoungsik 1:9530746906b6 31 // 1. Take Off (10m From Ground)
skyyoungsik 1:9530746906b6 32 // 2. Heading Align to Marker
skyyoungsik 1:9530746906b6 33 // 3. Go to Point ( Pitching & Altitude )
skyyoungsik 1:9530746906b6 34 // 4. Hovering
skyyoungsik 1:9530746906b6 35 // 5. Landing
skyyoungsik 1:9530746906b6 36 #define WAIT_TO_START 1
skyyoungsik 1:9530746906b6 37 #define TAKE_OFF 2
skyyoungsik 1:9530746906b6 38 #define HEADING_ALIGN 3
skyyoungsik 1:9530746906b6 39 #define GO_TO_POINT 4
skyyoungsik 1:9530746906b6 40 #define CHECK_MARKER 5
skyyoungsik 1:9530746906b6 41 #define LANDING 6
skyyoungsik 1:9530746906b6 42 #define WAIT 7
skyyoungsik 1:9530746906b6 43 int ex_AUTOFLIGHT_SEQUENCE;
skyyoungsik 1:9530746906b6 44 int AUTOFLIGHT_SEQUENCE = WAIT_TO_START;
skyyoungsik 1:9530746906b6 45 unsigned long AUTOFLIGHT_TIME_CNT;
skyyoungsik 1:9530746906b6 46 /* *************************** */
skyyoungsik 0:3473b92e991e 47
skyyoungsik 0:3473b92e991e 48 ROBOFRIEN_GUI GUI;
skyyoungsik 0:3473b92e991e 49 ROBOFRIEN_LED LED;
skyyoungsik 0:3473b92e991e 50 ROBOFRIEN_MOTOR MOTOR;
skyyoungsik 0:3473b92e991e 51 ROBOFRIEN_PID PID;
skyyoungsik 0:3473b92e991e 52 SPATIAL SPATIAL;
skyyoungsik 1:9530746906b6 53 ROBOFRIEN_SBUS SBUS;
skyyoungsik 1:9530746906b6 54 ROBOFRIEN_BAT BAT;
skyyoungsik 0:3473b92e991e 55
skyyoungsik 0:3473b92e991e 56
skyyoungsik 0:3473b92e991e 57 void GUI_UPDATE();
skyyoungsik 1:9530746906b6 58 void ALGORITHM();
skyyoungsik 1:9530746906b6 59 void ANGLE_CONTROL(double [3]);
skyyoungsik 1:9530746906b6 60 void PLANE_VEL_CONTROL(double, double, double *, double *);
skyyoungsik 1:9530746906b6 61 void VERTICAL_VEL_CONTROL(double, double *);
skyyoungsik 1:9530746906b6 62 void VEL_INTEG_RESET();
skyyoungsik 1:9530746906b6 63 float DEG_TO_METER(float , float , float , float );
skyyoungsik 0:3473b92e991e 64
skyyoungsik 1:9530746906b6 65 unsigned long millis_100hz, millis_10hz, millis_200hz;
skyyoungsik 1:9530746906b6 66 double want_Angle[3];
skyyoungsik 1:9530746906b6 67 double want_Rate[3];
skyyoungsik 1:9530746906b6 68 double err_Angle[3];
skyyoungsik 1:9530746906b6 69 double THROTTLE_VALUE;
skyyoungsik 1:9530746906b6 70 double want_LNG, want_LAT, want_ALT;
skyyoungsik 1:9530746906b6 71 int main()
skyyoungsik 0:3473b92e991e 72 {
skyyoungsik 1:9530746906b6 73 LED.Init();
skyyoungsik 1:9530746906b6 74 MOTOR.Init();
skyyoungsik 1:9530746906b6 75 wait(1);
skyyoungsik 1:9530746906b6 76 SPATIAL.Init(SENSOR_WAIT);
skyyoungsik 1:9530746906b6 77 SBUS.Init();
skyyoungsik 1:9530746906b6 78 PID.Init();
skyyoungsik 1:9530746906b6 79 GUI.Init();
skyyoungsik 1:9530746906b6 80 BAT.Init(3); // 3cell
skyyoungsik 1:9530746906b6 81 millisStart();
skyyoungsik 1:9530746906b6 82 while (1) {
skyyoungsik 1:9530746906b6 83 GUI.pc_rx_update();
skyyoungsik 1:9530746906b6 84 GUI.TRANS_BUFFER();
skyyoungsik 1:9530746906b6 85 LED.update(GUI.headlight_period, GUI.headlight_dutyrate, GUI.sidelight_period, GUI.sidelight_dutyrate );
skyyoungsik 1:9530746906b6 86 SPATIAL.SPATIAL_RECEIVE();
skyyoungsik 1:9530746906b6 87 SBUS.update();
skyyoungsik 1:9530746906b6 88 if ( ( millis() - millis_200hz ) > 5 ) {
skyyoungsik 1:9530746906b6 89 millis_200hz = millis();
skyyoungsik 1:9530746906b6 90 if ( SPATIAL.SPATIAL_STABLE() == false ) {
skyyoungsik 1:9530746906b6 91 LED.ALARM(1);
skyyoungsik 1:9530746906b6 92 if (GUI.button[0] == true) {
skyyoungsik 1:9530746906b6 93 ALGORITHM();
skyyoungsik 1:9530746906b6 94 MOTOR.update();
skyyoungsik 1:9530746906b6 95 } else {
skyyoungsik 1:9530746906b6 96 MOTOR.OFF();
skyyoungsik 0:3473b92e991e 97 }
skyyoungsik 1:9530746906b6 98 } else {
skyyoungsik 1:9530746906b6 99 LED.ALARM(0);
skyyoungsik 1:9530746906b6 100 ALGORITHM();
skyyoungsik 1:9530746906b6 101 MOTOR.update();
skyyoungsik 1:9530746906b6 102 }
skyyoungsik 0:3473b92e991e 103 }
skyyoungsik 1:9530746906b6 104
skyyoungsik 1:9530746906b6 105 if ( (millis() - millis_10hz ) > 100) {
skyyoungsik 1:9530746906b6 106 millis_10hz = millis();
skyyoungsik 1:9530746906b6 107 GUI_UPDATE();
skyyoungsik 1:9530746906b6 108 GUI.Trans();
skyyoungsik 1:9530746906b6 109 GUI.SET_DATA();
skyyoungsik 1:9530746906b6 110 }
skyyoungsik 1:9530746906b6 111 if (GUI.rx_bool() == true) {
skyyoungsik 1:9530746906b6 112 GUI.Refresh();
skyyoungsik 1:9530746906b6 113 }
skyyoungsik 1:9530746906b6 114 }
skyyoungsik 0:3473b92e991e 115 }
skyyoungsik 0:3473b92e991e 116
skyyoungsik 1:9530746906b6 117
skyyoungsik 1:9530746906b6 118 uint8_t EX_CONTROLLER_STATE;
skyyoungsik 1:9530746906b6 119 bool MOTOR_FORCED_OFF_BOOL = true;
skyyoungsik 1:9530746906b6 120 void ALGORITHM() { // 200 Hz //
skyyoungsik 1:9530746906b6 121 /* *************************** */
skyyoungsik 1:9530746906b6 122 /* ******* Want Angle ******** */
skyyoungsik 1:9530746906b6 123 /* *************************** */
skyyoungsik 1:9530746906b6 124 switch (SBUS.CONTROLLER_STATE) {
skyyoungsik 1:9530746906b6 125 case SIGNAL_OFF: {
skyyoungsik 1:9530746906b6 126 want_Angle[0] = 0; want_Angle[1] = 0; want_Angle[2] = SPATIAL.YAW;
skyyoungsik 1:9530746906b6 127 THROTTLE_VALUE = 0;
skyyoungsik 1:9530746906b6 128 } break;
skyyoungsik 1:9530746906b6 129 case MOTOR_OFF: {
skyyoungsik 1:9530746906b6 130 MOTOR_FORCED_OFF_BOOL = true;
skyyoungsik 1:9530746906b6 131 want_Angle[0] = 0; want_Angle[1] = 0; want_Angle[2] = SPATIAL.YAW;
skyyoungsik 1:9530746906b6 132 THROTTLE_VALUE = 0;
skyyoungsik 1:9530746906b6 133 } break;
skyyoungsik 1:9530746906b6 134 case MANUAL_ATTITUDE: {
skyyoungsik 1:9530746906b6 135 MOTOR_FORCED_OFF_BOOL = false;
skyyoungsik 1:9530746906b6 136 want_Angle[0] = ((SBUS.channel[0]) / 1000.0) * GUI.limit_rollx100 / 100.0; // Want Angle : Roll
skyyoungsik 1:9530746906b6 137 want_Angle[1] = ((SBUS.channel[1]) / 1000.0) * GUI.limit_pitchx100 / 100.0; // Want Angle : Pitch
skyyoungsik 1:9530746906b6 138 if ( (SBUS.channel[3] > 3) | (SBUS.channel[3] < -3) ) want_Angle[2] += ((SBUS.channel[3]) / 2000.0) / 200.0 * (GUI.limit_yaw_ratex100 / 100.0);
skyyoungsik 1:9530746906b6 139 if ( want_Angle[2] > 360) want_Angle[2] -= 360;
skyyoungsik 1:9530746906b6 140 else if ( want_Angle[2] < 0) want_Angle[2] += 360;
skyyoungsik 1:9530746906b6 141 THROTTLE_VALUE = ((SBUS.channel[2] + 1000) / 2000.0 * THROTTLE_MAX);
skyyoungsik 1:9530746906b6 142 } break;
skyyoungsik 1:9530746906b6 143 case MANUAL_VELOCITY ... AUTO_FLIGHT: { // MANUAL_VELOCITY(3), MANUAL_POSITION(4), AUTO_FLIGHT(5) //
skyyoungsik 1:9530746906b6 144 //// [LNG]Longitude Up : East Face, Longitude Down : West Face
skyyoungsik 1:9530746906b6 145 //// [LAT]Latitude Up : North Face, Latitude Down : South Face
skyyoungsik 1:9530746906b6 146 if ( EX_CONTROLLER_STATE != SBUS.CONTROLLER_STATE) {
skyyoungsik 1:9530746906b6 147 want_LAT = SPATIAL.LATITUDE;
skyyoungsik 1:9530746906b6 148 want_LNG = SPATIAL.LONGITUDE;
skyyoungsik 1:9530746906b6 149 want_ALT = SPATIAL.HEIGHT;
skyyoungsik 1:9530746906b6 150 AUTOFLIGHT_TIME_CNT = 0;
skyyoungsik 1:9530746906b6 151 }
skyyoungsik 1:9530746906b6 152
skyyoungsik 1:9530746906b6 153 double want_Vel[3]; // VEL[0] = X-axis, VEL[1] = Y-axis, VEL[2] = Z-axis
skyyoungsik 1:9530746906b6 154 if ( SBUS.CONTROLLER_STATE == MANUAL_VELOCITY ) {
skyyoungsik 1:9530746906b6 155 /* ******************************************************* */
skyyoungsik 1:9530746906b6 156 /* ****************** MANUAL VELOCITY ******************** */
skyyoungsik 1:9530746906b6 157 /* ******************************************************* */
skyyoungsik 1:9530746906b6 158 MOTOR_FORCED_OFF_BOOL = false;
skyyoungsik 1:9530746906b6 159 want_Vel[0] = -(SBUS.channel[1] / 1000.0) * LIMIT_PROGRESS_VELOCITY;
skyyoungsik 1:9530746906b6 160 want_Vel[1] = (SBUS.channel[0] / 1000.0) * LIMIT_PROGRESS_VELOCITY;
skyyoungsik 1:9530746906b6 161 if ( SBUS.channel[2] >= 0 ) want_Vel[2] = (SBUS.channel[2] / 1000.0) * LIMIT_UP_VELOCITY;
skyyoungsik 1:9530746906b6 162 else if ( SBUS.channel[2] < 0 ) want_Vel[2] = (SBUS.channel[2] / 1000.0) * LIMIT_DOWN_VELOCITY;
skyyoungsik 1:9530746906b6 163 if ( (SBUS.channel[3] > 3) | (SBUS.channel[3] < -3) ) want_Angle[2] += ((SBUS.channel[3]) / 2000.0) / 200.0 * (GUI.limit_yaw_ratex100 / 100.0);
skyyoungsik 1:9530746906b6 164
skyyoungsik 1:9530746906b6 165 } else {
skyyoungsik 1:9530746906b6 166 if ( SBUS.CONTROLLER_STATE == MANUAL_POSITION ) {
skyyoungsik 1:9530746906b6 167 /* ******************************************************* */
skyyoungsik 1:9530746906b6 168 /* ****************** MANUAL POSITION ******************** */
skyyoungsik 1:9530746906b6 169 /* ******************************************************* */
skyyoungsik 1:9530746906b6 170 MOTOR_FORCED_OFF_BOOL = false;
skyyoungsik 1:9530746906b6 171 double del_pos[3];
skyyoungsik 1:9530746906b6 172 del_pos[0] = (-(SBUS.channel[1] / 1000.0) * LIMIT_PROGRESS_VELOCITY); //divided by time
skyyoungsik 1:9530746906b6 173 del_pos[1] = ((SBUS.channel[0] / 1000.0) * LIMIT_PROGRESS_VELOCITY); //divided by time
skyyoungsik 1:9530746906b6 174 if (SBUS.channel[2] >= 0) del_pos[2] = ((SBUS.channel[2] / 1000.0) * LIMIT_UP_VELOCITY); //divided by time
skyyoungsik 1:9530746906b6 175 else if (SBUS.channel[2] < 0) del_pos[2] = ((SBUS.channel[2] / 1000.0) * LIMIT_DOWN_VELOCITY); //divided by time
skyyoungsik 1:9530746906b6 176
skyyoungsik 1:9530746906b6 177 double NED_del_pos[3];
skyyoungsik 1:9530746906b6 178 NED_del_pos[0] = del_pos[0] * cos(SPATIAL.YAW * M_PI / 180.0) - del_pos[1] * sin(SPATIAL.YAW * M_PI / 180.0);
skyyoungsik 1:9530746906b6 179 NED_del_pos[1] = del_pos[0] * sin(SPATIAL.YAW * M_PI / 180.0) + del_pos[1] * cos(SPATIAL.YAW * M_PI / 180.0);
skyyoungsik 1:9530746906b6 180
skyyoungsik 1:9530746906b6 181 if( (SBUS.channel[1] < 5) & (SBUS.channel[1] > -5) ) {}
skyyoungsik 1:9530746906b6 182 else want_LAT += (NED_del_pos[0] / 200.0) / 110574.0;
skyyoungsik 1:9530746906b6 183 if( (SBUS.channel[0] < 5) & (SBUS.channel[0] > -5) ) {}
skyyoungsik 1:9530746906b6 184 else want_LNG += (NED_del_pos[1] / 200.0) / 111320.0;
skyyoungsik 1:9530746906b6 185 if( (SBUS.channel[2] < 10) & (SBUS.channel[2] > -10) ) {}
skyyoungsik 1:9530746906b6 186 else want_ALT += (del_pos[2] / 200.0);
skyyoungsik 1:9530746906b6 187
skyyoungsik 1:9530746906b6 188 if ( (SBUS.channel[3] > 3) | (SBUS.channel[3] < -3) ) want_Angle[2] += ((SBUS.channel[3]) / 2000.0) / 200.0 * (GUI.limit_yaw_ratex100 / 100.0);
skyyoungsik 1:9530746906b6 189
skyyoungsik 1:9530746906b6 190 } else if ( SBUS.CONTROLLER_STATE == AUTO_FLIGHT) {
skyyoungsik 1:9530746906b6 191 /* ******************************************************* */
skyyoungsik 1:9530746906b6 192 /* ****************** AUTO FLIGHT ******************** */
skyyoungsik 1:9530746906b6 193 /* ******************************************************* */
skyyoungsik 1:9530746906b6 194 if (AUTOFLIGHT_SEQUENCE != ex_AUTOFLIGHT_SEQUENCE) {
skyyoungsik 1:9530746906b6 195 AUTOFLIGHT_TIME_CNT = 0;
skyyoungsik 1:9530746906b6 196 }
skyyoungsik 1:9530746906b6 197 ex_AUTOFLIGHT_SEQUENCE = AUTOFLIGHT_SEQUENCE;
skyyoungsik 1:9530746906b6 198 AUTOFLIGHT_TIME_CNT ++;
skyyoungsik 1:9530746906b6 199 if ( AUTOFLIGHT_SEQUENCE == WAIT_TO_START) MOTOR_FORCED_OFF_BOOL = true;
skyyoungsik 1:9530746906b6 200 else MOTOR_FORCED_OFF_BOOL = false;
skyyoungsik 1:9530746906b6 201 switch (AUTOFLIGHT_SEQUENCE) {
skyyoungsik 1:9530746906b6 202 case WAIT_TO_START: {
skyyoungsik 1:9530746906b6 203 if ( AUTOFLIGHT_TIME_CNT > (5 * 200) ) AUTOFLIGHT_SEQUENCE = TAKE_OFF;
skyyoungsik 1:9530746906b6 204 want_LAT = SPATIAL.LATITUDE;
skyyoungsik 1:9530746906b6 205 want_LNG = SPATIAL.LONGITUDE;
skyyoungsik 1:9530746906b6 206 want_ALT = SPATIAL.HEIGHT;
skyyoungsik 1:9530746906b6 207 want_Angle[2] = SPATIAL.YAW;
skyyoungsik 1:9530746906b6 208 break;
skyyoungsik 1:9530746906b6 209 }
skyyoungsik 1:9530746906b6 210 case TAKE_OFF: { /// Take off [ Ground --> 5m ] in 1m/s
skyyoungsik 1:9530746906b6 211 want_ALT += (1 / 200.0);
skyyoungsik 1:9530746906b6 212 if ( AUTOFLIGHT_TIME_CNT > (5 * 200)) {
skyyoungsik 1:9530746906b6 213 AUTOFLIGHT_SEQUENCE = CHECK_MARKER;
skyyoungsik 1:9530746906b6 214 GUI.CurrentMarker = 1;
skyyoungsik 1:9530746906b6 215 }
skyyoungsik 1:9530746906b6 216 break;
skyyoungsik 1:9530746906b6 217 }
skyyoungsik 1:9530746906b6 218 case HEADING_ALIGN: {
skyyoungsik 1:9530746906b6 219 float BEARING_ANGLE = bearing( SPATIAL.LATITUDE, SPATIAL.LONGITUDE, (float)(GUI.Marker_Lat[GUI.CurrentMarker - 1]) / 1000000.0, (float)(GUI.Marker_Lng[GUI.CurrentMarker - 1]) / 1000000.0);
skyyoungsik 1:9530746906b6 220 want_Angle[2] = BEARING_ANGLE;
skyyoungsik 1:9530746906b6 221 if ( ABSOL((BEARING_ANGLE - SPATIAL.YAW)) < 5 ) {
skyyoungsik 1:9530746906b6 222 if (AUTOFLIGHT_TIME_CNT > (3 * 200) ) AUTOFLIGHT_SEQUENCE = GO_TO_POINT;
skyyoungsik 1:9530746906b6 223 } else AUTOFLIGHT_TIME_CNT = 0;
skyyoungsik 1:9530746906b6 224 // GUI.DEBUGx100[0] = (BEARING_ANGLE + 100) * 100;
skyyoungsik 1:9530746906b6 225 // GUI.DEBUGx100[1] = (ABSOL((BEARING_ANGLE - SPATIAL.YAW)) + 100) * 100;
skyyoungsik 1:9530746906b6 226 break;
skyyoungsik 1:9530746906b6 227 }
skyyoungsik 1:9530746906b6 228 case GO_TO_POINT: {
skyyoungsik 1:9530746906b6 229 float Target_LAT = GUI.Marker_Lat[GUI.CurrentMarker - 1] / 1000000.0;
skyyoungsik 1:9530746906b6 230 float Target_LNG = GUI.Marker_Lng[GUI.CurrentMarker - 1] / 1000000.0;
skyyoungsik 1:9530746906b6 231 float Target_ALT = GUI.Marker_Alt[GUI.CurrentMarker - 1] / 100.0;
skyyoungsik 1:9530746906b6 232 // float BEARING_ANGLE = bearing( SPATIAL.LATITUDE, SPATIAL.LONGITUDE, (float)(GUI.Marker_Lat[GUI.CurrentMarker - 1]) / 1000000.0, (float)(GUI.Marker_Lng[GUI.CurrentMarker - 1]) / 1000000.0);
skyyoungsik 1:9530746906b6 233 // want_Angle[2] = BEARING_ANGLE;
skyyoungsik 1:9530746906b6 234 // 1ms ++
skyyoungsik 1:9530746906b6 235 /* if(Target_LAT > want_LAT) want_LAT += (1.5/200.0)/110574.0;
skyyoungsik 1:9530746906b6 236 else want_LAT -= (1/200.0)/110574.0;
skyyoungsik 1:9530746906b6 237 if(Target_LNG > want_LNG) want_LNG += (1.5/200.0)/111320.0;
skyyoungsik 1:9530746906b6 238 else want_LNG -= (1/200.0)/111320.0;
skyyoungsik 1:9530746906b6 239 if(Target_ALT > want_ALT) want_ALT += (1/200.0);
skyyoungsik 1:9530746906b6 240 else want_ALT -= (1/200.0);
skyyoungsik 1:9530746906b6 241 */
skyyoungsik 1:9530746906b6 242 // want_LAT = Target_LAT;
skyyoungsik 1:9530746906b6 243 // want_LNG = Target_LNG;
skyyoungsik 1:9530746906b6 244 // want_ALT = Target_ALT;
skyyoungsik 1:9530746906b6 245 if(Target_LAT > want_LAT) want_LAT += (LIMIT_PROGRESS_VELOCITY/200.0)/110574.0;
skyyoungsik 1:9530746906b6 246 else want_LAT -= (LIMIT_PROGRESS_VELOCITY/200.0)/110574.0;
skyyoungsik 1:9530746906b6 247 if(Target_LNG > want_LNG) want_LNG += (LIMIT_PROGRESS_VELOCITY/200.0)/111320.0;
skyyoungsik 1:9530746906b6 248 else want_LNG -= (LIMIT_PROGRESS_VELOCITY/200.0)/111320.0;
skyyoungsik 1:9530746906b6 249 if(Target_ALT > want_ALT) want_ALT += (LIMIT_UP_VELOCITY/200.0);
skyyoungsik 1:9530746906b6 250 else want_ALT -= (LIMIT_DOWN_VELOCITY/200.0);
skyyoungsik 1:9530746906b6 251
skyyoungsik 1:9530746906b6 252 bool escape_bool = false;
skyyoungsik 1:9530746906b6 253 float POSITION_DISTANCE;
skyyoungsik 1:9530746906b6 254 float HEIGHT_DISTANCE;
skyyoungsik 1:9530746906b6 255 POSITION_DISTANCE = DEG_TO_METER( want_LAT, want_LNG, SPATIAL.LATITUDE, SPATIAL.LONGITUDE );
skyyoungsik 1:9530746906b6 256 HEIGHT_DISTANCE = sqrt( (want_ALT - SPATIAL.HEIGHT) * (want_ALT - SPATIAL.HEIGHT) );
skyyoungsik 1:9530746906b6 257 if ( ( POSITION_DISTANCE < 5 ) & (HEIGHT_DISTANCE < 5)) { // 5m
skyyoungsik 1:9530746906b6 258 if ( (POSITION_DISTANCE < 3) ) { // 3m
skyyoungsik 1:9530746906b6 259 if ( (POSITION_DISTANCE < 1) ) { // 1m
skyyoungsik 1:9530746906b6 260 ///////////// Target in the 1m OK !!!! /////////////////
skyyoungsik 1:9530746906b6 261 escape_bool = true;
skyyoungsik 1:9530746906b6 262 /////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 263 }
skyyoungsik 1:9530746906b6 264 else {
skyyoungsik 1:9530746906b6 265 if ( AUTOFLIGHT_TIME_CNT > (5 * 200) ) escape_bool = true; // Time Out //
skyyoungsik 1:9530746906b6 266 }
skyyoungsik 1:9530746906b6 267 }
skyyoungsik 1:9530746906b6 268 else {
skyyoungsik 1:9530746906b6 269 if ( AUTOFLIGHT_TIME_CNT > (5 * 200) ) escape_bool = true; // Time Out //
skyyoungsik 1:9530746906b6 270 }
skyyoungsik 1:9530746906b6 271 }
skyyoungsik 1:9530746906b6 272 else {
skyyoungsik 1:9530746906b6 273 AUTOFLIGHT_TIME_CNT = 0;
skyyoungsik 1:9530746906b6 274 }
skyyoungsik 1:9530746906b6 275 if ( escape_bool == true) {
skyyoungsik 1:9530746906b6 276 AUTOFLIGHT_SEQUENCE = CHECK_MARKER;
skyyoungsik 1:9530746906b6 277 GUI.CurrentMarker ++;
skyyoungsik 1:9530746906b6 278 }
skyyoungsik 1:9530746906b6 279 // 1m내외
skyyoungsik 1:9530746906b6 280 break;
skyyoungsik 1:9530746906b6 281 }
skyyoungsik 1:9530746906b6 282 case CHECK_MARKER: {
skyyoungsik 1:9530746906b6 283 if (AUTOFLIGHT_TIME_CNT > (3 * 200) ) {
skyyoungsik 1:9530746906b6 284 if ( (GUI.Marker_Lat[GUI.CurrentMarker - 1] != 0) & (GUI.Marker_Lng[GUI.CurrentMarker - 1] != 0) ) {
skyyoungsik 1:9530746906b6 285 AUTOFLIGHT_SEQUENCE = HEADING_ALIGN;
skyyoungsik 1:9530746906b6 286 } else {
skyyoungsik 1:9530746906b6 287 AUTOFLIGHT_SEQUENCE = LANDING;
skyyoungsik 1:9530746906b6 288 }
skyyoungsik 1:9530746906b6 289 }
skyyoungsik 1:9530746906b6 290 break;
skyyoungsik 1:9530746906b6 291 }
skyyoungsik 1:9530746906b6 292 case LANDING: {
skyyoungsik 1:9530746906b6 293 want_ALT -= (0.5 / 200.0); // 0.5m/s
skyyoungsik 1:9530746906b6 294 break;
skyyoungsik 1:9530746906b6 295 }
skyyoungsik 1:9530746906b6 296 case WAIT: {
skyyoungsik 1:9530746906b6 297 break;
skyyoungsik 1:9530746906b6 298 }
skyyoungsik 1:9530746906b6 299 }
skyyoungsik 1:9530746906b6 300 }
skyyoungsik 1:9530746906b6 301 double NED_want_vel[3];
skyyoungsik 1:9530746906b6 302 NED_want_vel[0] = (want_LAT - SPATIAL.LATITUDE) * 110574.0 * (GUI.gain_px100[4] / 100.0);
skyyoungsik 1:9530746906b6 303 NED_want_vel[1] = (want_LNG - SPATIAL.LONGITUDE) * 111320.0 * (GUI.gain_px100[5] / 100.0);
skyyoungsik 1:9530746906b6 304 NED_want_vel[2] = (want_ALT - SPATIAL.HEIGHT) * (GUI.gain_px100[6] / 100.0);
skyyoungsik 1:9530746906b6 305
skyyoungsik 1:9530746906b6 306 want_Vel[0] = NED_want_vel[0] * cos(SPATIAL.YAW * M_PI / 180.0) + NED_want_vel[1] * sin(SPATIAL.YAW * M_PI / 180.0);
skyyoungsik 1:9530746906b6 307 want_Vel[1] = NED_want_vel[1] * cos(SPATIAL.YAW * M_PI / 180.0) - NED_want_vel[0] * sin(SPATIAL.YAW * M_PI / 180.0);
skyyoungsik 1:9530746906b6 308 want_Vel[2] = NED_want_vel[2];
skyyoungsik 1:9530746906b6 309
skyyoungsik 1:9530746906b6 310 float LIMIT_PROGRESS_VELOCITY_CALCULATED;
skyyoungsik 1:9530746906b6 311 float POSITION_DISTANCE = DEG_TO_METER( want_LAT, want_LNG, SPATIAL.LATITUDE, SPATIAL.LONGITUDE );
skyyoungsik 1:9530746906b6 312 if ( POSITION_DISTANCE < 20) LIMIT_PROGRESS_VELOCITY_CALCULATED = (0.04 * POSITION_DISTANCE + 0.2) * LIMIT_PROGRESS_VELOCITY;
skyyoungsik 1:9530746906b6 313 else LIMIT_PROGRESS_VELOCITY_CALCULATED = LIMIT_PROGRESS_VELOCITY;
skyyoungsik 1:9530746906b6 314
skyyoungsik 1:9530746906b6 315 want_Vel[0] = MIN_MAX(want_Vel[0], -LIMIT_PROGRESS_VELOCITY_CALCULATED, LIMIT_PROGRESS_VELOCITY_CALCULATED);
skyyoungsik 1:9530746906b6 316 want_Vel[1] = MIN_MAX(want_Vel[1], -LIMIT_PROGRESS_VELOCITY_CALCULATED, LIMIT_PROGRESS_VELOCITY_CALCULATED);
skyyoungsik 1:9530746906b6 317 if (want_Vel[2] >= 0) want_Vel[2] = MIN_MAX(want_Vel[2], -LIMIT_UP_VELOCITY, LIMIT_UP_VELOCITY);
skyyoungsik 1:9530746906b6 318 else if (want_Vel[2] < 0) want_Vel[2] = MIN_MAX(want_Vel[2], -LIMIT_DOWN_VELOCITY, LIMIT_DOWN_VELOCITY);
skyyoungsik 1:9530746906b6 319
skyyoungsik 1:9530746906b6 320 }
skyyoungsik 1:9530746906b6 321
skyyoungsik 1:9530746906b6 322 /* ********** WANT ANGLE GENERATE ************ */
skyyoungsik 1:9530746906b6 323 PLANE_VEL_CONTROL(want_Vel[0], want_Vel[1], &want_Angle[0], &want_Angle[1]);
skyyoungsik 1:9530746906b6 324 if ( want_Angle[2] > 360) want_Angle[2] -= 360;
skyyoungsik 1:9530746906b6 325 else if ( want_Angle[2] < 0) want_Angle[2] += 360;
skyyoungsik 1:9530746906b6 326
skyyoungsik 1:9530746906b6 327 /* ********** THROTTLE VALUE GENRATE ************* */
skyyoungsik 1:9530746906b6 328 VERTICAL_VEL_CONTROL(want_Vel[2], &THROTTLE_VALUE);
skyyoungsik 1:9530746906b6 329 if (MOTOR_FORCED_OFF_BOOL == true) THROTTLE_VALUE = 0;
skyyoungsik 1:9530746906b6 330
skyyoungsik 1:9530746906b6 331 } break;
skyyoungsik 1:9530746906b6 332 }
skyyoungsik 1:9530746906b6 333 EX_CONTROLLER_STATE = SBUS.CONTROLLER_STATE;
skyyoungsik 1:9530746906b6 334 /* ************************** */
skyyoungsik 1:9530746906b6 335 /* ******* Want Rate ******** */
skyyoungsik 1:9530746906b6 336 /* ************************** */
skyyoungsik 1:9530746906b6 337 ANGLE_CONTROL( want_Angle );
skyyoungsik 1:9530746906b6 338
skyyoungsik 1:9530746906b6 339 if (GUI.DPN_Info == 0) {
skyyoungsik 1:9530746906b6 340 if ( SBUS.CONTROLLER_STATE <= MOTOR_OFF) {
skyyoungsik 1:9530746906b6 341 PID.RAT_INTEGER_RESET();
skyyoungsik 1:9530746906b6 342 VEL_INTEG_RESET();
skyyoungsik 1:9530746906b6 343 for (int i = 0; i < 6; i++) MOTOR.Value[i] = 0;
skyyoungsik 1:9530746906b6 344 } else {
skyyoungsik 1:9530746906b6 345 int MOTOR_MIN_DEADZONE = 5;
skyyoungsik 1:9530746906b6 346 for (int i = 0; i < 5; i++) {
skyyoungsik 1:9530746906b6 347 if (GUI.motor_min[i] > 100)GUI.motor_min[i] = 100;
skyyoungsik 1:9530746906b6 348 }
skyyoungsik 1:9530746906b6 349 MOTOR.Value[0] = (GUI.motor_min[0] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE + PID.output_Data[0] / 2.0 - PID.output_Data[1] * 0.87 - PID.output_Data[2];
skyyoungsik 1:9530746906b6 350 MOTOR.Value[1] = (GUI.motor_min[1] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE + PID.output_Data[0] + 0 + PID.output_Data[2];
skyyoungsik 1:9530746906b6 351 MOTOR.Value[2] = (GUI.motor_min[2] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE + PID.output_Data[0] / 2.0 + PID.output_Data[1] * 0.87 - PID.output_Data[2];
skyyoungsik 1:9530746906b6 352 MOTOR.Value[3] = (GUI.motor_min[3] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE - PID.output_Data[0] / 2.0 + PID.output_Data[1] * 0.87 + PID.output_Data[2];
skyyoungsik 1:9530746906b6 353 MOTOR.Value[4] = (GUI.motor_min[4] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE - PID.output_Data[0] + 0 - PID.output_Data[2];
skyyoungsik 1:9530746906b6 354 MOTOR.Value[5] = (GUI.motor_min[5] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE - PID.output_Data[0] / 2.0 - PID.output_Data[1] * 0.87 + PID.output_Data[2];
skyyoungsik 1:9530746906b6 355 for (int i = 0; i < 6; i++) {
skyyoungsik 1:9530746906b6 356 if ( MOTOR.Value[i] < ((GUI.motor_min[0] - MOTOR_MIN_DEADZONE) * 10 ) ) {
skyyoungsik 1:9530746906b6 357 MOTOR.Value[i] = ((GUI.motor_min[0] - MOTOR_MIN_DEADZONE) * 10 );
skyyoungsik 1:9530746906b6 358 }
skyyoungsik 1:9530746906b6 359 }
skyyoungsik 0:3473b92e991e 360 }
skyyoungsik 1:9530746906b6 361 } else if (GUI.DPN_Info == 4) {
skyyoungsik 1:9530746906b6 362 MOTOR.Value[0] = (float)GUI.pwm_info[0] * 10;
skyyoungsik 1:9530746906b6 363 MOTOR.Value[1] = (float)GUI.pwm_info[1] * 10;
skyyoungsik 1:9530746906b6 364 MOTOR.Value[2] = (float)GUI.pwm_info[2] * 10;
skyyoungsik 1:9530746906b6 365 MOTOR.Value[3] = (float)GUI.pwm_info[3] * 10;
skyyoungsik 1:9530746906b6 366 MOTOR.Value[4] = (float)GUI.pwm_info[4] * 10;
skyyoungsik 1:9530746906b6 367 MOTOR.Value[5] = (float)GUI.pwm_info[5] * 10;
skyyoungsik 1:9530746906b6 368 }
skyyoungsik 1:9530746906b6 369 }
skyyoungsik 1:9530746906b6 370
skyyoungsik 1:9530746906b6 371
skyyoungsik 1:9530746906b6 372 void GUI_UPDATE() {
skyyoungsik 1:9530746906b6 373 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 374 //////////////////////////////////////////// [M/S] Mode and State ///////////////////////////////////////
skyyoungsik 1:9530746906b6 375 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 376 /* ************ MODE 1 ************* */
skyyoungsik 1:9530746906b6 377 GUI.Mode1 = SBUS.CONTROLLER_STATE;
skyyoungsik 1:9530746906b6 378 GUI.Alarm = !SPATIAL.SPATIAL_STABLE();
skyyoungsik 1:9530746906b6 379
skyyoungsik 1:9530746906b6 380 GUI.MissionState = AUTOFLIGHT_SEQUENCE;
skyyoungsik 1:9530746906b6 381 GUI.Bat1 = BAT.update();
skyyoungsik 1:9530746906b6 382 // [ Button State & Home Point Chksum & Marker Chksum ] is change automatically in "ROBOFRIEN_GUI.cpp" //
skyyoungsik 1:9530746906b6 383 // You Can not change this setting, just use it ///
skyyoungsik 1:9530746906b6 384 if (GUI.button[0] == true) {}
skyyoungsik 1:9530746906b6 385 else {}
skyyoungsik 1:9530746906b6 386 if (GUI.button[1] == true) {
skyyoungsik 1:9530746906b6 387 AUTOFLIGHT_SEQUENCE = WAIT_TO_START;
skyyoungsik 1:9530746906b6 388 }
skyyoungsik 1:9530746906b6 389 else {}
skyyoungsik 1:9530746906b6 390 if (GUI.button[2] == true) {}
skyyoungsik 1:9530746906b6 391 else {}
skyyoungsik 1:9530746906b6 392 if (GUI.button[3] == true) {}
skyyoungsik 1:9530746906b6 393 else {}
skyyoungsik 1:9530746906b6 394 if (GUI.button[4] == true) {}
skyyoungsik 1:9530746906b6 395 else {}
skyyoungsik 1:9530746906b6 396
skyyoungsik 1:9530746906b6 397 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 398 //////////////////////////////////////////////// [GPS] GPS //////////////////////////////////////////////
skyyoungsik 1:9530746906b6 399 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 400 GUI.utc_time = SPATIAL.UNIX_TIME;
skyyoungsik 1:9530746906b6 401 GUI.latitude = (SPATIAL.LATITUDE * 1000000);
skyyoungsik 1:9530746906b6 402 GUI.longitude = (SPATIAL.LONGITUDE * 1000000);
skyyoungsik 1:9530746906b6 403 GUI.altitude = SPATIAL.HEIGHT * 100;
skyyoungsik 1:9530746906b6 404 GUI.SatNum = SPATIAL.SATELLITE_NUM;
skyyoungsik 1:9530746906b6 405 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 406 ///////////////////////////////////////////////// AHRS //////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 407 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 408 GUI.rollx100 = (SPATIAL.ROLL * 100);
skyyoungsik 1:9530746906b6 409 GUI.pitchx100 = (SPATIAL.PITCH * 100);
skyyoungsik 1:9530746906b6 410 GUI.yawx100 = ((SPATIAL.YAW ) * 100);
skyyoungsik 1:9530746906b6 411 GUI.roll_ratex100 = SPATIAL.ROLL_RATE * 100;
skyyoungsik 1:9530746906b6 412 GUI.pitch_ratex100 = SPATIAL.PITCH_RATE * 100;
skyyoungsik 1:9530746906b6 413 GUI.yaw_ratex100 = SPATIAL.YAW_RATE * 100;
skyyoungsik 1:9530746906b6 414 GUI.VXx100 = SPATIAL.Vx * 100;
skyyoungsik 1:9530746906b6 415 GUI.VYx100 = SPATIAL.Vy * 100;
skyyoungsik 1:9530746906b6 416 GUI.VZx100 = SPATIAL.Vz * 100;
skyyoungsik 1:9530746906b6 417
skyyoungsik 1:9530746906b6 418 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 419 ////////////////////////////////////////////// [C/P] CAP/PWM ////////////////////////////////////////////
skyyoungsik 1:9530746906b6 420 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 421
skyyoungsik 1:9530746906b6 422 GUI.cap[0] = SBUS.channel[0] / 10.0;
skyyoungsik 1:9530746906b6 423 GUI.cap[1] = SBUS.channel[1] / 10.0;
skyyoungsik 1:9530746906b6 424 GUI.cap[2] = SBUS.channel[2] / 10.0;
skyyoungsik 1:9530746906b6 425 GUI.cap[3] = SBUS.channel[3] / 10.0;
skyyoungsik 1:9530746906b6 426 GUI.cap[4] = SBUS.channel[4] / 10.0;
skyyoungsik 1:9530746906b6 427 GUI.cap[5] = SBUS.channel[5] / 10.0;
skyyoungsik 1:9530746906b6 428 GUI.cap[6] = SBUS.channel[6] / 10.0;
skyyoungsik 1:9530746906b6 429 GUI.cap[7] = SBUS.channel[7] / 10.0;
skyyoungsik 1:9530746906b6 430
skyyoungsik 1:9530746906b6 431 GUI.pwm[0] = MOTOR.Value[0] / 100; // (0 ~ 10000) --> ( 0 ~ 100 )
skyyoungsik 1:9530746906b6 432 GUI.pwm[1] = MOTOR.Value[1] / 100; // (0 ~ 10000) --> ( 0 ~ 100 )
skyyoungsik 1:9530746906b6 433 GUI.pwm[2] = MOTOR.Value[2] / 100; // (0 ~ 10000) --> ( 0 ~ 100 )
skyyoungsik 1:9530746906b6 434 GUI.pwm[3] = MOTOR.Value[3] / 100; // (0 ~ 10000) --> ( 0 ~ 100 )
skyyoungsik 1:9530746906b6 435 GUI.pwm[4] = MOTOR.Value[4] / 100; // (0 ~ 10000) --> ( 0 ~ 100 )
skyyoungsik 1:9530746906b6 436 GUI.pwm[5] = MOTOR.Value[5] / 100; // (0 ~ 10000) --> ( 0 ~ 100 )
skyyoungsik 1:9530746906b6 437
skyyoungsik 1:9530746906b6 438 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 439 /////////////////////////////////////////// [E/D] Extra & Debug /////////////////////////////////////////
skyyoungsik 1:9530746906b6 440 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 441
skyyoungsik 1:9530746906b6 442 GUI.DEBUGx100[2] = (want_Angle[2] + 100) * 100;
skyyoungsik 1:9530746906b6 443 GUI.DEBUGx100[3] = GUI.Controller_Joystick[3];
skyyoungsik 1:9530746906b6 444 GUI.DEBUGx100[4] = GUI.Gimbal_Joystick[0];
skyyoungsik 1:9530746906b6 445 GUI.DEBUGx100[5] = GUI.Gimbal_Joystick[1];
skyyoungsik 1:9530746906b6 446 float PNU_RPM[2];
skyyoungsik 1:9530746906b6 447 PNU_RPM[0] = sin( millis() / 10000.0 ) * 10000;
skyyoungsik 1:9530746906b6 448 PNU_RPM[1] = cos( millis() / 10000.0 ) * 10000;
skyyoungsik 1:9530746906b6 449 GUI.DEBUGx100[6] = PNU_RPM[0];
skyyoungsik 1:9530746906b6 450 GUI.DEBUGx100[7] = PNU_RPM[1];
skyyoungsik 1:9530746906b6 451
skyyoungsik 1:9530746906b6 452 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 453 /////////////////////////////////////////// Configuration ///////////////////////////////////////////////
skyyoungsik 1:9530746906b6 454 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 455
skyyoungsik 1:9530746906b6 456 ///////////////////////////// -----------------DPN 1-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 457 // You can set the this value from "Config.h" ( EEPROM_MODEL_TYPE1, EEPROM_MODEL_TYPE2_UP, EEPROM_MODEL_TYPE2_DOWN ) //
skyyoungsik 1:9530746906b6 458
skyyoungsik 1:9530746906b6 459 ///////////////////////////// -----------------DPN 2-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 460 // You can set the this value from "Config.h" ( MODEL_INFO, FIRMWARE_INFO ) //
skyyoungsik 1:9530746906b6 461
skyyoungsik 1:9530746906b6 462 ///////////////////////////// -----------------DPN 3-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 463 /// You can set the original value of receiver to [raw_cap] with scale down ( -127 ~ 127 ) ///
skyyoungsik 1:9530746906b6 464 /// You can use the [cap_min[8], cap_neu[8], cap_max[8]] for calibration of RC receiver value //
skyyoungsik 1:9530746906b6 465
skyyoungsik 1:9530746906b6 466 ///////////////////////////// -----------------DPN 4-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 467 /// You can use the [pwm_info , motor_min[4]] for calibration of motor pwm value //
skyyoungsik 1:9530746906b6 468
skyyoungsik 1:9530746906b6 469 ///////////////////////////// -----------------DPN 5-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 470 /*
skyyoungsik 1:9530746906b6 471 LED.HeadlightPeriod = GUI.headlight_period;
skyyoungsik 1:9530746906b6 472 LED.HeadlightDutyrate = GUI.headlight_dutyrate;
skyyoungsik 1:9530746906b6 473 LED.SidelightPeriod = GUI.sidelight_period;
skyyoungsik 1:9530746906b6 474 LED.SidelightDutyrate = GUI.sidelight_dutyrate;
skyyoungsik 1:9530746906b6 475 */
skyyoungsik 1:9530746906b6 476 ///////////////////////////// -----------------DPN 6-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 477 /// You can set the original value of receiver to [raw_cap] with scale down ( -127 ~ 127 ) ///
skyyoungsik 1:9530746906b6 478 /// You can use the [cap_min[8], cap_neu[8], cap_max[8]] for calibration of RC receiver value //
skyyoungsik 1:9530746906b6 479 GUI.raw_cap[0] = (0 - 150) * 2;
skyyoungsik 1:9530746906b6 480 GUI.raw_cap[1] = (0 - 150) * 2;
skyyoungsik 1:9530746906b6 481 GUI.raw_cap[2] = (0 - 150) * 2;
skyyoungsik 1:9530746906b6 482 GUI.raw_cap[3] = (0 - 150) * 2;
skyyoungsik 1:9530746906b6 483 GUI.raw_cap[4] = (0 - 150) * 2;
skyyoungsik 1:9530746906b6 484 GUI.raw_cap[5] = (0 - 150) * 2;
skyyoungsik 1:9530746906b6 485 GUI.raw_cap[6] = 0;
skyyoungsik 1:9530746906b6 486 GUI.raw_cap[7] = 0;
skyyoungsik 1:9530746906b6 487
skyyoungsik 1:9530746906b6 488 if (GUI.attitude_configuration_bool == true) {
skyyoungsik 1:9530746906b6 489 GUI.attitude_configuration_bool = false;
skyyoungsik 1:9530746906b6 490 // You can calibration of attitude (Roll, Pitch) //
skyyoungsik 1:9530746906b6 491 // GUI.attitude_calibrate(accelData[0]*aRes,accelData[1]*aRes,(accelData[2]*aRes-1));
skyyoungsik 1:9530746906b6 492 }
skyyoungsik 1:9530746906b6 493 if (GUI.Compass_Calibration_Mode == 1) {
skyyoungsik 1:9530746906b6 494 // You can calibration of compass (Yaw)//
skyyoungsik 0:3473b92e991e 495 // if(ex_Compass_Calibration_Mode == 0){
skyyoungsik 1:9530746906b6 496 // magnetic_offset_reset();
skyyoungsik 0:3473b92e991e 497 // }else{
skyyoungsik 0:3473b92e991e 498 // //// calibrating ... /////
skyyoungsik 1:9530746906b6 499 // magnetic_calibration();
skyyoungsik 0:3473b92e991e 500 // }
skyyoungsik 1:9530746906b6 501 } else if (GUI.Compass_Calibration_Mode == 2) {
skyyoungsik 1:9530746906b6 502 // // You can finish the calibration of compass
skyyoungsik 0:3473b92e991e 503 // //// write to eeprom ////
skyyoungsik 0:3473b92e991e 504 // GUI.Compass_Calibration_Mode = 0;
skyyoungsik 1:9530746906b6 505 // GUI.write_compass_setting_to_eeprom();
skyyoungsik 1:9530746906b6 506 }
skyyoungsik 1:9530746906b6 507 else if (GUI.Compass_Calibration_Mode == 3) { // declination angle
skyyoungsik 1:9530746906b6 508 SPATIAL.DECLINATION_ANGLE = GUI.declination_angle;
skyyoungsik 1:9530746906b6 509 }
skyyoungsik 1:9530746906b6 510 // ex_Compass_Calibration_Mode = GUI.Compass_Calibration_Mode;
skyyoungsik 1:9530746906b6 511
skyyoungsik 1:9530746906b6 512 ///////////////////////////// -----------------DPN 7-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 513 /// You can use the [limit_rollx100, limit_pitchx100, limit_roll_ratex100, limit_pitch_ratex100, limit_yaw_ratex100] for limit the angle and angular velocity //
skyyoungsik 1:9530746906b6 514
skyyoungsik 1:9530746906b6 515 ///////////////////////////// -----------------DPN 8-------------------- ////////////////////////////////
skyyoungsik 1:9530746906b6 516 /// You can use the [gain_px100[20], gain_dx100[20], gain_ix100[20]] for gain tuning //
skyyoungsik 1:9530746906b6 517 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 518 //////////////////////////////////////////////// Refresh ////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 519 /////////////////////////////////////////////////////////////////////////////////////////////////////////
skyyoungsik 1:9530746906b6 520 // GUI.trans_flight_data(255, 0);
skyyoungsik 1:9530746906b6 521 GUI.pc_rx_update();
skyyoungsik 1:9530746906b6 522 }
skyyoungsik 1:9530746906b6 523
skyyoungsik 1:9530746906b6 524 void ANGLE_CONTROL(double IN_WANT_ANGLE[3]) {
skyyoungsik 1:9530746906b6 525 /* ********* MIN - MAX ************* */
skyyoungsik 1:9530746906b6 526 IN_WANT_ANGLE[0] = MIN_MAX(IN_WANT_ANGLE[0], -GUI.limit_rollx100 / 100.0, GUI.limit_rollx100 / 100.0 );
skyyoungsik 1:9530746906b6 527 IN_WANT_ANGLE[1] = MIN_MAX(IN_WANT_ANGLE[1], -GUI.limit_pitchx100 / 100.0, GUI.limit_pitchx100 / 100.0 );
skyyoungsik 1:9530746906b6 528 err_Angle[0] = IN_WANT_ANGLE[0] - SPATIAL.ROLL;
skyyoungsik 1:9530746906b6 529 err_Angle[1] = IN_WANT_ANGLE[1] - SPATIAL.PITCH;
skyyoungsik 1:9530746906b6 530 err_Angle[2] = IN_WANT_ANGLE[2] - SPATIAL.YAW;
skyyoungsik 1:9530746906b6 531 if (err_Angle[2] > 180) err_Angle[2] -= 360;
skyyoungsik 1:9530746906b6 532 else if (err_Angle[2] < -180) err_Angle[2] += 360;
skyyoungsik 1:9530746906b6 533 want_Rate[0] = err_Angle[0] * GUI.gain_px100[0] / 100.0; // Want Rate : Roll Rate
skyyoungsik 1:9530746906b6 534 want_Rate[1] = err_Angle[1] * GUI.gain_dx100[0] / 100.0; // Want Rate : Pitch Rate
skyyoungsik 1:9530746906b6 535 want_Rate[2] = err_Angle[2] * GUI.gain_ix100[0] / 100.0; // Want Rate : Yaw Rate
skyyoungsik 1:9530746906b6 536 want_Rate[0] = MIN_MAX(want_Rate[0], -GUI.limit_roll_ratex100 / 100.0, GUI.limit_roll_ratex100 / 100.0);
skyyoungsik 1:9530746906b6 537 want_Rate[1] = MIN_MAX(want_Rate[1], -GUI.limit_pitch_ratex100 / 100.0, GUI.limit_pitch_ratex100 / 100.0);
skyyoungsik 1:9530746906b6 538 want_Rate[2] = MIN_MAX(want_Rate[2], -GUI.limit_yaw_ratex100 / 100.0, GUI.limit_yaw_ratex100 / 100.0);
skyyoungsik 1:9530746906b6 539 PID.err_Rate[0] = (want_Rate[0] - SPATIAL.ROLL_RATE);
skyyoungsik 1:9530746906b6 540 PID.err_Rate[1] = (want_Rate[1] - SPATIAL.PITCH_RATE);
skyyoungsik 1:9530746906b6 541 PID.err_Rate[2] = (want_Rate[2] - SPATIAL.YAW_RATE);
skyyoungsik 1:9530746906b6 542 PID.RAT_KP[0] = -GUI.gain_px100[1] / 100.0;
skyyoungsik 1:9530746906b6 543 PID.RAT_KP[1] = -GUI.gain_px100[2] / 100.0;
skyyoungsik 1:9530746906b6 544 PID.RAT_KP[2] = -GUI.gain_px100[3] / 100.0;
skyyoungsik 1:9530746906b6 545 PID.RAT_KI[0] = -GUI.gain_ix100[1] / 100.0;
skyyoungsik 1:9530746906b6 546 PID.RAT_KI[1] = -GUI.gain_ix100[2] / 100.0;
skyyoungsik 1:9530746906b6 547 PID.RAT_KI[2] = -GUI.gain_ix100[3] / 100.0;
skyyoungsik 1:9530746906b6 548 PID.update();
skyyoungsik 0:3473b92e991e 549 }
skyyoungsik 1:9530746906b6 550
skyyoungsik 1:9530746906b6 551 double PLANE_VEL_INTEG[2];
skyyoungsik 1:9530746906b6 552 void PLANE_VEL_CONTROL(double IN_VEL_X, double IN_VEL_Y, double *OUTPUT_WANT_ROLL, double *OUTPUT_WANT_PITCH) {
skyyoungsik 1:9530746906b6 553 double err_Vel[2];
skyyoungsik 1:9530746906b6 554 err_Vel[0] = ( IN_VEL_X - SPATIAL.Vx );
skyyoungsik 1:9530746906b6 555 err_Vel[1] = ( IN_VEL_Y - SPATIAL.Vy );
skyyoungsik 1:9530746906b6 556 err_Vel[0] = MIN_MAX(err_Vel[0], -LIMIT_PROGRESS_VELOCITY, LIMIT_PROGRESS_VELOCITY);
skyyoungsik 1:9530746906b6 557 err_Vel[1] = MIN_MAX(err_Vel[1], -LIMIT_PROGRESS_VELOCITY, LIMIT_PROGRESS_VELOCITY);
skyyoungsik 1:9530746906b6 558 *OUTPUT_WANT_PITCH = -(err_Vel[0] * (GUI.gain_dx100[4] / 100.0));
skyyoungsik 1:9530746906b6 559 *OUTPUT_WANT_ROLL = +(err_Vel[1] * (GUI.gain_dx100[5] / 100.0));
skyyoungsik 1:9530746906b6 560
skyyoungsik 1:9530746906b6 561 /* ******** VEL PID - I **************** */
skyyoungsik 1:9530746906b6 562 PLANE_VEL_INTEG[0] -= (err_Vel[0]) * (GUI.gain_ix100[4] / 100.0);
skyyoungsik 1:9530746906b6 563 PLANE_VEL_INTEG[1] += (err_Vel[1]) * (GUI.gain_ix100[5] / 100.0);
skyyoungsik 1:9530746906b6 564 PLANE_VEL_INTEG[0] = MIN_MAX(PLANE_VEL_INTEG[0], -LIMIT_PLANE_VEL_INTEG, LIMIT_PLANE_VEL_INTEG);
skyyoungsik 1:9530746906b6 565 PLANE_VEL_INTEG[1] = MIN_MAX(PLANE_VEL_INTEG[1], -LIMIT_PLANE_VEL_INTEG, LIMIT_PLANE_VEL_INTEG);
skyyoungsik 1:9530746906b6 566 *OUTPUT_WANT_PITCH += PLANE_VEL_INTEG[0];
skyyoungsik 1:9530746906b6 567 *OUTPUT_WANT_ROLL += PLANE_VEL_INTEG[1];
skyyoungsik 1:9530746906b6 568
skyyoungsik 0:3473b92e991e 569 }
skyyoungsik 1:9530746906b6 570
skyyoungsik 1:9530746906b6 571 double VERTICAL_VEL_INTEG;
skyyoungsik 1:9530746906b6 572 void VERTICAL_VEL_CONTROL(double IN_VEL_Z, double *OUTPUT_THROTTLE_VALUE) {
skyyoungsik 1:9530746906b6 573 double err_Vel_Z;
skyyoungsik 1:9530746906b6 574 err_Vel_Z = IN_VEL_Z - SPATIAL.Vz;
skyyoungsik 1:9530746906b6 575 if (err_Vel_Z >= 0) err_Vel_Z = MIN_MAX(err_Vel_Z, -LIMIT_UP_VELOCITY, LIMIT_UP_VELOCITY);
skyyoungsik 1:9530746906b6 576 else err_Vel_Z = MIN_MAX(err_Vel_Z, -LIMIT_DOWN_VELOCITY, LIMIT_DOWN_VELOCITY);
skyyoungsik 1:9530746906b6 577 *OUTPUT_THROTTLE_VALUE = (err_Vel_Z * 10) * (GUI.gain_dx100[6] / 100.0);
skyyoungsik 1:9530746906b6 578
skyyoungsik 1:9530746906b6 579 VERTICAL_VEL_INTEG += (err_Vel_Z) * (GUI.gain_ix100[6] / 100.0);
skyyoungsik 1:9530746906b6 580 VERTICAL_VEL_INTEG = MIN_MAX(VERTICAL_VEL_INTEG, -LIMIT_VERTICAL_VEL_INTEG, LIMIT_VERTICAL_VEL_INTEG);
skyyoungsik 1:9530746906b6 581 *OUTPUT_THROTTLE_VALUE += VERTICAL_VEL_INTEG;
skyyoungsik 1:9530746906b6 582
skyyoungsik 1:9530746906b6 583 *OUTPUT_THROTTLE_VALUE = MIN_MAX(*OUTPUT_THROTTLE_VALUE, -THROTTLE_CONTROL_LIMIT, THROTTLE_CONTROL_LIMIT);
skyyoungsik 1:9530746906b6 584
skyyoungsik 1:9530746906b6 585 *OUTPUT_THROTTLE_VALUE += THROTTLE_BASE;
skyyoungsik 1:9530746906b6 586
skyyoungsik 1:9530746906b6 587 *OUTPUT_THROTTLE_VALUE = MIN_MAX( *OUTPUT_THROTTLE_VALUE, THROTTLE_MIN, THROTTLE_MAX );
skyyoungsik 1:9530746906b6 588
skyyoungsik 1:9530746906b6 589 }
skyyoungsik 1:9530746906b6 590
skyyoungsik 1:9530746906b6 591 void VEL_INTEG_RESET() {
skyyoungsik 1:9530746906b6 592 PLANE_VEL_INTEG[0] = 0; PLANE_VEL_INTEG[1] = 0; VERTICAL_VEL_INTEG = 0;
skyyoungsik 1:9530746906b6 593 }
skyyoungsik 1:9530746906b6 594
skyyoungsik 1:9530746906b6 595 float DEG_TO_METER(float lat1, float lon1, float lat2, float lon2) {
skyyoungsik 1:9530746906b6 596 float R = 6378.137; // Radius of earth in KM
skyyoungsik 1:9530746906b6 597 float dLat = lat2 * M_PI / 180.0 - lat1 * M_PI / 180.0;
skyyoungsik 1:9530746906b6 598 float dLon = lon2 * M_PI / 180.0 - lon1 * M_PI / 180.0;
skyyoungsik 1:9530746906b6 599 float a = sin(dLat / 2.0) * sin(dLat / 2.0) + cos(lat1 * M_PI / 180.0) * cos(lat2 * M_PI / 180.0) * sin(dLon / 2.0) * sin(dLon / 2.0);
skyyoungsik 1:9530746906b6 600 float c = 2 * atan2(sqrt(a), sqrt(1 - a));
skyyoungsik 1:9530746906b6 601 float d = R * c;
skyyoungsik 1:9530746906b6 602 return d * 1000; // meters
skyyoungsik 1:9530746906b6 603 }