Subversion Repositories NaviCtrl

Rev

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

Rev 576 Rev 577
1
/*#######################################################################################*/
1
/*#######################################################################################*/
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
3
/*#######################################################################################*/
3
/*#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + www.MikroKopter.com
5
// + www.MikroKopter.com
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
// + Software Nutzungsbedingungen (english version: see below)
7
// + Software Nutzungsbedingungen (english version: see below)
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool 
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool 
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand 
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand 
22
// + des Mitverschuldens offen.
22
// + des Mitverschuldens offen.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
27
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
27
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
28
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
28
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
29
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
29
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
// + Software LICENSING TERMS
32
// + Software LICENSING TERMS
33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware 
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware 
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
37
// + The Software may only be used with the Licensor's products.
37
// + The Software may only be used with the Licensor's products.
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
40
// + agreement shall be the property of the Licensor.
40
// + agreement shall be the property of the Licensor.
41
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
41
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
42
// + features that can be used to identify the program may not be altered or defaced by the customer.
42
// + features that can be used to identify the program may not be altered or defaced by the customer.
43
// + The customer shall be responsible for taking reasonable precautions
43
// + The customer shall be responsible for taking reasonable precautions
44
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
44
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
45
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
45
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
46
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
46
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
47
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
47
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
48
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
48
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
49
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
49
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
50
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
50
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
51
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
51
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
53
// + #### END OF LICENSING TERMS ####
53
// + #### END OF LICENSING TERMS ####
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56
#include <ctype.h>
56
#include <ctype.h>
57
#include <stdio.h>
57
#include <stdio.h>
58
#include <stdlib.h>      
58
#include <stdlib.h>      
59
#include <string.h>
59
#include <string.h>
60
#include "91x_lib.h"
60
#include "91x_lib.h"
61
#include "waypoints.h"
61
#include "waypoints.h"
62
#include "uart1.h"
62
#include "uart1.h"
63
#include "fat16.h"
63
#include "fat16.h"
64
#include "main.h"
64
#include "main.h"
65
#include "spi_slave.h"
65
#include "spi_slave.h"
66
 
66
 
67
 
67
 
68
WPL_Store_t WPL_Store;
68
WPL_Store_t WPL_Store;
69
 
69
 
70
// the waypoints list
70
// the waypoints list
71
#define MAX_LIST_LEN 101
71
#define MAX_LIST_LEN 101
72
 
72
 
73
Point_t PointList[MAX_LIST_LEN];
73
Point_t PointList[MAX_LIST_LEN];
74
u8 WPIndex = 0;         // list index of GPS point representig the current WP, can be maximal WPCount
74
u8 WPIndex = 0;         // list index of GPS point representig the current WP, can be maximal WPCount
75
u8 POIIndex = 0;        // list index of GPS Point representing the current POI, can be maximal WPCount
75
u8 POIIndex = 0;        // list index of GPS Point representing the current POI, can be maximal WPCount
76
u8 WPCount = 0;         // number of waypoints
76
u8 WPCount = 0;         // number of waypoints
77
u8 PointCount = 0;      // number of points in the list can be maximal equal to MAX_LIST_LEN
77
u8 PointCount = 0;      // number of points in the list can be maximal equal to MAX_LIST_LEN
78
u8 POICount = 0;        // number of point of interest in the list
78
u8 POICount = 0;        // number of point of interest in the list
79
s16 HeadingOld = -1;
79
s16 HeadingOld = -1;
-
 
80
u32 SD_WaypointTimeout = 5; // Setting on SD-Card
80
 
81
 
81
u8 WPActive = FALSE;
82
u8 WPActive = FALSE;
82
 
83
 
83
u8 PointList_Init(void)
84
u8 PointList_Init(void)
84
{
85
{
85
        return PointList_Clear();
86
        return PointList_Clear();
86
}
87
}
87
 
88
 
88
u8 PointList_Clear(void)
89
u8 PointList_Clear(void)
89
{
90
{
90
        u8 i;
91
        u8 i;
91
        WPIndex = 0;    // real list position are 1 ,2, 3 ...
92
        WPIndex = 0;    // real list position are 1 ,2, 3 ...
92
        POIIndex = 0;   // real list position are 1 ,2, 3 ...
93
        POIIndex = 0;   // real list position are 1 ,2, 3 ...
93
        WPCount = 0;    // no waypoints
94
        WPCount = 0;    // no waypoints
94
    POICount = 0;
95
    POICount = 0;
95
        PointCount = 0; // no contents
96
        PointCount = 0; // no contents
96
        WPActive = FALSE;
97
        WPActive = FALSE;
97
        NaviData.WaypointNumber = WPCount;
98
        NaviData.WaypointNumber = WPCount;
98
        NaviData.WaypointIndex = 0;
99
        NaviData.WaypointIndex = 0;
99
        for(i = 0; i < MAX_LIST_LEN; i++)
100
        for(i = 0; i < MAX_LIST_LEN; i++)
100
        {
101
        {
101
                PointList[i].Position.Status = INVALID;
102
                PointList[i].Position.Status = INVALID;
102
                PointList[i].Position.Latitude = 0;
103
                PointList[i].Position.Latitude = 0;
103
                PointList[i].Position.Longitude = 0;
104
                PointList[i].Position.Longitude = 0;
104
                PointList[i].Position.Altitude = 0;
105
                PointList[i].Position.Altitude = 0;
105
                PointList[i].Heading = 361;             // invalid value
106
                PointList[i].Heading = 361;             // invalid value
106
                PointList[i].ToleranceRadius = 0;       // in meters, if the MK is within that range around the target, then the next target is triggered
107
                PointList[i].ToleranceRadius = 0;       // in meters, if the MK is within that range around the target, then the next target is triggered
107
                PointList[i].HoldTime = 0;                      // in seconds, if the was once in the tolerance area around a WP, this time defines the delay before the next WP is triggered
108
                PointList[i].HoldTime = 0;                      // in seconds, if the was once in the tolerance area around a WP, this time defines the delay before the next WP is triggered
108
                PointList[i].Event_Flag = 0;            // future implementation
109
                PointList[i].Event_Flag = 0;            // future implementation
109
                PointList[i].Index = 0;
110
                PointList[i].Index = 0;
110
                PointList[i].Type = POINT_TYPE_INVALID;
111
                PointList[i].Type = POINT_TYPE_INVALID;
111
                PointList[i].WP_EventChannelValue = 0;
112
                PointList[i].WP_EventChannelValue = 0;
112
                PointList[i].AltitudeRate = 0;          // no change of setpoint
113
                PointList[i].AltitudeRate = 0;          // no change of setpoint
113
                PointList[i].Speed = 0;
114
                PointList[i].Speed = 0;
114
                PointList[i].CamAngle = 0;
115
                PointList[i].CamAngle = 0;
115
                PointList[i].Name[0] = 0;
116
                PointList[i].Name[0] = 0;
116
        }
117
        }
117
        ClearWLP_Name();
118
        ClearWLP_Name();
118
        return TRUE;           
119
        return TRUE;           
119
}
120
}
120
 
121
 
121
u8 PointList_GetCount(void)
122
u8 PointList_GetCount(void)
122
{
123
{
123
        return PointCount; // number of points in the list
124
        return PointCount; // number of points in the list
124
}
125
}
125
 
126
 
126
Point_t* PointList_GetAt(u8 index)
127
Point_t* PointList_GetAt(u8 index)
127
{
128
{
128
        if((index > 0) && (index <= PointCount)) return(&(PointList[index-1])); // return pointer to this waypoint
129
        if((index > 0) && (index <= PointCount)) return(&(PointList[index-1])); // return pointer to this waypoint
129
        else return(NULL);
130
        else return(NULL);
130
}
131
}
131
 
132
 
132
u8 PointList_SetAt(Point_t* pPoint)
133
u8 PointList_SetAt(Point_t* pPoint)
133
{
134
{
134
        // if index is in range
135
        // if index is in range
135
        if((pPoint->Index > 0) && (pPoint->Index <= MAX_LIST_LEN))
136
        if((pPoint->Index > 0) && (pPoint->Index <= MAX_LIST_LEN))
136
        {
137
        {
137
                // check list entry before update
138
                // check list entry before update
138
                switch(PointList[pPoint->Index-1].Type)
139
                switch(PointList[pPoint->Index-1].Type)
139
                {
140
                {
140
                        case POINT_TYPE_INVALID: // was invalid
141
                        case POINT_TYPE_INVALID: // was invalid
141
                                switch(pPoint->Type)
142
                                switch(pPoint->Type)
142
                                {
143
                                {
143
                                        default:
144
                                        default:
144
                                        case POINT_TYPE_INVALID:
145
                                        case POINT_TYPE_INVALID:
145
                                                // nothing to do
146
                                                // nothing to do
146
                                                break;
147
                                                break;
147
 
148
 
148
                                        case POINT_TYPE_WP:
149
                                        case POINT_TYPE_WP:
149
                                                WPCount++;
150
                                                WPCount++;
150
                                                PointCount++;
151
                                                PointCount++;
151
                                                break;
152
                                                break;
152
                                       
153
                                       
153
                                        case POINT_TYPE_POI:
154
                                        case POINT_TYPE_POI:
154
                                                POICount++;
155
                                                POICount++;
155
                                                PointCount++;
156
                                                PointCount++;
156
                                                break;
157
                                                break;
157
                                }
158
                                }
158
                                break;
159
                                break;
159
                               
160
                               
160
                        case POINT_TYPE_WP: // was a waypoint
161
                        case POINT_TYPE_WP: // was a waypoint
161
                                switch(pPoint->Type)
162
                                switch(pPoint->Type)
162
                                {
163
                                {
163
                                        case POINT_TYPE_INVALID:
164
                                        case POINT_TYPE_INVALID:
164
                                                WPCount--;
165
                                                WPCount--;
165
                                                PointCount--;
166
                                                PointCount--;
166
                                                break;
167
                                                break;
167
 
168
 
168
                                        default:
169
                                        default:
169
                                        case POINT_TYPE_WP:
170
                                        case POINT_TYPE_WP:
170
                                                //nothing to do
171
                                                //nothing to do
171
                                                break;
172
                                                break;
172
                                       
173
                                       
173
                                        case POINT_TYPE_POI:
174
                                        case POINT_TYPE_POI:
174
                                                POICount++;
175
                                                POICount++;
175
                                                WPCount--;
176
                                                WPCount--;
176
                                                break;
177
                                                break;
177
                                }
178
                                }
178
                                break;
179
                                break;
179
                               
180
                               
180
                        case POINT_TYPE_POI: // was a poi
181
                        case POINT_TYPE_POI: // was a poi
181
                                switch(pPoint->Type)
182
                                switch(pPoint->Type)
182
                                {
183
                                {
183
                                        case POINT_TYPE_INVALID:
184
                                        case POINT_TYPE_INVALID:
184
                                                POICount--;
185
                                                POICount--;
185
                                                PointCount--;
186
                                                PointCount--;
186
                                                break;
187
                                                break;
187
 
188
 
188
                                        case POINT_TYPE_WP:
189
                                        case POINT_TYPE_WP:
189
                                                WPCount++;
190
                                                WPCount++;
190
                                                POICount--;
191
                                                POICount--;
191
                                                break;
192
                                                break;
192
                                       
193
                                       
193
                                        case POINT_TYPE_POI:
194
                                        case POINT_TYPE_POI:
194
                                        default:
195
                                        default:
195
                                                // nothing to do
196
                                                // nothing to do
196
                                                break;
197
                                                break;
197
                                }
198
                                }
198
                                break;         
199
                                break;         
199
                }
200
                }
200
                memcpy(&PointList[pPoint->Index-1], pPoint, sizeof(Point_t)); // copy data to list entry                                                                                
201
                memcpy(&PointList[pPoint->Index-1], pPoint, sizeof(Point_t)); // copy data to list entry                                                                                
201
                NaviData.WaypointNumber = WPCount;
202
                NaviData.WaypointNumber = WPCount;
202
                return pPoint->Index;
203
                return pPoint->Index;
203
        }
204
        }
204
        else return(0);
205
        else return(0);
205
}
206
}
206
 
207
 
207
// returns the pointer to the first waypoint within the list
208
// returns the pointer to the first waypoint within the list
208
Point_t* PointList_WPBegin(void)
209
Point_t* PointList_WPBegin(void)
209
{
210
{
210
        u8 i;
211
        u8 i;
211
        WPIndex = 0; // set list position invalid
212
        WPIndex = 0; // set list position invalid
212
 
213
 
213
        if(WPActive == FALSE) return(NULL);
214
        if(WPActive == FALSE) return(NULL);
214
 
215
 
215
        POIIndex = 0; // set invalid POI
216
        POIIndex = 0; // set invalid POI
216
        if(PointCount > 0)
217
        if(PointCount > 0)
217
        {
218
        {
218
                // search for first wp in list
219
                // search for first wp in list
219
                for(i = 0; i <MAX_LIST_LEN; i++)
220
                for(i = 0; i <MAX_LIST_LEN; i++)
220
                {
221
                {
221
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID))
222
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID))
222
                        {
223
                        {
223
                                WPIndex = i + 1;
224
                                WPIndex = i + 1;
224
                                break;
225
                                break;
225
                        }
226
                        }
226
                }
227
                }
227
                if(WPIndex) // found a WP in the list
228
                if(WPIndex) // found a WP in the list
228
                {
229
                {
229
                        NaviData.WaypointIndex = 1;
230
                        NaviData.WaypointIndex = 1;
230
                        NewWaypointsReceived = 1; // activates the Waypoint list as soon as CH is started
231
                        NewWaypointsReceived = 1; // activates the Waypoint list as soon as CH is started
231
                        // update index to POI
232
                        // update index to POI
232
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
233
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
233
                        else POIIndex = 0;                     
234
                        else POIIndex = 0;                     
234
                }
235
                }
235
                else // some points in the list but no WP found
236
                else // some points in the list but no WP found
236
                {
237
                {
237
                        NaviData.WaypointIndex = 0;
238
                        NaviData.WaypointIndex = 0;
238
                        //Check for an existing POI
239
                        //Check for an existing POI
239
                        for(i = 0; i < MAX_LIST_LEN; i++)
240
                        for(i = 0; i < MAX_LIST_LEN; i++)
240
                        {
241
                        {
241
                                if((PointList[i].Type == POINT_TYPE_POI) && (PointList[i].Position.Status != INVALID))
242
                                if((PointList[i].Type == POINT_TYPE_POI) && (PointList[i].Position.Status != INVALID))
242
                                {
243
                                {
243
                                        POIIndex = i + 1;
244
                                        POIIndex = i + 1;
244
                                        break;
245
                                        break;
245
                                }
246
                                }
246
                        }
247
                        }
247
                }
248
                }
248
        }
249
        }
249
        else // no point in the list
250
        else // no point in the list
250
        {
251
        {
251
                POIIndex = 0;
252
                POIIndex = 0;
252
                NaviData.WaypointIndex = 0;    
253
                NaviData.WaypointIndex = 0;    
253
        }
254
        }
254
 
255
 
255
        if(WPIndex) return(&(PointList[WPIndex-1]));
256
        if(WPIndex) return(&(PointList[WPIndex-1]));
256
        else return(NULL);
257
        else return(NULL);
257
}
258
}
258
 
259
 
259
// returns the last waypoint
260
// returns the last waypoint
260
Point_t* PointList_WPEnd(void)
261
Point_t* PointList_WPEnd(void)
261
{
262
{
262
       
263
       
263
        u8 i;
264
        u8 i;
264
        WPIndex = 0; // set list position invalid
265
        WPIndex = 0; // set list position invalid
265
        POIIndex = 0; // set invalid
266
        POIIndex = 0; // set invalid
266
 
267
 
267
        if(WPActive == FALSE) return(NULL);
268
        if(WPActive == FALSE) return(NULL);
268
 
269
 
269
        if(PointCount > 0)
270
        if(PointCount > 0)
270
        {
271
        {
271
                // search backward!
272
                // search backward!
272
                for(i = 1; i <= MAX_LIST_LEN; i++)
273
                for(i = 1; i <= MAX_LIST_LEN; i++)
273
                {
274
                {
274
                        if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_WP) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
275
                        if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_WP) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
275
                        {      
276
                        {      
276
                                WPIndex = MAX_LIST_LEN - i + 1;
277
                                WPIndex = MAX_LIST_LEN - i + 1;
277
                                break;
278
                                break;
278
                        }
279
                        }
279
                }
280
                }
280
                if(WPIndex) // found a WP within the list
281
                if(WPIndex) // found a WP within the list
281
                {
282
                {
282
                        NaviData.WaypointIndex = WPCount;
283
                        NaviData.WaypointIndex = WPCount;
283
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
284
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
284
                        else POIIndex = 0;     
285
                        else POIIndex = 0;     
285
                }
286
                }
286
                else // list contains some points but no WP in the list
287
                else // list contains some points but no WP in the list
287
                {
288
                {
288
                        // search backward for a POI!
289
                        // search backward for a POI!
289
                        for(i = 1; i <= MAX_LIST_LEN; i++)
290
                        for(i = 1; i <= MAX_LIST_LEN; i++)
290
                        {
291
                        {
291
                                if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_POI) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
292
                                if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_POI) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
292
                                {      
293
                                {      
293
                                        POIIndex = MAX_LIST_LEN - i + 1;
294
                                        POIIndex = MAX_LIST_LEN - i + 1;
294
                                        break;
295
                                        break;
295
                                }
296
                                }
296
                        }
297
                        }
297
                        NaviData.WaypointIndex = 0;    
298
                        NaviData.WaypointIndex = 0;    
298
                }
299
                }
299
        }
300
        }
300
        else // no point in the list
301
        else // no point in the list
301
        {
302
        {
302
                POIIndex = 0;
303
                POIIndex = 0;
303
                NaviData.WaypointIndex = 0;
304
                NaviData.WaypointIndex = 0;
304
        }
305
        }
305
        if(WPIndex) return(&(PointList[WPIndex-1]));
306
        if(WPIndex) return(&(PointList[WPIndex-1]));
306
        else return(NULL);
307
        else return(NULL);
307
}
308
}
308
 
309
 
309
// returns a pointer to the next waypoint or NULL if the end of the list has been reached
310
// returns a pointer to the next waypoint or NULL if the end of the list has been reached
310
Point_t* PointList_WPNext(void)
311
Point_t* PointList_WPNext(void)
311
{
312
{
312
        u8 wp_found = 0;
313
        u8 wp_found = 0;
313
        if(WPActive == FALSE) return(NULL);
314
        if(WPActive == FALSE) return(NULL);
314
               
315
               
315
        if(WPIndex < MAX_LIST_LEN) // if there is a next entry in the list
316
        if(WPIndex < MAX_LIST_LEN) // if there is a next entry in the list
316
        {
317
        {
317
                u8 i;
318
                u8 i;
318
                for(i = WPIndex; i < MAX_LIST_LEN; i++) // start search for next at next list entry
319
                for(i = WPIndex; i < MAX_LIST_LEN; i++) // start search for next at next list entry
319
                {
320
                {
320
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID)) // jump over POIs
321
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID)) // jump over POIs
321
                        {
322
                        {
322
                                wp_found = i+1;
323
                                wp_found = i+1;
323
                                break;
324
                                break;
324
                        }
325
                        }
325
                }
326
                }
326
        }
327
        }
327
        if(wp_found)
328
        if(wp_found)
328
        {
329
        {
329
                WPIndex = wp_found; // update list position
330
                WPIndex = wp_found; // update list position
330
                NaviData.WaypointIndex++;
331
                NaviData.WaypointIndex++;
331
                if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
332
                if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
332
                else POIIndex = 0;
333
                else POIIndex = 0;
333
                return(&(PointList[WPIndex-1]));        // return pointer to this waypoint
334
                return(&(PointList[WPIndex-1]));        // return pointer to this waypoint
334
        }
335
        }
335
        else
336
        else
336
        {  // no next wp found
337
        {  // no next wp found
337
                NaviData.WaypointIndex = 0;    
338
                NaviData.WaypointIndex = 0;    
338
                POIIndex = 0;
339
                POIIndex = 0;
339
                return(NULL);
340
                return(NULL);
340
        }
341
        }
341
}      
342
}      
342
 
343
 
343
void PointList_WPActive(u8 set)
344
void PointList_WPActive(u8 set)
344
{
345
{
345
        if(set)
346
        if(set)
346
        {      
347
        {      
347
                WPActive = TRUE;
348
                WPActive = TRUE;
348
                PointList_WPBegin(); // updates POI index
349
                PointList_WPBegin(); // updates POI index
349
        }
350
        }
350
        else
351
        else
351
        {
352
        {
352
                WPActive = FALSE;
353
                WPActive = FALSE;
353
                POIIndex = 0;  // disable POI also
354
                POIIndex = 0;  // disable POI also
354
        }
355
        }
355
}
356
}
356
 
357
 
357
Point_t* PointList_GetPOI(void)
358
Point_t* PointList_GetPOI(void)
358
{
359
{
359
        return PointList_GetAt(POIIndex);      
360
        return PointList_GetAt(POIIndex);      
360
}
361
}
361
 
362
 
362
 
363
 
363
#define LINE_MAX 70
364
#define LINE_MAX 70
364
#define WP_FILE_VERSION_COMPATIBLE 3
365
#define WP_FILE_VERSION_COMPATIBLE 3
365
 
366
 
366
u8 PointList_Save(u8 * filename, u8* listname, u8 overwride)
367
u8 PointList_Save(u8 * filename, u8* listname, u8 overwride)
367
{
368
{
368
        File_t *fp;
369
        File_t *fp;
369
        s8 wpline[LINE_MAX];
370
        s8 wpline[LINE_MAX];
370
        u8 retval = WPL_ERROR;
371
        u8 retval = WPL_ERROR;
371
 
372
 
372
        UART1_PutString("\n\r Save WPL...");
373
        UART1_PutString("\n\r Save WPL...");
373
 
374
 
374
        if(Fat16_IsValid())
375
        if(Fat16_IsValid())
375
        {       // check if wpl file is existing
376
        {       // check if wpl file is existing
376
                if(fexist_(filename))
377
                if(fexist_(filename))
377
                {       //file is existent
378
                {       //file is existent
378
                        if(!(overwride))
379
                        if(!(overwride))
379
                        {
380
                        {
380
                                UART1_PutString("Error: file exist!\r\n");
381
                                UART1_PutString("Error: file exist!\r\n");
381
                                return(WPL_FILEEXIST);
382
                                return(WPL_FILEEXIST);
382
                        }      
383
                        }      
383
                }
384
                }
384
                fp = fopen_(filename, 'w');             // try to open the file
385
                fp = fopen_(filename, 'w');             // try to open the file
385
                if(fp == NULL)
386
                if(fp == NULL)
386
                {
387
                {
387
                        UART1_PutString("ERROR: Creating waypoint file!\r\n");
388
                        UART1_PutString("ERROR: Creating waypoint file!\r\n");
388
                        return(retval);
389
                        return(retval);
389
                }
390
                }
390
                // Create general section and key entries
391
                // Create general section and key entries
391
                fputs_("[General]\r\n", fp);
392
                fputs_("[General]\r\n", fp);
392
                sprintf(wpline, "Name=%s\r\n",  listname);
393
                sprintf(wpline, "Name=%s\r\n",  listname);
393
                fputs_(wpline, fp);
394
                fputs_(wpline, fp);
394
                sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE);
395
                sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE);
395
                fputs_(wpline, fp);
396
                fputs_(wpline, fp);
396
                sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount);
397
                sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount);
397
                fputs_(wpline, fp);
398
                fputs_(wpline, fp);
398
                // dump all points if existent
399
                // dump all points if existent
399
                if(PointCount)
400
                if(PointCount)
400
                {
401
                {
401
                        u8 i, u8_1;
402
                        u8 i, u8_1;
402
                        s32 i32_1, i32_2;
403
                        s32 i32_1, i32_2;
403
                        NewWPL_Name = 1;
404
                        NewWPL_Name = 1;
404
                        for (i = 0; i < PointCount; i++)
405
                        for (i = 0; i < PointCount; i++)
405
                        {
406
                        {
406
                                sprintf(wpline, "[Point%d]\r\n",PointList[i].Index);
407
                                sprintf(wpline, "[Point%d]\r\n",PointList[i].Index);
407
                                fputs_(wpline, fp);
408
                                fputs_(wpline, fp);
408
                                // write latitude in deg
409
                                // write latitude in deg
409
                                if(PointList[i].Position.Latitude < 0) u8_1 = '-';
410
                                if(PointList[i].Position.Latitude < 0) u8_1 = '-';
410
                                else u8_1 = '+';
411
                                else u8_1 = '+';
411
                                i32_1 = abs(PointList[i].Position.Latitude)/10000000L;
412
                                i32_1 = abs(PointList[i].Position.Latitude)/10000000L;
412
                                i32_2 = abs(PointList[i].Position.Latitude)%10000000L;
413
                                i32_2 = abs(PointList[i].Position.Latitude)%10000000L;
413
                                sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
414
                                sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
414
                                fputs_(wpline, fp);
415
                                fputs_(wpline, fp);
415
                                // write longitude in deg
416
                                // write longitude in deg
416
                                if(PointList[i].Position.Longitude < 0) u8_1 = '-';
417
                                if(PointList[i].Position.Longitude < 0) u8_1 = '-';
417
                                else u8_1 = '+';
418
                                else u8_1 = '+';
418
                                i32_1 = abs(PointList[i].Position.Longitude)/10000000L;
419
                                i32_1 = abs(PointList[i].Position.Longitude)/10000000L;
419
                                i32_2 = abs(PointList[i].Position.Longitude)%10000000L;
420
                                i32_2 = abs(PointList[i].Position.Longitude)%10000000L;
420
                                sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
421
                                sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
421
                                fputs_(wpline, fp);
422
                                fputs_(wpline, fp);
422
                                // write tolerace radius in m
423
                                // write tolerace radius in m
423
                                sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius);
424
                                sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius);
424
                                fputs_(wpline, fp);
425
                                fputs_(wpline, fp);
425
                                // write altitude in m
426
                                // write altitude in m
426
                                if(PointList[i].Position.Altitude < 0) u8_1 = '-';
427
                                if(PointList[i].Position.Altitude < 0) u8_1 = '-';
427
                                else u8_1 = '+';
428
                                else u8_1 = '+';
428
                                if(PointList[i].Type == POINT_TYPE_POI)
429
                                if(PointList[i].Type == POINT_TYPE_POI)
429
                                {
430
                                {
430
                                        i32_1 = abs(PointList[i].Position.Altitude)/100L;  // cm --> m
431
                                        i32_1 = abs(PointList[i].Position.Altitude)/100L;  // cm --> m
431
                                        i32_2 = abs(PointList[i].Position.Altitude)%100L;
432
                                        i32_2 = abs(PointList[i].Position.Altitude)%100L;
432
                                }
433
                                }
433
                                else
434
                                else
434
                                {
435
                                {
435
                                        i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m
436
                                        i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m
436
                                        i32_2 = abs(PointList[i].Position.Altitude)%10L;
437
                                        i32_2 = abs(PointList[i].Position.Altitude)%10L;
437
                                }
438
                                }
438
                                sprintf(wpline, "Altitude=%c%ld.%01ld\r\n",  u8_1, i32_1, i32_2);
439
                                sprintf(wpline, "Altitude=%c%ld.%01ld\r\n",  u8_1, i32_1, i32_2);
439
                                fputs_(wpline, fp);
440
                                fputs_(wpline, fp);
440
                                // write climb rate in 0.1 m/s
441
                                // write climb rate in 0.1 m/s
441
                                sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate);
442
                                sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate);
442
                                fputs_(wpline, fp);
443
                                fputs_(wpline, fp);
443
                                // write hold time in s
444
                                // write hold time in s
444
                                sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime);
445
                                sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime);
445
                                fputs_(wpline, fp);
446
                                fputs_(wpline, fp);
446
                                // write event channel value
447
                                // write event channel value
447
                                sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue);
448
                                sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue);
448
                                fputs_(wpline, fp);
449
                                fputs_(wpline, fp);
449
                                // write heading in deg (0= nothing, neg. values index to poi)
450
                                // write heading in deg (0= nothing, neg. values index to poi)
450
                                sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading);
451
                                sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading);
451
                                fputs_(wpline, fp);
452
                                fputs_(wpline, fp);
452
                                // write speed in 0.1 m/s
453
                                // write speed in 0.1 m/s
453
                                sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed);
454
                                sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed);
454
                                fputs_(wpline, fp);
455
                                fputs_(wpline, fp);
455
                                // write cam angle in degree (255 -> POI-Automatic)
456
                                // write cam angle in degree (255 -> POI-Automatic)
456
                                sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle);
457
                                sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle);
457
                                fputs_(wpline, fp);
458
                                fputs_(wpline, fp);
458
                                // write point type
459
                                // write point type
459
                                sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1);
460
                                sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1);
460
                                fputs_(wpline, fp);    
461
                                fputs_(wpline, fp);    
461
                                // write prefix 
462
                                // write prefix 
462
                                sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name);
463
                                sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name);
463
                                fputs_(wpline, fp);
464
                                fputs_(wpline, fp);
464
                        } // EOF loop over all points
465
                        } // EOF loop over all points
465
                } // EOF if(PointCount)
466
                } // EOF if(PointCount)
466
                if(EOF == fclose_(fp))
467
                if(EOF == fclose_(fp))
467
                {
468
                {
468
                        UART1_PutString("failed!\r\n");
469
                        UART1_PutString("failed!\r\n");
469
                }
470
                }
470
                else
471
                else
471
                {
472
                {
472
                        UART1_PutString("ok\r\n");
473
                        UART1_PutString("ok\r\n");
473
                        retval = WPL_OK;
474
                        retval = WPL_OK;
474
                }                                
475
                }                                
475
        } // EOF if(Fat16_IsValid())
476
        } // EOF if(Fat16_IsValid())
476
        else
477
        else
477
        {
478
        {
478
                UART1_PutString("no file system found!\r\n");
479
                UART1_PutString("no file system found!\r\n");
479
                retval = WPL_NO_SDCARD_FOUND;
480
                retval = WPL_NO_SDCARD_FOUND;
480
        }
481
        }
481
        return(retval);
482
        return(retval);
482
}
483
}
483
 
484
 
484
u8 PointList_Load(u8 * filename, u8* listname, u8 listnamelen, u8 use_preset_speed)
485
u8 PointList_Load(u8 * filename, u8* listname, u8 listnamelen, u8 use_preset_speed)
485
{
486
{
486
        File_t *fp;
487
        File_t *fp;
487
        s8 wpline[LINE_MAX];
488
        s8 wpline[LINE_MAX];
488
        u8 retval = WPL_ERROR;
489
        u8 retval = WPL_ERROR;
489
       
490
       
490
        s8 *name, *value;
491
        s8 *name, *value;
491
        u8 i;
492
        u8 i;
492
 
493
 
493
        u8 IsGeneralSection = 0;
494
        u8 IsGeneralSection = 0;
494
        u8 IsPointSection  = 0;
495
        u8 IsPointSection  = 0;
495
        u8 WPNumber = 0;
496
        u8 WPNumber = 0;
496
 
497
 
497
        // clear point list first
498
        // clear point list first
498
        PointList_Clear();
499
        PointList_Clear();
499
        HeadingOld = -1; // updates the direction if the new direction is the same like last time
500
        HeadingOld = -1; // updates the direction if the new direction is the same like last time
500
        UART1_PutString("\n\r Read ");
501
        UART1_PutString("\n\r Read ");
501
        UART1_PutString(filename);
502
        UART1_PutString(filename);
502
        UART1_PutString("...");
503
        UART1_PutString("...");
503
 
504
 
504
        if(Fat16_IsValid())
505
        if(Fat16_IsValid())
505
        {       // check if wpl file is existing
506
        {       // check if wpl file is existing
506
                fp = fopen_(filename, 'r');             // try to open the file
507
                fp = fopen_(filename, 'r');             // try to open the file
507
                if(fp == NULL)
508
                if(fp == NULL)
508
                {
509
                {
509
                        UART1_PutString("ERROR: Reading waypoint file!\r\n");
510
                        UART1_PutString("ERROR: Reading waypoint file!\r\n");
510
                        return(retval);
511
                        return(retval);
511
                }
512
                }
512
                // read all lines from file
513
                // read all lines from file
513
                while(fgets_(wpline, LINE_MAX, fp) != 0)
514
                while(fgets_(wpline, LINE_MAX, fp) != 0)
514
                {
515
                {
515
                        if ( // ignorelines starting with \r,\n,' ',';','#'
516
                        if ( // ignorelines starting with \r,\n,' ',';','#'
516
                                (wpline[0] != '\n') &&
517
                                (wpline[0] != '\n') &&
517
                                (wpline[0] != '\r') &&
518
                                (wpline[0] != '\r') &&
518
                                (wpline[0] != ' ' ) &&
519
                                (wpline[0] != ' ' ) &&
519
                                (wpline[0] != ';' ) &&
520
                                (wpline[0] != ';' ) &&
520
                                (wpline[0] != '#' )
521
                                (wpline[0] != '#' )
521
                                )
522
                                )
522
                        {
523
                        {
523
                                // check for section line found
524
                                // check for section line found
524
                                if(wpline[0] == '[')
525
                                if(wpline[0] == '[')
525
                                {
526
                                {
526
                                        // next section found
527
                                        // next section found
527
                                        IsGeneralSection = 0;
528
                                        IsGeneralSection = 0;
528
                                        IsPointSection = 0;
529
                                        IsPointSection = 0;
529
 
530
 
530
                                        name  = strtok(&wpline[1], "]");
531
                                        name  = strtok(&wpline[1], "]");
531
                                        if(name != NULL)   // if section name
532
                                        if(name != NULL)   // if section name
532
                                        {
533
                                        {
533
                                                // check section type
534
                                                // check section type
534
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
535
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
535
 
536
 
536
                                                if(strncmp(name, "POINT", 5) == 0)
537
                                                if(strncmp(name, "POINT", 5) == 0)
537
                                                {
538
                                                {
538
                                                        IsPointSection = (u8)atoi(&name[5]);
539
                                                        IsPointSection = (u8)atoi(&name[5]);
539
                                                        PointCount++;
540
                                                        PointCount++;
540
                                                }
541
                                                }
541
                                                else if(strcmp(name, "GENERAL") == 0)
542
                                                else if(strcmp(name, "GENERAL") == 0)
542
                                                {
543
                                                {
543
                                                        IsGeneralSection = 1;
544
                                                        IsGeneralSection = 1;
544
                                                }
545
                                                }
545
                                                else
546
                                                else
546
                                                {
547
                                                {
547
                                                        UART1_PutString("Unknown section: ");
548
                                                        UART1_PutString("Unknown section: ");
548
                                                        UART1_PutString(name);
549
                                                        UART1_PutString(name);
549
                                                        UART1_PutString("\r\n");
550
                                                        UART1_PutString("\r\n");
550
                                                }
551
                                                }
551
                                        }
552
                                        }
552
                                } // EOF section line
553
                                } // EOF section line
553
                                else
554
                                else
554
                                {       // look for key entrys of each sections
555
                                {       // look for key entrys of each sections
555
                                        name  = strtok(wpline, "="); // get name
556
                                        name  = strtok(wpline, "="); // get name
556
                                        value = strtok(NULL, "="); // get value
557
                                        value = strtok(NULL, "="); // get value
557
                                        if ((name != NULL) && (value != NULL))
558
                                        if ((name != NULL) && (value != NULL))
558
                                        {
559
                                        {
559
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
560
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
560
                                                if(IsPointSection &&  (IsPointSection <= WPNumber))
561
                                                if(IsPointSection &&  (IsPointSection <= WPNumber))
561
                                                {
562
                                                {
562
                                                        if(strcmp(name, "LATITUDE") == 0)
563
                                                        if(strcmp(name, "LATITUDE") == 0)
563
                                                        {
564
                                                        {
564
                                                                PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7);
565
                                                                PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7);
565
                                                        }
566
                                                        }
566
                                                        else if(strcmp(name, "LONGITUDE") == 0)
567
                                                        else if(strcmp(name, "LONGITUDE") == 0)
567
                                                        {
568
                                                        {
568
                                                                PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7);
569
                                                                PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7);
569
                                                        }
570
                                                        }
570
                                                        else if(strcmp(name, "RADIUS") == 0)
571
                                                        else if(strcmp(name, "RADIUS") == 0)
571
                                                        {
572
                                                        {
572
                                                                PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value);
573
                                                                PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value);
573
                                                        }
574
                                                        }
574
                                                        else if(strcmp(name, "ALTITUDE") == 0)
575
                                                        else if(strcmp(name, "ALTITUDE") == 0)
575
                                                        {
576
                                                        {
576
                                                                PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0);      // in cm
577
                                                                PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0);      // in cm
577
                                                                PointList[IsPointSection-1].Position.Status = NEWDATA;
578
                                                                PointList[IsPointSection-1].Position.Status = NEWDATA;
578
                                                        }
579
                                                        }
579
                                                        else if(strcmp(name, "CLIMBRATE") == 0)
580
                                                        else if(strcmp(name, "CLIMBRATE") == 0)
580
                                                        {
581
                                                        {
581
                                                                PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value);
582
                                                                PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value);
582
                                                        }
583
                                                        }
583
                                                        else if(strcmp(name, "DELAYTIME") == 0)
584
                                                        else if(strcmp(name, "DELAYTIME") == 0)
584
                                                        {
585
                                                        {
585
                                                                PointList[IsPointSection-1].HoldTime = (u8)atoi(value);
586
                                                                PointList[IsPointSection-1].HoldTime = (u8)atoi(value);
586
                                                        }
587
                                                        }
587
                                                        else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0)
588
                                                        else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0)
588
                                                        {
589
                                                        {
589
                                                                PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value);
590
                                                                PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value);
590
                                                        }
591
                                                        }
591
                                                        else if(strcmp(name, "HEADING") == 0)
592
                                                        else if(strcmp(name, "HEADING") == 0)
592
                                                        {
593
                                                        {
593
                                                                PointList[IsPointSection-1].Heading = (s16)atoi(value);
594
                                                                PointList[IsPointSection-1].Heading = (s16)atoi(value);
594
                                                        }
595
                                                        }
595
                                                        else if(strcmp(name, "SPEED") == 0)
596
                                                        else if(strcmp(name, "SPEED") == 0)
596
                                                        {
597
                                                        {
597
                                                                if(use_preset_speed) PointList[IsPointSection-1].Speed = use_preset_speed;
598
                                                                if(use_preset_speed) PointList[IsPointSection-1].Speed = use_preset_speed;
598
                                                                else PointList[IsPointSection-1].Speed = (u8)atoi(value);
599
                                                                else PointList[IsPointSection-1].Speed = (u8)atoi(value);
599
                                                        }
600
                                                        }
600
                                                        else if(strcmp(name, "CAM-NICK") == 0)
601
                                                        else if(strcmp(name, "CAM-NICK") == 0)
601
                                                        {
602
                                                        {
602
                                                                PointList[IsPointSection-1].CamAngle = (u8)atoi(value);
603
                                                                PointList[IsPointSection-1].CamAngle = (u8)atoi(value);
603
                                                        }
604
                                                        }
604
                                                        else if(strcmp(name, "TYPE") == 0)
605
                                                        else if(strcmp(name, "TYPE") == 0)
605
                                                        {
606
                                                        {
606
                                                                PointList[IsPointSection-1].Type = (u8)atoi(value);
607
                                                                PointList[IsPointSection-1].Type = (u8)atoi(value);
607
                                                                if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--;  // index shift
608
                                                                if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--;  // index shift
608
                                                                else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID;
609
                                                                else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID;
609
                                                       
610
                                                       
610
                                                                switch(PointList[IsPointSection-1].Type)
611
                                                                switch(PointList[IsPointSection-1].Type)
611
                                                                {
612
                                                                {
612
                                                                        case POINT_TYPE_WP:
613
                                                                        case POINT_TYPE_WP:
613
                                                                                // this works only if altitude key is set before point type key in WPL file     !!
614
                                                                                // this works only if altitude key is set before point type key in WPL file     !!
614
                                                                                PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs 
615
                                                                                PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs 
615
                                                                                WPCount++;
616
                                                                                WPCount++;
616
                                                                                break;
617
                                                                                break;
617
 
618
 
618
                                                                        case POINT_TYPE_POI:
619
                                                                        case POINT_TYPE_POI:
619
                                                                                POICount++;
620
                                                                                POICount++;
620
                                                                                break;
621
                                                                                break;
621
                                                                }
622
                                                                }
622
                                                        }
623
                                                        }
623
                                                        else if(strcmp(name, "PREFIX") == 0)
624
                                                        else if(strcmp(name, "PREFIX") == 0)
624
                                                        {
625
                                                        {
625
                                                                strncpy(PointList[IsPointSection-1].Name, value, 4);
626
                                                                strncpy(PointList[IsPointSection-1].Name, value, 4);
626
                                                                PointList[IsPointSection-1].Name[3] = 0; // Terminate string
627
                                                                PointList[IsPointSection-1].Name[3] = 0; // Terminate string
627
                                                        }
628
                                                        }
628
                                                        else
629
                                                        else
629
                                                        {
630
                                                        {
630
                                                                UART1_PutString("Unknown key: ");
631
                                                                UART1_PutString("Unknown key: ");
631
                                                                UART1_PutString(name);
632
                                                                UART1_PutString(name);
632
                                                                UART1_PutString("\r\n");
633
                                                                UART1_PutString("\r\n");
633
                                                        }      
634
                                                        }      
634
                                                } // EOF point section
635
                                                } // EOF point section
635
                                                else if(IsGeneralSection)
636
                                                else if(IsGeneralSection)
636
                                                {
637
                                                {
637
                                                        if(strcmp(name, "NUMBEROFWAYPOINTS") == 0)
638
                                                        if(strcmp(name, "NUMBEROFWAYPOINTS") == 0)
638
                                                        {      
639
                                                        {      
639
                                                                WPNumber = (u8)atoi(value);
640
                                                                WPNumber = (u8)atoi(value);
640
                                                                if(!WPNumber) // no waypoints in file
641
                                                                if(!WPNumber) // no waypoints in file
641
                                                                {
642
                                                                {
642
                                                                        return(WPL_NO_WAYPOINTS); // we are done here   
643
                                                                        return(WPL_NO_WAYPOINTS); // we are done here   
643
                                                                }
644
                                                                }
644
                                                                else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list
645
                                                                else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list
645
                                                                {
646
                                                                {
646
                                                                        UART1_PutString("To many points!");
647
                                                                        UART1_PutString("To many points!");
647
                                                                        return(WPL_ERROR);
648
                                                                        return(WPL_ERROR);
648
                                                                }
649
                                                                }
649
                                                        }
650
                                                        }
650
                                                        else if (strcmp(name, "FILEVERSION") == 0)
651
                                                        else if (strcmp(name, "FILEVERSION") == 0)
651
                                                        {
652
                                                        {
652
                                                                if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE)
653
                                                                if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE)
653
                                                                {
654
                                                                {
654
                                                                        PointList_Clear();
655
                                                                        PointList_Clear();
655
                                                                        UART1_PutString("Bad file version!\r\n");
656
                                                                        UART1_PutString("Bad file version!\r\n");
656
                                                                        return(WPL_ERROR);     
657
                                                                        return(WPL_ERROR);     
657
                                                                }
658
                                                                }
658
                                                        }
659
                                                        }
659
                                                        else if (strcmp(name, "NAME") == 0)
660
                                                        else if (strcmp(name, "NAME") == 0)
660
                                                        {
661
                                                        {
661
                                                                if(listname)
662
                                                                if(listname)
662
                                                                {
663
                                                                {
663
                                                                        u8 len = strlen(value);
664
                                                                        u8 len = strlen(value);
664
                                                                        if(len)
665
                                                                        if(len)
665
                                                                        {
666
                                                                        {
666
                                                                                if(value[len-1] == '\r')
667
                                                                                if(value[len-1] == '\r')
667
                                                                                {
668
                                                                                {
668
                                                                                        value[len-1] = 0;
669
                                                                                        value[len-1] = 0;
669
//                                                                                      len--;
670
//                                                                                      len--;
670
                                                                                }
671
                                                                                }
671
                                                                        }
672
                                                                        }
672
                                                                        if(len > listnamelen) len = listnamelen;
673
                                                                        if(len > listnamelen) len = listnamelen;
673
                                                                        if(len)
674
                                                                        if(len)
674
                                                                        {
675
                                                                        {
675
                                                                                value[len-1] = 0; // terminate string
676
                                                                                value[len-1] = 0; // terminate string
676
                                                                                if(listname) memcpy(listname, value, len);
677
                                                                                if(listname) memcpy(listname, value, len);
677
                                                                        }
678
                                                                        }
678
                                                                        NewWPL_Name = 1;
679
                                                                        NewWPL_Name = 1;
679
                                                                }
680
                                                                }
680
                                                        }
681
                                                        }
681
                                                        else
682
                                                        else
682
                                                        {
683
                                                        {
683
                                                                UART1_PutString("Unknown key: ");
684
                                                                UART1_PutString("Unknown key: ");
684
                                                                UART1_PutString(name);
685
                                                                UART1_PutString(name);
685
                                                                UART1_PutString("\r\n");
686
                                                                UART1_PutString("\r\n");
686
                                                        }
687
                                                        }
687
                                                } // EOF general section
688
                                                } // EOF general section
688
                                        } // EOF valid key entry
689
                                        } // EOF valid key entry
689
                                } // EOF key entry line
690
                                } // EOF key entry line
690
                        } // valid line
691
                        } // valid line
691
                } // EOF loop over all lines
692
                } // EOF loop over all lines
692
                fclose_(fp);
693
                fclose_(fp);
693
                NaviData.WaypointNumber = WPCount;
694
                NaviData.WaypointNumber = WPCount;
694
                retval = WPL_OK;        
695
                retval = WPL_OK;        
695
                UART1_PutString("ok\r\n");                               
696
                UART1_PutString("ok\r\n");                               
696
        } // EOF if(Fat16_IsValid())
697
        } // EOF if(Fat16_IsValid())
697
        else
698
        else
698
        {
699
        {
699
                UART1_PutString("no file system found!\r\n");
700
                UART1_PutString("no file system found!\r\n");
700
                retval = WPL_NO_SDCARD_FOUND;
701
                retval = WPL_NO_SDCARD_FOUND;
701
        }      
702
        }      
702
        return(retval);
703
        return(retval);
703
}
704
}
704
 
705
 
705
// load actual point list from SD card
706
// load actual point list from SD card
706
u8 PointList_ReadFromFile(WPL_Store_t * pWPL_Store)
707
u8 PointList_ReadFromFile(WPL_Store_t * pWPL_Store)
707
{
708
{
708
        u8 filename[30];       
709
        u8 filename[30];       
709
 
710
 
710
        pWPL_Store->Name[0] = 0; // clear current list name
711
        pWPL_Store->Name[0] = 0; // clear current list name
711
 
712
 
712
        // user absolute path, i.e. leading /
713
        // user absolute path, i.e. leading /
713
        if(pWPL_Store->Index == 0) // index 0 looks for a default WPL file in the root
714
        if(pWPL_Store->Index == 0) // index 0 looks for a default WPL file in the root
714
        {
715
        {
715
                sprintf(filename, "/default.wpl");     
716
                sprintf(filename, "/default.wpl");     
716
        }
717
        }
717
        else
718
        else
718
        {
719
        {
719
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
720
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
720
        }
721
        }
721
        return PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),0);
722
        return PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),0);
722
}
723
}
723
 
724
 
724
// save actual point list to SD card
725
// save actual point list to SD card
725
u8 PointList_WriteToFile(WPL_Store_t * pWPL_Store)
726
u8 PointList_WriteToFile(WPL_Store_t * pWPL_Store)
726
{
727
{
727
        u8 filename[30];
728
        u8 filename[30];
728
       
729
       
729
       
730
       
730
        if(PointCount == 0) return(WPL_NO_WAYPOINTS);
731
        if(PointCount == 0) return(WPL_NO_WAYPOINTS);
731
        // user absolute path, i.e. leading /   
732
        // user absolute path, i.e. leading /   
732
        if(pWPL_Store->Index == 0)
733
        if(pWPL_Store->Index == 0)
733
        {
734
        {
734
                sprintf(filename, "/default.wpl");
735
                sprintf(filename, "/default.wpl");
735
        }
736
        }
736
        else
737
        else
737
        {
738
        {
738
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
739
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
739
        }
740
        }
740
        return PointList_Save(filename, pWPL_Store->Name, pWPL_Store->OverwriteFile);
741
        return PointList_Save(filename, pWPL_Store->Name, pWPL_Store->OverwriteFile);
741
}
742
}
742
 
743
 
743
 
744
 
744
// save actual gps positiin and heading to file
745
// save actual gps positiin and heading to file
745
u8 PointList_SaveSinglePoint(WPL_Store_t * pWPL_Store)
746
u8 PointList_SaveSinglePoint(WPL_Store_t * pWPL_Store)
746
{
747
{
747
        u8 retval = WPL_ERROR;
748
        u8 retval = WPL_ERROR;
748
        u8 filename[30];
749
        u8 filename[30];
749
        Point_t WP;
750
        Point_t WP;
750
 
751
 
751
        UART1_PutString("\n\r write single point\n\r");
752
        UART1_PutString("\n\r write single point\n\r");
752
        if(GPSData.Position.Status == INVALID)
753
        if(GPSData.Position.Status == INVALID)
753
         {
754
         {
754
                UART1_PutString("ERROR: No GPS - Fix\n\r");
755
                UART1_PutString("ERROR: No GPS - Fix\n\r");
755
                return(retval);
756
                return(retval);
756
         }
757
         }
757
 
758
 
758
        // clear current point list
759
        // clear current point list
759
        PointList_Clear();
760
        PointList_Clear();
760
        // prepare WP at current position
761
        // prepare WP at current position
761
 
762
 
762
        if(NCFlags & NC_FLAG_FREE || NaviData.TargetPositionDeviation.Distance > 7*10)
763
        if(NCFlags & NC_FLAG_FREE || NaviData.TargetPositionDeviation.Distance > 7*10)
763
        {  // take actual position
764
        {  // take actual position
764
                GPSPos_Copy(&GPSData.Position, &(WP.Position));
765
                GPSPos_Copy(&GPSData.Position, &(WP.Position));
765
        }
766
        }
766
        else
767
        else
767
        {  // take last target position
768
        {  // take last target position
768
                GPSPos_Copy(&NaviData.TargetPosition, &(WP.Position));
769
                GPSPos_Copy(&NaviData.TargetPosition, &(WP.Position));
769
        }
770
        }
770
 
771
 
771
        GPSPos_Copy(&GPSData.Position, &(WP.Position));
772
        GPSPos_Copy(&GPSData.Position, &(WP.Position));
772
        // set heading
773
        // set heading
773
        WP.Heading = (CompassSetpointCorrected/10 + Parameter.CamOrientation * 15) % 360;
774
        WP.Heading = (CompassSetpointCorrected/10 + Parameter.CamOrientation * 15) % 360;
774
        if(WP.Heading == 0) WP.Heading = 360;
775
        if(WP.Heading == 0) WP.Heading = 360;
775
        WP.ToleranceRadius = 120; // 12m 
776
        WP.ToleranceRadius = 120; // 12m 
776
        WP.HoldTime  = 2;
777
        WP.HoldTime  = 2;
777
        WP.Index  = 1;
778
        WP.Index  = 1;
778
        WP.Type = POINT_TYPE_WP;
779
        WP.Type = POINT_TYPE_WP;
779
        WP.WP_EventChannelValue = 0;
780
        WP.WP_EventChannelValue = 0;
780
        if(FC.StatusFlags & FC_STATUS_FLY && ((FromFC_VarioCharacter != ' ') || (SimulationFlags & SIMULATION_ACTIVE))) // only in flight and if the Altitude control is enabled
781
        if(FC.StatusFlags & FC_STATUS_FLY && ((FromFC_VarioCharacter != ' ') || (SimulationFlags & SIMULATION_ACTIVE))) // only in flight and if the Altitude control is enabled
781
         {
782
         {
782
          WP.AltitudeRate = 255;  // Auto
783
          WP.AltitudeRate = 255;  // Auto
783
          WP.Position.Altitude = NaviData.SetpointAltitude / 2;
784
          WP.Position.Altitude = NaviData.SetpointAltitude / 2;
784
         }
785
         }
785
        else
786
        else
786
        {
787
        {
787
         WP.AltitudeRate = 0;
788
         WP.AltitudeRate = 0;
788
     WP.Position.Altitude = 0;
789
     WP.Position.Altitude = 0;
789
        }
790
        }
790
        WP.Speed = 50; // beim Laden wird der Wert nochmal neu gesetzt
791
        WP.Speed = 50; // beim Laden wird der Wert nochmal neu gesetzt
791
        WP.CamAngle = 0;
792
        WP.CamAngle = 0;
792
        WP.Name[0] = 'S';
793
        WP.Name[0] = 'S';
793
        WP.Name[1] = 'P';
794
        WP.Name[1] = 'P';
794
        WP.Name[2] = 'T';
795
        WP.Name[2] = 'T';
795
        WP.Name[3] = 0;
796
        WP.Name[3] = 0;
796
        // add this point to wp list
797
        // add this point to wp list
797
        PointList_SetAt(&WP);
798
        PointList_SetAt(&WP);
798
 
799
 
799
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
800
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
800
        UART1_PutString(filename);
801
        UART1_PutString(filename);
801
        sprintf(pWPL_Store->Name, "POINT%03d ", pWPL_Store->Index);
802
        sprintf(pWPL_Store->Name, "POINT%03d ", pWPL_Store->Index);
802
        retval = PointList_Save(filename, pWPL_Store->Name, 1);
803
        retval = PointList_Save(filename, pWPL_Store->Name, 1);
803
 
804
 
804
        // clear current point list
805
        // clear current point list
805
        if((NC_GPS_ModeCharacter != 'w') && (NC_GPS_ModeCharacter != 'W')) PointList_Clear();
806
        if((NC_GPS_ModeCharacter != 'w') && (NC_GPS_ModeCharacter != 'W')) PointList_Clear();
806
        else // es ist gearde ein Wegpunktflug aktiv -> updaten
807
        else // es ist gearde ein Wegpunktflug aktiv -> updaten
807
        {
808
        {
808
                if(FC.StatusFlags & FC_STATUS_FLY) PointList_WPActive(TRUE);
809
                if(FC.StatusFlags & FC_STATUS_FLY) PointList_WPActive(TRUE);
809
                GPS_pWaypoint = PointList_WPBegin(); // updates POI index
810
                GPS_pWaypoint = PointList_WPBegin(); // updates POI index
810
        }
811
        }
811
 
812
 
812
        return(retval);
813
        return(retval);
813
}
814
}
814
// load target gps posititon and heading from file
815
// load target gps posititon and heading from file
815
u8 PointList_LoadSinglePoint(WPL_Store_t * pWPL_Store)
816
u8 PointList_LoadSinglePoint(WPL_Store_t * pWPL_Store)
816
{
817
{
817
        u8 filename[30], result = 0;
818
        u8 filename[30], result = 0;
818
       
819
       
819
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
820
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
820
        pWPL_Store->Name[0] = 0; // clear current list name
821
        pWPL_Store->Name[0] = 0; // clear current list name
821
        result = PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),Parameter.SingleWpSpeed);
822
        result = PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),Parameter.SingleWpSpeed);
822
        if(result) UART1_Request_ReadPoint = 1; // Sends Point 1 to the PC
823
        if(result) UART1_Request_ReadPoint = 1; // Sends Point 1 to the PC
823
        return(result);
824
        return(result);
824
}
825
}
825
 
826
 
826
 
827
 
827
 
828
 
828
void ClearWLP_Name(void)
829
void ClearWLP_Name(void)
829
{
830
{
830
        u8 i;
831
        u8 i;
831
        for(i=0; i<sizeof(WPL_Store.Name);i++) WPL_Store.Name[i] = 0;
832
        for(i=0; i<sizeof(WPL_Store.Name);i++) WPL_Store.Name[i] = 0;
832
        NewWPL_Name = 1;
833
        NewWPL_Name = 1;
833
}
834
}
834
 
835
 
835
// move actual point list to ref pos., the point in the list marked by index gets the RefPos afterwards
836
// move actual point list to ref pos., the point in the list marked by index gets the RefPos afterwards
836
u8 PointList_Move(u8 RefIndex, GPS_Pos_t* pRefPos, u16 RotationAngle)
837
u8 PointList_Move(u8 RefIndex, GPS_Pos_t* pRefPos, u16 RotationAngle)
837
{
838
{
838
        u8 retval = 0;
839
        u8 retval = 0;
839
        s32 altitude;
840
        s32 altitude;
840
        GPS_Pos_t OldRefPos;
841
        GPS_Pos_t OldRefPos;
841
        GPS_Pos_Deviation_t RefDeviation;
842
        GPS_Pos_Deviation_t RefDeviation;
842
         
843
         
843
        // check inputs for plausibility;
844
        // check inputs for plausibility;
844
        if((RefIndex == 0) || (RefIndex > PointCount)) return(retval); 
845
        if((RefIndex == 0) || (RefIndex > PointCount)) return(retval); 
845
        if(pRefPos == NULL) return(retval);
846
        if(pRefPos == NULL) return(retval);
846
        if(pRefPos->Status == INVALID) return(retval);
847
        if(pRefPos->Status == INVALID) return(retval);
847
 
848
 
848
        if(GPSPos_Copy(&(PointList[RefIndex-1].Position), &OldRefPos)) // backup old reference position
849
        if(GPSPos_Copy(&(PointList[RefIndex-1].Position), &OldRefPos)) // backup old reference position
849
        {
850
        {
850
                u8 i;
851
                u8 i;
851
                // iterate the position list
852
                // iterate the position list
852
                for(i = 0; i < PointCount; i++)
853
                for(i = 0; i < PointCount; i++)
853
                {
854
                {
854
                        retval = 0;
855
                        retval = 0;
855
                        // backup altitude of this point
856
                        // backup altitude of this point
856
                        altitude = PointList[i].Position.Altitude;
857
                        altitude = PointList[i].Position.Altitude;
857
                        // calculate deviation form old ref, i.e the north and east shift of each point in the list from the reference position
858
                        // calculate deviation form old ref, i.e the north and east shift of each point in the list from the reference position
858
                        if(!GPSPos_Deviation(&(PointList[i].Position), &OldRefPos, &RefDeviation)) break;
859
                        if(!GPSPos_Deviation(&(PointList[i].Position), &OldRefPos, &RefDeviation)) break;
859
                        // copy of the new reference position into this list place
860
                        // copy of the new reference position into this list place
860
                        if(!GPSPos_Copy(pRefPos, &(PointList[i].Position))) break;
861
                        if(!GPSPos_Copy(pRefPos, &(PointList[i].Position))) break;
861
                        // restore former altitude 
862
                        // restore former altitude 
862
                        PointList[i].Position.Altitude = altitude;
863
                        PointList[i].Position.Altitude = altitude;
863
                        // move new reference according to the deviation of the old reference
864
                        // move new reference according to the deviation of the old reference
864
                        if(RotationAngle > 0)
865
                        if(RotationAngle > 0)
865
                        {
866
                        {
866
                                retval = GPSPos_ShiftGeodetic(&(PointList[i].Position), (RefDeviation.Bearing + 180 + RotationAngle)%360, RefDeviation.Distance );
867
                                retval = GPSPos_ShiftGeodetic(&(PointList[i].Position), (RefDeviation.Bearing + 180 + RotationAngle)%360, RefDeviation.Distance );
867
                                // Now rotate the heading positions if they are fixed angles
868
                                // Now rotate the heading positions if they are fixed angles
868
                                if(PointList[i].Heading >= 0 && PointList[i].Heading <= 360) PointList[i].Heading = (PointList[i].Heading + RotationAngle) % 360;
869
                                if(PointList[i].Heading >= 0 && PointList[i].Heading <= 360) PointList[i].Heading = (PointList[i].Heading + RotationAngle) % 360;
869
                        }
870
                        }
870
                        else // no rotation
871
                        else // no rotation
871
                        {
872
                        {
872
                                // move new reference according to the deviation of the old reference
873
                                // move new reference according to the deviation of the old reference
873
                                retval = GPSPos_ShiftCartesian(&(PointList[i].Position), RefDeviation.North, RefDeviation.East);
874
                                retval = GPSPos_ShiftCartesian(&(PointList[i].Position), RefDeviation.North, RefDeviation.East);
874
                        }
875
                        }
875
                        if(!retval) break;             
876
                        if(!retval) break;             
876
                }
877
                }
877
        } // else ref pos old not copied!
878
        } // else ref pos old not copied!
878
        if(!retval) PointList_Clear();
879
        if(!retval) PointList_Clear();
879
        return(retval);
880
        return(retval);
880
}
881
}
881
 
882
 
882
 
883
 
883
 
884
 
884
 
885