Rev 727 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 727 | Rev 733 | ||
---|---|---|---|
1 | #include <inttypes.h> |
1 | #include <inttypes.h> |
2 | 2 | ||
3 | #include "fc.h" |
3 | #include "fc.h" |
4 | #include "ubx.h" |
4 | #include "ubx.h" |
5 | #include "mymath.h" |
5 | #include "mymath.h" |
6 | #include "timer0.h" |
6 | #include "timer0.h" |
7 | 7 | ||
8 | int16_t GPS_Pitch = 0; |
8 | int16_t GPS_Pitch = 0; |
9 | int16_t GPS_Roll = 0; |
9 | int16_t GPS_Roll = 0; |
10 | 10 | ||
11 | int32_t GPS_P_Factor = 0; |
11 | int32_t GPS_P_Factor = 0; |
12 | int32_t GPS_D_Factor = 0; |
12 | int32_t GPS_D_Factor = 0; |
13 | 13 | ||
14 | typedef struct |
14 | typedef struct |
15 | { |
15 | { |
16 | int32_t Northing; |
16 | int32_t Northing; |
17 | int32_t Easting; |
17 | int32_t Easting; |
18 | uint8_t Status; |
18 | uint8_t Status; |
19 | 19 | ||
20 | } GPS_Pos_t; |
20 | } GPS_Pos_t; |
21 | 21 | ||
22 | // GPS coordinates for hold position |
22 | // GPS coordinates for hold position |
23 | GPS_Pos_t GPSHoldPoint = {0,0, INVALID}; |
23 | GPS_Pos_t GPSHoldPoint = {0,0, INVALID}; |
24 | 24 | ||
25 | 25 | ||
26 | 26 | ||
27 | // --------------------------------------------------------------------------------- |
27 | // --------------------------------------------------------------------------------- |
28 | 28 | ||
29 | 29 | ||
30 | void GPS_Main(void) |
30 | void GPS_Main(void) |
31 | { |
31 | { |
32 | int32_t coscompass, sincompass; |
32 | int32_t coscompass, sincompass; |
33 | int32_t P_North = 0, D_North = 0, P_East = 0, D_East = 0; |
33 | int32_t P_North = 0, D_North = 0, P_East = 0, D_East = 0; |
34 | int32_t PD_North = 0, PD_East = 0; |
34 | int32_t PD_North = 0, PD_East = 0; |
35 | int32_t GPSPosDev_North = 0, GPSPosDev_East = 0; |
35 | int32_t GPSPosDev_North = 0, GPSPosDev_East = 0; |
36 | 36 | ||
37 | // poti2 enables the gps feature |
37 | // poti2 enables the gps feature |
38 | if(Poti2 > 70) // run GPS function only if Poti 2 is larger than 70 (switch on) |
38 | if((Poti2 > 70) && (!EmergencyLanding)) // run GPS function only if Poti 2 is larger than 70 (switch on) |
39 | { |
39 | { |
40 | switch(GPSInfo.status) |
40 | switch(GPSInfo.status) |
41 | { |
41 | { |
42 | case INVALID: // invalid gps data |
42 | case INVALID: // invalid gps data |
43 | GPS_Pitch = 0; |
43 | GPS_Pitch = 0; |
44 | GPS_Roll = 0; |
44 | GPS_Roll = 0; |
45 | BeepTime = 50; |
45 | BeepTime = 50; |
46 | break; |
46 | break; |
47 | case PROCESSED: // if gps data are already processed |
47 | case PROCESSED: // if gps data are already processed |
48 | // downcount timeout |
48 | // downcount timeout |
49 | if(GPSTimeout) GPSTimeout--; |
49 | if(GPSTimeout) GPSTimeout--; |
50 | // if no new data arrived within timeout set current data invalid |
50 | // if no new data arrived within timeout set current data invalid |
51 | // and therefore disable GPS |
51 | // and therefore disable GPS |
52 | else |
52 | else |
53 | { |
53 | { |
54 | GPS_Pitch = 0; |
54 | GPS_Pitch = 0; |
55 | GPS_Roll = 0; |
55 | GPS_Roll = 0; |
56 | GPSInfo.status = INVALID; |
56 | GPSInfo.status = INVALID; |
57 | } |
57 | } |
58 | break; |
58 | break; |
59 | case VALID: // new valid data from gps device |
59 | case VALID: // new valid data from gps device |
60 | // if the gps data quality is sufficient |
60 | // if the gps data quality is sufficient |
61 | if (GPSInfo.satfix == SATFIX_3D) |
61 | if (GPSInfo.satfix == SATFIX_3D) |
62 | { |
62 | { |
63 | // if sticks are centered and hold position is valid enable position hold control |
63 | // if sticks are centered and hold position is valid enable position hold control |
64 | if ((MaxStickPitch < 20) && (MaxStickRoll < 20) && (GPSHoldPoint.Status == VALID)) |
64 | if ((MaxStickPitch < 20) && (MaxStickRoll < 20) && (GPSHoldPoint.Status == VALID)) |
65 | { |
65 | { |
66 | // Calculate deviation from hold position |
66 | // Calculate deviation from hold position |
67 | GPSPosDev_North = GPSInfo.utmnorth - GPSHoldPoint.Northing; |
67 | GPSPosDev_North = GPSInfo.utmnorth - GPSHoldPoint.Northing; |
68 | GPSPosDev_East = GPSInfo.utmeast - GPSHoldPoint.Easting; |
68 | GPSPosDev_East = GPSInfo.utmeast - GPSHoldPoint.Easting; |
69 | 69 | ||
70 | //Calculate PD-components of the controller (negative sign for compensation) |
70 | //Calculate PD-components of the controller (negative sign for compensation) |
71 | P_North = -(GPS_P_Factor * GPSPosDev_North)/2048; |
71 | P_North = -(GPS_P_Factor * GPSPosDev_North)/2048; |
72 | D_North = -(GPS_D_Factor * GPSInfo.velnorth)/512; |
72 | D_North = -(GPS_D_Factor * GPSInfo.velnorth)/512; |
73 | P_East = -(GPS_P_Factor * GPSPosDev_East)/2048; |
73 | P_East = -(GPS_P_Factor * GPSPosDev_East)/2048; |
74 | D_East = -(GPS_D_Factor * GPSInfo.veleast)/512; |
74 | D_East = -(GPS_D_Factor * GPSInfo.veleast)/512; |
75 | 75 | ||
76 | // PD-controller |
76 | // PD-controller |
77 | PD_North = P_North + D_North; |
77 | PD_North = P_North + D_North; |
78 | PD_East = P_East + D_East; |
78 | PD_East = P_East + D_East; |
79 | 79 | ||
80 | // GPS to pitch and roll settings |
80 | // GPS to pitch and roll settings |
81 | 81 | ||
82 | //A positive pitch angle moves head downwards (flying forward). |
82 | //A positive pitch angle moves head downwards (flying forward). |
83 | //A positive roll angle tilts left side downwards (flying left). |
83 | //A positive roll angle tilts left side downwards (flying left). |
84 | 84 | ||
85 | // If compass heading is 0 the head of the copter is in north direction. |
85 | // If compass heading is 0 the head of the copter is in north direction. |
86 | // A positive pitch angle will fly to north and a positive roll angle will fly to west. |
86 | // A positive pitch angle will fly to north and a positive roll angle will fly to west. |
87 | // In case of a positive north deviation/velocity the |
87 | // In case of a positive north deviation/velocity the |
88 | // copter should fly to south (negative pitch). |
88 | // copter should fly to south (negative pitch). |
89 | // In case of a positive east position deviation and a positive east velocity the |
89 | // In case of a positive east position deviation and a positive east velocity the |
90 | // copter should fly to west (positive roll). |
90 | // copter should fly to west (positive roll). |
91 | 91 | ||
92 | // The influence of the GPS_Pitch and GPS_Roll variable is contrarily to the stick values |
92 | // The influence of the GPS_Pitch and GPS_Roll variable is contrarily to the stick values |
93 | // in the fc.c. Therefore a positive north deviation/velocity should result in a positive |
93 | // in the fc.c. Therefore a positive north deviation/velocity should result in a positive |
94 | // GPS_Pitch and a positive east deviation/velocity should result in a negative GPS_Roll. |
94 | // GPS_Pitch and a positive east deviation/velocity should result in a negative GPS_Roll. |
95 | 95 | ||
96 | // rotation transformation to compass heading to match any copter orientation |
96 | // rotation transformation to compass heading to match any copter orientation |
97 | coscompass = (int32_t)c_cos_8192(CompassHeading); |
97 | coscompass = (int32_t)c_cos_8192(CompassHeading); |
98 | sincompass = (int32_t)c_sin_8192(CompassHeading); |
98 | sincompass = (int32_t)c_sin_8192(CompassHeading); |
99 | 99 | ||
100 | GPS_Roll = (int16_t)((coscompass * PD_East - sincompass * PD_North) / 8192); |
100 | GPS_Roll = (int16_t)((coscompass * PD_East - sincompass * PD_North) / 8192); |
101 | GPS_Pitch = -1*(int16_t)((sincompass * PD_East + coscompass * PD_North) / 8192); |
101 | GPS_Pitch = -1*(int16_t)((sincompass * PD_East + coscompass * PD_North) / 8192); |
102 | 102 | ||
103 | // limit GPS controls |
103 | // limit GPS controls |
104 | #define GPS_CTRL_LIMIT 35 |
104 | #define GPS_CTRL_LIMIT 35 |
105 | if (GPS_Pitch > GPS_CTRL_LIMIT) GPS_Pitch = GPS_CTRL_LIMIT; |
105 | if (GPS_Pitch > GPS_CTRL_LIMIT) GPS_Pitch = GPS_CTRL_LIMIT; |
106 | if (GPS_Pitch < -GPS_CTRL_LIMIT) GPS_Pitch = -GPS_CTRL_LIMIT; |
106 | if (GPS_Pitch < -GPS_CTRL_LIMIT) GPS_Pitch = -GPS_CTRL_LIMIT; |
107 | if (GPS_Roll > GPS_CTRL_LIMIT) GPS_Roll = GPS_CTRL_LIMIT; |
107 | if (GPS_Roll > GPS_CTRL_LIMIT) GPS_Roll = GPS_CTRL_LIMIT; |
108 | if (GPS_Roll < -GPS_CTRL_LIMIT) GPS_Roll = -GPS_CTRL_LIMIT; |
108 | if (GPS_Roll < -GPS_CTRL_LIMIT) GPS_Roll = -GPS_CTRL_LIMIT; |
109 | } |
109 | } |
110 | else // MK controlled by user |
110 | else // MK controlled by user |
111 | { |
111 | { |
112 | // update hold point to current gps position |
112 | // update hold point to current gps position |
113 | GPSHoldPoint.Northing = GPSInfo.utmnorth; |
113 | GPSHoldPoint.Northing = GPSInfo.utmnorth; |
114 | GPSHoldPoint.Easting = GPSInfo.utmeast; |
114 | GPSHoldPoint.Easting = GPSInfo.utmeast; |
115 | GPSHoldPoint.Status = VALID; |
115 | GPSHoldPoint.Status = VALID; |
116 | // disable gps control |
116 | // disable gps control |
117 | GPS_Pitch = 0; |
117 | GPS_Pitch = 0; |
118 | GPS_Roll = 0; |
118 | GPS_Roll = 0; |
119 | } |
119 | } |
120 | } // eof 3D-FIX |
120 | } // eof 3D-FIX |
121 | else // no 3D-SATFIX |
121 | else // no 3D-SATFIX |
122 | { // diable gps control |
122 | { // diable gps control |
123 | GPS_Pitch = 0; |
123 | GPS_Pitch = 0; |
124 | GPS_Roll = 0; |
124 | GPS_Roll = 0; |
125 | BeepTime = 50; |
125 | BeepTime = 50; |
126 | } |
126 | } |
127 | // set current data as processed to avoid further calculations on the same gps data |
127 | // set current data as processed to avoid further calculations on the same gps data |
128 | GPSInfo.status = PROCESSED; |
128 | GPSInfo.status = PROCESSED; |
129 | break; |
129 | break; |
130 | } // eof GPSInfo.status |
130 | } // eof GPSInfo.status |
131 | } |
131 | } |
132 | return; |
132 | return; |
133 | } |
133 | } |
134 | 134 | ||
135 | 135 |