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

2 minutes ago, Bosun said:

Maybe?   I open my Python 3.5, and run it from there...should I try running it from a separate cmd line emulator?  (Win doesn't do it's old cmd line anymore, and perhaps I mistakenly thought the Python itself was an emulator....I am trying others now)


Edit - After I download the krpc files from Github - do I place them in the library folder of Python?  

Yeah you're running it in the wrong terminal. You need to run it from command prompt (it's still there on windows, just a bit annoying to find...). On Windows 10 I get to it by clicking start, typing "cmd" and pressing enter.

The krpc-0.3.5.zip, which contains the server plugin, is all you should need to get from github. It should be extracted into your KSP GameData folder. pip install krpc will download and install all the python client (you don't need to download anything manually from github for that).

Link to comment
Share on other sites

37 minutes ago, dewin said:

Do you mean krpc-clientgen?

I tried that originally and went to calling servicedefs directly to to eliminate possible causes, but I've had no luck either way.

Discovered that there's also a krpc-servicedefs (hmm), and same result:


(venv) D:\git\KIPC>krpc-servicedefs KSP\ KSP\GameData\kOS\Plugins\kOS.dll KSP\gamedata\kos\Plugins\kOS.Safe.dll KSP\gamedata\kos\Plugins\ICSharpCode.SharpZipLib.dll KSP\GameData\KIPC\Plugins\KIPCPlugin.dll

Error: b"Failed to load assembly 'KSP\\gamedata\\kos\\Plugins\\kOS.Safe.dll'.\r\nCould not load file or assembly 'kOS.Safe, Version=0.20.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)\r\nAn attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.\r\n"

 

Sorry yes, I meant clientgen.

The following works fine for me in Linux (with all the DLLs in the current working directory):

krpc-clientgen cpp KIPC --ksp /home/alex/workspaces/ksp/ksp-1.1.3.1289 KRPC.SpaceCenter.dll kOS.dll kOS.Safe.dll JsonFx.dll ICSharpCode.SharpZipLib.dll KIPCPlugin.dll

But the equivalent command on Windows gives me an error saying the KIPC service could not be found:

C:\Python27\Scripts\krpc-clientgen.exe cpp KIPC --ksp C:\KSP\1.1.3.1289 KRPC.SpaceCenter.dll kOS.dll kOS.Safe.dll JsonFx.dll ICSharpCode.SharpZipLib.dll KIPCPlugin.dll

I've tracked it down to KRPC.dll failing to dynamically load the types (due to a workaround in the code for an old Mono bug that's no longer necessary...) I've put together a patched version of krpctools for you to try. Install it using:

pip install --upgrade https://krpc.s3.amazonaws.com/deploy/bug/servicedefs-type-loading/571.1/krpctools-0.3.5-3-gb9d0f6d.zip

 

Link to comment
Share on other sites

10 hours ago, djungelorm said:

Sorry yes, I meant clientgen.

The following works fine for me in Linux (with all the DLLs in the current working directory):


krpc-clientgen cpp KIPC --ksp /home/alex/workspaces/ksp/ksp-1.1.3.1289 KRPC.SpaceCenter.dll kOS.dll kOS.Safe.dll JsonFx.dll ICSharpCode.SharpZipLib.dll KIPCPlugin.dll

But the equivalent command on Windows gives me an error saying the KIPC service could not be found:


C:\Python27\Scripts\krpc-clientgen.exe cpp KIPC --ksp C:\KSP\1.1.3.1289 KRPC.SpaceCenter.dll kOS.dll kOS.Safe.dll JsonFx.dll ICSharpCode.SharpZipLib.dll KIPCPlugin.dll

I've tracked it down to KRPC.dll failing to dynamically load the types (due to a workaround in the code for an old Mono bug that's no longer necessary...) I've put together a patched version of krpctools for you to try. Install it using:


pip install --upgrade https://krpc.s3.amazonaws.com/deploy/bug/servicedefs-type-loading/571.1/krpctools-0.3.5-3-gb9d0f6d.zip

 

Will give that a go tonight.  If all goes well, I'll have a proper release ready.

Link to comment
Share on other sites

10 hours ago, dewin said:

Will give that a go tonight.  If all goes well, I'll have a proper release ready.

And still no-go, same "an attempt was made to load an assembly from a network location error as before:

(venv) D:\git\KIPC\dlls>krpc-clientgen cpp KIPC --output-defs defs.json --ksp D:\git\KIPC\KSP  KRPC.SpaceCenter.dll kOS.dll kOS.Safe.dll JsonFx.dll ICSharpCode.SharpZipLib.dll KIPCPlugin.dll
Error: b"Failed to load assembly 'D:\\git\\KIPC\\dlls\\kOS.dll'.\r\nCould not load file or assembly 'kOS, Version=0.20.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)\r\nAn attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.\r\n"

... oh.  But it seems to be giving correct output if I completely ignore all of the dependent assemblies, using.  So problem solved!  (still no idea why it can't load kOS though)

krpc-clientgen cpp KIPC --output-defs defs.json --ksp D:\git\KIPC\KSP  KIPCPlugin.dll

 

 

Edited by dewin
Link to comment
Share on other sites

Ok so here is my weekly confusing reference frame kRPC problem....

I want to point my vessel at something.  Seems this would be a very common thing right?  In my case I want to point my vessel at the sun so that my solar panels get optimum exposure.  Actually I want to point the back of my vessel at the sun but I figure if I can get the front pointed the right way I should be able to just invert it or something.

Anyway I have had no luck at all in making this work, and I feel like I must be overcomplicating what is probably a often done task in kRPC.

Can anyone provide some assistance?

Link to comment
Share on other sites

Ok so I managed to get this working by using MechJeb to align to the sun, then I got vessel.direction(sun.reference_frame) and recorded the values.  Then I just set the AP to use that ref frame and those values.  This works, but I have no idea how I would have derived it myself.

Edited by Agathorn
Link to comment
Share on other sites

21 hours ago, Agathorn said:

Can anyone provide some assistance?

Here's a fairly simple solution:

import krpc
import math

conn = krpc.connect()
vessel = conn.space_center.active_vessel

def normalized(v):
    l = math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
    return (v[0]/l, v[1]/l, v[2]/l)

ref = vessel.orbital_reference_frame
d = normalized(conn.space_center.bodies['Sun'].position(ref))

ap = vessel.auto_pilot
ap.target_direction = d
ap.reference_frame = ref
ap.engage()

while True:
    pass

The trick is that it uses the vessels orbital reference frame. The origin (0,0,0) in this frame is the center of the vessel, so the direction to the sun is simply the position of the sun (but normalized to have a length of 1).

Also, this reference frame does not rotate with the vessel, so the autopilot will work in this reference frame. If the frame did rotate with the vessel, then the autopilot would try to rotate the vessel but its direction wouldn't change as the frame would just rotate as the vessel rotates! Which makes me think maybe the autopilot should return an error in this case.

Link to comment
Share on other sites

4 hours ago, djungelorm said:

Here's a fairly simple solution:


import krpc
import math

conn = krpc.connect()
vessel = conn.space_center.active_vessel

def normalized(v):
    l = math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
    return (v[0]/l, v[1]/l, v[2]/l)

ref = vessel.orbital_reference_frame
d = normalized(conn.space_center.bodies['Sun'].position(ref))

ap = vessel.auto_pilot
ap.target_direction = d
ap.reference_frame = ref
ap.engage()

while True:
    pass

The trick is that it uses the vessels orbital reference frame. The origin (0,0,0) in this frame is the center of the vessel, so the direction to the sun is simply the position of the sun (but normalized to have a length of 1).

Also, this reference frame does not rotate with the vessel, so the autopilot will work in this reference frame. If the frame did rotate with the vessel, then the autopilot would try to rotate the vessel but its direction wouldn't change as the frame would just rotate as the vessel rotates! Which makes me think maybe the autopilot should return an error in this case.

I totally ran into the issue of having the AP reference frame set to vessel.reference_frame, so yeah I would vote for an error in that case as recovering from the insane spin that os induced in just mere seconds is pretty hard heh.

 

Link to comment
Share on other sites

On 7/2/2016 at 0:15 PM, Agathorn said:

Is there a way to detect what biome the craft is in/over?  I can't seem to find anything in the documentation.  Seems like something that should definitely be there so i'm assuming i'm just overlooking it.

I've added the following biome related RPCs which will be released in the next version. Does this cover everything you need?

  • Vessel.Biome - get the current biome from a vessel object
  • SpaceCenter.Experiment.Biome - get the current biome from an experiment object
  • SpaceCenter.CelestialBody.Biomes - a list of all the biomes on a body
  • SpaceCenter.CelestialBody.BiomeAt - the biome at a given lat/long on a body
Edited by djungelorm
typo
Link to comment
Share on other sites

9 hours ago, djungelorm said:

I've added the following biome related RPCs which will be released in the next version. Does this cover everything you need?

If not already present, it might be good to add the boundary altitudes for flying low/flying high/space low/space high as well.  I have an open PR to KER that does this here, feel free to steal from it.

Link to comment
Share on other sites

On 7/11/2016 at 7:00 AM, PeteWasEre said:

Hi  @djungelorm

I will apologise in advance, because I have a few issues now that I am debugging my controller code and I am sure at least some of them will be dumb errors on my part!

1. Camera distance doesn't seem to take effect for about 2 seconds after a camera mode change. I am setting the camera mode (which changes in the game immediately) and then setting camera.distance = camera.default_distance, this wasn't having any effect. So I forced this to set repeatedly and found that despite setting the distance each time on the next run through the code the distance was the original, and only after about 2s it changed. Is there some limitation here with the camera? I can reproduce it with the following snippet (and the cam starting off default zoom) where the last line does nothing, but change the previous sleep to 3s or higher and it works!


import krpc
import time

conn = krpc.connect(name='Game Controller')
vessel = conn.space_center.active_vessel
cam = conn.space_center.camera
time.sleep(2)
cam.mode = cam.mode.locked
time.sleep(5)
cam.mode = cam.mode.free
time.sleep(2)
cam.distance = cam.default_distance

2. I get an error when checking gear state after launch (or revert to launch) of an aircraft from the SPH. Once the gear is toggled (raised or lowered) the gear.state works fine, but until that first toggle i see the following. It is reproducible direct from the console by querying any gear state. Does it require some kind of initialisation i am missing?


    if gear.state == gear.state.retracted:
  File "<string>", line 1, in <lambda>
  File "C:\Users\petern\AppData\Local\Programs\Python\Python35-32\lib\site-packages\krpc\client.py", line 87, in _invoke
    raise RPCError(response.error)
krpc.error.RPCError: Operation is not valid due to the current state of the object

and it relates to this code:


gear_list = vessel.parts.landing_gear
    gear_up = 0
    gear_down = 0
    for gear in gear_list:
        if gear.state == gear.state.retracted:
            gear_up += 1

 

3. When a kerbal is EVA they still exist as a vessel, but vessel.control doesn't seem to have any effect. I am assuming that the game manages an EVA kerbal differently to a vessel, so this probably isn't supported. Is this assumption correct and is it something that could be included? Note though that issue #148 would probably achieve the same end by allowing controls to be mapped to key presses, and would allow things that are key driven like KAS/KIS also.

Anyway I think that is enough pestering for one night, so I shall leave it at that. Thank you again for all your help and the mod!

Cheers

Pete

 

Sorry for the delay... I forgot I hadn't looked into this!

1. Looks like the camera does indeed take some time before setting properties such as distance will take effect. I see a few options on how to make this better:

  • Make cam.mode = ... block until the camera has finished switching. However this would prevent the script from doing other things while the camera switches
  • Add an extra camera mode so that you can wait while the camera switches, for example while camera.mode == CameraMode.switching: pass Although this is potentially confusing as after setting the camera mode, it won't be the mode you just set!
  • Or we could cache any updates to cam.distance while the switch is happening, and apply the most recent value once the camera has finished switching.

I think I like the last approach best. Thoughts?

2. Looks like when a vessel is launched the landing gear state is an empty string. So there's a bug here that needs fixed!

3. I've not tried using the vessel class for an EVA Kerbal, so this is uncertain territory... something for the TODO list I guess!

Link to comment
Share on other sites

Hey @djungelorm, thanks for the reply.

Regarding the camera i like the last option. I am already doing the second option in my code by setting a timer on change. If this was in the back end though it would be confusing, especially as my camera control is a rotary switch so it skips through various modes and having to wait would make it hard to know what's going on. A cached solution would be best i think, at least in my application.

Looking forward to what you find on EVA :)

I have some other questions for you, as I am struggling with performance in my python code. I have found my coding approach executes FAAARRRR to many RPCs... that's my bad coding. For example:

    part_list = vessel.parts.all
    for p in part_list:
        if (p.temperature / p.max_temperature) > 0.5 or (p.skin_temperature / p.max_skin_temperature) > 0.5:
            output_buffer[2] |= 1 << 1
        if (p.temperature / p.max_temperature) > 0.3 or (p.skin_temperature / p.max_skin_temperature) > 0.3:
            output_buffer[2] |= 1 << 3

This is taking on average 35-40ms to execute! My intention is to move this to a list approach of:

part_temp_list = [(p.temperature, p.max_temperature, p.skin_temperature, p.max_skin_temperature) for p in vessel.parts.all]

and then do the calcs on that list. This reduces the RPCs for my small vessel by 50% but its still taking 30 ms. I think the answer here is to use streams, would I be thinking right? That's going to be a LOT of streams.... and i guess that i will need to manage those streams each time i decouple, break off a part, remove something with KAS etc. Is there any thing i am missing here, another way to do this?

And finally I have to end with a silly question... and i know this is my lack of understanding so sorry in advance. I am struggling to understand how to directly reference some items like LangingGearState. For example:

    gear_list = vessel.parts.landing_gear + vessel.parts.landing_legs
  
    for gear in gear_list:
        if gear.state == gear.state.retracted:

I am checking the gear state against gear.state.retracted, which is an RPC itself and it doesnt make sense to me to query the server to get a defined type to compare against. Its like saying 'is X = TRUE' but looking up True each time on the web. However (in my naive mind) I would have though I can reference this from the imported krpc library. Is that possible or am i doing this the right way?

Thanks again!

Pete

 

Link to comment
Share on other sites

Is it possible to generate client libraries for the dynamic languages (e.g. Python)?  That would aid in things like inspecting in certain IDEs (PyCharm comes to mind) for code completion and whatnot.

Link to comment
Share on other sites

So after some more testing I am starting to understand the performance issues a bit more.

Firstly, streams are AWESOME. After rewriting a lot of my output indicator code to use streams the performance is much better, and with about 65 active streams I see no performance impact in the game. 3k stream RPC/s and it seems happy. Also, the streams don't break if a part is lost. I blew away parts with whack-a-kerbal and the temperature streams for those parts just stopped updating which is very nice. I just reset all my streams on a stage event (and have to think about un-docking too!).

I also rewrote a lot of input code to avoid spamming RPCs. Basically I had a lot of vessel.control.<something> = switch and by moving to an edge detection on the switch the RPCs came right down. The main driver of RPCs is now the mapping in of analogue flight controls which I cant avoid. I wish there was an input stream (but realise that's pretty out there....)

So now my entire code (back end, its a separate process to the GUI) is running < 60ms which is a big improvement.

The performance though is still occasionally variable with a long delay at an RPC request. These delays are often of the order of 50-60ms! I think this might be a synch issue where my code sometimes spans two frames in the game. I tried playing with the blocking time limit with mixed results, increasing this seemed to reduce the frequency but the delay was longer.

So if I can find a way to look up LandingGearState in the library rather than an RPC and move gear states to streams that will help again. And finally I will change my Python / Arduino interaction model to be parallel as they are currently serial and python has to wait for the Arduino which is 12-20ms delay with data transfer time. If I can be consistently sub 50ms I would be happy.

@djungelorm you can probably then ignore most of my previous question on performance issues, but if you can help me understand how to properly reference things like LandingGearState I would be much appreciative!

All this though is on a small 20 part test ship..... I might have to load my old Duna base of 400 parts..... that would be 1200 streams for heat alone! That will be fun :)

 

Link to comment
Share on other sites

@PeteWasEre Glad you figured out streams :) They are indeed quite efficient - the stream updates are all sent to the client in a single network message, and omit values that haven't changed since the last update.

Regarding landing gear state, the python client dynamically creates all the classes and enums for a service when it connects, and they are available via, for example, connection.space_center.LandingGearState. So to check landing gear state with just one RPC, or a stream, you want something like this:

if gear.state == connection.space_center.LandingGearState.retracted:

 

22 hours ago, dewin said:

Is it possible to generate client libraries for the dynamic languages (e.g. Python)?  That would aid in things like inspecting in certain IDEs (PyCharm comes to mind) for code completion and whatnot.

Currently krpc-clientgen has no support for this, but would be easy to add. We would then need a way to tell the python client to use either the hard coded stubs or dynamically created ones. We could do this by adding an extra argument to krpc.connect() so that the user can specify which ones they want to use? I think it might be best to set the default to be to use the hard coded ones - as I don't think people often futz with the RPCs that are available, and it would actually improve the time taken to connect a fair bit (the client can take up to half a second to connect over the network with dynamically created stubs)

Edited by djungelorm
Link to comment
Share on other sites

4 hours ago, PeteWasEre said:

Firstly, streams are AWESOME. After rewriting a lot of my output indicator code to use streams the performance is much better, and with about 65 active streams I see no performance impact in the game. 3k stream RPC/s and it seems happy. Also, the streams don't break if a part is lost. I blew away parts with whack-a-kerbal and the temperature streams for those parts just stopped updating which is very nice. I just reset all my streams on a stage event (and have to think about un-docking too!).  [..]

I'm actually toying with an extension to streams that allows them to trigger callbacks.  This would eliminate needing to examine their values in a loop and instead have a function called whenever their value changes, so it would improve performance clientside as well.  More about this is in this issue here and the PR that references it.  (Python-only for now).

2 hours ago, djungelorm said:

[...] Currently krpc-clientgen has no support for this, but would be easy to add. We would then need a way to tell the python client to use either the hard coded stubs or dynamically created ones. We could do this by adding an extra argument to krpc.connect() so that the user can specify which ones they want to use? I think it might be best to set the default to be to use the hard coded ones - as I don't think people often futz with the RPCs that are available, and it would actually improve the time taken to connect a fair bit (the client can take up to half a second to connect over the network with dynamically created stubs)

I'd almost say take the dynamic one by default since the main reason for wanting generated Python code (and probably Lua/etc as well) is for documentation/inspection/code completion purposes.  In fact, it may be sufficient to generate _just_ the documentation -- i.e. a series of dummy classes and methods with docstrings but no actual code.

Link to comment
Share on other sites

20 hours ago, djungelorm said:

if gear.state == connection.space_center.LandingGearState.retracted:

Thanks, that worked perfectly.

On performance issues I do like @dewin 's idea on stream events. This would be great for things like landing gear state, I only care when it changes.

However I was also reading the conversation on Issue #311

In particular I was drawn to the comment (comment #4) from @djungelorm talking about a general concept of telling the server how to handle some data before streaming it. As an example take heat. I am currently streaming temps from every part to find max(temp/max_temp) and use this to trigger an alert. Given I check skin temp and core temp that's 2 x <number of parts> streams but I only want one number. If I could send a code statement to the server and ask it to stream the result it would make this amazingly efficient!

I also had another thought, would it be possible to group data to send to the server? For example each iteration of my code I set at least 9 items in Vessel.Control (3 x rotation, 3 x translation, throttle, wheel throttle, wheel steering) from my analogue inputs. That's 9 lots of overhead. I was wondering if there was a way I could bundle that to make it one send to the server, then it would dramatically reduce the number of comms. Hypothetically I tell it an object and give it [(attribute,value)] if you know what I mean.

I thought of this based on the earlier description that streams package data together into one send, and thought it would be neat to be able to do that for inputs too. If it was grouped at the object level it would be fine, e.g. I send one batch of control inputs and a separate batch of autopilot inputs etc. It would still cut RPCs from dozens to a handful.

I will leave it to you wiser folk to determine if this is feasible as I realise my technical knowledge of how this all works is 0 and I may be talking out my engine bell :)

I also realise each time I come here I seem to create work for you, thank you again for you patience and efforts!

Cheers

Pete

 

 

 

Link to comment
Share on other sites

16 hours ago, PeteWasEre said:

In particular I was drawn to the comment (comment #4) from @djungelorm talking about a general concept of telling the server how to handle some data before streaming it. As an example take heat. I am currently streaming temps from every part to find max(temp/max_temp) and use this to trigger an alert. Given I check skin temp and core temp that's 2 x <number of parts> streams but I only want one number. If I could send a code statement to the server and ask it to stream the result it would make this amazingly efficient!

Telling the server "how to handle some data before streaming it" essentially boils down to adding some sort of scripting language to kRPC. But... that's exactly what kOS does! I see a few options to make your use case more efficient:

  • Use the kOS/kRPC bridge (linked below). You could write a kOS script to compute the temperature ratios, then expose it through kRPC to your client script.
  • Write a custom service DLL, to add a new RPC to the server that can compute the values you need. This requires C# expertise though. It's documented here: http://krpc.github.io/krpc/extending.html
  • Or if this use case is a common one, we could just add it as an RPC to the main SpaceCenter service.

 

16 hours ago, PeteWasEre said:

I also had another thought, would it be possible to group data to send to the server? For example each iteration of my code I set at least 9 items in Vessel.Control (3 x rotation, 3 x translation, throttle, wheel throttle, wheel steering) from my analogue inputs. That's 9 lots of overhead. I was wondering if there was a way I could bundle that to make it one send to the server, then it would dramatically reduce the number of comms. Hypothetically I tell it an object and give it [(attribute,value)] if you know what I mean.

I thought of this based on the earlier description that streams package data together into one send, and thought it would be neat to be able to do that for inputs too. If it was grouped at the object level it would be fine, e.g. I send one batch of control inputs and a separate batch of autopilot inputs etc. It would still cut RPCs from dozens to a handful.

Yeah there's no way to do this at the moment. Sounds like what we want is some sort of database transaction style thing. I'll have a think about how this could be done.

And don't worry about creating work - I enjoy tinkering with this stuff :P

On 7/24/2016 at 11:33 AM, dewin said:

I'd almost say take the dynamic one by default since the main reason for wanting generated Python code (and probably Lua/etc as well) is for documentation/inspection/code completion purposes.  In fact, it may be sufficient to generate _just_ the documentation -- i.e. a series of dummy classes and methods with docstrings but no actual code.

I'll add a github issue for this.

Edited by djungelorm
typo
Link to comment
Share on other sites

I am less than a novice with coding, and was wondering if someone could help me understand how to do something. I have a standard shuttle, 3 SSMEs, 2 OMS engines, 2 SRBS, big ass ET, all that.

I would like to be able to stream the amount of propellant in each SRB, but I don't understand how to tell one from the other. When I get a list of engines from parts.engines, the 2 SRBS have identical names. I'm sure the answer is really basic, and I apologize for the absurdity of it, but I am just at a loss here. Here's the layout I have so far:

niKz5Nq.png

 

I have most of the fields working with the streams, but I'm just stuck on the SRB thing. Which means I'm also going to have the same problem with the three main engines, too. :(

 

 

OK, I figured a way to differentiate the engines, but I would bet it's not the right way to do it. It works, but I feel bad for doing it. So on to a second issue;

It says that the temperature of parts is reported in kelvin. The highest temp I've seen an SSME generate is about 370 kelvin. I refuse to believe my engine is running a cool 200 degrees F. lol. Am I missing something here?

Edited by Scott76
1 problem sort of solved, a new one created.
Link to comment
Share on other sites

I've done it! I managed to get to orbit with kRPC and Python.

What a lot of fun this is. The rocket completely launches automated and on screen I can follow how my apoapsis and periapsis are doing in the critical phases.

It isn't the most efficient launch I've ever done, but step by step it's getting better.

I've placed the Python code and the craft file online if you want to try it or tinker with it.

 

Link to comment
Share on other sites

  • 2 weeks later...

Hi @djungelorm

  I've been working away at my GUI and have some questions and feature ideas I'd like to raise.

1. Part temps - I note there is an open issue on KOS related to adding part temps so currently that's not an option. I also spent some time reading on how to extend KRPC and came to the conclusion that with zero C# experience its not a wise approach for my blood pressure. Therefore could I request something around max temps be added? Not sure what forms it should take yet but what I am really interested in is the part closest to blowing up. Some thoughts are:

  • Return the n hottest parts and their associated max temps
  • Return all parts that are above x% of their max temp
    • Though I wonder if you can stream something like a list of 'parts'? I guess you can only stream attributes?

There is probably a few ways to approach this, the end result is I would like to show say up to the top 5 parts closest to melting and the % of max temp

2. Rendezvous Data

I am trying to replicate some data I currently get on MechJeb, or via the map view, in my GUI. I can see how I can get target vessel orbital info, relative velocity and position etc. However I cant see how to get intercept data? Specifically I am thinking closest approach distance, time to closest approach, relative velocity at closest approach etc. That is, the interaction of the two orbits. Is this possible?

3. DeltaV

So I can get a total vessel deltaV but I am struggling to get it per stage. Resource and ISP per stage is ok, but mass is hard. For the current stage its ok as I can subtract the resource mass I will use up from the current mass to get my empty mass (or close enough, I wont eat that many snacks during a burn!). However I cant see how to do this for future stages without summing the mass of parts_in_decouple_stage and subtracting from the current mass and imagining what resources are gone etc. If we can get 'Mass in decouple stage' using the cumulative flag = True it should work for the start mass and the end mass is again based on the resource burn. Possible?

4. Waypoint data

In the game you can set Nav waypoints, and I would love to be able to provide guidance to those in my GUI. It will also help later as I want a Nav mode for my autopilot. Is it possible to expose the waypoints? I am mostly interested in reading them but I guess setting would be useful too.

Thanks!

Pete

 

 

 

Link to comment
Share on other sites

Oh, I forgot one!

I am getting strange readouts for orbit.inclination. I am in an equatorial orbit of the Mun and MechJeb pins my inclination at 0.15. However KRPC is reporting vessel.orbit.inclination as 2.88 radians, or 165 degrees.

Other orbital parameters completely align with MJ. Is this a bug or a liveware problem?

Cheers

Pete

 

Link to comment
Share on other sites

Thanks for the suggestions!

1) Aggregate part temps has come up a few times now! Will add to the todo list.

2) Currently there is no "high level" rendevouz data. All the tools should be there to calculate these things your self (i.e. from the orbital elements of the two vessels) but I think we should add the commonly used things (time to intercept, closest approach etc.) as RPCs on the server.

3) Sounds like we want some sort of "aggregate" parts object, a bit like the resources object. By that I mean a single object, that has properties such as mass etc. but for a group of parts rather than an individual part. Then add an RPC to the vessel class to get part groups for specific decouple stages. This could also then be extended to get part groups based on other things, for example all parts on one side of a docking port.

4) I wasn't aware of waypoints! Will look into it.

5) There is a known bug with orbit.inclination. Already got a fix, but not been released yet. Basically, it's doing the wrong thing when trying to convert from degrees to radians. A temporary workaround is to multiple the value you get by Pi / 180. This will give you the correct angle, in degrees.

(PS. I currently don't have internet at home, so progress my rather long todo list for the mod has unfortunately slowed... will be fixed at the end of the month!)

Link to comment
Share on other sites

Hi @djungelorm

 

Thanks for those responses, they all look great!

A quick minor thing that might be a bug. I am trying to dynamically open and close streams of resources but in PyCharm the stream.remove() method is requesting a mandatory parameter 'x', It comes up as method remove(self,x) and gives me a warning if i dont give a parameter. Note it works fine without any parameter, but my CDO (its just like OCD, but with the letters in the right order!) forces me to remove all warnings.

Cheers!

 

Link to comment
Share on other sites

On 8/21/2016 at 6:48 AM, PeteWasEre said:

Hi @djungelorm

 

Thanks for those responses, they all look great!

A quick minor thing that might be a bug. I am trying to dynamically open and close streams of resources but in PyCharm the stream.remove() method is requesting a mandatory parameter 'x', It comes up as method remove(self,x) and gives me a warning if i dont give a parameter. Note it works fine without any parameter, but my CDO (its just like OCD, but with the letters in the right order!) forces me to remove all warnings.

Cheers!

 

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

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