Rev 733 | Rev 746 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
726 | killagreg | 1 | #include <inttypes.h> |
1 | ingob | 2 | |
726 | killagreg | 3 | #include "fc.h" |
4 | #include "ubx.h" |
||
5 | #include "mymath.h" |
||
727 | killagreg | 6 | #include "timer0.h" |
741 | killagreg | 7 | #include "uart.h" |
701 | killagreg | 8 | |
741 | killagreg | 9 | #define TSK_IDLE 0 |
10 | #define TSK_HOLD 1 |
||
11 | #define TSK_HOME 2 |
||
12 | |||
13 | |||
726 | killagreg | 14 | int16_t GPS_Pitch = 0; |
15 | int16_t GPS_Roll = 0; |
||
16 | |||
727 | killagreg | 17 | int32_t GPS_P_Factor = 0; |
18 | int32_t GPS_D_Factor = 0; |
||
726 | killagreg | 19 | |
20 | typedef struct |
||
1 | ingob | 21 | { |
726 | killagreg | 22 | int32_t Northing; |
23 | int32_t Easting; |
||
24 | uint8_t Status; |
||
1 | ingob | 25 | |
726 | killagreg | 26 | } GPS_Pos_t; |
27 | |||
28 | // GPS coordinates for hold position |
||
741 | killagreg | 29 | GPS_Pos_t HoldPosition = {0,0, INVALID}; |
30 | // GPS coordinates for home position |
||
31 | GPS_Pos_t HomePosition = {0,0, INVALID}; |
||
726 | killagreg | 32 | |
33 | |||
34 | // --------------------------------------------------------------------------------- |
||
35 | |||
36 | |||
37 | void GPS_Main(void) |
||
1 | ingob | 38 | { |
726 | killagreg | 39 | int32_t coscompass, sincompass; |
40 | int32_t P_North = 0, D_North = 0, P_East = 0, D_East = 0; |
||
41 | int32_t PD_North = 0, PD_East = 0; |
||
42 | int32_t GPSPosDev_North = 0, GPSPosDev_East = 0; |
||
741 | killagreg | 43 | static uint8_t GPS_Task = TSK_IDLE; |
1 | ingob | 44 | |
741 | killagreg | 45 | |
726 | killagreg | 46 | // poti2 enables the gps feature |
741 | killagreg | 47 | if(Poti2 < 70) GPS_Task = TSK_IDLE; |
48 | else if (Poti2 < 160) GPS_Task = TSK_HOLD; |
||
49 | //else GPS_Task = TSK_HOME; |
||
50 | |||
51 | |||
52 | switch(GPSInfo.status) |
||
726 | killagreg | 53 | { |
741 | killagreg | 54 | case INVALID: // invalid gps data |
55 | GPS_Pitch = 0; |
||
56 | GPS_Roll = 0; |
||
57 | if(GPS_Task != TSK_IDLE) BeepTime = 50; // beep if signal is neccesary |
||
58 | break; |
||
59 | case PROCESSED: // if gps data are already processed |
||
60 | // downcount timeout |
||
61 | if(GPSTimeout) GPSTimeout--; |
||
62 | // if no new data arrived within timeout set current data invalid |
||
63 | // and therefore disable GPS |
||
64 | else |
||
726 | killagreg | 65 | { |
66 | GPS_Pitch = 0; |
||
67 | GPS_Roll = 0; |
||
741 | killagreg | 68 | GPSInfo.status = INVALID; |
69 | } |
||
70 | break; |
||
71 | case VALID: // new valid data from gps device |
||
72 | // if the gps data quality is sufficient |
||
73 | if (GPSInfo.satfix == SATFIX_3D) |
||
74 | { |
||
75 | switch(GPS_Task) // check what's to do |
||
726 | killagreg | 76 | { |
741 | killagreg | 77 | case TSK_IDLE: |
78 | // update hold point to current gps position |
||
79 | HoldPosition.Northing = GPSInfo.utmnorth; |
||
80 | HoldPosition.Easting = GPSInfo.utmeast; |
||
81 | HoldPosition.Status = VALID; |
||
82 | // disable gps control |
||
83 | GPS_Pitch = 0; |
||
84 | GPS_Roll = 0; |
||
85 | break; // eof TSK_IDLE |
||
86 | case TSK_HOLD: |
||
87 | // if sticks are centered and hold position is valid enable position hold control |
||
88 | if ((MaxStickPitch < 20) && (MaxStickRoll < 20) && (HoldPosition.Status == VALID)) |
||
89 | { |
||
90 | // Calculate deviation from hold position |
||
91 | GPSPosDev_North = GPSInfo.utmnorth - HoldPosition.Northing; |
||
92 | GPSPosDev_East = GPSInfo.utmeast - HoldPosition.Easting; |
||
93 | DebugOut.Analog[12] = GPSPosDev_North; |
||
94 | DebugOut.Analog[13] = GPSPosDev_East; |
||
1 | ingob | 95 | |
741 | killagreg | 96 | //Calculate PD-components of the controller (negative sign for compensation) |
97 | P_North = -(GPS_P_Factor * GPSPosDev_North)/2048; |
||
98 | D_North = -(GPS_D_Factor * GPSInfo.velnorth)/512; |
||
99 | P_East = -(GPS_P_Factor * GPSPosDev_East)/2048; |
||
100 | D_East = -(GPS_D_Factor * GPSInfo.veleast)/512; |
||
1 | ingob | 101 | |
741 | killagreg | 102 | // PD-controller |
103 | PD_North = P_North + D_North; |
||
104 | PD_East = P_East + D_East; |
||
726 | killagreg | 105 | |
741 | killagreg | 106 | // GPS to pitch and roll settings |
726 | killagreg | 107 | |
741 | killagreg | 108 | //A positive pitch angle moves head downwards (flying forward). |
109 | //A positive roll angle tilts left side downwards (flying left). |
||
727 | killagreg | 110 | |
741 | killagreg | 111 | // If compass heading is 0 the head of the copter is in north direction. |
112 | // A positive pitch angle will fly to north and a positive roll angle will fly to west. |
||
113 | // In case of a positive north deviation/velocity the |
||
114 | // copter should fly to south (negative pitch). |
||
115 | // In case of a positive east position deviation and a positive east velocity the |
||
116 | // copter should fly to west (positive roll). |
||
727 | killagreg | 117 | |
741 | killagreg | 118 | // The influence of the GPS_Pitch and GPS_Roll variable is contrarily to the stick values |
119 | // in the fc.c. Therefore a positive north deviation/velocity should result in a positive |
||
120 | // GPS_Pitch and a positive east deviation/velocity should result in a negative GPS_Roll. |
||
727 | killagreg | 121 | |
741 | killagreg | 122 | // rotation transformation to compass heading to match any copter orientation |
123 | if (CompassHeading < 0) // no valid compass data |
||
124 | { // disable GPS |
||
125 | GPS_Task = TSK_IDLE; |
||
126 | GPS_Pitch = 0; |
||
127 | GPS_Roll = 0; |
||
128 | } |
||
129 | else |
||
130 | { |
||
131 | coscompass = (int32_t)c_cos_8192(CompassHeading); |
||
132 | sincompass = (int32_t)c_sin_8192(CompassHeading); |
||
133 | GPS_Roll = (int16_t)((coscompass * PD_East - sincompass * PD_North) / 8192); |
||
134 | GPS_Pitch = -1*(int16_t)((sincompass * PD_East + coscompass * PD_North) / 8192); |
||
135 | } |
||
136 | } |
||
137 | else // MK controlled by user |
||
138 | { |
||
139 | // update hold point to current gps position |
||
140 | HoldPosition.Northing = GPSInfo.utmnorth; |
||
141 | HoldPosition.Easting = GPSInfo.utmeast; |
||
142 | HoldPosition.Status = VALID; |
||
143 | // disable gps control |
||
144 | GPS_Pitch = 0; |
||
145 | GPS_Roll = 0; |
||
146 | } |
||
147 | break; // eof TSK_HOLD |
||
148 | default: // unhandled task |
||
149 | GPS_Task = TSK_IDLE; |
||
150 | GPS_Pitch = 0; |
||
151 | GPS_Roll = 0; |
||
152 | break; // eof default |
||
153 | } // eof switch GPS_Task |
||
727 | killagreg | 154 | |
741 | killagreg | 155 | // limit GPS controls |
156 | #define GPS_CTRL_LIMIT 35 |
||
157 | if (GPS_Pitch > GPS_CTRL_LIMIT) GPS_Pitch = GPS_CTRL_LIMIT; |
||
158 | if (GPS_Pitch < -GPS_CTRL_LIMIT) GPS_Pitch = -GPS_CTRL_LIMIT; |
||
159 | if (GPS_Roll > GPS_CTRL_LIMIT) GPS_Roll = GPS_CTRL_LIMIT; |
||
160 | if (GPS_Roll < -GPS_CTRL_LIMIT) GPS_Roll = -GPS_CTRL_LIMIT; |
||
161 | } // eof 3D-FIX |
||
727 | killagreg | 162 | |
741 | killagreg | 163 | else // no 3D-SATFIX |
164 | { // disable gps control |
||
165 | GPS_Pitch = 0; |
||
166 | GPS_Roll = 0; |
||
167 | if(GPS_Task != TSK_IDLE) BeepTime = 50; |
||
168 | } |
||
169 | |||
170 | // set current data as processed to avoid further calculations on the same gps data |
||
171 | GPSInfo.status = PROCESSED; |
||
172 | break; |
||
173 | } // eof GPSInfo.status |
||
174 | DebugOut.Analog[14] = GPS_Pitch; |
||
175 | DebugOut.Analog[15] = GPS_Roll; |
||
726 | killagreg | 176 | } |
177 |