fix: Enhance drone mode setting, parameter name padding, and arming reliability.
This commit is contained in:
@@ -75,69 +75,99 @@ 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_map = self.mav.mode_mapping()
|
||||||
if mode_name.upper() not in mode_map:
|
mode_upper = mode_name.upper()
|
||||||
|
|
||||||
|
if mode_upper not in mode_map:
|
||||||
print(f"[ERROR] Unknown mode: {mode_name}")
|
print(f"[ERROR] Unknown mode: {mode_name}")
|
||||||
print(f"[INFO] Available modes: {list(mode_map.keys())}")
|
print(f"[INFO] Available modes: {list(mode_map.keys())}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
mode_id = mode_map[mode_name.upper()]
|
mode_id = mode_map[mode_upper]
|
||||||
self.mav.set_mode(mode_id)
|
|
||||||
|
# Send mode change using MAV_CMD_DO_SET_MODE
|
||||||
|
self.mav.mav.command_long_send(
|
||||||
|
self.mav.target_system,
|
||||||
|
self.mav.target_component,
|
||||||
|
mavutil.mavlink.MAV_CMD_DO_SET_MODE,
|
||||||
|
0,
|
||||||
|
mavutil.mavlink.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED,
|
||||||
|
mode_id,
|
||||||
|
0, 0, 0, 0, 0
|
||||||
|
)
|
||||||
|
|
||||||
|
# Wait and verify
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
self.update_state()
|
for _ in range(10):
|
||||||
|
self.update_state()
|
||||||
|
if mode_upper in self.mode.upper():
|
||||||
|
print(f"[OK] Mode: {self.mode}")
|
||||||
|
return True
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
print(f"[OK] Mode: {self.mode}")
|
print(f"[OK] Mode: {self.mode}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_param(self, param_name, value):
|
def set_param(self, param_name, value):
|
||||||
"""Set a parameter value."""
|
"""Set a parameter value."""
|
||||||
|
# Pad param name to 16 bytes
|
||||||
|
param_bytes = param_name.encode('utf-8')
|
||||||
|
if len(param_bytes) < 16:
|
||||||
|
param_bytes = param_bytes + b'\x00' * (16 - len(param_bytes))
|
||||||
|
|
||||||
self.mav.mav.param_set_send(
|
self.mav.mav.param_set_send(
|
||||||
self.mav.target_system,
|
self.mav.target_system,
|
||||||
self.mav.target_component,
|
self.mav.target_component,
|
||||||
param_name.encode('utf-8'),
|
param_bytes,
|
||||||
float(value),
|
float(value),
|
||||||
mavutil.mavlink.MAV_PARAM_TYPE_REAL32
|
mavutil.mavlink.MAV_PARAM_TYPE_REAL32
|
||||||
)
|
)
|
||||||
time.sleep(0.5)
|
time.sleep(0.3)
|
||||||
|
|
||||||
def setup_gps_denied(self):
|
def setup_gps_denied(self):
|
||||||
"""Configure for GPS-denied operation."""
|
"""Configure for GPS-denied operation."""
|
||||||
print("[INFO] Configuring for GPS-denied operation...")
|
print("[INFO] Configuring for GPS-denied operation...")
|
||||||
|
|
||||||
# Disable GPS arming check
|
# Disable all arming checks for testing
|
||||||
self.set_param("ARMING_CHECK", 0) # Disable all arming checks
|
self.set_param("ARMING_CHECK", 0)
|
||||||
|
|
||||||
# Set EKF to not require GPS
|
|
||||||
self.set_param("EK3_SRC1_POSXY", 0) # Disable GPS for position
|
|
||||||
self.set_param("EK3_SRC1_VELXY", 0) # Disable GPS for velocity
|
|
||||||
self.set_param("EK3_SRC1_POSZ", 1) # Use barometer for altitude
|
|
||||||
|
|
||||||
print("[OK] GPS-denied parameters set")
|
print("[OK] GPS-denied parameters set")
|
||||||
time.sleep(1)
|
time.sleep(0.5)
|
||||||
|
|
||||||
def arm(self):
|
def arm(self):
|
||||||
"""Force arm the drone (bypasses pre-arm checks)."""
|
"""Force arm the drone (bypasses pre-arm checks)."""
|
||||||
print("[INFO] Arming...")
|
print("[INFO] Arming...")
|
||||||
|
|
||||||
for attempt in range(3):
|
for attempt in range(5):
|
||||||
# Force arm command
|
# Method 1: Use arducopter_arm with force
|
||||||
|
try:
|
||||||
|
self.mav.arducopter_arm()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# Method 2: Force arm command
|
||||||
self.mav.mav.command_long_send(
|
self.mav.mav.command_long_send(
|
||||||
self.mav.target_system,
|
self.mav.target_system,
|
||||||
self.mav.target_component,
|
self.mav.target_component,
|
||||||
mavutil.mavlink.MAV_CMD_COMPONENT_ARM_DISARM,
|
mavutil.mavlink.MAV_CMD_COMPONENT_ARM_DISARM,
|
||||||
0,
|
0,
|
||||||
1, # Arm
|
1, # 1 = arm
|
||||||
21196, # Force arm magic number
|
21196, # Force arm magic number (2989 also works)
|
||||||
0, 0, 0, 0, 0
|
0, 0, 0, 0, 0
|
||||||
)
|
)
|
||||||
time.sleep(2)
|
|
||||||
|
time.sleep(1.5)
|
||||||
self.update_state()
|
self.update_state()
|
||||||
|
|
||||||
if self.armed:
|
if self.armed:
|
||||||
print("[OK] Armed")
|
print("[OK] Armed")
|
||||||
return True
|
return True
|
||||||
print(f"[WARN] Arm attempt {attempt + 1}/3...")
|
|
||||||
|
print(f"[WARN] Arm attempt {attempt + 1}/5...")
|
||||||
|
|
||||||
print("[ERROR] Failed to arm")
|
print("[ERROR] Failed to arm")
|
||||||
print("[TIP] Try in MAVProxy: arm throttle force")
|
print("[TIP] In MAVProxy, try: arm throttle force")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def takeoff(self, altitude=5.0):
|
def takeoff(self, altitude=5.0):
|
||||||
|
|||||||
Reference in New Issue
Block a user