#!/usr/bin/env bash # run.sh – Build UDPStreamer and launch the test MARTe2 application. # # Usage: # ./run.sh # run MARTe2 app only # ./run.sh --webui # also start the WebUI Go client in the background # ./run.sh --help # show this message # # The WebUI is started with three sources: # Streamer @ 127.0.0.1:44500 (scalar signals, PacketTime, 1 kHz) # FastStreamer @ 127.0.0.1:44501 (packed arrays, FirstSample/LastSample, 5 kHz) # FullArrStreamer @ 127.0.0.1:44502 (packed arrays, FullArray, 5 kHz) # Additional sources and a persistent source list file (--sources-file) can # be configured directly in the WebUI or by editing this script. # # Prerequisites: # - marte_env.sh must be present in the repo root (sets MARTe2_DIR, etc.) # - MARTe2 and MARTe2-components must already be built # # The script resolves all paths relative to the repo root so it can be # called from any working directory. set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" # ── Parse arguments ────────────────────────────────────────────────────────── START_WEBUI=0 for arg in "$@"; do case "$arg" in --webui) START_WEBUI=1 ;; --help|-h) sed -n '2,15p' "$0" exit 0 ;; esac done # ── Load MARTe2 environment ────────────────────────────────────────────────── ENV_SCRIPT="${REPO_ROOT}/marte_env.sh" if [ ! -f "${ENV_SCRIPT}" ]; then echo "ERROR: ${ENV_SCRIPT} not found." >&2 exit 1 fi # shellcheck source=/dev/null source "${ENV_SCRIPT}" if [ -z "${MARTe2_DIR}" ]; then echo "ERROR: MARTe2_DIR is not set after sourcing marte_env.sh." >&2 exit 1 fi # ── Build components ───────────────────────────────────────────────────────── TARGET=x86-linux UDPSTREAMER_SRC="${REPO_ROOT}/Source/Components/DataSources/UDPStreamer" UDPSTREAMER_LIB="${REPO_ROOT}/Build/${TARGET}/Components/DataSources/UDPStreamer" SINEARRAYGAM_SRC="${REPO_ROOT}/Source/Components/GAMs/SineArrayGAM" SINEARRAYGAM_LIB="${REPO_ROOT}/Build/${TARGET}/Components/GAMs/SineArrayGAM" TIMEARRAYGAM_SRC="${REPO_ROOT}/Source/Components/GAMs/TimeArrayGAM" TIMEARRAYGAM_LIB="${REPO_ROOT}/Build/${TARGET}/Components/GAMs/TimeArrayGAM" echo "==> Building UDPStreamer (TARGET=${TARGET})..." make -C "${UDPSTREAMER_SRC}" \ -f Makefile.gcc \ TARGET="${TARGET}" \ 2>&1 | tail -5 echo "==> Building SineArrayGAM (TARGET=${TARGET})..." make -C "${SINEARRAYGAM_SRC}" \ -f Makefile.gcc \ TARGET="${TARGET}" \ 2>&1 | tail -5 echo "==> Building TimeArrayGAM (TARGET=${TARGET})..." make -C "${TIMEARRAYGAM_SRC}" \ -f Makefile.gcc \ TARGET="${TARGET}" \ 2>&1 | tail -5 echo "==> Build done." # ── Build WebUI binary (if requested and not already built) ────────────────── WEBUI_DIR="${REPO_ROOT}/Client/WebUI" WEBUI_BIN="${WEBUI_DIR}/udpstreamer-webui" if [ "${START_WEBUI}" -eq 1 ] && [ ! -x "${WEBUI_BIN}" ]; then echo "==> Building WebUI..." (cd "${WEBUI_DIR}" && go build -o udpstreamer-webui ./...) echo "==> WebUI build done." fi # ── Set LD_LIBRARY_PATH ─────────────────────────────────────────────────────── COMP="${MARTe2_Components_DIR}/Build/${TARGET}/Components" export LD_LIBRARY_PATH="\ ${UDPSTREAMER_LIB}:\ ${SINEARRAYGAM_LIB}:\ ${TIMEARRAYGAM_LIB}:\ ${MARTe2_DIR}/Build/${TARGET}/Core:\ ${COMP}/DataSources/LinuxTimer:\ ${COMP}/DataSources/LoggerDataSource:\ ${COMP}/GAMs/IOGAM:\ ${COMP}/GAMs/WaveformGAM:\ ${LD_LIBRARY_PATH}" echo "==> LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" # ── Create class-name symlinks for MARTe2 auto-loader ──────────────────────── # MARTe2 looks for .so when a class is not yet registered. # Some components bundle multiple classes into one .so (e.g. WaveformGAM.so # contains WaveformSin, WaveformChirp, WaveformPointsDef). We need symlinks # so dlopen(".so") succeeds. WAVEFORM_DIR="${COMP}/GAMs/WaveformGAM" for cls in WaveformSin WaveformChirp WaveformPointsDef; do target="${WAVEFORM_DIR}/${cls}.so" if [ ! -e "${target}" ]; then ln -sf "${WAVEFORM_DIR}/WaveformGAM.so" "${target}" fi done # ── Optionally start WebUI ──────────────────────────────────────────────────── if [ "${START_WEBUI}" -eq 1 ]; then echo "==> Starting WebUI on http://localhost:8080 (source: 127.0.0.1:44500)..." "${WEBUI_BIN}" \ --source "Streamer@127.0.0.1:44500" \ --source "FastStreamer@127.0.0.1:44501" \ --source "FullArrStreamer@127.0.0.1:44502" \ --listen :8080 & WEBUI_PID=$! echo "==> WebUI PID ${WEBUI_PID}" fi # ── Launch MARTe2 application ───────────────────────────────────────────────── MARTE_APP="${MARTe2_DIR}/Build/${TARGET}/App/MARTeApp.ex" CFG="${SCRIPT_DIR}/TestApp.cfg" if [ ! -x "${MARTE_APP}" ]; then echo "ERROR: MARTeApp.ex not found at ${MARTE_APP}" >&2 exit 1 fi echo "==> Starting MARTe2 application (state=Running)..." echo "==> Thread1: scalar signals 1 kHz → port 44500" echo "==> Thread2: packed arrays 5 kHz → port 44501 (FirstSample / LastSample)" echo "==> Thread3: FullArray arrays 5 kHz → port 44502 (FullArray)" echo "==> Press Ctrl+C to stop." echo "" cleanup() { echo "" echo "==> Stopping..." if [ "${START_WEBUI}" -eq 1 ] && kill -0 "${WEBUI_PID}" 2>/dev/null; then kill "${WEBUI_PID}" fi } trap cleanup EXIT INT TERM "${MARTE_APP}" \ -l RealTimeLoader \ -f "${CFG}" \ -s Running