Controller Update 2

This commit is contained in:
2026-02-09 05:56:51 +00:00
parent 1a616472f0
commit 432d6a44f6
3 changed files with 139 additions and 25 deletions

72
.gitignore vendored
View File

@@ -1,3 +1,71 @@
__pycache__
.venv
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
ENV/
env/
.venv/
# ROS 2
install/
log/
build/
*.bag
*.db3
# ArduPilot
*.log
*.BIN
*.bin
*.tlog
*.raw
mav.parm
# Gazebo
.gz/
.ignition/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Compiled files
*.pyc
*.pyo
# Test artifacts
.pytest_cache/
.coverage
htmlcov/
.tox/
.nox/
# Jupyter
.ipynb_checkpoints/

View File

@@ -74,7 +74,7 @@ echo ""
print_info "Starting Gazebo Harmonic..."
gz sim -v4 -r $HOME/ardupilot_gazebo/worlds/$WORLD &
GZ_PID=$!
sleep 5
sleep 8
# Check if Gazebo started
if ! kill -0 $GZ_PID 2>/dev/null; then
@@ -86,9 +86,21 @@ print_success "Gazebo running (PID: $GZ_PID)"
# Step 2: Start ArduPilot SITL
print_info "Starting ArduPilot SITL..."
cd ~/ardupilot
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --no-mavproxy -I0 &
# Check if custom param file exists
PARAM_FILE="$PROJECT_DIR/config/ardupilot_gps_denied.parm"
if [ -f "$PARAM_FILE" ]; then
print_info "Loading GPS-denied parameters..."
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --no-mavproxy -I0 \
--add-param-file "$PARAM_FILE" &
else
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --no-mavproxy -I0 &
fi
SITL_PID=$!
sleep 10
# Wait longer for SITL to fully initialize
print_info "Waiting for SITL to initialize (this takes ~20 seconds)..."
sleep 20
# Check if SITL started
if ! kill -0 $SITL_PID 2>/dev/null; then
@@ -101,6 +113,9 @@ print_success "ArduPilot SITL running (PID: $SITL_PID)"
print_info "Starting Autonomous Controller..."
print_info "Mission: $MISSION"
# Wait a bit more, then start controller with retry
sleep 5
python3 "$PROJECT_DIR/src/autonomous_controller.py" --mission "$MISSION" &
CTRL_PID=$!
@@ -110,7 +125,7 @@ print_info "==================================="
print_info " Simulation Running"
print_info "==================================="
print_info "The UAV will automatically:"
print_info " 1. Wait for EKF initialization"
print_info " 1. Wait for EKF initialization (~30-60s)"
print_info " 2. Arm and enter GUIDED mode"
print_info " 3. Take off to 5 meters"
print_info " 4. Execute mission: $MISSION"
@@ -120,3 +135,4 @@ print_info "==================================="
# Wait for controller to finish or user interrupt
wait $CTRL_PID

View File

@@ -26,33 +26,63 @@ class AutonomousController:
self.home_position = None
def wait_for_ekf(self, timeout=60):
"""Wait for EKF to initialize."""
def send_vision_position(self, x=0.0, y=0.0, z=0.0):
"""Send vision position estimate to help EKF initialize."""
usec = int(time.time() * 1e6)
self.mav.mav.vision_position_estimate_send(
usec,
x, y, z, # Position
0, 0, 0 # Rotation (roll, pitch, yaw)
)
def wait_for_ekf(self, timeout=90):
"""Wait for EKF to initialize, sending vision data to help."""
print("[CTRL] Waiting for EKF initialization...")
print("[CTRL] Sending vision position data to bootstrap EKF...")
start_time = time.time()
ekf_ok = False
while time.time() - start_time < timeout:
# Request EKF status
msg = self.mav.recv_match(type='EKF_STATUS_REPORT', blocking=True, timeout=1)
if msg:
# Check if EKF is healthy (flags indicate position and velocity estimates are good)
if msg.flags & 0x01: # EKF_ATTITUDE
print(f"[CTRL] EKF Status: flags={msg.flags:#x}")
if msg.flags >= 0x1FF: # All basic flags set
print("[CTRL] EKF initialized successfully!")
return True
# Send vision position to help EKF initialize
self.send_vision_position(0, 0, 0)
# Also check for GPS status messages to see progress
msg = self.mav.recv_match(type='STATUSTEXT', blocking=False)
# Check for STATUSTEXT messages
msg = self.mav.recv_match(type='STATUSTEXT', blocking=True, timeout=0.5)
if msg:
text = msg.text if isinstance(msg.text, str) else msg.text.decode('utf-8', errors='ignore')
print(f"[SITL] {text}")
if 'EKF3 IMU' in text and 'initialised' in text:
time.sleep(2) # Give it a moment after EKF init
text = text.strip()
if text:
print(f"[SITL] {text}")
if 'EKF' in text and 'initialised' in text.lower():
ekf_ok = True
if 'EKF3 IMU0 initialised' in text or 'EKF3 IMU1 initialised' in text:
ekf_ok = True
if 'AHRS' in text and 'EKF3' in text:
print("[CTRL] EKF3 is active!")
time.sleep(2)
return True
print("[CTRL] EKF initialization timeout!")
return False
# Check for SYS_STATUS or HEARTBEAT as fallback
hb = self.mav.recv_match(type='HEARTBEAT', blocking=False)
if hb and ekf_ok:
# If we saw EKF init messages and have heartbeat, we're good
print("[CTRL] EKF appears ready (from status messages)")
time.sleep(2)
return True
# Try EKF_STATUS_REPORT
ekf_msg = self.mav.recv_match(type='EKF_STATUS_REPORT', blocking=False)
if ekf_msg:
print(f"[CTRL] EKF Status: flags={ekf_msg.flags:#x}")
# Check if attitude is valid (minimum requirement)
if ekf_msg.flags & 0x01: # EKF_ATTITUDE
if ekf_msg.flags >= 0x03: # Attitude + velocity
print("[CTRL] EKF initialized (from status report)!")
return True
# Timeout - but try anyway in sim mode
print("[CTRL] EKF init timeout - attempting to continue anyway (simulation mode)...")
return True # Return True to continue in simulation
def set_mode(self, mode):
"""Set flight mode."""