#!/usr/bin/env sh # Host-only closed-loop acceptance scenario. It verifies the actual UDP lease, # estimator, safety, trajectory, controller, allocator, and Gazebo loop across # ascent, cross-axis translation, descent, and terminal landing. Every terminal # phase holds independent, noise-free Gazebo truth; that recorder cannot feed # the controller. set -eu project_root=$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd) compose_file="$project_root/tools/sitl/compose.yaml" python3 "$project_root/tools/sitl/world-structure-test.py" cleanup() { status=$? trap - EXIT # Preserve the first failing command's result, but retain enough evidence # to distinguish a client/lease failure from a Gazebo or container start # failure in CI. `down` otherwise removes the only useful diagnostics. if [ "$status" -ne 0 ]; then echo "SITL smoke failed (exit $status); compose state and recent logs follow:" >&2 docker compose -f "$compose_file" ps >&2 || true docker compose -f "$compose_file" logs --no-color --tail 250 >&2 || true fi docker compose -f "$compose_file" down --remove-orphans || true exit "$status" } trap cleanup EXIT trap 'exit 130' INT trap 'exit 143' TERM docker compose -f "$compose_file" up -d --build "$project_root/tools/sitl/kaptan-sim" ready --timeout 30 "$project_root/tools/sitl/kaptan-sim" move 0 0 1.5 --wait --verify-truth --timeout 60 "$project_root/tools/sitl/kaptan-sim" move 5 3 5 --wait --verify-truth --timeout 90 "$project_root/tools/sitl/kaptan-sim" move -4 -2 2 --wait --verify-truth --timeout 90 # Start the terminal operation while airborne and off the landing point. A # `move ... 1` is an armed hover, not evidence of landing or zero motors. "$project_root/tools/sitl/kaptan-sim" land 0 0 --wait --verify-truth --timeout 60