Jump to content

[1.8.x to 1.12.x] kRPC: Remote Procedure Call Server (v0.5.1, 2nd March 2023)


djungelorm

Recommended Posts

How do I make the vessel point retrograde relative to the surface? I cannot figure this out at all, probably because of some sparse documentation on Github. You really need the documentation on geometry.vector3, I would really like to know if it is subscriptable, or if it has properties of pitch and yaw, or something like that. Here's some code I was trying, it's supposed to make the craft go up for 6 seconds, and then up at 45 degrees pitch for 4, and it does this, but then I try to point it retrograde for 2 seconds, and no matter what I try, it always points retrograde orbital. After that, it points straight up again like I want it to, then it controls the throttle based on vertical velocity exactly how I want as well.

http://pastebin.com/nddps16A

Also great mod btw, I've been wanting something like this since kOS was created, since it's silly syntax was nothing like I wanted.

Link to comment
Share on other sites

Your code looks fine. I tried a simplified version, and it didn't work for me either. There must be a bug somewhere in the reference frame code.

I've added documentation for vector types on the wiki. They are just containers for the three vector components, accessed using properties x, y and z. They don't provide anything fancy like roll/pitch/yaw values. For example:


import krpc
p = krpc.space_center.active_vessel.flight().prograde
print p.x, p.y, p.z

Link to comment
Share on other sites

I took a look at the server code, and there is indeed a bug with transforming orbital vectors to the surface reference frame. I forgot to include the velocity vector of the planet's surface in the calculations.

I don't have time right now to make the changes and test it properly - I will do so on Monday.

Link to comment
Share on other sites

You'd need to implement a java client library that you can use from your java programs to talk to the server. My knowledge of Java is limited, but I guess it would do something like translate Java RMI calls to/from protocol buffer messages that the server understands. I haven't yet documented how the protocol buffer communication protocol works, but it could be reverse engineered from the existing python client library.

tja mentioned back on page 6 (http://forum.kerbalspaceprogram.com/threads/69313-WIP-kRPC-A-language-agnostic-Remote-Procedure-Call-server-for-KSP?p=1028791&viewfull=1#post1028791) that they'd had a go at implementing such a java client. Maybe tja could share the code with you?

id rather have a lua client myself. though id rather wait for documentation than learn to read python.

Link to comment
Share on other sites

I may write a C++ client for this. Or java, if there are more people interested in that. No promises or anything, I just want to have some feedback which of them and also have the following questions:

You mentioned somewhere that the python client creates most of the API at runtime after asking the server for a list of RPC methods. Of course, a java or C++ client can't do that (I want to provide "regular" function calls for the application code), but I'm interested in generating part of the client with a similar method. The obvious disadvantage is that KSP, including kRPC and anything extending the API has to run while building the client. On the other hand, this a) saves me from encapsulating every RPC by hand and B) can automatically include any extension to the API.

I would like to know what you think of this approach, and whether you would recommend looking at the python client code to learn about your protocol, or have some documentation about that.

Please keep in mind that my time to work on this will be very limited and I am not committing to finish anything - I'm just curious to try.

EDIT: Another question: What IDE would you recommend for Linux? Everytime I have written C++ on Linux, I was limited to Emacs for one reason or the other, but now that I'm developing on my home PC I would like a proper IDE with a bit more...features :D

Edited by Garek
Link to comment
Share on other sites

Happy to hear there are people keen to add support for more languages :)

When the python client connects to the server, it calls a special RPC -- called KRPC.GetServices() -- which lists all the available RPCs and a bunch of type information. The python client uses this to dynamically create python classes and methods to invoke the RPCs. As you point out, it'd be annoying having to manually write all the RPCs in the client, and that's why the python client works this way.

For a compiled language like C++ or Java, I think it'd be good to keep this behaviour as far as is possible. Maybe by having a script that calls KRPC.GetServices and generates C++/Java wrapper code for all the available RPCs. Then whenever the server changes, you just rerun the script.

I think it should be possible to run such a script without having KSP running. We'd just need a tool that scans the DLLs containing the RPCs to retrieve the method names and type information, and sets up a server to provide a KRPC.GetServices() method. In fact, I do exactly this with a little test server to test the python client without having to run KSP. The core kRPC server code doesn't depend on KSP, so it can be linked with and run from another application.

I use emacs for most of my coding (python/C++) on Linux! Except C# for which I use monodevelop. I've not really found a C++ IDE for linux that I like - although I did use Code::Blocks briefly and it wasn't too bad.

Link to comment
Share on other sites

A script generating the Wrapper code based on KRPC.GetServices is exactly what I had in mind, nice to know that we agree on that approach. I also like the possibility of running that script against a KSP-less test server. Is your implementation of that also in the git-repository linked in the first post?

As soon as I get the time at home (I'm writing this while I wait for stuff at work) I'll install KRPC and try setting up a development enviroment for this. Haven't worked with git before, but I'm sure I'll find enaugh help with that on the internet. Then I'll take a look at your python client and see where I get from there :D

Well, last time I looked at Code::Blocks (okay, that was several years ago) I didn't really like the feel of it. Maybe I'll try again, or just stick with emacs.

EDIT: another question of more theoretical nature: Does KRPC handle multiple concurrent clients well? The use case being that compiled client applications propably won't be as modular as python-based ones, so I will probably start a separate client per thing I want to do. What happens if two run at the same time because a) I have one for data outputs and one for actually doing stuff or even B) I forgot to kill one before starting the next?

Again, this is a more theoretical question, since it will be some time before I start writing actual client applications, and the mentioned use cases propably won't even occur. But I'm curious.

Edited by Garek
Link to comment
Share on other sites

Ideally, you (djungelorm) would release the testing script/server, and even add code generation capabilities to the testing script, or, alternatively, have the test script export all services in a language-independent format (JSON, XML?). Still, it would probably be easier to do the C++/Java/... code generation directly from the Python testing script.

On the topic of IDEs: Code::Blocks, Netbeans and Eclipse all have a C/C++ mode, and I've even made good experiences with their GDB/git integration, but I honestly recommend to simply use your text editor of choice. C/C++ is not an IDE-centered language like Java/C#, and IMHO IDEs don't provide any comfort bonus for those languages.

Link to comment
Share on other sites

Garek: The test server code is here: https://github.com/djungelorm/krpc/tree/master/test/TestServer

I'll write documentation for the server communication protocol at some point next week, but if you know python I don't think extracting the information you need from the existing client would be too difficult.

mic_e: I like your idea of providing a script to export the RPCs in some language-independent form :) Maybe via a C# command line tool that takes a list of paths to the DLLs containing the RPCs and spits out XML/JSON/yaml/... to stdout or a file.

Link to comment
Share on other sites

Thanks for the link. I know python, even though it may need some refreshing. But I'm used to reading foreign code, so it should do.

Exporting the RPCs into XML/JSON/... is a nice idea, although in the end it makes not that much of a difference if the generator reads from a file or from the result of a RPC. This reminds me to make the generator modular so the input can easily be changed. The main advantage would be that someone could build wrapper code for a combination of KRPC-services simply from the definition files without the services actually installed and running. There got to be a use case for that :D

Link to comment
Share on other sites

EDIT: another question of more theoretical nature: Does KRPC handle multiple concurrent clients well? The use case being that compiled client applications propably won't be as modular as python-based ones, so I will probably start a separate client per thing I want to do. What happens if two run at the same time because a) I have one for data outputs and one for actually doing stuff or even B) I forgot to kill one before starting the next?

Again, this is a more theoretical question, since it will be some time before I start writing actual client applications, and the mentioned use cases propably won't even occur. But I'm curious.

The server supports multiple concurrent clients, and RPCs are serviced in round-robin order. Separating your functionality into separate connections should work just fine, and it will work just fine for scenarios a) and B).

Link to comment
Share on other sites

This is nice to know, thanks. I set up kRPC from source and started working on my project. I'm calling it krpc2cpp, because it provides an interface from C++ to kRPC...okay, that sounds a little wierd, but I'll keep it :D

I won't have much time to work on this during the week, but next weekend I'll propably push on github whatever I have until than to collect some feedback. It of course won't be anywhere near a working version, but I hope to have finished at least the basic RPC framework, including a way to dump GetServices() result for debugging purposes.

Link to comment
Share on other sites

This is nice to know, thanks. I set up kRPC from source and started working on my project. I'm calling it krpc2cpp, because it provides an interface from C++ to kRPC...okay, that sounds a little wierd, but I'll keep it :D

I won't have much time to work on this during the week, but next weekend I'll propably push on github whatever I have until than to collect some feedback. It of course won't be anywhere near a working version, but I hope to have finished at least the basic RPC framework, including a way to dump GetServices() result for debugging purposes.

Cool - sounds good!

I've started documenting the RPC protocol here:

https://github.com/djungelorm/krpc/wiki/RPC-Protocol

It should be a complete description of the protocol, but is lacking a few more examples to make the description clearer.

Link to comment
Share on other sites

The documentation is already very useful. One major question I have left: when encoding primitive types like int32, do you encode them with field tag, or without? I'm currently implementing the C++ side using the internal WireFormatLite from protobuf, which offers writing functions for both. Although I may switch to using more basic functions from Coded*Stream, because that is intended for external use and therefore far better documented - it just lacks functions for everything besides ints, so I would have to build the encoding for other primitive types myself.

Link to comment
Share on other sites

Version 0.1.2 has been released (see OP for download links). Most notably with fixed reference frame code (e.g. pointing the vessel retrograde in the surface reference frame should now work).

Full changelog:


SpaceCenter service changes:
- Include reference frame velocity in orbital direction vectors
- Remove ReferenceFrame.SurfaceVelocity and ReferenceFrame.TargetVelocity
- Change default reference frames for Vessel.Flight() and AutoPilot functions to ReferenceFrame.Orbital
- Use Pa instead of kPa for atmospheric pressure

Python client changes:
- Convert parameter names to snake_case

Link to comment
Share on other sites

I am coming from kOS and this add-on looks cool for several reasons:

1. Python provides a full fledged basis for writing any code - and extension to other languages is easily possible.

2. All variables from here are exposed and available.

I will have a look and try to migrate my kOS mission toolkit for launch, circular orbit, Hohman transfer to Mun and Mun soft landing to kRPC/Python.

Regards, Andreas

Link to comment
Share on other sites

Hi Andreas! Pleased you like the mod :) It would be great to get some feedback on how your porting efforts go, to help me improve the SpaceCenter API (which is almost certainly far from perfect).

Also, is your kOS mission toolkit available to download? I think it would be useful to have a look at the design patterns/functions it uses to help refine the SpaceCenter API too.

Link to comment
Share on other sites

This is properly amazing and useful. Thank you so much for making it.

I had a go at running a kOS career but gave up pretty quickly becuase of the limitations, pid control is about the limit of reasonable complexity and you have to rewrite it every time. The ability to "import scipy" is going to be awesome.

Minor notes:

1 - the names on the wiki are out of date with the current release, still showing "Flight().VerticalSpeed" when it's actually "flight().vertical_speed"

2 - might be worth putting a health warning on true_altitude that it returns altitude above the sea floor if you're over water, so a parachute deployment loop should be looking for min(altitude, true_altitude). Took me a few ocean crashes to work that one out.

Link to comment
Share on other sites

Two things which occured to me while looking at the SpaceCenter API:

a) according to the description, you support only action groups 1 to 9. It would be nice to have support for all ten numeric action groups, as well as for the special action groups like gear or abort. (maybe map the latter to indices > 10 with an enum?)

B) at CelestialBody.GravitationalParameter, the link to wikipedia is broken

Link to comment
Share on other sites

Hi Andreas! Pleased you like the mod :) It would be great to get some feedback on how your porting efforts go, to help me improve the SpaceCenter API (which is almost certainly far from perfect).

Also, is your kOS mission toolkit available to download? I think it would be useful to have a look at the design patterns/functions it uses to help refine the SpaceCenter API too.

The kOS toolkit is available here: http://kos.wikia.com/wiki/Mission_toolkit_v2. Caveat: the scripts are full of Newtonian math.

I will publish an extended version soon and submit an entry in the automated mission challenge. After that the next item on the roadmap is start setting up my Python development environment and start migrating.

After migration I should be able to publish the mission toolkit for Python. The mission toolkit contains scripts for:

1. Kerbin ascent

2. orbit adjustments

3. Hohmann transfer from Kerbin to Mun

4. land on Mun

5. take off into low orbit

6. leave Mun SOI and

7. land on Kerbin.

Currently everything is pretty 2D but with Python I'd like to use vector math and support stuff like inclination changes and targeting landing zones on arbitrary coordinates.

Sounds like lots of fun.

Edited by baloan
Link to comment
Share on other sites

Minor notes:

1 - the names on the wiki are out of date with the current release, still showing "Flight().VerticalSpeed" when it's actually "flight().vertical_speed"

2 - might be worth putting a health warning on true_altitude that it returns altitude above the sea floor if you're over water, so a parachute deployment loop should be looking for min(altitude, true_altitude). Took me a few ocean crashes to work that one out.

The wiki has been updated to fix this.

Two things which occured to me while looking at the SpaceCenter API:

a) according to the description, you support only action groups 1 to 9. It would be nice to have support for all ten numeric action groups, as well as for the special action groups like gear or abort. (maybe map the latter to indices > 10 with an enum?)

B) at CelestialBody.GravitationalParameter, the link to wikipedia is broken

I've fixed the link on the wiki.

You can already trigger most of the special action groups using Control.sas, Control.gear, Control.lights etc. (I'll add the missing abort and 0 action groups in the next release)

E.g. to lower the landing gear and switch on the lights:


conn.space_center.active_vessel.control.gear = True
conn.space_center.active_vessel.control.lights = True

Link to comment
Share on other sites

I've think I've found another bug that looks like it will be the same as the one mentioned a few days ago with transforming orbital to surface reference, but this time it's maneuver to orbital. The following


import krpc
conn = krpc.connect(name='Auto-launch')
vessel = conn.space_center.active_vessel

node = vessel.control.add_node(conn.space_center.ut,prograde=1.,radial=0.,normal=0.)
vessel.auto_pilot.set_direction(node.vector,reference_frame=conn.space_center.ReferenceFrame.maneuver)

should be putting up a 1ms prograde maneuver for current time and pointing the vessel along it, but actually points -ve normal.

A 1ms radial works fine, but 1ms normal also points in +ve radial.

Everything else is good so far:D

Link to comment
Share on other sites

Two questions:

1. How do I instantiate a vector in Python?

As an example I'd like to take

import krpc
p = krpc.space_center.active_vessel.flight().prograde
pn = norm(p)
[B]v = (1,0,0) # what is the correct type to use here? Geometry.Vector3?[/B]
a = cross(pn,v)

2. Can I run multiple threads using a kRPC connection?

I'd like to run a thread monitoring conditions for staging in a separate thread:


def run_thread():
while liquid_fuel() > 0:
time.sleep(1)
control.activate_next_stage()

If not: events might be an elegant alternative as they spare the effort of polling.

Edited by baloan
Link to comment
Share on other sites

double Resources.max (string name, uint32 stage = 0)

with stage = 0 returns the resource for the vessel. When stage > 0 it returns the value for the stage. I have stages 0 to 4.

How does the stage argument map to my stages?

stages.png

IMHO stage should default to -1. Then values [0:] from the KSP UI can be used as argument without applying a shift.

Edited by baloan
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...