Subversion Repositories FlightCtrl

Rev

Rev 242 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 242 Rev 258
1
/*
1
/*
2
This program (files gps.c and gps.h) is free software; you can redistribute it and/or modify
2
This program (files gps.c and gps.h) is free software; you can redistribute it and/or modify
3
it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation;
3
it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation;
4
either version 3 of the License, or (at your option) any later version.  
4
either version 3 of the License, or (at your option) any later version.  
5
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
6
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7
GNU General Public License and GNU Lesser General Public License for more details.
7
GNU General Public License and GNU Lesser General Public License for more details.
8
You should have received a copy of GNU General Public License ((License_GPL.txt)  and
8
You should have received a copy of GNU General Public License (License_GPL.txt)  and
9
GNU Lesser General Public License (License_LGPL.txt) along with this program.
9
GNU Lesser General Public License (License_LGPL.txt) along with this program.
10
If not, see <http://www.gnu.org/licenses/>.
10
If not, see <http://www.gnu.org/licenses/>.
11
 
11
 
12
Please note: All the other files for the project "Mikrokopter" by H.Buss are under the license (license_buss.txt) published by www.mikrokopter.de
12
Please note: All the other files for the project "Mikrokopter" by H.Buss are under the license (license_buss.txt) published by www.mikrokopter.de
13
*/
13
*/
14
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
Peter Muehlenbrock
15
Peter Muehlenbrock
16
Auswertung der Daten vom GPS im ublox Format
16
Auswertung der Daten vom GPS im ublox Format
17
Hold Modus mit PID Regler
17
Hold Modus mit PID Regler
18
Rückstuerz zur Basis Funktion
18
Rückstuerz zur Basis Funktion
19
Stand 7.10.2007
19
Stand 8.10.2007
20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21
*/
21
*/
22
#include "main.h"
22
#include "main.h"
23
//#include "gps.h"
23
//#include "gps.h"
24
 
24
 
25
// Defines fuer ublox Messageformat um Auswertung zu steuern
25
// Defines fuer ublox Messageformat um Auswertung zu steuern
26
#define                 UBLOX_IDLE              0
26
#define                 UBLOX_IDLE              0
27
#define                 UBLOX_SYNC1             1
27
#define                 UBLOX_SYNC1             1
28
#define                 UBLOX_SYNC2             2
28
#define                 UBLOX_SYNC2             2
29
#define                 UBLOX_CLASS             3
29
#define                 UBLOX_CLASS             3
30
#define                 UBLOX_ID                4
30
#define                 UBLOX_ID                4
31
#define                 UBLOX_LEN1              5
31
#define                 UBLOX_LEN1              5
32
#define                 UBLOX_LEN2              6
32
#define                 UBLOX_LEN2              6
33
#define                 UBLOX_CKA               7
33
#define                 UBLOX_CKA               7
34
#define                 UBLOX_CKB               8
34
#define                 UBLOX_CKB               8
35
#define                 UBLOX_PAYLOAD   9
35
#define                 UBLOX_PAYLOAD   9
36
 
36
 
37
// ublox Protokoll Identifier 
37
// ublox Protokoll Identifier 
38
#define                 UBLOX_NAV_POSUTM                0x08
38
#define                 UBLOX_NAV_POSUTM                0x08
39
#define                 UBLOX_NAV_STATUS                0x03
39
#define                 UBLOX_NAV_STATUS                0x03
40
#define                 UBLOX_NAV_VELED                 0x12
40
#define                 UBLOX_NAV_VELED                 0x12
41
#define                 UBLOX_NAV_CLASS                 0x01
41
#define                 UBLOX_NAV_CLASS                 0x01
42
#define                 UBLOX_SYNCH1_CHAR               0xB5
42
#define                 UBLOX_SYNCH1_CHAR               0xB5
43
#define                 UBLOX_SYNCH2_CHAR               0x62
43
#define                 UBLOX_SYNCH2_CHAR               0x62
44
 
44
 
45
signed int      GPS_Nick = 0;
45
signed int                      GPS_Nick = 0;
46
signed int      GPS_Roll = 0;
46
signed int                      GPS_Roll = 0;
47
short int       ublox_msg_state = UBLOX_IDLE;
47
short int                       ublox_msg_state = UBLOX_IDLE;
48
static          uint8_t chk_a =0; //Checksum
48
static                          uint8_t chk_a =0; //Checksum
49
static          uint8_t chk_b =0;
49
static                          uint8_t chk_b =0;
50
short int       gps_state,gps_sub_state; //Zustaende der Statemachine
50
short int                       gps_state,gps_sub_state; //Zustaende der Statemachine
51
short int       gps_updte_flag;
51
short int                       gps_updte_flag;
52
signed int      GPS_hdng_abs_2trgt; //Winkel zum Ziel bezogen auf Nordpol
52
signed int                      GPS_hdng_abs_2trgt; //Winkel zum Ziel bezogen auf Nordpol
53
signed int      GPS_hdng_rel_2trgt; //Winkel zum Ziel bezogen auf Nordachse des Kopters
53
signed int                      GPS_hdng_rel_2trgt; //Winkel zum Ziel bezogen auf Nordachse des Kopters
54
signed int      GPS_dist_2trgt; //vorzeichenlose Distanz zum Ziel 
54
signed int                      GPS_dist_2trgt; //vorzeichenlose Distanz zum Ziel 
55
signed int      gps_int_x,gps_int_y,gps_reg_x,gps_reg_y;                               
55
signed int                      gps_int_x,gps_int_y,gps_reg_x,gps_reg_y;                               
56
static unsigned int rx_len;
56
static unsigned int rx_len;
57
static unsigned int ptr_payload_data_end;
57
static unsigned int ptr_payload_data_end;
58
unsigned int            gps_alive_cnt; // Wird bei jedem gueltigen GPS Telegramm hochgezaehlt
58
unsigned int            gps_alive_cnt; // Wird bei jedem gueltigen GPS Telegramm hochgezaehlt
59
signed hdng_2home,dist_2home; //Richtung und Entfernung zur home Position 
59
signed int                      hdng_2home,dist_2home; //Richtung und Entfernung zur home Position 
60
signed gps_tick; //wird bei jedem Update durch das GPS Modul hochgezaehlt 
60
static signed           gps_tick; //wird bei jedem Update durch das GPS Modul hochgezaehlt 
61
static short int hold_fast,hold_reset_int; //Flags fuer Hold Regler
61
static                          short int hold_fast,hold_reset_int; //Flags fuer Hold Regler
62
static uint8_t *ptr_payload_data;
62
static                          uint8_t *ptr_payload_data;
63
static uint8_t *ptr_pac_status;
63
static                          uint8_t *ptr_pac_status;
64
long int dist_flown;
64
long int                        dist_flown;
65
 
65
 
66
short int Get_GPS_data(void);
66
short int Get_GPS_data(void);
67
 
67
 
68
NAV_POSUTM_t actual_pos;    // Aktuelle Nav Daten werden hier im ublox Format abgelegt
68
NAV_POSUTM_t actual_pos;    // Aktuelle Nav Daten werden hier im ublox Format abgelegt
69
NAV_STATUS_t actual_status; // Aktueller Nav Status
69
NAV_STATUS_t actual_status; // Aktueller Nav Status
70
NAV_VELNED_t actual_speed;  // Aktueller Geschwindigkeits und Richtungsdaten
70
NAV_VELNED_t actual_speed;  // Aktueller Geschwindigkeits und Richtungsdaten
71
 
71
 
72
GPS_ABS_POSITION_t              gps_act_position;               // Alle wichtigen Daten zusammengefasst
72
GPS_ABS_POSITION_t              gps_act_position;               // Alle wichtigen Daten zusammengefasst
73
GPS_ABS_POSITION_t              gps_home_position;      // Die Startposition, beim Kalibrieren ermittelt
73
GPS_ABS_POSITION_t              gps_home_position;      // Die Startposition, beim Kalibrieren ermittelt
74
GPS_REL_POSITION_t              gps_rel_act_position;   // Die aktuelle relative Position bezogen auf Home Position
74
GPS_REL_POSITION_t              gps_rel_act_position;   // Die aktuelle relative Position bezogen auf Home Position
75
GPS_REL_POSITION_t              gps_rel_hold_position;  // Die gespeicherte Sollposition fuer GPS_ Hold Mode
75
GPS_REL_POSITION_t              gps_rel_hold_position;  // Die gespeicherte Sollposition fuer GPS_ Hold Mode
76
GPS_REL_POSITION_t              gps_rel_start_position;         // Die gespeicherte Ausgangsposition fuer GPS_ Home Mode
76
GPS_REL_POSITION_t              gps_rel_start_position; // Die gespeicherte Ausgangsposition fuer GPS_ Home Mode
77
 
77
 
78
// Initialisierung
78
// Initialisierung
79
void GPS_Neutral(void)
79
void GPS_Neutral(void)
80
{
80
{
81
        ublox_msg_state                         =       UBLOX_IDLE;
81
        ublox_msg_state                         =       UBLOX_IDLE;
82
        gps_state                                       =       GPS_CRTL_IDLE;
82
        gps_state                                       =       GPS_CRTL_IDLE;
83
        actual_pos.status                       =       0;
83
        actual_pos.status                       =       0;
84
        actual_speed.status                     =       0;
84
        actual_speed.status                     =       0;
85
        actual_status.status            =       0;
85
        actual_status.status            =       0;
86
        gps_home_position.status        =       0; // Noch keine gueltige Home Position
86
        gps_home_position.status        =       0; // Noch keine gueltige Home Position
87
        gps_act_position.status         =       0;
87
        gps_act_position.status         =       0;
88
        gps_rel_act_position.status     =       0;     
88
        gps_rel_act_position.status     =       0;     
89
        GPS_Nick                                        =       0;
89
        GPS_Nick                                        =       0;
90
        GPS_Roll                                        =       0;
90
        GPS_Roll                                        =       0;
91
        gps_updte_flag                          =       0;
91
        gps_updte_flag                          =       0;
92
        gps_int_x                                       =       0;
92
        gps_int_x                                       =       0;
93
        gps_int_y                                       =       0;
93
        gps_int_y                                       =       0;
94
        gps_alive_cnt                           =       0;
94
        gps_alive_cnt                           =       0;
95
}
95
}
96
 
96
 
97
// Home Position sichern falls Daten verfuegbar sind. 
97
// Home Position sichern falls Daten verfuegbar sind. 
98
void GPS_Save_Home(void)
98
void GPS_Save_Home(void)
99
{
99
{
100
        short int n;
100
        short int n;
101
        n = Get_GPS_data();
101
        n = Get_GPS_data();
102
        if (n == 0)   // Gueltige  und aktuelle Daten ?   
102
        if (n == 0)   // Gueltige  und aktuelle Daten ?   
103
        {
103
        {
104
                // Neue GPS Daten liegen vor
104
                // Neue GPS Daten liegen vor
105
                gps_home_position.utm_east      = gps_act_position.utm_east;   
105
                gps_home_position.utm_east      = gps_act_position.utm_east;   
106
                gps_home_position.utm_north     = gps_act_position.utm_north;  
106
                gps_home_position.utm_north     = gps_act_position.utm_north;  
107
                gps_home_position.utm_alt       = gps_act_position.utm_alt;
107
                gps_home_position.utm_alt       = gps_act_position.utm_alt;
108
                gps_home_position.status        = 1; // Home Position gueltig                   
108
                gps_home_position.status        = 1; // Home Position gueltig                   
109
        }
109
        }
110
}
110
}
111
 
111
 
112
// Relative Position zur Home Position bestimmen
112
// Relative Position zur Home Position bestimmen
113
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
113
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
114
short int Get_Rel_Position(void)
114
short int Get_Rel_Position(void)
115
{
115
{
116
        short int n = 0;
116
        short int n = 0;
117
        n = Get_GPS_data();
117
        n = Get_GPS_data();
118
        if (n >=1) return (n); // nix zu tun, weil keine neue Daten da sind
118
        if (n >=1) return (n); // nix zu tun, weil keine neue Daten da sind
119
        if (gps_alive_cnt < 400) gps_alive_cnt += 300; // Timeoutzaehler. Wird in Motorregler Routine ueberwacht und dekrementiert
119
        if (gps_alive_cnt < 400) gps_alive_cnt += 300; // Timeoutzaehler. Wird in Motorregler Routine ueberwacht und dekrementiert
120
        if  (gps_home_position.status > 0) //Nur wenn Home Position vorliegt
120
        if  (gps_home_position.status > 0) //Nur wenn Home Position vorliegt
121
        {
121
        {
122
                gps_rel_act_position.utm_east   = (int)  (gps_act_position.utm_east - gps_home_position.utm_east);
122
                gps_rel_act_position.utm_east   = (int)  (gps_act_position.utm_east - gps_home_position.utm_east);
123
                gps_rel_act_position.utm_north  = (int)  (gps_act_position.utm_north - gps_home_position.utm_north);
123
                gps_rel_act_position.utm_north  = (int)  (gps_act_position.utm_north - gps_home_position.utm_north);
124
                gps_rel_act_position.status     = 1; // gueltige Positionsdaten
124
                gps_rel_act_position.status     = 1; // gueltige Positionsdaten
125
                n = 0;
125
                n = 0;
126
                gps_updte_flag = 1; // zeigt an, dass neue Daten vorliegen.
126
                gps_updte_flag = 1; // zeigt an, dass neue Daten vorliegen.
127
        }
127
        }
128
        else
128
        else
129
        {
129
        {
130
                n = 2; //keine gueltigen Daten vorhanden
130
                n = 2; //keine gueltigen Daten vorhanden
131
                gps_rel_act_position.status = 0; //keine gueltige Position weil keine home Position da ist.
131
                gps_rel_act_position.status = 0; //keine gueltige Position weil keine home Position da ist.
132
        }      
132
        }      
133
        return (n);
133
        return (n);
134
}
134
}
135
 
135
 
136
// Daten aus aktuellen ublox Messages extrahieren 
136
// Daten aus aktuellen ublox Messages extrahieren 
137
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
137
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
138
short int Get_GPS_data(void)
138
short int Get_GPS_data(void)
139
{
139
{
140
        short int n = 1;
140
        short int n = 1;
141
 
141
 
142
        if (actual_pos.status == 0) return (1); //damit es schnell geht, wenn nix zu tun ist
142
        if (actual_pos.status == 0) return (1); //damit es schnell geht, wenn nix zu tun ist
143
        if ((actual_pos.status > 0) && (actual_status.status > 0) && (actual_speed.status > 0))
143
        if ((actual_pos.status > 0) && (actual_status.status > 0) && (actual_speed.status > 0))
144
        {
144
        {
145
                if (((actual_status.gpsfix_type & 0x03) >=2) && ((actual_status.nav_status_flag & 0x01) >=1)) // nur wenn Daten aktuell und gueltig sind
145
                if (((actual_status.gpsfix_type & 0x03) >=2) && ((actual_status.nav_status_flag & 0x01) >=1)) // nur wenn Daten aktuell und gueltig sind
146
                {
146
                {
147
                        gps_act_position.utm_east       = actual_pos.utm_east/10;
147
                        gps_act_position.utm_east       = actual_pos.utm_east/10;
148
                        gps_act_position.utm_north      = actual_pos.utm_north/10;
148
                        gps_act_position.utm_north      = actual_pos.utm_north/10;
149
                        gps_act_position.utm_alt        = actual_pos.utm_alt/10;
149
                        gps_act_position.utm_alt        = actual_pos.utm_alt/10;
150
                        gps_act_position.speed_gnd      = actual_speed.speed_gnd/10;
150
                        gps_act_position.speed_gnd      = actual_speed.speed_gnd/10;
151
                        gps_act_position.speed_gnd      = actual_speed.speed_gnd/10;
151
                        gps_act_position.speed_gnd      = actual_speed.speed_gnd/10;
152
                        gps_act_position.heading        = actual_speed.heading/100000;
152
                        gps_act_position.heading        = actual_speed.heading/100000;
153
                        gps_act_position.status         = 1;
153
                        gps_act_position.status         = 1;
154
                        n                                                       = 0; //Daten gueltig
154
                        n                                                       = 0; //Daten gueltig
155
                }
155
                }
156
                else
156
                else
157
                {
157
                {
158
                        gps_act_position.status = 0; //Keine gueltigen Daten
158
                        gps_act_position.status = 0; //Keine gueltigen Daten
159
                        n                                               = 2;
159
                        n                                               = 2;
160
                }
160
                }
161
                actual_pos.status               = 0; //neue ublox Messages anfordern
161
                actual_pos.status               = 0; //neue ublox Messages anfordern
162
                actual_status.status    = 0;
162
                actual_status.status    = 0;
163
                actual_speed.status     = 0;
163
                actual_speed.status     = 0;
164
        }      
164
        }      
165
        return (n);    
165
        return (n);    
166
}
166
}
167
 
-
 
168
 
167
 
169
/*
168
/*
170
Daten vom GPS im ublox MSG Format auswerten
169
Daten vom GPS im ublox MSG Format auswerten
171
Die Routine wird bei jedem Empfang eines Zeichens vom GPS Modul durch den UART IRQ aufgerufen
170
Die Routine wird bei jedem Empfang eines Zeichens vom GPS Modul durch den UART IRQ aufgerufen
172
// Die UBX Messages NAV_POSUTM, NAV_STATUS und NAV_VALED muessen aktiviert sein
171
// Die UBX Messages NAV_POSUTM, NAV_STATUS und NAV_VALED muessen aktiviert sein
173
*/
172
*/
174
void Get_Ublox_Msg(uint8_t rx)
173
void Get_Ublox_Msg(uint8_t rx)
175
{
174
{
176
        switch (ublox_msg_state)
175
        switch (ublox_msg_state)
177
        {
176
        {
178
 
177
 
179
                case UBLOX_IDLE: // Zuerst Synchcharacters pruefen
178
                case UBLOX_IDLE: // Zuerst Synchcharacters pruefen
180
                        if ( rx == UBLOX_SYNCH1_CHAR ) ublox_msg_state = UBLOX_SYNC1;
179
                        if ( rx == UBLOX_SYNCH1_CHAR ) ublox_msg_state = UBLOX_SYNC1;
181
                        else ublox_msg_state = UBLOX_IDLE;
180
                        else ublox_msg_state = UBLOX_IDLE;
182
                        break;
181
                        break;
183
 
182
 
184
                case UBLOX_SYNC1:
183
                case UBLOX_SYNC1:
185
 
184
 
186
                        if (rx == UBLOX_SYNCH2_CHAR) ublox_msg_state = UBLOX_SYNC2;
185
                        if (rx == UBLOX_SYNCH2_CHAR) ublox_msg_state = UBLOX_SYNC2;
187
                        else ublox_msg_state = UBLOX_IDLE;
186
                        else ublox_msg_state = UBLOX_IDLE;
188
                        chk_a = 0,chk_b = 0;
187
                        chk_a = 0,chk_b = 0;
189
                        break;
188
                        break;
190
 
189
 
191
                case UBLOX_SYNC2:
190
                case UBLOX_SYNC2:
192
                        if (rx == UBLOX_NAV_CLASS) ublox_msg_state = UBLOX_CLASS;      
191
                        if (rx == UBLOX_NAV_CLASS) ublox_msg_state = UBLOX_CLASS;      
193
                        else ublox_msg_state = UBLOX_IDLE;
192
                        else ublox_msg_state = UBLOX_IDLE;
194
                        break;
193
                        break;
195
 
194
 
196
                case UBLOX_CLASS: // Nur NAV Meldungen auswerten
195
                case UBLOX_CLASS: // Nur NAV Meldungen auswerten
197
                        switch (rx)
196
                        switch (rx)
198
                        {
197
                        {
199
                                case UBLOX_NAV_POSUTM:
198
                                case UBLOX_NAV_POSUTM:
200
                                        ptr_pac_status  =       &actual_pos.status;
199
                                        ptr_pac_status  =       &actual_pos.status;
201
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE; //Abbruch weil Daten noch nicht verwendet wurden
200
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE; //Abbruch weil Daten noch nicht verwendet wurden
202
                                        else
201
                                        else
203
                                        {
202
                                        {
204
                                                ptr_payload_data                = &actual_pos;
203
                                                ptr_payload_data                = &actual_pos;
205
                                                ptr_payload_data_end    = &actual_pos.status;
204
                                                ptr_payload_data_end    = &actual_pos.status;
206
                                                ublox_msg_state                 = UBLOX_LEN1;
205
                                                ublox_msg_state                 = UBLOX_LEN1;
207
                                        }
206
                                        }
208
                                        break;
207
                                        break;
209
 
208
 
210
                                case UBLOX_NAV_STATUS:
209
                                case UBLOX_NAV_STATUS:
211
                                        ptr_pac_status  =       &actual_status.status;
210
                                        ptr_pac_status  =       &actual_status.status;
212
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
211
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
213
                                        else
212
                                        else
214
                                        {
213
                                        {
215
                                                ptr_payload_data                = &actual_status;
214
                                                ptr_payload_data                = &actual_status;
216
                                                ptr_payload_data_end    = &actual_status.status;
215
                                                ptr_payload_data_end    = &actual_status.status;
217
                                                ublox_msg_state                 = UBLOX_LEN1;
216
                                                ublox_msg_state                 = UBLOX_LEN1;
218
                                        }
217
                                        }
219
                                        break;
218
                                        break;
220
 
219
 
221
                                case UBLOX_NAV_VELED:
220
                                case UBLOX_NAV_VELED:
222
                                        ptr_pac_status          =       &actual_speed.status;
221
                                        ptr_pac_status          =       &actual_speed.status;
223
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
222
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
224
                                        else
223
                                        else
225
                                        {
224
                                        {
226
                                                ptr_payload_data                = &actual_speed;
225
                                                ptr_payload_data                = &actual_speed;
227
                                                ptr_payload_data_end    = &actual_speed.status;
226
                                                ptr_payload_data_end    = &actual_speed.status;
228
                                                ublox_msg_state                 = UBLOX_LEN1;
227
                                                ublox_msg_state                 = UBLOX_LEN1;
229
                                        }
228
                                        }
230
                                        break;
229
                                        break;
231
 
230
 
232
                                default:
231
                                default:
233
                                        ublox_msg_state = UBLOX_IDLE;
232
                                        ublox_msg_state = UBLOX_IDLE;
234
                                        break; 
233
                                        break; 
235
                        }
234
                        }
236
                        chk_a   = UBLOX_NAV_CLASS + rx;
235
                        chk_a   = UBLOX_NAV_CLASS + rx;
237
                        chk_b   = UBLOX_NAV_CLASS + chk_a;                     
236
                        chk_b   = UBLOX_NAV_CLASS + chk_a;                     
238
                        break;
237
                        break;
239
 
238
 
240
                case UBLOX_LEN1: // Laenge auswerten
239
                case UBLOX_LEN1: // Laenge auswerten
241
                        rx_len  = rx;
240
                        rx_len  = rx;
242
                        chk_a   += rx;
241
                        chk_a   += rx;
243
                        chk_b   += chk_a;              
242
                        chk_b   += chk_a;              
244
                        ublox_msg_state = UBLOX_LEN2;
243
                        ublox_msg_state = UBLOX_LEN2;
245
                        break;
244
                        break;
246
 
245
 
247
 
246
 
248
                case UBLOX_LEN2: // Laenge auswerten
247
                case UBLOX_LEN2: // Laenge auswerten
249
                        rx_len = rx_len + (rx *256); // Laenge ermitteln
248
                        rx_len = rx_len + (rx *256); // Laenge ermitteln
250
                        chk_a   += rx;
249
                        chk_a   += rx;
251
                        chk_b   += chk_a;      
250
                        chk_b   += chk_a;      
252
                        ublox_msg_state = UBLOX_PAYLOAD;
251
                        ublox_msg_state = UBLOX_PAYLOAD;
253
                        break;
252
                        break;
254
 
253
 
255
                case UBLOX_PAYLOAD: // jetzt Nutzdaten einlesen
254
                case UBLOX_PAYLOAD: // jetzt Nutzdaten einlesen
256
                        if (rx_len > 0)
255
                        if (rx_len > 0)
257
                        {
256
                        {
258
                                *ptr_payload_data = rx;
257
                                *ptr_payload_data = rx;
259
                                chk_a   += rx;
258
                                chk_a   += rx;
260
                                chk_b   += chk_a;
259
                                chk_b   += chk_a;
261
                                --rx_len;      
260
                                --rx_len;      
262
                                if ((rx_len > 0) && (ptr_payload_data <= ptr_payload_data_end))                          
261
                                if ((rx_len > 0) && (ptr_payload_data <= ptr_payload_data_end))                          
263
                                {
262
                                {
264
                                        ptr_payload_data++;
263
                                        ptr_payload_data++;
265
                                        ublox_msg_state = UBLOX_PAYLOAD;
264
                                        ublox_msg_state = UBLOX_PAYLOAD;
266
                            }
265
                            }
267
                                else ublox_msg_state = UBLOX_CKA;
266
                                else ublox_msg_state = UBLOX_CKA;
268
                        }      
267
                        }      
269
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
268
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
270
                        break;
269
                        break;
271
 
270
 
272
                case UBLOX_CKA: // Checksum pruefen
271
                case UBLOX_CKA: // Checksum pruefen
273
                        if (rx == chk_a) ublox_msg_state = UBLOX_CKB;                          
272
                        if (rx == chk_a) ublox_msg_state = UBLOX_CKB;                          
274
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
273
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
275
                        break;
274
                        break;
276
 
275
 
277
                case UBLOX_CKB: // Checksum pruefen
276
                case UBLOX_CKB: // Checksum pruefen
278
                        if (rx == chk_b) *ptr_pac_status = 1; // Paket ok
277
                        if (rx == chk_b) *ptr_pac_status = 1; // Paket ok
279
                        ublox_msg_state    = UBLOX_IDLE;
278
                        ublox_msg_state    = UBLOX_IDLE;
280
                        break;
279
                        break;
281
 
280
 
282
                default:
281
                default:
283
                        ublox_msg_state = UBLOX_IDLE;          
282
                        ublox_msg_state = UBLOX_IDLE;          
284
                        break;
283
                        break;
285
        }
284
        }
286
}
285
}
287
       
286
       
288
//Zentrale Statemachine fuer alle GPS relevanten Regelungsablauefe
287
//Zentrale Statemachine fuer alle GPS relevanten Regelungsablauefe
289
short int GPS_CRTL(short int cmd)
288
short int GPS_CRTL(short int cmd)
290
{
289
{
291
        static unsigned int cnt;                                        //Zaehler fuer diverse Verzoegerungen 
290
        static unsigned int cnt;                                        //Zaehler fuer diverse Verzoegerungen 
292
        static signed int int_east,int_north;   //Integrierer 
291
        static signed int int_east,int_north;   //Integrierer 
293
        static signed int dist_north,dist_east;
292
        static signed int dist_north,dist_east;
294
        static signed int diff_east,diff_north;         // Differenzierer  (Differenz zum  vorhergehenden x bzw. y  Wert)
293
        static signed int diff_east,diff_north;         // Differenzierer  (Differenz zum  vorhergehenden x bzw. y  Wert)
295
        static signed int diff_east_f,diff_north_f; // Differenzierer,  gefiltert
294
        static signed int diff_east_f,diff_north_f; // Differenzierer,  gefiltert
296
        signed int n,diff_v;
295
        signed int n,diff_v;
297
        static signed int gps_g2t_act_v; // Aktuelle Geschwindigkeitsvorgabe fuer Home Funktion
296
        static signed int gps_g2t_act_v; // Aktuelle Geschwindigkeitsvorgabe fuer Home Funktion
298
        long signed int dev,n_l;
297
        long signed int dev,n_l;
299
        signed int dist_frm_start_east,dist_frm_start_north;
298
        signed int dist_frm_start_east,dist_frm_start_north;
300
        switch (cmd)
299
        switch (cmd)
301
        {
300
        {
302
 
301
 
303
                case GPS_CMD_REQ_HOME: // Es soll zum Startpunkt zurueckgeflogen werden. 
302
                case GPS_CMD_REQ_HOME: // Es soll zum Startpunkt zurueckgeflogen werden. 
304
                        if ((gps_state != GPS_CRTL_HOLD_ACTIVE) && (gps_state != GPS_CRTL_HOME_ACTIVE))
303
                        if ((gps_state != GPS_CRTL_HOLD_ACTIVE) && (gps_state != GPS_CRTL_HOME_ACTIVE))
305
                        {
304
                        {
306
                                cnt++;
305
                                cnt++;
307
                                if (cnt > 500) // erst nach Verzoegerung 
306
                                if (cnt > 500) // erst nach Verzoegerung 
308
                                {
307
                                {
309
                                        // Erst mal initialisieren
308
                                        // Erst mal initialisieren
310
                                        cnt                             = 0;
309
                                        cnt                             = 0;
311
                                        gps_tick                = 0;                                   
310
                                        gps_tick                = 0;                                   
312
                                        hold_fast               = 0;
311
                                        hold_fast               = 0;
313
                                        hold_reset_int  = 0; // Integrator enablen
312
                                        hold_reset_int  = 0; // Integrator enablen
314
                                        int_east                = 0, int_north  = 0;
313
                                        int_east                = 0, int_north  = 0;
315
                                        gps_reg_x               = 0, gps_reg_y  = 0;
314
                                        gps_reg_x               = 0, gps_reg_y  = 0;
316
                                        dist_east               = 0, dist_north = 0;
315
                                        dist_east               = 0, dist_north = 0;
317
                                        diff_east_f             = 0, diff_north_f= 0;
316
                                        diff_east_f             = 0, diff_north_f= 0;
318
                                        diff_east               = 0, diff_north  = 0;  
317
                                        diff_east               = 0, diff_north  = 0;  
319
                                        dist_flown              = 0;
318
                                        dist_flown              = 0;
320
                                        gps_g2t_act_v   = 0;
319
                                        gps_g2t_act_v   = 0;
321
                                        gps_sub_state   = GPS_CRTL_IDLE;
320
                                        gps_sub_state   = GPS_CRTL_IDLE;
322
                                        // aktuelle positionsdaten abspeichern
321
                                        // aktuelle positionsdaten abspeichern
323
                                        if (gps_rel_act_position.status > 0)
322
                                        if (gps_rel_act_position.status > 0)
324
                                        {
323
                                        {
325
                                                gps_rel_start_position.utm_east = gps_rel_act_position.utm_east;
324
                                                gps_rel_start_position.utm_east = gps_rel_act_position.utm_east;
326
                                                gps_rel_start_position.utm_north= gps_rel_act_position.utm_north;
325
                                                gps_rel_start_position.utm_north= gps_rel_act_position.utm_north;
327
                                                gps_rel_start_position.status   = 1; // gueltige Positionsdaten 
326
                                                gps_rel_start_position.status   = 1; // gueltige Positionsdaten 
328
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
327
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
329
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
328
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
330
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
329
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
331
                                                //Richtung zur Home Positionbezogen auf Nordpol bestimmen
330
                                                //Richtung zur Home Positionbezogen auf Nordpol bestimmen
332
                                                hdng_2home = arctan_i(-gps_rel_start_position.utm_east,-gps_rel_start_position.utm_north);
331
                                                hdng_2home = arctan_i(-gps_rel_start_position.utm_east,-gps_rel_start_position.utm_north);
333
                                                // in Winkel 0...360 Grad umrechnen
332
                                                // in Winkel 0...360 Grad umrechnen
334
                                                if (( gps_rel_start_position.utm_east < 0)) hdng_2home = ( 90-hdng_2home);
333
                                                if (( gps_rel_start_position.utm_east < 0)) hdng_2home = ( 90-hdng_2home);
335
                                                else  hdng_2home = (270 - hdng_2home);
334
                                                else  hdng_2home = (270 - hdng_2home);
336
                                                dist_2home = (int) get_dist(gps_rel_start_position.utm_east,gps_rel_start_position.utm_north,hdng_2home); //Entfernung zur Home Position bestimmen
335
                                                dist_2home = get_dist(gps_rel_start_position.utm_east,gps_rel_start_position.utm_north,hdng_2home); //Entfernung zur Home Position bestimmen
337
                                                gps_state       = GPS_CRTL_HOME_ACTIVE;
336
                                                gps_state       = GPS_CRTL_HOME_ACTIVE;
338
                                                return (GPS_STST_OK);                          
337
                                                return (GPS_STST_OK);                          
339
                                        }
338
                                        }
340
                                        else
339
                                        else
341
                                        {
340
                                        {
342
                                                gps_rel_start_position.status   =       0;  //Keine Daten verfuegbar
341
                                                gps_rel_start_position.status   =       0;  //Keine Daten verfuegbar
343
                                                gps_state                                               = GPS_CRTL_IDLE;
342
                                                gps_state                                               = GPS_CRTL_IDLE;
344
                                                return(GPS_STST_ERR); // Keine Daten da
343
                                                return(GPS_STST_ERR); // Keine Daten da
345
                                        }
344
                                        }
346
                                }
345
                                }
347
                                else return(GPS_STST_PEND); // noch warten
346
                                else return(GPS_STST_PEND); // noch warten
348
                        }
347
                        }
349
                   break;
348
                   break;
350
// ******************************
349
// ******************************
351
 
350
 
352
                case GPS_CMD_REQ_HOLD: // Die Lageregelung soll aktiviert werden.
351
                case GPS_CMD_REQ_HOLD: // Die Lageregelung soll aktiviert werden.
353
                        if (gps_state != GPS_CRTL_HOLD_ACTIVE)
352
                        if (gps_state != GPS_CRTL_HOLD_ACTIVE)
354
                        {
353
                        {
355
                                cnt++;
354
                                cnt++;
356
                                if (cnt > 500) // erst nach Verzoegerung 
355
                                if (cnt > 500) // erst nach Verzoegerung 
357
                                {
356
                                {
358
                                        cnt     =       0;
357
                                        cnt     =       0;
359
                                        // aktuelle positionsdaten abspeichern
358
                                        // aktuelle positionsdaten abspeichern
360
                                        if (gps_rel_act_position.status > 0)
359
                                        if (gps_rel_act_position.status > 0)
361
                                        {
360
                                        {
362
                                                hold_fast               = 0;
361
                                                hold_fast               = 0;
363
                                                hold_reset_int  = 0; // Integrator enablen
362
                                                hold_reset_int  = 0; // Integrator enablen
364
                                                int_east        = 0, int_north  = 0;
363
                                                int_east        = 0, int_north  = 0;
365
                                                gps_reg_x       = 0, gps_reg_y  = 0;
364
                                                gps_reg_x       = 0, gps_reg_y  = 0;
366
                                                dist_east       = 0, dist_north = 0;
365
                                                dist_east       = 0, dist_north = 0;
367
                                                diff_east_f     = 0, diff_north_f= 0;
366
                                                diff_east_f     = 0, diff_north_f= 0;
368
                                                diff_east       = 0, diff_north  = 0;
367
                                                diff_east       = 0, diff_north  = 0;
369
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
368
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
370
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
369
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
371
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
370
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
372
                                                gps_state                                               = GPS_CRTL_HOLD_ACTIVE;
371
                                                gps_state                                               = GPS_CRTL_HOLD_ACTIVE;
373
                                                return (GPS_STST_OK);                          
372
                                                return (GPS_STST_OK);                          
374
                                        }
373
                                        }
375
                                        else
374
                                        else
376
                                        {
375
                                        {
377
                                                gps_rel_hold_position.status    =       0;  //Keine Daten verfuegbar
376
                                                gps_rel_hold_position.status    =       0;  //Keine Daten verfuegbar
378
                                                gps_state                                               = GPS_CRTL_IDLE;
377
                                                gps_state                                               = GPS_CRTL_IDLE;
379
                                                return(GPS_STST_ERR); // Keine Daten da
378
                                                return(GPS_STST_ERR); // Keine Daten da
380
                                        }
379
                                        }
381
                                }
380
                                }
382
                                else return(GPS_STST_PEND); // noch warten
381
                                else return(GPS_STST_PEND); // noch warten
383
                        }
382
                        }
384
                        break;
383
                        break;
385
 
384
 
386
                case GPS_CMD_STOP: // Lageregelung beenden
385
                case GPS_CMD_STOP: // Lageregelung beenden
387
                        cnt                             =       0;
386
                        cnt                             =       0;
388
                        GPS_Nick                =       0;
387
                        GPS_Nick                =       0;
389
                        GPS_Roll                =       0;
388
                        GPS_Roll                =       0;
390
                        gps_int_x               =       0;
389
                        gps_int_x               =       0;
391
                        gps_int_y               =       0;
390
                        gps_int_y               =       0;
392
                        gps_state       =       GPS_CRTL_IDLE;
391
                        gps_state       =       GPS_CRTL_IDLE;
393
                        return (GPS_STST_OK);
392
                        return (GPS_STST_OK);
394
                        break;
393
                        break;
395
 
394
 
396
                default:
395
                default:
397
                        return (GPS_STST_ERR);
396
                        return (GPS_STST_ERR);
398
                        break;
397
                        break;
399
        }
398
        }
400
 
399
 
401
        switch (gps_state)
400
        switch (gps_state)
402
        {      
401
        {      
403
                case GPS_CRTL_IDLE:
402
                case GPS_CRTL_IDLE:
404
                        cnt             =       0;
403
                        cnt             =       0;
405
                        return (GPS_STST_OK);
404
                        return (GPS_STST_OK);
406
                        break;
405
                        break;
407
 
406
 
408
                case GPS_CRTL_HOME_ACTIVE: // Rueckflug zur Basis
407
                case GPS_CRTL_HOME_ACTIVE: // Rueckflug zur Basis
409
                //Der Sollwert des Lagereglers wird der Homeposition angenaehert
408
                //Der Sollwert des Lagereglers wird der Homeposition angenaehert
410
                        if (gps_rel_start_position.status >0)
409
                        if (gps_rel_start_position.status >0)
411
                        {
410
                        {
412
                                if ((gps_updte_flag > 0) && (gps_sub_state !=GPS_HOME_FINISHED)) // nur wenn neue GPS Daten vorliegen und nicht schon alles fertig ist
411
                                if ((gps_updte_flag > 0) && (gps_sub_state !=GPS_HOME_FINISHED)) // nur wenn neue GPS Daten vorliegen und nicht schon alles fertig ist
413
                                {
412
                                {
414
                                        gps_tick++;
413
                                        gps_tick++;
415
                                        int d1,d2,d3;
414
                                        int d1,d2,d3;
416
                                        d1      = abs (gps_rel_hold_position.utm_east - gps_rel_act_position.utm_east );
415
                                        d1      = abs (gps_rel_hold_position.utm_east - gps_rel_act_position.utm_east );
417
                                        d2      = abs (gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north );
416
                                        d2      = abs (gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north );
418
                                        d3      = (dist_2home - (int)dist_flown); // Restdistanz zum Ziel       
417
                                        d3      = (dist_2home - (int)dist_flown); // Restdistanz zum Ziel       
419
       
418
       
420
                                        if (d3 > GPS_G2T_DIST_MAX_STOP)
419
                                        if (d3 > GPS_G2T_DIST_MAX_STOP) // Schneller Rueckflug, noch weit weg vom Ziel
421
                                        {
420
                                        {
422
                                                hold_fast                               = 1; // Schnell Regeln
421
//                                              hold_fast               = 1; // Schnell Regeln
423
                                                hold_reset_int                  = 1; // Integrator ausschalten            
422
                                                hold_reset_int  = 1; // Integrator ausschalten            
424
                                                if ((d1 < GPS_G2T_TOL)  && (d2 < GPS_G2T_TOL)) //nur weiter wenn Lage innerhalb der Toleranz
423
                                                if ((d1 < GPS_G2T_FAST_TOL)  && (d2 < GPS_G2T_FAST_TOL)) //nur weiter wenn Lage innerhalb der Toleranz
425
                                                {
424
                                                {
426
                                                        if (gps_g2t_act_v < GPS_G2T_V_MAX) gps_g2t_act_v++; //Geschwindigkeit langsam erhoehen
425
                                                        if (gps_g2t_act_v < GPS_G2T_V_MAX) gps_g2t_act_v++; //Geschwindigkeit langsam erhoehen
427
                                                        dist_flown                              += (long)gps_g2t_act_v; // Vorgabe der Strecke anhand der Geschwindigkeit
426
                                                        dist_flown                                              +=(long)gps_g2t_act_v; // Vorgabe der Strecke anhand der Geschwindigkeit
428
                                                        dist_frm_start_east             = (int)((dist_flown * (long)sin_i(hdng_2home))/1000);
427
                                                        dist_frm_start_east                             = (int)((dist_flown * (long)sin_i(hdng_2home))/1000);
429
                                                        dist_frm_start_north    = (int)((dist_flown * (long)cos_i(hdng_2home))/1000);
428
                                                        dist_frm_start_north                    = (int)((dist_flown * (long)cos_i(hdng_2home))/1000);
430
                                                        gps_rel_hold_position.utm_east = gps_rel_start_position.utm_east + dist_frm_start_east; //naechster Zielpunkt
429
                                                        gps_rel_hold_position.utm_east  = gps_rel_start_position.utm_east  + dist_frm_start_east; //naechster Zielpunkt
431
                                                        gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + dist_frm_start_north; //naechster Zielpunkt
430
                                                        gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + dist_frm_start_north; //naechster Zielpunkt
432
                                                        gps_sub_state                   = GPS_HOME_FAST_IN_TOL;
431
                                                        gps_sub_state                                   = GPS_HOME_FAST_IN_TOL;
433
                                                }
432
                                                }
434
                                                else    //Den Lageregler in Ruhe arbeiten lassen weil ausserhalb der Toleranz
433
                                                else    //Den Lageregler in Ruhe arbeiten lassen weil ausserhalb der Toleranz
435
                                                {
434
                                                {
436
/*                                                      if (gps_sub_state == GPS_HOME_FAST_IN_TOL) hold_reset_int = 1; //Integrator einmal am Beginn des normalen Regelns resetten
-
 
437
                                                        else hold_reset_int = 0;
-
 
438
*/                                                      if (gps_g2t_act_v > 0) gps_g2t_act_v--;
435
                                                        if (gps_g2t_act_v > 1) gps_g2t_act_v--; // Geschwindigkeit reduzieren
439
                                                        gps_sub_state   = GPS_HOME_FAST_OUTOF_TOL;
436
                                                        gps_sub_state   = GPS_HOME_FAST_OUTOF_TOL;
440
                                                }
437
                                                }
441
                                        }
438
                                        }
442
                                        else   //Schon ziemlich nahe am Ziel, deswegen abbremsen
439
                                        else if (d3 > GPS_G2T_DIST_HOLD)   //Das Ziel naehert sich, deswegen abbremsen
443
                                        {
440
                                        {
-
 
441
                                                hold_reset_int  = 0; // Integrator einschalten            
444
                                                if ((d1 < GPS_G2T_TOL)  && (d2 < GPS_G2T_TOL)) //nur weiter wenn Lage innerhalb der Toleranz
442
                                                if ((d1 < GPS_G2T_NRML_TOL)  && (d2 < GPS_G2T_NRML_TOL)) //nur weiter wenn Lage innerhalb der Toleranz
445
                                                {
443
                                                {
-
 
444
                                                        if (gps_g2t_act_v > GPS_G2T_V_RAMP_DWN) gps_g2t_act_v = GPS_G2T_V_RAMP_DWN; // Geschwindigkeit zu hoch
-
 
445
                                                        else  gps_g2t_act_v++; //Geschwindigkeit langsam erhoehen
-
 
446
                                                        dist_flown                                              +=(long)gps_g2t_act_v; // Vorgabe der Strecke anhand der Geschwindigkeit
-
 
447
                                                        dist_frm_start_east                             = (int)((dist_flown * (long)sin_i(hdng_2home))/1000);
-
 
448
                                                        dist_frm_start_north                    = (int)((dist_flown * (long)cos_i(hdng_2home))/1000);
-
 
449
                                                        gps_rel_hold_position.utm_east  = gps_rel_start_position.utm_east  + dist_frm_start_east; //naechster Zielpunkt
-
 
450
                                                        gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + dist_frm_start_north; //naechster Zielpunkt
446
                                                        gps_sub_state   = GPS_HOME_RMPDWN_IN_TOL;
451
                                                        gps_sub_state   = GPS_HOME_RMPDWN_IN_TOL;
-
 
452
                                                }
-
 
453
                                                else
-
 
454
                                                {
447
                                                        if (d3 > GPS_G2T_DIST_HOLD)
455
                                                        if (gps_g2t_act_v > 1) gps_g2t_act_v--;
-
 
456
                                                        gps_sub_state   = GPS_HOME_RMPDWN_OUTOF_TOL;
448
                                                        {
457
                                                }                                      
-
 
458
                                        }                                                      
-
 
459
                                        else  //Soll-Ziel fast erreicht, Jetzt noch Reste ausgleichen, weil Zielpunkt nicht exakt bestimmt werden konnte (Fehler in Winkelfkt) 
-
 
460
                                        {
449
                                                                if (gps_g2t_act_v < GPS_G2T_V_RAMP_DWN) gps_g2t_act_v++; //Geschwindigkeit langsam erhoehen
461
                                                if ((d1 < GPS_G2T_NRML_TOL)  && (d2 < GPS_G2T_NRML_TOL)) // Jetzt bis zum Zielpunkt regeln
-
 
462
                                                {
-
 
463
                                                        gps_sub_state   = GPS_HOME_IN_TOL;
450
                                                                dist_flown                              += (long)gps_g2t_act_v; // Vorgabe der Strecke anhand der Geschwindigkeit
464
                                                        hold_fast               = 0; // Wieder normal regeln
451
                                                                dist_frm_start_east             = (dist_flown * (long)sin_i(hdng_2home))/1000;
465
                                                        hold_reset_int  = 0; // Integrator wieder aktivieren              
452
                                                                dist_frm_start_north    = (dist_flown * (long)cos_i(hdng_2home))/1000;
466
                                                        if (gps_rel_hold_position.utm_east >= GPS_G2T_V_MIN) gps_rel_hold_position.utm_east -= GPS_G2T_V_MIN;
453
                                                                gps_rel_hold_position.utm_east  = gps_rel_start_position.utm_east + (int)dist_frm_start_east; //naechster Zielpunkt
467
                                                        else if (gps_rel_hold_position.utm_east <= -GPS_G2T_V_MIN ) gps_rel_hold_position.utm_east += GPS_G2T_V_MIN;
454
                                                                gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + (int)dist_frm_start_north; //naechster Zielpunkt
468
                                                        if (gps_rel_hold_position.utm_north >= GPS_G2T_V_MIN) gps_rel_hold_position.utm_north -= GPS_G2T_V_MIN;
455
                                                        }
-
 
456
                                                        else //Ziel fast erreicht, Jetzt noch Reste ausgleichen, weil Zielpunkt nicht exakt bestimmt werden konnte (Fehler in Winkelfkt) 
469
                                                        else if (gps_rel_hold_position.utm_north <= - GPS_G2T_V_MIN ) gps_rel_hold_position.utm_north += GPS_G2T_V_MIN;
-
 
470
                                                        if ((abs(gps_rel_hold_position.utm_east) <= GPS_G2T_V_MIN) && (abs(gps_rel_hold_position.utm_north) <=GPS_G2T_V_MIN))
457
                                                        {
471
                                                        {
458
                                                                hold_fast               = 0; // Wieder normal regeln
-
 
459
                                                                hold_reset_int  = 0; // Integrator wieder aktivieren              
-
 
460
                                                                if (gps_rel_hold_position.utm_east > GPS_G2T_V_MIN) gps_rel_hold_position.utm_east -= GPS_G2T_V_MIN;
-
 
461
                                                                else if (gps_rel_hold_position.utm_east < -GPS_G2T_V_MIN ) gps_rel_hold_position.utm_east += GPS_G2T_V_MIN;
-
 
462
                                                                if (gps_rel_hold_position.utm_north > GPS_G2T_V_MIN) gps_rel_hold_position.utm_north -= GPS_G2T_V_MIN;
-
 
463
                                                                else if (gps_rel_hold_position.utm_north < - GPS_G2T_V_MIN ) gps_rel_hold_position.utm_north += GPS_G2T_V_MIN;
-
 
464
                                                                if ((abs(gps_rel_hold_position.utm_east) <= GPS_G2T_V_MIN) && (abs(gps_rel_hold_position.utm_north) <=GPS_G2T_V_MIN))
-
 
465
                                                                {
-
 
466
                                                                        gps_rel_hold_position.utm_east  = 0;
472
                                                                gps_rel_hold_position.utm_east  = 0;
467
                                                                        gps_rel_hold_position.utm_north = 0;
473
                                                                gps_rel_hold_position.utm_north = 0;
468
                                                                        gps_sub_state                                   = GPS_HOME_FINISHED;
474
                                                                gps_sub_state                                   = GPS_HOME_FINISHED;
469
                                                                }
-
 
470
                                                        }
475
                                                        }
471
                                                }
476
                                                }
472
                                                else  
-
 
473
                                                {
-
 
474
                                                        gps_sub_state   = GPS_HOME_RMPDWN_OUTOF_TOL;   
-
 
475
                                                        if (gps_g2t_act_v > 0) gps_g2t_act_v--;
-
 
476
                                        }
-
 
477
                                        }                                              
477
                                        }                                      
478
                                        gps_state       = GPS_CRTL_HOLD_ACTIVE; //Zwischensprung
-
 
479
                                        return (GPS_STST_OK);
-
 
480
                                }
478
                                }
-
 
479
                                gps_state = GPS_CRTL_HOLD_ACTIVE; //Zwischensprung
481
                                else return (GPS_STST_OK);
480
                                return (GPS_STST_OK);                                  
482
                        }
481
                        }
483
                        else
482
                        else  // Keine GPS Daten verfuegbar, deswegen Abbruch
484
                        {
483
                        {
485
                                gps_state       =       GPS_CRTL_IDLE;          //Abbruch       
484
                                gps_state       =       GPS_CRTL_IDLE; 
486
                                return (GPS_STST_ERR);
485
                                return (GPS_STST_ERR);
487
                        }
486
                        }
488
                        break;
487
                        break;
489
 
488
 
490
 
489
 
491
                case GPS_CRTL_HOLD_ACTIVE:  // Hier werden die Daten fuer Nick und Roll errechnet
490
                case GPS_CRTL_HOLD_ACTIVE:  // Hier werden die Daten fuer Nick und Roll errechnet
492
                        if (gps_updte_flag >0)  // nur wenn neue GPS Daten vorliegen
491
                        if (gps_updte_flag >0)  // nur wenn neue GPS Daten vorliegen
493
                        {
492
                        {
494
                                gps_updte_flag = 0;
493
                                gps_updte_flag = 0;
495
                                // ab hier wird geregelt
494
                                // ab hier wird geregelt
496
                                diff_east       = -dist_east;     //Alten Wert fuer Differenzier schon mal abziehen
495
                                diff_east       = -dist_east;     //Alten Wert fuer Differenzier schon mal abziehen
497
                                diff_north      = -dist_north;
496
                                diff_north      = -dist_north;
498
                                dist_east       = gps_rel_hold_position.utm_east  - gps_rel_act_position.utm_east;
497
                                dist_east       = gps_rel_hold_position.utm_east  - gps_rel_act_position.utm_east;
499
                                dist_north      = gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north;
498
                                dist_north      = gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north;
500
                                int_east        += dist_east;
499
                                int_east        += dist_east;
501
                                int_north   += dist_north;
500
                                int_north   += dist_north;
502
                                diff_east       += dist_east;   // Differenz zur vorhergehenden East Position
501
                                diff_east       += dist_east;   // Differenz zur vorhergehenden East Position
503
                                diff_north      += dist_north;  // Differenz zur vorhergehenden North Position
502
                                diff_north      += dist_north;  // Differenz zur vorhergehenden North Position
504
/*
503
/*
505
                                diff_east_f             = ((diff_east_f )/4) + (diff_east*3/4); //Differenzierer filtern       
504
                                diff_east_f             = ((diff_east_f )/4) + (diff_east*3/4); //Differenzierer filtern       
506
                                diff_north_f    = ((diff_north_f)/4) + (diff_north*3/4); //Differenzierer filtern      
505
                                diff_north_f    = ((diff_north_f)/4) + (diff_north*3/4); //Differenzierer filtern      
507
*/
506
*/
508
                                #define GPSINT_MAX 30000 //neuer Wert ab 7.10.2007 Begrenzung 
507
                                #define GPSINT_MAX 30000 //neuer Wert ab 7.10.2007 Begrenzung 
509
                                if ((abs(int_east) > GPSINT_MAX) || (abs(int_north)> GPSINT_MAX)) //Bei zu hohem Wert Integrator auf Wert halten
508
                                if ((abs(int_east) > GPSINT_MAX) || (abs(int_north)> GPSINT_MAX)) //Bei zu hohem Wert Integrator auf Wert halten
510
                                {
509
                                {
511
                                        int_east        -= dist_east;
510
                                        int_east        -= dist_east;
512
                                        int_north   -= dist_north;                                     
511
                                        int_north   -= dist_north;                                     
513
                                }
512
                                }
514
                                if (hold_reset_int > 0)  //Im Schnellen Mode Integrator abschalten
513
                                if (hold_reset_int > 0)  //Im Schnellen Mode Integrator abschalten
515
                                {
514
                                {
516
                                        int_east        = 0;   
515
                                        int_east        = 0;   
517
                                        int_north       = 0;                                   
516
                                        int_north       = 0;                                   
518
                                }
517
                                }
519
 
518
 
520
                                // Variable Verstarkung fuer Differenzierer ermitteln. Je weiter vom Ziel wir entfernt sind
519
                                // Variable Verstarkung fuer Differenzierer ermitteln. Je weiter vom Ziel wir entfernt sind
521
                                // desto groesser wird der Faktor. Es gibt aber einen Maximalwert. Bei 0 ist die Verstaerkung immer 1
520
                                // desto groesser wird der Faktor. Es gibt aber einen Maximalwert. Bei 0 ist die Verstaerkung immer 1
522
                                #define GPS_DIFF_MAX_V 20 //maximale Verstaerkung * 10
-
 
523
                                #define GPS_DIFF_MAX_D 30 //Entfernung bei der maximale Verstaerkung erreicht wird in 10cm
-
 
524
                                signed long dist,int_east1,int_north1;
521
                                signed long dist,int_east1,int_north1;
525
                                int phi;
522
                                int phi;
526
                                phi = arctan_i(abs(dist_north),abs(dist_east));
523
                                phi = arctan_i(abs(dist_north),abs(dist_east));
527
                                dist = get_dist(dist_east,dist_north,phi); //Zunaechst Entfernung zum Ziel ermitteln
524
                                dist = (long) (get_dist(dist_east,dist_north,phi)); //Zunaechst Entfernung zum Ziel ermitteln
-
 
525
 
-
 
526
                                if (hold_fast == 0)  // je Nach Modus andere Verstaerkungskurve fuer Differenzierer
528
 
527
                                {
529
                                diff_v = (int)((dist * (GPS_DIFF_MAX_V - 10)) / GPS_DIFF_MAX_D) +10; //Verstaerkung * 10
528
                                        diff_v = (int)((dist * (GPS_DIFF_NRML_MAX_V - 10)) / GPS_DIFF_NRML_MAX_D) +10; //Verstaerkung * 10
-
 
529
                                        if (diff_v > GPS_DIFF_NRML_MAX_V) diff_v = GPS_DIFF_NRML_MAX_V; //begrenzen
-
 
530
                                }
-
 
531
                                else
-
 
532
                                {
530
                                if (diff_v > GPS_DIFF_MAX_V) diff_v = GPS_DIFF_MAX_V; //begrenzen
533
                                        diff_v = (int)((dist * (GPS_DIFF_FAST_MAX_V - 10)) / GPS_DIFF_FAST_MAX_D) +10; //Verstaerkung * 10
-
 
534
                                        if (diff_v > GPS_DIFF_FAST_MAX_V) diff_v = GPS_DIFF_FAST_MAX_V; //begrenzen
531
//                              if (hold_fast > 0) diff_v = 10;  //im schnellen Modus schwache Wirkung des Differenzierers
535
                                }
532
 
536
 
533
                                //I Werte begrenzen
537
                                //I Werte begrenzen
534
                                #define INT1_MAX (20 * GPS_V)
538
                                #define INT1_MAX (20 * GPS_V)
535
                                int_east1 =  ((((long)int_east)   * Parameter_UserParam2)/32);
539
                                int_east1 =  ((((long)int_east)   * Parameter_UserParam2)/32);
536
                                int_north =  ((((long)int_north)  * Parameter_UserParam2)/32);
540
                                int_north =  ((((long)int_north)  * Parameter_UserParam2)/32);
537
                                if (int_east1 > INT1_MAX) int_east1 =  INT1_MAX; //begrenzen
541
                                if (int_east1 > INT1_MAX) int_east1 =  INT1_MAX; //begrenzen
538
                                else if (int_east1 < -INT1_MAX) int_east1 =  -INT1_MAX;
542
                                else if (int_east1 < -INT1_MAX) int_east1 =  -INT1_MAX;
539
                                if (int_north1 > INT1_MAX) int_north1 =  INT1_MAX; //begrenzen
543
                                if (int_north1 > INT1_MAX) int_north1 =  INT1_MAX; //begrenzen
540
                                else if (int_north1 < -INT1_MAX) int_north1 =  -INT1_MAX;
544
                                else if (int_north1 < -INT1_MAX) int_north1 =  -INT1_MAX;
541
 
545
 
542
                                int diff_p;
546
                                int diff_p;
-
 
547
                                if (hold_fast == 0) diff_p = 1;  
543
                                if (hold_fast > 0) diff_p = 2;  //im schnellen Modus Proportionalanteil staerken
548
                                else diff_p = 2; //im schnellen Modus Proportionalanteil staerken
544
                                else diff_p = 1;
-
 
545
 
549
 
546
                                //PID Regler Werte aufsummieren
550
                                //PID Regler Werte aufsummieren
547
                                gps_reg_x = ((int)int_east1  + ((dist_east  * Parameter_UserParam1 * diff_p)/8)+ ((diff_east  * diff_v * Parameter_UserParam3)/10));  // I + P +D  Anteil X Achse
551
                                gps_reg_x = ((int)int_east1  + ((dist_east  * Parameter_UserParam1 * diff_p)/8)+ ((diff_east  * diff_v * Parameter_UserParam3)/10));  // I + P +D  Anteil X Achse
548
                                gps_reg_y = ((int)int_north1 + ((dist_north * Parameter_UserParam1 * diff_p)/8)+ ((diff_north * diff_v * Parameter_UserParam3)/10));  // I + P +D  Anteil Y Achse
552
                                gps_reg_y = ((int)int_north1 + ((dist_north * Parameter_UserParam1 * diff_p)/8)+ ((diff_north * diff_v * Parameter_UserParam3)/10));  // I + P +D  Anteil Y Achse
549
 
553
 
550
                                //Ziel-Richtung bezogen auf Nordpol bestimmen
554
                                //Ziel-Richtung bezogen auf Nordpol bestimmen
551
                                GPS_hdng_abs_2trgt = arctan_i(gps_reg_x,gps_reg_y);
555
                                GPS_hdng_abs_2trgt = arctan_i(gps_reg_x,gps_reg_y);
552
 
556
 
553
                                // in Winkel 0...360 Grad umrechnen
557
                                // in Winkel 0...360 Grad umrechnen
554
                                if ((gps_reg_x >= 0)) GPS_hdng_abs_2trgt = ( 90-GPS_hdng_abs_2trgt);
558
                                if ((gps_reg_x >= 0)) GPS_hdng_abs_2trgt = ( 90-GPS_hdng_abs_2trgt);
555
                                else  GPS_hdng_abs_2trgt = (270 - GPS_hdng_abs_2trgt);
559
                                else  GPS_hdng_abs_2trgt = (270 - GPS_hdng_abs_2trgt);
556
 
560
 
557
                                // Relative Richtung in bezug auf Nordachse des Kopters errechen
561
                                // Relative Richtung in bezug auf Nordachse des Kopters errechen
558
                                n= GyroKomp_Int/GYROKOMP_INC_GRAD_DEFAULT;
562
                                n= GyroKomp_Int/GYROKOMP_INC_GRAD_DEFAULT;
559
                                GPS_hdng_rel_2trgt      =       GPS_hdng_abs_2trgt - n;
563
                                GPS_hdng_rel_2trgt      =       GPS_hdng_abs_2trgt - n;
560
                                if      ((GPS_hdng_rel_2trgt >180) && (GPS_hdng_abs_2trgt >=180)) GPS_hdng_rel_2trgt = GPS_hdng_rel_2trgt-360;
564
                                if      ((GPS_hdng_rel_2trgt >180) && (GPS_hdng_abs_2trgt >=180)) GPS_hdng_rel_2trgt = GPS_hdng_rel_2trgt-360;
561
                                else if (GPS_hdng_rel_2trgt >180)  GPS_hdng_rel_2trgt = 360 - GPS_hdng_rel_2trgt;
565
                                else if (GPS_hdng_rel_2trgt >180)  GPS_hdng_rel_2trgt = 360 - GPS_hdng_rel_2trgt;
562
                                else if (GPS_hdng_rel_2trgt <-180)  GPS_hdng_rel_2trgt = 360 + GPS_hdng_rel_2trgt;
566
                                else if (GPS_hdng_rel_2trgt <-180)  GPS_hdng_rel_2trgt = 360 + GPS_hdng_rel_2trgt;
563
                               
567
                               
564
                                // Regelabweichung aus x,y zu Ziel in Distanz umrechnen 
568
                                // Regelabweichung aus x,y zu Ziel in Distanz umrechnen 
565
                                if (abs(gps_reg_x) > abs(gps_reg_y) )
569
                                if (abs(gps_reg_x) > abs(gps_reg_y) )
566
                                {
570
                                {
567
                                        dev = (long)gps_reg_x; //Groesseren Wert wegen besserer Genauigkeit nehmen
571
                                        dev = (long)gps_reg_x; //Groesseren Wert wegen besserer Genauigkeit nehmen
568
                                        dev = abs((dev *1000) / (long) sin_i(GPS_hdng_abs_2trgt));
572
                                        dev = abs((dev *1000) / (long) sin_i(GPS_hdng_abs_2trgt));
569
                                }
573
                                }
570
                                else
574
                                else
571
                                {
575
                                {
572
                                        dev = (long)gps_reg_y;
576
                                        dev = (long)gps_reg_y;
573
                                        dev = abs((dev *1000) / (long) cos_i(GPS_hdng_abs_2trgt));
577
                                        dev = abs((dev *1000) / (long) cos_i(GPS_hdng_abs_2trgt));
574
                                }
578
                                }
575
                                GPS_dist_2trgt  = (int) dev;
579
                                GPS_dist_2trgt  = (int) dev;
576
                                // Winkel und Distanz in Nick und Rollgroessen umrechnen
580
                                // Winkel und Distanz in Nick und Rollgroessen umrechnen
577
                                GPS_Roll = (int) +( (dev * (long) sin_i(GPS_hdng_rel_2trgt))/1000);
581
                                GPS_Roll = (int) +( (dev * (long) sin_i(GPS_hdng_rel_2trgt))/1000);
578
                                GPS_Nick = (int) -( (dev * (long) cos_i(GPS_hdng_rel_2trgt))/1000);
582
                                GPS_Nick = (int) -( (dev * (long) cos_i(GPS_hdng_rel_2trgt))/1000);
579
                                       
583
                                       
580
                                if (GPS_Roll > (GPS_NICKROLL_MAX * GPS_V)) GPS_Roll = (GPS_NICKROLL_MAX * GPS_V);
584
                                if (GPS_Roll > (GPS_NICKROLL_MAX * GPS_V)) GPS_Roll = (GPS_NICKROLL_MAX * GPS_V);
581
                                else if (GPS_Roll < -(GPS_NICKROLL_MAX * GPS_V)) GPS_Roll = -(GPS_NICKROLL_MAX * GPS_V);
585
                                else if (GPS_Roll < -(GPS_NICKROLL_MAX * GPS_V)) GPS_Roll = -(GPS_NICKROLL_MAX * GPS_V);
582
                                if (GPS_Nick > (GPS_NICKROLL_MAX * GPS_V)) GPS_Nick = (GPS_NICKROLL_MAX * GPS_V);
586
                                if (GPS_Nick > (GPS_NICKROLL_MAX * GPS_V)) GPS_Nick = (GPS_NICKROLL_MAX * GPS_V);
583
                                else if (GPS_Nick < -(GPS_NICKROLL_MAX * GPS_V)) GPS_Nick = -(GPS_NICKROLL_MAX * GPS_V);
587
                                else if (GPS_Nick < -(GPS_NICKROLL_MAX * GPS_V)) GPS_Nick = -(GPS_NICKROLL_MAX * GPS_V);
584
 
588
 
585
                                //Kleine Werte verstaerken, Grosse abschwaechen
589
                                //Kleine Werte verstaerken, Grosse abschwaechen
586
                                n                       = sin_i((GPS_Roll*90)/(GPS_NICKROLL_MAX * GPS_V));
590
                                n                       = sin_i((GPS_Roll*90)/(GPS_NICKROLL_MAX * GPS_V));
587
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
591
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
588
                                GPS_Roll        = (int) n_l;
592
                                GPS_Roll        = (int) n_l;
589
                                n                       = sin_i((GPS_Nick*90)/(GPS_NICKROLL_MAX * GPS_V));
593
                                n                       = sin_i((GPS_Nick*90)/(GPS_NICKROLL_MAX * GPS_V));
590
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
594
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
591
                                GPS_Nick        = (int) n_l;
595
                                GPS_Nick        = (int) n_l;
592
                                 
596
                                 
593
                                if ((abs(dist_east) > GPS_DIST_MAX) || (abs(dist_north) > GPS_DIST_MAX))  // bei zu grossem Abstand abbrechen
597
                                if ((abs(dist_east) > GPS_DIST_MAX) || (abs(dist_north) > GPS_DIST_MAX))  // bei zu grossem Abstand abbrechen
594
                                {
598
                                {
595
                                        GPS_Roll        = 0;
599
                                        GPS_Roll        = 0;
596
                                        GPS_Nick        = 0;
600
                                        GPS_Nick        = 0;
597
                                        gps_state       = GPS_CRTL_IDLE;
601
                                        gps_state       = GPS_CRTL_IDLE;
598
                                        return (GPS_STST_ERR); 
602
                                        return (GPS_STST_ERR); 
599
                                        break;                                 
603
                                        break;                                 
600
                                }
604
                                }
601
                                else
605
                                else
602
                                {
606
                                {
603
                                        if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
607
                                        if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
604
                                        return (GPS_STST_OK);
608
                                        return (GPS_STST_OK);
605
                                }
609
                                }
606
                        }
610
                        }
607
                        else
611
                        else
608
                        {
612
                        {
609
                                if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
613
                                if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
610
                                return (GPS_STST_OK);
614
                                return (GPS_STST_OK);
611
                        }
615
                        }
612
                        break;
616
                        break;
613
 
617
 
614
                default:
618
                default:
615
                        gps_state = GPS_CRTL_IDLE;
619
                        gps_state = GPS_CRTL_IDLE;
616
                        return (GPS_STST_ERR);
620
                        return (GPS_STST_ERR);
617
                        break;
621
                        break;
618
        }      
622
        }      
619
        return (GPS_STST_ERR);
623
        return (GPS_STST_ERR);
620
                       
624
                       
621
}
625
}
622
 
626
 
623
 
627