Skip to content

Multirotor Y-axis drift but not X-axis #4780

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

Open
WreckItTim opened this issue Jan 25, 2023 · 2 comments
Open

Multirotor Y-axis drift but not X-axis #4780

WreckItTim opened this issue Jan 25, 2023 · 2 comments

Comments

@WreckItTim
Copy link

WreckItTim commented Jan 25, 2023

Bug report

  • AirSim Version/#commit: 1.8.1
  • UE/Unity version: N/A - using release blocks v1.8.1 Windows
  • autopilot version: N/A
  • OS Version: Windows 10 Pro

What's the issue you encountered?

I was doing some RL training, and noticed a drift in some of the episodes. I wrote some test script to isolate the problem and found that there is some odd behavior that happens only along the Y-axis. This is causing the drift, but not apparent along the X-axis.

I added a YouTube video showing the problem: https://youtu.be/Nwjk_-ua3K4
Also below is the test script you can use to repeat the isolated problem and tinker with it yourself.

Settings

{
'ClockSpeed': 8,
"SimMode": "Multirotor",
"ViewMode": "SpringArmChase",
"SubWindows": []
}

How can the issue be reproduced?

I made this script to just plug and play and repeat error. Run this python script (replacing as needed to launch configuration). I used the v1.8.1 Blocks release on Windows and dropped the parent folder in the same folder as the bellow python script file, along with setup_path.py. After launching, you can use the terminal to input commands.

  1. Enter 'y' to line up with the y-axis then 'f' to move forward. Watch. After moving, the drone will begin to spin in a slow circle. Press 'f' to go forward again. The circle will make the movement forward look like a drift.
  2. Now enter 'x' to line up with the x-axis then 'f' to move forward. Watch. The drone will not spin in a circle. Press 'f' to go forward again, no apparent drift.
  3. Line up with the y-axis again and go forward. The same spin and drift will reappear!
  4. Repeat as much as you want to make sure you're not crazy.

Note that reducing the clock speed will have the same bug but it will be slower and harder to see, but trust me it is still there if you look close enough.

import subprocess
import setup_path
import airsim
import json
import os

release_path = 'Blocks/WindowsNoEditor/Blocks.exe'

flags = '-Windowed'

settings = {
  'ClockSpeed': 8,
  "SimMode": "Multirotor",
  "ViewMode": "SpringArmChase",
  "SubWindows": []
}
settings_path = os.getcwd() + '/settings.json'
json.dump(settings, open(settings_path, 'w'), indent=2)

terminal_command = f'{release_path} {flags} -settings=\"{settings_path}\"'
process = subprocess.Popen(terminal_command, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)

print('send any key when ready...')
x = input()

client = airsim.MultirotorClient()
client.confirmConnection()
client.enableApiControl(True)
client.armDisarm(True)
client.takeoffAsync().join()
client.moveByVelocityAsync(0, 0, -1, 2).join()

facing = ''

def rotate_to(yaw):
	client.rotateToYawAsync(yaw) 
		
def move(x_speed, y_speed, z_speed, duration):
	client.moveByVelocityAsync(x_speed, y_speed, z_speed, duration).join()

while True:
	print('x to rotate facing x-axis')
	print('y to rotate facing y-axis')
	print('f to move forward')
	response = input()
	if response not in ['x', 'y', 'f']:
		print('invalid input')
		continue
	if response == 'x':
		rotate_to(180)
		facing = 'x'
	if response == 'y':
		rotate_to(270)
		facing = 'y'
	if response == 'f':
		if facing == 'x':
			move(-2, 0, 0, 2)
		elif facing == 'y':
			move(0, -2, 0, 2)
		else:
			print('must enter x or y first')

Include full error message in text form

no error message

What's better than filing an issue? Filing a pull request :).

edit* (did some debugging and found a stop-gap / narrowed down the problem)
I am trying to get some results for my RL research from this asap (have a paper deadline). So I'd be thrilled to just find a stop-gap for the moment, even until a full fix is found. So I did some trial and error tonight....

I have tried the following, but get the same bug:

  1. different map release (AirSimNH)
  2. clockspeed=1
  3. default settings
  4. different PID gains as suggested by https://github.com/microsoft/AirSim/issues/2851
  5. fetching collision info as suggested by https://github.com/microsoft/AirSim/issues/2852
  6. not windowed mode (no flags or settings file passed into command line)
  7. launching Blocks separately from script, then only running control script
  8. using moveToPositionAsync().join()
  9. not using .join()
  10. facing the y-axis but moving along the x-axis

Number 10 gave me the stop-gap I needed! Rotate yaw to face the x-axis, move to desired position, rotate back to original yaw. Works for the moment, LOL!

@WreckItTim
Copy link
Author

Found that a better stop-gap is to either sleep until oscillations stop (expensive) or force the velocity of the drone to 0 in all dims, by adding something like this to where it is needed in your code:

# stabalize drone
if stabelize:
	self._airsim._client.rotateByYawRateAsync(0, 0.1)
	self._airsim._client.moveByVelocityAsync(0, 0, 0, 0.1).join()

@sandilyasg
Copy link

@WreckItTim Can you please share how you set the different PID gains? Is it using the API calls or directly in AirSim/AirLib/include/vehicles/multirotor/firmwares/simple_flight/firmware/Params.hpp?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants