Subversion Repositories Projects

Rev

Rev 2205 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2205 Rev 2209
Line 2... Line 2...
2
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Line 3... Line 3...
3
 
3
 
4
//############################################################################
4
//############################################################################
5
//# HISTORY  gps.c
5
//# HISTORY  gps.c
-
 
6
//#
-
 
7
//#
-
 
8
//#
-
 
9
//#
-
 
10
//#
-
 
11
//#
-
 
12
//#
-
 
13
//#
-
 
14
//# 22.09.2015 Starter
-
 
15
//# - followme_add_offset(...) und followme_calculate_offset getestet mit PKT
-
 
16
//# - add my_abs(...)
6
//#
17
//#
7
//# 20.09.2015 Startet
18
//# 20.09.2015 Starter
8
//# - add Routine um einen Offset in Meter zu den aktuellen Koordinaten dazurechnen
19
//# - add Routine um einen Offset in Meter zu den aktuellen Koordinaten dazurechnen
9
//#    followme_calculate_offset(...)
20
//#    followme_calculate_offset(...)
10
//#
21
//#
11
//# 03.08.2015 cebra
22
//# 03.08.2015 cebra
Line 34... Line 45...
34
#include "../mk-data-structs.h"
45
#include "../mk-data-structs.h"
35
#include "../gps/mymath.h"
46
#include "../gps/mymath.h"
36
#include "gps.h"
47
#include "gps.h"
Line 37... Line -...
37
 
-
 
38
 
-
 
39
/*
-
 
40
// definiert in: mk_data-stucts.h
-
 
41
typedef struct
-
 
42
{
-
 
43
    u16 Distance;       // distance to target in cm
-
 
44
    s16 Bearing;        // course to target in deg
-
 
45
} __attribute__((packed)) GPS_PosDev_t;
-
 
46
*/
-
 
47
 
-
 
48
/*
-
 
49
// definiert in: mk_data-stucts.h
-
 
50
typedef struct
-
 
51
{
-
 
52
    s32 Longitude;      // in 1E-7 deg
-
 
53
    s32 Latitude;       // in 1E-7 deg
-
 
54
    s32 Altitude;       // in mm
-
 
55
    u8 Status;          // validity of data
-
 
56
} __attribute__((packed)) GPS_Pos_t;
-
 
57
*/
-
 
58
 
-
 
59
 
-
 
60
//--------------------------------------------------------------
48
 
61
 
49
 
62
#define NMEA_PI                     (3.141592653589793)             /**< PI value */
50
#define NMEA_PI                     (3.141592653589793)             /**< PI value */
63
#define NMEA_PI180                  (NMEA_PI / 180)                 /**< PI division by 180 */
51
#define NMEA_PI180                  (NMEA_PI / 180)                 /**< PI division by 180 */
64
#define NMEA_EARTHRADIUS_KM         (6378)                          /**< Earth's mean radius in km */
52
#define NMEA_EARTHRADIUS_KM         (6378)                          /**< Earth's mean radius in km */
Line 107... Line 95...
107
    int RetVal = 1;
95
    int RetVal = 1;
Line 108... Line 96...
108
 
96
 
109
    distance /= NMEA_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */
97
    distance /= NMEA_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */
Line 110... Line 98...
110
    azimuth = nmea_degree2radian(azimuth);
98
    azimuth = nmea_degree2radian(azimuth);
Line 111... Line 99...
111
 
99
 
Line 112... Line 100...
112
    end_pos->lat = asin( sin(p1.lat) * cos(distance) + cos(p1.lat) * sin(distance) * cos(azimuth));
100
    end_pos->latitude = asin( sin(p1.latitude) * cos(distance) + cos(p1.latitude) * sin(distance) * cos(azimuth));
113
 
101
 
114
    end_pos->lon = p1.lon + atan2( sin(azimuth) * sin(distance) * cos(p1.lat), cos(distance) - sin(p1.lat) * sin(end_pos->lat));
102
    end_pos->longitude = p1.longitude + atan2( sin(azimuth) * sin(distance) * cos(p1.latitude), cos(distance) - sin(p1.latitude) * sin(end_pos->latitude));
115
 
103
 
116
    if(NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon))
104
    if(NMEA_POSIX(isnan)(end_pos->latitude) || NMEA_POSIX(isnan)(end_pos->longitude))
Line 117... Line 105...
117
    {
105
    {
118
        end_pos->lat = 0; end_pos->lon = 0;
106
        end_pos->latitude = 0; end_pos->longitude = 0;
Line 139... Line 127...
139
    )
127
    )
140
{
128
{
141
        nmeaPOS pktPos = *pPktPos;
129
        nmeaPOS pktPos = *pPktPos;
142
        positionOffset followMeOffset = * pFollowMeOffset;
130
        positionOffset followMeOffset = * pFollowMeOffset;
Line 143... Line 131...
143
       
131
       
144
    target_pos->lat = pktPos.lat + ( ( followMeOffset.offset_lat * ( LAT_DIV  / FOLLOWME_M2DEG ) ) ) / 1000;
132
    target_pos->latitude = pktPos.latitude + ( ( followMeOffset.latitude * ( LAT_DIV  / FOLLOWME_M2DEG ) ) ) / 1000;
145
    target_pos->lon = pktPos.lon + ( ( followMeOffset.offset_long * ( LONG_DIV  / FOLLOWME_M2DEG ) * (8192/1000) ) / my_abs( c_cos_8192( (pktPos.lat / LONG_DIV ) ) ) );
133
    target_pos->longitude = pktPos.longitude + ( ( followMeOffset.longitude * ( LONG_DIV  / FOLLOWME_M2DEG ) * (8192/1000) ) / my_abs( c_cos_8192( (pktPos.latitude / LONG_DIV ) ) ) );
146
        return 1;
134
        return 1;
Line -... Line 135...
-
 
135
}
-
 
136
 
-
 
137
 
147
}
138
// schlanke abs-Methode
148
 
139
// TODO: move to mymath.h
149
int16_t my_abs(int16_t input)
140
int16_t my_abs(int16_t input)
150
{
141
{
151
        if(input < 0)
142
        if(input < 0)
Line 164... Line 155...
164
                positionOffset *followMeOffset
155
                positionOffset *followMeOffset
165
                )
156
                )
166
{
157
{
167
        angle %= 360;                   // map angle to 0° - 360°
158
        angle %= 360;                   // map angle to 0° - 360°
Line 168... Line 159...
168
 
159
 
169
        followMeOffset->offset_lat = ( radius * c_cos_8192( angle ) ) / 8192;
160
        followMeOffset->latitude = ( radius * c_cos_8192( angle ) ) / 8192;
Line 170... Line 161...
170
        followMeOffset->offset_long = ( radius * c_sin_8192( angle ) ) / 8192;
161
        followMeOffset->longitude = ( radius * c_sin_8192( angle ) ) / 8192;
171
 
162
 
Line 199... Line 190...
199
 
190
 
200
    return PosDev;
191
    return PosDev;
Line 201... Line -...
201
}
-
 
202
 
-
 
203
 
-
 
204
///**
-
 
205
// * \brief Calculate distance between two points
-
 
206
// * \return Distance in meters
-
 
207
// */
-
 
208
//int32_t nmea_distance(
-
 
209
//        const nmeaPOS *from_pos,    /**< From position in radians */
-
 
210
//        const nmeaPOS *to_pos       /**< To position in radians */
-
 
211
//        )
-
 
212
//{
-
 
213
//  int32_t dist = ((int32_t)NMEA_EARTHRADIUS_M) * acos(
-
 
214
//        sin(to_pos->lat) * sin(from_pos->lat) +
-
 
215
//        cos(to_pos->lat) * cos(from_pos->lat) * cos(to_pos->lon - from_pos->lon)
-
 
216
//        );
-
 
217
//    return dist;
-
 
218
//}
-
 
219
 
-
 
220
 
-
 
221
 
-
 
222
//// Berechnung von Distanz und Winkel aus GPS-Daten home(MK eingeschaltet)
-
 
223
//// zur aktuellen Position(nach Motorstart)
-
 
224
//geo_t calc_geo(HomePos_t *home, GPS_Pos_t *pos)
-
 
225
//{ double lat1, lon1, lat2, lon2, d1, dlat;
-
 
226
//        geo_t geo;
-
 
227
//
-
 
228
//        lon1 = MK_pos.Home_Lon;
-
 
229
//        lat1 = MK_pos.Home_Lat;
-
 
230
//        lon2 = (double)pos->Longitude   / 10000000.0;
-
 
231
//        lat2 = (double)pos->Latitude    / 10000000.0;
-
 
232
//
-
 
233
//        // Formel verwendet von http://www.kompf.de/gps/distcalc.html
-
 
234
//        // 111.3 km = Abstand zweier Breitenkreise und/oder zweier Längenkreise am Äquator
-
 
235
//        // es wird jedoch in Meter weiter gerechnet
-
 
236
//        d1       = 111300 * (double)cos((double)(lat1 + lat2) / 2 * DEG_TO_RAD) * (lon1 - lon2);
-
 
237
//        dlat = 111300 * (double)(lat1 - lat2);
-
 
238
//        // returns a value in metres http://www.kompf.de/gps/distcalc.html
-
 
239
//        geo.bearing = fmod((RAD_TO_DEG * (double)atan2(d1, dlat)) + 180, 360); // +180 besserer Vergleich mit MkCockpit
-
 
240
//        if (geo.bearing > 360) geo.bearing -= 360; // bekam schon Werte über 400
-
 
241
//        geo.distance = sqrt(d1 * d1 + dlat * dlat);
-
 
242
//        return(geo);
-
 
243
//}
-
 
244
 
-
 
245
// Berechnung von Distanz und Winkel aus GPS-Daten home(MK eingeschaltet)
-
 
246
// zur aktuellen Position(nach Motorstart)
-
 
247
//--------------------------------------------------------------
-
 
248
//--------------------------------------------------------------
-
 
249
 
-
 
250
/*
-
 
251
geo_t calc_geo( HomePos_t *home, GPS_Pos_t *pos )
-
 
252
{
-
 
253
    int32_t lat1, lon1, lat2, lon2;
-
 
254
        int32_t d1, dlat;
-
 
255
        geo_t geo;
-
 
256
 
-
 
257
        lon1 = home->Home_Lon;
-
 
258
        lat1 = home->Home_Lat;
-
 
259
        lon2 = pos->Longitude;
-
 
260
        lat2 = pos->Latitude;
-
 
261
 
-
 
262
        if( !CheckGPS )
-
 
263
        {
-
 
264
            writex_gpspos(  0, 3, home->Home_Lat , MNORMAL,  0,0);    // Anzeige: Breitengrad (Latitude)
-
 
265
            writex_gpspos( 11, 3, home->Home_Lon , MNORMAL,  0,0);    // Anzeige: Laengengrad (Longitude)
-
 
266
            writex_gpspos(  0, 4, pos->Latitude  , MNORMAL,  0,0);    // Anzeige: Breitengrad (Latitude)
-
 
267
            writex_gpspos( 11, 4, pos->Longitude , MNORMAL,  0,0);    // Anzeige: Laengengrad (Longitude)
-
 
268
 
-
 
269
            //lcd_puts_at (0, 3, my_itoa(home->Home_Lat, 10, 7, 7), 0);     // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
270
            //lcd_puts_at (11, 3, my_itoa(home->Home_Lon, 10, 7, 7), 0);    // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
271
            //lcd_puts_at (0, 4, my_itoa(pos->Latitude, 10, 7, 7), 0);      // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
272
            //lcd_puts_at (11, 4, my_itoa(pos->Longitude, 10, 7, 7), 0);    // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
273
        }
-
 
274
 
-
 
275
        // Formel verwendet von http://www.kompf.de/gps/distcalc.html
-
 
276
        // 111.3 km = Abstand zweier Breitenkreise und/oder zweier Langenkreise am Äquator
-
 
277
        // es wird jedoch in dm Meter weiter gerechnet
-
 
278
        // (tlon1 - tlon2)/10) sonst uint32_t-Überlauf bei cos(0) gleich 1
-
 
279
        d1       = (1359 * (int32_t)(c_cos_8192((lat1 + lat2) / 20000000)) * ((lon1 - lon2)/10))/ 10000000;
-
 
280
        dlat = 1113 * (lat1 - lat2) / 10000;
-
 
281
        geo.bearing = (my_atan2(d1, dlat) + 540) % 360; // 360 +180 besserer Vergleich mit MkCockpit
-
 
282
        geo.distance = sqrt32(d1 * d1 + dlat * dlat);
-
 
283
        if( !CheckGPS )
-
 
284
        {
-
 
285
            lcd_printp_at (0, 5, PSTR("Bear:"), 0);
-
 
286
 
-
 
287
            lcdx_printf_at_P( 5, 5, MNORMAL, 0,0, PSTR("%3d"), geo.bearing );
-
 
288
            //lcd_puts_at (5, 5, my_itoa((uint32_t)geo.bearing, 3, 0, 0), 0);       // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
289
 
-
 
290
            lcd_printp_at (8, 5, PSTR("\x1e"), 0);
-
 
291
            lcd_printp_at (9, 5, PSTR("Dist:"), 0);
-
 
292
 
-
 
293
            lcdx_printf_at_P( 15, 5, MNORMAL, 0,0, PSTR("%3d"), geo.distance );
-
 
294
            //lcd_puts_at (15, 5, my_itoa((uint32_t)geo.distance, 3, 1, 1), 0);     // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
295
 
-
 
296
            lcd_printp_at (20, 5, PSTR("m"), 0);
-
 
297
        }
-
 
298
 
-
 
299
 
-