Jump to content

[1.12.x] kRPC: Control the game using C#, C++, Java, Lua, Python, Ruby, Haskell, C (Arduino)... (v0.5.4)


djungelorm

Recommended Posts

6 hours ago, djungelorm said:

That's odd... stream.remove() definitely doesn't have a parameter called x! The code is here: https://github.com/krpc/krpc/blob/master/client/python/krpc/stream.py#L52

Ok, its a liveware problem! I followed it back to the declaration and for some reason its picking up the remove method from builtins, not the remove method for the stream object.

It only happens where i have a list of streams i am trying to iterate through. If I work on a stream object directly, even if it is an element of a list, no warning appears!

In the code the first part gives a warning, the second doesn't. However i think the warning is false as the code correctly closes the stream so its all good.

for x in list_of_streams:
	x.remove()


list_of_streams[0].remove()

 

Link to comment
Share on other sites

  • 2 weeks later...

KOS is more like BASIC running on a 8-bit computer, it's extremely limited in comparison, but it's barrier for entry is much lower.  Because krpc allows you to extract and input data to and from the game from other languages and hardware platforms, it's possibilities are nearly limitless.  

Say you want to hook up a smoke machine to a Raspberry Pi that fires when using your engines in KSP, you can do that with KRPC.

Say you had a 6 degree of motion freedom platform ripped from a plane flight simulator, you could hook it into KSP with KRPC.

Say you had a load of old nixie tubes and wanted to build a hardware readout panel, with speed, apoapsis etc, you can do that with KRPC.

Say you wanted to hook up an emulator of the Apollo computer and you wanted to fly your craft in KSP using it, you can do that with KRPC.

KOS is great at what it does, but this is in another league as to what you can achieve with it.

1 hour ago, gowthamn said:

Does it obey the rules of remote tech

You can access the RemoteTech API, so you can write your code to follow the RT rules if you so wish.

http://krpc.github.io/krpc/cpp/api/remote-tech/comms.html

 

Edited by Sonny_Jim
Link to comment
Share on other sites

43 minutes ago, Sonny_Jim said:

KOS is more like BASIC running on a 8-bit computer, it's extremely limited in comparison, but it's barrier for entry is much lower.  Because krpc allows you to extract and input data to and from the game from other languages and hardware platforms, it's possibilities are nearly limitless.  

 

Thanks. I like its flexibility. I will take a look at this. I always dreamt of building a aircraft or chopper which learns to fly using ML. Especially Reinforcement Learning using Deep Learning. May be I can build a model in Java and run it on KSP using this mod.

Link to comment
Share on other sites

5 hours ago, gowthamn said:

does it need a electricity to run or is it independent of the game?

No, electricity is not required, nor is it consumed. It's pretty much independent of the game - except the current scene that is loaded. Most functionality is only available in the flight scene.

One thing to point out is that there is a price for kRPC's flexibility - latency. Each remote procedure call (RPC) is sent from your script to the game over a network socket, which introduces some overhead. When run locally, this is pretty fast (on the order of thousands of RPCs per second, depending on your machine). kOS executes code within the game, so it completely avoids this overhead.

The latency becomes really painful for some use cases:

  • When you are wanting repeated updates of the game state (for example getting the vessel altitude once per physics tick). Using kRPC "streams" helps reduce this overhead.
  • Waiting on an event (for example, the vessel reaching a chosen altitude) currently has to be done using a spin wait. I'm working on adding a more efficient events mechanism, based on streams, to make this use case better.
Link to comment
Share on other sites

On 9/6/2016 at 10:16 PM, djungelorm said:

One thing to point out is that there is a price for kRPC's flexibility - latency. Each remote procedure call (RPC) is sent from your script to the game over a network socket, which introduces some overhead. When run locally, this is pretty fast (on the order of thousands of RPCs per second, depending on your machine). kOS executes code within the game, so it completely avoids this overhead.

The latency becomes really painful for some use cases:

  • When you are wanting repeated updates of the game state (for example getting the vessel altitude once per physics tick). Using kRPC "streams" helps reduce this overhead.
  • Waiting on an event (for example, the vessel reaching a chosen altitude) currently has to be done using a spin wait. I'm working on adding a more efficient events mechanism, based on streams, to make this use case better.

10 - 20 or so flight corrections per second should be ok I guess? It would be good to access all the metrics I want from the game with just 1 call and make it return an object. Is that possible? Or should I write a mod which runs in game to collect the information and make 1 RPC to get all the info?

Also, will this mod work with parts from other mods like DMagic orbital science?

Edited by gowthamn
Link to comment
Share on other sites

kRPC 0.3.6 has been released!

There are lots of bug fixes in this release. Apart from that, here are the salient features:

  • Part tagging is now possible, via the Part.Tag property. This requires either kOS or the NameTag mod to be installed alongside kRPC.
  • More aerodynamic data is accessible (such as mach speed) when FAR is installed
  • Arbitrary forces can be applied to parts via Part.AddForce
  • Support for biomes - you can now get all the biomes for a planet, and an experiment's current biome
  • Interaction with waypoints (list, edit and delete them)

A full change list is available here

Link to comment
Share on other sites

15 minutes ago, djungelorm said:

kRPC 0.3.6 has been released!

There are lots of bug fixes in this release. Apart from that, here are the salient features:

  • Part tagging is now possible, via the Part.Tag property. This requires either kOS or the NameTag mod to be installed alongside kRPC.
  • More aerodynamic data is accessible (such as mach speed) when FAR is installed
  • Arbitrary forces can be applied to parts via Part.AddForce
  • Support for biomes - you can now get all the biomes for a planet, and an experiment's current biome
  • Interaction with waypoints (list, edit and delete them)

A full change list is available here

Nice. One question. Does experimentation work with Dmagic? Or just stock parts for now?

Edited by gowthamn
Link to comment
Share on other sites

8 minutes ago, gowthamn said:

Nice. One question. Does experimentation with with Dmagic? Or just stock parts for now?

I've not tested it, and I'm not familiar with dmagic. Depends what PartModule it uses. If it's ModuleScienceExperiment then it should work fine.

26 minutes ago, gowthamn said:

10 - 20 or so flight corrections per second should be ok I guess? It would be good to access all the metrics I want from the game with just 1 call and make it return an object. Is that possible? Or should I write a mod which runs in game to collect the information and make 1 RPC to get all the info?

I've written scripts with update rates of about 10Hz, and that was sufficient for precise rocket control.

As for a single call to get lots of data - these are coming soon! I'm working on a protocol overhaul in v0.4.0 which will add the ability to do "batched" RPCs. I.e. send multiple calls in a single network message and get all the results back in a single message.

However, if you just want to get data out, and do it repeatedly, then you should use streams. Internally, stream update messages are batched together, so one message is sent per physics tick regardless of how many streams you create.

Edited by djungelorm
Link to comment
Share on other sites

  • 2 weeks later...

A kRPC pre-release for KSP 1.3 is available here: https://krpc.s3.amazonaws.com/deploy/feature/ksp-1.2/687.1/krpc-0.3.6-16-g7940236.zip

Expect bugs! Also note, this doesn't add support for any of the new features in KSP 1.3 (such as the comms network). It's just a build of kRPC v0.3.6 that is compatible with the KSP pre-release.

Link to comment
Share on other sites

  • 3 weeks later...

Hi @djungelorm

I have been playing with the Autopilot now that I have a nice hardware panel for it, and I have a few ideas, suggestions, misunderstandings and general mayhem type things that mostly come from me being rather ambitious :)

1. Is it possible to separate the lateral and longitudinal modes?

    I went for a typical A/C setup and its normal to have Lateral, Longitudinal and Speed as 3 separate modes. So for example you can enable 'Pitch hold' but heading / roll is still free for manual control. In the current KRPC implementation it can only be on or off for both Pitch and Heading.

2. Would it be possible to allow the use of the roll target without heading?

  This enables a typical 'hold bank angle' mode of A/C and you can fly visually just change bank set. Currently you have to set a heading I think, but I want to have no heading target, just hold bank.

3. Any thoughts of adding an auto-throttle controller? I imagine the same PID approach should work but may require different tunings to respond to different engine spool up times. If you could also specify a velocity vector for it to target, and you give it vertical we now have hover hold and gentle landings too!

4. Any thoughts of adding higher level modes? Altitude hold, Rate of Climb hold, ILS maybe (glideslope and localiser), waypoint guidance etc. I know some of these, in fact all of these, could be done by driving pitch and heading, but if that is in a slow python module then i suspect osculations of two controllers talking to each other.

5. The autopilot, at first test really didnt like my high manoeuvrability fighter :) Massive overcontrol but it seemed the autotune didnt dial it out? it was persistent. Only reducing the control authority of the surfaces stabilised it. Would like to know your thoughts on limits of autotune, or if that really is the case could we have a control scaling factor? Say i let the AP have 25% of the control authority so I can still fly like a nutcase if I like? 

Thanks!

Pete

 

Link to comment
Share on other sites

15 hours ago, PeteWasEre said:

Hi @djungelorm

I have been playing with the Autopilot now that I have a nice hardware panel for it, and I have a few ideas, suggestions, misunderstandings and general mayhem type things that mostly come from me being rather ambitious :)

...

Hi! The autopilot is intentionally quite simple. It just provides the functionality to point the rocket in a chosen direction, as this is a basic requirement for writing your first launch script. I consider anything more than that to be beyond the scope of the SpaceCenter service. This is because a more complex autopilot could be implemented as a client program, and my time is limited and I'd prefer to focus on other aspects of the mod such as exposing more of KSPs API (lots of new things to add for 1.2!!!), fixing bugs and adding support for more languages - gRPC coming "soon"..... hopefully!). Of course if someone else fancies writing a more complex AP a pull request on github would be welcome!

Re. your specific questions:

1 and 2: I'm happy to make small changes like this, as these changes are just modifications to the interface used to configure the autopilot, not actually changes to the autopilot itself.

3. An auto-throttle controller is pretty easy to do client side using a simple PID loop, so I won't be adding this to the server. For example in my python toolkit I wrote such a thing: https://github.com/djungelorm/krpc-toolkit/blob/master/krpctoolkit/throttle.py

4. I don't plan to add these. Sorry! But it should be possible to do these from a client script.

5. There are some issues with the math behind the current tuning approach, although it's a bit over my head. There is more discussion of this here: https://github.com/krpc/krpc/issues/310 Have you tried tweaking the stopping time and deceleration time parameters? A combination of them should reduce the APs "control authority".

Link to comment
Share on other sites

@djungelorm Thanks :)

1 and 2 sound nice as they would give user flexibility to configure as they like. If it's not too much to ask that would be a nice help.

For 3 and 4 I completely understand, no need for sorry! It makes way more sense for you to work on things we cant do on the client side (like more API interfaces, oh what goodies will that bring!) than things we can. I only wish I was skilled enough to make that pull request! I am already thinking of ideas to get faster response, a seperate python AP process or maybe the KOS bridge. It will be a nice challenge for me.

For 5 i haven't played with the parameters yet, but will do. I did read #310 and got confused very quickly... my control theory classes were almost 20 years ago... I will see how I go with those. However my thinking came from real A/C autopilots that generally dont have full control range. In RL this is more to do with safety, so the pilot can always pull up more than George pushes down, but it might help here. Will let you know how I go.

Thanks again!

Pete

 

Link to comment
Share on other sites

On 9/7/2016 at 6:16 AM, djungelorm said:

The latency becomes really painful for some use cases:

  • When you are wanting repeated updates of the game state (for example getting the vessel altitude once per physics tick). Using kRPC "streams" helps reduce this overhead.
  • Waiting on an event (for example, the vessel reaching a chosen altitude) currently has to be done using a spin wait. I'm working on adding a more efficient events mechanism, based on streams, to make this use case better.

Hi djungleorm,

Firstly a huge thank you for creating and maintiaining this mod. It is really a fantastic thing - and I imagine will quickly become my favourite KSP mod! I've just "finished" the stock tech tree with a ISRU mining SSTE and wanted a new challenge so I think I'll try to play through career again (on Interstellar perhaps) but this time using only (well mostly) python .. Can't be that hard right?

Anyway after catching up with this thread, and in particular this comment above (bold) I wondered whether you actually need to consider a new events mechanism at all - can't this already be done fairly straightforwardly on the client side?

For python at least, the asyncio module allows you to create and run tasks as cooperatively scheduled co-routines, so you can create asychronous flight plans based on some simple event handling with coroutines monitoring the streams that you've already implemented in the KRPC client library.

I threw together a quick example below that will monitor altitude and speed and handle triggered events in either order.

#!/usr/bin/python3
import asyncio
import krpc

class KspSession(object):
    def __init__ (self):
        self.conn = krpc.connect(name="stream_test")
        self.msg("KRPC client Connected!")

        # Set up a queue for tasks to communicate
        self.event_queue = asyncio.Queue()
        self.vessel = self.conn.space_center.active_vessel

        # Get the event loop and add some tasks
        self.loop = asyncio.get_event_loop()
        self.loop.create_task(
            self.listen_flight_attr(self.vessel.surface_reference_frame,
                                    "mean_altitude",
                                    3000, 8000))
        self.loop.create_task(
            self.listen_flight_attr(self.vessel.orbit.body.reference_frame,
                                    "speed",
                                    170, 240))

        # Finally add a task to handle all the flight events
        self.loop.create_task(self.handle_flight_events())

    def msg(self, s, duration=5.0):
        self.conn.ui.message(s, duration=duration)

    @asyncio.coroutine
    def handle_flight_events (self):
        while True:
            # Wait until an item is put on the queue before dequeuing
            data = yield from self.event_queue.get()
            self.msg('Flight event: {} at {}'.format(data[0], data[1]))
            # Process event here..
            # Test part, adjust course, deploy chutes, suicide burn etc..
 
    @asyncio.coroutine
    def listen_flight_attr(self, ref, attr, minimum, maximum):
        self.msg("Listening for '{}' events between {} and {}".format(attr, minimum, maximum))
        with self.conn.stream(self.vessel.flight, ref) as flight:
            while True:
                yield # Let the CPU do other work
                val = getattr(flight(), attr)
                if val > minimum and val < maximum:
                    # Put the flight data on the queue
                    data = ( attr, val )
                    asyncio.async(self.event_queue.put(data))
                    return
                 
    def run(self):
        # Run all tasks in an event loop, and don't stop
        self.loop.run_forever()

sess = KspSession()
sess.run()

Hope this is helpful!

Best regards,

Tom.  

Link to comment
Share on other sites

Thanks @ThomasD! I'm planning to add something exactly like this in the python client library.

While your code improves things on the client side, it doesn't address the issue that you have to constantly pull data from the server to check for the event. I plan to add a bit of logic to the server so that we can effectively have the `listen_flight_attr` code run on the server. The client will subscribe to a stream of boolean values, for which it will only receive an update message when the event occurs.

Link to comment
Share on other sites

@djungelorm I've praised you earlier in the thread, but I feel like I have to do it again. I knew Python before I started hacking together a play-RSS-for-me suite, but this has really stretched my knowledge and made me much more familiar with the language and with programming in general, to my benefit. Thanks a ton.

General question to anyone who feels like answering:

I'm trying to create a simple script that will take a target orbit and a pre-launch active vessel and warp time until the active vessel is under the target orbit. (Specifically, I'm going to the Moon in RSS, but I plan on making it much more general - fulfilling contract orbits, setting up orbital rendezvous from launch, etc.)

At first I thought this would be simple: take the longitude of the launch site, compare to the longitude of the ascending (or descending) node of the orbit, get the vessel's angular velocity, and calculate how long it will take from that for the vessel to rotate under the orbit. (Naturally taking into account the latitude offset.) Do all these calculations in the inertial reference frame of the body the vessel is currently landed on.

Maybe I'm missing something, but it looks like it's not that simple? The non-rotating reference frame (and indeed, all reference frames) uses x,y,z coordinates instead of r,theta,phi coordinates? Is there some easy way to get spherical (or even cylindrical) coordinates, or do I have to convert them myself?

If anyone wants to post some sample code or sample pseudo-code I'll love you forever, but that'd just be icing on the cake.

Thanks!

 

ETA: Would it be better to be using vessel.orbit? Could I even do so when I'm landed or pre-launch? Would that even be accurate?

Edited by Jovus
Link to comment
Share on other sites

Just looked to find the function I used for that, but looks like I didn't upload any of my pre-launch code.  =(

 

A couple things I remember is that one of the hardest things about that module was the warp-to part in RSS.  Due to latency and how fast the time-warping is in RSS, it was a challenge, and a robust RSS time warp function was essential part of my libs.  Especially for that particular pre-launch function.

 

For the launch time part, I will poke around some of my archives to see if I can dig my py script up.  But for now you can just check how sarbian does it: MechJeb

Edited by BevoLJ
Link to comment
Share on other sites

@djungelorm An event system sounds great, but please do preserve the streams! It would be nice to build client side AIs on top of this thing, and streaming telemetry is a good/valid way to go, 

Just for my own pleasure/fun,  I'm working on a very simple Kivy based console that allows you to queue up sequences of maneuvers (launch, orbit, transfer, deorbit, etc) whilst also allowing background events/triggers (test part, autostage, deploy chutes), and also displaying flight data & a very simple 2d orbital "view". Using a GUI slightly complicates things in that I've needed to use a separate thread, with messages queued between the GUI side and the KRPC/asyncio coroutine side.

I'll try to post/share something on github in a week or two, perhaps it can be added as an example somewhere if deemed worthy :)

Regards,

Tom.

Link to comment
Share on other sites

Hello

I just wanted to let you know that I managed to connect to kRPC using a low cost WeMos D1 Mini board with ESP8266 WiFi chip.

The code is an ESP8266 core Arduino project and github repository is here: https://github.com/ytmytm/espkrpc

The platform has 4MB of flash and there is about 80KB or RAM available for application so it's not possible to use C++ client provided by kRPC. I use only 20% of the flash but already 40% of RAM, without counting the dynamically allocated objects.

Instead of Google protobuf I used Nanopb - a library with low RAM usage, aimed for microcontrollers. Because of this I had to reimplement the services too.

At the moment the code in the repository reimplements the script from kRPC tutorial.

So I have a device that I can just connect to a powerbank and it will automatically sends a rocket up, to 100km apoapsis using autopilot and brings the Kerbals safely back. I don't know why, but having this as a physical thing that I can hold makes me more happy than using MechJeb :). In both cases my input is minimal.

The real reason I had in mind while playing with this was to use it in custom control/display designs.

In my KSP Gegi project I used a Python script running on the game host to act as an interface between simple serial commands sent over USB to Arduinos to display something (LEDs, LCD) and back to react on button presses. Using this approach I can get rid of this dependency and keep whole control panel as a one box that only needs power.

For current Arduino users - you can also think about it as a KSP Serial IO on steroids. The ESP8266 chip will connect over WiFi to the game and send back any information transcribed to data packet according to your needs.

Edited by ytmytm
Link to comment
Share on other sites

  • 4 weeks later...

I'm using this thing for the first time (with Python if it matters) and I'm trying to figure out this: is there a way to measure in-game time rather than real time for my scripts? Basically something similar to time.sleep except based on in-game time? What I'm trying to use so far is a custom sleep function using vessel.met, but would it work if the vessel is still on the launchpad and MET timer hasn't started?

Edit: Well I got the time measurement to work as I want it with vessel.met, so it works under time acceleration, but I'm still wondering if it works for something that's on a launchpad and if not, then whether there's a better way.

Edited by xrayfishx
Link to comment
Share on other sites

Hi, I want to thank you for this great mod.

Currently I am learning Java at school so most of the time my programming is based of trial and error.

But even after a lot of testing I don't seem to get the output for the vessel speed working: no matter when I check it, it always gives "0.0" back.

Here is the part of my code:

    public double getVerticalSpeed() throws IOException, RPCException, StreamException
    {      
        this.surfaceReferenceFrame = vessel.getSurfaceReferenceFrame();
        return flight.getVerticalSpeed();   
    }

The methods getSpeed,getVerticalSpeed and getHorizontalSpeed are not working. Any clue what my failure could be?

However the method getTrueAirSpeed() is working for me.

Thanks in advance.

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...