Serious error about position and velocity
LIAOTIANx opened this issue · 15 comments
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.
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
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 useelapsed_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.
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 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.
@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. 😀
@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.
@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.
This could be related to #639 . Going to attempt to address the hybrid reference frame issues and hopefully this will be resolved. Removing triage.
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:
Sample data, vessels traveling straight upwards (normal to planet surface), surface reference frame:
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
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).
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.
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
Modify "unpack" parameter? Are there other parameters need to be changed?
@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?
@LIAOTIANx @JacekCzupyt Great work in spotting that. I will work on a patch and see if it resolves some of these possibly related issues.