Subversion Repositories FlightCtrl

Rev

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

Rev 258 Rev 266
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 8.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 int                      hdng_2home,dist_2home; //Richtung und Entfernung zur home Position 
59
signed int                      hdng_2home,dist_2home; //Richtung und Entfernung zur home Position 
60
static 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
        gps_sub_state                           =       GPS_CRTL_IDLE;
83
        actual_pos.status                       =       0;
84
        actual_pos.status                       =       0;
84
        actual_speed.status                     =       0;
85
        actual_speed.status                     =       0;
85
        actual_status.status            =       0;
86
        actual_status.status            =       0;
86
        gps_home_position.status        =       0; // Noch keine gueltige Home Position
87
        gps_home_position.status        =       0; // Noch keine gueltige Home Position
87
        gps_act_position.status         =       0;
88
        gps_act_position.status         =       0;
88
        gps_rel_act_position.status     =       0;     
89
        gps_rel_act_position.status     =       0;     
89
        GPS_Nick                                        =       0;
90
        GPS_Nick                                        =       0;
90
        GPS_Roll                                        =       0;
91
        GPS_Roll                                        =       0;
91
        gps_updte_flag                          =       0;
92
        gps_updte_flag                          =       0;
92
        gps_int_x                                       =       0;
93
        gps_int_x                                       =       0;
93
        gps_int_y                                       =       0;
94
        gps_int_y                                       =       0;
94
        gps_alive_cnt                           =       0;
95
        gps_alive_cnt                           =       0;
95
}
96
}
96
 
97
 
97
// Home Position sichern falls Daten verfuegbar sind. 
98
// Home Position sichern falls Daten verfuegbar sind. 
98
void GPS_Save_Home(void)
99
void GPS_Save_Home(void)
99
{
100
{
100
        short int n;
101
        short int n;
101
        n = Get_GPS_data();
102
        n = Get_GPS_data();
102
        if (n == 0)   // Gueltige  und aktuelle Daten ?   
103
        if (n == 0)   // Gueltige  und aktuelle Daten ?   
103
        {
104
        {
104
                // Neue GPS Daten liegen vor
105
                // Neue GPS Daten liegen vor
105
                gps_home_position.utm_east      = gps_act_position.utm_east;   
106
                gps_home_position.utm_east      = gps_act_position.utm_east;   
106
                gps_home_position.utm_north     = gps_act_position.utm_north;  
107
                gps_home_position.utm_north     = gps_act_position.utm_north;  
107
                gps_home_position.utm_alt       = gps_act_position.utm_alt;
108
                gps_home_position.utm_alt       = gps_act_position.utm_alt;
108
                gps_home_position.status        = 1; // Home Position gueltig                   
109
                gps_home_position.status        = 1; // Home Position gueltig                   
109
        }
110
        }
110
}
111
}
111
 
112
 
112
// Relative Position zur Home Position bestimmen
113
// Relative Position zur Home Position bestimmen
113
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
114
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
114
short int Get_Rel_Position(void)
115
short int Get_Rel_Position(void)
115
{
116
{
116
        short int n = 0;
117
        short int n = 0;
117
        n = Get_GPS_data();
118
        n = Get_GPS_data();
118
        if (n >=1) return (n); // nix zu tun, weil keine neue Daten da sind
119
        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
120
        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
121
        if  (gps_home_position.status > 0) //Nur wenn Home Position vorliegt
121
        {
122
        {
122
                gps_rel_act_position.utm_east   = (int)  (gps_act_position.utm_east - gps_home_position.utm_east);
123
                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);
124
                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
125
                gps_rel_act_position.status     = 1; // gueltige Positionsdaten
125
                n = 0;
126
                n = 0;
126
                gps_updte_flag = 1; // zeigt an, dass neue Daten vorliegen.
127
                gps_updte_flag = 1; // zeigt an, dass neue Daten vorliegen.
127
        }
128
        }
128
        else
129
        else
129
        {
130
        {
130
                n = 2; //keine gueltigen Daten vorhanden
131
                n = 2; //keine gueltigen Daten vorhanden
131
                gps_rel_act_position.status = 0; //keine gueltige Position weil keine home Position da ist.
132
                gps_rel_act_position.status = 0; //keine gueltige Position weil keine home Position da ist.
132
        }      
133
        }      
133
        return (n);
134
        return (n);
134
}
135
}
135
 
136
 
136
// Daten aus aktuellen ublox Messages extrahieren 
137
// Daten aus aktuellen ublox Messages extrahieren 
137
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
138
// Rueckgabewert 0= Daten sind aktuell und gueltig. 1= Keine Aenderung. 2= Daten ungueltig
138
short int Get_GPS_data(void)
139
short int Get_GPS_data(void)
139
{
140
{
140
        short int n = 1;
141
        short int n = 1;
141
 
142
 
142
        if (actual_pos.status == 0) return (1); //damit es schnell geht, wenn nix zu tun ist
143
        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))
144
        if ((actual_pos.status > 0) && (actual_status.status > 0) && (actual_speed.status > 0))
144
        {
145
        {
145
                if (((actual_status.gpsfix_type & 0x03) >=2) && ((actual_status.nav_status_flag & 0x01) >=1)) // nur wenn Daten aktuell und gueltig sind
146
                if (((actual_status.gpsfix_type & 0x03) >=2) && ((actual_status.nav_status_flag & 0x01) >=1)) // nur wenn Daten aktuell und gueltig sind
146
                {
147
                {
147
                        gps_act_position.utm_east       = actual_pos.utm_east/10;
148
                        gps_act_position.utm_east       = actual_pos.utm_east/10;
148
                        gps_act_position.utm_north      = actual_pos.utm_north/10;
149
                        gps_act_position.utm_north      = actual_pos.utm_north/10;
149
                        gps_act_position.utm_alt        = actual_pos.utm_alt/10;
150
                        gps_act_position.utm_alt        = actual_pos.utm_alt/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.speed_gnd      = actual_speed.speed_gnd/10;
152
                        gps_act_position.heading        = actual_speed.heading/100000;
153
                        gps_act_position.heading        = actual_speed.heading/100000;
153
                        gps_act_position.status         = 1;
154
                        gps_act_position.status         = 1;
154
                        n                                                       = 0; //Daten gueltig
155
                        n                                                       = 0; //Daten gueltig
155
                }
156
                }
156
                else
157
                else
157
                {
158
                {
158
                        gps_act_position.status = 0; //Keine gueltigen Daten
159
                        gps_act_position.status = 0; //Keine gueltigen Daten
159
                        n                                               = 2;
160
                        n                                               = 2;
160
                }
161
                }
161
                actual_pos.status               = 0; //neue ublox Messages anfordern
162
                actual_pos.status               = 0; //neue ublox Messages anfordern
162
                actual_status.status    = 0;
163
                actual_status.status    = 0;
163
                actual_speed.status     = 0;
164
                actual_speed.status     = 0;
164
        }      
165
        }      
165
        return (n);    
166
        return (n);    
166
}
167
}
167
 
168
 
168
/*
169
/*
169
Daten vom GPS im ublox MSG Format auswerten
170
Daten vom GPS im ublox MSG Format auswerten
170
Die Routine wird bei jedem Empfang eines Zeichens vom GPS Modul durch den UART IRQ aufgerufen
171
Die Routine wird bei jedem Empfang eines Zeichens vom GPS Modul durch den UART IRQ aufgerufen
171
// Die UBX Messages NAV_POSUTM, NAV_STATUS und NAV_VALED muessen aktiviert sein
172
// Die UBX Messages NAV_POSUTM, NAV_STATUS und NAV_VALED muessen aktiviert sein
172
*/
173
*/
173
void Get_Ublox_Msg(uint8_t rx)
174
void Get_Ublox_Msg(uint8_t rx)
174
{
175
{
175
        switch (ublox_msg_state)
176
        switch (ublox_msg_state)
176
        {
177
        {
177
 
178
 
178
                case UBLOX_IDLE: // Zuerst Synchcharacters pruefen
179
                case UBLOX_IDLE: // Zuerst Synchcharacters pruefen
179
                        if ( rx == UBLOX_SYNCH1_CHAR ) ublox_msg_state = UBLOX_SYNC1;
180
                        if ( rx == UBLOX_SYNCH1_CHAR ) ublox_msg_state = UBLOX_SYNC1;
180
                        else ublox_msg_state = UBLOX_IDLE;
181
                        else ublox_msg_state = UBLOX_IDLE;
181
                        break;
182
                        break;
182
 
183
 
183
                case UBLOX_SYNC1:
184
                case UBLOX_SYNC1:
184
 
185
 
185
                        if (rx == UBLOX_SYNCH2_CHAR) ublox_msg_state = UBLOX_SYNC2;
186
                        if (rx == UBLOX_SYNCH2_CHAR) ublox_msg_state = UBLOX_SYNC2;
186
                        else ublox_msg_state = UBLOX_IDLE;
187
                        else ublox_msg_state = UBLOX_IDLE;
187
                        chk_a = 0,chk_b = 0;
188
                        chk_a = 0,chk_b = 0;
188
                        break;
189
                        break;
189
 
190
 
190
                case UBLOX_SYNC2:
191
                case UBLOX_SYNC2:
191
                        if (rx == UBLOX_NAV_CLASS) ublox_msg_state = UBLOX_CLASS;      
192
                        if (rx == UBLOX_NAV_CLASS) ublox_msg_state = UBLOX_CLASS;      
192
                        else ublox_msg_state = UBLOX_IDLE;
193
                        else ublox_msg_state = UBLOX_IDLE;
193
                        break;
194
                        break;
194
 
195
 
195
                case UBLOX_CLASS: // Nur NAV Meldungen auswerten
196
                case UBLOX_CLASS: // Nur NAV Meldungen auswerten
196
                        switch (rx)
197
                        switch (rx)
197
                        {
198
                        {
198
                                case UBLOX_NAV_POSUTM:
199
                                case UBLOX_NAV_POSUTM:
199
                                        ptr_pac_status  =       &actual_pos.status;
200
                                        ptr_pac_status  =       &actual_pos.status;
200
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE; //Abbruch weil Daten noch nicht verwendet wurden
201
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE; //Abbruch weil Daten noch nicht verwendet wurden
201
                                        else
202
                                        else
202
                                        {
203
                                        {
203
                                                ptr_payload_data                = &actual_pos;
204
                                                ptr_payload_data                = &actual_pos;
204
                                                ptr_payload_data_end    = &actual_pos.status;
205
                                                ptr_payload_data_end    = &actual_pos.status;
205
                                                ublox_msg_state                 = UBLOX_LEN1;
206
                                                ublox_msg_state                 = UBLOX_LEN1;
206
                                        }
207
                                        }
207
                                        break;
208
                                        break;
208
 
209
 
209
                                case UBLOX_NAV_STATUS:
210
                                case UBLOX_NAV_STATUS:
210
                                        ptr_pac_status  =       &actual_status.status;
211
                                        ptr_pac_status  =       &actual_status.status;
211
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
212
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
212
                                        else
213
                                        else
213
                                        {
214
                                        {
214
                                                ptr_payload_data                = &actual_status;
215
                                                ptr_payload_data                = &actual_status;
215
                                                ptr_payload_data_end    = &actual_status.status;
216
                                                ptr_payload_data_end    = &actual_status.status;
216
                                                ublox_msg_state                 = UBLOX_LEN1;
217
                                                ublox_msg_state                 = UBLOX_LEN1;
217
                                        }
218
                                        }
218
                                        break;
219
                                        break;
219
 
220
 
220
                                case UBLOX_NAV_VELED:
221
                                case UBLOX_NAV_VELED:
221
                                        ptr_pac_status          =       &actual_speed.status;
222
                                        ptr_pac_status          =       &actual_speed.status;
222
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
223
                                        if (*ptr_pac_status > 0) ublox_msg_state = UBLOX_IDLE;
223
                                        else
224
                                        else
224
                                        {
225
                                        {
225
                                                ptr_payload_data                = &actual_speed;
226
                                                ptr_payload_data                = &actual_speed;
226
                                                ptr_payload_data_end    = &actual_speed.status;
227
                                                ptr_payload_data_end    = &actual_speed.status;
227
                                                ublox_msg_state                 = UBLOX_LEN1;
228
                                                ublox_msg_state                 = UBLOX_LEN1;
228
                                        }
229
                                        }
229
                                        break;
230
                                        break;
230
 
231
 
231
                                default:
232
                                default:
232
                                        ublox_msg_state = UBLOX_IDLE;
233
                                        ublox_msg_state = UBLOX_IDLE;
233
                                        break; 
234
                                        break; 
234
                        }
235
                        }
235
                        chk_a   = UBLOX_NAV_CLASS + rx;
236
                        chk_a   = UBLOX_NAV_CLASS + rx;
236
                        chk_b   = UBLOX_NAV_CLASS + chk_a;                     
237
                        chk_b   = UBLOX_NAV_CLASS + chk_a;                     
237
                        break;
238
                        break;
238
 
239
 
239
                case UBLOX_LEN1: // Laenge auswerten
240
                case UBLOX_LEN1: // Laenge auswerten
240
                        rx_len  = rx;
241
                        rx_len  = rx;
241
                        chk_a   += rx;
242
                        chk_a   += rx;
242
                        chk_b   += chk_a;              
243
                        chk_b   += chk_a;              
243
                        ublox_msg_state = UBLOX_LEN2;
244
                        ublox_msg_state = UBLOX_LEN2;
244
                        break;
245
                        break;
245
 
246
 
246
 
247
 
247
                case UBLOX_LEN2: // Laenge auswerten
248
                case UBLOX_LEN2: // Laenge auswerten
248
                        rx_len = rx_len + (rx *256); // Laenge ermitteln
249
                        rx_len = rx_len + (rx *256); // Laenge ermitteln
249
                        chk_a   += rx;
250
                        chk_a   += rx;
250
                        chk_b   += chk_a;      
251
                        chk_b   += chk_a;      
251
                        ublox_msg_state = UBLOX_PAYLOAD;
252
                        ublox_msg_state = UBLOX_PAYLOAD;
252
                        break;
253
                        break;
253
 
254
 
254
                case UBLOX_PAYLOAD: // jetzt Nutzdaten einlesen
255
                case UBLOX_PAYLOAD: // jetzt Nutzdaten einlesen
255
                        if (rx_len > 0)
256
                        if (rx_len > 0)
256
                        {
257
                        {
257
                                *ptr_payload_data = rx;
258
                                *ptr_payload_data = rx;
258
                                chk_a   += rx;
259
                                chk_a   += rx;
259
                                chk_b   += chk_a;
260
                                chk_b   += chk_a;
260
                                --rx_len;      
261
                                --rx_len;      
261
                                if ((rx_len > 0) && (ptr_payload_data <= ptr_payload_data_end))                          
262
                                if ((rx_len > 0) && (ptr_payload_data <= ptr_payload_data_end))                          
262
                                {
263
                                {
263
                                        ptr_payload_data++;
264
                                        ptr_payload_data++;
264
                                        ublox_msg_state = UBLOX_PAYLOAD;
265
                                        ublox_msg_state = UBLOX_PAYLOAD;
265
                            }
266
                            }
266
                                else ublox_msg_state = UBLOX_CKA;
267
                                else ublox_msg_state = UBLOX_CKA;
267
                        }      
268
                        }      
268
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
269
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
269
                        break;
270
                        break;
270
 
271
 
271
                case UBLOX_CKA: // Checksum pruefen
272
                case UBLOX_CKA: // Checksum pruefen
272
                        if (rx == chk_a) ublox_msg_state = UBLOX_CKB;                          
273
                        if (rx == chk_a) ublox_msg_state = UBLOX_CKB;                          
273
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
274
                        else ublox_msg_state = UBLOX_IDLE; // Abbruch wegen Fehler
274
                        break;
275
                        break;
275
 
276
 
276
                case UBLOX_CKB: // Checksum pruefen
277
                case UBLOX_CKB: // Checksum pruefen
277
                        if (rx == chk_b) *ptr_pac_status = 1; // Paket ok
278
                        if (rx == chk_b) *ptr_pac_status = 1; // Paket ok
278
                        ublox_msg_state    = UBLOX_IDLE;
279
                        ublox_msg_state    = UBLOX_IDLE;
279
                        break;
280
                        break;
280
 
281
 
281
                default:
282
                default:
282
                        ublox_msg_state = UBLOX_IDLE;          
283
                        ublox_msg_state = UBLOX_IDLE;          
283
                        break;
284
                        break;
284
        }
285
        }
285
}
286
}
286
       
287
       
287
//Zentrale Statemachine fuer alle GPS relevanten Regelungsablauefe
288
//Zentrale Statemachine fuer alle GPS relevanten Regelungsablauefe
288
short int GPS_CRTL(short int cmd)
289
short int GPS_CRTL(short int cmd)
289
{
290
{
290
        static unsigned int cnt;                                        //Zaehler fuer diverse Verzoegerungen 
291
        static unsigned int cnt;                                        //Zaehler fuer diverse Verzoegerungen 
291
        static signed int int_east,int_north;   //Integrierer 
292
        static signed int int_east,int_north;   //Integrierer 
292
        static signed int dist_north,dist_east;
293
        static signed int dist_north,dist_east;
293
        static signed int diff_east,diff_north;         // Differenzierer  (Differenz zum  vorhergehenden x bzw. y  Wert)
294
        static signed int diff_east,diff_north;         // Differenzierer  (Differenz zum  vorhergehenden x bzw. y  Wert)
294
        static signed int diff_east_f,diff_north_f; // Differenzierer,  gefiltert
295
        static signed int diff_east_f,diff_north_f; // Differenzierer,  gefiltert
295
        signed int n,diff_v;
296
        signed int n,diff_v;
296
        static signed int gps_g2t_act_v; // Aktuelle Geschwindigkeitsvorgabe fuer Home Funktion
297
        static signed int gps_g2t_act_v; // Aktuelle Geschwindigkeitsvorgabe fuer Home Funktion
297
        long signed int dev,n_l;
298
        long signed int dev,n_l;
298
        signed int dist_frm_start_east,dist_frm_start_north;
299
        signed int dist_frm_start_east,dist_frm_start_north;
299
        switch (cmd)
300
        switch (cmd)
300
        {
301
        {
301
 
302
 
302
                case GPS_CMD_REQ_HOME: // Es soll zum Startpunkt zurueckgeflogen werden. 
303
                case GPS_CMD_REQ_HOME: // Es soll zum Startpunkt zurueckgeflogen werden. 
303
                        if ((gps_state != GPS_CRTL_HOLD_ACTIVE) && (gps_state != GPS_CRTL_HOME_ACTIVE))
304
                        if ((gps_state != GPS_CRTL_HOLD_ACTIVE) && (gps_state != GPS_CRTL_HOME_ACTIVE))
304
                        {
305
                        {
305
                                cnt++;
306
                                cnt++;
306
                                if (cnt > 500) // erst nach Verzoegerung 
307
                                if (cnt > 500) // erst nach Verzoegerung 
307
                                {
308
                                {
308
                                        // Erst mal initialisieren
309
                                        // Erst mal initialisieren
309
                                        cnt                             = 0;
310
                                        cnt                             = 0;
310
                                        gps_tick                = 0;                                   
311
                                        gps_tick                = 0;                                   
311
                                        hold_fast               = 0;
312
                                        hold_fast               = 0;
312
                                        hold_reset_int  = 0; // Integrator enablen
313
                                        hold_reset_int  = 0; // Integrator enablen
313
                                        int_east                = 0, int_north  = 0;
314
                                        int_east                = 0, int_north  = 0;
314
                                        gps_reg_x               = 0, gps_reg_y  = 0;
315
                                        gps_reg_x               = 0, gps_reg_y  = 0;
315
                                        dist_east               = 0, dist_north = 0;
316
                                        dist_east               = 0, dist_north = 0;
316
                                        diff_east_f             = 0, diff_north_f= 0;
317
                                        diff_east_f             = 0, diff_north_f= 0;
317
                                        diff_east               = 0, diff_north  = 0;  
318
                                        diff_east               = 0, diff_north  = 0;  
318
                                        dist_flown              = 0;
319
                                        dist_flown              = 0;
319
                                        gps_g2t_act_v   = 0;
320
                                        gps_g2t_act_v   = 0;
320
                                        gps_sub_state   = GPS_CRTL_IDLE;
321
                                        gps_sub_state   = GPS_CRTL_IDLE;
321
                                        // aktuelle positionsdaten abspeichern
322
                                        // aktuelle positionsdaten abspeichern
322
                                        if (gps_rel_act_position.status > 0)
323
                                        if (gps_rel_act_position.status > 0)
323
                                        {
324
                                        {
324
                                                gps_rel_start_position.utm_east = gps_rel_act_position.utm_east;
325
                                                gps_rel_start_position.utm_east = gps_rel_act_position.utm_east;
325
                                                gps_rel_start_position.utm_north= gps_rel_act_position.utm_north;
326
                                                gps_rel_start_position.utm_north= gps_rel_act_position.utm_north;
326
                                                gps_rel_start_position.status   = 1; // gueltige Positionsdaten 
327
                                                gps_rel_start_position.status   = 1; // gueltige Positionsdaten 
327
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
328
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
328
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
329
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
329
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
330
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
330
                                                //Richtung zur Home Positionbezogen auf Nordpol bestimmen
331
                                                //Richtung zur Home Positionbezogen auf Nordpol bestimmen
331
                                                hdng_2home = arctan_i(-gps_rel_start_position.utm_east,-gps_rel_start_position.utm_north);
332
                                                hdng_2home = arctan_i(-gps_rel_start_position.utm_east,-gps_rel_start_position.utm_north);
332
                                                // in Winkel 0...360 Grad umrechnen
333
                                                // in Winkel 0...360 Grad umrechnen
333
                                                if (( gps_rel_start_position.utm_east < 0)) hdng_2home = ( 90-hdng_2home);
334
                                                if (( gps_rel_start_position.utm_east < 0)) hdng_2home = ( 90-hdng_2home);
334
                                                else  hdng_2home = (270 - hdng_2home);
335
                                                else  hdng_2home = (270 - hdng_2home);
335
                                                dist_2home = get_dist(gps_rel_start_position.utm_east,gps_rel_start_position.utm_north,hdng_2home); //Entfernung zur Home Position bestimmen
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
336
                                                gps_state       = GPS_CRTL_HOME_ACTIVE;
337
                                                gps_state       = GPS_CRTL_HOME_ACTIVE;
337
                                                return (GPS_STST_OK);                          
338
                                                return (GPS_STST_OK);                          
338
                                        }
339
                                        }
339
                                        else
340
                                        else
340
                                        {
341
                                        {
341
                                                gps_rel_start_position.status   =       0;  //Keine Daten verfuegbar
342
                                                gps_rel_start_position.status   =       0;  //Keine Daten verfuegbar
342
                                                gps_state                                               = GPS_CRTL_IDLE;
343
                                                gps_state                                               = GPS_CRTL_IDLE;
343
                                                return(GPS_STST_ERR); // Keine Daten da
344
                                                return(GPS_STST_ERR); // Keine Daten da
344
                                        }
345
                                        }
345
                                }
346
                                }
346
                                else return(GPS_STST_PEND); // noch warten
347
                                else return(GPS_STST_PEND); // noch warten
347
                        }
348
                        }
348
                   break;
349
                   break;
349
// ******************************
350
// ******************************
350
 
351
 
351
                case GPS_CMD_REQ_HOLD: // Die Lageregelung soll aktiviert werden.
352
                case GPS_CMD_REQ_HOLD: // Die Lageregelung soll aktiviert werden.
352
                        if (gps_state != GPS_CRTL_HOLD_ACTIVE)
353
                        if (gps_state != GPS_CRTL_HOLD_ACTIVE)
353
                        {
354
                        {
354
                                cnt++;
355
                                cnt++;
355
                                if (cnt > 500) // erst nach Verzoegerung 
356
                                if (cnt > 500) // erst nach Verzoegerung 
356
                                {
357
                                {
357
                                        cnt     =       0;
358
                                        cnt     =       0;
358
                                        // aktuelle positionsdaten abspeichern
359
                                        // aktuelle positionsdaten abspeichern
359
                                        if (gps_rel_act_position.status > 0)
360
                                        if (gps_rel_act_position.status > 0)
360
                                        {
361
                                        {
361
                                                hold_fast               = 0;
362
                                                hold_fast               = 0;
362
                                                hold_reset_int  = 0; // Integrator enablen
363
                                                hold_reset_int  = 0; // Integrator enablen
363
                                                int_east        = 0, int_north  = 0;
364
                                                int_east        = 0, int_north  = 0;
364
                                                gps_reg_x       = 0, gps_reg_y  = 0;
365
                                                gps_reg_x       = 0, gps_reg_y  = 0;
365
                                                dist_east       = 0, dist_north = 0;
366
                                                dist_east       = 0, dist_north = 0;
366
                                                diff_east_f     = 0, diff_north_f= 0;
367
                                                diff_east_f     = 0, diff_north_f= 0;
367
                                                diff_east       = 0, diff_north  = 0;
368
                                                diff_east       = 0, diff_north  = 0;
368
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
369
                                                gps_rel_hold_position.utm_east  = gps_rel_act_position.utm_east;
369
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
370
                                                gps_rel_hold_position.utm_north = gps_rel_act_position.utm_north;
370
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
371
                                                gps_rel_hold_position.status    = 1; // gueltige Positionsdaten 
371
                                                gps_state                                               = GPS_CRTL_HOLD_ACTIVE;
372
                                                gps_state                                               = GPS_CRTL_HOLD_ACTIVE;
372
                                                return (GPS_STST_OK);                          
373
                                                return (GPS_STST_OK);                          
373
                                        }
374
                                        }
374
                                        else
375
                                        else
375
                                        {
376
                                        {
376
                                                gps_rel_hold_position.status    =       0;  //Keine Daten verfuegbar
377
                                                gps_rel_hold_position.status    =       0;  //Keine Daten verfuegbar
377
                                                gps_state                                               = GPS_CRTL_IDLE;
378
                                                gps_state                                               = GPS_CRTL_IDLE;
378
                                                return(GPS_STST_ERR); // Keine Daten da
379
                                                return(GPS_STST_ERR); // Keine Daten da
379
                                        }
380
                                        }
380
                                }
381
                                }
381
                                else return(GPS_STST_PEND); // noch warten
382
                                else return(GPS_STST_PEND); // noch warten
382
                        }
383
                        }
383
                        break;
384
                        break;
384
 
385
 
385
                case GPS_CMD_STOP: // Lageregelung beenden
386
                case GPS_CMD_STOP: // Lageregelung beenden
386
                        cnt                             =       0;
387
                        cnt                             =       0;
387
                        GPS_Nick                =       0;
388
                        GPS_Nick                =       0;
388
                        GPS_Roll                =       0;
389
                        GPS_Roll                =       0;
389
                        gps_int_x               =       0;
390
                        gps_int_x               =       0;
390
                        gps_int_y               =       0;
391
                        gps_int_y               =       0;
-
 
392
                        gps_sub_state   =       GPS_CRTL_IDLE;
391
                        gps_state       =       GPS_CRTL_IDLE;
393
                        gps_state               =       GPS_CRTL_IDLE;
392
                        return (GPS_STST_OK);
394
                        return (GPS_STST_OK);
393
                        break;
395
                        break;
394
 
396
 
395
                default:
397
                default:
396
                        return (GPS_STST_ERR);
398
                        return (GPS_STST_ERR);
397
                        break;
399
                        break;
398
        }
400
        }
399
 
401
 
400
        switch (gps_state)
402
        switch (gps_state)
401
        {      
403
        {      
402
                case GPS_CRTL_IDLE:
404
                case GPS_CRTL_IDLE:
403
                        cnt             =       0;
405
                        cnt             =       0;
404
                        return (GPS_STST_OK);
406
                        return (GPS_STST_OK);
405
                        break;
407
                        break;
406
 
408
 
407
                case GPS_CRTL_HOME_ACTIVE: // Rueckflug zur Basis
409
                case GPS_CRTL_HOME_ACTIVE: // Rueckflug zur Basis
408
                //Der Sollwert des Lagereglers wird der Homeposition angenaehert
410
                //Der Sollwert des Lagereglers wird der Homeposition angenaehert
409
                        if (gps_rel_start_position.status >0)
411
                        if (gps_rel_start_position.status >0)
410
                        {
412
                        {
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
                                if ((gps_updte_flag > 0) && (gps_sub_state !=GPS_HOME_FINISHED)) // nur wenn neue GPS Daten vorliegen und nicht schon alles fertig ist
412
                                {
414
                                {
413
                                        gps_tick++;
415
                                        gps_tick++;
414
                                        int d1,d2,d3;
416
                                        int d1,d2,d3;
415
                                        d1      = abs (gps_rel_hold_position.utm_east - gps_rel_act_position.utm_east );
417
                                        d1      = abs (gps_rel_hold_position.utm_east - gps_rel_act_position.utm_east );
416
                                        d2      = abs (gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north );
418
                                        d2      = abs (gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north );
417
                                        d3      = (dist_2home - (int)dist_flown); // Restdistanz zum Ziel       
419
                                        d3      = (dist_2home - (int)dist_flown); // Restdistanz zum Ziel       
418
       
420
       
419
                                        if (d3 > GPS_G2T_DIST_MAX_STOP) // Schneller Rueckflug, noch weit weg vom Ziel
421
                                        if (d3 > GPS_G2T_DIST_MAX_STOP) // Schneller Rueckflug, noch weit weg vom Ziel
420
                                        {
422
                                        {
421
//                                              hold_fast               = 1; // Schnell Regeln
-
 
422
                                                hold_reset_int  = 1; // Integrator ausschalten            
-
 
423
                                                if ((d1 < GPS_G2T_FAST_TOL)  && (d2 < GPS_G2T_FAST_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
424
                                                {
424
                                                {
425
                                                        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
426
                                                        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
427
                                                        dist_frm_start_east                             = (int)((dist_flown * (long)sin_i(hdng_2home))/1000);
-
 
428
                                                        dist_frm_start_north                    = (int)((dist_flown * (long)cos_i(hdng_2home))/1000);
-
 
429
                                                        gps_rel_hold_position.utm_east  = gps_rel_start_position.utm_east  + dist_frm_start_east; //naechster Zielpunkt
-
 
430
                                                        gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + dist_frm_start_north; //naechster Zielpunkt
-
 
431
                                                        gps_sub_state                                   = GPS_HOME_FAST_IN_TOL;
427
                                                        gps_sub_state                                   = GPS_HOME_FAST_IN_TOL;
432
                                                }
428
                                                }
433
                                                else    //Den Lageregler in Ruhe arbeiten lassen weil ausserhalb der Toleranz
429
                                                else    //Den Lageregler in Ruhe arbeiten lassen weil ausserhalb der Toleranz
434
                                                {
430
                                                {
435
                                                        if (gps_g2t_act_v > 1) gps_g2t_act_v--; // Geschwindigkeit reduzieren
431
                                                        if (gps_g2t_act_v > 1) gps_g2t_act_v--; // Geschwindigkeit reduzieren
-
 
432
                                                        dist_flown++;                                                   //Auch ausserhalb der Toleranz langsam erhoehen
436
                                                        gps_sub_state   = GPS_HOME_FAST_OUTOF_TOL;
433
                                                        gps_sub_state   = GPS_HOME_FAST_OUTOF_TOL;
437
                                                }
434
                                                }
-
 
435
                                                hold_fast                                               = 1; // Regler fuer schnellen Flug
-
 
436
                                                hold_reset_int                                  = 1; // Integrator ausschalten            
-
 
437
                                                dist_frm_start_east                             = (int)((dist_flown * (long)sin_i(hdng_2home))/1000);
-
 
438
                                                dist_frm_start_north                    = (int)((dist_flown * (long)cos_i(hdng_2home))/1000);
-
 
439
                                                gps_rel_hold_position.utm_east  = gps_rel_start_position.utm_east  + dist_frm_start_east; //naechster Zielpunkt
-
 
440
                                                gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + dist_frm_start_north; //naechster Zielpunkt
438
                                        }
441
                                        }
439
                                        else if (d3 > GPS_G2T_DIST_HOLD)   //Das Ziel naehert sich, deswegen abbremsen
442
                                        else if (d3 > GPS_G2T_DIST_HOLD)   //Das Ziel naehert sich, deswegen abbremsen
440
                                        {
443
                                        {
441
                                                hold_reset_int  = 0; // Integrator einschalten            
-
 
442
                                                if ((d1 < GPS_G2T_NRML_TOL)  && (d2 < GPS_G2T_NRML_TOL)) //nur weiter wenn Lage innerhalb der Toleranz
444
                                                if ((d1 < GPS_G2T_NRML_TOL)  && (d2 < GPS_G2T_NRML_TOL))  
443
                                                {
445
                                                {
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
446
                                                        dist_flown              +=      GPS_G2T_V_RAMP_DWN; // 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
-
 
451
                                                        gps_sub_state   = GPS_HOME_RMPDWN_IN_TOL;
447
                                                        gps_sub_state   =       GPS_HOME_RMPDWN_IN_TOL;
452
                                                }
448
                                                }
453
                                                else
449
                                                else
454
                                                {
450
                                                {
455
                                                        if (gps_g2t_act_v > 1) gps_g2t_act_v--;
451
                                                        dist_flown++; //Auch ausserhalb der Toleranz langsam erhoehen
456
                                                        gps_sub_state   = GPS_HOME_RMPDWN_OUTOF_TOL;
452
                                                        gps_sub_state   = GPS_HOME_RMPDWN_OUTOF_TOL;
457
                                                }                                      
453
                                                }                                      
-
 
454
                                                hold_fast                                               = 0; // Wieder normal regeln
-
 
455
                                                hold_reset_int                                  = 1; // Integrator ausschalten            
-
 
456
                                                dist_frm_start_east                             = (int)((dist_flown * (long)sin_i(hdng_2home))/1000);
-
 
457
                                                dist_frm_start_north                    = (int)((dist_flown * (long)cos_i(hdng_2home))/1000);
-
 
458
                                                gps_rel_hold_position.utm_east  = gps_rel_start_position.utm_east  + dist_frm_start_east; //naechster Zielpunkt
-
 
459
                                                gps_rel_hold_position.utm_north = gps_rel_start_position.utm_north + dist_frm_start_north; //naechster Zielpunkt
458
                                        }                                                      
460
                                        }                                                      
459
                                        else  //Soll-Ziel fast erreicht, Jetzt noch Reste ausgleichen, weil Zielpunkt nicht exakt bestimmt werden konnte (Fehler in Winkelfkt) 
461
                                        else  //Soll-Ziel fast erreicht, Jetzt noch Reste ausgleichen, weil Zielpunkt nicht exakt bestimmt werden konnte (Fehler in Winkelfkt) 
460
                                        {
462
                                        {
461
                                                if ((d1 < GPS_G2T_NRML_TOL)  && (d2 < GPS_G2T_NRML_TOL)) // Jetzt bis zum Zielpunkt regeln
463
                                                if ((d1 < GPS_G2T_NRML_TOL)  && (d2 < GPS_G2T_NRML_TOL)) // Jetzt bis zum Zielpunkt regeln
462
                                                {
464
                                                {
463
                                                        gps_sub_state   = GPS_HOME_IN_TOL;
465
                                                        gps_sub_state   = GPS_HOME_IN_TOL;
464
                                                        hold_fast               = 0; // Wieder normal regeln
466
                                                        hold_fast               = 0; // Wieder normal regeln
465
                                                        hold_reset_int  = 0; // Integrator wieder aktivieren              
467
                                                        hold_reset_int  = 0; // Integrator wieder aktivieren              
466
                                                        if (gps_rel_hold_position.utm_east >= GPS_G2T_V_MIN) gps_rel_hold_position.utm_east -= GPS_G2T_V_MIN;
468
                                                        if (gps_rel_hold_position.utm_east >= GPS_G2T_V_MIN) gps_rel_hold_position.utm_east -= GPS_G2T_V_MIN;
467
                                                        else if (gps_rel_hold_position.utm_east <= -GPS_G2T_V_MIN ) gps_rel_hold_position.utm_east += GPS_G2T_V_MIN;
469
                                                        else if (gps_rel_hold_position.utm_east <= -GPS_G2T_V_MIN ) gps_rel_hold_position.utm_east += GPS_G2T_V_MIN;
468
                                                        if (gps_rel_hold_position.utm_north >= GPS_G2T_V_MIN) gps_rel_hold_position.utm_north -= GPS_G2T_V_MIN;
470
                                                        if (gps_rel_hold_position.utm_north >= GPS_G2T_V_MIN) gps_rel_hold_position.utm_north -= GPS_G2T_V_MIN;
469
                                                        else if (gps_rel_hold_position.utm_north <= - GPS_G2T_V_MIN ) gps_rel_hold_position.utm_north += GPS_G2T_V_MIN;
471
                                                        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))
472
                                                        if ((abs(gps_rel_hold_position.utm_east) <= GPS_G2T_V_MIN) && (abs(gps_rel_hold_position.utm_north) <=GPS_G2T_V_MIN))
471
                                                        {
473
                                                        {
472
                                                                gps_rel_hold_position.utm_east  = 0;
474
                                                                gps_rel_hold_position.utm_east  = 0;
473
                                                                gps_rel_hold_position.utm_north = 0;
475
                                                                gps_rel_hold_position.utm_north = 0;
474
                                                                gps_sub_state                                   = GPS_HOME_FINISHED;
476
                                                                gps_sub_state                                   = GPS_HOME_FINISHED;
475
                                                        }
477
                                                        }
476
                                                }
478
                                                }
-
 
479
                                                else gps_sub_state      = GPS_HOME_OUTOF_TOL;
477
                                        }                                      
480
                                        }                                      
478
                                }
481
                                }
479
                                gps_state = GPS_CRTL_HOLD_ACTIVE; //Zwischensprung
482
                                gps_state = GPS_CRTL_HOLD_ACTIVE; //Zwischensprung
480
                                return (GPS_STST_OK);                                  
483
                                return (GPS_STST_OK);                                  
481
                        }
484
                        }
482
                        else  // Keine GPS Daten verfuegbar, deswegen Abbruch
485
                        else  // Keine GPS Daten verfuegbar, deswegen Abbruch
483
                        {
486
                        {
484
                                gps_state       =       GPS_CRTL_IDLE; 
487
                                gps_state       =       GPS_CRTL_IDLE; 
485
                                return (GPS_STST_ERR);
488
                                return (GPS_STST_ERR);
486
                        }
489
                        }
487
                        break;
490
                        break;
488
 
491
 
489
 
492
 
490
                case GPS_CRTL_HOLD_ACTIVE:  // Hier werden die Daten fuer Nick und Roll errechnet
493
                case GPS_CRTL_HOLD_ACTIVE:  // Hier werden die Daten fuer Nick und Roll errechnet
491
                        if (gps_updte_flag >0)  // nur wenn neue GPS Daten vorliegen
494
                        if (gps_updte_flag >0)  // nur wenn neue GPS Daten vorliegen
492
                        {
495
                        {
493
                                gps_updte_flag = 0;
496
                                gps_updte_flag = 0;
494
                                // ab hier wird geregelt
497
                                // ab hier wird geregelt
495
                                diff_east       = -dist_east;     //Alten Wert fuer Differenzier schon mal abziehen
498
                                diff_east       = -dist_east;     //Alten Wert fuer Differenzier schon mal abziehen
496
                                diff_north      = -dist_north;
499
                                diff_north      = -dist_north;
497
                                dist_east       = gps_rel_hold_position.utm_east  - gps_rel_act_position.utm_east;
500
                                dist_east       = gps_rel_hold_position.utm_east  - gps_rel_act_position.utm_east;
498
                                dist_north      = gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north;
501
                                dist_north      = gps_rel_hold_position.utm_north - gps_rel_act_position.utm_north;
499
                                int_east        += dist_east;
502
                                int_east        += dist_east;
500
                                int_north   += dist_north;
503
                                int_north   += dist_north;
501
                                diff_east       += dist_east;   // Differenz zur vorhergehenden East Position
504
                                diff_east       += dist_east;   // Differenz zur vorhergehenden East Position
502
                                diff_north      += dist_north;  // Differenz zur vorhergehenden North Position
505
                                diff_north      += dist_north;  // Differenz zur vorhergehenden North Position
503
/*
506
/*
504
                                diff_east_f             = ((diff_east_f )/4) + (diff_east*3/4); //Differenzierer filtern       
507
                                diff_east_f             = ((diff_east_f )/4) + (diff_east*3/4); //Differenzierer filtern       
505
                                diff_north_f    = ((diff_north_f)/4) + (diff_north*3/4); //Differenzierer filtern      
508
                                diff_north_f    = ((diff_north_f)/4) + (diff_north*3/4); //Differenzierer filtern      
506
*/
509
*/
507
                                #define GPSINT_MAX 30000 //neuer Wert ab 7.10.2007 Begrenzung 
510
                                #define GPSINT_MAX 30000 //neuer Wert ab 7.10.2007 Begrenzung 
508
                                if ((abs(int_east) > GPSINT_MAX) || (abs(int_north)> GPSINT_MAX)) //Bei zu hohem Wert Integrator auf Wert halten
511
                                if ((abs(int_east) > GPSINT_MAX) || (abs(int_north)> GPSINT_MAX)) //Bei zu hohem Wert Integrator auf Wert halten
509
                                {
512
                                {
510
                                        int_east        -= dist_east;
513
                                        int_east        -= dist_east;
511
                                        int_north   -= dist_north;                                     
514
                                        int_north   -= dist_north;                                     
512
                                }
515
                                }
513
                                if (hold_reset_int > 0)  //Im Schnellen Mode Integrator abschalten
516
                                if (hold_reset_int > 0)  //Im Schnellen Mode Integrator abschalten
514
                                {
517
                                {
515
                                        int_east        = 0;   
518
                                        int_east        = 0;   
516
                                        int_north       = 0;                                   
519
                                        int_north       = 0;                                   
517
                                }
520
                                }
518
 
521
 
519
                                // Variable Verstarkung fuer Differenzierer ermitteln. Je weiter vom Ziel wir entfernt sind
522
                                // Variable Verstarkung fuer Differenzierer ermitteln. Je weiter vom Ziel wir entfernt sind
520
                                // desto groesser wird der Faktor. Es gibt aber einen Maximalwert. Bei 0 ist die Verstaerkung immer 1
523
                                // desto groesser wird der Faktor. Es gibt aber einen Maximalwert. Bei 0 ist die Verstaerkung immer 1
521
                                signed long dist,int_east1,int_north1;
524
                                signed long dist,int_east1,int_north1;
522
                                int phi;
525
                                int phi;
523
                                phi = arctan_i(abs(dist_north),abs(dist_east));
526
                                phi  = arctan_i(abs(dist_north),abs(dist_east));
524
                                dist = (long) (get_dist(dist_east,dist_north,phi)); //Zunaechst Entfernung zum Ziel ermitteln
527
                                dist = get_dist(dist_east,dist_north,phi); //Zunaechst Entfernung zum Ziel ermitteln
525
 
528
 
526
                                if (hold_fast == 0)  // je Nach Modus andere Verstaerkungskurve fuer Differenzierer
529
                                if (hold_fast == 0)  // je Nach Modus andere Verstaerkungskurve fuer Differenzierer
527
                                {
530
                                {
528
                                        diff_v = (int)((dist * (GPS_DIFF_NRML_MAX_V - 10)) / GPS_DIFF_NRML_MAX_D) +10; //Verstaerkung * 10
531
                                        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
532
                                        if (diff_v > GPS_DIFF_NRML_MAX_V) diff_v = GPS_DIFF_NRML_MAX_V; //begrenzen
530
                                }
533
                                }
531
                                else
534
                                else
532
                                {
535
                                {
533
                                        diff_v = (int)((dist * (GPS_DIFF_FAST_MAX_V - 10)) / GPS_DIFF_FAST_MAX_D) +10; //Verstaerkung * 10
536
                                        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
537
                                        if (diff_v > GPS_DIFF_FAST_MAX_V) diff_v = GPS_DIFF_FAST_MAX_V; //begrenzen
535
                                }
538
                                }
-
 
539
 
-
 
540
                                int diff_p;  //Vom Modus abhaengige zusaetzliche Verstaerkung
-
 
541
                                if (hold_fast > 0) diff_p = GPS_PROP_FAST_V;
-
 
542
                                else diff_p = GPS_PROP_NRML_V;
536
 
543
 
537
                                //I Werte begrenzen
544
                                //I Werte begrenzen
538
                                #define INT1_MAX (20 * GPS_V)
545
                                #define INT1_MAX (20 * GPS_V)
539
                                int_east1 =  ((((long)int_east)   * Parameter_UserParam2)/32);
546
                                int_east1 =  ((((long)int_east)   * Parameter_UserParam2)/32);
540
                                int_north =  ((((long)int_north)  * Parameter_UserParam2)/32);
547
                                int_north =  ((((long)int_north)  * Parameter_UserParam2)/32);
541
                                if (int_east1 > INT1_MAX) int_east1 =  INT1_MAX; //begrenzen
548
                                if (int_east1 > INT1_MAX) int_east1 =  INT1_MAX; //begrenzen
542
                                else if (int_east1 < -INT1_MAX) int_east1 =  -INT1_MAX;
549
                                else if (int_east1 < -INT1_MAX) int_east1 =  -INT1_MAX;
543
                                if (int_north1 > INT1_MAX) int_north1 =  INT1_MAX; //begrenzen
550
                                if (int_north1 > INT1_MAX) int_north1 =  INT1_MAX; //begrenzen
544
                                else if (int_north1 < -INT1_MAX) int_north1 =  -INT1_MAX;
551
                                else if (int_north1 < -INT1_MAX) int_north1 =  -INT1_MAX;
545
 
-
 
546
                                int diff_p;
-
 
547
                                if (hold_fast == 0) diff_p = 1;  
-
 
548
                                else diff_p = 2; //im schnellen Modus Proportionalanteil staerken
-
 
549
 
552
 
550
                                //PID Regler Werte aufsummieren
553
                                //PID Regler Werte aufsummieren
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
554
                                gps_reg_x = ((int)int_east1  + ((dist_east  * Parameter_UserParam1 * diff_p)/(8*2))+ ((diff_east  * diff_v * Parameter_UserParam3)/10));  // I + P +D  Anteil X 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
555
                                gps_reg_y = ((int)int_north1 + ((dist_north * Parameter_UserParam1 * diff_p)/(8*2))+ ((diff_north * diff_v * Parameter_UserParam3)/10));  // I + P +D  Anteil Y Achse
553
 
556
 
554
                                //Ziel-Richtung bezogen auf Nordpol bestimmen
557
                                //Ziel-Richtung bezogen auf Nordpol bestimmen
555
                                GPS_hdng_abs_2trgt = arctan_i(gps_reg_x,gps_reg_y);
558
                                GPS_hdng_abs_2trgt = arctan_i(gps_reg_x,gps_reg_y);
556
 
559
 
557
                                // in Winkel 0...360 Grad umrechnen
560
                                // in Winkel 0...360 Grad umrechnen
558
                                if ((gps_reg_x >= 0)) GPS_hdng_abs_2trgt = ( 90-GPS_hdng_abs_2trgt);
561
                                if ((gps_reg_x >= 0)) GPS_hdng_abs_2trgt = ( 90-GPS_hdng_abs_2trgt);
559
                                else  GPS_hdng_abs_2trgt = (270 - GPS_hdng_abs_2trgt);
562
                                else  GPS_hdng_abs_2trgt = (270 - GPS_hdng_abs_2trgt);
560
 
563
 
561
                                // Relative Richtung in bezug auf Nordachse des Kopters errechen
564
                                // Relative Richtung in bezug auf Nordachse des Kopters errechen
562
                                n= GyroKomp_Int/GYROKOMP_INC_GRAD_DEFAULT;
565
                                n= GyroKomp_Int/GYROKOMP_INC_GRAD_DEFAULT;
563
                                GPS_hdng_rel_2trgt      =       GPS_hdng_abs_2trgt - n;
566
                                GPS_hdng_rel_2trgt      =       GPS_hdng_abs_2trgt - n;
564
                                if      ((GPS_hdng_rel_2trgt >180) && (GPS_hdng_abs_2trgt >=180)) GPS_hdng_rel_2trgt = GPS_hdng_rel_2trgt-360;
567
                                if      ((GPS_hdng_rel_2trgt >180) && (GPS_hdng_abs_2trgt >=180)) GPS_hdng_rel_2trgt = GPS_hdng_rel_2trgt-360;
565
                                else if (GPS_hdng_rel_2trgt >180)  GPS_hdng_rel_2trgt = 360 - GPS_hdng_rel_2trgt;
568
                                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;
569
                                else if (GPS_hdng_rel_2trgt <-180)  GPS_hdng_rel_2trgt = 360 + GPS_hdng_rel_2trgt;
567
                               
570
                               
568
                                // Regelabweichung aus x,y zu Ziel in Distanz umrechnen 
571
                                // Regelabweichung aus x,y zu Ziel in Distanz umrechnen 
569
                                if (abs(gps_reg_x) > abs(gps_reg_y) )
572
                                if (abs(gps_reg_x) > abs(gps_reg_y) )
570
                                {
573
                                {
571
                                        dev = (long)gps_reg_x; //Groesseren Wert wegen besserer Genauigkeit nehmen
574
                                        dev = (long)gps_reg_x; //Groesseren Wert wegen besserer Genauigkeit nehmen
572
                                        dev = abs((dev *1000) / (long) sin_i(GPS_hdng_abs_2trgt));
575
                                        dev = abs((dev *1000) / (long) sin_i(GPS_hdng_abs_2trgt));
573
                                }
576
                                }
574
                                else
577
                                else
575
                                {
578
                                {
576
                                        dev = (long)gps_reg_y;
579
                                        dev = (long)gps_reg_y;
577
                                        dev = abs((dev *1000) / (long) cos_i(GPS_hdng_abs_2trgt));
580
                                        dev = abs((dev *1000) / (long) cos_i(GPS_hdng_abs_2trgt));
578
                                }
581
                                }
579
                                GPS_dist_2trgt  = (int) dev;
582
                                GPS_dist_2trgt  = (int) dev;
580
                                // Winkel und Distanz in Nick und Rollgroessen umrechnen
583
                                // Winkel und Distanz in Nick und Rollgroessen umrechnen
581
                                GPS_Roll = (int) +( (dev * (long) sin_i(GPS_hdng_rel_2trgt))/1000);
584
                                GPS_Roll = (int) +( (dev * (long) sin_i(GPS_hdng_rel_2trgt))/1000);
582
                                GPS_Nick = (int) -( (dev * (long) cos_i(GPS_hdng_rel_2trgt))/1000);
585
                                GPS_Nick = (int) -( (dev * (long) cos_i(GPS_hdng_rel_2trgt))/1000);
583
                                       
586
                                       
584
                                if (GPS_Roll > (GPS_NICKROLL_MAX * GPS_V)) GPS_Roll = (GPS_NICKROLL_MAX * GPS_V);
587
                                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);
588
                                else if (GPS_Roll < -(GPS_NICKROLL_MAX * GPS_V)) GPS_Roll = -(GPS_NICKROLL_MAX * GPS_V);
586
                                if (GPS_Nick > (GPS_NICKROLL_MAX * GPS_V)) GPS_Nick = (GPS_NICKROLL_MAX * GPS_V);
589
                                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);
590
                                else if (GPS_Nick < -(GPS_NICKROLL_MAX * GPS_V)) GPS_Nick = -(GPS_NICKROLL_MAX * GPS_V);
588
 
591
 
589
                                //Kleine Werte verstaerken, Grosse abschwaechen
592
                                //Kleine Werte verstaerken, Grosse abschwaechen
590
                                n                       = sin_i((GPS_Roll*90)/(GPS_NICKROLL_MAX * GPS_V));
593
                                n                       = sin_i((GPS_Roll*90)/(GPS_NICKROLL_MAX * GPS_V));
591
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
594
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
592
                                GPS_Roll        = (int) n_l;
595
                                GPS_Roll        = (int) n_l;
593
                                n                       = sin_i((GPS_Nick*90)/(GPS_NICKROLL_MAX * GPS_V));
596
                                n                       = sin_i((GPS_Nick*90)/(GPS_NICKROLL_MAX * GPS_V));
594
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
597
                                n_l                     = ((long) GPS_NICKROLL_MAX  * (long) n)/1000;
595
                                GPS_Nick        = (int) n_l;
598
                                GPS_Nick        = (int) n_l;
596
                                 
599
                                 
597
                                if ((abs(dist_east) > GPS_DIST_MAX) || (abs(dist_north) > GPS_DIST_MAX))  // bei zu grossem Abstand abbrechen
600
                                if ((abs(dist_east) > GPS_DIST_MAX) || (abs(dist_north) > GPS_DIST_MAX))  // bei zu grossem Abstand abbrechen
598
                                {
601
                                {
599
                                        GPS_Roll        = 0;
602
                                        GPS_Roll        = 0;
600
                                        GPS_Nick        = 0;
603
                                        GPS_Nick        = 0;
601
                                        gps_state       = GPS_CRTL_IDLE;
604
                                        gps_state       = GPS_CRTL_IDLE;
602
                                        return (GPS_STST_ERR); 
605
                                        return (GPS_STST_ERR); 
603
                                        break;                                 
606
                                        break;                                 
604
                                }
607
                                }
605
                                else
608
                                else
606
                                {
609
                                {
607
                                        if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
610
                                        if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
608
                                        return (GPS_STST_OK);
611
                                        return (GPS_STST_OK);
609
                                }
612
                                }
610
                        }
613
                        }
611
                        else
614
                        else
612
                        {
615
                        {
613
                                if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
616
                                if ( cmd == GPS_CMD_REQ_HOME ) gps_state = GPS_CRTL_HOME_ACTIVE; // State umsetzen
614
                                return (GPS_STST_OK);
617
                                return (GPS_STST_OK);
615
                        }
618
                        }
616
                        break;
619
                        break;
617
 
620
 
618
                default:
621
                default:
619
                        gps_state = GPS_CRTL_IDLE;
622
                        gps_state = GPS_CRTL_IDLE;
620
                        return (GPS_STST_ERR);
623
                        return (GPS_STST_ERR);
621
                        break;
624
                        break;
622
        }      
625
        }      
623
        return (GPS_STST_ERR);
626
        return (GPS_STST_ERR);
624
                       
627
                       
625
}
628
}
626
 
629
 
627
 
630