SDK Question Getting Vessel Attitude

ChrisRowland

Member
Joined
Feb 19, 2021
Messages
28
Reaction score
24
Points
18
Location
On the sofa
I'm trying to set up an autopilot that will cause a vessel to be pointed in a specified direction.
So far I'm trying to specify a direction as a vector in the local horizon system which I can use to get vessel pitch, yaw and eventually bank errors. I don't want to use GetPitch() and GetYaw() because these don't work when the pitch is 90 deg.

It looks as if HorizonInvRot will give me what I want. I specify the direction I want to point in the local horizon coordinates and HorizonInvRotate gives me a vector defining that direction in my vessel coordinates. As my vessel rotates the direction changes and I can use that to get the pitch and yaw errors.
This is fine for yaw, at least when the vessel has a pitch of zero, but doesn't seem to give me any pitch information. If I pitch my vessel up by 10 degrees I would expect that from my vessel a horizontal direction would be at a pitch angle of -10 deg, but it doesn't. It stays with a pitch of zero.
Here's a code fragment:

C++:
// for now only for rotation wrt the local horizon frame

    vessel->HorizonInvRot(target, error);

    yawErr = atan2(error.z, -error.x);
    pitchErr = atan2(error.y, error.z);
If I set target to 0 0 1 I expect that the direction is pointing to the East horizon and if my vessel is pointing in that direction the error vector is -1 0 0, z and x give me an angle about the y axis. But this doesn't work for pitch. pitching up or down doesn't really change anything. I actually see x and y changing with roll.

What I am taking away from this is that I don't understand how these rotate transforms work. I had expected that HorizonInvRotate would cause a direction to change relative to my vessel direction as the vessel changes direction. While it does it doesn't do so in a way that makes sense to me.

What I'd appreciate is some pointers to how I should implement this. Is there a solution involving HorizInvRot or is there a better way?

Thanks,

Chris
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,272
Reaction score
3,244
Points
203
Location
Toulouse
Regarding orientation and attitude, the most important thing is to keep in mind what your reference body is : another vessel, the planet you're orbiting, the Sun..

For an autopilot, your reference should be the main Gbody (the Earth, Mars, anywhere you want to fly).

You have API functions like GetPitch(), GetYaw(), GetBank() and even oapiGetFocusHeading(&vector) which should be very useful to you ?

Edit : nevermind, I missed your first line. Still, oapiGetFocusHeading(&vector) should help.

Else you should use GetRotationMatrix(), but you have to find a way to set a local reference frame.
 

ChrisRowland

Member
Joined
Feb 19, 2021
Messages
28
Reaction score
24
Points
18
Location
On the sofa
oapiGepFocusHeading only returns the heading, I would also need to use oapiGetFocusPitch to get the pitch and these will have the same gimbal lock issues at the zenith as GetPitch and GetYaw. Similarly with oapiGetHeading and its friends.

Is there nothing that will give me the direction my vessel is pointing wrt the horizon as a vector in the vessel system? That's what I thought HorizonInvRot would give me.
I suppose I could generate a vector from GetPitch and GetYaw but at the zenith that's dividing two small numbers and prone to error.
 

BrianJ

Addon Developer
Addon Developer
Joined
Apr 19, 2008
Messages
1,676
Reaction score
900
Points
128
Location
Code 347
I'm trying to set up an autopilot that will cause a vessel to be pointed in a specified direction.
So far I'm trying to specify a direction as a vector in the local horizon system which I can use to get vessel pitch, yaw and eventually bank errors. I don't want to use GetPitch() and GetYaw() because these don't work when the pitch is 90 deg.

It looks as if HorizonInvRot will give me what I want. I specify the direction I want to point in the local horizon coordinates and HorizonInvRotate gives me a vector defining that direction in my vessel coordinates. As my vessel rotates the direction changes and I can use that to get the pitch and yaw errors.
This is fine for yaw, at least when the vessel has a pitch of zero, but doesn't seem to give me any pitch information. If I pitch my vessel up by 10 degrees I would expect that from my vessel a horizontal direction would be at a pitch angle of -10 deg, but it doesn't. It stays with a pitch of zero.
Here's a code fragment:

C++:
// for now only for rotation wrt the local horizon frame

    vessel->HorizonInvRot(target, error);

    yawErr = atan2(error.z, -error.x);
    pitchErr = atan2(error.y, error.z);
If I set target to 0 0 1 I expect that the direction is pointing to the East horizon and if my vessel is pointing in that direction the error vector is -1 0 0, z and x give me an angle about the y axis. But this doesn't work for pitch. pitching up or down doesn't really change anything. I actually see x and y changing with roll.

What I am taking away from this is that I don't understand how these rotate transforms work. I had expected that HorizonInvRotate would cause a direction to change relative to my vessel direction as the vessel changes direction. While it does it doesn't do so in a way that makes sense to me.

What I'd appreciate is some pointers to how I should implement this. Is there a solution involving HorizInvRot or is there a better way?

Thanks,

Chris
Hi Chris,
I wonder if the problem is your interpretation of Orbiter's Local Horizon Frame: +X = East, +Y = Up, +Z = North.
Your "target" vector 0 0 1 is pointing North. If your vessel has conventional orientation of +Z = Forwards(pointy end), and is pointing East, then your "error" vector will indeed be -1 0 0. But pitching up from this attitude is just rotating around the "target" vector - your pitch error will remain zero, your yaw error will remain 90deg.

Your code looks fine to me (at first glance).

EDIT: Actually, I think your yawErr is backwards,

Code:
vessel->HorizonInvRot(target, error);

    yawErr = atan2(-error.x, error.z);
    pitchErr = atan2(error.y, error.z);

Cheers,
Brian
 
Last edited:

ChrisRowland

Member
Joined
Feb 19, 2021
Messages
28
Reaction score
24
Points
18
Location
On the sofa
Hi Brian,
I wouldn't be the least surprised that I've got the axes wrong.

I turned on the visual helper axes display and saw that a surface base had the +X axis pointing South, the +Z axis pointing East and the +Y axis up. I thought that would be the same as the local horizon axes. It seems not, I'm 90 degrees out.

I'll try again, all these coordinate frames are very confusing. It's likely that once the axes are sorted correctly the yawErr will look correct.

Thanks,

Chris
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,842
Reaction score
2,105
Points
203
Location
between the planets
Yeah, orbiter uses a right-handed coordinate system, where the index finger is Z and the thumb is Y, so X points the other way than you'd intuitively assume. Always keep that in mind.
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,390
Reaction score
577
Points
153
Location
Vienna
Yeah, orbiter uses a right-handed coordinate system, where the index finger is Z and the thumb is Y, so X points the other way than you'd intuitively assume. Always keep that in mind.

I always thought the letter assignment is straight forward X to thumb, Y to index, Z to middle finger, just on the left hand for Orbiter in contrast to right-handed in literature. Did that change?
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,272
Reaction score
3,244
Points
203
Location
Toulouse
I'm not fond of the "fingers rules", because some people are right-handed, others left-handed and that can lead to even more confusion.

This is a 100% genuine picture from Orbiter 2016, with "Axis" overlay enabled, I'd say its enough, the DG being pretty much like any airplane :

 

ChrisRowland

Member
Joined
Feb 19, 2021
Messages
28
Reaction score
24
Points
18
Location
On the sofa
Everything I've seen indicates what I'd call a left hand coordinate system everywhere.

Thumb is X, first finger Y, second finger Z. All on the left hand.

Or index is Z, thumb is Y and second finger is X also all on your left hand.

But even having this conversation makes me think that this could be documented more clearly.
 

BrianJ

Addon Developer
Addon Developer
Joined
Apr 19, 2008
Messages
1,676
Reaction score
900
Points
128
Location
Code 347
Everything I've seen indicates what I'd call a left hand coordinate system everywhere.

Thumb is X, first finger Y, second finger Z. All on the left hand.

Or index is Z, thumb is Y and second finger is X also all on your left hand.

But even having this conversation makes me think that this could be documented more clearly.
Yep, I did try to find confirmation of the Local Horizon frame convention in the docs, but couldn't.
The trouble with "left/right handed" descriptions is - it depends which finger you start with!
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,842
Reaction score
2,105
Points
203
Location
between the planets
I always thought the letter assignment is straight forward X to thumb, Y to index, Z to middle finger, just on the left hand for Orbiter in contrast to right-handed in literature. Did that change?
Uhm... it depends on how you look at it, I guess :lol:

When I was a toolmaker, things were pretty clear: Left hand, thumb is Z+ (up), index is Y+ (away), middle is X+ (right). That's the axes of a simple CnC machine.

When I switched to a frame of reference where Z was usually the direction you look in, left-handed still worked, except index was now Z+ (away), thumb was Y+ (up) and X+ was still middle (right).

When transfering that to orbiter, as far as I remember everything was still the same, except x+ went the other way, so I had to take my right hand. I guess it's possible Y changed direction too? I dunno it's been a while...
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,390
Reaction score
577
Points
153
Location
Vienna
If I loosely hold out my left hand in front of me, and let thumb, index and middle finger make a coordinate system, with thumb X, index Y and middle Z, I get the exact coordinate system as depicted in N_Molson's image. No need to twist my hand or reverse anything. What am I missing?
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,272
Reaction score
3,244
Points
203
Location
Toulouse
except x+ went the other way

I don't agree. Look at the DeltaGlider on the pic I posted :

+X is the right wing, "starboard" in nautical terms from old english. Usually a nav green light (nautical convention).
-X is the left wing, "port". Usually a nav red light (nautical convention).

+Y is dorsal "zenith" (nautical terms from ancient Arab)
-Y is ventral "nadir"

+Z is nose
- Z is stern (tail)

@Face : I thought a second "Martins could have reverted the visual indicators to help understanding" then "No way !! The whole point of those reference axes is to help addons devs to see what they are doing !"
 
Last edited:

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,842
Reaction score
2,105
Points
203
Location
between the planets
What am I missing?
Probably just that I like to point with my index finger more than I like pointing with my middle finger, and I like the Z-axis to point away from my body, because I'm really, really bad at rotating things in my head... :p
However, looking at that image, it does indeed seem like I got the X-axis pointing the wrong way with my right hand. So I probably remembered it the wrong way around and I was using my left hand in Orbiter. Mea Culpa, it's been a couple of years...
 

Arvil

Well-known member
Joined
Apr 20, 2008
Messages
400
Reaction score
315
Points
78
Location
Pennsylvania, USA
Preferred Pronouns
he/him
Face is correct, but, the hand orientation must be specified, index finger up, thumb to the right middle finger forward, I was confused until I compared his description to N_Milsons DG shot.
Jedediah jedidia, you’re thinking CNC in terms of the operator’s viewpoint. Think in terms if you are the workpiece. If we could put the DG in a vise on a vertical mill wings left-right, nose up to the spindle, dorsal toward the operator’s door, X+ is to the right, Y+ is to the operator’s door, Z+ is to the spindle. Clamp the DG into the vise on the tombstone on a horizontal mill, tail in the vise, dorsal up, nose to the spindle, X+ is toward the operator door, Y+ is up, Z+ is toward the spindle. Imagine you’re sitting in the cockpit for those views. Now that I thought that through for myself, it’ll be easier for me to remember.
 
Last edited:

ChrisRowland

Member
Joined
Feb 19, 2021
Messages
28
Reaction score
24
Points
18
Location
On the sofa
Brian's suggestion seems to have been correct, once I used the correct alignment things made sense and I've got to the point where the autopilot heads to the correct position, oscillates wildly, and rushes off to oblivion.

Chris
 
Top