Jump to content

[1.8.1 - 1.12.5] RSVP - kOS library for scripted interplanetary transfers and vessel rendezvous


ManEatingApe

Recommended Posts

RSVP

RSVP is a kOS library that finds orbital launch windows then creates maneuver nodes to make the transfer. The acronym stands for "Rendezvous s’il vous plaît", a playful pun on the regular meaning of the phrase.

This library enables players to make automated low delta-v transfers between two planets or vessels in-game, either directly from their own kOS scripts or from the kOS console. It provides a script-able alternative to existing tools, such as the excellent web based Launch Window Planner or the snazzy MechJeb Maneuver Planner.

Features

  • Integrates with your kOS scripts.
  • Creates departure and arrival maneuver nodes.
  • Supports rendezvous between vessels, planets, moons, asteroids and comets.
  • Adapts to planetary packs such as Galileo's Planet Pack, Outer Planets Mods and JNSQ.

See these features in action:

Links

Quickstart

  1. Acquire latest version of rsvp.zip from download link.
  2. Unzip into <KSP install location>/Ships/Script directory. This step adds the library to the kOS archive volume, making it available to all vessels.
  3. Launch a craft into a stable orbit of Kerbin.
  4. Run this script from the craft:
    set config:ipu to 2000.
    runoncepath("0:/rsvp/main.ks").
    local options is lexicon("create_maneuver_nodes", "both", "verbose", true).
    rsvp:goto(duna, options).

    This will find the next transfer window from Kerbin to Duna then create the corresponding maneuver nodes necessary to make the journey.
    Additionally it will print details to the console during the search.

Edited by ManEatingApe
Link to comment
Share on other sites

Released Version 2. First bugfix, first new feature and first technical improvement.

New Features

  • Add cleanup_maneuver_nodes option. Enabled by default, this will delete any maneuver nodes created if any problem occurs when creating the transfer, in order to leave a clean slate for the next attempt.

Bug Fixes

  • Fix issue search.ks fails when time:seconds > 2^31. The kOS range expression expects values to fit within a signed 32 bit integer. This caused the script to break when run on save games with a universal time greater than 2³¹ seconds or about 233 years. Replaced the range expression with a from loop as a straightforward workaround.

Technical Improvements

  • Calculate the time at destination periapsis (used when creating the arrival node) directly from Keplerian orbital parameters of the intercept patch. This is more efficient and accurate than the previous approach, which used a line search to find the closest approach distance by trying different times.
Edited by ManEatingApe
Link to comment
Share on other sites

Released Version 3. Improve handling of objects on hyperbolic orbits.

Technical Improvements

  • Use different strategy when calculating default search_duration, max_time_of_flight and search_interval values for a destination with a hyperbolic orbit, for example an asteroid or comet. This change prevents a Tried to push Infinity onto the stack error that occurred because the approach used for planets assumes an elliptical orbit with a finite orbital period.
Edited by ManEatingApe
Link to comment
Share on other sites

Released Version 4. Support .ksm compiled files.

New Features

  • Implement issue Running other files should not include extension. Add ability to use more compact compiled version of the source on craft that have limited volume space. Compiled files take about 20% of the space of the raw source, resulting in a significant space savings.
  • Add compile_to convenience function that compiles the source to a user-specified destination, for example a kOS processor hard drive.
Edited by ManEatingApe
Link to comment
Share on other sites

43 minutes ago, Muetdhiver said:

Any chance to couple such a thing to a python based flyby sequence finder or triple impulse transfer solver ?

Those are some interesting use-cases! If all you need is a Lambert solver, then the code in lambert.ks is completely general and has no KSP/kOS specifics, so it should be relatively straightforward to port to Python.

How wedded are you to Python? The reason I ask is that's there are some advantages to staying within the kOS ecosystem. Kerboscript is a neat flexible functional language.

Kerboscript pros:

  • Leverage existing RSVP code
  • Use built-in kOS functions for vessel and celestial body position and velocity
    (no need to copy orbital parameters back and forth, then use an external Kepler solver)
    Would also adapt to any planet pack mods "for free" with no extra effort, for example GPP, RSS, JNSQ.
  • Users have access to the tool "in-game" as they fly missions.

Python pros:

  • Faster execution
  • Access to the entire Python library ecosystem
Link to comment
Share on other sites

I'm using the the pygmo library from ESA to tackle problems beyond the scope of lambert. For example finding moho transfers with multiple assists, which is immensly expensive w.o. high quality search algorithms.

I will meditate on it for a few days. I might come up with some ideas.

Link to comment
Share on other sites

Released Version 5.

Bug Fixes

Technical Improvements

  • Add build_documentation Github Action that creates documentation in the same format as kOS. On any change to the doc folder, this action will automatically run the Sphinx generator to convert raw .rst text files to HTML, then publish the changes to Github Pages. This keeps a clean separation in the repository between the raw source files and the generated output.
Link to comment
Share on other sites

  • 3 weeks later...

Released Version 6.

New Features

This release adds a new mathematical approach to refining transfers when the ratio of the destination SOI to Periapsis exceeds a threshold. This fixes 2 issues:

  • Transfers to larger moons (especially in the Jool system) are much less likely to go astray.
  • Polar orbit orientation when travelling to Mun or Ike no longer results in huge delta-v values.

The new approach is based on the paper A new method of patched-conic for interplanetary orbit by Jin Li, Jianhui Zhao and Fan Li.

Given a velocity vector at SOI boundary, periapsis altitude and inclination, this approach calculates the position vector that satisifies these contraints. This position vector is combined in a feedback loop with the Lambert solver to refine the initial estimate from one that only considers planets as points to one that takes the SOI spheres into account. This removes the need both for the impact_parameter function and the line search algorithm simplifying the vessel-to-body case. The body-to-body case also simplifies into a single step instead of two.

For vessels and planets with a SOI to Periapsis ratio of less than 1% the existing strategy is used. This strategy considers the planets as a zero-width point on the assumption that over large distance only small adjustments will be need to the predicted transfer.

However some bodies in KSP have extremely large SOI to Periapsis ratios, for example Ike (38%), Mun (23%) and Tylo (17%). For transfers to and from these bodies, the SOI sphere needs to be taken into account when finding the lowest cost transfer. The offset_from_soi_edge and duration_from_soi_edge function in orbit.ks predict the time and position where a craft will exit/enter SOI.

Interestingly another challenge with very large SOI to Periapsis ratios is that the minimum escape velocity can be higher than the desired transfer. For example a direct Hohmann transfer from Laythe to Vall is impossible, as the minmum escape velocity from Laythe is higher than the velocity required. The search algorithm now supports a minimum value for deltav, making this type of transfer possible.

Bug Fixes

  • Fix calculation of periapis time when insertion orbit is mathematically elliptical. Insertion manuever node will now be placed in the correct location.
  • Fix bug in a guard clause in the Lambert solver that was throwing NaN exception is certain situations.

Technical Improvements

  • Add validation check to final_orbit_periapsis option to ensure that supplied value is within SOI radius of destination.
  • Refactor maneuver related code from orbit.ks to maneuver.ks.
Link to comment
Share on other sites

  • 1 year later...

Hello! I've been using RSVP in stock KSP for a while now and it's been working great. However, I recently switched over to Galileo's Planet Pack and now RSVP is running much, much faster when searching for interplanetary transfer windows, but it finds a lot fewer of those windows. I wasn't really expecting a search with a maximum duration of 500 days to find fewer than 10 transfer windows to certain planets in the outskirts of the solar system as in stock similar searches would not only take a lot long (tens instead of single-digit minutes) and I'm curious if you can think of why this would be the case.

Maybe it's just the layout of the solar system (I've tried JNSQ but can't remember noticing this), but I just wanted to make sure. :)

Link to comment
Share on other sites

9 hours ago, Black-Two- said:

Hello! I've been using RSVP in stock KSP for a while now and it's been working great.

Delighted to hear it!

9 hours ago, Black-Two- said:

However, I recently switched over to Galileo's Planet Pack and now RSVP is running much, much faster when searching for interplanetary transfer windows, but it finds a lot fewer of those windows. I wasn't really expecting a search with a maximum duration of 500 days to find fewer than 10 transfer windows to certain planets in the outskirts of the solar system as in stock similar searches would not only take a lot long (tens instead of single-digit minutes) and I'm curious if you can think of why this would be the case.

Maybe it's just the layout of the solar system (I've tried JNSQ but can't remember noticing this), but I just wanted to make sure. :)

Hmm...the default search parameters could need tweaking to better suit GPP. If you upload a copy of your save file and the transfer(s) you're attempting,  I can take a look.

Link to comment
Share on other sites

Right, so I think I have everything set up. There are two test vessels orbiting Gael. Test-1 is in a 100x100km orbit with an inclination of 8.3 degrees. A pretty standard launch orbit for GPP. Test-0 is in a 500x500km orbit with no inclination. I launched this after just to be absolutely sure inclination wasn't an issue.

I've tested Iota, Niven and Tellumo. Iota is the closest moon, and Niven and Tellumo are the nearest planets inside and outside Gael's orbit respectively. For reference, current date is year 9, day 92. Here are some trials runs I ran just to make sure.

Test-0 Iota: Starts slowly (doesn't anything for some seconds), then seems normal, stops at day 115 which corresponds with Iota's orbital period.
Test-0 Niven: Finishes completely in a few seconds, and only prints out six times at day 92, 230, 368, (new year,) 81, 219, 358. It does find a very good transfer though.
Test-0 Tellumo: Takes a few seconds to start, but is faster than Iota. It's then pretty similar to Niven.

Test-1 Iota: Runs very quickly, to the point where I went back to Test-0 to see if it was still slow (it was). The final maneuver is not very good though, as it has rather substantial radial and normal values, and it drops the periapsis into the atmosphere.
Test-1 Niven: Again, runs very quickly, and again only prints six times. The maneuver is worse, but this is probably due to the inclined orbit.
Test-1 Tellumo: Runs slower than the other two, but is other than that very similar to the Niven run with few prints and a pretty bad maneuver.

The Iota tests are pretty much what I'm used to from stock (lots of prints, sometimes faster or slower) but the Niven and Tellumo ones are the ones I wondering about. Here's the save file: https://www.dropbox.com/s/0vjeatjv397pntt/GPPrsvptest.zip?dl=0

Here's the code, just in case the script isn't saved. I use a different script when actually playing, but it's really just this plus a nifty little way to input a new maximum search duration in the terminal. Both scripts have the same issue. Config:ipu is 2000.

parameter dest.

runoncepath("0:/rsvp/main").
local options is lexicon("create_maneuver_nodes", "first", "verbose", true).
rsvp:goto(dest, options).

Edit: I don't use part mods other than kOS but let me know if you need a modlist as well. :)

Edited by Black-Two-
Link to comment
Share on other sites

Hey @Black-Two- thanks for the save file. I have setup:

  • Clean install of KSP 1.12.2
  • GPP 1.6.7
  • kOS 1.3.2
  • RSVP v6
  • Your save file "Abyss of the Void" (love the name!)

Reading your post, looks like the items to investigate are:

  1. Discrepancy in search duration when searching transfer from Test-0 to Iota (takes a while) vs searching for a transfer to Niven/Tellumo (quick)
  2. Long pause between starting script and seeing any output.
  3. Bad transfer from Test-1 to Iota
  4. Higher delta-v from Test-1 to Niven/Tellumo than with Test-0
     
Link to comment
Share on other sites

Let's start with item 1:

1 minute ago, ManEatingApe said:

Discrepancy in search duration when searching transfer from Test-0 to Iota (takes a while) vs searching for a transfer to Niven/Tellumo (quick)

RSVP's default search parameters are very conservative. The intention is to always find the best (lowest dV) transfer with the tradeoff of using extra time when performing the search.

The default search period is the maximum of either the synodic period between the two bodies or the sidereal orbital period . The synodic period is defined as the period for the phase angle between the 2 bodies to repeat. This period covers every possible relative orientation of the 2 bodies. Here's the relevant code line:
https://github.com/maneatingape/rsvp/blob/master/src/search.ks#L36

The search interval is smaller than the search period and is how often RSVP begins a new search using its hill climbing algorithm. The default search interval is half of the minimum orbital period. Relevant code line:
https://github.com/maneatingape/rsvp/blob/master/src/search.ks#L59

Here's a table of the 3 transfers from Test-0

Destination Search Period (s) Search Interval (s) Ratio
Tellumo 18625942 4600800 4
Niven 17061136 2988830 5.7
Iota 495456 1792 276

Note that the search interval used is half the orbital period of Gael when going to Tellumo/Niven, but half the orbital period of Test-0 when going to Iota. The default parameters work well for the planet to planet case and I was able to reproduce the decent transfers that you found.

Now we can see why the Iota transfer search is so much slower than the others. So the question isn't why the Niven/Tellumo transfers are so fast (they seem fine) but what can we do to speed up the transfer search between Test-0 and Iota.

One suggestion is to use the knowledge that Test-0 and Iota are in co-planar orbits. So a single orbit of Test-0 will cover all possible scenarios. Test-0 has an orbital period of ~30 min, so I changed the parameters to

local options is lexicon(
  "search_duration", 30 * 60,
  "search_interval", 0.25 * 30 * 60,
  "create_maneuver_nodes", "first",
  "verbose", true).


This found a decent transfer in a fraction of the time.

I'll investigate item 2 next.

Link to comment
Share on other sites

On 11/18/2021 at 9:46 PM, ManEatingApe said:

2. Long pause between starting script and seeing any output.

@Black-Two- Nice find, this was an interesting issue to investigate! The long pause was caused by the very first pork chop search taking many more iterations than subsequent searches. The root cause was that the search period was very much less than the time of flight. RSVP uses the search period to determine the size of the "step" used when searching.

A visual example should help. The search period is on the x-axis and the time of flight is on the y-axis.  A planet to planet transfer (for example Gael to Niven) has a reasonably square aspect ratio. As width and height are matched, the step size is a good choice for both horizontal and vertical steps.

YJt4Psu.png
Here's an example with a more skewed 1:3 ratio. (the actual ratio of Test-0 to Iota was even more extreme at 103). We can see that the step size is still fine in the horizontal direction but too small in the vertical direction, resulting in extra steps.

RWYLwq8.png
Now that the problem is clear the fix is straightforward - scale the horizontal and vertical steps independently. With a larger vertical step the ratio is effectively square once again and the search time improves.

FiyjeOw.png

Here's the details from your provided save:

c2DfqF0.png

The Test-0/Iota case is 55% faster. The Niven/Tellumo duration remained around the same. Delta-V was the same except for 2 cases that were a bit higher.

Edited by ManEatingApe
Link to comment
Share on other sites

Hey there,  I ran into a different problem.

https://imgur.com/a/jvbkGbK

I have a craft in a very eccentric orbit of Gratian, wanting to get to Geminus, Gratian's moon. Ten days (day 78 is today) into a search I get the error above. It looks like cos_E is greater than 1 and sin_E then tries to get the square root of a negative number. Here's a save: https://www.dropbox.com/s/8x14sqaz1ug8t7n/GPPrsvpgratian.zip?dl=0

Link to comment
Share on other sites

@Black-Two- Let's take a look at the next two issues.

 

On 11/18/2021 at 9:46 PM, ManEatingApe said:

3. Bad transfer from Test-1 to Iota

Test-1 is in an inclined orbit around Gael. By default RVSP assumes that you want to inject into a prograde orbit at 0°  inclination.
This is causing it to "force" the 1st node at the cost of extra delta-v, essentially trying to hammer a square peg into a round hole.

The tweak is to change the desired final orbit type to polar. Relaxing this constraint allows RSVP to find a much better transfer. Here's a table of results:

Settings Delta-V
Manual testing (not using RSVP) 888 m/s
Default RSVP settings 1184 m/s
"final_orbit_orientation", "polar" 902 m/s

 

On 11/18/2021 at 9:46 PM, ManEatingApe said:

4. Higher delta-v from Test-1 to Niven/Tellumo than with Test-0

In general, transferring from an inclined orbit around one planet to another is going to cost more delta-v than launching from an equatorial orbit at 0°  inclination.
RSVP usually finds the transfer that intersects the destination planet at its ascending/descending node which tends to be optimal.

Using the velocity in the inclined orbit required precise timing on the maneuver node to depart at exactly the right time. Any offset from this time is harmful, as the manuever node delta-v is fighting against the inclination velocity.

That said, RSVP doesn't blindly create maneuver nodes at the exact time returned by the hill climb search. It adjusts them based on the ship's orbit to find the very best time possible. You can see the implementation in the "create_maneuver_node_in_correct_location" function (no prizes for guessing what that does :D)
https://github.com/maneatingape/rsvp/blob/master/src/transfer.ks#L285

(Interesting implementation detail: This uses the same code as the 2 dimensional pork chop hill climb, but restricted to 1 dimenstion).

Edited by ManEatingApe
Link to comment
Share on other sites

5 hours ago, Black-Two- said:

Hey there,  I ran into a different problem.

I have a craft in a very eccentric orbit of Gratian, wanting to get to Geminus, Gratian's moon. Ten days (day 78 is today) into a search I get the error above. It looks like cos_E is greater than 1 and sin_E then tries to get the square root of a negative number. Here's a save: https://www.dropbox.com/s/8x14sqaz1ug8t7n/GPPrsvpgratian.zip?dl=0

Ah, that's a good one!

I tried the save file but could find no craft in orbit of Gratian. There's also a bunch of missing part errors (I don't have the same mods)

Would you mind uploading the save again - with only the craft in question, with only stock parts (you can use the debug menu to rendezvous a dummy craft to the same orbit).

Link to comment
Share on other sites

12 hours ago, ManEatingApe said:

I tried the save file but could find no craft in orbit of Gratian. There's also a bunch of missing part errors (I don't have the same mods)

That's really weird. Pod-R at the bottom of the list in the tracking station shows up for me. When or where are you getting these part errors? I'm asking because the only part mod I use is kOS which presumably you also use.

18 hours ago, ManEatingApe said:

The tweak is to change the desired final orbit type to polar. Relaxing this constraint allows RSVP to find a much better transfer.

Let me try to understand this. "Circular" means that RSVP really, really wants the final orbit to have 0° inclination, but "polar" means inclination it isn't particularly concerned with inclination, is that right?

Link to comment
Share on other sites

2 hours ago, Black-Two- said:

That's really weird. Pod-R at the bottom of the list in the tracking station shows up for me. When or where are you getting these part errors? I'm asking because the only part mod I use is kOS which presumably you also use.

It was missing Breaking Ground/Making History DLCs. When I added them, then restored a fresh copy of the save file I could see the craft and reproduce the error successfully.
Previously I was getting a popup dialog error about unknown parts and it looks like KSP deletes a craft from the save if it has parts it can't load.

2 hours ago, Black-Two- said:

Let me try to understand this. "Circular" means that RSVP really, really wants the final orbit to have 0° inclination, but "polar" means inclination it isn't particularly concerned with inclination, is that right?

Depending of the value of the "final_orbit_orientation"
https://github.com/maneatingape/rsvp/#final-orbit-orientation

RSVP tries to achieve a destination orbit of:
"prograde" => 0°
"polar" => 90°
"retrograde" => 180°

In this case the polar orbit was a closer match to the craft's existing orbit.

("circular" is an option for the eccentricity of the final orbit, which is a different unrelated option "final_orbit_type" https://github.com/maneatingape/rsvp/#final-orbit-type )

Edited by ManEatingApe
Link to comment
Share on other sites

On 11/23/2021 at 6:27 PM, Black-Two- said:

Hey there,  I ran into a different problem.

https://imgur.com/a/jvbkGbK

I have a craft in a very eccentric orbit of Gratian, wanting to get to Geminus, Gratian's moon. Ten days (day 78 is today) into a search I get the error above. It looks like cos_E is greater than 1 and sin_E then tries to get the square root of a negative number. Here's a save: https://www.dropbox.com/s/8x14sqaz1ug8t7n/GPPrsvpgratian.zip?dl=0

Update on what's going wrong...

I originally thought it was due to the fact that the craft intercepts Geminus (no fewer than 3 times in a row!) within the search period, but after some investigation kOS doesn't track future intercepts until the game shows them in the UI so that was ruled out.
 

This extremely polished graphic will help illustrate:

Row97qN.png

KSP uses patched conics, where each body has a finite SOI (sphere of influence). Within each SOI only the central body gravity is considered, reducing orbital equation to readily solvable 2 body forms. This means that at the boundary of the SOI there is a minimum possible velocity. This is given by the vis-viva equation and is 83 m/s for Geminus with a PE of 100km and AP at SOI boundary.

RSVP uses a spherical cow approximation for the initial transfer returned by the Lambert solver. This assumes the origin, destination and craft are all zero dimensional points. RSVP then refines this raw initial transfer, using an iterative process that takes into account the finite SOIs of the origin and destination when applicable:
https://github.com/maneatingape/rsvp/blob/master/src/refine.ks#L203

For one particular iteration the intercept is returning 28 m/s as the relative velocity of the craft and Geminus. As this is below the minimum possible, it mucks up the math and results in the stack trace you reported.

That's the background...so how do we fix it?
I'm not sure yet. One solution might be to force a minimum floor on the intercept velocity. Another may be to better mirror how KSP translates velocity when transitioning SOIs.

Link to comment
Share on other sites

Released Version 7

New Features

This release increases the speed of the hill climbing algorithm when searching the pork chop plot in certain scenarios. The larger the relative difference between the origin and destination orbits, the more benefit this provides. The eventual transfer found and delta-v needed is the same as before but takes less time to find.

For example a transfer search from Kerbin to Duna takes the same time. A transfer search from Moho to Eeloo takes 15% of the previous time.

Technical Improvements

  • When verbose mode is enabled, print details if a problem occurs during a transfer search.
  • Add CPU speed boost to quickstart code snippet
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...