Controller Update 2
This commit is contained in:
72
.gitignore
vendored
72
.gitignore
vendored
@@ -1,3 +1,71 @@
|
|||||||
__pycache__
|
# Python
|
||||||
.venv
|
__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..."
|
print_info "Starting Gazebo Harmonic..."
|
||||||
gz sim -v4 -r $HOME/ardupilot_gazebo/worlds/$WORLD &
|
gz sim -v4 -r $HOME/ardupilot_gazebo/worlds/$WORLD &
|
||||||
GZ_PID=$!
|
GZ_PID=$!
|
||||||
sleep 5
|
sleep 8
|
||||||
|
|
||||||
# Check if Gazebo started
|
# Check if Gazebo started
|
||||||
if ! kill -0 $GZ_PID 2>/dev/null; then
|
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
|
# Step 2: Start ArduPilot SITL
|
||||||
print_info "Starting ArduPilot SITL..."
|
print_info "Starting ArduPilot SITL..."
|
||||||
cd ~/ardupilot
|
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 &
|
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --no-mavproxy -I0 &
|
||||||
|
fi
|
||||||
SITL_PID=$!
|
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
|
# Check if SITL started
|
||||||
if ! kill -0 $SITL_PID 2>/dev/null; then
|
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 "Starting Autonomous Controller..."
|
||||||
print_info "Mission: $MISSION"
|
print_info "Mission: $MISSION"
|
||||||
|
|
||||||
|
# Wait a bit more, then start controller with retry
|
||||||
|
sleep 5
|
||||||
|
|
||||||
python3 "$PROJECT_DIR/src/autonomous_controller.py" --mission "$MISSION" &
|
python3 "$PROJECT_DIR/src/autonomous_controller.py" --mission "$MISSION" &
|
||||||
CTRL_PID=$!
|
CTRL_PID=$!
|
||||||
|
|
||||||
@@ -110,7 +125,7 @@ print_info "==================================="
|
|||||||
print_info " Simulation Running"
|
print_info " Simulation Running"
|
||||||
print_info "==================================="
|
print_info "==================================="
|
||||||
print_info "The UAV will automatically:"
|
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 " 2. Arm and enter GUIDED mode"
|
||||||
print_info " 3. Take off to 5 meters"
|
print_info " 3. Take off to 5 meters"
|
||||||
print_info " 4. Execute mission: $MISSION"
|
print_info " 4. Execute mission: $MISSION"
|
||||||
@@ -120,3 +135,4 @@ print_info "==================================="
|
|||||||
|
|
||||||
# Wait for controller to finish or user interrupt
|
# Wait for controller to finish or user interrupt
|
||||||
wait $CTRL_PID
|
wait $CTRL_PID
|
||||||
|
|
||||||
|
|||||||
@@ -26,33 +26,63 @@ class AutonomousController:
|
|||||||
|
|
||||||
self.home_position = None
|
self.home_position = None
|
||||||
|
|
||||||
def wait_for_ekf(self, timeout=60):
|
def send_vision_position(self, x=0.0, y=0.0, z=0.0):
|
||||||
"""Wait for EKF to initialize."""
|
"""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] Waiting for EKF initialization...")
|
||||||
|
print("[CTRL] Sending vision position data to bootstrap EKF...")
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
ekf_ok = False
|
||||||
|
|
||||||
while time.time() - start_time < timeout:
|
while time.time() - start_time < timeout:
|
||||||
# Request EKF status
|
# Send vision position to help EKF initialize
|
||||||
msg = self.mav.recv_match(type='EKF_STATUS_REPORT', blocking=True, timeout=1)
|
self.send_vision_position(0, 0, 0)
|
||||||
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
|
|
||||||
|
|
||||||
# Also check for GPS status messages to see progress
|
# Check for STATUSTEXT messages
|
||||||
msg = self.mav.recv_match(type='STATUSTEXT', blocking=False)
|
msg = self.mav.recv_match(type='STATUSTEXT', blocking=True, timeout=0.5)
|
||||||
if msg:
|
if msg:
|
||||||
text = msg.text if isinstance(msg.text, str) else msg.text.decode('utf-8', errors='ignore')
|
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}")
|
print(f"[SITL] {text}")
|
||||||
if 'EKF3 IMU' in text and 'initialised' in text:
|
if 'EKF' in text and 'initialised' in text.lower():
|
||||||
time.sleep(2) # Give it a moment after EKF init
|
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
|
return True
|
||||||
|
|
||||||
print("[CTRL] EKF initialization timeout!")
|
# Check for SYS_STATUS or HEARTBEAT as fallback
|
||||||
return False
|
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):
|
def set_mode(self, mode):
|
||||||
"""Set flight mode."""
|
"""Set flight mode."""
|
||||||
|
|||||||
Reference in New Issue
Block a user