feat: Add vehicle type detection and robust flight mode setting based on vehicle type.
This commit is contained in:
@@ -38,6 +38,7 @@ class DroneController:
|
|||||||
self.mode = "UNKNOWN"
|
self.mode = "UNKNOWN"
|
||||||
self.altitude = 0
|
self.altitude = 0
|
||||||
self.position = {"x": 0, "y": 0, "z": 0}
|
self.position = {"x": 0, "y": 0, "z": 0}
|
||||||
|
self.vehicle_type = "copter" # Default to copter
|
||||||
|
|
||||||
def connect(self, timeout=30):
|
def connect(self, timeout=30):
|
||||||
"""Connect to ArduPilot SITL."""
|
"""Connect to ArduPilot SITL."""
|
||||||
@@ -45,8 +46,25 @@ class DroneController:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.mav = mavutil.mavlink_connection(self.connection_string)
|
self.mav = mavutil.mavlink_connection(self.connection_string)
|
||||||
self.mav.wait_heartbeat(timeout=timeout)
|
msg = self.mav.wait_heartbeat(timeout=timeout)
|
||||||
print(f"[OK] Connected to system {self.mav.target_system}")
|
print(f"[OK] Connected to system {self.mav.target_system}")
|
||||||
|
|
||||||
|
# Detect vehicle type from heartbeat
|
||||||
|
if msg:
|
||||||
|
mav_type = msg.type
|
||||||
|
if mav_type == mavutil.mavlink.MAV_TYPE_QUADROTOR:
|
||||||
|
self.vehicle_type = "copter"
|
||||||
|
print(f"[INFO] Vehicle: Quadrotor (ArduCopter)")
|
||||||
|
elif mav_type == mavutil.mavlink.MAV_TYPE_HELICOPTER:
|
||||||
|
self.vehicle_type = "copter"
|
||||||
|
print(f"[INFO] Vehicle: Helicopter")
|
||||||
|
elif mav_type == mavutil.mavlink.MAV_TYPE_FIXED_WING:
|
||||||
|
self.vehicle_type = "plane"
|
||||||
|
print(f"[INFO] Vehicle: Fixed Wing (ArduPlane)")
|
||||||
|
else:
|
||||||
|
self.vehicle_type = "copter" # Default to copter
|
||||||
|
print(f"[INFO] Vehicle type: {mav_type}")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[ERROR] Connection failed: {e}")
|
print(f"[ERROR] Connection failed: {e}")
|
||||||
@@ -74,15 +92,53 @@ class DroneController:
|
|||||||
|
|
||||||
def set_mode(self, mode_name):
|
def set_mode(self, mode_name):
|
||||||
"""Set flight mode."""
|
"""Set flight mode."""
|
||||||
mode_map = self.mav.mode_mapping()
|
|
||||||
mode_upper = mode_name.upper()
|
mode_upper = mode_name.upper()
|
||||||
|
|
||||||
if mode_upper not in mode_map:
|
# ArduCopter mode IDs (hardcoded as fallback since pymavlink can be buggy)
|
||||||
print(f"[ERROR] Unknown mode: {mode_name}")
|
copter_modes = {
|
||||||
print(f"[INFO] Available modes: {list(mode_map.keys())}")
|
'STABILIZE': 0,
|
||||||
return False
|
'ACRO': 1,
|
||||||
|
'ALT_HOLD': 2,
|
||||||
|
'AUTO': 3,
|
||||||
|
'GUIDED': 4,
|
||||||
|
'LOITER': 5,
|
||||||
|
'RTL': 6,
|
||||||
|
'CIRCLE': 7,
|
||||||
|
'LAND': 9,
|
||||||
|
'DRIFT': 11,
|
||||||
|
'SPORT': 13,
|
||||||
|
'FLIP': 14,
|
||||||
|
'AUTOTUNE': 15,
|
||||||
|
'POSHOLD': 16,
|
||||||
|
'BRAKE': 17,
|
||||||
|
'THROW': 18,
|
||||||
|
'AVOID_ADSB': 19,
|
||||||
|
'GUIDED_NOGPS': 20,
|
||||||
|
'SMART_RTL': 21,
|
||||||
|
}
|
||||||
|
|
||||||
mode_id = mode_map[mode_upper]
|
# Try copter modes first if we detected a copter
|
||||||
|
if hasattr(self, 'vehicle_type') and self.vehicle_type == 'copter':
|
||||||
|
if mode_upper in copter_modes:
|
||||||
|
mode_id = copter_modes[mode_upper]
|
||||||
|
else:
|
||||||
|
print(f"[ERROR] Unknown copter mode: {mode_name}")
|
||||||
|
print(f"[INFO] Available modes: {list(copter_modes.keys())}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# Fall back to pymavlink mode mapping
|
||||||
|
mode_map = self.mav.mode_mapping()
|
||||||
|
if mode_upper not in mode_map:
|
||||||
|
# Try copter modes anyway
|
||||||
|
if mode_upper in copter_modes:
|
||||||
|
mode_id = copter_modes[mode_upper]
|
||||||
|
else:
|
||||||
|
print(f"[ERROR] Unknown mode: {mode_name}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
mode_id = mode_map[mode_upper]
|
||||||
|
|
||||||
|
print(f"[INFO] Setting mode to {mode_upper} (id={mode_id})...")
|
||||||
|
|
||||||
# Send mode change using MAV_CMD_DO_SET_MODE
|
# Send mode change using MAV_CMD_DO_SET_MODE
|
||||||
self.mav.mav.command_long_send(
|
self.mav.mav.command_long_send(
|
||||||
@@ -104,7 +160,7 @@ class DroneController:
|
|||||||
return True
|
return True
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
print(f"[OK] Mode: {self.mode}")
|
print(f"[OK] Mode set (current: {self.mode})")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_param(self, param_name, value):
|
def set_param(self, param_name, value):
|
||||||
|
|||||||
Reference in New Issue
Block a user