untoldwind / KontrolSystem2

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

Request for GeoCoordinates #132

Closed PhilouDS closed 1 month ago

PhilouDS commented 3 months ago

Hi,

in KSP::Orbit::GeoCoordinates, is it possible to add the following please?

Thanks :)

untoldwind commented 3 months ago

The first is already possible via the celestial body:

As for bearing and distance: The GeoCoordinate already has information about the surface normal, terrain_height and functions to get the position at a given altitude (above sea-level ... I will improve the documentation a bit) ... so calculating the bearing and distance between to geo-coordinates should be simple:

PhilouDS commented 3 months ago

Ok. I admit I check my scripts written with kOS for KSP1 and I saw I used bearing and distance. That's why I asked. Thanks for your answer.

PhilouDS commented 3 months ago

I have what I want for the distance. For the bearing, I'm not sure I have understood how it works. The code below doesn't give me what I want. I'm testing this with a plane landed at runway 09L and I want the bearing to the runway 27R.

use { CONSOLE } from ksp::console
use { CONSOLE_WINDOW } from ksp::ui
use { Vessel } from ksp::vessel
use { Body, GeoCoordinates } from ksp::orbit
use { Vec3, vec2 } from ksp::math
use { yield } from ksp::game
use { format } from core::str

pub fn main_flight(vessel: Vessel) -> Unit = {

  CONSOLE.clear()

  CONSOLE_WINDOW.open()
  CONSOLE_WINDOW.size = vec2(500,600)

  const body = vessel.main_body

  // runway 27R
  const rw_coord = body.geo_coordinates(-0.62737558144645, -74.7654563642046)

  while (true) {
  let vessel_coord = vessel.geo_coordinates
    let dist = distance_from_vessel(vessel, rw_coord)
    let brg = bearing(vessel, rw_coord)

  CONSOLE.print_at(0,0, format("Distance = {0:N2} m   ", dist))
  CONSOLE.print_at(1,0, format("Bearing = {0:N2}°   ", brg))

  yield()
  }
}

fn distance_from_vessel(vessel: Vessel, geo_position: GeoCoordinates) -> float = {
  const body = vessel.main_body
  const vessel_vec = body.surface_position(vessel.geo_coordinates.latitude, vessel.geo_coordinates.longitude, vessel.geo_coordinates.terrain_height)
  const geo_vec = body.surface_position(geo_position.latitude, geo_position.longitude, geo_position.terrain_height)

  return vessel_vec.distance_to(geo_vec)
}

fn bearing(vessel: Vessel, target_position: GeoCoordinates) -> float = {
  const vessel_geo = vessel.geo_coordinates
  const vec_bearing = bearing_vec_between_geo(vessel_geo, target_position)
  return vessel.north.angle_to(vec_bearing)
}

fn bearing_vec_between_geo(current_position: GeoCoordinates, target_position: GeoCoordinates) -> Vec3 = {
  const body = current_position.body
  const surfPosition1 = body.surface_position(current_position.latitude, current_position.longitude, current_position.terrain_height)
  const surfNormal1 = current_position.surface_normal
  const geo_vec = surfNormal1.exclude_from(surfPosition1)
  const geovec2 = body.surface_position(target_position.latitude, target_position.longitude, target_position.terrain_height)
  return (geo_vec - geovec2)
}
untoldwind commented 3 months ago

I just realized that there was a coordinate system mixup in body.surface_position which should be fixed in 0.5.4.1

Here is a little test program I used with a rover on the runway:

use { Vessel } from ksp::vessel
use { CONSOLE } from ksp::console
use { sleep } from ksp::game
use { atan2_deg, acos } from core::math

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

    while(true) {
        const frame = vessel.main_body.celestial_frame
        const target_geo = vessel.main_body.geo_coordinates(-0.6, -75)
        const current_geo = vessel.geo_coordinates
        const current_pos = current_geo.altitude_position(current_geo.terrain_height)
        const target_pos = target_geo.altitude_position(target_geo.terrain_height)
        const target_vector = target_pos - current_pos
        const bearing_vector = current_geo.surface_normal.exclude_from(target_vector.normalized)

        const forward = vessel.facing.vector
        const right = vessel.facing.right_vector

        const bearing = atan2_deg(bearing_vector * right, bearing_vector * forward)
        const dist1 = target_vector.magnitude
        const dist2 = vessel.main_body.radius * acos(current_geo.surface_normal * target_geo.surface_normal)

        CONSOLE.print_at(4, 0, " " + current_geo.latitude.to_fixed(5) + " " + current_geo.longitude.to_fixed(5))
        CONSOLE.print_at(5, 0, " "  + bearing.to_fixed(2) + " " + dist1.to_fixed(2) + " " + dist2.to_fixed(2))
        sleep(0.5)
    }
}

Replacing .altitude_position with .global_altitude_position and .surface_normal with .global_surface_normal should now produce the same results

github-actions[bot] commented 1 month 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.