KSP-KOS / KOS

Fully programmable autopilot mod for KSP. Originally By Nivekk
Other
697 stars 230 forks source link

vector/direction conversion routines #106

Open Dunbaratu opened 10 years ago

Dunbaratu commented 10 years ago

(This is mostly a to-do list for myself. I'd like to implement these.)

Doing docking operations (and other stuff) would be a lot easier if the system supported conversions and applications of vectors with rotation directions.

Apply a rotation to a vector V(100,0,0) + R(45,0,0) should return a vector equal to the original vector rotated 45 degrees.

Convert to and from vectors and rotations: Either with a pair of function calls or with suffixes. (i.e. make the :vector of a Direction always work by calculating a unit vector in that direction, and make a vector have a suffix of :direction that returns a R() direction in the direction of the vector). (problem: have to decide what default to pick for the "lost" information of roll direction with the conversion).

marianoapp commented 10 years ago

Should we also include functions to change vectors/rotations between the global frame of reference and the local one? Not that is too difficult to do it now, but it requires calculating the unit vectors and then a dot product which can be a bit too much for a beginner.

Dunbaratu commented 10 years ago

What is the global frame of reference you had in mind? "global" in its computer meaning as "the same everywhere" or as in geography: "the globe - the SOI Body"..

There sort of isn't a global (in the computer sense) coordinate system in KSP. The world coordinate system is ever changing.

marianoapp commented 10 years ago

What I meant was to be able to convert from the KSP coordinate system (XYZ, whatever its origin may be) to a "local" frame of reference centered in the vessel (on the surface this would be expressed as North, East and Up). As I said its already possible to do this with some vector math, but that is not too beginner friendly.

The same with rotations, the way they are expressed now makes them difficult to understand and work with. For example a direction expressed in the current system is a lot harder to grasp than if it were expressed in degrees from north and elevation.

I know that once you are in space the coordinates origin moves near your ship, so my suggestion would really apply when on the surface / lower atmosphere. And of course we have to try our best to hide the coordinate system change as much as we can.

Dunbaratu commented 10 years ago

I'd still like the coordinates that are soi body-related to be something you can convert into but are not the universal for everything - because they move too much are are not static. the positions of things already are being translated to a ship-origin system, but aren't being rotated to a navball-oriented system.

I'd like there to be a vector suffix for coordinate system like this:

set v to ship:velocity:orbit. print "raw velocity is: " + v. print "lat/long/alt velocity is: " + v:geocoord. // gives velocity where x=latitude, y=longitude, z=altitude. set p to ship:position. print "raw ship position is: " + p. // gives v(0,0,0) because default coords are ship-centered. print "lat/long/alt position:" + p:geocoord. // gives position relative to body in latitude, longitude, altitude.

Dunbaratu commented 10 years ago

@marianoapp and @erendrake - what do you think of this proposal?

First off, as I thought about this more and contemplated how to make the syntax look to the user, it became hard to hide the complexity from the user unless we make our vector and rotation objects smarter and aware of what frame of reference they're stored in. If we don't store the frame of reference in the vector objects, then we end up making the user have to remember it and understand which routines expect the directions and vectors in which reference frame.

This could be a complex large change affecting a lot of little bits of code, but might be worth it to make things more sane to the user.

Okay, with that aside, let me explain it:

( * ) - In all the above cases where I say "vessel", what I mean is not neccessarily the ActiveVessel, but rather the vessel containing the kOS CPU part that is running the code. A bit of code running on a vessel that is within 2.5 km and thus loaded, but not the current vessel, needs to see things relative to its OWN position, not the vessel the camera is looking at. Otherwise moving the camera to the next vessel with '[' or ']' will change how the code steers the vessel that was just left from.

Okay, with that aside, here's some code snippet examples I'm picturing that all that work would allow users to do:

// Getter examples:
set vel to ship:velocity:orbit.
print vel:REFFRAME. // result "REFFRAME("RAW")".
print "I am drifting northward at " + vel:GEO:x + " meters per second.".
print "I am drifting in my pointing direction at " + vel:SHIP:z + "meters per second.".
set vel to vel:GEO.
print "vel in geo coords is: " + vel. // prints some set of numbers.
lock steering to (-1)*vel.  // result same as locking to retrograde.
set vel to vel:RAW.
print "vel in ship coords is: " + vel. // prints a *different* set of numbers than before.
lock steering to (-1)*vel.  // result: NO CHANGE to steering because even though vel
                             // is in a different frame of reference from before. it *knows* that
                             // and can return the raw reference version of itself, and steering knows
                             // to ask the vector for its raw version before trying
                             // to interact with the KSP API.

// Setter examples:

// When you assign to the raw variable name, you
// are asking kOS to keep the same reference frame in the new value
set pos2 to pos.  

// When you DO assign to a suffix in the assignment statement, you are asking kOS to perform a reference frame conversion for you, like these examples:
set pos:RAW to V(200,0,0).  // pos is now pointing at a spot 200 meters in KSP's raw X-axis direction.
set pos:SHIP to V(200,0,0).  // pos is now pointing at a spot 200 meters to the ship's left.
set pos:GEO to V(200,0,0).  // pos is now pointing at a spot 200 meters north of the ship.

set pos:SHIP to V(200,0,0).
print "200 meters to my left is this in raw coords: " + pos:RAW.

// Does not change pos, but changes what reference frame it uses to express itself:
set pos to pos:RAW.
erendrake commented 9 years ago

@Dunbaratu it looks like most of this is done but there is still a bit to do. I think we should break down the rest into some new tickets.

abenkovskii commented 9 years ago

Can some of this features be implemented in the KSLib instead?

Dunbaratu commented 9 years ago

@abenkovskii Not the way it was suggested, where vectors have methods for changing context. First we'd have to make the library capable of more object-oriented code style, which in current kOS it really can't.

I am unsure whether to leave this open or not. It's not implemented, but it's unlikely to be addressed any time soon. There's other stuff on the more nearby to-do list.