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 | - |