Code reorganization. Display recording fixes. Search Flight Planner Fixes. Bug Fixes
This commit is contained in:
@@ -50,7 +50,6 @@ DICT_SIZES = {
|
||||
"DICT_7X7_1000": 1000,
|
||||
}
|
||||
|
||||
|
||||
def generate_marker(dict_name, marker_id, pixel_size=600, border_bits=1):
|
||||
dict_id = ARUCO_DICTS[dict_name]
|
||||
aruco_dict = cv2.aruco.getPredefinedDictionary(dict_id)
|
||||
@@ -65,7 +64,6 @@ def generate_marker(dict_name, marker_id, pixel_size=600, border_bits=1):
|
||||
padded[border_px:border_px + pixel_size, border_px:border_px + pixel_size] = marker_img
|
||||
return padded
|
||||
|
||||
|
||||
def get_landing_id():
|
||||
search_cfg = CONFIG_DIR / "search.yaml"
|
||||
if search_cfg.exists():
|
||||
@@ -76,7 +74,6 @@ def get_landing_id():
|
||||
return land_ids[0]
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Generate ArUco marker tags for Gazebo simulation")
|
||||
parser.add_argument("--dict", default="DICT_4X4_50", choices=list(ARUCO_DICTS.keys()))
|
||||
@@ -113,7 +110,7 @@ def main():
|
||||
params = cv2.aruco.DetectorParameters()
|
||||
except AttributeError:
|
||||
params = cv2.aruco.DetectorParameters_create()
|
||||
|
||||
|
||||
params.minMarkerPerimeterRate = 0.01
|
||||
try:
|
||||
params.cornerRefinementMethod = cv2.aruco.CORNER_REFINE_SUBPIX
|
||||
@@ -132,9 +129,8 @@ def main():
|
||||
_, detected_ids, _ = _detect(img)
|
||||
if detected_ids is not None and marker_id in detected_ids.flatten():
|
||||
ok += 1
|
||||
|
||||
print(f"Done. {ok}/{len(ids)} markers verified.")
|
||||
|
||||
print(f"Done. {ok}/{len(ids)} markers verified.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -22,10 +22,10 @@ def generate_world(base_filename="uav_ugv_search_base.sdf", output_filename="uav
|
||||
|
||||
ugv_x = ugv_cfg.get("position", {}).get("x", 0.0)
|
||||
ugv_y = ugv_cfg.get("position", {}).get("y", 0.0)
|
||||
|
||||
|
||||
uav_x = ugv_x
|
||||
uav_y = ugv_y
|
||||
uav_z = 0.40 # Start on top of UGV (0.18 top + 0.195 legs)
|
||||
uav_z = 0.40
|
||||
|
||||
marker = search_cfg.get("marker", {})
|
||||
target_pos = marker.get("target_position", [8.0, -6.0])
|
||||
@@ -42,19 +42,19 @@ def generate_world(base_filename="uav_ugv_search_base.sdf", output_filename="uav
|
||||
try:
|
||||
tree = ET.parse(base_path)
|
||||
root = tree.getroot()
|
||||
|
||||
|
||||
world = root.find('world')
|
||||
if world is None:
|
||||
print("[ERROR] No <world> tag found in SDF.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
for include in world.findall('include'):
|
||||
uri = include.find('uri')
|
||||
if uri is not None and uri.text == 'model://iris_with_gimbal':
|
||||
pose = include.find('pose')
|
||||
if pose is not None:
|
||||
pose.text = f"{uav_x} {uav_y} {uav_z} 0 0 90"
|
||||
|
||||
|
||||
name = include.find('name')
|
||||
if name is not None and name.text == 'ugv':
|
||||
pose = include.find('pose')
|
||||
@@ -72,7 +72,7 @@ def generate_world(base_filename="uav_ugv_search_base.sdf", output_filename="uav
|
||||
if geofence_cfg.get("enabled", False):
|
||||
points = geofence_cfg.get("points", [])
|
||||
if len(points) >= 3:
|
||||
# Remove old geofence visual if it exists
|
||||
|
||||
for old_model in world.findall('model'):
|
||||
if old_model.get('name') == 'geofence_visual':
|
||||
world.remove(old_model)
|
||||
@@ -80,29 +80,29 @@ def generate_world(base_filename="uav_ugv_search_base.sdf", output_filename="uav
|
||||
gf_model = ET.SubElement(world, "model", name="geofence_visual")
|
||||
ET.SubElement(gf_model, "static").text = "true"
|
||||
link = ET.SubElement(gf_model, "link", name="link")
|
||||
|
||||
|
||||
import math
|
||||
for i in range(len(points)):
|
||||
p1 = points[i]
|
||||
p2 = points[(i + 1) % len(points)]
|
||||
x1, y1 = float(p1[0]), float(p1[1])
|
||||
x2, y2 = float(p2[0]), float(p2[1])
|
||||
|
||||
|
||||
dx = x2 - x1
|
||||
dy = y2 - y1
|
||||
length = math.sqrt(dx*dx + dy*dy)
|
||||
cx = x1 + dx / 2.0
|
||||
cy = y1 + dy / 2.0
|
||||
yaw = math.atan2(dy, dx)
|
||||
|
||||
|
||||
visual = ET.SubElement(link, "visual", name=f"edge_{i}")
|
||||
ET.SubElement(visual, "pose").text = f"{cx} {cy} 0.01 0 0 {yaw}"
|
||||
|
||||
|
||||
geometry = ET.SubElement(visual, "geometry")
|
||||
box = ET.SubElement(geometry, "box")
|
||||
# size is Length(X), Width(Y), Thickness(Z)
|
||||
|
||||
ET.SubElement(box, "size").text = f"{length} 0.2 0.02"
|
||||
|
||||
|
||||
material = ET.SubElement(visual, "material")
|
||||
ET.SubElement(material, "ambient").text = "1 0 0 1"
|
||||
ET.SubElement(material, "diffuse").text = "1 0 0 1"
|
||||
@@ -112,7 +112,7 @@ def generate_world(base_filename="uav_ugv_search_base.sdf", output_filename="uav
|
||||
print(f"[INFO] Generated world file: {output_path}")
|
||||
print(f"[INFO] UGV set to ({ugv_x}, {ugv_y})")
|
||||
print(f"[INFO] Target Marker set to ({target_x}, {target_y})")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Failed to parse or write XML: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Killing all simulation processes..."
|
||||
|
||||
pkill -9 -f "gz sim" 2>/dev/null || true
|
||||
pkill -9 -f "ruby" 2>/dev/null || true # gz sim uses ruby
|
||||
pkill -9 -f "ruby" 2>/dev/null || true
|
||||
pkill -9 -f "gazebo" 2>/dev/null || true
|
||||
pkill -9 -f "gzserver" 2>/dev/null || true
|
||||
pkill -9 -f "gzclient" 2>/dev/null || true
|
||||
@@ -15,9 +13,7 @@ pkill -9 -f "ArduRover" 2>/dev/null || true
|
||||
pkill -9 -f "arducopter" 2>/dev/null || true
|
||||
pkill -9 -f "autonomous_controller" 2>/dev/null || true
|
||||
pkill -9 -f "ros2" 2>/dev/null || true
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "All processes killed."
|
||||
echo "Remaining ROS nodes:"
|
||||
ros2 node list 2>/dev/null || echo "No ROS nodes running"
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() { echo -e "${CYAN}[INFO]${NC} $1"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
SOFTWARE_RENDER=auto
|
||||
WORLD="uav_ugv_search.sdf"
|
||||
SEARCH="spiral"
|
||||
ALTITUDE=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--software-render) SOFTWARE_RENDER=true; shift ;;
|
||||
@@ -39,7 +33,6 @@ while [[ $# -gt 0 ]]; do
|
||||
*) shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
cleanup_all() {
|
||||
print_info "Cleaning up ..."
|
||||
pkill -f "camera_viewer.py" 2>/dev/null || true
|
||||
@@ -50,7 +43,6 @@ cleanup_all() {
|
||||
pkill -f "mavproxy" 2>/dev/null || true
|
||||
pkill -f "main.py" 2>/dev/null || true
|
||||
}
|
||||
|
||||
cleanup_sitl() {
|
||||
pkill -f "arducopter" 2>/dev/null || true
|
||||
pkill -f "sim_vehicle.py" 2>/dev/null || true
|
||||
@@ -58,7 +50,6 @@ cleanup_sitl() {
|
||||
pkill -f "main.py" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup_all EXIT
|
||||
|
||||
if [ -f "$PROJECT_DIR/venv/bin/activate" ]; then
|
||||
print_info "Using venv: $PROJECT_DIR/venv"
|
||||
source "$PROJECT_DIR/venv/bin/activate"
|
||||
@@ -66,18 +57,15 @@ elif [ -f "$PROJECT_DIR/.venv/bin/activate" ]; then
|
||||
print_info "Using .venv: $PROJECT_DIR/.venv"
|
||||
source "$PROJECT_DIR/.venv/bin/activate"
|
||||
fi
|
||||
|
||||
export PATH=$PATH:$HOME/ardupilot/Tools/autotest:$HOME/.local/bin
|
||||
export GZ_SIM_RESOURCE_PATH="$PROJECT_DIR/models:$PROJECT_DIR/worlds:$HOME/ardupilot_gazebo/models:$HOME/ardupilot_gazebo/worlds"
|
||||
export GZ_SIM_SYSTEM_PLUGIN_PATH=$HOME/ardupilot_gazebo/build
|
||||
|
||||
print_info "Model path: $GZ_SIM_RESOURCE_PATH"
|
||||
if [ -f "$PROJECT_DIR/models/iris_with_gimbal/model.sdf" ]; then
|
||||
print_info "Using LOCAL iris_with_gimbal (with downward camera)"
|
||||
else
|
||||
print_info "Using ardupilot_gazebo iris_with_gimbal (NO downward camera)"
|
||||
fi
|
||||
|
||||
if [ "$SOFTWARE_RENDER" = "auto" ]; then
|
||||
if grep -qi microsoft /proc/version 2>/dev/null; then
|
||||
print_info "WSL detected -> software rendering"
|
||||
@@ -86,15 +74,12 @@ if [ "$SOFTWARE_RENDER" = "auto" ]; then
|
||||
SOFTWARE_RENDER=false
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SOFTWARE_RENDER" = "true" ]; then
|
||||
export LIBGL_ALWAYS_SOFTWARE=1
|
||||
export GALLIUM_DRIVER=llvmpipe
|
||||
export MESA_GL_VERSION_OVERRIDE=3.3
|
||||
fi
|
||||
|
||||
cleanup_all 2>/dev/null
|
||||
|
||||
WORLD_FILE=""
|
||||
if [ -f "$PROJECT_DIR/worlds/$WORLD" ]; then
|
||||
WORLD_FILE="$PROJECT_DIR/worlds/$WORLD"
|
||||
@@ -106,29 +91,23 @@ else
|
||||
print_error "World file not found: $WORLD"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$PROJECT_DIR/scripts/generate_world.py" ]; then
|
||||
python3 "$PROJECT_DIR/scripts/generate_world.py"
|
||||
fi
|
||||
|
||||
print_info "==================================="
|
||||
print_info " UAV-UGV Simulation"
|
||||
print_info "==================================="
|
||||
print_info "World: $WORLD_FILE"
|
||||
print_info "Mission: $MISSION"
|
||||
echo ""
|
||||
|
||||
GZ_DEFAULT_GUI="/usr/share/gz/gz-sim8/gui/gui.config"
|
||||
GZ_USER_GUI="$HOME/.gz/sim/8/gui.config"
|
||||
CAMERA_PLUGINS="$PROJECT_DIR/config/gui.config"
|
||||
|
||||
rm -rf /tmp/gz-* /tmp/gazebo-* 2>/dev/null
|
||||
|
||||
mkdir -p "$HOME/.gz/sim/8"
|
||||
cp "$GZ_DEFAULT_GUI" "$GZ_USER_GUI"
|
||||
sed -i 's|<start_paused>true</start_paused>|<start_paused>false</start_paused>|' "$GZ_USER_GUI"
|
||||
sed -i 's|show_again="true"|show_again="false"|' "$GZ_USER_GUI"
|
||||
|
||||
cat << 'EOF' >> "$GZ_USER_GUI"
|
||||
<plugin filename="VideoRecorder" name="VideoRecorder">
|
||||
<gz-gui>
|
||||
@@ -141,7 +120,6 @@ cat << 'EOF' >> "$GZ_USER_GUI"
|
||||
<property key="showTitleBar" type="bool">false</property>
|
||||
<property key="cardBackground" type="string">#777777</property>
|
||||
</gz-gui>
|
||||
|
||||
<record_video>
|
||||
<use_sim_time>true</use_sim_time>
|
||||
<lockstep>true</lockstep>
|
||||
@@ -149,58 +127,45 @@ cat << 'EOF' >> "$GZ_USER_GUI"
|
||||
</record_video>
|
||||
</plugin>
|
||||
EOF
|
||||
|
||||
print_info "[1/4] Starting Gazebo ..."
|
||||
gz sim -v4 -r "$WORLD_FILE" &
|
||||
GZ_PID=$!
|
||||
sleep 10
|
||||
|
||||
if ! kill -0 $GZ_PID 2>/dev/null; then
|
||||
print_error "Gazebo failed to start"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Gazebo running (PID: $GZ_PID)"
|
||||
|
||||
print_info "[2/4] Starting ArduPilot SITL ..."
|
||||
cd ~/ardupilot
|
||||
|
||||
SITL_ARGS="-v ArduCopter -f gazebo-iris --model JSON -I0"
|
||||
SITL_ARGS="$SITL_ARGS --no-mavproxy"
|
||||
|
||||
PARAM_FILE="$PROJECT_DIR/config/ardupilot_gps_denied.parm"
|
||||
if [ -f "$PARAM_FILE" ]; then
|
||||
print_info "Loading params: $PARAM_FILE"
|
||||
SITL_ARGS="$SITL_ARGS --add-param-file $PARAM_FILE"
|
||||
fi
|
||||
|
||||
sim_vehicle.py $SITL_ARGS &
|
||||
SITL_PID=$!
|
||||
|
||||
print_info "Waiting for SITL (~20s) ..."
|
||||
sleep 20
|
||||
|
||||
if ! pgrep -f "arducopter" > /dev/null 2>&1; then
|
||||
print_error "ArduPilot SITL failed to start"
|
||||
exit 1
|
||||
fi
|
||||
print_success "ArduPilot SITL running (TCP 5760)"
|
||||
|
||||
print_info "[3/4] Starting main.py ..."
|
||||
cd "$PROJECT_DIR"
|
||||
sleep 3
|
||||
|
||||
MAIN_ARGS="--device sim --connection tcp:127.0.0.1:5760 --search $SEARCH"
|
||||
[ -n "$ALTITUDE" ] && MAIN_ARGS="$MAIN_ARGS --altitude $ALTITUDE"
|
||||
|
||||
python3 src/main.py $MAIN_ARGS &
|
||||
MAIN_PID=$!
|
||||
print_success "main.py running (PID: $MAIN_PID)"
|
||||
|
||||
print_info "[4/4] Starting camera viewer ..."
|
||||
python3 -W ignore:RuntimeWarning -m src.vision.camera_processor down &
|
||||
CAM_PID=$!
|
||||
print_success "Camera viewer running (PID: $CAM_PID)"
|
||||
|
||||
print_info ""
|
||||
print_info "==================================="
|
||||
print_info " Simulation Running"
|
||||
@@ -216,11 +181,8 @@ print_info " target tag, dispatches UGV, lands on UGV"
|
||||
print_info " Search: $SEARCH"
|
||||
print_info " Press Ctrl+C to stop"
|
||||
print_info "==================================="
|
||||
|
||||
wait $MAIN_PID 2>/dev/null
|
||||
|
||||
cleanup_sitl
|
||||
|
||||
print_info ""
|
||||
print_info "=================================="
|
||||
print_info " Search Complete!"
|
||||
@@ -229,5 +191,4 @@ print_info "Gazebo GUI still open."
|
||||
print_info "Press Ctrl+C to exit."
|
||||
print_info "=================================="
|
||||
print_info ""
|
||||
|
||||
wait $GZ_PID 2>/dev/null
|
||||
|
||||
@@ -1,40 +1,22 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# UAV-UGV Simulation - Run Script
|
||||
# =============================================================================
|
||||
# Launches Gazebo with ArduPilot SITL for GPS-denied navigation testing
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/run_simulation.sh # Default world
|
||||
# ./scripts/run_simulation.sh --world runway # Runway world
|
||||
# ./scripts/run_simulation.sh --software-render # For WSL/no GPU
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
echo -e "${BLUE}==========================================${NC}"
|
||||
echo -e "${BLUE} UAV-UGV Simulation${NC}"
|
||||
echo -e "${BLUE} GPS-Denied Navigation with Geofencing${NC}"
|
||||
echo -e "${BLUE}==========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Detect WSL
|
||||
IS_WSL=false
|
||||
if grep -qEi "(microsoft|wsl)" /proc/version 2>/dev/null; then
|
||||
IS_WSL=true
|
||||
echo -e "${YELLOW}Running in WSL environment${NC}"
|
||||
fi
|
||||
|
||||
# Detect ROS distro
|
||||
ROS_DISTRO=""
|
||||
for distro in jazzy humble iron galactic; do
|
||||
if [ -d "/opt/ros/$distro" ]; then
|
||||
@@ -42,22 +24,16 @@ for distro in jazzy humble iron galactic; do
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$ROS_DISTRO" ]; then
|
||||
source /opt/ros/${ROS_DISTRO}/setup.bash
|
||||
echo -e "${GREEN}ROS 2: $ROS_DISTRO${NC}"
|
||||
fi
|
||||
|
||||
# ArduPilot paths
|
||||
ARDUPILOT_HOME="${ARDUPILOT_HOME:-$HOME/ardupilot}"
|
||||
ARDUPILOT_GZ="${ARDUPILOT_GZ:-$HOME/ardupilot_gazebo}"
|
||||
|
||||
# Parse arguments
|
||||
WORLD_NAME="iris_runway"
|
||||
VEHICLE="ArduCopter"
|
||||
USE_SOFTWARE_RENDER=false
|
||||
INSTANCE=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--world)
|
||||
@@ -96,16 +72,11 @@ while [[ $# -gt 0 ]]; do
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Setup Gazebo paths
|
||||
export GZ_SIM_RESOURCE_PATH="$PROJECT_DIR/models:$PROJECT_DIR/worlds:${GZ_SIM_RESOURCE_PATH:-}"
|
||||
|
||||
if [ -d "$ARDUPILOT_GZ" ]; then
|
||||
export GZ_SIM_SYSTEM_PLUGIN_PATH="$ARDUPILOT_GZ/build:${GZ_SIM_SYSTEM_PLUGIN_PATH:-}"
|
||||
export GZ_SIM_RESOURCE_PATH="$ARDUPILOT_GZ/models:$ARDUPILOT_GZ/worlds:$GZ_SIM_RESOURCE_PATH"
|
||||
fi
|
||||
|
||||
# Find world file
|
||||
WORLD_FILE=""
|
||||
if [ -f "$PROJECT_DIR/worlds/${WORLD_NAME}.sdf" ]; then
|
||||
WORLD_FILE="$PROJECT_DIR/worlds/${WORLD_NAME}.sdf"
|
||||
@@ -123,8 +94,6 @@ else
|
||||
ls "$ARDUPILOT_GZ/worlds/"*.sdf 2>/dev/null | xargs -I {} basename {} .sdf || echo " (none)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# WSL/Display setup
|
||||
if $IS_WSL; then
|
||||
if [ -z "$DISPLAY" ]; then
|
||||
if [ -d "/mnt/wslg" ]; then
|
||||
@@ -135,75 +104,52 @@ if $IS_WSL; then
|
||||
fi
|
||||
echo -e "${BLUE}DISPLAY: $DISPLAY${NC}"
|
||||
fi
|
||||
|
||||
if $USE_SOFTWARE_RENDER; then
|
||||
echo -e "${YELLOW}Using software rendering${NC}"
|
||||
export LIBGL_ALWAYS_SOFTWARE=1
|
||||
export MESA_GL_VERSION_OVERRIDE=3.3
|
||||
fi
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}Shutting down simulation...${NC}"
|
||||
|
||||
pkill -f "sim_vehicle.py" 2>/dev/null || true
|
||||
pkill -f "mavproxy" 2>/dev/null || true
|
||||
pkill -f "arducopter" 2>/dev/null || true
|
||||
pkill -f "ardurover" 2>/dev/null || true
|
||||
pkill -f "ruby" 2>/dev/null || true # gz sim uses ruby
|
||||
pkill -f "ruby" 2>/dev/null || true
|
||||
pkill -f "gz sim" 2>/dev/null || true
|
||||
|
||||
sleep 2
|
||||
echo -e "${GREEN}Cleanup complete.${NC}"
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Check ArduPilot installation
|
||||
if [ ! -d "$ARDUPILOT_HOME" ]; then
|
||||
echo -e "${RED}ERROR: ArduPilot not found at $ARDUPILOT_HOME${NC}"
|
||||
echo "Run setup.sh first to install ArduPilot"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Gazebo plugin
|
||||
if [ ! -f "$ARDUPILOT_GZ/build/libArduPilotPlugin.so" ]; then
|
||||
echo -e "${RED}ERROR: ArduPilot Gazebo plugin not found${NC}"
|
||||
echo "Run setup.sh first to build the plugin"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Configuration:${NC}"
|
||||
echo " Vehicle: $VEHICLE"
|
||||
echo " World: $(basename $WORLD_FILE .sdf)"
|
||||
echo " Instance: $INSTANCE"
|
||||
echo ""
|
||||
|
||||
# Start Gazebo in background
|
||||
echo -e "${GREEN}Starting Gazebo...${NC}"
|
||||
gz sim -v4 -r "$WORLD_FILE" &
|
||||
GZ_PID=$!
|
||||
|
||||
sleep 5
|
||||
|
||||
# Check if Gazebo started
|
||||
if ! kill -0 $GZ_PID 2>/dev/null; then
|
||||
echo -e "${RED}ERROR: Gazebo failed to start${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Gazebo running (PID: $GZ_PID)${NC}"
|
||||
|
||||
# Start ArduPilot SITL
|
||||
echo -e "${GREEN}Starting ArduPilot SITL...${NC}"
|
||||
cd "$ARDUPILOT_HOME"
|
||||
|
||||
export PATH=$PATH:$ARDUPILOT_HOME/Tools/autotest:$HOME/.local/bin:$HOME/.local/pipx/venvs/mavproxy/bin
|
||||
|
||||
# Run sim_vehicle.py without --console to keep it running
|
||||
# The --no-mavproxy flag runs just the SITL, then we start mavproxy separately
|
||||
sim_vehicle.py \
|
||||
-v $VEHICLE \
|
||||
-f gazebo-iris \
|
||||
@@ -212,11 +158,7 @@ sim_vehicle.py \
|
||||
--no-mavproxy \
|
||||
&
|
||||
SITL_PID=$!
|
||||
|
||||
# Wait for SITL to initialize
|
||||
sleep 8
|
||||
|
||||
# Start MAVProxy in foreground so user can interact with it
|
||||
echo ""
|
||||
echo -e "${GREEN}==========================================${NC}"
|
||||
echo -e "${GREEN} Simulation Running${NC}"
|
||||
@@ -227,17 +169,15 @@ echo " - Gazebo: PID $GZ_PID"
|
||||
echo " - ArduPilot SITL: PID $SITL_PID"
|
||||
echo ""
|
||||
echo -e "${BLUE}MAVProxy Commands:${NC}"
|
||||
echo " mode guided # Switch to GUIDED mode"
|
||||
echo " arm throttle # Arm the drone"
|
||||
echo " takeoff 5 # Takeoff to 5 meters"
|
||||
echo " guided 10 5 -10 # Fly to position (N, E, D)"
|
||||
echo " rtl # Return to launch"
|
||||
echo " land # Land"
|
||||
echo " mode guided
|
||||
echo " arm throttle
|
||||
echo " takeoff 5
|
||||
echo " guided 10 5 -10
|
||||
echo " rtl
|
||||
echo " land
|
||||
echo ""
|
||||
echo -e "${YELLOW}MAVProxy starting... (Ctrl+C to exit)${NC}"
|
||||
echo ""
|
||||
|
||||
# Start MAVProxy in foreground - user can type commands directly
|
||||
mavproxy.py \
|
||||
--master tcp:127.0.0.1:5760 \
|
||||
--sitl 127.0.0.1:5501 \
|
||||
|
||||
@@ -1,34 +1,19 @@
|
||||
#!/bin/bash
|
||||
# Setup script for NVIDIA GPU with Gazebo
|
||||
|
||||
set -e
|
||||
|
||||
echo "Setting up NVIDIA GPU for Gazebo..."
|
||||
|
||||
# Check if NVIDIA GPU is available
|
||||
if ! command -v nvidia-smi &> /dev/null; then
|
||||
echo "NVIDIA driver not found. Please install NVIDIA drivers first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nvidia-smi
|
||||
|
||||
# Set environment variables for NVIDIA
|
||||
export __NV_PRIME_RENDER_OFFLOAD=1
|
||||
export __GLX_VENDOR_LIBRARY_NAME=nvidia
|
||||
|
||||
# For Gazebo Harmonic
|
||||
export LIBGL_ALWAYS_SOFTWARE=0
|
||||
|
||||
# Create persistent config
|
||||
cat >> ~/.bashrc << 'EOF'
|
||||
|
||||
# NVIDIA GPU for Gazebo
|
||||
export __NV_PRIME_RENDER_OFFLOAD=1
|
||||
export __GLX_VENDOR_LIBRARY_NAME=nvidia
|
||||
export LIBGL_ALWAYS_SOFTWARE=0
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "NVIDIA setup complete!"
|
||||
echo "Please restart your terminal or run: source ~/.bashrc"
|
||||
|
||||
@@ -1,38 +1,20 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# UAV-UGV Simulation - Uninstall Script
|
||||
# =============================================================================
|
||||
# Removes ArduPilot, ardupilot_gazebo, and project files
|
||||
# Does NOT remove ROS 2 or Gazebo (system packages)
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/uninstall.sh # Remove ArduPilot and plugin only
|
||||
# ./scripts/uninstall.sh --all # Remove everything including project
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
ARDUPILOT_HOME="$HOME/ardupilot"
|
||||
ARDUPILOT_GZ="$HOME/ardupilot_gazebo"
|
||||
|
||||
echo -e "${BLUE}==========================================${NC}"
|
||||
echo -e "${BLUE} UAV-UGV Simulation - Uninstall${NC}"
|
||||
echo -e "${BLUE}==========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Parse arguments
|
||||
REMOVE_ALL=false
|
||||
FORCE=false
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--all)
|
||||
@@ -54,8 +36,6 @@ for arg in "$@"; do
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Confirmation
|
||||
if [ "$FORCE" = false ]; then
|
||||
echo "This will remove:"
|
||||
echo " - ArduPilot SITL ($ARDUPILOT_HOME)"
|
||||
@@ -73,10 +53,7 @@ if [ "$FORCE" = false ]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Kill running processes
|
||||
echo -e "${YELLOW}Stopping running processes...${NC}"
|
||||
pkill -f "sim_vehicle.py" 2>/dev/null || true
|
||||
pkill -f "mavproxy" 2>/dev/null || true
|
||||
@@ -86,8 +63,6 @@ pkill -f "gz sim" 2>/dev/null || true
|
||||
pkill -f "gzserver" 2>/dev/null || true
|
||||
pkill -f "gzclient" 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
# Remove ArduPilot
|
||||
if [ -d "$ARDUPILOT_HOME" ]; then
|
||||
echo -e "${YELLOW}Removing ArduPilot ($ARDUPILOT_HOME)...${NC}"
|
||||
rm -rf "$ARDUPILOT_HOME"
|
||||
@@ -95,8 +70,6 @@ if [ -d "$ARDUPILOT_HOME" ]; then
|
||||
else
|
||||
echo "ArduPilot not found at $ARDUPILOT_HOME"
|
||||
fi
|
||||
|
||||
# Remove ardupilot_gazebo
|
||||
if [ -d "$ARDUPILOT_GZ" ]; then
|
||||
echo -e "${YELLOW}Removing ardupilot_gazebo ($ARDUPILOT_GZ)...${NC}"
|
||||
rm -rf "$ARDUPILOT_GZ"
|
||||
@@ -104,33 +77,22 @@ if [ -d "$ARDUPILOT_GZ" ]; then
|
||||
else
|
||||
echo "ardupilot_gazebo not found at $ARDUPILOT_GZ"
|
||||
fi
|
||||
|
||||
# Remove Python venv
|
||||
if [ -d "$PROJECT_DIR/venv" ]; then
|
||||
echo -e "${YELLOW}Removing Python virtual environment...${NC}"
|
||||
rm -rf "$PROJECT_DIR/venv"
|
||||
echo -e "${GREEN}Removed venv${NC}"
|
||||
fi
|
||||
|
||||
# Remove generated files
|
||||
rm -f "$PROJECT_DIR/activate_venv.sh" 2>/dev/null || true
|
||||
rm -f "$PROJECT_DIR/wsl_env.sh" 2>/dev/null || true
|
||||
|
||||
# Remove ArduPilot environment files
|
||||
rm -f "$HOME/.ardupilot_env" 2>/dev/null || true
|
||||
|
||||
# Remove pip user packages
|
||||
echo -e "${YELLOW}Removing user pip packages (mavproxy, pymavlink)...${NC}"
|
||||
pip3 uninstall -y mavproxy pymavlink pexpect 2>/dev/null || true
|
||||
|
||||
# Remove project directory if --all
|
||||
if [ "$REMOVE_ALL" = true ]; then
|
||||
echo -e "${YELLOW}Removing project directory ($PROJECT_DIR)...${NC}"
|
||||
cd "$HOME"
|
||||
rm -rf "$PROJECT_DIR"
|
||||
echo -e "${GREEN}Removed project directory${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}==========================================${NC}"
|
||||
echo -e "${GREEN} Uninstall Complete${NC}"
|
||||
|
||||
Reference in New Issue
Block a user