untoldwind / KontrolSystem2

Autopilot scripting system for KSP2
Other
54 stars 14 forks source link

Thrust Vector Frame Of Reference Confusion #128

Closed Calaverah closed 1 month ago

Calaverah commented 4 months ago

I'm attempting to use vessel.delta_v.stages[0].active_engines[0].get_thrust_vector() to control an asymmetrical engine. The goal is to gimble the engine so that the thrust vector points at the CoM of the vessel and calculate a directional offset for guidance (a good example is the space shuttle with the offset SSME's). However my issue is that I'm not understanding what frame of reference the thrust vector is using. It doesn't appear to be celestial frame of the main body like most default to (as it shouldn't), but I can't seem to work out where the origin is. Through testing, it seems as if the vector is rooted to the engine itself but if that were the case, I would imagine the initial unit vector would be something like [0,0,-1], but it's really more like [0.262, -0.01, -0.965]...

Furthermore is there a chance we can add the ability to control gimble angles/vectors on engines? Maybe the ability to read the vessel's total resultant thrust (vessel.get_thrust_angle)?

untoldwind commented 4 months ago

After some digging, the answer to you question is: get_thrust_vector is in PhysicsSpace. Which is not very helpful since I recently found out that (as of 0.2.x.x) physics space differs from the celestial frame of the main body.

So I added a coordinate system independent variant to get_thrust_vector and also added a thrust_direction to ModuleEngine

So this will work with in the next release:

use { Vessel, DeltaVSituation } from ksp::vessel
use { CONSOLE } from ksp::console

pub fn main_flight(vessel: Vessel) -> Result<Unit, string> = {
    CONSOLE.clear()

    const frame = vessel.body_frame

    for(engine in vessel.engines) {
        CONSOLE.print_line(engine.part_name)
        CONSOLE.print_line("   " + engine.global_thrust_direction.to_local(frame).to_fixed(2))
    }

    CONSOLE.print_line("In delta")
    for(engine in vessel.delta_v.stages[0].active_engines) {
        CONSOLE.print_line(engine.engine_module.part_name)
        CONSOLE.print_line("  " + engine.get_global_thrust_vector(DeltaVSituation.SeaLevel).to_local(frame).to_fixed(2))
    }
}

And here is my test vessel (which looks too hilarious to ignore):

image ... of course I had to launch it ... surprisingly enough it reached a height of about 170 meters

untoldwind commented 4 months ago

In 0.5.3.2 get_thrust_vector should be now in the celestial frame like everything else. And there is the additional coordinate independent variant.

Calaverah commented 4 months ago

Appreciate adding an alternative to going through DeltaV references ha.

I think for now the best way to control these gimbles is use single engine with PID through a COM -> engine location input on the YAW/Pitch override and just disable any control surfaces until there’s a way to directly control engine throttle/gimbles independently. (Assuming the engine location is the pivot point of the vector).

Calaverah commented 4 months ago

Whoops didn’t mean to close prematurely

untoldwind commented 4 months ago

I expanded the the engine bindings in 0.5.3.3 that should help with individual engine control: engine.independent_throttle_enabled set this to true to enable individual thrust for that engine (same as checking the box in the UI. engine.independent_throttle set this to the desired throttle of that engine (0.0 - 1.0)

Note: If you add multiple engines to the vessel via the symmetry tool in the VAB all these engines are somehow bound to each other an can not be controlled individually (most likely a glitch in the game). To support individual throttle each engine has to be added one by one.

Additionally I added an optional engine.gimbal which is only defined for engines that actually have a gimbal (e.g. the Dart engine does not have one). Setting engine.gimbal.enabled to false with disable the gimbal for the regular flight controls (i.e. will make it individually controllable). Inside the script the gimbal could be set via engine.gimbal.pitch_yaw_roll (which would be the same as the corresponding flight controls). ... it would be nice to set the gimbal direction more directly, but I am still figuring out how the internal transformations are working.

Here is a little test-script that does not do much more than demonstrate the basic functionality:

use { Vessel, DeltaVSituation } from ksp::vessel
use { CONSOLE } from ksp::console
use { CONSOLE_WINDOW } from ksp::ui
use { vec3 } from ksp::math
use { sleep } from ksp::game

pub fn main_flight(vessel: Vessel) -> Result<Unit, string> = {
    CONSOLE.clear()

    const frame = vessel.body_frame

    for(engine in vessel.engines) {
        CONSOLE.print_line(engine.part_name)
        CONSOLE.print_line("   " + engine.global_thrust_direction.to_local(frame).to_fixed(2))
        CONSOLE.print_line("   " + engine.is_gimbal.to_string())
        engine.independent_throttle_enabled = true
        if(Some(gimbal) = engine.gimbal) {
            gimbal.enabled = false
        }
    }

    for(engine in vessel.engines) {
        if(Some(gimbal) = engine.gimbal) {
            engine.independent_throttle = 0.02
            CONSOLE.print_line("Moving " + engine.part_name)
            for(i in 0..10) {
                gimbal.pitch_yaw_roll = vec3(0.1 * i, 0.0, 0.0)
                sleep(0.5)
                CONSOLE.print_line(">>> " + engine.global_thrust_direction.to_local(frame).to_fixed(5))
            }
        }
    }
}
github-actions[bot] commented 2 months ago

This issue is stale because it has been open for 60 days with no activity.

github-actions[bot] commented 1 month ago

This issue was closed because it has been inactive for 14 days since being marked as stale.