Jump to content

[1.8.x to 1.12.x] kRPC: Control the game using C#, C++, Java, Lua, Python, Ruby, Haskell, C (Arduino)... (v0.5.2, 18th March 2023)


djungelorm

Recommended Posts

4 hours ago, Spul M. said:

This is what I am wondering as well. For some reason the server console is gone since 1.1.2. Normally the server automatically starts, But I am no longer able to connect to it.

Looks like they changed something with the code to show popup dialogs. kRPC v0.3.1 should have just worked with 1.1.2, but when it tries to display a popup warning you about running kRPC on a potentially incompatible version of KSP it failed and the mod was disabled.

Link to comment
Share on other sites

I' beginning to feel stupid :(

I've been working with this mode now for a couple of days just learning the basic and right now I am at the part where I need to learn how to do maneuver nodes and I can't figure it out. From the Python guide I try to add a node like this: 
 

Quote

 

            var universalTime = con.AddStream(() => spaceCenter.UT);

            var node = vessel.Control.AddNode(universalTime.Get());

 

I have tried printing the time and I get something from it so atleast that one is not wrong. I've tried it in flight and at the pad before launch. I've also removed all code I had that use to set the direction for the burn at the node as well but that didn't give me a different result.

To the error then: Object reference not set to an instance of an object

Is what I am getting when trying to create a new node. I've been working on it for 2 hours straight now. Anyone that could aid me in this?

Thanks in advance and Djungelorm I really love the mod! Keep up the good work :)

//Toastmastern

Link to comment
Share on other sites

I've had a go trying to reproduce this but have been unsuccessful. At first I thought it might be something to do with setting the burn vector to a delta-v of 0 m/s, but that doesn't appear to break it.

What situation is your active vessel in? Maybe that's causing the issue?

Also are there any errors reported in KSPs output_log.txt? Also, if you go into the kRPC GameData folder, and edit settings.cfg so that verboseErrors=True, it will give you a stack trace along with the error message which might reveal what's causing it.

Link to comment
Share on other sites

Just found a UI bug that might be related. The "client requesting connection" dialog fails to show when a client connects (with lots of object reference exceptions in the output log). A workaround is to go into advanced settings and enable "auto-accept client connections" as this will bypass the dialog.

Edited by djungelorm
Link to comment
Share on other sites

8 minutes ago, djungelorm said:

Just found a UI bug that might be related. The "client requesting connection" dialog fails to show when a client connects (with lots of object reference exceptions in the output log). A workaround is to go into advanced settings and enable "auto-accept client connections" as this will bypass the dialog.

I will check out both things tomorrow, now I am heading to bed :)

 

I tried both when the vechile was on the pad and in flight above Kerbin ready for the OIB

Link to comment
Share on other sites

On 5/1/2016 at 2:49 PM, djungelorm said:

Just found a UI bug that might be related. The "client requesting connection" dialog fails to show when a client connects (with lots of object reference exceptions in the output log). A workaround is to go into advanced settings and enable "auto-accept client connections" as this will bypass the dialog.

This explains EVERYTHING. Now I can get back to scripting. Thanks!

Link to comment
Share on other sites

8 hours ago, royying said:

Can I use kRPC to display something on game screen?

At the moment the only thing you can do is draw lines: http://krpc.github.io/krpc/csharp/api/space-center/space-center.html#method-SpaceCenter.DrawDirection

I'm working on adding more though (e.g. polygons, text...) Details here: https://github.com/krpc/krpc/issues/253

Link to comment
Share on other sites

Hi.

I just wanted to give you a BIIIG thank you for your work. kOS was never my thing, with the constant fear that my calculations would clog the cpu but this... this is genius. The ability to use my fav language (java) to its full potential from another computer is something I never even dreamt of. Just know that I made an account here to give you this big "thank you". You deserve it. Keep up the good work and know that you have just made me soooo happy (actually this is the 3rd night I lose programming a full-fledged spaceplane autopilot, with abort modes :D so maybe it's just lack of sleep).

Link to comment
Share on other sites

Wondering if someone could help me out. Derpy question, no doubt, but having trouble with the celestial bodies. I'm trying to get mu but having a hard time.

How could I print the name, mu, or anything from celestial bodies? I've tried:

import krpc
conn = krpc.connect(name='WTB a mu')
print(conn.space_center.CelestialBody.name)

that works (kinda) but what it returns is "property object at [stuff]"

*using .name for sake of testing

Edited by BevoLJ
Link to comment
Share on other sites

v0.3.3 has been released :) Here are the highlights:

  • Fixed a bug with dialog windows not appearing
  • Add "AvailableTorque" properties to engines, RCS thrusters, reaction wheels and aerodynamic control surfaces
  • Add support for RemoteTech 1.7 - you can now target your dishes using RPCs!

The full changelog can be found here

27 minutes ago, BevoLJ said:

Wondering if someone could help me out. Derpy question, no doubt, but having trouble with the celestial bodies. I'm trying to get mu but having a hard time.

How could I print the name, mu, or anything from celestial bodies? I've tried:


import krpc
conn = krpc.connect(name='WTB a mu')
print(conn.space_center.CelestialBody.name)

that works (kinda) but what it returns is "property object at [stuff]"

*using .name for sake of testing

You're calling .name on the CelestialBody class. You need to get an instance using conn.space_center.bodies. Here's an example:

kerbin = conn.space_center.bodies['Kerbin']
print (kerbin.name)
print (kerbin.gravitational_parameter)

Also, looks like the documentation for the celestial body class doesn't link back to the conn.space_center.bodies property - I'll add a note to make this a bit clearer!

Edited by djungelorm
add link to docs
Link to comment
Share on other sites

  • 2 weeks later...
On 29.04.2016 at 6:26 AM, djungelorm said:

You could add a stream for each temperature on each part? This is probably a lot of streams though so I'm not sure how well the server would handle it.

Another option would be to add a new RPC to the server. kRPC is extensible, so you could write add your own if you like. Details are here: http://krpc.github.io/krpc/extending.html#service-api

 

I didn't try adding streams ot each part. I took the plunge with C# programming and I tried adding my own RPC. Thanks to your excellent documentation it was quite easy and I'm very happy with the result. Now the status comes back instantly and there is no noticeable delay that could interfere with user controls.

When I started with this project I overlooked in docs that it is possible to use 'getattr' as argument for add_stream. Now I rewrote my code to use streams whenever possible and it really, really, makes a difference.

This rewrite gave my controller another boost. Now, really the only limiting thing is the microcontroller speed.

Thank you again!

Link to comment
Share on other sites

v0.3.4 has been released! Here are the highlights:

  • Major server performance improvements. Finally got round to running the code through a profiler, and managed to significantly reduced the memory pressure caused by the main server loop. This means that the game no longer stutters every few seconds when the garbage collector kicks in.
  • Added functionality to draw lines, polygons and text in the game scene (http://krpc.github.io/krpc/csharp/api/drawing.html)
  • Added functionality to add and interact with custom UI elements. Tutorial here: http://krpc.github.io/krpc/tutorials/user-interface.html

The full changelog can be found here

Link to comment
Share on other sites

Hi there!

This is the *best* addon, thank you! A couple questions:

  1. Is there a way to get a list of vessels that can be launched from VAB/SPH?
  2. Is there a way to recover a vessel once landed on Kerbin?
  3. I see clicking through the science collected pop-up window has been requested on this forum thread before. Is this not yet implemented?

Thank you once again!

Link to comment
Share on other sites

Hey guys -- not sure if this is in the right area so appologies in advance if it isn't:

Xenon is slow and it consumes all active fuel tanks while running so I thought I'd give krpc a go to asparagus stage my tanks (spaceprobe below). I got the tank removal once they're empty working but since I've disabled all tanks for staging I am now struggling to enable them.

ib8Uayb.png

Here is the code I am using at the moment:

import krpc, operator

# generic setup
conn = krpc.connect(name='xenondump')
vessel = conn.space_center.active_vessel
tanks = {}

# autopilot pointing prograde
ap = vessel.auto_pilot
ap.reference_frame = vessel.orbital_reference_frame
ap.engage()
ap.target_direction = (0,1,0)

# gets list of remaining xenon tanks
def gettank():
    stack = [(vessel.parts.root, 0)]
    while len(stack) > 0:
        part,depth = stack.pop()
        if part.name == 'xenonTankLarge':
            tanks[part] = depth
        for child in part.children:
            stack.append((child, depth+1))

# enable next tank
def nexttank():
    exiter = 0
    for tank in tanks:
        if tanks[tank] == max(tanks.values()) and exiter == 0:
            print('enable new tank here')
            exiter = 1

def removeemptytank():
    for decoupler in vessel.parts.decouplers:
        if decoupler.part.children[0].mass - decoupler.part.children[0].massless == 412.4999940395355:
            decoupler.decouple()
            nexttank()

# main loop
while True:
    gettank()
    removeemptytank()
    ap.wait()

At "print('enable new tank here')" I am trying to run something like tank.resources.enabled = True but I have no idea. (https://krpc.github.io/krpc/python/api/space-center/resources.html)

Again, sorry if this is in the wrong place -- any hints would be greatly appreciated!

Link to comment
Share on other sites

This is revolutionary. In about 5 minutes I got setup running KSP from python over the local network on my laptop. Now I can explore the API, do little things I've always wanted to do but didn't want to learn unity and C#.... this....I'm speechless. Now not only can I nerd out building fake rockets and spaceships, I can nerd out by writing scripts to control them from a separate machine! It's crazy.

Link to comment
Share on other sites

My first idea at a project was to determine how much science is available for all of the experiments on the current craft at the current time. It looks like much of this part of the KSP API is not exposed by kRPC, and unfortunately, the reason I'm here is because my python is good but my C# is non-existent.

I think I have identified the parts of the API that need to be exposed, but I'm not sure exactly how much work is involved in this. This code is taken from @SpaceTiger's AutomatedScienceSampler addon:

    public float GetScienceValue(ModuleScienceExperiment baseExperiment, Dictionary<string, int> shipCotainsExperiments, ScienceSubject currentScienceSubject)
    {
      return Utilities.Science.GetScienceValue(shipCotainsExperiments, baseExperiment.experiment, currentScienceSubject);
    }

ModuleScienceExperiment, ScienceSubject, and GetScienceValue are all a part of the KSP API, I'm just not sure how to put things together such that I can pull the right information out of a part, generate the right objects, and pass them to GetScienceValue.

For a little context, development of the mod 'Science Alert' has been slow (no updates since 1.0.4), and I want to see if I can put a kRPC python script together that kills warp when non-zero science values are detected on any parts with experiments on the current vessel. It's not intended to have very much functionality, just this bare-bones behavior.

So, one can get all of the parts with experiments on the vessel with i.e.

parts_with_experiments = vessel.parts.with_module('ModuleScienceExperiment')

Then, one can access and trigger the science experiments by doing, i.e.

parts_with_experiments[0].trigger_event(str(parts_with_experiments.events[0]))

(trigger_event doesn't accept unicode strings)

What I'd love is to be able to say something like:

parts_with_experiments[0].get_science_value()

Although that's probably asking for more than the KSP API can handle, and I will probably have to pull out the above mentioned objects first to pass to the KSP getScienceValue.

Is this something that's pretty simple to implement, and is there anyone who can put the C# together for this extension of kRPC?

Edited by drhay53
Link to comment
Share on other sites

On 5/28/2016 at 3:43 PM, Lorentz said:

Hi there!

This is the *best* addon, thank you! A couple questions:

  1. Is there a way to get a list of vessels that can be launched from VAB/SPH?
  2. Is there a way to recover a vessel once landed on Kerbin?
  3. I see clicking through the science collected pop-up window has been requested on this forum thread before. Is this not yet implemented?

Thank you once again!

Unfortunately the answer is "no, not yet" to all three questions :( 1 and 2 sound like trivial additions, so will try and get them into the next version.

I've not had time to look into KSP's science API at all yet. Definitely on the todo list. A few people are wanting to at least be able to interact with the science pop up window, so I think a good starting point would be to get that working first, and later flesh it out into a more complete API that simplifies the running of experiments (without having to go through part module events as @drhay53 was mentioning).

On 5/29/2016 at 11:07 PM, churai said:

At "print('enable new tank here')" I am trying to run something like tank.resources.enabled = True but I have no idea. (https://krpc.github.io/krpc/python/api/space-center/resources.html)

It's very possible that there is a bug with resources.enabled = true. This feature was added quite recently, so is probably not the most stable. I don't have much time right now to look into it, but will have a look later this week.

Edited by djungelorm
Link to comment
Share on other sites

On 6/4/2016 at 1:55 AM, churai said:

djungel0rm: :) That would be so awesome. 

Got it working :)

import krpc

conn = krpc.connect()
vessel = conn.space_center.active_vessel
tanks = {}

# gets list of remaining xenon tanks
def gettank():
    global tanks
    tanks = {}
    for part in vessel.parts.all:
        if 'XenonGas' in part.resources.names:
            tanks[part] = part.decouple_stage

# decouple all empty tanks
def removeemptytank():
    for decoupler in vessel.parts.decouplers:
        if decoupler.part.children[0].resources.amount('XenonGas') == 0:
            decoupler.decouple()
            gettank()
            enabletank()

# enable next tank
def enabletank():
    for tank in tanks:
        if tanks[tank] == max(tanks.values()):
            for resource in tank.resources.with_resource('XenonGas'):
                resource.enabled = True
            return

# main loop
while True:
    gettank()
    removeemptytank()
    enabletank()

I had to change a few things to get it to work:

  • It gets the tanks based on what resource they contain, rather than the part name (bit more extensible - and worked with my example craft that used a different xenon tank)
  • The values in the tanks dictionary are set to part.decouple_stage (the number of stage the decoupler attached to the tank fires in). Your previous code was setting the value to the tanks depth in the parts tree - which isn't what we want. In my example craft this value was 3 for every tank!
  • enabletank() uses the resources object to check the amount of xenon - bit cleaner than using the mass of the part
  • After decoupling a tank it calls gettank() to recompute the list of tanks, otherwise the script will try to inspect a decoupled part, causing a NullReferenceException

Also, the resource API struck me as slightly clunky - I think it would be good to add a tank.resources.enabled property to future versions of the mod that can be used to enable/disable all the resources in a part. That would avoid having to use the for loop to set the XenonGas resource to enabled.

Edited by djungelorm
Link to comment
Share on other sites

17 hours ago, djungelorm said:

Got it working :)


import krpc

conn = krpc.connect()
vessel = conn.space_center.active_vessel
tanks = {}

# gets list of remaining xenon tanks
def gettank():
    global tanks
    tanks = {}
    for part in vessel.parts.all:
        if 'XenonGas' in part.resources.names:
            tanks[part] = part.decouple_stage

# decouple all empty tanks
def removeemptytank():
    for decoupler in vessel.parts.decouplers:
        if decoupler.part.children[0].resources.amount('XenonGas') == 0:
            decoupler.decouple()
            gettank()
            enabletank()

# enable next tank
def enabletank():
    for tank in tanks:
        if tanks[tank] == max(tanks.values()):
            for resource in tank.resources.with_resource('XenonGas'):
                resource.enabled = True
            return

# main loop
while True:
    gettank()
    removeemptytank()
    enabletank()

I had to change a few things to get it to work:

  • It gets the tanks based on what resource they contain, rather than the part name (bit more extensible - and worked with my example craft that used a different xenon tank)
  • The values in the tanks dictionary are set to part.decouple_stage (the number of stage the decoupler attached to the tank fires in). Your previous code was setting the value to the tanks depth in the parts tree - which isn't what we want. In my example craft this value was 3 for every tank!
  • enabletank() uses the resources object to check the amount of xenon - bit cleaner than using the mass of the part
  • After decoupling a tank it calls gettank() to recompute the list of tanks, otherwise the script will try to inspect a decoupled part, causing a NullReferenceException

Also, the resource API struck me as slightly clunky - I think it would be good to add a tank.resources.enabled property to future versions of the mod that can be used to enable/disable all the resources in a part. That would avoid having to use the for loop to set the XenonGas resource to enabled.

:o This. Is. Brilliant! 

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