2019-07-27 20:04:39 +02:00

174 lines
5.4 KiB
Python

import pygame
import sys
from pyparrot.Minidrone import Swing
def joystick_init():
"""
Initializes the controller, allows the choice of the controller.
If no controller is detected returns an error.
:param:
:return joystick:
"""
pygame.init()
pygame.joystick.init()
joystick_count = pygame.joystick.get_count()
if joystick_count > 0:
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i)
joystick.init()
name = joystick.get_name()
print([i], name)
joystick.quit()
else:
sys.exit("Error: No joystick detected")
selected_joystick = eval(input("Enter your joystick number:"))
if selected_joystick not in range(joystick_count):
sys.exit("Error: Your choice is not valid")
joystick = pygame.joystick.Joystick(selected_joystick)
joystick.init()
return joystick
def mapping_button(joystick, dict_commands):
"""
Associating a controller key with a command in dict_commands.
:param joystick, dict_commands:
:return mapping:
"""
mapping = {}
for command in dict_commands:
print("Press the key", command)
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.JOYBUTTONDOWN:
if event.button not in (value for value in mapping.values()):
mapping[command] = event.button
done = True
return mapping
def mapping_axis(joystick, axes=["pitch", "roll", "yaw", "vertical"]):
"""
Associating the analog thumbsticks of the controller with a command in dict commands
:param joystick, dict_commands:
:return mapping:
"""
mapping = {}
for i in axes:
print("Push the", i, "axis")
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.JOYAXISMOTION:
if event.axis not in (value for value in mapping.values()):
mapping[i] = event.axis
done = True
return mapping
def _parse_button(dict_commands, button):
"""
Send the commands to the drone.
If multiple commands are assigned to a key each command will be sent one by one to each press.
:param dict_commands, button:
:return:
"""
commands = dict_commands[button][0]
args = dict_commands[button][-1]
command = commands[0]
arg = args[0]
if len(commands) == 1:
if len(args) == 1:
command(arg)
else:
command(arg)
dict_commands[button][-1] = args[1:]+[arg]
else:
if len(commands) == 1:
command(arg)
dict_commands[button][0] = commands[1:]+[command]
else:
command(arg)
dict_commands[button][0] = commands[1:]+[command]
dict_commands[button][-1] = args[1:]+[arg]
def main_loop(joystick, dict_commands, mapping_button, mapping_axis):
"""
First connects to the drone and makes a flat trim.
Then in a loop read the events of the controller to send commands to the drone.
:param joystick, dict_commands, mapping_button, mapping_axis:
:return:
"""
swing.connect(10)
swing.flat_trim()
while True:
pygame.event.get()
pitch = joystick.get_axis(mapping_axis["pitch"])*-100
roll = joystick.get_axis(mapping_axis["roll"])*100
yaw = joystick.get_axis(mapping_axis["yaw"])*100
vertical = joystick.get_axis(mapping_axis["vertical"])*-100
swing.fly_direct(roll, pitch, yaw, vertical, 0.1)
for button, value in mapping_button.items():
if joystick.get_button(value):
_parse_button(dict_commands, button)
if __name__ == "__main__":
swing = Swing("e0:14:04:a7:3d:cb")
#Example of dict_commands
dict_commands = {
"takeoff_landing":[ #Name of the button
[swing.safe_takeoff, swing.safe_land],#Commands execute one by one
[5]#Argument for executing the function
],
"fly_mode":[
[swing.set_flying_mode],
["quadricopter", "plane_forward"]
],
"plane_gear_box_up":[
[swing.set_plane_gear_box],
[((swing.sensors.plane_gear_box[:-1]+str(int(swing.sensors.plane_gear_box[-1])+1)) if swing.sensors.plane_gear_box[-1] != "3" else "gear_3")]#"gear_1" => "gear_2" => "gear_3"
],
"plane_gear_box_down":[
[swing.set_plane_gear_box],
[((swing.sensors.plane_gear_box[:-1]+str(int(swing.sensors.plane_gear_box[-1])-1)) if swing.sensors.plane_gear_box[-1] != "1" else "gear_1")]#"gear_3" => "gear_2" => "gear_1"
]
}
joystick = joystick_init()
mapping_button = mapping_button(joystick, dict_commands)
mapping_axis = mapping_axis(joystick)
main_loop(joystick, dict_commands, mapping_button, mapping_axis)