Jump to content

Acquiring a position vector


Recommended Posts

New to creating plugins for KSP, trying to figure out how to acquire two vessels' (or celestial body's) position vectors in the same frame to do pointing math.

I'm trying to ascertain how to use

Vessel GetVessel() and Vector3d GetWorldPos3d()

Or if those are even the correct methods to be using in this case. I haven't been able to find a good code example snippet to showcase how to do simple telemetry gets, so even just pointing me at a source code file would be fine.

Link to comment
Share on other sites

There's a lot of this stuff in the kOS mod, because it has to present the geometry of the game to the user in a way that lets them write scrips without having to delve into the weirdity of KSP's internal coordinate system. (Still an ongoing project because we haven't made the features to hide the fact that the universe switches between still-universe-rotating-planet mode and rotating-planet-still-universe mode depending on your altitude.)

https://github.com/KSP-KOS/KOS

I've had some experience with KSP's oddball coordinate system because of that project, not by choice but because we've had to delve into it in order to make the mod work. If you have any questions feel free to ask.

The first thing to remember is that the terminology "world coordinates" has nothing to do with the planet or moon. It doesn't mean "world" in that sense of the word. I would be better described as "universe coordinates". The reason it's called "world" coordinates is that it's terminology coming from the underlying Unity system, which chose to describe the entire XYZ universe with the word "world" - a term that makes sense if you're writing most sorts of games, but gets a bit misleading when writing a game in space with planets.

In Unity, "world" is used to differentiate from "local". i.e. the coordinates of this fuel tank relative to the entire scene Unity is rendering, versus the coordinates of this fuel tank relative to the ship it's part of.

"Scene" would probably have been a better word than "world", as it has a longstanding traditional meaning in 3d software as meaning "everything there is in the coord grid right now".

So GetWorldPos3D() is in fact getting the coordinates of the item in question relative to the whole rendered scene.

But to make sense of that you'd need to know where the origin of the scene actually is... and that's a big big mess because it moves. The origin of the scene is always *NEAR* the current vessel but not necessarily ON it. When you are on rails THEN the origin is exactly where the active vessel is, rigidly. But then when you come off of rails the vessel is allowed to drift away from the origin during the full-physics simulation. After you've been off of rails for a minute or so, the origin will typically be as much as 100 or 200 meters away from the active vessel.

If you want to know where one vessel is relative to another vessel, then you can ignore the moving origin problem and just do simple vector subtraction between the two positions. Call vessel 1's GetWorldPos3d() and vessel 2's GetWordPos3d() and subtract one vector from the other. That would give you the same consistent answer regardless of where the shared origin of those two positions is.

Scale: When in flight-camara mode (as opposed to map view mode) the grid is scaled so that 1 unit of math = 1 meter of space. When in map view mode the scale of the universe changes a lot for drawing on the screen, but the coordinates behind the scenes for other stuff are the same.

Rotation: This is a mess. To see a description of it, look here : http://ksp-kos.github.io/KOS_DOC/ref_frame/index.html and look at the part about the RAW rotation.

Link to comment
Share on other sites

Thank you much! The description of the math helps a lot to give me context to base my math.

I guess what I'm still confused on is how one accesses a particular vessel's (or celestial body's) methods? (And am assuming that GetWorldPos3d is, or is analagous to, an Object Method). Here's the lines of code (I'm writing a partmodule, so these are running inside of that)

        public override void OnUpdate()
{
Vessel current = vessel.GetVessel();
Vector3d position = current.GetWorldPos3d();
//maths happen here
}

Except whatever I'm doing isn't be recognized by either the IDE, or the compiler. However, when I compile with this replacement:

        public override void OnUpdate()
{
Vector3 position = transform.position;
//maths happen here
}

It compiles just fine (and runs in-game just fine as well), placed it on the context menu for the part), however, this is the position relative to the local frame (that travels with the spaceship to help prevent the Kraken, as I understand it from your post). So, onto my questions:

  1. How do I assign an object to my current vessel?
  2. How do I assign an object for some arbitrary vessel x?
  3. Corrollary to 2, how do I grab the object for a planet, say I want to do pointing math to Kerbin while in orbit around Jool?

For context, let's say in my persistence file I have two vessels:

VESSEL
{
pid = 591e5579d8dd4cca8ade75f7a66becc9
name = Jool Test Craft
type = Probe
sit = ORBITING
//more stuff here
}

and

VESSEL
{
pid = 53d2cbfd6a1d4f1682347b995e648ea1
name = Kerbin Test Craft
type = Probe
sit = ORBITING
//more stuff here
}

Do I need to reference any of that data to ID the craft, or is there a simpler way of doing this?

Thanks again for all your help, I'm very new to all of this.

Link to comment
Share on other sites

On rotation, it sounds like there isn't a 'world' rotation, or a quaternion that describes the vessel's rotation in world coordinates? That would be ideal, if it exists. (Crosses fingers for GetWorldQuat())

Link to comment
Share on other sites


public override void OnUpdate()
{
Vessel current = vessel.GetVessel();
Vector3d position = current.GetWorldPos3d();
//maths happen here
}

Except whatever I'm doing isn't be recognized by either the IDE, or the compiler.

'vessel' (lowercase) isn't a thing yet. You didn't declare it as a variable.

'Vessel' (uppercase) is the name of the Vessel class, and you could use it to call a static method without an instance of the class, but Vessel.GetVessel() isn't a static method so you can't do that.

You need to get a variable of type Vessel first. That's what you're missing. If the vessel you're interested in is the current active one (the one the cameras is looking at and which receives the control inputs from the keyboard), here's how you can get it:


Vessel curVessel = FlightGlobals.fetch.activeVessel();

After that you can do things like curVessel.GetWorldPos3d().

To get the vessel orientation as a quaternion, first get its Unity transform, for example:

Transform trans = curVessel.ReferenceTransform();

Now you can get the quaternion from calls into Unity.

Quaternion q = trans.rotation;

Edited by Steven Mading
Link to comment
Share on other sites

Wow, I am a dummy, I had assumed that grabbing a vessel would be in the Vessel class, but neglected to look at FlightGlobals. Thanks so much!

And that quaternion is from the world frame to the vessel frame (Oriented with the body of the vessel)? Or is it from the odd frame you were referencing in the kOS documentation you linked me to, to the vessel frame?

Link to comment
Share on other sites

Wow, I am a dummy, I had assumed that grabbing a vessel would be in the Vessel class, but neglected to look at FlightGlobals. Thanks so much!

And that quaternion is from the world frame to the vessel frame (Oriented with the body of the vessel)? Or is it from the odd frame you were referencing in the kOS documentation you linked me to, to the vessel frame?

I *think* it's from the odd world references. But then in principle it should be possible to get it relative to the vessel by combining the vessel rotation relative to world coords and the horizon rotation relative to world coords.

Link to comment
Share on other sites

Point of curiosity, when you say odd world references, is this reference frame oriented the same way as the 'World' reference frame? If so, that's quite convenient, as I only really care about the relative orientation to the position vector's frame.

Link to comment
Share on other sites

Yes. I consider the orientation of the world reference frame odd. When I say "odd world references" I mean "what KSP chose to tell Unity to use as the world coord system, which keeps changing orientation."

Link to comment
Share on other sites

Excellent, that's what I was hoping for. For the purposes of my math, it doesn't matter as long as they're both in reference to the same frame.

I do wonder what led them to have a seemingly arbitrarily oriented frame, though. The aerospace engineer in me would have set up a global frame centered on the sun (centerpoint of the universe), and had all the 'world' frames match that frame's orientation for simplicity. Ah well, I'm sure they had their reasons.

Link to comment
Share on other sites

Ah well, I'm sure they had their reasons.

Space Kraken.

The problem is that while centering the universe on the Sun is mathematically elegant, it's not so elegant when dealing with floating point representations of numbers in a computer which have a fixed limit to the number of significant digits they can represent. Because they're stored with a mantissa/exponent format, with a fixed number of significant digits in the mantissa, the precision gets worse the farther from zero the numbers are. At zero you have the ability to store the difference between 0.00000001 and 0.00000002 meters. But when those numbers get big and you're talking about a billion meters, then it's a problem that you don't have that precision anymore.

Trying to calculate whether or not your fuel tank has collided too hard into your command pod when the numbers you're using to perform the calculation have to be rounded to the nearest 10 centimeters or so tends to make your ship blow up. It tricks the system into thinking the part has suddenly moved really fast in a fraction of a second as it "snaps" to the next available number.

Thus ships used to just unfairly blow up when you started getting too far from the sun and the position values became less precise. Moving the origin of the universe to always be near the ship is how SQUAD fixed that problem.

The thing I don't understand is why the *rotation* of the axes had to be made to change all the time.

Link to comment
Share on other sites

Yeah, completely understand the rationale behind moving the origin. The floating point error symptoms still exist, actually, if you move your ship to the light-years scale. Due to floating point errors your orbit will vary wildly, though on the bright side you won't explode (as far as I've seen, anyway).

Agreed on the rotation of the axes. Either there's a reason they didn't orient them consistently, or it was just easier to deal with in the code this way.

To be fair, though, there are perfectly valid (non-inertial) reference frames that rotate their origins in a semi-organized fashion. LVLH is a pretty good one, mark your attitude relative to your current velocity and position vectors.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...