Created
May 1, 2024 02:06
-
-
Save RishiRavula/fae6f7cb81f06e915cc0df67ab6cd800 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Environment setup commands: | |
# olympe: source ~/code/parrot-groundsdk/./products/olympe/linux/env/shell | |
import tkinter as tk | |
from tkinter import * | |
from PIL import Image | |
from PIL import ImageTk | |
import olympe | |
import subprocess | |
import time | |
from olympe.messages.ardrone3.Piloting import TakeOff, Landing, PCMD | |
from collections import defaultdict | |
from olympe.messages.ardrone3.PilotingSettingsState import MaxTiltChanged | |
from olympe.messages.ardrone3.PilotingState import FlyingStateChanged | |
import olympe.messages.gimbal as gimbal | |
from olympe.messages.rth import set_auto_trigger_mode | |
from olympe.messages.rth import cancel_auto_trigger | |
import pygame | |
# Importing class: | |
import cv2 | |
import numpy as np | |
import time | |
import threading | |
drone_tracker = None | |
class DroneTracker: | |
def __init__(self): | |
self.cap = cv2.VideoCapture(0) | |
self.hsv_value = np.array([68, 81, 170]) # Initial GREEN HSV value | |
# Error margins for HSV thresholding | |
self.hue_margin = 5 | |
self.sat_margin = 40 | |
self.val_margin = 60 | |
self.center_rect_fraction = (0.2, 0.2) # 20% of the frame for both width and height | |
self.last_direction_time = 0 | |
self.base_interval = 3 # Base interval in seconds | |
self.minimum_interval = 0.2 # Minimum interval in seconds | |
self.mouse_click_position = None # Mouse click position for recalibration | |
self.tracking_active = True # Control flag for tracking | |
self.tracking_allowed = False # Control flag for direction output | |
# Position control | |
self.position_index = 0 | |
self.positions = ['center', 'top_right', 'bottom_right', 'bottom_left', 'top_left'] | |
self.last_position_time = time.time() | |
self.margin = 30 # Margin from the border | |
def mouse_click(self, event, x, y, flags, param): | |
if event == cv2.EVENT_LBUTTONDOWN: | |
self.mouse_click_position = (x, y) | |
self.tracking_allowed = False | |
print(f"Calibration point selected at: {self.mouse_click_position}, press SPACE to calibrate and start tracking.") | |
def track(self): | |
cv2.namedWindow('Object Tracking') | |
cv2.setMouseCallback('Object Tracking', self.mouse_click) | |
while self.tracking_active: | |
ret, frame = self.cap.read() | |
if not ret: | |
break | |
current_time = time.time() | |
frame_height, frame_width = frame.shape[:2] | |
center_rect_width = int(frame_width * self.center_rect_fraction[0]) | |
center_rect_height = int(frame_height * self.center_rect_fraction[1]) | |
# Position cycling | |
if current_time - self.last_position_time >= 10: | |
self.position_index = (self.position_index + 1) % len(self.positions) | |
self.last_position_time = current_time | |
# Set position of the rectangle | |
if self.positions[self.position_index] == 'center': | |
center_rect_x = (frame_width - center_rect_width) // 2 | |
center_rect_y = (frame_height - center_rect_height) // 2 | |
elif self.positions[self.position_index] == 'top_right': | |
center_rect_x = frame_width - center_rect_width - self.margin | |
center_rect_y = self.margin | |
elif self.positions[self.position_index] == 'bottom_right': | |
center_rect_x = frame_width - center_rect_width - self.margin | |
center_rect_y = frame_height - center_rect_height - self.margin | |
elif self.positions[self.position_index] == 'bottom_left': | |
center_rect_x = self.margin | |
center_rect_y = frame_height - center_rect_height - self.margin | |
elif self.positions[self.position_index] == 'top_left': | |
center_rect_x = self.margin | |
center_rect_y = self.margin | |
center_point = (center_rect_x + center_rect_width // 2, center_rect_y + center_rect_height // 2) | |
cv2.rectangle(frame, (center_rect_x, center_rect_y), (center_rect_x + center_rect_width, center_rect_y + center_rect_height), (0, 0, 255), 2) | |
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) | |
lower_bound = self.hsv_value - np.array([self.hue_margin, self.sat_margin, self.val_margin]) | |
upper_bound = self.hsv_value + np.array([self.hue_margin, self.sat_margin, self.val_margin]) | |
mask = cv2.inRange(hsv, lower_bound, upper_bound) | |
# Morphological operations to clean up the mask | |
kernel = np.ones((5, 5), np.uint8) | |
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) | |
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) | |
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
if contours: | |
largest_contour = max(contours, key=cv2.contourArea) | |
x, y, w, h = cv2.boundingRect(largest_contour) | |
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) | |
centroid_x = x + w // 2 | |
centroid_y = y + h // 2 | |
distance = np.sqrt((centroid_x - center_point[0]) ** 2 + (centroid_y - center_point[1]) ** 2) | |
max_distance = np.sqrt((frame_width / 2) ** 2 + (frame_height / 2) ** 2) | |
distance_ratio = distance / max_distance | |
self.direction_interval = max(self.minimum_interval, self.base_interval * np.exp(-3 * distance_ratio)) | |
if current_time - self.last_direction_time >= self.direction_interval and self.tracking_allowed: | |
if centroid_x < center_rect_x: | |
print("go left") | |
elif centroid_x > center_rect_x + center_rect_width: | |
print("go right") | |
if centroid_y < center_rect_y: | |
print("go down") | |
elif centroid_y > center_rect_y + center_rect_height: | |
print("go up") | |
self.last_direction_time = current_time | |
cv2.imshow('Object Tracking', frame) | |
key = cv2.waitKey(1) & 0xFF | |
if key == ord('q'): | |
break | |
elif key == ord(' '): | |
if self.mouse_click_position is not None: | |
x, y = self.mouse_click_position | |
hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) | |
self.hsv_value = hsv_frame[y, x] | |
self.mouse_click_position = None | |
print(f"HSV recalibrated to: {self.hsv_value}") | |
self.tracking_allowed = True | |
print("Calibration done. Tracking started.") | |
self.cap.release() | |
cv2.destroyAllWindows() | |
def start_tracking(self): | |
tracking_thread = threading.Thread(target=self.track) | |
tracking_thread.start() | |
def stop_tracking(self): | |
self.tracking_active = False | |
# from enum import Enum | |
# Drone flight state variables | |
is_connected = False | |
camera_on = False | |
gimbal_attitude = 0 | |
horzScalingFactor = 10 | |
vertScalingFactor = 10 | |
p1 = None | |
# Drone constants | |
DRONE_IP = "192.168.42.1" | |
SPHINX_IP = "10.202.0.1" | |
# UI Global variables | |
HEIGHT = 750 | |
WIDTH = 830 | |
BUTTON_WIDTH = 50 | |
BUTTON_HEIGHT = 50 | |
ROTATE_BUTTON_WIDTH = 70 | |
ROTATE_BUTTON_HEIGHT = 400 | |
# Control variables | |
control_quit = 0 | |
control_takeoff = 1 | |
# Button helper functions | |
# Roll drone to the left | |
def roll_left(): | |
drone( | |
PCMD( | |
1, | |
-10, | |
0, | |
0, | |
0, | |
10, | |
) | |
) | |
# Roll drone to the right | |
def roll_right(): | |
drone( | |
PCMD( | |
1, | |
10, | |
0, | |
0, | |
0, | |
10, | |
) | |
) | |
# Pitch the drone forward (move forward) | |
def pitch_fwd(): | |
drone( | |
PCMD( | |
1, | |
0, | |
10, | |
0, | |
0, | |
10, | |
) | |
) | |
# Pitch drone backward (move backward) | |
def pitch_back(): | |
drone( | |
PCMD( | |
1, | |
0, | |
-10, | |
0, | |
0, | |
10, | |
) | |
) | |
# Spin drone to the left | |
def turn_left(): | |
display_message('Turning left...') | |
drone( | |
PCMD( | |
1, | |
0, | |
0, | |
-10, | |
0, | |
10, | |
) | |
) | |
# Turn drone to the right | |
def turn_right(): | |
display_message('Turning right...') | |
drone( | |
PCMD( | |
1, | |
0, | |
0, | |
10, | |
0, | |
10, | |
) | |
) | |
def increase_throttle(): | |
drone( | |
PCMD( | |
0, | |
0, | |
0, | |
0, | |
10, | |
10, | |
) | |
) | |
def decrease_throttle(): | |
drone( | |
PCMD( | |
0, | |
0, | |
0, | |
0, | |
-10, | |
10, | |
) | |
) | |
def move_drone(rollVal=0, pitchVal=0, spinVal=0, throttleVal=0): | |
drone( | |
PCMD( | |
1, | |
int(rollVal), # roll (negative means left, positive means right) | |
int(pitchVal), # pitch (negative means back, positive means forward) | |
int(spinVal), # yaw (negative means turn left, positive means turn right) | |
int(throttleVal), # power (negative means descend, positive means ascend) | |
1, | |
) | |
) | |
# Connect to drone | |
def connect(): | |
global is_connected | |
if not is_connected: | |
display_message('Connecting to the drone...') | |
if(not drone.connect()): | |
display_message('Connection failed.') | |
is_connected = False | |
return False | |
display_message('Connected successfully.') | |
is_connected = True | |
enable_gimbal_buttons() | |
else: | |
land() | |
display_message("Disconnecting from the drone...") | |
if drone.disconnect(): | |
is_connected = False | |
display_message("Disonnected succesfully") | |
disable_gimbal_buttons() | |
start_fpv_button.config(state = "normal") | |
# trigger = drone(set_auto_trigger_mode(0)).wait() # 0 means auto trigger of Return to Home will never happen | |
# if(trigger.success()): | |
# display_message("Rth off") | |
# Takeoff routine | |
def takeoff(): | |
global drone_tracker | |
display_message('Taking off...') | |
if not drone(TakeOff()).wait().success(): | |
display_message('Failed to takeoff') | |
return False | |
display_message('Takeoff successful') | |
# Set gimbal to attitude so that it looks straight | |
drone( | |
gimbal.set_target( | |
gimbal_id=0, | |
control_mode="position", | |
yaw_frame_of_reference="absolute", | |
yaw=0.0, | |
pitch_frame_of_reference="absolute", | |
pitch=0, | |
roll_frame_of_reference="absolute", | |
roll=0.0 | |
) | |
).wait() | |
takeoff_button.config(state="disabled") | |
enable_movement_buttons() | |
# Initialize and start the tracking thread | |
drone_tracker = DroneTracker() | |
drone_tracker.start_tracking() | |
def land(): | |
global drone_tracker | |
display_message('Landing...') | |
if not drone(Landing()).wait().success(): | |
display_message('Failed to land') | |
return False | |
if drone_tracker is not None: | |
drone_tracker.stop_tracking() # Stop tracking when landing | |
display_message('Landed successfully.') | |
disable_all_buttons() | |
enable_gimbal_buttons() | |
def move_forward(): | |
global gimbal_attitude | |
# Move straight | |
if gimbal_attitude <= 10 and gimbal_attitude >= -10: | |
display_message('Moving straight forward.') | |
pitch_fwd() | |
# Increase throttle - move up | |
elif gimbal_attitude == 100: | |
display_message('Increasing throttle.') | |
increase_throttle() | |
# Decrease throttle - move down | |
elif gimbal_attitude == -100: | |
display_message('Decreasing throttle.') | |
decrease_throttle() | |
def move_gimbal(attitude): | |
drone( | |
gimbal.set_target( | |
gimbal_id = 0, | |
control_mode = "position", | |
yaw_frame_of_reference = "absolute", | |
yaw = 0.0, | |
pitch_frame_of_reference = "absolute", | |
pitch = attitude, | |
roll_frame_of_reference = "absolute", | |
roll = 0.0 | |
) | |
).wait() | |
def gimbal_up(): | |
global gimbal_attitude | |
new_attitude = gimbal_attitude + 10 | |
if new_attitude > 100: | |
new_attitude = 100 | |
display_message('Tilting gimbal up.') | |
move_gimbal(new_attitude) | |
gimbal_attitude = new_attitude | |
if gimbal_attitude != 100: | |
takeoff_button.config(state = "disabled") | |
else: | |
takeoff_button.config(state = "normal") | |
land_button.config(state = "disabled") | |
def gimbal_up(attitude): | |
global gimbal_attitude | |
new_attitude = gimbal_attitude + attitude | |
if new_attitude > 100: | |
new_attitude = 100 | |
display_message('Tilting gimbal up.') | |
move_gimbal(new_attitude) | |
gimbal_attitude = new_attitude | |
if gimbal_attitude != 100: | |
takeoff_button.config(state = "disabled") | |
else: | |
takeoff_button.config(state = "normal") | |
land_button.config(state = "disabled") | |
def gimbal_down(): | |
global gimbal_attitude | |
new_attitude = gimbal_attitude - 10 | |
if new_attitude < -100: | |
new_attitude = -100 | |
display_message('Tilting gimbal down') | |
move_gimbal(new_attitude) | |
gimbal_attitude = new_attitude | |
if gimbal_attitude != -100: | |
land_button.config(state = "disabled") | |
else: | |
land_button.config(state = "normal") | |
takeoff_button.config(state = "disabled") | |
def gimbal_down(attitude): | |
global gimbal_attitude | |
new_attitude = gimbal_attitude - attitude | |
if new_attitude < -100: | |
new_attitude = -100 | |
display_message('Tilting gimbal down') | |
move_gimbal(new_attitude) | |
gimbal_attitude = new_attitude | |
if gimbal_attitude != -100: | |
land_button.config(state = "disabled") | |
else: | |
land_button.config(state = "normal") | |
takeoff_button.config(state = "disabled") | |
def look_forward(): | |
global gimbal_attitude | |
move_gimbal(0) | |
display_message('Gimbal facing straight ahead.') | |
gimbal_attitude = 0 | |
takeoff_button.config(state = "disabled") | |
land_button.config(state = "disabled") | |
def look_up(): | |
global gimbal_attitude | |
move_gimbal(100) | |
display_message('Gimbal facing straight up.') | |
gimbal_attitude = 100 | |
takeoff_button.config(state = "normal") | |
land_button.config(state = "disabled") | |
def look_down(): | |
global gimbal_attitude | |
move_gimbal(-100) | |
display_message('Gimbal facing straight down.') | |
gimbal_attitude = -100 | |
takeoff_button.config(state = "disabled") | |
land_button.config(state = "normal") | |
def start_fpv(): | |
global camera_on | |
global p1 | |
if not camera_on: | |
display_message('Starting first person view video feed...') | |
p1 = subprocess.Popen(['/home/rishiravula/code/groundsdk-tools/out/groundsdk-linux/staging/native-wrapper.sh', 'pdraw', '-u','rtsp://%s/live' % DRONE_IP]) | |
camera_on = True | |
else: | |
subprocess.Popen.kill(p1) | |
camera_on = False | |
def startController(): | |
try: | |
ps4 = PS4Controller() | |
ps4.init() | |
ps4.listen() | |
start_controller_button.config(state="normal") | |
except: | |
display_message("Failed to connect to Controller") | |
def display_message(message): | |
global message_box | |
message_box.insert(END, message) | |
# setting up screen | |
root = tk.Tk() | |
root.resizable(False, False) | |
root.title("Anafi Drone GUI") | |
root.configure(bg='white') | |
p2 = PhotoImage(file = 'images/drone.png') | |
root.iconphoto(False, p2) | |
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH) | |
canvas.configure(bg='white') | |
canvas.pack() | |
controlFrame = tk.Frame(root) | |
controlFrame.configure(bg='white') | |
controlFrame.place(relwidth=.95, relheight=.95, relx=0.025, rely=0.025) | |
# rotate left | |
l_rotate_button_image = Image.open("images/turn_left.png") | |
l_rotate_photoImg = ImageTk.PhotoImage(l_rotate_button_image) | |
l_rotate_button = Button(controlFrame, image=l_rotate_photoImg, command=turn_left) | |
l_rotate_button.place(relwidth=.2, relheight=.2105, relx=0, rely=0.35) | |
# rotate right | |
r_rotate_button_image = Image.open("images/turn_right.png") | |
r_rotate_photoImg = ImageTk.PhotoImage(r_rotate_button_image) | |
r_rotate_button = Button( | |
controlFrame, image=r_rotate_photoImg, command=turn_right) | |
r_rotate_button.place(relwidth=.2, relheight=.2105, relx=0.35, rely=0.35) | |
# move forward button | |
forward_button_image = Image.open("images/move_forward.png") | |
forward_button_photoImg = ImageTk.PhotoImage(forward_button_image) | |
forward_button = Button( | |
controlFrame, image=forward_button_photoImg, command=move_forward) | |
forward_button.place(relwidth=0.15, relheight=0.2, relx=0.20, rely=0.1) | |
# connect button | |
connect_button_image = Image.open("images/connect.png") | |
connect_button_photoImg = ImageTk.PhotoImage(connect_button_image) | |
connect_button = Button( | |
controlFrame, image=connect_button_photoImg, command=connect) | |
connect_button.place(relwidth=0.2, relheight=0.1, relx=.56, rely=.58) | |
# Start FPV button | |
start_fpv_image = Image.open("images/start_fpv.png") | |
start_fpv_button_photoImg = ImageTk.PhotoImage(start_fpv_image) | |
start_fpv_button = Button( | |
controlFrame, image=start_fpv_button_photoImg, command=start_fpv) | |
start_fpv_button.place(relwidth=0.2, relheight=0.1, relx=0.785, rely=.58) | |
# takeoff button | |
takeoff_button_image = Image.open("images/takeoff.png") | |
takeoff_button_photoImg = ImageTk.PhotoImage(takeoff_button_image) | |
takeoff_button = Button( | |
controlFrame, image=takeoff_button_photoImg, command=takeoff) | |
takeoff_button.place(relwidth=0.22, relheight=0.28, relx=0.55, rely=.7) | |
# land button | |
land_button_image = Image.open("images/land.png") | |
land_button_photoImg = ImageTk.PhotoImage(land_button_image) | |
land_button = Button( | |
controlFrame, image=land_button_photoImg, command=land) | |
land_button.place(relwidth=0.22, relheight=0.28, relx=0.785, rely=.7) | |
# gimbal up button | |
gimbal_up_button_image = Image.open("images/gimbal_up.png") | |
gimbal_up_button_photoImg = ImageTk.PhotoImage(gimbal_up_button_image) | |
gimbal_up_button = Button( | |
controlFrame, image=gimbal_up_button_photoImg, command=gimbal_up) | |
gimbal_up_button.place(relwidth=.207, relheight=.2105, relx=0.56, rely=0.1) | |
# gimbal down button | |
gimbal_down_button_image = Image.open("images/gimbal_down.png") | |
gimbal_down_button_photoImg = ImageTk.PhotoImage(gimbal_down_button_image) | |
gimbal_down_button = Button( | |
controlFrame, image=gimbal_down_button_photoImg, command=gimbal_down) | |
gimbal_down_button.place(relwidth=.207, relheight=.2105, relx=0.56, rely=0.35) | |
# look up button | |
look_up_button_image = Image.open("images/look_up.png") | |
look_up_button_photoImg = ImageTk.PhotoImage(look_up_button_image) | |
look_up_button = Button( | |
controlFrame, image=look_up_button_photoImg, command=look_up) | |
look_up_button.place(relwidth=.207, relheight=.15, relx=0.785, rely=0.1) | |
# look forward button | |
look_forward_button_image = Image.open("images/look_forward.png") | |
look_forward_button_photoImg = ImageTk.PhotoImage(look_forward_button_image) | |
look_forward_button = Button( | |
controlFrame, image=look_forward_button_photoImg, command=look_forward) | |
look_forward_button.place(relwidth=.207, relheight=.15, relx=0.785, rely=0.257) | |
# look down button | |
look_down_button_image = Image.open("images/look_down.png") | |
look_down_button_photoImg = ImageTk.PhotoImage(look_down_button_image) | |
look_down_button = Button( | |
controlFrame, image=look_down_button_photoImg, command=look_down) | |
look_down_button.place(relwidth=.207, relheight=.15, relx=0.785, rely=0.41) | |
# Controller button | |
start_controller_button_image = Image.open("images/start_controller.png") | |
start_controller_button_photoImg = ImageTk.PhotoImage(start_controller_button_image) | |
start_controller_button = Button( | |
controlFrame, image=start_controller_button_photoImg, command=startController) | |
start_controller_button.place(relwidth=.15, relheight=.15, relx=0.20, rely=0.6) | |
message_box = Listbox(controlFrame) | |
message_box.place(relwidth= .5, relheight= .2, relx= 0, rely= .8) | |
buttons = [ l_rotate_button, | |
r_rotate_button, | |
forward_button, | |
takeoff_button, | |
land_button, | |
gimbal_up_button, | |
gimbal_down_button, | |
look_up_button, | |
look_forward_button, | |
look_down_button, | |
connect_button, | |
start_fpv_button, | |
start_controller_button ] | |
def disable_all_buttons(): | |
global buttons | |
for button in buttons: | |
button.config(state = "disabled") | |
def enable_all_buttons(): | |
global buttons | |
for button in buttons: | |
button.config(state = "normal") | |
def disable_gimbal_buttons(): | |
look_up_button.config(state = "disabled") | |
look_down_button.config(state = "disabled") | |
look_forward_button.config(state = "disabled") | |
gimbal_up_button.config(state = "disabled") | |
gimbal_down_button.config(state = "disabled") | |
def enable_gimbal_buttons(): | |
look_up_button.config(state = "normal") | |
look_down_button.config(state = "normal") | |
look_forward_button.config(state = "normal") | |
gimbal_up_button.config(state = "normal") | |
gimbal_down_button.config(state = "normal") | |
def enable_movement_buttons(): | |
l_rotate_button.config(state = "normal") | |
r_rotate_button.config(state = "normal") | |
forward_button.config(state = "normal") | |
# class for the ps4 controller object | |
class PS4Controller(object): | |
"""Class representing the PS4 controller. Pretty straightforward functionality.""" | |
controller = None | |
axis_data = None | |
button_data = None | |
hat_data = None | |
def init(self): | |
"""Initialize the joystick components""" | |
pygame.init() | |
pygame.joystick.init() | |
self.controller = pygame.joystick.Joystick(0) | |
self.controller.init() | |
def listen(self): | |
"""Listen for events to happen""" | |
global horzScalingFactor | |
global vertScalingFactor | |
if not self.axis_data: | |
self.axis_data = [0,0,0,0,0,0] | |
if not self.button_data: | |
self.button_data = {} | |
for i in range(self.controller.get_numbuttons()): | |
self.button_data[i] = False | |
if not self.hat_data: | |
self.hat_data = (0,0) | |
# for i in range(self.controller.get_numhats()): | |
# self.hat_data[i] = (0, 0) | |
while True: | |
for event in pygame.event.get(): | |
if event.type == pygame.JOYAXISMOTION: | |
self.axis_data[event.axis] = round(event.value,2) | |
elif event.type == pygame.JOYBUTTONDOWN: | |
self.button_data[event.button] = True | |
# handle single press buttons | |
if is_connected: | |
if event.button == 2: | |
# land | |
land() | |
elif event.button == 3: | |
# takeoff | |
takeoff() | |
elif event.button == 4: | |
l1 = 0 #unused button input - can be used for future functionalities | |
elif event.button == 5: | |
r1 = 0 #unused button input - can be used for future functionalities | |
elif event.button == 6: | |
start_fpv() | |
elif event.button == 9: | |
l3 = 0 #unused button input - can be used for future functionalities | |
elif event.button == 10: | |
r3 = 0 #unused button input - can be used for future functionalities | |
if event.button == 7: | |
#connect to drone | |
connect() | |
elif event.button == 8: | |
#exit controller mode | |
return | |
elif event.type == pygame.JOYBUTTONUP: | |
self.button_data[event.button] = False | |
elif event.type == pygame.JOYHATMOTION: | |
self.hat_data = event.value | |
# Handle hat inputs for adjusting scaling factor (i.e. speed of drone) | |
if self.hat_data[0] != 0: | |
horzScalingFactor = horzScalingFactor + 10*self.hat_data[0] | |
if self.hat_data[1] !=0: | |
vertScalingFactor = vertScalingFactor + 10*self.hat_data[1] | |
if vertScalingFactor > 100: | |
vertScalingFactor = 100 | |
elif vertScalingFactor < 10: | |
vertScalingFactor = 10 | |
if horzScalingFactor > 100: | |
horzScalingFactor = 100 | |
elif horzScalingFactor < 10: | |
horzScalingFactor = 10 | |
# handle buttons that are held down | |
if is_connected: | |
# handle left joystick input to move drone | |
if self.axis_data[0] != 0 or self.axis_data[1] != 0 or self.axis_data[2] > 0 or self.axis_data[5] > 0 or self.button_data[0] != 0 or self.button_data[1] !=0: | |
# send all data from the joystick to the roll / pitch commands | |
throttleInput = -vertScalingFactor * self.button_data[0] + vertScalingFactor * self.button_data[1] | |
# handle trigger inputs to spin drone | |
spinInput = 0 | |
if self.axis_data[2] > 0 and self.axis_data[5] > 0: | |
spinInput = 0 | |
elif self.axis_data[2] > 0: | |
spinInput = -100*self.axis_data[2] | |
elif self.axis_data[5] > 0: | |
spinInput = 100*self.axis_data[5] | |
move_drone(rollVal=horzScalingFactor*self.axis_data[0], pitchVal=-horzScalingFactor*self.axis_data[1], throttleVal=throttleInput, spinVal=spinInput) | |
# handle right joystick to move camera up or down | |
if self.axis_data[4] < 0: | |
gimbal_up(abs(self.axis_data[4])) | |
elif self.axis_data[4] > 0: | |
gimbal_down(abs(self.axis_data[4])) | |
# Main Loop Start: | |
if __name__ == "__main__": | |
# Define the drone tracking function as a separate function | |
#gui_thread.start() | |
with olympe.Drone(DRONE_IP) as drone: | |
disable_all_buttons() | |
connect_button.config(state="normal") | |
start_controller_button.config(state="normal") | |
root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment