Subversion Repositories NaviCtrl

Rev

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

Rev 695 Rev 737
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
Point_t PointList[MAX_LIST_LEN];
70
Point_t PointList[MAX_LIST_LEN];
71
u8 WPIndex = 0;         // list index of GPS point representig the current WP, can be maximal WPCount
71
u8 WPIndex = 0;         // list index of GPS point representig the current WP, can be maximal WPCount
72
u8 POIIndex = 0;        // list index of GPS Point representing the current POI, can be maximal WPCount
72
u8 POIIndex = 0;        // list index of GPS Point representing the current POI, can be maximal WPCount
73
u8 WPCount = 0;         // number of waypoints
73
u8 WPCount = 0;         // number of waypoints
74
u8 PointCount = 0;      // number of points in the list can be maximal equal to MAX_LIST_LEN
74
u8 PointCount = 0;      // number of points in the list can be maximal equal to MAX_LIST_LEN
75
u8 POICount = 0;        // number of point of interest in the list
75
u8 POICount = 0;        // number of point of interest in the list
76
u8 FsPointCnt = 0;
76
u8 FsPointCnt = 0;
77
s16 HeadingOld = -1;
77
s16 HeadingOld = -1;
78
u32 SD_WaypointTimeout = 5; // Setting on SD-Card
78
u32 SD_WaypointTimeout = 5; // Setting on SD-Card
79
 
79
 
80
u8 WPActive = FALSE;
80
u8 WPActive = FALSE;
81
 
81
 
82
u8 PointList_Init(void)
82
u8 PointList_Init(void)
83
{
83
{
84
        return PointList_Clear();
84
        return PointList_Clear();
85
}
85
}
86
 
86
 
87
u8 PointList_Clear(void)
87
u8 PointList_Clear(void)
88
{
88
{
89
        u8 i;
89
        u8 i;
90
        WPIndex = 0;    // real list position are 1 ,2, 3 ...
90
        WPIndex = 0;    // real list position are 1 ,2, 3 ...
91
        POIIndex = 0;   // real list position are 1 ,2, 3 ...
91
        POIIndex = 0;   // real list position are 1 ,2, 3 ...
92
        WPCount = 0;    // no waypoints
92
        WPCount = 0;    // no waypoints
93
        FsPointCnt = 0;
93
        FsPointCnt = 0;
94
    POICount = 0;
94
    POICount = 0;
95
        PointCount = 0; // no contents
95
        PointCount = 0; // no contents
96
        WPActive = FALSE;
96
        WPActive = FALSE;
97
        NaviData.WaypointNumber = WPCount;
97
        NaviData.WaypointNumber = WPCount;
98
        NaviData.WaypointIndex = 0;
98
        NaviData.WaypointIndex = 0;
99
        for(i = 0; i < MAX_LIST_LEN; i++)
99
        for(i = 0; i < MAX_LIST_LEN; i++)
100
        {
100
        {
101
                PointList[i].Position.Status = INVALID;
101
                PointList[i].Position.Status = INVALID;
102
                PointList[i].Position.Latitude = 0;
102
                PointList[i].Position.Latitude = 0;
103
                PointList[i].Position.Longitude = 0;
103
                PointList[i].Position.Longitude = 0;
104
                PointList[i].Position.Altitude = 0;
104
                PointList[i].Position.Altitude = 0;
105
                PointList[i].Heading = 361;             // invalid value
105
                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
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].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
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].Event_Flag = 0;            // future implementation
108
                PointList[i].Event_Flag = 0;            // future implementation
109
                PointList[i].Index = 0;
109
                PointList[i].Index = 0;
110
                PointList[i].Type = POINT_TYPE_INVALID;
110
                PointList[i].Type = POINT_TYPE_INVALID;
111
                PointList[i].WP_EventChannelValue = 0;
111
                PointList[i].WP_EventChannelValue = 0;
112
                PointList[i].AltitudeRate = 0;          // no change of setpoint
112
                PointList[i].AltitudeRate = 0;          // no change of setpoint
113
                PointList[i].Speed = 0;
113
                PointList[i].Speed = 0;
114
                PointList[i].CamAngle = 0;
114
                PointList[i].CamAngle = 0;
115
                PointList[i].Name[0] = 0;
115
                PointList[i].Name[0] = 0;
116
        }
116
        }
117
        ClearWLP_Name();
117
        ClearWLP_Name();
118
        return TRUE;           
118
        return TRUE;           
119
}
119
}
120
 
120
 
121
u8 PointList_GetCount(void)
121
u8 PointList_GetCount(void)
122
{
122
{
123
        return PointCount; // number of points in the list
123
        return PointCount; // number of points in the list
124
}
124
}
125
 
125
 
126
Point_t* PointList_GetAt(u8 index)
126
Point_t* PointList_GetAt(u8 index)
127
{
127
{
128
        if((index > 0) && (index <= PointCount)) return(&(PointList[index-1])); // return pointer to this waypoint
128
        if((index > 0) && (index <= PointCount)) return(&(PointList[index-1])); // return pointer to this waypoint
129
        else return(NULL);
129
        else return(NULL);
130
}
130
}
131
 
131
 
132
u8 PointList_SetAt(Point_t* pPoint)
132
u8 PointList_SetAt(Point_t* pPoint)
133
{
133
{
134
        // if index is in range
134
        // if index is in range
135
        if((pPoint->Index > 0) && (pPoint->Index <= MAX_LIST_LEN))
135
        if((pPoint->Index > 0) && (pPoint->Index <= MAX_LIST_LEN))
136
        {
136
        {
137
                // check list entry before update
137
                // check list entry before update
138
                switch(PointList[pPoint->Index-1].Type)
138
                switch(PointList[pPoint->Index-1].Type)
139
                {
139
                {
140
                        case POINT_TYPE_INVALID: // was invalid
140
                        case POINT_TYPE_INVALID: // was invalid
141
                                switch(pPoint->Type)
141
                                switch(pPoint->Type)
142
                                {
142
                                {
143
                                        default:
143
                                        default:
144
                                        case POINT_TYPE_INVALID:
144
                                        case POINT_TYPE_INVALID:
145
                                                // nothing to do
145
                                                // nothing to do
146
                                                break;
146
                                                break;
147
 
147
 
148
                                        case POINT_TYPE_WP:
148
                                        case POINT_TYPE_WP:
149
                                                WPCount++;
149
                                                WPCount++;
150
                                                PointCount++;
150
                                                PointCount++;
151
                                                break;
151
                                                break;
152
                                       
152
                                       
153
                                        case POINT_TYPE_POI:
153
                                        case POINT_TYPE_POI:
154
                                                POICount++;
154
                                                POICount++;
155
                                                PointCount++;
155
                                                PointCount++;
156
                                                break;
156
                                                break;
157
                                        case POINT_TYPE_FS:
157
                                        case POINT_TYPE_FS:
158
                                                FsPointCnt++;
158
                                                FsPointCnt++;
159
                                                PointCount++;
159
                                                PointCount++;
160
                                                break;
160
                                                break;
161
                                }
161
                                }
162
                                break;
162
                                break;
163
                               
163
                               
164
                        case POINT_TYPE_WP: // was a waypoint
164
                        case POINT_TYPE_WP: // was a waypoint
165
                                switch(pPoint->Type)
165
                                switch(pPoint->Type)
166
                                {
166
                                {
167
                                        case POINT_TYPE_INVALID:
167
                                        case POINT_TYPE_INVALID:
168
                                                WPCount--;
168
                                                WPCount--;
169
                                                PointCount--;
169
                                                PointCount--;
170
                                                break;
170
                                                break;
171
 
171
 
172
                                        default:
172
                                        default:
173
                                        case POINT_TYPE_WP:
173
                                        case POINT_TYPE_WP:
174
                                                //nothing to do
174
                                                //nothing to do
175
                                                break;
175
                                                break;
176
                                        case POINT_TYPE_FS:
176
                                        case POINT_TYPE_FS:
177
                                                FsPointCnt++;
177
                                                FsPointCnt++;
178
                                                WPCount--;
178
                                                WPCount--;
179
                                                break;
179
                                                break;
180
                                        case POINT_TYPE_POI:
180
                                        case POINT_TYPE_POI:
181
                                                POICount++;
181
                                                POICount++;
182
                                                WPCount--;
182
                                                WPCount--;
183
                                                break;
183
                                                break;
184
                                }
184
                                }
185
                                break;
185
                                break;
186
                               
186
                               
187
                        case POINT_TYPE_POI: // was a poi
187
                        case POINT_TYPE_POI: // was a poi
188
                                switch(pPoint->Type)
188
                                switch(pPoint->Type)
189
                                {
189
                                {
190
                                        case POINT_TYPE_INVALID:
190
                                        case POINT_TYPE_INVALID:
191
                                                POICount--;
191
                                                POICount--;
192
                                                PointCount--;
192
                                                PointCount--;
193
                                                break;
193
                                                break;
194
 
194
 
195
                                        case POINT_TYPE_WP:
195
                                        case POINT_TYPE_WP:
196
                                                WPCount++;
196
                                                WPCount++;
197
                                                POICount--;
197
                                                POICount--;
198
                                                break;
198
                                                break;
199
 
199
 
200
                                        case POINT_TYPE_FS:
200
                                        case POINT_TYPE_FS:
201
                                                FsPointCnt++;
201
                                                FsPointCnt++;
202
                                                POICount--;
202
                                                POICount--;
203
                                                break;
203
                                                break;
204
                                       
204
                                       
205
                                        case POINT_TYPE_POI:
205
                                        case POINT_TYPE_POI:
206
                                        default:
206
                                        default:
207
                                                // nothing to do
207
                                                // nothing to do
208
                                                break;
208
                                                break;
209
                                }
209
                                }
210
                        case POINT_TYPE_FS: // was a Failsafe
210
                        case POINT_TYPE_FS: // was a Failsafe
211
                                switch(pPoint->Type)
211
                                switch(pPoint->Type)
212
                                {
212
                                {
213
                                        case POINT_TYPE_INVALID:
213
                                        case POINT_TYPE_INVALID:
214
                                                FsPointCnt--;
214
                                                FsPointCnt--;
215
                                                PointCount--;
215
                                                PointCount--;
216
                                                break;
216
                                                break;
217
 
217
 
218
                                        case POINT_TYPE_WP:
218
                                        case POINT_TYPE_WP:
219
                                                WPCount++;
219
                                                WPCount++;
220
                                                FsPointCnt--;
220
                                                FsPointCnt--;
221
                                                break;
221
                                                break;
222
                                       
222
                                       
223
                                        case POINT_TYPE_POI:
223
                                        case POINT_TYPE_POI:
224
                                                POICount++;
224
                                                POICount++;
225
                                                FsPointCnt--;
225
                                                FsPointCnt--;
226
                                                break;
226
                                                break;
227
 
227
 
228
                                        case POINT_TYPE_FS:
228
                                        case POINT_TYPE_FS:
229
                                                break;
229
                                                break;
230
                                        default:
230
                                        default:
231
                                                // nothing to do
231
                                                // nothing to do
232
                                                break;
232
                                                break;
233
                                }
233
                                }
234
                                break;         
234
                                break;         
235
                }
235
                }
236
                memcpy(&PointList[pPoint->Index-1], pPoint, sizeof(Point_t)); // copy data to list entry                                                                                
236
                memcpy(&PointList[pPoint->Index-1], pPoint, sizeof(Point_t)); // copy data to list entry                                                                                
237
                NaviData.WaypointNumber = WPCount;
237
                NaviData.WaypointNumber = WPCount;
238
                return pPoint->Index;
238
                return pPoint->Index;
239
        }
239
        }
240
        else return(0);
240
        else return(0);
241
}
241
}
242
 
242
 
243
// returns the pointer to the first waypoint within the list
243
// returns the pointer to the first waypoint within the list
244
Point_t* PointList_WPBegin(void)
244
Point_t* PointList_WPBegin(void)
245
{
245
{
246
        u8 i;
246
        u8 i;
247
        WPIndex = 0; // set list position invalid
247
        WPIndex = 0; // set list position invalid
248
 
248
 
249
        if(WPActive == FALSE) return(NULL);
249
        if(WPActive == FALSE) return(NULL);
250
 
250
 
251
        POIIndex = 0; // set invalid POI
251
        POIIndex = 0; // set invalid POI
252
        if(PointCount > 0)
252
        if(PointCount > 0)
253
        {
253
        {
254
                // search for first wp in list
254
                // search for first wp in list
255
                for(i = 0; i <MAX_LIST_LEN; i++)
255
                for(i = 0; i <MAX_LIST_LEN; i++)
256
                {
256
                {
257
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID))  // jump over POIs and FS-Positions
257
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID))  // jump over POIs and FS-Positions
258
                        {
258
                        {
259
                                WPIndex = i + 1;
259
                                WPIndex = i + 1;
260
                                break;
260
                                break;
261
                        }
261
                        }
262
/*
262
/*
263
                        else
263
                        else
264
                        if((PointList[i].Type == POINT_TYPE_FS) && (PointList[i].Position.Status != INVALID))
264
                        if((PointList[i].Type == POINT_TYPE_FS) && (PointList[i].Position.Status != INVALID))
265
                        {
265
                        {
266
                                GPSPos_Copy(&(PointList[i].Position), &GPS_FailsafePosition);
266
                                GPSPos_Copy(&(PointList[i].Position), &GPS_FailsafePosition);
267
                        }
267
                        }
268
*/
268
*/
269
                }
269
                }
270
                if(WPIndex) // found a WP in the list
270
                if(WPIndex) // found a WP in the list
271
                {
271
                {
272
                        NaviData.WaypointIndex = 1;
272
                        NaviData.WaypointIndex = 1;
273
                        NewWaypointsReceived = 1; // activates the Waypoint list as soon as CH is started
273
                        NewWaypointsReceived = 1; // activates the Waypoint list as soon as CH is started
274
                        // update index to POI
274
                        // update index to POI
275
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
275
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
276
                        else POIIndex = 0;                     
276
                        else POIIndex = 0;                     
277
                }
277
                }
278
                else // some points in the list but no WP found
278
                else // some points in the list but no WP found
279
                {
279
                {
280
                        NaviData.WaypointIndex = 0;
280
                        NaviData.WaypointIndex = 0;
281
                        //Check for an existing POI
281
                        //Check for an existing POI
282
                        for(i = 0; i < MAX_LIST_LEN; i++)
282
                        for(i = 0; i < MAX_LIST_LEN; i++)
283
                        {
283
                        {
284
                                if((PointList[i].Type == POINT_TYPE_POI) && (PointList[i].Position.Status != INVALID))
284
                                if((PointList[i].Type == POINT_TYPE_POI) && (PointList[i].Position.Status != INVALID))
285
                                {
285
                                {
286
                                        POIIndex = i + 1;
286
                                        POIIndex = i + 1;
287
                                        break;
287
                                        break;
288
                                }
288
                                }
289
                        }
289
                        }
290
                }
290
                }
291
        }
291
        }
292
        else // no point in the list
292
        else // no point in the list
293
        {
293
        {
294
                POIIndex = 0;
294
                POIIndex = 0;
295
                NaviData.WaypointIndex = 0;    
295
                NaviData.WaypointIndex = 0;    
296
        }
296
        }
297
 
297
 
298
        if(WPIndex) return(&(PointList[WPIndex-1]));
298
        if(WPIndex) return(&(PointList[WPIndex-1]));
299
        else return(NULL);
299
        else return(NULL);
300
}
300
}
301
 
301
 
302
// returns the last waypoint
302
// returns the last waypoint
303
Point_t* PointList_WPEnd(void)
303
Point_t* PointList_WPEnd(void)
304
{
304
{
305
       
305
       
306
        u8 i;
306
        u8 i;
307
        WPIndex = 0; // set list position invalid
307
        WPIndex = 0; // set list position invalid
308
        POIIndex = 0; // set invalid
308
        POIIndex = 0; // set invalid
309
 
309
 
310
        if(WPActive == FALSE) return(NULL);
310
        if(WPActive == FALSE) return(NULL);
311
 
311
 
312
        if(PointCount > 0)
312
        if(PointCount > 0)
313
        {
313
        {
314
                // search backward!
314
                // search backward!
315
                for(i = 1; i <= MAX_LIST_LEN; i++)
315
                for(i = 1; i <= MAX_LIST_LEN; i++)
316
                {
316
                {
317
                        if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_WP) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
317
                        if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_WP) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
318
                        {      
318
                        {      
319
                                WPIndex = MAX_LIST_LEN - i + 1;
319
                                WPIndex = MAX_LIST_LEN - i + 1;
320
                                break;
320
                                break;
321
                        }
321
                        }
322
                }
322
                }
323
                if(WPIndex) // found a WP within the list
323
                if(WPIndex) // found a WP within the list
324
                {
324
                {
325
                        NaviData.WaypointIndex = WPCount;
325
                        NaviData.WaypointIndex = WPCount;
326
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
326
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
327
                        else POIIndex = 0;     
327
                        else POIIndex = 0;     
328
                }
328
                }
329
                else // list contains some points but no WP in the list
329
                else // list contains some points but no WP in the list
330
                {
330
                {
331
                        // search backward for a POI!
331
                        // search backward for a POI!
332
                        for(i = 1; i <= MAX_LIST_LEN; i++)
332
                        for(i = 1; i <= MAX_LIST_LEN; i++)
333
                        {
333
                        {
334
                                if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_POI) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
334
                                if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_POI) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
335
                                {      
335
                                {      
336
                                        POIIndex = MAX_LIST_LEN - i + 1;
336
                                        POIIndex = MAX_LIST_LEN - i + 1;
337
                                        break;
337
                                        break;
338
                                }
338
                                }
339
                        }
339
                        }
340
                        NaviData.WaypointIndex = 0;    
340
                        NaviData.WaypointIndex = 0;    
341
                }
341
                }
342
        }
342
        }
343
        else // no point in the list
343
        else // no point in the list
344
        {
344
        {
345
                POIIndex = 0;
345
                POIIndex = 0;
346
                NaviData.WaypointIndex = 0;
346
                NaviData.WaypointIndex = 0;
347
        }
347
        }
348
        if(WPIndex) return(&(PointList[WPIndex-1]));
348
        if(WPIndex) return(&(PointList[WPIndex-1]));
349
        else return(NULL);
349
        else return(NULL);
350
}
350
}
351
 
351
 
352
// returns a pointer to the next waypoint or NULL if the end of the list has been reached
352
// returns a pointer to the next waypoint or NULL if the end of the list has been reached
353
Point_t* PointList_WPNext(void)
353
Point_t* PointList_WPNext(void)
354
{
354
{
355
        u8 wp_found = 0;
355
        u8 wp_found = 0;
356
        if(WPActive == FALSE) return(NULL);
356
        if(WPActive == FALSE) return(NULL);
357
               
357
               
358
        if(WPIndex < MAX_LIST_LEN) // if there is a next entry in the list
358
        if(WPIndex < MAX_LIST_LEN) // if there is a next entry in the list
359
        {
359
        {
360
                u8 i;
360
                u8 i;
361
                for(i = WPIndex; i < MAX_LIST_LEN; i++) // start search for next at next list entry
361
                for(i = WPIndex; i < MAX_LIST_LEN; i++) // start search for next at next list entry
362
                {
362
                {
363
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID)) // jump over POIs and FS-Positions
363
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID)) // jump over POIs and FS-Positions
364
                        {
364
                        {
365
                                wp_found = i+1;
365
                                wp_found = i+1;
366
                                break;
366
                                break;
367
                        }
367
                        }
368
/*
368
/*
369
                        else
369
                        else
370
                        if((PointList[i].Type == POINT_TYPE_FS) && (PointList[i].Position.Status != INVALID)) // jump over POIs
370
                        if((PointList[i].Type == POINT_TYPE_FS) && (PointList[i].Position.Status != INVALID)) // jump over POIs
371
                        {
371
                        {
372
                        GPSPos_Copy(&(PointList[i].Position), &GPS_FailsafePosition);
372
                        GPSPos_Copy(&(PointList[i].Position), &GPS_FailsafePosition);
373
                        }
373
                        }
374
*/
374
*/
375
                }
375
                }
376
        }
376
        }
377
        if(wp_found)
377
        if(wp_found)
378
        {
378
        {
379
                WPIndex = wp_found; // update list position
379
                WPIndex = wp_found; // update list position
380
                NaviData.WaypointIndex++;
380
                NaviData.WaypointIndex++;
381
                if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
381
                if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
382
                else POIIndex = 0;
382
                else POIIndex = 0;
383
                return(&(PointList[WPIndex-1]));        // return pointer to this waypoint
383
                return(&(PointList[WPIndex-1]));        // return pointer to this waypoint
384
        }
384
        }
385
        else
385
        else
386
        {  // no next wp found
386
        {  // no next wp found
387
                NaviData.WaypointIndex = 0;    
387
                NaviData.WaypointIndex = 0;    
388
                POIIndex = 0;
388
                POIIndex = 0;
389
                return(NULL);
389
                return(NULL);
390
        }
390
        }
391
}      
391
}      
392
 
392
 
393
void PointList_WPActive(u8 set)
393
void PointList_WPActive(u8 set)
394
{
394
{
395
        if(set)
395
        if(set)
396
        {      
396
        {      
397
                WPActive = TRUE;
397
                WPActive = TRUE;
398
                PointList_WPBegin(); // updates POI index
398
                PointList_WPBegin(); // updates POI index
399
        }
399
        }
400
        else
400
        else
401
        {
401
        {
402
                WPActive = FALSE;
402
                WPActive = FALSE;
403
                POIIndex = 0;  // disable POI also
403
                POIIndex = 0;  // disable POI also
404
        }
404
        }
405
}
405
}
406
 
406
 
407
Point_t* PointList_GetPOI(void)
407
Point_t* PointList_GetPOI(void)
408
{
408
{
409
        return PointList_GetAt(POIIndex);      
409
        return PointList_GetAt(POIIndex);      
410
}
410
}
411
 
411
 
412
 
412
 
413
#define LINE_MAX 70
413
#define LINE_MAX 70
414
#define WP_FILE_VERSION_COMPATIBLE 3
414
#define WP_FILE_VERSION_COMPATIBLE 3
415
 
415
 
416
u8 PointList_Save(u8 * filename, u8* listname, u8 overwride)
416
u8 PointList_Save(u8 * filename, u8* listname, u8 overwride)
417
{
417
{
418
        File_t *fp;
418
        File_t *fp;
419
        s8 wpline[LINE_MAX];
419
        s8 wpline[LINE_MAX];
420
        u8 retval = WPL_ERROR;
420
        u8 retval = WPL_ERROR;
421
 
421
 
422
        UART1_PutString("\n\r Save WPL...");
422
        UART1_PutString("\n\r Save WPL...");
423
 
423
 
424
        if(Fat16_IsValid())
424
        if(Fat16_IsValid())
425
        {       // check if wpl file is existing
425
        {       // check if wpl file is existing
426
                if(fexist_(filename))
426
                if(fexist_(filename))
427
                {       //file is existent
427
                {       //file is existent
428
                        if(!(overwride))
428
                        if(!(overwride))
429
                        {
429
                        {
430
                                UART1_PutString("Error: file exist!\r\n");
430
                                UART1_PutString("Error: file exist!\r\n");
431
                                return(WPL_FILEEXIST);
431
                                return(WPL_FILEEXIST);
432
                        }      
432
                        }      
433
                }
433
                }
434
                fp = fopen_(filename, 'w');             // try to open the file
434
                fp = fopen_(filename, 'w');             // try to open the file
435
                if(fp == NULL)
435
                if(fp == NULL)
436
                {
436
                {
437
                        UART1_PutString("ERROR: Creating waypoint file!\r\n");
437
                        UART1_PutString("ERROR: Creating waypoint file!\r\n");
438
                        return(retval);
438
                        return(retval);
439
                }
439
                }
440
                // Create general section and key entries
440
                // Create general section and key entries
441
                fputs_("[General]\r\n", fp);
441
                fputs_("[General]\r\n", fp);
442
                sprintf(wpline, "Name=%s\r\n",  listname);
442
                sprintf(wpline, "Name=%s\r\n",  listname);
443
                fputs_(wpline, fp);
443
                fputs_(wpline, fp);
444
                sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE);
444
                sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE);
445
                fputs_(wpline, fp);
445
                fputs_(wpline, fp);
446
                sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount);
446
                sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount);
447
                fputs_(wpline, fp);
447
                fputs_(wpline, fp);
448
                // dump all points if existent
448
                // dump all points if existent
449
                if(PointCount)
449
                if(PointCount)
450
                {
450
                {
451
                        u8 i, u8_1;
451
                        u8 i, u8_1;
452
                        s32 i32_1, i32_2;
452
                        s32 i32_1, i32_2;
453
                        NewWPL_Name = 1;
453
                        NewWPL_Name = 1;
454
                        for (i = 0; i < PointCount; i++)
454
                        for (i = 0; i < PointCount; i++)
455
                        {
455
                        {
456
                                sprintf(wpline, "[Point%d]\r\n",PointList[i].Index);
456
                                sprintf(wpline, "[Point%d]\r\n",PointList[i].Index);
457
                                fputs_(wpline, fp);
457
                                fputs_(wpline, fp);
458
                                // write latitude in deg
458
                                // write latitude in deg
459
                                if(PointList[i].Position.Latitude < 0) u8_1 = '-';
459
                                if(PointList[i].Position.Latitude < 0) u8_1 = '-';
460
                                else u8_1 = '+';
460
                                else u8_1 = '+';
461
                                i32_1 = abs(PointList[i].Position.Latitude)/10000000L;
461
                                i32_1 = abs(PointList[i].Position.Latitude)/10000000L;
462
                                i32_2 = abs(PointList[i].Position.Latitude)%10000000L;
462
                                i32_2 = abs(PointList[i].Position.Latitude)%10000000L;
463
                                sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
463
                                sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
464
                                fputs_(wpline, fp);
464
                                fputs_(wpline, fp);
465
                                // write longitude in deg
465
                                // write longitude in deg
466
                                if(PointList[i].Position.Longitude < 0) u8_1 = '-';
466
                                if(PointList[i].Position.Longitude < 0) u8_1 = '-';
467
                                else u8_1 = '+';
467
                                else u8_1 = '+';
468
                                i32_1 = abs(PointList[i].Position.Longitude)/10000000L;
468
                                i32_1 = abs(PointList[i].Position.Longitude)/10000000L;
469
                                i32_2 = abs(PointList[i].Position.Longitude)%10000000L;
469
                                i32_2 = abs(PointList[i].Position.Longitude)%10000000L;
470
                                sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
470
                                sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
471
                                fputs_(wpline, fp);
471
                                fputs_(wpline, fp);
472
                                // write tolerace radius in m
472
                                // write tolerace radius in m
473
                                sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius);
473
                                sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius);
474
                                fputs_(wpline, fp);
474
                                fputs_(wpline, fp);
475
                                // write altitude in m
475
                                // write altitude in m
476
                                if(PointList[i].Position.Altitude < 0) u8_1 = '-';
476
                                if(PointList[i].Position.Altitude < 0) u8_1 = '-';
477
                                else u8_1 = '+';
477
                                else u8_1 = '+';
478
                                if(PointList[i].Type == POINT_TYPE_POI)
478
                                if(PointList[i].Type == POINT_TYPE_POI)
479
                                {
479
                                {
480
                                        i32_1 = abs(PointList[i].Position.Altitude)/100L;  // cm --> m
480
                                        i32_1 = abs(PointList[i].Position.Altitude)/100L;  // cm --> m
481
                                        i32_2 = abs(PointList[i].Position.Altitude)%100L;
481
                                        i32_2 = abs(PointList[i].Position.Altitude)%100L;
482
                                }
482
                                }
483
                                else
483
                                else
484
                                {
484
                                {
485
                                        i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m
485
                                        i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m
486
                                        i32_2 = abs(PointList[i].Position.Altitude)%10L;
486
                                        i32_2 = abs(PointList[i].Position.Altitude)%10L;
487
                                }
487
                                }
488
                                sprintf(wpline, "Altitude=%c%ld.%01ld\r\n",  u8_1, i32_1, i32_2);
488
                                sprintf(wpline, "Altitude=%c%ld.%01ld\r\n",  u8_1, i32_1, i32_2);
489
                                fputs_(wpline, fp);
489
                                fputs_(wpline, fp);
490
                                // write climb rate in 0.1 m/s
490
                                // write climb rate in 0.1 m/s
491
                                sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate);
491
                                sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate);
492
                                fputs_(wpline, fp);
492
                                fputs_(wpline, fp);
493
                                // write hold time in s
493
                                // write hold time in s
494
                                sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime);
494
                                sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime);
495
                                fputs_(wpline, fp);
495
                                fputs_(wpline, fp);
496
                                // write event channel value
496
                                // write event channel value
497
                                sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue);
497
                                sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue);
498
                                fputs_(wpline, fp);
498
                                fputs_(wpline, fp);
499
                                // write heading in deg (0= nothing, neg. values index to poi)
499
                                // write heading in deg (0= nothing, neg. values index to poi)
500
                                sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading);
500
                                sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading);
501
                                fputs_(wpline, fp);
501
                                fputs_(wpline, fp);
502
                                // write speed in 0.1 m/s
502
                                // write speed in 0.1 m/s
503
                                sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed);
503
                                sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed);
504
                                fputs_(wpline, fp);
504
                                fputs_(wpline, fp);
505
                                // write cam angle in degree (255 -> POI-Automatic)
505
                                // write cam angle in degree (255 -> POI-Automatic)
506
                                sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle);
506
                                sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle);
507
                                fputs_(wpline, fp);
507
                                fputs_(wpline, fp);
508
                                // write point type
508
                                // write point type
509
                                sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1);
509
                                sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1);
510
                                fputs_(wpline, fp);    
510
                                fputs_(wpline, fp);    
511
                                // write prefix 
511
                                // write prefix 
512
                                sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name);
512
                                sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name);
513
                                fputs_(wpline, fp);
513
                                fputs_(wpline, fp);
514
                                sprintf(wpline, "AutoTrigger=%d\r\n", PointList[i].AutoPhotoDistance);
514
                                sprintf(wpline, "AutoTrigger=%d\r\n", PointList[i].AutoPhotoDistance);
515
                                fputs_(wpline, fp);    
515
                                fputs_(wpline, fp);    
516
                        } // EOF loop over all points
516
                        } // EOF loop over all points
517
                } // EOF if(PointCount)
517
                } // EOF if(PointCount)
518
                if(EOF == fclose_(fp))
518
                if(EOF == fclose_(fp))
519
                {
519
                {
520
                        UART1_PutString("failed!\r\n");
520
                        UART1_PutString("failed!\r\n");
521
                }
521
                }
522
                else
522
                else
523
                {
523
                {
524
                        UART1_PutString("ok\r\n");
524
                        UART1_PutString("ok\r\n");
525
                        retval = WPL_OK;
525
                        retval = WPL_OK;
526
                }                                
526
                }                                
527
        } // EOF if(Fat16_IsValid())
527
        } // EOF if(Fat16_IsValid())
528
        else
528
        else
529
        {
529
        {
530
                UART1_PutString("no file system found!\r\n");
530
                UART1_PutString("no file system found!\r\n");
531
                retval = WPL_NO_SDCARD_FOUND;
531
                retval = WPL_NO_SDCARD_FOUND;
532
        }
532
        }
533
        return(retval);
533
        return(retval);
534
}
534
}
535
 
535
 
536
u8 PointList_Load(u8 * filename, u8* listname, u8 listnamelen, u8 use_preset_speed)
536
u8 PointList_Load(u8 * filename, u8* listname, u8 listnamelen, u8 use_preset_speed)
537
{
537
{
538
        File_t *fp;
538
        File_t *fp;
539
        s8 wpline[LINE_MAX];
539
        s8 wpline[LINE_MAX];
540
        u8 retval = WPL_ERROR;
540
        u8 retval = WPL_ERROR;
541
       
541
       
542
        s8 *name, *value;
542
        s8 *name, *value;
543
        u8 i;
543
        u8 i;
544
 
544
 
545
        u8 IsGeneralSection = 0;
545
        u8 IsGeneralSection = 0;
546
        u8 IsPointSection  = 0;
546
        u8 IsPointSection  = 0;
547
        u8 WPNumber = 0;
547
        u8 WPNumber = 0;
548
 
548
 
549
        // clear point list first
549
        // clear point list first
550
        PointList_Clear();
550
        PointList_Clear();
551
        HeadingOld = -1; // updates the direction if the new direction is the same like last time
551
        HeadingOld = -1; // updates the direction if the new direction is the same like last time
552
        UART1_PutString("\n\r Read ");
552
        UART1_PutString("\n\r Read ");
553
        UART1_PutString(filename);
553
        UART1_PutString(filename);
554
        UART1_PutString("...");
554
        UART1_PutString("...");
555
 
555
 
556
        if(Fat16_IsValid())
556
        if(Fat16_IsValid())
557
        {       // check if wpl file is existing
557
        {       // check if wpl file is existing
558
                fp = fopen_(filename, 'r');             // try to open the file
558
                fp = fopen_(filename, 'r');             // try to open the file
559
                if(fp == NULL)
559
                if(fp == NULL)
560
                {
560
                {
561
                        UART1_PutString("ERROR: Reading waypoint file!\r\n");
561
                        UART1_PutString("ERROR: Reading waypoint file!\r\n");
562
                        return(retval);
562
                        return(retval);
563
                }
563
                }
564
                // read all lines from file
564
                // read all lines from file
565
                while(fgets_(wpline, LINE_MAX, fp) != 0)
565
                while(fgets_(wpline, LINE_MAX, fp) != 0)
566
                {
566
                {
567
                        if ( // ignorelines starting with \r,\n,' ',';','#'
567
                        if ( // ignorelines starting with \r,\n,' ',';','#'
568
                                (wpline[0] != '\n') &&
568
                                (wpline[0] != '\n') &&
569
                                (wpline[0] != '\r') &&
569
                                (wpline[0] != '\r') &&
570
                                (wpline[0] != ' ' ) &&
570
                                (wpline[0] != ' ' ) &&
571
                                (wpline[0] != ';' ) &&
571
                                (wpline[0] != ';' ) &&
572
                                (wpline[0] != '#' )
572
                                (wpline[0] != '#' )
573
                                )
573
                                )
574
                        {
574
                        {
575
                                // check for section line found
575
                                // check for section line found
576
                                if(wpline[0] == '[')
576
                                if(wpline[0] == '[')
577
                                {
577
                                {
578
                                        // next section found
578
                                        // next section found
579
                                        IsGeneralSection = 0;
579
                                        IsGeneralSection = 0;
580
                                        IsPointSection = 0;
580
                                        IsPointSection = 0;
581
 
581
 
582
                                        name  = strtok(&wpline[1], "]");
582
                                        name  = strtok(&wpline[1], "]");
583
                                        if(name != NULL)   // if section name
583
                                        if(name != NULL)   // if section name
584
                                        {
584
                                        {
585
                                                // check section type
585
                                                // check section type
586
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
586
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
587
 
587
 
588
                                                if(strncmp(name, "POINT", 5) == 0)
588
                                                if(strncmp(name, "POINT", 5) == 0)
589
                                                {
589
                                                {
590
                                                        IsPointSection = (u8)atoi(&name[5]);
590
                                                        IsPointSection = (u8)atoi(&name[5]);
591
                                                        PointCount++;
591
                                                        PointCount++;
592
                                                }
592
                                                }
593
                                                else if(strcmp(name, "GENERAL") == 0)
593
                                                else if(strcmp(name, "GENERAL") == 0)
594
                                                {
594
                                                {
595
                                                        IsGeneralSection = 1;
595
                                                        IsGeneralSection = 1;
596
                                                }
596
                                                }
597
                                                else
597
                                                else
598
                                                {
598
                                                {
599
                                                        UART1_PutString("Unknown section: ");
599
                                                        UART1_PutString("Unknown section: ");
600
                                                        UART1_PutString(name);
600
                                                        UART1_PutString(name);
601
                                                        UART1_PutString("\r\n");
601
                                                        UART1_PutString("\r\n");
602
                                                }
602
                                                }
603
                                        }
603
                                        }
604
                                } // EOF section line
604
                                } // EOF section line
605
                                else
605
                                else
606
                                {       // look for key entrys of each sections
606
                                {       // look for key entrys of each sections
607
                                        name  = strtok(wpline, "="); // get name
607
                                        name  = strtok(wpline, "="); // get name
608
                                        value = strtok(NULL, "="); // get value
608
                                        value = strtok(NULL, "="); // get value
609
                                        if ((name != NULL) && (value != NULL))
609
                                        if ((name != NULL) && (value != NULL))
610
                                        {
610
                                        {
611
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
611
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
612
                                                if(IsPointSection &&  (IsPointSection <= WPNumber))
612
                                                if(IsPointSection &&  (IsPointSection <= WPNumber))
613
                                                {
613
                                                {
614
                                                        if(strcmp(name, "LATITUDE") == 0)
614
                                                        if(strcmp(name, "LATITUDE") == 0)
615
                                                        {
615
                                                        {
616
                                                                PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7);
616
                                                                PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7);
617
                                                        }
617
                                                        }
618
                                                        else if(strcmp(name, "LONGITUDE") == 0)
618
                                                        else if(strcmp(name, "LONGITUDE") == 0)
619
                                                        {
619
                                                        {
620
                                                                PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7);
620
                                                                PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7);
621
                                                        }
621
                                                        }
622
                                                        else if(strcmp(name, "RADIUS") == 0)
622
                                                        else if(strcmp(name, "RADIUS") == 0)
623
                                                        {
623
                                                        {
624
                                                                PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value);
624
                                                                PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value);
625
                                                        }
625
                                                        }
626
                                                        else if(strcmp(name, "ALTITUDE") == 0)
626
                                                        else if(strcmp(name, "ALTITUDE") == 0)
627
                                                        {
627
                                                        {
628
                                                                PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0);      // in cm
628
                                                                PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0);      // in cm
629
                                                                PointList[IsPointSection-1].Position.Status = NEWDATA;
629
                                                                PointList[IsPointSection-1].Position.Status = NEWDATA;
630
                                                        }
630
                                                        }
631
                                                        else if(strcmp(name, "CLIMBRATE") == 0)
631
                                                        else if(strcmp(name, "CLIMBRATE") == 0)
632
                                                        {
632
                                                        {
633
                                                                PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value);
633
                                                                PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value);
634
                                                        }
634
                                                        }
635
                                                        else if(strcmp(name, "DELAYTIME") == 0)
635
                                                        else if(strcmp(name, "DELAYTIME") == 0)
636
                                                        {
636
                                                        {
637
                                                                PointList[IsPointSection-1].HoldTime = (u8)atoi(value);
637
                                                                PointList[IsPointSection-1].HoldTime = (u8)atoi(value);
638
                                                        }
638
                                                        }
639
                                                        else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0)
639
                                                        else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0)
640
                                                        {
640
                                                        {
641
                                                                PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value);
641
                                                                PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value);
642
                                                        }
642
                                                        }
643
                                                        else if(strcmp(name, "HEADING") == 0)
643
                                                        else if(strcmp(name, "HEADING") == 0)
644
                                                        {
644
                                                        {
645
                                                                PointList[IsPointSection-1].Heading = (s16)atoi(value);
645
                                                                PointList[IsPointSection-1].Heading = (s16)atoi(value);
646
                                                        }
646
                                                        }
647
                                                        else if(strcmp(name, "SPEED") == 0)
647
                                                        else if(strcmp(name, "SPEED") == 0)
648
                                                        {
648
                                                        {
649
                                                                if(use_preset_speed) PointList[IsPointSection-1].Speed = use_preset_speed;
649
                                                                if(use_preset_speed) PointList[IsPointSection-1].Speed = use_preset_speed;
650
                                                                else PointList[IsPointSection-1].Speed = (u8)atoi(value);
650
                                                                else PointList[IsPointSection-1].Speed = (u8)atoi(value);
651
                                                        }
651
                                                        }
652
                                                        else if(strcmp(name, "CAM-NICK") == 0)
652
                                                        else if(strcmp(name, "CAM-NICK") == 0)
653
                                                        {
653
                                                        {
654
                                                                PointList[IsPointSection-1].CamAngle = (u8)atoi(value);
654
                                                                PointList[IsPointSection-1].CamAngle = (u8)atoi(value);
655
                                                        }
655
                                                        }
656
                                                        else if(strcmp(name, "TYPE") == 0)
656
                                                        else if(strcmp(name, "TYPE") == 0)
657
                                                        {
657
                                                        {
658
                                                                PointList[IsPointSection-1].Type = (u8)atoi(value);
658
                                                                PointList[IsPointSection-1].Type = (u8)atoi(value);
659
                                                                if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--;  // index shift
659
                                                                if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--;  // index shift
660
                                                                else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID;
660
                                                                else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID;
661
                                                       
661
                                                       
662
                                                                switch(PointList[IsPointSection-1].Type)
662
                                                                switch(PointList[IsPointSection-1].Type)
663
                                                                {
663
                                                                {
664
                                                                        case POINT_TYPE_WP:
664
                                                                        case POINT_TYPE_WP:
665
                                                                                // this works only if altitude key is set before point type key in WPL file     !!
665
                                                                                // this works only if altitude key is set before point type key in WPL file     !!
666
                                                                                PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs 
666
                                                                                PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs 
667
                                                                                WPCount++;
667
                                                                                WPCount++;
668
                                                                                break;
668
                                                                                break;
669
                                                                        case POINT_TYPE_FS:
669
                                                                        case POINT_TYPE_FS:
670
                                                                                FsPointCnt++;
670
                                                                                FsPointCnt++;
671
                                                                                break;
671
                                                                                break;
672
                                                                        case POINT_TYPE_POI:
672
                                                                        case POINT_TYPE_POI:
673
                                                                                POICount++;
673
                                                                                POICount++;
674
                                                                                break;
674
                                                                                break;
675
                                                                }
675
                                                                }
676
                                                        }
676
                                                        }
677
                                                        else if(strcmp(name, "PREFIX") == 0)
677
                                                        else if(strcmp(name, "PREFIX") == 0)
678
                                                        {
678
                                                        {
679
                                                                strncpy(PointList[IsPointSection-1].Name, value, 4);
679
                                                                strncpy(PointList[IsPointSection-1].Name, value, 4);
680
                                                                PointList[IsPointSection-1].Name[3] = 0; // Terminate string
680
                                                                PointList[IsPointSection-1].Name[3] = 0; // Terminate string
681
                                                        }
681
                                                        }
682
                                                        else if(strcmp(name, "AUTOTRIGGER") == 0)
682
                                                        else if(strcmp(name, "AUTOTRIGGER") == 0)
683
                                                        {
683
                                                        {
684
                                                                PointList[IsPointSection-1].AutoPhotoDistance = (u8)atoi(value);
684
                                                                PointList[IsPointSection-1].AutoPhotoDistance = (u8)atoi(value);
685
                                                        }
685
                                                        }
686
                                                        else
686
                                                        else
687
                                                        {
687
                                                        {
688
                                                                UART1_PutString("Unknown key: ");
688
                                                                UART1_PutString("Unknown key: ");
689
                                                                UART1_PutString(name);
689
                                                                UART1_PutString(name);
690
                                                                UART1_PutString("\r\n");
690
                                                                UART1_PutString("\r\n");
691
                                                        }      
691
                                                        }      
692
                                                } // EOF point section
692
                                                } // EOF point section
693
                                                else if(IsGeneralSection)
693
                                                else if(IsGeneralSection)
694
                                                {
694
                                                {
695
                                                        if(strcmp(name, "NUMBEROFWAYPOINTS") == 0)
695
                                                        if(strcmp(name, "NUMBEROFWAYPOINTS") == 0)
696
                                                        {      
696
                                                        {      
697
                                                                WPNumber = (u8)atoi(value);
697
                                                                WPNumber = (u8)atoi(value);
698
                                                                if(!WPNumber) // no waypoints in file
698
                                                                if(!WPNumber) // no waypoints in file
699
                                                                {
699
                                                                {
700
                                                                        return(WPL_NO_WAYPOINTS); // we are done here   
700
                                                                        return(WPL_NO_WAYPOINTS); // we are done here   
701
                                                                }
701
                                                                }
702
                                                                else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list
702
                                                                else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list
703
                                                                {
703
                                                                {
704
                                                                        UART1_PutString("To many points!");
704
                                                                        UART1_PutString("To many points!");
705
                                                                        return(WPL_ERROR);
705
                                                                        return(WPL_ERROR);
706
                                                                }
706
                                                                }
707
                                                        }
707
                                                        }
708
                                                        else if (strcmp(name, "FILEVERSION") == 0)
708
                                                        else if (strcmp(name, "FILEVERSION") == 0)
709
                                                        {
709
                                                        {
710
                                                                if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE)
710
                                                                if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE)
711
                                                                {
711
                                                                {
712
                                                                        PointList_Clear();
712
                                                                        PointList_Clear();
713
                                                                        UART1_PutString("Bad file version!\r\n");
713
                                                                        UART1_PutString("Bad file version!\r\n");
714
                                                                        return(WPL_ERROR);     
714
                                                                        return(WPL_ERROR);     
715
                                                                }
715
                                                                }
716
                                                        }
716
                                                        }
717
                                                        else if (strcmp(name, "NAME") == 0)
717
                                                        else if (strcmp(name, "NAME") == 0)
718
                                                        {
718
                                                        {
719
                                                                if(listname)
719
                                                                if(listname)
720
                                                                {
720
                                                                {
721
                                                                        u8 len = strlen(value);
721
                                                                        u8 len = strlen(value);
722
                                                                        if(len)
722
                                                                        if(len)
723
                                                                        {
723
                                                                        {
724
                                                                                if(value[len-1] == '\r')
724
                                                                                if(value[len-1] == '\r')
725
                                                                                {
725
                                                                                {
726
                                                                                        value[len-1] = 0;
726
                                                                                        value[len-1] = 0;
727
//                                                                                      len--;
727
//                                                                                      len--;
728
                                                                                }
728
                                                                                }
729
                                                                        }
729
                                                                        }
730
                                                                        if(len > listnamelen) len = listnamelen;
730
                                                                        if(len > listnamelen) len = listnamelen;
731
                                                                        if(len)
731
                                                                        if(len)
732
                                                                        {
732
                                                                        {
733
                                                                                value[len-1] = 0; // terminate string
733
                                                                                value[len-1] = 0; // terminate string
734
                                                                                if(listname) memcpy(listname, value, len);
734
                                                                                if(listname) memcpy(listname, value, len);
735
                                                                        }
735
                                                                        }
736
                                                                        NewWPL_Name = 1;
736
                                                                        NewWPL_Name = 1;
737
                                                                }
737
                                                                }
738
                                                        }
738
                                                        }
739
                                                        else
739
                                                        else
740
                                                        {
740
                                                        {
741
                                                                UART1_PutString("Unknown key: ");
741
                                                                UART1_PutString("Unknown key: ");
742
                                                                UART1_PutString(name);
742
                                                                UART1_PutString(name);
743
                                                                UART1_PutString("\r\n");
743
                                                                UART1_PutString("\r\n");
744
                                                        }
744
                                                        }
745
                                                } // EOF general section
745
                                                } // EOF general section
746
                                        } // EOF valid key entry
746
                                        } // EOF valid key entry
747
                                } // EOF key entry line
747
                                } // EOF key entry line
748
                        } // valid line
748
                        } // valid line
749
                } // EOF loop over all lines
749
                } // EOF loop over all lines
750
                fclose_(fp);
750
                fclose_(fp);
751
                NaviData.WaypointNumber = WPCount;
751
                NaviData.WaypointNumber = WPCount;
752
                retval = WPL_OK;        
752
                retval = WPL_OK;        
753
                UART1_PutString("ok\r\n");                               
753
                UART1_PutString("ok\r\n");                               
754
        } // EOF if(Fat16_IsValid())
754
        } // EOF if(Fat16_IsValid())
755
        else
755
        else
756
        {
756
        {
757
                UART1_PutString("no file system found!\r\n");
757
                UART1_PutString("no file system found!\r\n");
758
                retval = WPL_NO_SDCARD_FOUND;
758
                retval = WPL_NO_SDCARD_FOUND;
759
        }      
759
        }      
760
        return(retval);
760
        return(retval);
761
}
761
}
762
 
762
 
763
// load actual point list from SD card
763
// load actual point list from SD card
764
u8 PointList_ReadFromFile(WPL_Store_t * pWPL_Store)
764
u8 PointList_ReadFromFile(WPL_Store_t * pWPL_Store)
765
{
765
{
766
        u8 filename[30];       
766
        u8 filename[30];       
767
 
767
 
768
        pWPL_Store->Name[0] = 0; // clear current list name
768
        pWPL_Store->Name[0] = 0; // clear current list name
769
 
769
 
770
        // user absolute path, i.e. leading /
770
        // user absolute path, i.e. leading /
771
        if(pWPL_Store->Index == 0) // index 0 looks for a default WPL file in the root
771
        if(pWPL_Store->Index == 0) // index 0 looks for a default WPL file in the root
772
        {
772
        {
773
                sprintf(filename, "/default.wpl");     
773
                sprintf(filename, "/default.wpl");     
774
        }
774
        }
775
        else
775
        else
776
        {
776
        {
777
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
777
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
778
        }
778
        }
779
        return PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),0);
779
        return PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),0);
780
}
780
}
781
 
781
 
782
// save actual point list to SD card
782
// save actual point list to SD card
783
u8 PointList_WriteToFile(WPL_Store_t * pWPL_Store)
783
u8 PointList_WriteToFile(WPL_Store_t * pWPL_Store)
784
{
784
{
785
        u8 filename[30];
785
        u8 filename[30];
786
       
786
       
787
       
787
       
788
        if(PointCount == 0) return(WPL_NO_WAYPOINTS);
788
        if(PointCount == 0) return(WPL_NO_WAYPOINTS);
789
        // user absolute path, i.e. leading /   
789
        // user absolute path, i.e. leading /   
790
        if(pWPL_Store->Index == 0)
790
        if(pWPL_Store->Index == 0)
791
        {
791
        {
792
                sprintf(filename, "/default.wpl");
792
                sprintf(filename, "/default.wpl");
793
        }
793
        }
794
        else
794
        else
795
        {
795
        {
796
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
796
                sprintf(filename, "/WPL/list_%03d.wpl", pWPL_Store->Index);
797
        }
797
        }
798
        return PointList_Save(filename, pWPL_Store->Name, pWPL_Store->OverwriteFile);
798
        return PointList_Save(filename, pWPL_Store->Name, pWPL_Store->OverwriteFile);
799
}
799
}
800
 
800
 
801
 
801
 
802
// save actual gps positiin and heading to file
802
// save actual gps positiin and heading to file
803
u8 PointList_SaveSinglePoint(WPL_Store_t * pWPL_Store)
803
u8 PointList_SaveSinglePoint(WPL_Store_t * pWPL_Store)
804
{
804
{
805
        u8 retval = WPL_ERROR;
805
        u8 retval = WPL_ERROR;
806
        u8 filename[30];
806
        u8 filename[30];
807
        Point_t WP;
807
        Point_t WP;
808
 
808
 
809
        UART1_PutString("\n\r write single point\n\r");
809
        UART1_PutString("\n\r write single point\n\r");
810
        if(GPSData.Position.Status == INVALID)
810
        if(GPSData.Position.Status == INVALID)
811
         {
811
         {
812
                UART1_PutString("ERROR: No GPS - Fix\n\r");
812
                UART1_PutString("ERROR: No GPS - Fix\n\r");
813
                return(retval);
813
                return(retval);
814
         }
814
         }
815
 
815
 
816
        // clear current point list
816
        // clear current point list
817
        PointList_Clear();
817
        PointList_Clear();
818
        // prepare WP at current position
818
        // prepare WP at current position
819
 
819
 
820
        if(NCFlags & NC_FLAG_FREE || NaviData.TargetPositionDeviation.Distance > 7*10)
820
        if(NCFlags & NC_FLAG_FREE || NaviData.TargetPositionDeviation.Distance_dm > 7*10)
821
        {  // take actual position
821
        {  // take actual position
822
                GPSPos_Copy(&GPSData.Position, &(WP.Position));
822
                GPSPos_Copy(&GPSData.Position, &(WP.Position));
823
        }
823
        }
824
        else
824
        else
825
        {  // take last target position
825
        {  // take last target position
826
                GPSPos_Copy(&NaviData.TargetPosition, &(WP.Position));
826
                GPSPos_Copy(&NaviData.TargetPosition, &(WP.Position));
827
        }
827
        }
828
 
828
 
829
        GPSPos_Copy(&GPSData.Position, &(WP.Position));
829
        GPSPos_Copy(&GPSData.Position, &(WP.Position));
830
        // set heading
830
        // set heading
831
        WP.Heading = (CompassSetpointCorrected/10 + Parameter.CamOrientation * 15) % 360;
831
        WP.Heading = (CompassSetpointCorrected/10 + Parameter.CamOrientation * 15) % 360;
832
        if(WP.Heading == 0) WP.Heading = 360;
832
        if(WP.Heading == 0) WP.Heading = 360;
833
        WP.ToleranceRadius = 120; // 12m 
833
        WP.ToleranceRadius = 120; // 12m 
834
        WP.HoldTime  = 2;
834
        WP.HoldTime  = 2;
835
        WP.Index  = 1;
835
        WP.Index  = 1;
836
        WP.Type = POINT_TYPE_WP;
836
        WP.Type = POINT_TYPE_WP;
837
        WP.WP_EventChannelValue = 100;
837
        WP.WP_EventChannelValue = 100;
838
        if(FC.StatusFlags & FC_STATUS_FLY && ((FromFC_VarioCharacter != ' ') || (SimulationFlags & SIMULATION_ACTIVE))) // only in flight and if the Altitude control is enabled
838
        if(FC.StatusFlags & FC_STATUS_FLY && ((FromFC_VarioCharacter != ' ') || (SimulationFlags & SIMULATION_ACTIVE))) // only in flight and if the Altitude control is enabled
839
         {
839
         {
840
          WP.AltitudeRate = 255;  // Auto
840
          WP.AltitudeRate = 255;  // Auto
841
          WP.Position.Altitude = NaviData.SetpointAltitude / 2;
841
          WP.Position.Altitude = NaviData.SetpointAltitude / 2;
842
         }
842
         }
843
        else
843
        else
844
        {
844
        {
845
         WP.AltitudeRate = 0;
845
         WP.AltitudeRate = 0;
846
     WP.Position.Altitude = 0;
846
     WP.Position.Altitude = 0;
847
        }
847
        }
848
        WP.Speed = 50; // beim Laden wird der Wert nochmal neu gesetzt
848
        WP.Speed = 50; // beim Laden wird der Wert nochmal neu gesetzt
849
        WP.CamAngle = 0;
849
        WP.CamAngle = 0;
850
        WP.Name[0] = 'S';
850
        WP.Name[0] = 'S';
851
        WP.Name[1] = 'P';
851
        WP.Name[1] = 'P';
852
        WP.Name[2] = 'T';
852
        WP.Name[2] = 'T';
853
        WP.Name[3] = 0;
853
        WP.Name[3] = 0;
854
        // add this point to wp list
854
        // add this point to wp list
855
        PointList_SetAt(&WP);
855
        PointList_SetAt(&WP);
856
 
856
 
857
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
857
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
858
        UART1_PutString(filename);
858
        UART1_PutString(filename);
859
        sprintf(pWPL_Store->Name, "POINT%03d ", pWPL_Store->Index);
859
        sprintf(pWPL_Store->Name, "POINT%03d ", pWPL_Store->Index);
860
        retval = PointList_Save(filename, pWPL_Store->Name, 1);
860
        retval = PointList_Save(filename, pWPL_Store->Name, 1);
861
 
861
 
862
        // clear current point list
862
        // clear current point list
863
        if((NC_GPS_ModeCharacter != 'w') && (NC_GPS_ModeCharacter != 'W')) PointList_Clear();
863
        if((NC_GPS_ModeCharacter != 'w') && (NC_GPS_ModeCharacter != 'W')) PointList_Clear();
864
        else // es ist gearde ein Wegpunktflug aktiv -> updaten
864
        else // es ist gearde ein Wegpunktflug aktiv -> updaten
865
        {
865
        {
866
                if(FC.StatusFlags & FC_STATUS_FLY) PointList_WPActive(TRUE);
866
                if(FC.StatusFlags & FC_STATUS_FLY) PointList_WPActive(TRUE);
867
                GPS_pWaypoint = PointList_WPBegin(); // updates POI index
867
                GPS_pWaypoint = PointList_WPBegin(); // updates POI index
868
        }
868
        }
869
 
869
 
870
        return(retval);
870
        return(retval);
871
}
871
}
872
// load target gps posititon and heading from file
872
// load target gps posititon and heading from file
873
u8 PointList_LoadSinglePoint(WPL_Store_t * pWPL_Store)
873
u8 PointList_LoadSinglePoint(WPL_Store_t * pWPL_Store)
874
{
874
{
875
        u8 filename[30], result = 0;
875
        u8 filename[30], result = 0;
876
       
876
       
877
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
877
        sprintf(filename, "/POINT/POINT%03d.wpl", pWPL_Store->Index);
878
        pWPL_Store->Name[0] = 0; // clear current list name
878
        pWPL_Store->Name[0] = 0; // clear current list name
879
        result = PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),Parameter.SingleWpSpeed);
879
        result = PointList_Load(filename, pWPL_Store->Name, sizeof(pWPL_Store->Name),Parameter.SingleWpSpeed);
880
        if(result) UART1_Request_ReadPoint = 1; // Sends Point 1 to the PC
880
        if(result) UART1_Request_ReadPoint = 1; // Sends Point 1 to the PC
881
        return(result);
881
        return(result);
882
}
882
}
883
 
883
 
884
 
884
 
885
 
885
 
886
void ClearWLP_Name(void)
886
void ClearWLP_Name(void)
887
{
887
{
888
        u8 i;
888
        u8 i;
889
        for(i=0; i<sizeof(WPL_Store.Name);i++) WPL_Store.Name[i] = 0;
889
        for(i=0; i<sizeof(WPL_Store.Name);i++) WPL_Store.Name[i] = 0;
890
        NewWPL_Name = 1;
890
        NewWPL_Name = 1;
891
}
891
}
892
 
892
 
893
// move actual point list to ref pos., the point in the list marked by index gets the RefPos afterwards
893
// move actual point list to ref pos., the point in the list marked by index gets the RefPos afterwards
894
u8 PointList_Move(u8 RefIndex, GPS_Pos_t* pRefPos, u16 RotationAngle)
894
u8 PointList_Move(u8 RefIndex, GPS_Pos_t* pRefPos, u16 RotationAngle)
895
{
895
{
896
        u8 retval = 0;
896
        u8 retval = 0;
897
        s32 altitude;
897
        s32 altitude;
898
        GPS_Pos_t OldRefPos;
898
        GPS_Pos_t OldRefPos;
899
        GPS_Pos_Deviation_t RefDeviation;
899
        GPS_Pos_Deviation_t RefDeviation;
900
         
900
         
901
        // check inputs for plausibility;
901
        // check inputs for plausibility;
902
        if((RefIndex == 0) || (RefIndex > PointCount)) return(retval); 
902
        if((RefIndex == 0) || (RefIndex > PointCount)) return(retval); 
903
        if(pRefPos == NULL) return(retval);
903
        if(pRefPos == NULL) return(retval);
904
        if(pRefPos->Status == INVALID) return(retval);
904
        if(pRefPos->Status == INVALID) return(retval);
905
 
905
 
906
        if(GPSPos_Copy(&(PointList[RefIndex-1].Position), &OldRefPos)) // backup old reference position
906
        if(GPSPos_Copy(&(PointList[RefIndex-1].Position), &OldRefPos)) // backup old reference position
907
        {
907
        {
908
                u8 i;
908
                u8 i;
909
                // iterate the position list
909
                // iterate the position list
910
                for(i = 0; i < PointCount; i++)
910
                for(i = 0; i < PointCount; i++)
911
                {
911
                {
912
                        retval = 0;
912
                        retval = 0;
913
                        // backup altitude of this point
913
                        // backup altitude of this point
914
                        altitude = PointList[i].Position.Altitude;
914
                        altitude = PointList[i].Position.Altitude;
915
                        // calculate deviation form old ref, i.e the north and east shift of each point in the list from the reference position
915
                        // calculate deviation form old ref, i.e the north and east shift of each point in the list from the reference position
916
                        if(!GPSPos_Deviation(&(PointList[i].Position), &OldRefPos, &RefDeviation)) break;
916
                        if(!GPSPos_Deviation(&(PointList[i].Position), &OldRefPos, &RefDeviation)) break;
917
                        // copy of the new reference position into this list place
917
                        // copy of the new reference position into this list place
918
                        if(!GPSPos_Copy(pRefPos, &(PointList[i].Position))) break;
918
                        if(!GPSPos_Copy(pRefPos, &(PointList[i].Position))) break;
919
                        // restore former altitude 
919
                        // restore former altitude 
920
                        PointList[i].Position.Altitude = altitude;
920
                        PointList[i].Position.Altitude = altitude;
921
                        // move new reference according to the deviation of the old reference
921
                        // move new reference according to the deviation of the old reference
922
                        if(RotationAngle > 0)
922
                        if(RotationAngle > 0)
923
                        {
923
                        {
924
                                retval = GPSPos_ShiftGeodetic(&(PointList[i].Position), (RefDeviation.Bearing + 180 + RotationAngle)%360, RefDeviation.Distance );
924
                                retval = GPSPos_ShiftGeodetic(&(PointList[i].Position), (RefDeviation.Bearing + 180 + RotationAngle)%360, RefDeviation.Distance_cm );
925
                                // Now rotate the heading positions if they are fixed angles
925
                                // Now rotate the heading positions if they are fixed angles
926
                                if(PointList[i].Heading >= 0 && PointList[i].Heading <= 360) PointList[i].Heading = (PointList[i].Heading + RotationAngle) % 360;
926
                                if(PointList[i].Heading >= 0 && PointList[i].Heading <= 360) PointList[i].Heading = (PointList[i].Heading + RotationAngle) % 360;
927
                        }
927
                        }
928
                        else // no rotation
928
                        else // no rotation
929
                        {
929
                        {
930
                                // move new reference according to the deviation of the old reference
930
                                // move new reference according to the deviation of the old reference
931
                                retval = GPSPos_ShiftCartesian(&(PointList[i].Position), RefDeviation.North, RefDeviation.East);
931
                                retval = GPSPos_ShiftCartesian(&(PointList[i].Position), RefDeviation.North, RefDeviation.East);
932
                        }
932
                        }
933
                        if(!retval) break;             
933
                        if(!retval) break;             
934
                }
934
                }
935
        } // else ref pos old not copied!
935
        } // else ref pos old not copied!
936
        if(!retval) PointList_Clear();
936
        if(!retval) PointList_Clear();
937
        return(retval);
937
        return(retval);
938
}
938
}
939
 
939
 
940
 
940
 
941
 
941
 
942
 
942