Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transfer into a target orbit? #28

Open
mathuin opened this issue Feb 5, 2018 · 4 comments
Open

Transfer into a target orbit? #28

mathuin opened this issue Feb 5, 2018 · 4 comments

Comments

@mathuin
Copy link
Collaborator

mathuin commented Feb 5, 2018

Right now when I send a scanner to a moon, I use the transfer script to end up in a low equatorial orbit, then elevate my orbit, then change the inclination. When I fly these "by hand", I use the transfer injection braking burn to place the initial periapsis at the right altitude in the right inclination (or close to it on both marks) which uses a lot less fuel. How hard is it to do this from within the transfer script?

@xeger
Copy link
Owner

xeger commented Feb 7, 2018

Choosing the right initial periapsis shouldn't be too hard; IIRC, we already have a correction factor in place to make sure we don't rendezvous into the target body. It's a matter of letting the user ask for a specific periapsis distance with an optional parameter.

Choosing a specific inclination is probably going to be substantially more difficult. At the very least, if node_hoh lets me choose an apsis then it should also let me choose a direction of spin around the target body -- which is a very coarse way to choose an inclination, if you think about it. That can be done as part of the correction step, e.g. if I'm transferring "up" to Mun and I want to insert counterclockwise, then I add dv so that instead of encountering Mun's center of mass, I encounter a point that is radially "outward" with respect to Kerbin -- once I get to that encounter, I decelarate to insert. If instead I wanted clockwise insertion I'd subtract that same amount of dv.

Worst case, you could always perform a midcourse correction, i.e. immediately after your Mun encounter begins you could change inclination, possibly even by calling the existing node_inc_equ script from inside the transfer script. (Fair warning that @firda-cze has some impending changes to the inclination-change script; when I test his changes, I'll include some hyperbolic orbits to see how it behaves. My suspicion is that the current script would not work well for a hyperbolic since it was written with the assumption of an initial circular orbit!)

@ghost
Copy link

ghost commented Feb 7, 2018

I will look into the transfers after I am satisfied with the inclination scripts (and the current really don't work in many cases, especially for higher eccentricity). That is a good start to get used to the utilDtTrue and all the orbital mechanics I have learned in last few days.

I didn't think about hyperbolic orbits so far and it won't be so easy, because kOS terminates whenever seeing infinity or NaN (with default settings). I will at least add eccentricity checks to print understandable message if I cannot find proper solution.

I plan to add some fine tuning to hohmann (maybe something iterative immitating what I am usually doing manually) including inclination correction for Minmus transfer (I usually burn in normal direction when passing Mun's orbit). It could be better to wait a bit in order to meet Minmus at AN/DN nodes, but that won't work well for Life Support mods (I use USI myself).

P.S.: Did you watch Falcon Heavy yesterday? Amazing!

@xeger
Copy link
Owner

xeger commented Feb 8, 2018

Yes indeed! The synchronized landing of the side boosters was beautiful. It's nice to be excited about space again.

The mock transfer injection burn? Not so amazing. But nobody gets it right on the first try, as we kOS coders know. :-)

Regarding change of inclination during transfer, MechJeb uses the same technique as @firda-cze: wait until halfway to encounter, then perform a course-correction burn to fix inclination as well as deal with any error in the encounter apsis. If you decide to pursue an analytical solution, I'd probably begin by reading their source code.

@ghost
Copy link

ghost commented Feb 19, 2018

I have started by cleaning node_hoh and implementing the direct calculation of dt,
it should not be a big problem to reduce r2 for final dv calculation, to end with desired prograde orbit.
Would be a bit harder for retrograde.

@xeger What do you think about this direct approach? (See the line local k is (mt*ar - ma)/360.) Didn't fail me so far.

// Delta vee math stolen from http://en.wikipedia.org/wiki/Hohmann_transfer_orbit#Calculation
// Phase angle math stolen from https://docs.google.com/document/d/1IX6ykVb0xifBrB4BRFDpqPO6kjYiLvOcEo3zwmZL0sQ/edit and here https://forum.kerbalspaceprogram.com/index.php?/topic/122685-how-to-calculate-a-rendezvous/ and from here too https://forum.kerbalspaceprogram.com/index.php?/topic/85285-phase-angle-calculation-for-kos/

runoncepath("lib_ui").
runoncepath("lib_util").

if body <> target:body
	uiFatal("Node", "Incompatible orbits").
if orbit:eccentricity > 0.01
	uiWarning("Node", "Eccentric ship e=" + round(ship:obt:eccentricity, 1)).
if target:obt:eccentricity > 0.01
	uiWarning("Node", "Eccentric target e=" +  + round(target:obt:eccentricity, 1)).

local ri is orbit:inclination - target:orbit:inclination.
if abs(ri) > 0.2
	uiWarning("Node", "Inclination difference ri=" + round(ri, 1)).

utilRemoveNodes().

// Compute prograde delta-vee required to achieve Hohmann transfer
// negative means retrograde burn.
local function hohDv {
  parameter r1 is orbit:semimajoraxis.
  parameter r2 is target:orbit:semimajoraxis.
  return sqrt(body:mu/r1) * (sqrt((2*r2)/(r1+r2)) - 1).
}

local r1 is   ship:orbit:semiMajorAxis.
local r2 is target:orbit:semiMajorAxis.
local pt is 0.5 * ((r1+r2) / (2*r2))^1.5.
local ft is pt - floor(pt).
// angular distance that target will travel during transfer (if circular)
local theta is 360 * ft.
// angles to universal reference direction
local sa is   ship:orbit:lan + ship:orbit:argumentOfPeriapsis + ship:orbit:trueAnomaly. 
local ta is target:orbit:lan+target:orbit:argumentOfPeriapsis+target:orbit:trueAnomaly. 
local t0 is time:seconds.
// match angle (+k*360)
local ma is utilAngleTo360(ta+theta-sa-180).
// angle change rate (inaccurate for eccentric orbits but good for a start)
local ar is 360/ship:orbit:period - 360/target:orbit:period.
// estimated burn time
local dv is hohDv().
local mt is 5+.5*dv*ship:mass/max(0.1,ship:availableThrust).
// k closest to zero such that (ma + k*360)/ar >= mt
local k is (mt*ar - ma)/360.
// closest integer
if ar < 0 set k to floor(k).
else set k to ceiling(k).
// time to node (exact if both orbits are perfectly circular)
local dt is (ma+k*360)/ar.
// add node
set t1 to t0+dt.
local nd is node(t1, 0, 0, dv).
add nd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants