Subversion Repositories Projects

Rev

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

Rev 2200 Rev 2212
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 107... Line 118...
107
    int RetVal = 1;
118
    int RetVal = 1;
Line 108... Line 119...
108
 
119
 
109
    distance /= NMEA_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */
120
    distance /= NMEA_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */
Line 110... Line 121...
110
    azimuth = nmea_degree2radian(azimuth);
121
    azimuth = nmea_degree2radian(azimuth);
Line 111... Line 122...
111
 
122
 
Line 112... Line 123...
112
    end_pos->lat = asin( sin(p1.lat) * cos(distance) + cos(p1.lat) * sin(distance) * cos(azimuth));
123
    end_pos->latitude = asin( sin(p1.latitude) * cos(distance) + cos(p1.latitude) * sin(distance) * cos(azimuth));
113
 
124
 
114
    end_pos->lon = p1.lon + atan2( sin(azimuth) * sin(distance) * cos(p1.lat), cos(distance) - sin(p1.lat) * sin(end_pos->lat));
125
    end_pos->longitude = p1.longitude + atan2( sin(azimuth) * sin(distance) * cos(p1.latitude), cos(distance) - sin(p1.latitude) * sin(end_pos->latitude));
115
 
126
 
116
    if(NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon))
127
    if(NMEA_POSIX(isnan)(end_pos->latitude) || NMEA_POSIX(isnan)(end_pos->longitude))
Line 117... Line 128...
117
    {
128
    {
118
        end_pos->lat = 0; end_pos->lon = 0;
129
        end_pos->latitude = 0; end_pos->longitude = 0;
Line -... Line 130...
-
 
130
        RetVal = 0;
-
 
131
    }
-
 
132
 
119
        RetVal = 0;
133
    return RetVal;
120
    }
-
 
-
 
134
}
121
 
135
 
122
    return RetVal;
136
 
-
 
137
 
Line 123... Line 138...
123
}
138
 
124
 
139
 
125
 
140
// Fügt den Startpostition einen Offset hinzu und gibt es als Zielposition zurück
126
// Berechnet die Position der Kopters für FollowMeStep2
141
//
127
// Momentan wird die gleich Position ausgegeben
-
 
128
// Benutzt die c_cos_8192 der FC
142
// Benutzt die c_cos_8192 der FC
129
// TODO: move to followme.c
143
// TODO: move to followme.c
130
 
144
// TODO: *8192 optimieren
-
 
145
 
Line 131... Line 146...
131
uint8_t followme_calculate_offset(
146
uint8_t followme_add_offset(
132
    const nmeaPOS *pPktPos,     /**< Start position in radians */
147
    const nmeaPOS *pPktPos,                     /**< Start position in radians */
-
 
148
    nmeaPOS *target_pos,                        /**< Result position in radians */
-
 
149
        positionOffset *pFollowMeOffset         /**< Position Offset in Millimeters */
-
 
150
    )
-
 
151
{
-
 
152
        nmeaPOS pktPos = *pPktPos;
-
 
153
        positionOffset followMeOffset = * pFollowMeOffset;
-
 
154
       
-
 
155
    target_pos->latitude = pktPos.latitude + ( ( followMeOffset.latitude * ( LAT_DIV / FOLLOWME_M2DEG ) ) ) / 1000;
-
 
156
    target_pos->longitude = pktPos.longitude + ( ( followMeOffset.longitude * ( LONG_DIV / FOLLOWME_M2DEG ) * (8192/1000) ) / my_abs( c_cos_8192( (pktPos.latitude / LONG_DIV ) ) ) );
-
 
157
        return 1;
-
 
158
}
-
 
159
 
-
 
160
 
-
 
161
// schlanke abs-Methode
-
 
162
// TODO: move to mymath.h
-
 
163
int16_t my_abs(int16_t input)
-
 
164
{
-
 
165
        if(input < 0)
-
 
166
                return -input;
-
 
167
        else
-
 
168
                return input;
-
 
169
}
-
 
170
 
-
 
171
// Rechnet einen Offset aus Radius und Winkel nach Lat/Long
-
 
172
// Benutzt die c_cos_8192 und c_sin_8192 der FC
-
 
173
// TODO: move to followme.c
-
 
174
 
-
 
175
uint8_t followme_calculate_offset(
Line 133... Line 176...
133
    nmeaPOS *target_pos,        /**< Result position in radians */
176
                int32_t radius,                         // in mm
134
    int d_lat,                  /**< Distance lat(m) */
177
                int16_t angle,                          // in Grad °
Line 170... Line 213...
170
 
213
 
171
    return PosDev;
214
    return PosDev;
Line 172... Line -...
172
}
-
 
173
 
-
 
174
 
-
 
175
///**
-
 
176
// * \brief Calculate distance between two points
-
 
177
// * \return Distance in meters
-
 
178
// */
-
 
179
//int32_t nmea_distance(
-
 
180
//        const nmeaPOS *from_pos,    /**< From position in radians */
-
 
181
//        const nmeaPOS *to_pos       /**< To position in radians */
-
 
182
//        )
-
 
183
//{
-
 
184
//  int32_t dist = ((int32_t)NMEA_EARTHRADIUS_M) * acos(
-
 
185
//        sin(to_pos->lat) * sin(from_pos->lat) +
-
 
186
//        cos(to_pos->lat) * cos(from_pos->lat) * cos(to_pos->lon - from_pos->lon)
-
 
187
//        );
-
 
188
//    return dist;
-
 
189
//}
-
 
190
 
-
 
191
 
-
 
192
 
-
 
193
//// Berechnung von Distanz und Winkel aus GPS-Daten home(MK eingeschaltet)
-
 
194
//// zur aktuellen Position(nach Motorstart)
-
 
195
//geo_t calc_geo(HomePos_t *home, GPS_Pos_t *pos)
-
 
196
//{ double lat1, lon1, lat2, lon2, d1, dlat;
-
 
197
//        geo_t geo;
-
 
198
//
-
 
199
//        lon1 = MK_pos.Home_Lon;
-
 
200
//        lat1 = MK_pos.Home_Lat;
-
 
201
//        lon2 = (double)pos->Longitude   / 10000000.0;
-
 
202
//        lat2 = (double)pos->Latitude    / 10000000.0;
-
 
203
//
-
 
204
//        // Formel verwendet von http://www.kompf.de/gps/distcalc.html
-
 
205
//        // 111.3 km = Abstand zweier Breitenkreise und/oder zweier Längenkreise am Äquator
-
 
206
//        // es wird jedoch in Meter weiter gerechnet
-
 
207
//        d1       = 111300 * (double)cos((double)(lat1 + lat2) / 2 * DEG_TO_RAD) * (lon1 - lon2);
-
 
208
//        dlat = 111300 * (double)(lat1 - lat2);
-
 
209
//        // returns a value in metres http://www.kompf.de/gps/distcalc.html
-
 
210
//        geo.bearing = fmod((RAD_TO_DEG * (double)atan2(d1, dlat)) + 180, 360); // +180 besserer Vergleich mit MkCockpit
-
 
211
//        if (geo.bearing > 360) geo.bearing -= 360; // bekam schon Werte über 400
-
 
212
//        geo.distance = sqrt(d1 * d1 + dlat * dlat);
-
 
213
//        return(geo);
-
 
214
//}
-
 
215
 
-
 
216
// Berechnung von Distanz und Winkel aus GPS-Daten home(MK eingeschaltet)
-
 
217
// zur aktuellen Position(nach Motorstart)
-
 
218
//--------------------------------------------------------------
-
 
219
//--------------------------------------------------------------
-
 
220
 
-
 
221
/*
-
 
222
geo_t calc_geo( HomePos_t *home, GPS_Pos_t *pos )
-
 
223
{
-
 
224
    int32_t lat1, lon1, lat2, lon2;
-
 
225
        int32_t d1, dlat;
-
 
226
        geo_t geo;
-
 
227
 
-
 
228
        lon1 = home->Home_Lon;
-
 
229
        lat1 = home->Home_Lat;
-
 
230
        lon2 = pos->Longitude;
-
 
231
        lat2 = pos->Latitude;
-
 
232
 
-
 
233
        if( !CheckGPS )
-
 
234
        {
-
 
235
            writex_gpspos(  0, 3, home->Home_Lat , MNORMAL,  0,0);    // Anzeige: Breitengrad (Latitude)
-
 
236
            writex_gpspos( 11, 3, home->Home_Lon , MNORMAL,  0,0);    // Anzeige: Laengengrad (Longitude)
-
 
237
            writex_gpspos(  0, 4, pos->Latitude  , MNORMAL,  0,0);    // Anzeige: Breitengrad (Latitude)
-
 
238
            writex_gpspos( 11, 4, pos->Longitude , MNORMAL,  0,0);    // Anzeige: Laengengrad (Longitude)
-
 
239
 
-
 
240
            //lcd_puts_at (0, 3, my_itoa(home->Home_Lat, 10, 7, 7), 0);     // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
241
            //lcd_puts_at (11, 3, my_itoa(home->Home_Lon, 10, 7, 7), 0);    // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
242
            //lcd_puts_at (0, 4, my_itoa(pos->Latitude, 10, 7, 7), 0);      // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
243
            //lcd_puts_at (11, 4, my_itoa(pos->Longitude, 10, 7, 7), 0);    // 30.05.2014 OG: my_itoa() gibt es nicht mehr
-
 
244
        }
-
 
245
 
-
 
246
        // Formel verwendet von http://www.kompf.de/gps/distcalc.html
-
 
247
        // 111.3 km = Abstand zweier Breitenkreise und/oder zweier Langenkreise am Äquator
-
 
248
        // es wird jedoch in dm Meter weiter gerechnet
-
 
249
        // (tlon1 - tlon2)/10) sonst uint32_t-Überlauf bei cos(0) gleich 1
-
 
250
        d1       = (1359 * (int32_t)(c_cos_8192((lat1 + lat2) / 20000000)) * ((lon1 - lon2)/10))/ 10000000;
-
 
251
        dlat = 1113 * (lat1 - lat2) / 10000;
-
 
252
        geo.bearing = (my_atan2(d1, dlat) + 540) % 360; // 360 +180 besserer Vergleich mit MkCockpit
-
 
253
        geo.distance = sqrt32(d1 * d1 + dlat * dlat);
-
 
254
        if( !CheckGPS )
-
 
255
        {
-
 
256
            lcd_printp_at (0, 5, PSTR("Bear:"), 0);
-
 
257
 
-
 
258
            lcdx_printf_at_P( 5, 5, MNORMAL, 0,0, PSTR("%3d"), geo.bearing );
-
 
259
            //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
-
 
260
 
-
 
261
            lcd_printp_at (8, 5, PSTR("\x1e"), 0);
-
 
262
            lcd_printp_at (9, 5, PSTR("Dist:"), 0);
-
 
263
 
-
 
264
            lcdx_printf_at_P( 15, 5, MNORMAL, 0,0, PSTR("%3d"), geo.distance );
-
 
265
            //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
-
 
266
 
-
 
267
            lcd_printp_at (20, 5, PSTR("m"), 0);
-
 
268
        }
-
 
269
 
-
 
270
 
-