Jump to content

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


djungelorm

Recommended Posts

28 minutes ago, sashan said:

Hello, how do I detect if server has disconnected a Python client? I kill connection from the game when something starts going wrong but then I have Python processes hanged on my PC. 

I don't think the python program will exit unless it attempts to use the connection, at which point it should get an raise an OSError (I think... not able to test it right now)

Link to comment
Share on other sites

I know it won't. I need a way to track connection and terminate the program when the server breaks it. Well, it can be done by tracking errors but IMO there should be easier and cleaner way.

Also, a question. Can I get KSP's internal time with microsecond accuracy somehow? Running PIDs off computer's time is wrong since should the game slow down PID gains would all be wrong

 

Link to comment
Share on other sites

Thanks @djungelorm for answering my previous questions. I indeed wanted to deploy landing legs and thanks to your help this now works. I also got the air brakes working. I'm getting closer to a crude self landing rocket.

I have to ask one more question, because I just don't get reference frames. I want to get the speed of my rocket stage and I get zero's on vessel.flight().speed, velocity and such. I understand I need to use a reference frame, but I'm not sure how to apply that. I've tried this:

print str(vessel.flight().speed(Vessel.surface_reference_frame))

and this:

vessel.flight().surface_reference_frame = True

print str(vessel.flight().speed)

But that all doesn't work or gives errors.

I think I need a hint to go further.

Link to comment
Share on other sites

3 hours ago, sashan said:

I know it won't. I need a way to track connection and terminate the program when the server breaks it. Well, it can be done by tracking errors but IMO there should be easier and cleaner way.

I'll look into it and get back to you!

3 hours ago, sashan said:

Also, a question. Can I get KSP's internal time with microsecond accuracy somehow? Running PIDs off computer's time is wrong since should the game slow down PID gains would all be wrong

spacecenter.ut gives the current universal time (which KSP's notion of a global absolute time) in seconds with floating point accuracy. Is that sufficient? http://krpc.github.io/krpc/python/api/space-center/space-center.html#SpaceCenter.ut

1 hour ago, BaryonicMan said:

Thanks @djungelorm for answering my previous questions. I indeed wanted to deploy landing legs and thanks to your help this now works. I also got the air brakes working. I'm getting closer to a crude self landing rocket.

I have to ask one more question, because I just don't get reference frames. I want to get the speed of my rocket stage and I get zero's on vessel.flight().speed, velocity and such. I understand I need to use a reference frame, but I'm not sure how to apply that. I've tried this:

print str(vessel.flight().speed(Vessel.surface_reference_frame))

and this:

vessel.flight().surface_reference_frame = True

print str(vessel.flight().speed)

But that all doesn't work or gives errors.

I think I need a hint to go further.

Glad you got the legs working :)

There are some examples in the tutorials of how to get the speed of a vessel either relative to the orbit or to the surface (equivalent to the values shown on the navball in game): http://krpc.github.io/krpc/tutorials/reference-frames.html#vessel-speed

That page is worth a read as it should explain the concepts behind reference frames. Let me know if that helps!

Link to comment
Share on other sites

Hey, I saw some of SpaceX's look rougher than that!   You didn't have a fireball that obliterated the camera filming it like they did one time I was watching!

I don't know if it helps with your approach at all, but in the library at https://github.com/krpc/krpc-library/tree/master/Art_Whaleys_KRPC_Demos my landing script has a python port of the mechjeb suicide burn algorithm (with a couple of changes.  I think I do a better job of clearing terrain obstacles because I test them along the descent path, not just at the projected landing site...  and I make my calculations and fly my landings assuming 95% of max thrust, but with the loop testing if we're ever over speed and boosting to full power when necessary, for an extra safety factor.)   It works pretty reliably for automated landings on the mun, but that's the only test case I'd done with it.   It doesn't consider atmospheres at all, but still could be useful to you in that final landing burn phase.

It looks like you're chasing the retrograde bug there at the end, and an over correction takes you too far from vertical?   Perhaps a final phase is in order where if the horizontal speed is less than some threshhold, it simply locks vertical instead of trying to chase down those last few meters per second and landing on it's side?

Good idea on passing spacecenter.ut to the pid instead of just time.now() which IS totally what I've been using in my PID loops!  I'll look at rewriting it this way so it adjusts for lag!  

Link to comment
Share on other sites

I was laughing out loud when it went of as a boat. Never occurred to me in KSP before.

9 hours ago, artwhaley said:

I don't know if it helps with your approach at all, but in the library at https://github.com/krpc/krpc-library/tree/master/Art_Whaleys_KRPC_Demos my landing script has a python port of the mechjeb suicide burn algorithm (with a couple of changes.  I think I do a better job of clearing terrain obstacles because I test them along the descent path, not just at the projected landing site...  and I make my calculations and fly my landings assuming 95% of max thrust, but with the loop testing if we're ever over speed and boosting to full power when necessary, for an extra safety factor.)   It works pretty reliably for automated landings on the mun, but that's the only test case I'd done with it.   It doesn't consider atmospheres at all, but still could be useful to you in that final landing burn phase.

I have come across your github library yesterday, but I wanted to try to program this myself first. I'll have a look at it now. Your code looks a lot neater than mine :)

9 hours ago, artwhaley said:

It looks like you're chasing the retrograde bug there at the end, and an over correction takes you too far from vertical?   Perhaps a final phase is in order where if the horizontal speed is less than some threshhold, it simply locks vertical instead of trying to chase down those last few meters per second and landing on it's side?

Good idea on passing spacecenter.ut to the pid instead of just time.now() which IS totally what I've been using in my PID loops!  I'll look at rewriting it this way so it adjusts for lag!  

Yes, I've seen the same behaviour in previous attempts. I might turn off retrograde and tell it just to pitch up 0% for the last meters.

There's still a lot to be done, before I get my rockets nicely land on that island east of the KSC. But step by step I get further.

 

Link to comment
Share on other sites

I have written a PID loop class in Python. It works well for holding altitude, still need to test it with attitude control.

Here it is, with the full program for simple simulation of Grasshopper test. Attitude control is manual. Just build a rocket that can hover, has landing legs and RCS. Put it on the pad, launch script. It will ascend slowly for 10 seconds, then hover, then descend. Manually kill the script after landing. If the rocket pointed roughly up it should do fine, otherwise do some small adjustments.

import krpc
import math
import time

class PIDregulator:
    def __init__(self,kp,ki,kd,minout,maxout,target,state,nowtime,prevtime=0,prevstate=0,midpoint=0):
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.target = target #target setpoint
        self.state = state #current state
        self.minout = minout #minimal needed output
        self.maxout = maxout #maximal needed output
        self.nowtime = nowtime #current time, time.time() works when KSP is running at close to realtime
        self.prevtime = prevtime
        self.prevstate = prevstate
        self.midpoint = midpoint #optional: expected set point, e.g. 1/TWR for throttle control
        self.I_term = 0
        self.preverror = 0
        self.prevtarget = 0
        self.prevtime = nowtime

    def __enter__(self):
        return self

    def update(self,state,target,nowtime,midpoint=0):
        self.state = state
        self.target = target
        self.nowtime = nowtime
        self.error = (self.target - self.state)
        self.dt=(self.nowtime - self.prevtime)
        self.midpoint = midpoint
        # PID regulator
        self.P_term = self.error*self.kp

        self.I_term = self.I_term + self.error*self.dt*self.ki
        #limit I term
        if self.I_term>self.maxout:
            self.I_term = self.maxout
        elif self.I_term<self.minout:
            self.I_term = self.minout

        self.D_term = -(self.error-self.preverror)/self.dt*self.kd

        self.output = self.midpoint + self.P_term + self.I_term + self.D_term
        print(self.P_term, self.I_term, self.D_term)
        return self.output

        self.prevtime = nowtime
        self.prevtarget = target
        self.preverror = error


conn = krpc.connect(name='Grasshopper')
vessel = conn.space_center.active_vessel

alt_kP = 0.3
alt_kI = 0.1
alt_kD = 0.0





ref_frame = conn.space_center.ReferenceFrame.create_hybrid(
    position=vessel.orbit.body.reference_frame,
    rotation=vessel.surface_reference_frame)



conn.drawing.add_direction((0, 1, 0), vessel.surface_velocity_reference_frame)
#some telemetry
ut = conn.add_stream(getattr, conn.space_center, 'ut')
g_constant = conn.add_stream(getattr, conn.space_center, 'g')
altitude = conn.add_stream(getattr, vessel.flight(vessel.orbit.body.reference_frame), 'surface_altitude')
vertical_vel = conn.add_stream(getattr, vessel.flight(vessel.orbit.body.reference_frame), 'vertical_speed')

vessel.control.sas = True
vessel.control.rcs = True
vessel.control.throttle = 0.0
vessel.control.activate_next_stage()

start_time = time.time()
last_update_time = start_time

#initialise PIDs
#args: kp,ki,kd,minout,maxout,target,state,nowtime
altPID = PIDregulator(alt_kP,alt_kI,alt_kD,0,1,0,0,start_time)


while True:
    #manage time
    now_time = time.time()

    #Get data
    velocity = vessel.flight(ref_frame).velocity

    #calculate hover throttle

    if vessel.available_thrust>0:
        hov_thr = vessel.mass/(vessel.available_thrust*0.10197)
    else:
        hov_thr = 1
    #decide on how and where to fly
    if (now_time-start_time<10):
        desired_velz = 2
    elif (now_time-start_time<15):
        desired_velz = 0
    else:
        desired_velz = -2



        #call PID regulator
    throttle = altPID.update(velocity[0],desired_velz,time.time(),midpoint=hov_thr)
    vessel.control.throttle = throttle

    #print(hov_thr,desired_velz,velocity[0],throttle)
Edited by sashan
Link to comment
Share on other sites

@sashan I tried a test to see how the python client behaves when you terminate the connection from the in-game server window. This was my test program:

import krpc
conn = krpc.connect()
while True:
    print conn.space_center.active_vessel.name

and it exited with this exception when I closed the connection:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<string>", line 1, in <lambda>
  File "C:\Python27\lib\site-packages\krpc\client.py", line 90, in _invoke
    response = self._receive_response()
  File "C:\Python27\lib\site-packages\krpc\client.py", line 136, in _receive_response
    data += self._rpc_connection.partial_receive(1)
  File "C:\Python27\lib\site-packages\krpc\connection.py", line 69, in partial_receive
    return self._socket.recv(length)
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host

Do you have a small test program that demonstrates the non-terminating behaviour you are seeing?

Link to comment
Share on other sites

There are 2 instances when it happens:
1. When I run Py script by double-clicking it. Happens all the time, and those processes do consume CPU time.

2. It occasionally happens when I terminate any program. For example, that PID one I've posted. Instead of stating an error it just hangs and does nothing. 

Link to comment
Share on other sites

6 hours ago, sashan said:

Hey, is there a way to get specific impulse for an engine that is not active? I need to calculate dV and TWR that separatron would give me in current situation.

Unfortunately there's only engine.vacuum_specific_impulse and engine.kerbin_sea_level_specific_impulse for inactive engines.

Engine.specific_impulse returns zero if the engine is inactive, but you can calculate it from the current atmospheric pressure, and the vacuum and sea level ISP. The formula (from https://wiki.kerbalspaceprogram.com/wiki/Specific_impulse) is:

Isp(P) = Isp(vac) + (Isp(atm) - Isp(vac)) * P

And I think the pressure you want can be obtained using Flight.static_pressure

Link to comment
Share on other sites

Is this mod capable of sending a RPM part camera view to a webpage? This is something i have been wanting to do for awhile now and before I go through hoops of learning and researching and learning this coding thing is it even possible? an example is here

 

Link to comment
Share on other sites

I've done it: I've managed to land the first stage of a rocket automatically in KSP with Python. The program launches the rocket, releases the second stage and quickly switches to the second stage to start the engine. Then the program quickly switches back to the first stage, does a reentry burn. At 20 km it deploys the air brakes and later does a "near-suicide burn" before it splashes down.

Python code:

https://github.com/Marcel-Jan/KSP-kRPC-Python/blob/master/kRPC_falkon5_git_01.py

.craft file:

https://github.com/Marcel-Jan/KSP-kRPC-Python/blob/master/Falkon-5A.craft

I'm going to do a Youtube video where I explain how the code works later on.

 

Edited by BaryonicMan
Link to comment
Share on other sites

On 13/10/2017 at 2:23 PM, sashan said:

Would it be possible to add raycasting? I really need to detect stuff I'm trying to land on - it will not always be terrain. It's also useful for some other things.

Certainly! I've added it to the todo list: https://github.com/krpc/krpc/issues/423

On 11/10/2017 at 4:14 PM, Redneck said:

Is this mod capable of sending a RPM part camera view to a webpage? This is something i have been wanting to do for awhile now and before I go through hoops of learning and researching and learning this coding thing is it even possible? an example is here

Not currently, although I don't think it would be too difficult to add. I'll look into this (also added a ticket for it here: https://github.com/krpc/krpc/issues/424)

Link to comment
Share on other sites

3 hours ago, djungelorm said:

Certainly! I've added it to the todo list: https://github.com/krpc/krpc/issues/423

Not currently, although I don't think it would be too difficult to add. I'll look into this (also added a ticket for it here: https://github.com/krpc/krpc/issues/424)

Awsome thank you

Link to comment
Share on other sites

v0.4.0 has been released :)

After more than a year in development (in parallel with the 0.3.x versions) I've finally released this rather large update... The main changes include:

  • The plugin now allows you to start more than one server, with different settings.
  • Improved the protobuf communication protocol to improve performance and simplify the protocol (details here: https://github.com/krpc/krpc/pull/325)
  • Added a websockets server protocol for interacting with browsers.
  • (The serial IO server protocol isn't quite finished and will be released in a future update - I didn't want it to delay this release any longer)
  • Streams provide a mechanism to synchronize on stream updates. This allows a client program to wait (efficiently, either using a condition variable or a callback) until the value of a stream changes.
  • Events: you can now add events to the server and wait on them (efficiently). For example, you can create an event that is triggered when your craft reaches a certain altitude. The sub-orbital flight tutorial has been rewritten to use these: http://krpc.github.io/krpc/tutorials/suborbital-flight.html
  • The server no longer freezes when the game is paused, and RPCs have been added to pause/unpause the game
  • RPCs can now throw custom exceptions in the client, making error reporting much nicer.

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

Link to comment
Share on other sites

Here is the video where I explain how I automatically land a rocket stage with kRPC (still 0.3.11 though. Not 0.3.9 as I say in the video.). I go through the whole code I've written so that could either be interesting for you, or extremely boring. In the second case, go to 22:30 to see the glorious splashdown.

Isn't it wonderful how you find your own stupid bugs while describing how your code works? :)

Comments and ideas are welcome.

 

Edited by BaryonicMan
Link to comment
Share on other sites

  • 2 weeks later...

@djungelorm I have a question regarding the c++ documentation.

in the documentation, class Client has a void func close() but I can't seem to use this func. 

krpc::Client conn = krpc::connect("blah", "xxx.xxx.x.x",xxxx,xxxx);

conn.close(); //I tried this but the error says there is no member close() of krpc::Client

Is there a way to close the connection? 

 

Thank you 

Link to comment
Share on other sites

10 hours ago, KerbalX said:

@djungelorm I have a question regarding the c++ documentation.

in the documentation, class Client has a void func close() but I can't seem to use this func. 

krpc::Client conn = krpc::connect("blah", "xxx.xxx.x.x",xxxx,xxxx);

conn.close(); //I tried this but the error says there is no member close() of krpc::Client

Is there a way to close the connection? 

 

Thank you 

Sorry the docs are incorrect. The only way to close the connection is to destroy the client object.

Link to comment
Share on other sites

Exciting news - I've just released v0.4.1, with the following changes:

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

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