Branch data Line data Source code
1 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 : :
3 : : Header: FGLocation.h
4 : : Author: Jon S. Berndt, Mathias Froehlich
5 : : Date started: 04/04/2004
6 : :
7 : : ------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) ------------------
8 : : ------- (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) ----
9 : :
10 : : This program is free software; you can redistribute it and/or modify it under
11 : : the terms of the GNU Lesser General Public License as published by the Free Software
12 : : Foundation; either version 2 of the License, or (at your option) any later
13 : : version.
14 : :
15 : : This program is distributed in the hope that it will be useful, but WITHOUT
16 : : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 : : FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 : : details.
19 : :
20 : : You should have received a copy of the GNU Lesser General Public License along with
21 : : this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22 : : Place - Suite 330, Boston, MA 02111-1307, USA.
23 : :
24 : : Further information about the GNU Lesser General Public License can also be found on
25 : : the world wide web at http://www.gnu.org.
26 : :
27 : : HISTORY
28 : : -------------------------------------------------------------------------------
29 : : 04/04/2004 MF Created from code previously in the old positions class.
30 : :
31 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 : : SENTRY
33 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
34 : :
35 : : #ifndef FGLOCATION_H
36 : : #define FGLOCATION_H
37 : :
38 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 : : INCLUDES
40 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 : :
42 : : #include "FGJSBBase.h"
43 : : #include "input_output/FGPropertyManager.h"
44 : : #include "FGColumnVector3.h"
45 : : #include "FGMatrix33.h"
46 : :
47 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 : : DEFINITIONS
49 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50 : :
51 : : #define ID_LOCATION "$Id: FGLocation.h,v 1.24 2010/08/25 00:32:32 jberndt Exp $"
52 : :
53 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 : : FORWARD DECLARATIONS
55 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
56 : :
57 : : namespace JSBSim {
58 : :
59 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 : : CLASS DOCUMENTATION
61 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
62 : :
63 : : /** FGLocation holds an arbitrary location in the Earth centered Earth fixed
64 : : reference frame (ECEF). This coordinate frame has its center in the middle
65 : : of the earth. The X-axis points from the center of the Earth towards a
66 : : location with zero latitude and longitude on the Earth surface. The Y-axis
67 : : points from the center of the Earth towards a location with zero latitude
68 : : and 90 deg East longitude on the Earth surface. The Z-axis points from the
69 : : Earth center to the geographic north pole.
70 : :
71 : : This class provides access functions to set and get the location as either
72 : : the simple X, Y and Z values in ft or longitude/latitude and the radial
73 : : distance of the location from the Earth center.
74 : :
75 : : It is common to associate a parent frame with a location. This frame is
76 : : usually called the local horizontal frame or simply the local frame. It is
77 : : also called the NED frame (North, East, Down), as well as the Navigation
78 : : frame. This frame has its X/Y plane parallel to the surface of the Earth
79 : : (with the assumption of a spherical Earth). The X-axis points towards north,
80 : : the Y-axis points east and the Z-axis points to the center of the Earth.
81 : :
82 : : Since the local frame is determined by the location (and NOT by the
83 : : orientation of the vehicle IN any frame), this class also provides the
84 : : rotation matrices required to transform from the Earth centered (ECEF) frame
85 : : to the local horizontal frame and back. This class also "owns" the
86 : : transformations that go from the inertial frame (Earth-centered Inertial, or
87 : : ECI) to and from the ECEF frame, as well as to and from the local frame.
88 : : Again, this is because the ECI, ECEF, and local frames do not involve the
89 : : actual orientation of the vehicle - only the location on the Earth surface,
90 : : and the angular difference between the ECI and ECEF frames. There are
91 : : conversion functions for conversion of position vectors given in the one
92 : : frame to positions in the other frame.
93 : :
94 : : The Earth centered reference frame is NOT an inertial frame since it rotates
95 : : with the Earth.
96 : :
97 : : The coordinates in the Earth centered frame are the master values. All other
98 : : values are computed from these master values and are cached as long as the
99 : : location is changed by access through a non-const member function. Values
100 : : are cached to improve performance. It is best practice to work with a
101 : : natural set of master values. Other parameters that are derived from these
102 : : master values are calculated only when needed, and IF they are needed and
103 : : calculated, then they are cached (stored and remembered) so they do not need
104 : : to be re-calculated until the master values they are derived from are
105 : : themselves changed (and become stale).
106 : :
107 : : Accuracy and round off
108 : :
109 : : Given,
110 : :
111 : : -that we model a vehicle near the Earth
112 : : -that the Earth surface radius is about 2*10^7, ft
113 : : -that we use double values for the representation of the location
114 : :
115 : : we have an accuracy of about
116 : :
117 : : 1e-16*2e7ft/1 = 2e-9 ft
118 : :
119 : : left. This should be sufficient for our needs. Note that this is the same
120 : : relative accuracy we would have when we compute directly with
121 : : lon/lat/radius. For the radius value this is clear. For the lon/lat pair
122 : : this is easy to see. Take for example KSFO located at about 37.61 deg north
123 : : 122.35 deg west, which corresponds to 0.65642 rad north and 2.13541 rad
124 : : west. Both values are of magnitude of about 1. But 1 ft corresponds to about
125 : : 1/(2e7*2*pi) = 7.9577e-09 rad. So the left accuracy with this representation
126 : : is also about 1*1e-16/7.9577e-09 = 1.2566e-08 which is of the same magnitude
127 : : as the representation chosen here.
128 : :
129 : : The advantage of this representation is that it is a linear space without
130 : : singularities. The singularities are the north and south pole and most
131 : : notably the non-steady jump at -pi to pi. It is harder to track this jump
132 : : correctly especially when we need to work with error norms and derivatives
133 : : of the equations of motion within the time-stepping code. Also, the rate of
134 : : change is of the same magnitude for all components in this representation
135 : : which is an advantage for numerical stability in implicit time-stepping.
136 : :
137 : : Note: The latitude is a GEOCENTRIC value. FlightGear converts latitude to a
138 : : geodetic value and uses that. In order to get best matching relative to a
139 : : map, geocentric latitude must be converted to geodetic.
140 : :
141 : : @see Stevens and Lewis, "Aircraft Control and Simulation", Second edition
142 : : @see W. C. Durham "Aircraft Dynamics & Control", section 2.2
143 : :
144 : : @author Mathias Froehlich
145 : : @version $Id: FGLocation.h,v 1.24 2010/08/25 00:32:32 jberndt Exp $
146 : : */
147 : :
148 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 : : CLASS DECLARATION
150 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
151 : :
152 : : class FGLocation : virtual FGJSBBase
153 [ + - ][ # # ]: 108014 : {
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ + - ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
154 : : public:
155 : : /** Default constructor. */
156 : : FGLocation(void);
157 : :
158 : : /** Constructor to set the longitude, latitude and the distance
159 : : from the center of the earth.
160 : : @param lon longitude
161 : : @param lat GEOCENTRIC latitude
162 : : @param radius distance from center of earth to vehicle in feet*/
163 : : FGLocation(double lon, double lat, double radius);
164 : :
165 : : /** Column constructor. */
166 : 108011 : FGLocation(const FGColumnVector3& lv) : mECLoc(lv), mCacheValid(false)
167 : : {
168 : 108011 : a = 0.0;
169 : 108011 : b = 0.0;
170 : 108011 : a2 = 0.0;
171 : 108011 : b2 = 0.0;
172 : 108011 : e2 = 1.0;
173 : 108011 : e = 1.0;
174 : 108011 : eps2 = -1.0;
175 : 108011 : f = 1.0;
176 : 0 : }
177 : :
178 : : /** Copy constructor. */
179 : : FGLocation(const FGLocation& l)
180 : : : mECLoc(l.mECLoc), mCacheValid(l.mCacheValid)
181 : : {
182 : : // if (!mCacheValid) return; // This doesn't seem right.
183 : :
184 : : mLon = l.mLon;
185 : : mLat = l.mLat;
186 : : mRadius = l.mRadius;
187 : :
188 : : mTl2ec = l.mTl2ec;
189 : : mTec2l = l.mTec2l;
190 : :
191 : : a = l.a;
192 : : b = l.b;
193 : : a2 = l.a2;
194 : : b2 = l.b2;
195 : : e2 = l.e2;
196 : : e = l.e;
197 : : eps2 = l.eps2;
198 : : f = l.f;
199 : :
200 : : initial_longitude = l.initial_longitude;
201 : : }
202 : :
203 : : /** Set the longitude.
204 : : @param longitude Longitude in rad to set.
205 : : Sets the longitude of the location represented with this class
206 : : instance to the value of the given argument. The value is meant
207 : : to be in rad. The latitude and the radius value are preserved
208 : : with this call with the exception of radius being equal to
209 : : zero. If the radius is previously set to zero it is changed to be
210 : : equal to 1.0 past this call. Longitude is positive east and negative west. */
211 : : void SetLongitude(double longitude);
212 : :
213 : : /** Set the latitude.
214 : : @param latitude Latitude in rad to set.
215 : : Sets the latitude of the location represented with this class
216 : : instance to the value of the given argument. The value is meant
217 : : to be in rad. The longitude and the radius value are preserved
218 : : with this call with the exception of radius being equal to
219 : : zero. If the radius is previously set to zero it is changed to be
220 : : equal to 1.0 past this call.
221 : : Latitude is positive north and negative south.
222 : : The arguments should be within the bounds of -pi/2 <= lat <= pi/2.
223 : : The behavior of this function with arguments outside this range is
224 : : left as an exercise to the gentle reader ... */
225 : : void SetLatitude(double latitude);
226 : :
227 : : /** Set the distance from the center of the earth.
228 : : @param radius Radius in ft to set.
229 : : Sets the radius of the location represented with this class
230 : : instance to the value of the given argument. The value is meant
231 : : to be in ft. The latitude and longitude values are preserved
232 : : with this call with the exception of radius being equal to
233 : : zero. If the radius is previously set to zero, latitude and
234 : : longitude is set equal to zero past this call.
235 : : The argument should be positive.
236 : : The behavior of this function called with a negative argument is
237 : : left as an exercise to the gentle reader ... */
238 : : void SetRadius(double radius);
239 : :
240 : : /** Sets the longitude, latitude and the distance from the center of the earth.
241 : : @param lon longitude in radians
242 : : @param lat GEOCENTRIC latitude in radians
243 : : @param radius distance from center of earth to vehicle in feet*/
244 : : void SetPosition(double lon, double lat, double radius);
245 : :
246 : : /** Sets the longitude, latitude and the distance above the reference ellipsoid.
247 : : @param lon longitude in radians
248 : : @param lat GEODETIC latitude in radians
249 : : @param height distance above the reference ellipsoid to vehicle in feet*/
250 : : void SetPositionGeodetic(double lon, double lat, double height);
251 : :
252 : : /** Sets the semimajor and semiminor axis lengths for this planet.
253 : : The eccentricity and flattening are calculated from the semimajor
254 : : and semiminor axis lengths */
255 : : void SetEllipse(double semimajor, double semiminor);
256 : :
257 : : /** Sets the Earth position angle.
258 : : This is the relative orientation of the ECEF frame with respect to the
259 : : Inertial frame.
260 : : @param EPA Earth fixed frame (ECEF) rotation offset about the axis with
261 : : respect to the Inertial (ECI) frame in radians. */
262 : 54006 : void SetEarthPositionAngle(double EPA) {epa = EPA; mCacheValid = false; ComputeDerived();}
263 : :
264 : : /** Get the longitude.
265 : : @return the longitude in rad of the location represented with this
266 : : class instance. The returned values are in the range between
267 : : -pi <= lon <= pi. Longitude is positive east and negative west. */
268 : 54006 : double GetLongitude() const { ComputeDerived(); return mLon; }
269 : :
270 : : /** Get the longitude.
271 : : @return the longitude in deg of the location represented with this
272 : : class instance. The returned values are in the range between
273 : : -180 <= lon <= 180. Longitude is positive east and negative west. */
274 : 4911 : double GetLongitudeDeg() const { ComputeDerived(); return radtodeg*mLon; }
275 : :
276 : : /** Get the sine of Longitude. */
277 : : double GetSinLongitude() const { ComputeDerived(); return -mTec2l(2,1); }
278 : :
279 : : /** Get the cosine of Longitude. */
280 : : double GetCosLongitude() const { ComputeDerived(); return mTec2l(2,2); }
281 : :
282 : : /** Get the latitude.
283 : : @return the latitude in rad of the location represented with this
284 : : class instance. The returned values are in the range between
285 : : -pi/2 <= lon <= pi/2. Latitude is positive north and negative south. */
286 : 108012 : double GetLatitude() const { ComputeDerived(); return mLat; }
287 : :
288 : : /** Get the geodetic latitude.
289 : : @return the geodetic latitude in rad of the location represented with this
290 : : class instance. The returned values are in the range between
291 : : -pi/2 <= lon <= pi/2. Latitude is positive north and negative south. */
292 : 1 : double GetGeodLatitudeRad(void) const { ComputeDerived(); return mGeodLat; }
293 : :
294 : : /** Get the latitude.
295 : : @return the latitude in deg of the location represented with this
296 : : class instance. The returned value is in the range between
297 : : -90 <= lon <= 90. Latitude is positive north and negative south. */
298 : 4911 : double GetLatitudeDeg() const { ComputeDerived(); return radtodeg*mLat; }
299 : :
300 : : /** Get the geodetic latitude in degrees.
301 : : @return the geodetic latitude in degrees of the location represented by
302 : : this class instance. The returned value is in the range between
303 : : -90 <= lon <= 90. Latitude is positive north and negative south. */
304 : 1 : double GetGeodLatitudeDeg(void) const { ComputeDerived(); return radtodeg*mGeodLat; }
305 : :
306 : : /** Gets the geodetic altitude in feet. */
307 : 1 : double GetGeodAltitude(void) const { return GeodeticAltitude;}
308 : :
309 : : /** Get the sine of Latitude. */
310 : : double GetSinLatitude() const { ComputeDerived(); return -mTec2l(3,3); }
311 : :
312 : : /** Get the cosine of Latitude. */
313 : : double GetCosLatitude() const { ComputeDerived(); return mTec2l(1,3); }
314 : :
315 : : /** Get the cosine of Latitude. */
316 : : double GetTanLatitude() const {
317 : 1 : ComputeDerived();
318 : 2 : double cLat = mTec2l(1,3);
319 [ - + ]: 1 : if (cLat == 0.0)
320 : 0 : return 0.0;
321 : : else
322 : 1 : return -mTec2l(3,3)/cLat;
323 : : }
324 : :
325 : : /** Get the distance from the center of the earth.
326 : : @return the distance of the location represented with this class
327 : : instance to the center of the earth in ft. The radius value is
328 : : always positive. */
329 : : //double GetRadius() const { return mECLoc.Magnitude(); } // may not work with FlightGear
330 : 1040880 : double GetRadius() const { ComputeDerived(); return mRadius; }
331 : :
332 : : /** Transform matrix from local horizontal to earth centered frame.
333 : : Returns a const reference to the rotation matrix of the transform from
334 : : the local horizontal frame to the earth centered frame. */
335 : 54006 : const FGMatrix33& GetTl2ec(void) const { ComputeDerived(); return mTl2ec; }
336 : :
337 : : /** Transform matrix from the earth centered to local horizontal frame.
338 : : Returns a const reference to the rotation matrix of the transform from
339 : : the earth centered frame to the local horizontal frame. */
340 : 0 : const FGMatrix33& GetTec2l(void) const { ComputeDerived(); return mTec2l; }
341 : :
342 : : /** Transform matrix from inertial to earth centered frame.
343 : : Returns a const reference to the rotation matrix of the transform from
344 : : the inertial frame to the earth centered frame (ECI to ECEF). */
345 : : const FGMatrix33& GetTi2ec(void);
346 : :
347 : : /** Transform matrix from the earth centered to inertial frame.
348 : : Returns a const reference to the rotation matrix of the transform from
349 : : the earth centered frame to the inertial frame (ECEF to ECI). */
350 : : const FGMatrix33& GetTec2i(void);
351 : :
352 : 54006 : const FGMatrix33& GetTi2l(void) const {return mTi2l;}
353 : :
354 : 0 : const FGMatrix33& GetTl2i(void) const {return mTl2i;}
355 : :
356 : : /** Conversion from Local frame coordinates to a location in the
357 : : earth centered and fixed frame.
358 : : @param lvec Vector in the local horizontal coordinate frame
359 : : @return The location in the earth centered and fixed frame */
360 : : FGLocation LocalToLocation(const FGColumnVector3& lvec) const {
361 : 54005 : ComputeDerived(); return mTl2ec*lvec + mECLoc;
362 : : }
363 : :
364 : : /** Conversion from a location in the earth centered and fixed frame
365 : : to local horizontal frame coordinates.
366 : : @param ecvec Vector in the earth centered and fixed frame
367 : : @return The vector in the local horizontal coordinate frame */
368 : : FGColumnVector3 LocationToLocal(const FGColumnVector3& ecvec) const {
369 : : ComputeDerived(); return mTec2l*(ecvec - mECLoc);
370 : : }
371 : :
372 : : // For time-stepping, locations have vector properties...
373 : :
374 : : /** Read access the entries of the vector.
375 : : @param idx the component index.
376 : : Return the value of the matrix entry at the given index.
377 : : Indices are counted starting with 1.
378 : : Note that the index given in the argument is unchecked. */
379 : : double operator()(unsigned int idx) const { return mECLoc.Entry(idx); }
380 : :
381 : : /** Write access the entries of the vector.
382 : : @param idx the component index.
383 : : @return a reference to the vector entry at the given index.
384 : : Indices are counted starting with 1.
385 : : Note that the index given in the argument is unchecked. */
386 : : double& operator()(unsigned int idx) { mCacheValid = false; return mECLoc.Entry(idx); }
387 : :
388 : : /** Read access the entries of the vector.
389 : : @param idx the component index.
390 : : @return the value of the matrix entry at the given index.
391 : : Indices are counted starting with 1.
392 : : This function is just a shortcut for the <tt>double
393 : : operator()(unsigned int idx) const</tt> function. It is
394 : : used internally to access the elements in a more convenient way.
395 : : Note that the index given in the argument is unchecked. */
396 : : double Entry(unsigned int idx) const { return mECLoc.Entry(idx); }
397 : :
398 : : /** Write access the entries of the vector.
399 : : @param idx the component index.
400 : : @return a reference to the vector entry at the given index.
401 : : Indices are counted starting with 1.
402 : : This function is just a shortcut for the double&
403 : : operator()(unsigned int idx) function. It is
404 : : used internally to access the elements in a more convenient way.
405 : : Note that the index given in the argument is unchecked. */
406 : : double& Entry(unsigned int idx) {
407 : : mCacheValid = false; return mECLoc.Entry(idx);
408 : : }
409 : :
410 : : /** Sets this location via the supplied vector.
411 : : The location can be set by an Earth-centered, Earth-fixed (ECEF) frame
412 : : position vector. The cache is marked as invalid, so any future requests
413 : : for selected important data will cause the parameters to be calculated.
414 : : @param v the ECEF column vector in feet.
415 : : @return a reference to the FGLocation object. */
416 : : const FGLocation& operator=(const FGColumnVector3& v)
417 : : {
418 : 216022 : mECLoc(eX) = v(eX);
419 : 216022 : mECLoc(eY) = v(eY);
420 : 216022 : mECLoc(eZ) = v(eZ);
421 : 108011 : mCacheValid = false;
422 : 54005 : ComputeDerived();
423 : 108011 : return *this;
424 : : }
425 : :
426 : : /** Sets this location via the supplied location object.
427 : : @param v A location object reference.
428 : : @return a reference to the FGLocation object. */
429 : : const FGLocation& operator=(const FGLocation& l)
430 : : {
431 : 54005 : mECLoc = l.mECLoc;
432 : 54005 : mCacheValid = l.mCacheValid;
433 : :
434 : : // if (!mCacheValid) return *this; // Why is this here for an assignment operator?
435 : :
436 : 54005 : mLon = l.mLon;
437 : 54005 : mLat = l.mLat;
438 : 54005 : mRadius = l.mRadius;
439 : :
440 : 54005 : mTl2ec = l.mTl2ec;
441 : 54005 : mTec2l = l.mTec2l;
442 : :
443 : 54005 : a = l.a;
444 : 54005 : b = l.b;
445 : 54005 : a2 = l.a2;
446 : 54005 : b2 = l.b2;
447 : 54005 : e2 = l.e2;
448 : 54005 : e = l.e;
449 : 54005 : eps2 = l.eps2;
450 : 54005 : f = l.f;
451 : :
452 : 54005 : initial_longitude = l.initial_longitude;
453 : 54005 : mGeodLat = l.mGeodLat;
454 : 54005 : GeodeticAltitude = l.GeodeticAltitude;
455 : :
456 : 54005 : return *this;
457 : : }
458 : :
459 : : /** This operator returns true if the ECEF location vectors for the two
460 : : location objects are equal. */
461 : : bool operator==(const FGLocation& l) const {
462 : : return mECLoc == l.mECLoc;
463 : : }
464 : :
465 : : /** This operator returns true if the ECEF location vectors for the two
466 : : location objects are not equal. */
467 : : bool operator!=(const FGLocation& l) const { return ! operator==(l); }
468 : :
469 : : /** This operator adds the ECEF position vectors.
470 : : The supplied vector (right side) is added to the ECEF position vector
471 : : on the left side of the equality, and a pointer to this object is
472 : : returned. */
473 : : const FGLocation& operator+=(const FGLocation &l) {
474 : : mCacheValid = false;
475 : : mECLoc += l.mECLoc;
476 : : return *this;
477 : : }
478 : :
479 : : const FGLocation& operator-=(const FGLocation &l) {
480 : 54006 : mCacheValid = false;
481 : 54006 : mECLoc -= l.mECLoc;
482 : 54006 : return *this;
483 : : }
484 : :
485 : : const FGLocation& operator*=(double scalar) {
486 : : mCacheValid = false;
487 : : mECLoc *= scalar;
488 : : return *this;
489 : : }
490 : :
491 : : const FGLocation& operator/=(double scalar) {
492 : : return operator*=(1.0/scalar);
493 : : }
494 : :
495 : : FGLocation operator+(const FGLocation& l) const {
496 : : return FGLocation(mECLoc + l.mECLoc);
497 : : }
498 : :
499 : : FGLocation operator-(const FGLocation& l) const {
500 : : return FGLocation(mECLoc - l.mECLoc);
501 : : }
502 : :
503 : : FGLocation operator*(double scalar) const {
504 : : return FGLocation(scalar*mECLoc);
505 : : }
506 : :
507 : : /** Cast to a simple 3d vector */
508 : : operator const FGColumnVector3&() const {
509 : 166928 : return mECLoc;
510 : : }
511 : :
512 : : private:
513 : : /** Computation of derived values.
514 : : This function re-computes the derived values like lat/lon and
515 : : transformation matrices. It does this unconditionally. */
516 : : void ComputeDerivedUnconditional(void) const;
517 : :
518 : : /** Computation of derived values.
519 : : This function checks if the derived values like lat/lon and
520 : : transformation matrices are already computed. If so, it
521 : : returns. If they need to be computed this is done here. */
522 : 981970 : void ComputeDerived(void) const {
523 [ + + + - : 1374741 : if (!mCacheValid)
# # # # ]
[ + + - + ]
[ + - - + ]
[ # # ][ # # ]
[ - + ][ - + ]
[ + - - + ]
[ - + # # ]
[ # # ][ # # ]
[ # # - +
- + - + ]
524 : 216026 : ComputeDerivedUnconditional();
525 : 981970 : }
526 : :
527 : : /** The coordinates in the earth centered frame. This is the master copy.
528 : : The coordinate frame has its center in the middle of the earth.
529 : : Its x-axis points from the center of the earth towards a
530 : : location with zero latitude and longitude on the earths
531 : : surface. The y-axis points from the center of the earth towards a
532 : : location with zero latitude and 90deg longitude on the earths
533 : : surface. The z-axis points from the earths center to the
534 : : geographic north pole.
535 : : @see W. C. Durham "Aircraft Dynamics & Control", section 2.2 */
536 : : FGColumnVector3 mECLoc;
537 : :
538 : : /** The cached lon/lat/radius values. */
539 : : mutable double mLon;
540 : : mutable double mLat;
541 : : mutable double mRadius;
542 : : mutable double mGeodLat;
543 : : mutable double GeodeticAltitude;
544 : :
545 : : double initial_longitude;
546 : :
547 : : /** The cached rotation matrices from and to the associated frames. */
548 : : mutable FGMatrix33 mTl2ec;
549 : : mutable FGMatrix33 mTec2l;
550 : : mutable FGMatrix33 mTi2ec;
551 : : mutable FGMatrix33 mTec2i;
552 : : mutable FGMatrix33 mTi2l;
553 : : mutable FGMatrix33 mTl2i;
554 : :
555 : : double epa;
556 : :
557 : : /* Terms for geodetic latitude calculation. Values are from WGS84 model */
558 : : double a; // Earth semimajor axis in feet (6,378,137.0 meters)
559 : : double b; // Earth semiminor axis in feet (6,356,752.3142 meters)
560 : : double a2;
561 : : double b2;
562 : : double e; // Earth eccentricity
563 : : double e2; // Earth eccentricity squared
564 : : double eps2; //
565 : : double f; // Flattening
566 : :
567 : : /** A data validity flag.
568 : : This class implements caching of the derived values like the
569 : : orthogonal rotation matrices or the lon/lat/radius values. For caching we
570 : : carry a flag which signals if the values are valid or not.
571 : : The C++ keyword "mutable" tells the compiler that the data member is
572 : : allowed to change during a const member function. */
573 : : mutable bool mCacheValid;
574 : : };
575 : :
576 : : /** Scalar multiplication.
577 : :
578 : : @param scalar scalar value to multiply with.
579 : : @param l Vector to multiply.
580 : :
581 : : Multiply the Vector with a scalar value. */
582 : : inline FGLocation operator*(double scalar, const FGLocation& l)
583 : : {
584 : : return l.operator*(scalar);
585 : : }
586 : :
587 : : } // namespace JSBSim
588 : :
589 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590 : : #endif
|