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

On 21/11/2017 at 7:23 AM, 42. said:

Hi, I'd like to first thank djungelorm for this great mod, it takes KSP to the next level!

I've already programmed a basic rocket landing script, but my code is all over the place and I'd like to make it nicer. To this end, I thought about using streams to get information about the vessel's flight. I, however, run into problems when trying to add a raycasting stream. You see, I use raycasting to determine the location of my potential landing site as opposed to the vessel.surface_altitude attribute because I'm not always landing on perfectly flat terrain. My prototype program casts a ray from the vessel's lower bounding vector in the direction of its velocity vector. I am trying to set up a stream to do this continuously, but run into the following problem: I can't find a way to get an expression for accessing the first element of vessel.bounding_box. Is there a way to do this?

I assume you are doing this in Python? In which case vessel.bounding_box is a Python tuple with 2 elements. You can access the first element using vessel.bounding_box[0] This returns a 3 element tuple with the x, y, z coordinates of the minimum vertex of the bounding box.

2 hours ago, Thertor said:

Will the mod support PHP at some point?

At some point yes. I plan to add grpc support, which would allow many many more languages to communicate, including PHP.

Edited by djungelorm
Typo
Link to comment
Share on other sites

  • 2 weeks later...

I've just released v0.4.3 :D

  • You can now control the rate at which the server sends data to the client over a stream, in Hz. This is settable on the stream object in whatever language you're using. For example, in the python client, this is documented here: http://krpc.github.io/krpc/python/client.html#krpc.stream.Stream.rate
  • The mod now supports KSP versions 1.2.2 and 1.3.0, as well as 1.3.1, for those of you still stuck on older versions due to mods not being updated
  • Low level change: RPC calls can now be made using id numbers instead of the string name of the RPC. This is utilised by the C-nano (Arduino) client, to reduce code size by ~30% (depending on the program) and to vastly reduce the size of messages sent over the wire - handy when you're using a serial i/o connection at 9600 baud...

The full changelog is available here: https://github.com/krpc/krpc/releases/tag/v0.4.3

Link to comment
Share on other sites

On 11/28/2017 at 10:50 PM, djungelorm said:

I assume you are doing this in Python? In which case vessel.bounding_box is a Python tuple with 2 elements. You can access the first element using vessel.bounding_box[0] This returns a 3 element tuple with the x, y, z coordinates of the minimum vertex of the bounding box.

Hi, sorry for the late answer. I am indeed using Python, but I must have not been clear enough in my question: I'm trying to get a stream to cast a ray in the direction the vessel is currently moving from the current lower bounding vector. I can set up a stream for the vessel.bounding_box attribute, and I can set up a stream to cast a ray in the right direction from a fixed point, but I can't find a way to access the first element of vessel.bounding_box with a server-side expression so I can use it as an argument to pass to the raycast_distance function inside a stream. If I use vessel.bounding_box[0] in the stream definition, it just uses the value of the lower bounding vector at initialization and doesn't change when the vessel moves. Is this possible and, if so, how would you go about doing it? Hoping this is somewhat comprehensible, thank you in advance.

Link to comment
Share on other sites

  • 2 weeks later...

I am in the process of trying to move my custom controller from KSP Serial I/O to kRPC.   I suspect it's because I'm literally the worst programmer, but I have been banging my head around getting an Arduino running kRPC C-nano to successfully connect to the KSP plugin via serial connection and cannot for the life of me figure it out.  I am using the example code from the Github repository, just with the modification to replace main() with loop() or setup() as appropriate.  

Quote

#include <krpc.h>
#include <krpc/services/krpc.h>

int main() {
  krpc_connection_t conn;
  krpc_open(&conn, "COM0");
  krpc_connect(conn, "Basic example");
  krpc_schema_Status status;
  krpc_KRPC_GetStatus(conn, &status);
  printf("Connected to kRPC server version %s\n", status.version);
}

No error messages, but the program is clearly hanging at the krpc_open command.  I know the hardware is solid because it kicks right on if I upload my previous (non-kRPC) sketch.  I am sure I am missing something very simple.

Any guidance, or anyone with a working Arduino serial sketch willing to share?

Link to comment
Share on other sites

On 12/13/2017 at 4:20 PM, 42. said:

Hi, sorry for the late answer. I am indeed using Python, but I must have not been clear enough in my question: I'm trying to get a stream to cast a ray in the direction the vessel is currently moving from the current lower bounding vector. I can set up a stream for the vessel.bounding_box attribute, and I can set up a stream to cast a ray in the right direction from a fixed point, but I can't find a way to access the first element of vessel.bounding_box with a server-side expression so I can use it as an argument to pass to the raycast_distance function inside a stream. If I use vessel.bounding_box[0] in the stream definition, it just uses the value of the lower bounding vector at initialization and doesn't change when the vessel moves. Is this possible and, if so, how would you go about doing it? Hoping this is somewhat comprehensible, thank you in advance.

Ah I see. You can't do that yet - looks like I neglected to add operators to extract elements from lists, tuples, sets etc. Have added an issue on github so will get this added soon. https://github.com/krpc/krpc/issues/435

Link to comment
Share on other sites

13 hours ago, commissar_squid said:

I am in the process of trying to move my custom controller from KSP Serial I/O to kRPC.   I suspect it's because I'm literally the worst programmer, but I have been banging my head around getting an Arduino running kRPC C-nano to successfully connect to the KSP plugin via serial connection and cannot for the life of me figure it out.  I am using the example code from the Github repository, just with the modification to replace main() with loop() or setup() as appropriate.  

No error messages, but the program is clearly hanging at the krpc_open command.  I know the hardware is solid because it kicks right on if I upload my previous (non-kRPC) sketch.  I am sure I am missing something very simple.

Any guidance, or anyone with a working Arduino serial sketch willing to share?

Appears I neglected to document this, sorry! The code in the docs shows how to use the library on a system that uses POSIX serial io communication - which uses a string to identify the serial port (like "COM0"). On Arduino, you instead need to pass a pointer to the serial object that should be used for communication (such as a pointer to Serial). I can't test it right now, but I think the following example should work:

#include <krpc.h>
#include <krpc/services/krpc.h>

void setup() {
  krpc_connection_t conn;
  krpc_open(&conn, &Serial);
  krpc_connect(conn, "Basic example");
  krpc_schema_Status status;
  krpc_KRPC_GetStatus(conn, &status);
  printf("Connected to kRPC server version %s\n", status.version);
}

It's annoying that the compiler doesn't give you an error, but it seems passing a string instead of the pointer to a serial object doesn't cause a type error :(

Link to comment
Share on other sites

13 hours ago, djungelorm said:

Appears I neglected to document this, sorry! The code in the docs shows how to use the library on a system that uses POSIX serial io communication - which uses a string to identify the serial port (like "COM0"). On Arduino, you instead need to pass a pointer to the serial object that should be used for communication (such as a pointer to Serial). I can't test it right now, but I think the following example should work:


#include <krpc.h>
#include <krpc/services/krpc.h>

void setup() {
  krpc_connection_t conn;
  krpc_open(&conn, &Serial);
  krpc_connect(conn, "Basic example");
  krpc_schema_Status status;
  krpc_KRPC_GetStatus(conn, &status);
  printf("Connected to kRPC server version %s\n", status.version);
}

It's annoying that the compiler doesn't give you an error, but it seems passing a string instead of the pointer to a serial object doesn't cause a type error :(

Thanks for the quick feedback!  Unfortunately, I am seeing the same lack of function as before.  I did add a Serial.begin(9600) above the code above at the beginning of the setup section - no dice (whether it's included or not).  Arduino's using the default configuration (8N1) and so is the in-game plugin, which is assigned to the COM port used to program the arduino, so I'm pretty sure the setup is correct.  Just from putting random LED-on messages into the code, it looks like it's still hanging at the krpc_open command - and it has the same effect whether the above code is in setup() or in loop().  Also various serial speeds from 9600 all the way to 115200 were tried.

It also definitely looks like the plugin is pointed at the right port, because I can't re-upload to the Arduino as long as the server's started in the in-game plugin.

Is there anywhere I can be looking for logged connection refusals or the like?

Edited by commissar_squid
Link to comment
Share on other sites

On 27/12/2017 at 12:35 AM, commissar_squid said:

Thanks for the quick feedback!  Unfortunately, I am seeing the same lack of function as before.  I did add a Serial.begin(9600) above the code above at the beginning of the setup section - no dice (whether it's included or not).  Arduino's using the default configuration (8N1) and so is the in-game plugin, which is assigned to the COM port used to program the arduino, so I'm pretty sure the setup is correct.  Just from putting random LED-on messages into the code, it looks like it's still hanging at the krpc_open command - and it has the same effect whether the above code is in setup() or in loop().  Also various serial speeds from 9600 all the way to 115200 were tried.

It also definitely looks like the plugin is pointed at the right port, because I can't re-upload to the Arduino as long as the server's started in the in-game plugin.

Is there anywhere I can be looking for logged connection refusals or the like?

I'm back from holiday now so have time again to look at this :) I was mistaken in my previous post - you actually need to pass a pointer to the hardware serial object as the first argument of krpc_open and set the second argument to NULL (it's not used on Arduino). The following code demonstrating this was tested this on my own Arduino and it successfully lights the LED at the end of the program:

#include <krpc.h>
#include <krpc/services/krpc.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  krpc_connection_t conn = &Serial;
  krpc_open(&conn, NULL);
  krpc_connect(conn, "Basic example");
  krpc_schema_Status status;
  krpc_KRPC_GetStatus(conn, &status);
  printf("Connected to kRPC server version %s\n", status.version);
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop() {
}

Hope that helps! I'm in the process of writing up a more complete description of how the library works on Arduino which will be included in the online documentation.

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

Hi there !

You like Kerbal? You like Python? You like Krpc ? (you have a debian distribution running on raspberry, or pc, or virtual machine ?)
Ok, listen.
Im coming from france, and there is, in a town near mine, a guy who develop something interesting...
As life is funny, the project (far from kerbal i think) is named "Kalliope" (https://en.wikipedia.org/wiki/Calliope)
It gives by python scripting the possibility to voice command a lot of things... And his pretty intelligently builded.

I've ton of work and should stay focus on powershell and vba for my job, (and focus on my childs at home) so, no time at the moment for learn python,
But im sure there is someone else here who wanna say : "Jeb, lets go for the gravity turn" and look everything happenning while peeling potatoes to make fries for children.

Just for fun.


Here's the project : https://github.com/kalliope-project/kalliope



 

Edited by Val
Fixed wikipedia link
Link to comment
Share on other sites

v0.4.4 has been released!

The full changelog is available here: https://github.com/krpc/krpc/releases/tag/v0.4.4

Link to comment
Share on other sites

This may seem like a dumb question but please keep in mind I have very little knowledge of coding (other than my beloved, MATLAB). How do I run scripts written with editors like pycharm? I can get the spacecraft to do things but only by typing commands into the terminal. I have python 3.6. Thanks in advance. 

Link to comment
Share on other sites

  • 3 weeks later...

This thing looks amazing. However I have got a problem. I think it may be with the computer but this is just to check. I am using the python module. I installed using pip. I tried the connection script but it returned an error;

Spoiler

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import krpc
>>> conn = krpc.connect()
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    conn = krpc.connect()
  File "E:\Python\lib\site-packages\krpc\__init__.py", line 25, in connect
    rpc_connection.connect()
  File "E:\Python\lib\site-packages\krpc\connection.py", line 15, in connect
    self._socket.connect((self._address, self._port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
>>>

I am using windows 8.1 and Norton for antivirus. "the target machine actively refused it" by this I am not sure if it was windows, Norton or ksp. Ksp was open with a vessel on the launch pad.

Edited by Orion Kerman
Link to comment
Share on other sites

On 29/01/2018 at 3:20 PM, dafidge9898 said:

This may seem like a dumb question but please keep in mind I have very little knowledge of coding (other than my beloved, MATLAB). How do I run scripts written with editors like pycharm? I can get the spacecraft to do things but only by typing commands into the terminal.  I have python 3.6. Thanks in advance. 

I actually use the python idle that comes with the python download, however for advice on your current editor search on the website it came from and yes you can run commands one by one strait from the terminal, also using modules such as tkinter (tried a bit myself) you could code it to do functions when a button on a window is pressed or when a key is pressed. For tkinter I would refer you to the youtuber sentdex, he did quite a good tutorial on tkinter.  But yes you should be able to type it one at a time on terminal. And if you save it as .py it will run when you double click.

 

 

Please tell me if I'm wrong in anything

Edited by Orion Kerman
Link to comment
Share on other sites

  • 2 weeks later...

Hi!

I am new to this mod and programming in general. Right now I am trying to make my program output an amount of fuel in current stage. The problem is that it does not do it dynamically for every stage. At the moment the code is much like in tutorial with some changes to determine what the current stage is.

var currentStage = conn.AddStream(() => vessel.Control.CurrentStage);
var currentStageResources = vessel.ResourcesInDecoupleStage(stage: currentStage.Get() - 1, cumulative: false); //btw parameter stage is still broken
                                                                                                               //and needs one to be substracted
var resources = conn.AddStream(() => currentStageResources.All);
while(true)
{
  Console.WriteLine(Calculations.GetFuel(resources)) // method GetFuel iterates through resources and returns their total mass. It will return 0 if I stage
}

I thought that making currentStageResources a stream would solve the problem but that's not possible. And as I understand it putting the definition of currentStageResources inside the loop, while works, is not the best way to do it. Or is it? Should I even bother?

Link to comment
Share on other sites

On 02/03/2018 at 1:24 PM, logaritm said:

argh, I'm failing miserably at building the c++ library for windows, built it fine for Linux but that does not help me much, anyone want to describe how they built the library for use in windows?

Should work fine using Cygwin or MSYS2 (with MinGW). I wrote up a little guide recently for setting up a build environment using MSYS2 and CodeBlocks: https://gist.github.com/djungelorm/f19163ee8c68c16f9e4f253a3b464ece

On 07/03/2018 at 11:53 AM, FumbeiNumbie said:

Hi!

I am new to this mod and programming in general. Right now I am trying to make my program output an amount of fuel in current stage. The problem is that it does not do it dynamically for every stage. At the moment the code is much like in tutorial with some changes to determine what the current stage is.


var currentStage = conn.AddStream(() => vessel.Control.CurrentStage);
var currentStageResources = vessel.ResourcesInDecoupleStage(stage: currentStage.Get() - 1, cumulative: false); //btw parameter stage is still broken
                                                                                                               //and needs one to be substracted
var resources = conn.AddStream(() => currentStageResources.All);
while(true)
{
  Console.WriteLine(Calculations.GetFuel(resources)) // method GetFuel iterates through resources and returns their total mass. It will return 0 if I stage
}

I thought that making currentStageResources a stream would solve the problem but that's not possible. And as I understand it putting the definition of currentStageResources inside the loop, while works, is not the best way to do it. Or is it? Should I even bother?

Do you need to use streams? If performance isn't critical you could just use plain RPCs - you are using a polling while loop anyway so I don't think that would be an issue.

Another approach would be to use an event to detect when the current stage changes, and when it does obtain a new resources object (by calling ResourcesInDecoupleStage) to be used when calling Calculations.GetFuel.

Link to comment
Share on other sites

7 hours ago, djungelorm said:

Should work fine using Cygwin or MSYS2 (with MinGW). I wrote up a little guide recently for setting up a build environment using MSYS2 and CodeBlocks: https://gist.github.com/djungelorm/f19163ee8c68c16f9e4f253a3b464ece

Do you need to use streams? If performance isn't critical you could just use plain RPCs - you are using a polling while loop anyway so I don't think that would be an issue.

Another approach would be to use an event to detect when the current stage changes, and when it does obtain a new resources object (by calling ResourcesInDecoupleStage) to be used when calling Calculations.GetFuel.

Already got it working, just downloaded the source and built the lib

Link to comment
Share on other sites

You're a monster, I used to just program during work, now I program all the day AND work with math when I come home...

You see what have done to my life?, you feel no shame?, do you get joy from doing this to people?

(shake fist in anger)

Link to comment
Share on other sites

I some some questions regarding the auto pilot, first is it possible to disable it for one axis?

Second, if i want it to adjust slower to new commands do I increase all the tuning values with the same precentage or is it better to adjust them in different proportions?

Link to comment
Share on other sites

Hopefully someone smarter will answer in an hour or two...  but...  

To disable the autopilot on an axis, setting the kP, KI, and KD values to zero should do it, I'd think?   The AP would still be calculating and would tell you errors, but it wouldn't have any steering authority?

To make it respond slower to new commands, you'd decrease the kP and then tune the kI...  P responds to immediate errors and I responds to errors over time... so the longer it's wrong the stronger the I correction would be.

It sounds to me like you've got a unique use case?   What are you trying to do?  

It might make more sense to roll your own autopilot if you have specific needs?   It's not hard to do in KRPC!  

 

Link to comment
Share on other sites

I'm currently playing with the whole "realism overhaul" package including "real space" so i am trying to code a "normal" gravity turn, so far the actual gravity turn works flawlessly but i would want the autopilot to still correct any deviations in heading/roll, also i feel that currently the autopilot is way to aggressive to do some maneuvers in atmosphere like the initial tip of the gravity turn, i could just turn of the autopilot and set the pitch manually but then the autopilot wont correct the other axis's.

Link to comment
Share on other sites

4 minutes ago, logaritm said:

I'm currently playing with the whole "realism overhaul" package including "real space" so i am trying to code a "normal" gravity turn, so far the actual gravity turn works flawlessly but i would want the autopilot to still correct any deviations in heading/roll, also i feel that currently the autopilot is way to aggressive to do some maneuvers in atmosphere like the initial tip of the gravity turn, i could just turn of the autopilot and set the pitch manually but then the autopilot wont correct the other axis's.

Hi! Not sure if I can help you with your question but I wonder what you mean by normal gravity turn. Especially compared to actual gravity turn.

My script gradually turns to 45 degrees before 12 km, then it continues turning and flattens out right at apogee. This approach is far from real gravity turn. If only I could find an equation that would describe ships trajectory. Then locking autopilot's pitch and heading to alpha and 90 (where alpha is defined by the equation) would be a relatively easy thing. Meh, if only...

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