kRPC: Control the game using C#, C++, Java, Lua, Python...

kRPC: Control the game using C#, C++, Java, Lua, Python...

7.8k Downloads

Serious error about position and velocity

LIAOTIANx opened this issue · 15 comments

commented

What happened?

When I develope a guidance procedure, I found the position and velocity is inconsistent between game-pausing and game-running.

I want to design a intercept control procedure, that is, a missile aims to hit a spacecraft. But the missile always can't hit the target by the guidance law based on current state. When I debug and try to fix the problem, I find the value of position and velocity obtained by
(In a while loop)

Rr=vessel.flight(RF_FarApproach ).center_of_mass
Vr=vessel.flight(RF_FarApproach ).velocity

print('RrVr_Error:(% 0.4f, % 0.4f, %0.4f, % 0.4f, % 0.4f, %0.4f) m,m/s (ut_c):(% 0.3f) ' 
            % (Rr[0],Rr[1],Rr[2],Vr[0],Vr[1],Vr[2],ut_c))

are not right when game is running. However, their value is correct when the game is pausing (I have verified).

This problem has troubled me a lot of days.

1

How can someone else reproduce it?

Python scripts:

(RF_FarApproach : a aim reference frame)

RF_FarApproach_hy=create_hy(position=vessel.reference_frame,rotation=RF_FarApproach)
while True:
        Rr=vessel.flight(RF_FarApproach).center_of_mass
        Vr=vessel.flight(RF_FarApproach).velocity
        ut_c=conn.space_center.ut
        m = vessel.mass

        Rr_XZ=(Rr[0],0,Rr[2])
        Vr_XZ=(Vr[0],0,Vr[2])
        Rr_XY__Body=conn.space_center.transform_position(Rr_XZ, RF_FarApproach_hy, Body)
        Vr_XY__Body=conn.space_center.transform_position(Vr_XZ, RF_FarApproach_hy, Body)
        fx=(abs(Rr_XY__Body[0])<e_threshold)
        fy=(abs(Rr_XY__Body[1])<e_threshold)
        fz=(abs(Rr_XY__Body[2])<e_threshold)
        fdx=(abs(Vr_XY__Body[0])<de_threshold)
        fdy=(abs(Vr_XY__Body[1])<de_threshold)
        fdz=(abs(Vr_XY__Body[2])<de_threshold)

        if (not fx) | (not fdx):
            F_right=-0.8*Vr_XY__Body[0]*m/Dt/FRCSmax[0]
            vessel.control.right=F_right
        else:
            vessel.control.right=0

        if (not fy) | (not fdy):
            F_forward=-0.8*Vr_XY__Body[1]*m/Dt/FRCSmax[1]
            vessel.control.forward=F_forward
        else:
            vessel.control.forward=0

        if (not fz) | (not fdz):
            F_up=0.8*Vr_XY__Body[2]*m/Dt/FRCSmax[2]
            vessel.control.up=F_up
        else:
            vessel.control.up=0
        
        print('RrVr_Error:(% 0.4f, % 0.4f, %0.4f, % 0.4f, % 0.4f, %0.4f) m,m/s (ut_c):(% 0.3f) ' 
            % (Rr[0],Rr[1],Rr[2],Vr[0],Vr[1],Vr[2],ut_c))

        time.sleep(Dt)

What is your environment?

mod version 0.5.2
game version 1.12.5.3190

Anything else we need to know?

No response

commented

I wonder if the time.sleep(DT) is causing issues? Is DT fixed? Being that it is accurate on pause makes me lean that direction. If DT is too large, it will likely produce error and is not reporting frequently enough to be accurate. If it is too small, you could run into system resource issues. Try adjusting DT and see if that increases or decreases error. Edit - time.sleep() can be problematic for real-time application (assuming it is not related to reference frame). Variable time methods that use elapsed_itme = current_time - previous_time for example may be worth exploring.

Thanks for your suggestion. I just tried the way to use elapsed_itme = current_time - previous_time. However, the problem is still existing.
In the codes before, Dt is fixed at 0.2s. Actually, I have tested a variety of different Dt, but it not works.

From the picture above, the most weird thing is that the position jumps from -12.9m to 4.8m when the game is switched from pausing to running; and jumps back to -12.8m when switched back to pausing, which should not happen if the problem is caused by a inappropriate choosing for Dt.

I forgot an important detail: this issue happens in a large relative speed (300m/s in this case), If the relative speed is small, the values are right.

commented
commented

I wonder if the time.sleep(DT) is causing issues? Is DT fixed? Being that it is accurate on pause makes me lean that direction. If DT is too large, it will likely produce error and is not reporting frequently enough to be accurate. If it is too small, you could run into system resource issues. Try adjusting DT and see if that increases or decreases error.
Edit - time.sleep() can be problematic for real-time application (assuming it is not related to reference frame). Variable time methods that use elapsed_itme = current_time - previous_time for example may be worth exploring.

commented

Thanks for taking a look @GaryDeco

I wonder if using streams would help. As this is stated to work at low relative speed, but breaks at higher relative speeds, server lag could be the cause of the inaccuraciesB By the time the client has executed all those RPC calls in the while loop body, the target vessel may have moved quite a long way. Using streams would significanlty reduce the lag getting the telemetry, i.e. set up streams, then read from them in the while loop.

commented

@LIAOTIANx. As stated above from @djungelorm , a stream is ideal for continuous data collection. There are of course limitations. I ran a simulation collecting speed and position relative to a fixed hybrid reference frame. The data seems accurate. Please review the following: Streaming Data: Python Client
Syntax looks like the following:

import krpc
conn = krpc.connect()
vessel = conn.space_center.active_vessel
refframe = vessel.orbit.body.reference_frame
with conn.stream(vessel.position, refframe) as position:
    while True:
        print(position())

Let us know if it worked out so we can either close this out or identify the root cause.
Also keep in mind...
Don't forget to use the krpc discord forum to seek assistance or just ask questions.
If you wish to share the code in its entirety, it would be much easier to help, otherwise we may miss something due to unknowns. 😀

commented

@GaryDeco @djungelorm
I tried to use streams, and the issue is still existing.

I really want to share my codes with you, but there are some external codes based on matlab procedure, which are too complicate to present here.

I try to describe the scenario more accurate:
In the game scenario: Tranning--Docking
Suppose I have got a trajectory which can intercept with the target vessel. To hit the target, I want to eliminate position error in the terminal guidance stage. So I establish a reference frame using create_relative(), whose Y-axis is the direction from vessel to target vessel at the beginning of terminal guidance stage. In such a reference frame, transverse position changes slowly because almost all velocity distributes on longitudinal axis (Y-axis)
however, the transverse position values always jump between game-pausing and game-running.

From the picture above, the position jumps from -12.9m to 4.8m when the game is switched from pausing to running; and jumps back to -12.8m when switched back to pausing.

Neither changing Dt nor using streams can solve this problem.

commented

Besides, It seems that if the relative speed is less than 80m/s, the position and velocity will be correct (outputs of game-pausing and game-running are the same).

2

commented

@LIAOTIANx I will leave this open and run a test with varied sample rates and stream vs sleep methods. I want to rule out a reference frame issue.

commented

This could be related to #639 . Going to attempt to address the hybrid reference frame issues and hopefully this will be resolved. Removing triage.

commented

I appear to have inadvertently reproduced this problem while working on a very similar project in C#, so I'll add my own observations.

  • I did not explicitly use hybrid reference frames anywhere in my code, I was was able to recreate the issue using the SurfaceReferenceFrame and OrbitalReferenceFrame of the active vessel, and the NonRotatingReferenceFrame of the orbited body. I also recreated it using both properties, and streams.
  • I was not able to find any inconsistency with my vessels relative velocity, only the position.
  • The jump in relative position appeared to always be in the same axis as the vessels velocity relative to the orbited body (orbit prograde/retrograde)
  • The issue also appears to be scaled by the orbital velocity, I preformed a test with an extremely low orbital speed, and the issue was not present or negligible
  • During my experiments, the issue was present regardless of the relative speeds of the vessels, however it constantly vanished a few frames after the distance between the vessels dropped below 200 meters. This appears to be consistent with the data shown by @LIAOTIANx in his last post

Sample data, from low kerbin orbit, surface reference frame:
krpc_1

Sample data, vessels traveling straight upwards (normal to planet surface), surface reference frame:
krpc_2

Red circles highlight inconsistent position data between game paused and running
Blue circles show running position data suddenly jumping around the 200m threshold
Green circles show that running position data becomes consistent with paused position data at close range

My best guess is that the data about the two vessels, or the vessel and reference frame, are being gathered at different physics ticks, causing one to catch up/run away from the other in between. Not sure why getting within 200m would fix that though.

In case it's useful, the code is in the MissileControl project of this repo https://github.com/JacekCzupyt/ksp-krpc-projects

commented

I found the cause of the problem - the target object was not in physics range, causing its position to be inaccurate. In orbit, physics are only loaded when an object enters a 200m radius, which is why the issue suddenly disappeared at that range. I don't know enough about how KRPC and KSP works to tell whether this could be considered a bug, or an inevitable consequence of how the engine and mod work.

For the time being, the easiest fix is to extend the physics range. There are mods that do that, or you manually edit the values at the bottom of the Physics.cfg file in the game directory (or GameData/ModuleManager.Physics if you use ModuleManager).

commented

I found the cause of the problem - the target object was not in physics range, causing its position to be inaccurate. In orbit, physics are only loaded when an object enters a 200m radius, which is why the issue suddenly disappeared at that range. I don't know enough about how KRPC and KSP works to tell whether this could be considered a bug, or an inevitable consequence of how the engine and mod work.

For the time being, the easiest fix is to extend the physics range. There are mods that do that, or you manually edit the values at the bottom of the Physics.cfg file in the game directory (or GameData/ModuleManager.Physics if you use ModuleManager).

@JacekCzupyt Excellent! Thanks very much for your careful works! The limitation of physics range indeed is a reasonable cause. I will try to fix it by your suggestion.

commented

I found the cause of the problem - the target object was not in physics range, causing its position to be inaccurate. In orbit, physics are only loaded when an object enters a 200m radius, which is why the issue suddenly disappeared at that range. I don't know enough about how KRPC and KSP works to tell whether this could be considered a bug, or an inevitable consequence of how the engine and mod work.

For the time being, the easiest fix is to extend the physics range. There are mods that do that, or you manually edit the values at the bottom of the Physics.cfg file in the game directory (or GameData/ModuleManager.Physics if you use ModuleManager).

@JacekCzupyt
001
Modify "unpack" parameter? Are there other parameters need to be changed?

commented

@JacekCzupyt @GaryDeco @djungelorm
You are right. I used mod "PhysicsRangeExtender" to extend the physics range, and the problem I mentioned above is vanished.

Maybe the reference frame issue #639 is also related to physics range?

commented

@LIAOTIANx @JacekCzupyt Great work in spotting that. I will work on a patch and see if it resolves some of these possibly related issues.