API Question Improving geometry skills: oapiEquToLocal

Wishbone

Clueless developer
Addon Developer
Joined
Sep 12, 2010
Messages
2,420
Reaction score
2
Points
0
Location
Moscow
What are the axes in the planetocentric coordinate frame used by EquToLocal?

I have the following formula:

x = r*cos(Lat)*cos(Lon)
y = r*cos(Lat)*sin(Lon)
z = r*sin(Lat)

which means the z axis sticks out of the North pole while x goes through the Guinea Bay position, y sticking out of the 0 lat, 90 lon point. Apparently, the oapiEquToLocal doesn't think so (I'm getting angular difference of 78 degrees or so between the two vectors).
 
It looks like you are using a right-handed frame, Orbiter typically uses left-handed.

y = r*cos(Lat)*-sin(Lon)
 
Left-handedness makes me look for those wall-banging smilies...

---------- Post added at 07:41 AM ---------- Previous post was at 05:53 AM ----------

I checked it out. It is the Y-axis that goes to the pole. The system looks to be right-handed all right. Wish there were a technote on this and various other nitty-gritty details.
 
There is a reference to the right-handed system in the Orbiter.pdf in Doc directory, page 131, Appendix C.1.

I think I've seen others, I'll have a look through.

Edit:
In precession.pdf, page 1.
In Orbiter’s left-handed system,  is defined as (1,0,0), and N is
defined as (0,1,0).

Wel, i'm confused!
N.
 
Last edited:
Small wonder I'm getting weird results. Thanks a lot, will overhaul the code (right now there are papers to be marked... :| )
 
My mistake, for reason I had momentary lapse and thought that +Z was aligned with the north pole. I was thinking of the local horizon frame which has +Z north, +Y up and +X east :facepalm:. I agree a single document outlining the different reference frames and their associated API functions would be useful. On the to-do list now :)

A body has multiple reference frames. The one referred to at the start of precession.pdf is approximately inertial (ie, it does not rotate with the surface of the planet, but it does rotate of longer time preiods - the precession). This reference frame has +X aligned with ascending node of the ecliptic plane through equatorial plane and has +Y perpendicular to the equatorial plane, ie, aligned with the north pole. This reference frame can be obtained by oapiGetPlanetObliquityMatrix.

There is another reference frame that has its +Y axis aligned with the north pole and +X passing through Lat=0, Lon=0. This reference frame can be obtained by oapiGetRotationMatrix and it rotates around the +Y axis with approximately the same period as the sidereal rotation period of the planet (there are some minor precession effects in there).

So, Wishbone, I think your functions should be:
x = r*cos(Lat)*cos(Lon)
y = r*sin(Lat)
z = r*cos(Lat)*sin(Lon)
 
Candidate list of reference frames for documenting
  • Ecliptic
  • Precession
  • Equatorial
  • Body
  • Local horizontal/surface
  • Vessel
  • Docking/attachment
Any others you want?
 
Last edited:
+Local orbital frame (rvel as primary, rpos as secondary).

This is more or less what's currently in use. I've also seen B1950.0 ecliptic and galactic frames.

---------- Post added at 07:30 PM ---------- Previous post was at 04:25 PM ----------

+ Free airstream frame. (noticed that high-altitude winds are present in 2010-P1, would like to know what the model is)

Of course the frame would be used to finally compute the airspeed vector of an unladen swallow...
 
Added those, see hierarchical view:
2010-12-14 Reference Frames.png

(noticed that high-altitude winds are present in 2010-P1, would like to know what the model is)
From the documentation for oapiGetWindVector:
Warning:
Local wind velocities are not currently implemented. The surface-relative wind velocity is always (0,0,0). To ensure forward compatibility, plugins should not rely on this limitation, but use this function instead.
 
Ah, that I do know, but there is an obscure warning in the API reference to the effect that AirstreamVector at high altitudes doesn't coincide with the ground-relative vector.
 
Ah, I see it in GetAirspeed. I guess GetAirspeed/GetShipAirspeedVector will take the return value of oapiGetWindVector into account in the future. As far as I can tell the only reliable way to get the free airstream at present is to derive it from the vessel velocity and GetShipAirspeedVector because oapiGetWindVector doesn't seem to take the drag effect into account. Can you verify that (I'm not in a position to test atm)?

Also, how do you want this airstream frame derived? Presumably, the wind vector at the origin is {0,0,0}, but how do you want the axes aligned? Parallel to local surface frame? Aligned with wind vector and local horizontal? Aligned with ecliptic so you can use VESSELSTATUS::rvel easier?
 
Think for now some explanation is needed on how atmosphere rotates. The effects are really non negligible on Venus and at the jet stream altitudes (10-12 km) on Earth (in real life, got to test in a simple ascent setup - e.g. difference between own calculations and Orbiter).
 
My suggestion is to scrap the left handedness and convert Orbiters highly non-standard coordinate systems to standard orbital mechanical frames at the start of any calculation, perform the calculation in the usual manner, then convert them back into Orbiterness only as needed.

This way you can use any real world source material of the last century to assist you. The use of "standards" is an extremely powerful tool in the real world.

Doing such a coordinate frame heirarchy is usually an early step in simulation in the real world. Documenting these frames carefully is a very good idea. One generally creates unique names and abbreviations to refer to each frame, and documents the rotations from each frame to every adjacent frame.

As an example of how "anal" ;) one can be about trying to clearly and unambiguously define this sort of thing:

ANSI/AIAA R-004-1992 "Recommended Practice for Atmospheric and Space Flight Vehicle Coordinate Systems"
Extremely useful. Sadly one has to buy these things.

AIAA draft specification S-119, "Flight Dynamics Model Exchange Standard"
http://aiaa.kavi.com/public/pub_rev/AIAA_S-119_Final_for_2PR2.pdf
This is downloadable. Chapter 5 discusses coordinate frames, but critical details are by reference to ANSI/AIAA R-004-1992 and other standards.

----------------------

On another standards subject (but related to S-119):

The DAVE-ML (Dynamic Aerospace Vehicle Markup Language) portion of the S-119 spec would be extremely useful for Orbiter. It would allow you to create a complete aerodynamic model in XML, and load it into Orbiter and interpret it in real time. That is, without changing Orbiter or Orbiter plugin C++ code. (The interpretation penalty is slight, perhaps doubling the processing time over a hand coded solution.) The models include table look up definitions and also the equations to tie the table lookup results together (uses content MATH-ML).

Some tools to work with DAVE-ML are available now and others are in the process of being released. These hopefully include a prototype converter from a subset of DAVE-ML to compilable C code. (Removing most of the interpretation penalty, though not usually required.) Another interesting thing to watch for is a release of the Australian Defense Science Technology Organisation's "Janus" DAVE-ML interpreter under the LGPL (rather than the current GPL).

DAVE-ML website: http://daveml.org

One example of what you can do with this kind of XML technology is JSBSim, the default flight model used with the FlightGear open source simulator. (Similar ideas, different XML dialect)
[ame="http://en.wikipedia.org/wiki/JSBSim"]JSBSim - Wikipedia, the free encyclopedia[/ame]
http://jsbsim.sourceforge.net

The Power Of Standards
 
Last edited:
Thanks for the input, mjessick :thumbup:

My suggestion is to scrap the left handedness and convert Orbiters highly non-standard coordinate systems to standard orbital mechanical frames at the start of any calculation, perform the calculation in the usual manner, then convert them back into Orbiterness only as needed.
When we wrote KOST we used right-handed conventions and State Vector MFD (which uses KOST) does just what you suggest.

The intent of the Orbiter Reference Frame technote is to understand the reference frames as they are used in the Orbiter API, so left-handed it needs to be ;). Also, even once you have converted a frame to right-handedness, you still need to understand how the frame relates to other frames/objects/trajectories. That is the main purpose of the the technote. That said, information on how to convert from the Orbiter reference frames into more standard right hand frames would be useful information to include.
 
Three full-fledged definitions that have to be passed through the code once I'm done with teaching courses in this term:

Orbital plane CS
- Parent - refbody-centric inertial fixed CS
- Right-handed
- x (principal direction) - radius-vector from ref body to the satellite
- y (secondary direction) - vector from ref body to a point in the plane 90 degrees ahead of the satellite in terms of its motion
- z = crossp( r, rdot) (??)

Keplerian CS
- Right handed
- x points to the periapsis
- y as in Orbital plane
- z = crossp( r, rdot)

Equinoctial CS
- Right handed
- x points to the origin of longitudes
- y as in Orbital plane
- z = crossp( r, rdot)
 
Last edited:
ANSI/AIAA R-004-1992 "Recommended Practice for Atmospheric and Space Flight Vehicle Coordinate Systems"
Extremely useful. Sadly one has to buy these things.
I thought I might have been able to get this through our office's standards subscription but its current status is showing "withdrawn" so it is not available in electronic form. I guess I'll have to find some different holiday reading :P, unless you can point me to an alternative.

Three full-fledged definitions that have to be passed through the code once I'm done with teaching courses in this term:

Orbital plane CS
- z = crossp( r, rdot) (??)

Keplerian CS
- z = crossp( r, rdot)

Equinoctial CS
- z = crossp( r, rdot)
These systems fail because they are not orthogonal. z should be crossp(x,y) in all cases.

Orbital plane CS
- Parent - refbody-centric inertial fixed CS
- x (principal direction) - radius-vector from ref body to the satellite
- y (secondary direction) - vector from ref body to a point in the plane 90 degrees ahead of the satellite in terms of its motion
If +X is pointing at the orbiting body the frame is rotating, not inertial. Also, Why have Y lies in the local horizontal plane, it does not convey any useful information about the orbit that way. A local horizon frame is useful, as is an orbital frame, but not some hybrid of them - IMHO.
 
The idea and wording was borrowed from GSFC's manual on their old orbit prediction software, and z-axis puzzled me a bit (unless I can show that y actually is the rdot). I'll be experimenting with this stuff. Rotating systems are also needed; my code hasn't got the required velocity transformation yet.
 
I thought I might have been able to get this through our office's standards subscription but its current status is showing "withdrawn" so it is not available in electronic form. I guess I'll have to find some different holiday reading :P, unless you can point me to an alternative.

Yes, this is annoying. I had access to this a dozen years ago and remember it as very useful. I looked it up expecting $20 and found it was double that. (Like Texas property taxes, they have only one useful tax so they charge enough to be painful.)

If +X is pointing at the orbiting body the frame is rotating, not inertial. Also, Why have Y lies in the local horizontal plane, it does not convey any useful information about the orbit that way. A local horizon frame is useful, as is an orbital frame, but not some hybrid of them - IMHO.

I use this frame for rendezvous work, for example using the Hill's / Clohessy-Wiltshire equations.


For whatever it is worth, these are the coordinate systems I have defined rotations for and found useful with Orbiter. None of these are "Orbiter" frames. All are right handed.

----------------------------------
HE-Frame: Heliocentric Ecliptic (Inertial).
X along Vernal Equinox radius in Earth ecliptic plane,
Y fwd in orbit plane
Z up

P-Frame: Planet Centered Inertial (Inertial)
Reference inertial coordinates for planet.
For Earth:
X along Vernal Equinox radius in Earth ecliptic plane
Y fwd in direction of circular orbit, in Earth equatorial plane
Z up

R-Frame: Rotating (or Relative) Planet frame (Rotating)
Rotated from P-Frame by longitude of reference meridian at epoch

N-Frame: North-East-Down (Rotating)
X = in local (oblate or spherical) horizontal plane, Northwards
Y = Eastward
Z = down toward center of planet

H-Frame: Horizon (Variant of NED, similar to that used by Orbiter)
NED but additionally rotated about +Z by velocity heading. (F-frame without flight
path rotation)

C-Frame: Hill - Clohessy-Wiltshire Rendezvous frame (rotating)
X up along radius
Y fwd in circular orbit path
Z left out of plane

B-Frame: Base Frame. (Rotating, fixed to planet) Local horizontal coordinates of a ground
base. Rotated about +Z (down) from N-Frame by base rotation.
X in horizontal plane, rotated from North by base rotation
Y in horizontal plane, rotated from East by base rotation
Z down

L-Frame: Launch Inertial. (Inertial) Up - Right - Downrange (fixed at time of launch)
X Local Up (spherical or oblate)
Y out of Up-Downrange plane to the Right
Z Downrange (As defined by Launch Azimuth at launch) in local horizontal plane

F-Frame: Flight Path frame (Rotating). Used as basis for aero angles
X forward along flight path
Y right out of plane of flight path, in local horizontal plane
Z completes the set (roughly “down” for near zero fpa)

B-Frame: Body frame. (Rotating)
X fwd axis of body
Y right axis
Z down

----------

Detailed Rotations (Order of rotations is right to left):

(THP = transformation FROM Heliocentric TO (Earth) Planetary
THP = R1(Inclination to Ecliptic) R3 (longitude of ascending node to ecliptic)
Only correct for Earth. (Other planets may have 3 rotations?)
(My Inclination to Ecliptic for Earth is -23.45 degrees. Orbiter may use a positive value so the R1 rotation about the X axis above would probably be reversed when using the Orbiter value.)
This is a rotation about the +Z axis followed by a rortation about the new +X axis.

TPC = R1(pi) R3(argper) R1(inc) R3(RAAN)

TPR = R3(long0 = longitude of reference meridian at epoch)

TRN = R2(Lat + pi/2) R3(rel long)

TNL = R2(pi/2) R3(Laz)

TPL = R1(pi - Laz) R2(lat) R3(long0 + long)

TNF = R2(fpa) R3(heading)

TFB = R1(roll) R3(-sideslip) R2(AoA)

TLB = R3(- chi_yaw) R1(chi_roll) R2( - Chi_pitch)

TNB = R1(roll) R2(pitch) R3(heading)

Remember, these are all non-Orbiter and right-handed frames.
 
Back
Top