-
Notifications
You must be signed in to change notification settings - Fork 4.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect behavior of MoveToPositionAsync #1643,how to solve it? #1677
Comments
Might help to post your settings.json file so we know what type of drone you are flying and how it was configured. When I try the PX4 drone with this script:
it seems to fly ok, here's the position reported: |
I have experienced exactly the same issue (I posted it in Incorrect behavior of MoveToPositionAsync #1643). { |
@lovettchris My setting.json is the default mode,Is it my setup problem?The UE4 coordinate is converted to the Ned coordinate using ToLocalNed. Is there a problem with my flight mode? I found that when my pixhawk switched to position mode, it actually switched to Altitude mode. Why can't I switch to position mode? |
I think I have the same problem. I am trying to control multiple SimpleFlight drones with the Python API, and I am encountering errors in how MoveToPositionAsync actually moves the drones. For instance, this is a set of commands I gave the drone:
My world is properly aligned, so this should make the drone fly in a nicely aligned square. Instead, this is what the drone does (plotted from the airsim_rec log): Unless I am doing/understanding something wrong, this seems to be a pretty major issue. |
Here's why my flight looks like when running that python script: |
which script? saihv's ? If so I would imagine you would need to add some .join() calls to each of his moveToPositionAsync calls. |
@lovettchris No, sir. The script you posted. I cannot get 2 moveToPositionAsync().Join() calls to ever work. Certainly not 3 or more. Even while putting extra client.enableApiControl(True) all over the place. No dice, I lose control to the failsafe. I'm guessing the problem is with the PX4 params. Could you or someone provide, or could ya'll add to the AirSim repo an generic PX4 params test file that could be used by a new user to help us verify our PX4 sitl setup? params that are optimized to work with all of the test Api's like HelloDrone, etc? I posted my param here: show params |
@lovettchris |
@jasonhbartlett Did you check if the position of the drone in unreal is actually as requested? In my case, using SimpleFlight, the drone overshoots the requested position as described in #1643. This behavior varies considerably with speed. You probably won't see the problem with a low velocity say 1m/s. The problem becomes more serious starting from 5 m/s. using @jasonhbartlett 's script hello_drone3 with 1m/s with 5m/s |
Hi @majouda7 Running in Unreal 5m/s : (Although it seemed to correct itself over time in Unreal) I can chart the path in Unity. |
@jasonhbartlett, in my case the drone doesn't seem to correct itself in unreal over time. This what I get if I put a sleep after each move. It is obvious that the drone is drifting over x and y axes. |
@jasonhbartlett regarding parameters, I did put some info here moveOnPath demo. Saving all parameters would be a maintenance problem because px4 might add or change other unrelated parameters. But the ones I usually use are:
There's also some in px4_sitl. I have found a bug in airsim to do with magnetic declination, so until that is fixed I recommend flying with latitude 0. I put my full set of params here. Let's also rule out C++ versus python, can you run this python test script and paste the results (as text) ? Thanks. import sys
import time
import setup_path
import airsim
def print_position(client):
state = client.getMultirotorState()
gps = state.gps_location
print("gps location lat={}, lon={}, alt={}".format(gps.latitude, gps.longitude, gps.altitude))
pos = state.kinematics_estimated.position
print("local position x={}, y={}, z={}".format(pos.x_val, pos.y_val, pos.z_val))
client = airsim.MultirotorClient()
client.confirmConnection()
client.enableApiControl(True)
client.armDisarm(True)
print_position(client)
landed = client.getMultirotorState().landed_state
if landed == airsim.LandedState.Landed:
print("taking off...")
client.takeoffAsync().join()
else:
client.hoverAsync().join()
if client.getMultirotorState().landed_state == airsim.LandedState.Landed:
print("take off failed, please check message log")
sys.exit(1)
# AirSim uses NED coordinates so negative axis is up.
# z of -7 is 7 meters above the original launch point.
z = -7
# make sure we are at the start location (previous flight might have missed the landing spot by a bit.)
client.moveToPositionAsync(0,0,z,1).join()
print("flying path...")
# this method is async, but we are calling .join() so the script waits for path to complete.
for i in range(100):
time.sleep(3)
pos = client.simGetGroundTruthKinematics().position
print("{:.3f},{:.3f},{:.3f}".format(pos.x_val, pos.y_val, pos.z_val))
client.enableApiControl(True)
client.moveToPositionAsync(-5,0,z,1).join()
pos = client.simGetGroundTruthKinematics().position
print("{:.3f},{:.3f},{:.3f}".format(pos.x_val, pos.y_val, pos.z_val))
time.sleep(3)
pos = client.simGetGroundTruthKinematics().position
print("{:.3f},{:.3f},{:.3f}".format(pos.x_val, pos.y_val, pos.z_val))
client.enableApiControl(True)
client.moveToPositionAsync(5,0,z,1).join()
pos = client.simGetGroundTruthKinematics().position
print("{:.3f},{:.3f},{:.3f}".format(pos.x_val, pos.y_val, pos.z_val))
client.moveToPositionAsync(0,0,-10,1).join()
print("landing")
client.landAsync().join()
print("disarming drone")
client.armDisarm(False)
client.enableApiControl(False)
print("done!")
print_position(client) With this test script I am seeing some sort of AirSim bug where sometimes the moveToPositionAsync call terminates prematurely, possibly thinking it has already reached the intended destination, when it clearly has not. So my graph below shows this problem - it should be a sharp tooth diagram back and forth like you see it do a few times, but most of the time it gets stuck on one end or the other for a while: So this will need some airsim debugging... But I did not see any "Accel #0 fail" or "Gyro #0 fail" errors. I do see lots of "Failsafe enabled:" warnings, which you can safely ignore. |
@lovettchris, Do you have any insights on the variation (offset) of the drone's arriving position with respect to its velocity ? Is there any plans to fix that bug? |
@lovettchris
And here's a picture showing the complete flight path. (I'll have to start publishing these as abstract art :) Please let me know what else I can do to help test things out. Hopefully this bug is traceable. :) Thanks sir! |
Ok, great, so we have a repro for the bug and we should make this a high priority item. I also see the final print_position 0,0,0 but which is another bug, not sure what's happening there, perhaps changing the armed state or the enableApiControl state is impacting the position printed (which it shouldn't)... |
I met the same problem and unfortunately I met another problem #1292 too. Finally I found that I could use def moveToPosition(x, y, z, v):
currentPos = uav.getMultirotorState().kinematics_estimated.position
t = ((currentPos.x_val - x)**2 + (currentPos.y_val - y)**2 + (currentPos.z_val - z)**2)**0.5 / v
delta_x = x - currentPos.x_val
delta_y = y - currentPos.y_val
delta_z = z - currentPos.z_val
vx = delta_x / t
vy = delta_y / t
vz = delta_z / t
uav.moveByVelocityAsync(vx, vy, vz, t)
time.sleep(t)
uav.moveByVelocityAsync(0, 0, 0, 5)
uav.hoverAsync().join() This method is able to make the drone stop at the given position accurately even with a fast speed (e.g. 10m/s in my simple test). So this might be a temporal solution before the bug has been fixed. |
I've encountered this problem and investigated a little inside AirSim source code.
I'm not sure that this is the reason of the discussion above. |
So, this may not solve anyone's problems, but I had a lot of issues in using the join calls for calling absolute positioning and what I have determined is that when using loops inside of Python to do that type of async behavior with the join() calls, either Unreal, Airsim or RPC freaks out about the asynchronous method that freezes the call. My thought would be that it has something to do with freezing the currently running process, when it is supposed to be communicating with the RPC server. (I had the same exact issues using an interrupt-based GPS module and calling sleep in the process loop. Took me 6 months to figure out why it wasn't working!) To solve my issues, as I was writing a simple chase-follow script, I did the following. This isn't refactored in any way but I haven't had any issues with positioning since.
I have gotten this to work with sufficiently large enough distance between points. I currently break up the route into 50 points and then just do this. The route object you are seeing is something I build before starting the drone's movement. I'm going to be writing a GPS based version of this that can go between x,y,z and GPS coordinates to mimic some of what a PixHawk does when interpreting points. Let me know if there are any improvements to this. |
@xxEoD2242, Thanks for the snippet. |
@saihv, would you explain how to plot the vehicle trajectory using |
@lovettchris, thanks for posting nice graph of drone location. I try to plot, but I couldn't find how to get the position continuously. Please, share the function of recording drone location, thanks. |
I was using PX4 drone with a mavlink logger, probably connected to the LogViewer app included in this repo. |
The arrival of the target will vary considerably with speed.
The UE4 coordinate is converted to the ned coordinate using tolocalned, but the arrival of the target point will vary greatly with the speed.I don't know why?
The text was updated successfully, but these errors were encountered: