Controller Update 2
This commit is contained in:
72
.gitignore
vendored
72
.gitignore
vendored
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
@@ -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')
|
||||
text = text.strip()
|
||||
if text:
|
||||
print(f"[SITL] {text}")
|
||||
if 'EKF3 IMU' in text and 'initialised' in text:
|
||||
time.sleep(2) # Give it a moment after EKF init
|
||||
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."""
|
||||
|
||||
Reference in New Issue
Block a user