microsoft / AirSim

Open source simulator for autonomous vehicles built on Unreal Engine / Unity, from Microsoft AI & Research
https://microsoft.github.io/AirSim/
Other
16.4k stars 4.57k forks source link

Unexpected Drone Throttle Behavior in Unreal Blocks Project with Python API #2466

Closed Vadaam closed 2 years ago

Vadaam commented 4 years ago

Python: 3.8 Unreal Version: 4.18.3 Windows 7 64 bit Airsim Version 1.2.2

Hi,

I'm trying to integrate a custom controller with Airsim through the use of a custom Python API. The controller in question has the functionality very similar to that of a Wii Nunchuk - Two buttons, and a stick.

The python script reads signals from the controller in through the serial port, and then interprets them into RC commands that it sends onto Airsim. However, I'm getting some very unexpected behaviour, and I can't figure out where its coming from.

The positive and negative power of the throttle is assigned to the two buttons, and at launch, the drone rises and falls correctly when the two respective buttons are pressed. However, when I fly the drone up, and activate its pitch or roll functionality (yaw is not yet included in the project) and then allow it to return to neutral, then reengage the throttle, the drone doesn't active it in the same way that it does on the program's startup.

When powered with positive throttle, the drone just shakes in place, and slowly falls in altitude. When powered with the negative throttle, the drone points one of its corners down at a 45 degree angle, and descends in that direction. When the negative throttle is removed, and then applied a half-second later, the opposite corner dips, and it the descends in that direction, losing height in a similar fashion to a falling leaf.

I've tried hard setting pitch and roll values to zero when engaging the throttle, but this doesn't seem to make any changes to the issue. I can't figure out where else to look, as the code is really simple at this stage. I can't help but feel I'm missing something.

Would you be able to help me out?

I have an MP4 of the drone's behaviour saved, although I'm unable to attach it to this post. Please let me know if you need to see it, and I can try and find a way of sending it over.

Code is shown below.

`import setup_path import airsim import msvcrt

import os import tempfile import pprint import time import serial

// Try to connect to the port try: myPySerial = serial.Serial('COM5', 9600) #Using COM5 as serial port connection except: print('Failed to connect. Try running this command in the command line to see your available serial port conections:') print('python -m serial.tools.list_ports') print('(Note that this is not your command line, this is a the Python Interpreter)') exit()

// connect to the AirSim simulator client = airsim.MultirotorClient() client.confirmConnection() client.enableApiControl(True) client.armDisarm(True)

state = client.getMultirotorState() s = pprint.pformat(state) print("state: %s" % s)

client.moveByManualAsync(vx_max = 1E6, vy_max = 1E6, z_min = -1E6, duration = 1E10) airsim.wait_key('Manual mode is setup. Press any key to send RC data to takeoff')

values for movement

throttle = 0.0 roll = 0.0 pitch = 0.0 yaw = 0.0 soft = 0.01 mild = 0.05 coarse = 0.1 nsoft = -0.01 nmild = -0.05 ncoarse = -0.1 counter = 0

while True:

line = myPySerial.readline()
line = line.decode()
counter = 0

#these are the commands received through the serial bus from the controller

#pitch forward
if line == "F1\n":
    pitch = soft
elif line == "F2\n":
    pitch = mild
elif line == "F3\n":
    pitch = coarse

#pitch backward
elif line == "B1\n":
    pitch = nsoft
elif line == "B2\n":
    pitch = nmild
elif line == "B3\n":
    pitch = ncoarse

#roll right
if line == "R1\n":
    roll = soft
elif line == "R2\n":
    roll = mild
elif line == "R3\n":
    roll = coarse

#roll left
elif line == "L1\n":
    roll = nsoft
elif line == "L2\n":
    roll = nmild
elif line == "L3\n":
    roll = ncoarse

#go up / power throttle
if line == "UOn\n":
    throttle = 1
    pitch = 0
    roll = 0
elif line == "UOff\n":
    throttle = 0

#go down / negative power to throttle
elif line == "DOn\n":
    throttle = -1
    pitch = 0
    roll = 0
elif line == "DOff\n":
    throttle = 0

#keep signal steady when nothing is being received on the serial bus
while myPySerial.in_waiting == 0:

    client.moveByRC(rcdata = airsim.RCData(pitch = pitch, throttle = throttle, roll= roll, is_initialized = True, is_valid = True))

    #if nothing is received for 500 cycles, then decay pitch/roll to 0
    if counter > 500:
        pitch *= 0.95
        roll *= 0.95
        if pitch < 0.001 and pitch > -0.001:
            pitch = 0
        if roll < 0.001 and roll > -0.001:
             roll = 0

    counter += 1
    time.sleep(0.0005)

// that's enough fun for now. let's quit cleanly client.enableApiControl(False) `

Thank you very much for your help in advance; any and all advice would be much appreciated.

rajat2004 commented 4 years ago

Hi, Video would be good here(maybe upload to Google Drive and share the link?), plus a minimal example script to reproduce the issue would be very useful

jonyMarino commented 4 years ago

@Vadaam do you still have this issue or you was able to solve it?

jonyMarino commented 2 years ago

Closed due to lack of response. Feel free to ask to reopen if you can answer our questions. Thanks!