forest_navigating_uav/scripts/worldgen/spawn_uav.sh
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/bash

# Spawn a UAV at an edge location in an existing world
# Usage: ./spawn_uav.sh <world_sdf_path> [--index INDEX] [--margin MARGIN] [--height HEIGHT]
#
# Requires: Gazebo must be already running with the specified world loaded
#
# This script calculates spawn points on-the-fly from meta.json and spawns
# the UAV at the specified corner index.
#
# Defaults:
#   - index: 0 (NW corner)
#   - margin: 1.0 m (distance from world edge)
#   - height: 2.0 m (altitude above ground)

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"

if [ $# -lt 1 ]; then
    echo "Usage: $0 <world_sdf_path> [--index INDEX] [--margin MARGIN] [--height HEIGHT]"
    echo ""
    echo "Example:"
    echo "  $0 worldgen/outputs/runs/2026-02-09_123456_random/world.sdf --index 0"
    exit 1
fi

WORLD_FILE="$1"
shift

if [ ! -f "$WORLD_FILE" ]; then
    echo "Error: World file not found: $WORLD_FILE"
    exit 1
fi

# Get the directory containing world.sdf to find meta.json
WORLD_DIR="$(dirname "$WORLD_FILE")"
META_FILE="$WORLD_DIR/meta.json"

if [ ! -f "$META_FILE" ]; then
    echo "Error: Metadata file not found: $META_FILE"
    exit 1
fi

# Parse arguments
INDEX=0
MARGIN=1.0
HEIGHT=0.3

while [ $# -gt 0 ]; do
    case "$1" in
        --index)
            INDEX="$2"
            shift 2
            ;;
        --margin)
            MARGIN="$2"
            shift 2
            ;;
        --height)
            HEIGHT="$2"
            shift 2
            ;;
        *)
            shift
            ;;
    esac
done

# Calculate spawn point on-the-fly using Python
SPAWN_POINT=$(python3 -c "
import json
import random
import math

# Read metadata from meta.json
with open('$META_FILE', 'r') as f:
    meta = json.load(f)

start_goal = meta.get('start_goal')
if isinstance(start_goal, dict) and isinstance(start_goal.get('start_xy'), list) and len(start_goal.get('start_xy')) >= 2:
    sx, sy = start_goal['start_xy'][:2]
    print(f\"{float(sx):.2f} {float(sy):.2f} {float($HEIGHT):.2f}\")
    raise SystemExit(0)

area_size = meta['world']['area_size']

# Calculate edge spawn
margin = $MARGIN
height = $HEIGHT
half_side = area_size / 2.0
edge = half_side - margin

# Generate 4 corner spawn points
spawns = [
    {'x': -edge, 'y': edge, 'z': height},   # NW
    {'x': -edge, 'y': -edge, 'z': height},  # SW
    {'x': edge, 'y': -edge, 'z': height},   # SE
    {'x': edge, 'y': edge, 'z': height},    # NE
]

idx = $INDEX % len(spawns)
pt = spawns[idx]
print(f\"{pt['x']:.2f} {pt['y']:.2f} {pt['z']:.2f}\")
")

read X Y Z <<< "$SPAWN_POINT"

echo "Spawning UAV at edge position [$INDEX]: x=$X, y=$Y, z=$Z"

# Extract world name from world.sdf
WORLD_NAME=$(python3 -c "
import re
with open('$WORLD_FILE', 'r') as f:
    content = f.read()
    match = re.search(r'<world name=\"([^\"]+)\">', content)
    if match:
        print(match.group(1))
    else:
        print('randomized_world')
")

ros2 run ros_gz_sim create -world "$WORLD_NAME" -name uav1 -file models/drones/uav_simple/model.sdf -x "$X" -y "$Y" -z "$Z"

if [ $? -eq 0 ]; then
    echo "UAV spawned successfully!"
else
    echo "Error: UAV spawn failed!"
    exit 1
fi