UnityTrafficSimulation/run-linux.sh

104 lines
3.7 KiB
Shell
Executable file

#!/usr/bin/env bash
set -euo pipefail
repo_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
output_dir="$repo_dir/Builds/linux"
player="$output_dir/Simulation.x86_64"
mode="${1:---demo}"
case "$mode" in
--demo|--server|--vnc) ;;
*) echo "Usage: $0 [--demo | --server | --vnc]"; exit 2 ;;
esac
if [[ ! -x "$player" ]]; then
echo "Build the Linux player first: ./build-linux.sh" >&2
exit 1
fi
if [[ "$mode" == --vnc && -z "${DISPLAY:-}" ]]; then
exec xvfb-run -a -s '-screen 0 1280x800x24 -nolisten tcp' "$0" --vnc
fi
if [[ "$mode" == --demo && -z "${DISPLAY:-}" ]]; then
echo "No display. Use --vnc to view over SSH, or --server for a headless server." >&2
exit 1
fi
if [[ "$mode" == --vnc ]]; then
command -v x11vnc >/dev/null || { echo "Install x11vnc, xvfb, and xauth." >&2; exit 1; }
fi
cd "$repo_dir"
mkdir -p "$output_dir"
children=()
cleanup() {
trap - EXIT INT TERM
if (( ${#children[@]} )); then
kill "${children[@]}" 2>/dev/null || true
wait "${children[@]}" 2>/dev/null || true
fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
# These services control the local simulation. Refuse to reuse unknown servers.
python3 - <<'PY'
import socket
for port in (8080, 8081):
with socket.socket() as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind(('127.0.0.1', port))
except OSError:
raise SystemExit('Port %s is already in use; stop the previous simulation first.' % port)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
try:
sock.bind(('0.0.0.0', 7777))
except OSError:
raise SystemExit('UDP port 7777 is already in use.')
PY
SIMULATION_BIND_ADDRESS=127.0.0.1 python3 -u traffic_light_server.py >"$output_dir/traffic.log" 2>&1 &
children+=("$!")
SIMULATION_BIND_ADDRESS=127.0.0.1 python3 -u event_server.py >"$output_dir/events.log" 2>&1 &
children+=("$!")
python3 - <<'PY'
import time, urllib.request
for port, path in ((8080, '/trafficLights/'), (8081, '/tweetCount')):
for attempt in range(50):
try:
with urllib.request.urlopen('http://127.0.0.1:%s%s' % (port, path), timeout=1) as response:
response.read()
break
except OSError:
time.sleep(.1)
else:
raise SystemExit('Backend failed to start; inspect Builds/linux/*.log')
PY
: > "$output_dir/server.log"
"$player" -batchmode -nographics --server \
--traffic-url http://127.0.0.1:8080 --event-url http://127.0.0.1:8081 \
-logFile "$output_dir/server.log" >"$output_dir/server-console.log" 2>&1 &
children+=("$!")
echo "Simulation server running on port 7777. Logs: $output_dir"
if [[ "$mode" != --server ]]; then
# Wait for UNet to finish loading the scene before connecting the client.
for ((attempt=0; attempt<100; attempt++)); do
if grep -q 'Simulation server started' "$output_dir/server.log"; then break; fi
kill -0 "${children[2]}" 2>/dev/null || exit 1
sleep .1
done
if ! grep -q 'Simulation server started' "$output_dir/server.log"; then
echo "Server startup timed out; inspect $output_dir/server.log" >&2
exit 1
fi
"$player" --connect 127.0.0.1 -screen-width 1280 -screen-height 800 \
-screen-fullscreen 0 -force-glcore -logFile "$output_dir/client.log" \
>"$output_dir/client-console.log" 2>&1 &
children+=("$!")
fi
if [[ "$mode" == --vnc ]]; then
x11vnc -display "$DISPLAY" -localhost -rfbport 5901 -forever -shared -nopw \
>"$output_dir/vnc.log" 2>&1 &
children+=("$!")
echo "Forward SSH port 5901, then connect your VNC viewer to localhost:5901."
fi
echo "Press Ctrl-C to stop the simulation and its services."
wait -n "${children[@]}"