add models

This commit is contained in:
Sebastian Unterschütz
2026-04-21 15:45:43 +02:00
parent f5d344cf75
commit e72ba2989e
14 changed files with 1589 additions and 79 deletions

View File

@@ -1,6 +1,6 @@
# drone_pilot/config.py
class Config:
WIN_NAME = "Tello AI Pilot v2.0 (High Speed)"
WIN_NAME = "Tello AI Pilot v2.0 (Extreme Speed)"
WIDTH, HEIGHT = 1024, 720
TARGET_ALTITUDE = 1.5
@@ -8,21 +8,28 @@ class Config:
TARGET_PERSON_SIZE = 400
ALT_THRESHOLD = 0.12
YAW_GAIN = 0.08 # Reduced for smoother rotation
FORWARD_GAIN = 1.5 # Kept high for fast pursuit
# Normal Mode Gains
YAW_GAIN = 0.12
FORWARD_GAIN = 1.5
ALT_GAIN = 40
# Sport Mode Gains (Much more aggressive)
SPORT_YAW_GAIN = 0.25
SPORT_FB_GAIN = 2.0
SPORT_LR_GAIN = 0.6
DEPTH_THRESHOLD = 0.90
OBSTACLE_TOF_CM = 70
FACE_DEADZONE = 30 # Slightly larger deadzone for stability
FACE_ROT_ONLY = 100
FACE_DEADZONE = 20
FACE_ROT_ONLY = 80
PERSON_CONF_THRESHOLD = 0.5
SMOOTHING_ALPHA = 0.35 # High directness, but slightly more damped than extreme
SMOOTHING_ALPHA = 0.35
class Colors:
GREEN = (0, 255, 0)
RED = (0, 0, 255)
BLUE = (255, 0, 0)
PURPLE = (255, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
HUD_BG = (10, 10, 10)

View File

@@ -4,19 +4,24 @@ from typing import List, Tuple, Dict
from .config import Config
class FlightController:
"""
Verantwortlich für die Berechnung der Flugvektoren basierend auf KI-Ergebnissen.
Unterstützt Normal-Modus (sequenziell) und Sport-Modus (simultan/LR).
"""
def __init__(self):
self.last_sent_rc = [0, 0, 0, 0]
self.smooth_face = None
self.search_start = time.time()
self.status = "INITIALIZING"
# Memory for lost targets
self.last_target_side = 0 # -1 for left, 1 for right
# Speicher für verloren gegangene Ziele
self.last_target_side = 0
self.lost_time = 0
def calculate(self,
faces: List[Tuple],
is_manual: bool,
is_sport: bool, # NEU: Sport-Modus Flag
emergency_stop: bool,
is_locked: bool,
locked_person: Tuple,
@@ -29,7 +34,6 @@ class FlightController:
lr, fb, ud, yv = 0, 0, 0, 0
# Face smoothing for UI/Visuals
if len(faces) > 0:
target = max(faces, key=lambda f: f[2] * f[3])
if self.smooth_face is None: self.smooth_face = target
@@ -42,13 +46,13 @@ class FlightController:
self.status = "EMERGENCY STOP"
return (0, 0, 0, 0), self.status
# Obstacle Avoidance (always active if flying)
# Hindernisvermeidung
center_blocked = zones["CENTER"] or tof < Config.OBSTACLE_TOF_CM
if center_blocked:
self.status = "AVOIDING OBSTACLE"
yv = 80 if zone_scores["LEFT"] < zone_scores["RIGHT"] else -80
fb = -30
return self._smooth(lr, fb, ud, yv)
return self._smooth(0, fb, 0, yv)
if is_manual:
self.status = "MANUAL CONTROL"
@@ -59,54 +63,57 @@ class FlightController:
# AI LOGIC
if is_locked:
if locked_person is not None:
# Target is visible -> Normal Pursuit
self.search_start = time.time()
self.lost_time = 0
(x, y, w, h) = locked_person
center_x = x + w // 2
err_x = center_x - (Config.WIDTH // 2)
# Remember which side it was on
self.last_target_side = 1 if err_x > 0 else -1
# Rotation (Yaw) - SMOOTHER
if abs(err_x) > Config.FACE_DEADZONE:
yv = int(np.clip(Config.YAW_GAIN * err_x, -50, 50))
# Forward/Backward pursuit - EXTREME SPEED
alignment_factor = max(0.4, 1.0 - (abs(err_x) / Config.FACE_ROT_ONLY))
target_fb = int(np.clip(Config.FORWARD_GAIN * (Config.TARGET_PERSON_SIZE - w), -90, 90))
fb = int(target_fb * alignment_factor)
self.status = "PURSUIT: EXTREME"
if is_sport:
# SPORT MODUS: Alles gleichzeitig + LR-Strafing
yv = int(np.clip(Config.SPORT_YAW_GAIN * err_x, -100, 100))
fb = int(np.clip(Config.SPORT_FB_GAIN * (Config.TARGET_PERSON_SIZE - w), -100, 100))
lr = int(np.clip(Config.SPORT_LR_GAIN * err_x, -60, 60))
self.status = "SPORT PURSUIT: FULL AXIS"
else:
# NORMAL MODUS: Sequenziell (Drehen ODER Fliegen)
if abs(err_x) > Config.FACE_DEADZONE:
yv = int(np.clip(Config.YAW_GAIN * err_x, -50, 50))
fb = 0
self.status = "PURSUIT: AIMING"
else:
yv = 0
fb = int(np.clip(Config.FORWARD_GAIN * (Config.TARGET_PERSON_SIZE - w), -80, 80))
self.status = "PURSUIT: APPROACHING"
else:
# Target is LOST -> Rapid Search logic
# Target verloren
if self.lost_time == 0: self.lost_time = time.time()
elapsed = time.time() - self.lost_time
if elapsed < 10.0: # Search longer and faster
yv = 40 * self.last_target_side
search_speed = 60 if is_sport else 40
if elapsed < 10.0:
yv = search_speed * self.last_target_side
self.status = f"LOST TARGET: SCANNING {'RIGHT' if self.last_target_side > 0 else 'LEFT'}"
else:
self.status = "TARGET LOST: AGGRESSIVE PATROL"
self.status = "TARGET LOST: PATROL"
yv = 30
elif self.smooth_face is not None:
# Face found but not locked
(x, y, w, h) = self.smooth_face
err_x = (x + w // 2) - (Config.WIDTH // 2)
if abs(err_x) > Config.FACE_DEADZONE:
yv = int(np.clip(Config.YAW_GAIN * err_x, -40, 40))
yv = int(np.clip(Config.YAW_GAIN * err_x, -40, 40))
self.status = "AWAITING LOCK"
else:
# Patrol mode - faster
elapsed = (time.time() - self.search_start) % 6.0
if elapsed < 2.0:
self.status = "PATROL: DASH"
fb = 40
# Patrouille
elapsed = (time.time() - self.search_start) % 8.0
if elapsed < 3.0:
self.status = "PATROL: ADVANCE"
fb = 35
else:
self.status = "PATROL: SCAN"
yv = 30
yv = 35
return self._smooth(lr, fb, ud, yv)
@@ -117,10 +124,10 @@ class FlightController:
sud = int(self.last_sent_rc[2] * (1-alpha) + ud * alpha)
syv = int(self.last_sent_rc[3] * (1-alpha) + yv * alpha)
if abs(slr) < 2: slr = 0
if abs(sfb) < 2: sfb = 0
if abs(sud) < 2: sud = 0
if abs(syv) < 2: syv = 0
if abs(slr) < 3: slr = 0
if abs(sfb) < 3: sfb = 0
if abs(sud) < 3: sud = 0
if abs(syv) < 3: syv = 0
self.last_sent_rc = [slr, sfb, sud, syv]
return (slr, sfb, sud, syv), self.status

View File

@@ -23,6 +23,7 @@ class FaceTrackingApp:
# State Management
self.is_running = True
self.is_manual = True
self.is_sport = False # NEW: Sport Mode flag
self.is_locked = False
self.is_taking_off = False
self.is_flying = False
@@ -180,9 +181,10 @@ class FaceTrackingApp:
self.locked_person_features = feat
self.is_locked = True
self.lock_trigger = False
self.is_manual = False
break
# UI
# UI Graphics
if self.is_locked and self.locked_person:
(x,y,w,h) = self.locked_person
cv2.rectangle(frame, (x,y), (x+w,y+h), Colors.BLUE, 3)
@@ -204,6 +206,7 @@ class FaceTrackingApp:
rc, status = self.flight_controller.calculate(
faces=faces,
is_manual=self.is_manual,
is_sport=self.is_sport, # NEW
emergency_stop=self.emergency_stop,
is_locked=self.is_locked,
locked_person=self.locked_person,
@@ -215,7 +218,8 @@ class FaceTrackingApp:
manual_rc=active_manual_rc
)
# Throttle and optimized sending
if self.is_sport: status = "SPORT MODE: ACTIVE"
now = time.time()
if now - self.last_rc_time >= 0.1:
changed = any(abs(rc[i] - self._prev_rc[i]) > 1 for i in range(4))
@@ -250,7 +254,6 @@ class FaceTrackingApp:
def _handle_takeoff(self):
if self.is_taking_off or self.is_flying: return
self.is_taking_off = True
self.takeoff_error = False
def _task():
@@ -265,13 +268,13 @@ class FaceTrackingApp:
self.takeoff_error = True
finally:
self.is_taking_off = False
threading.Thread(target=_task, daemon=True).start()
def _handle_input(self, key: int):
if key == 13: self.is_running = False
elif key == 32: self.emergency_stop = not self.emergency_stop
elif key == ord('m'): self.is_manual = not self.is_manual
elif key == ord('2'): self.is_sport = not self.is_sport # Toggle Sport Mode
elif key == ord('k'):
self.lock_trigger = not self.lock_trigger
self.is_locked = False
@@ -287,11 +290,9 @@ class FaceTrackingApp:
except: pass
elif key == ord('1'): self.is_rotating = not self.is_rotating
# Reset manual speed
self.m_lr, self.m_fb, self.m_ud, self.m_yv = 0, 0, 0, 0
if self.is_manual and not self.emergency_stop:
s = 100 # Maximum manual speed
s = 100
if key == ord('w'): self.m_fb = s
elif key == ord('s'): self.m_fb = -s
elif key == ord('a'): self.m_lr = -s