diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9282590..a94fed3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,14 +29,9 @@ jobs: - arch: arm64 runner: ubuntu-24.04-arm steps: - # Without git, actions/checkout downloads an archive, and init.sh can't check out the submodules - - name: Install git - run: apt-get update && apt-get install -y --no-install-recommends ca-certificates git - uses: actions/checkout@v5 - name: Install dependencies - run: | - git config --global --add safe.directory '*' - ./init.sh + run: ./init.sh - name: Build run: ./build.sh - name: Test diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 82f6e36..0000000 --- a/.gitmodules +++ /dev/null @@ -1,7 +0,0 @@ -[submodule "external/openocean-messages"] - path = external/openocean-messages - url = https://github.com/openocean-software/openocean-messages.git -[submodule "external/moos-ivp"] - path = external/moos-ivp - url = https://github.com/GobySoft/moos-ivp.git - shallow = true diff --git a/CMakeLists.txt b/CMakeLists.txt index ed1c740..ca7663b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,10 +16,11 @@ include(GNUInstallDirs) set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") find_package(Protobuf REQUIRED) -find_package(openocean_messages 0.1 REQUIRED COMPONENTS cpp) +find_package(openocean_messages 0.0.1 REQUIRED COMPONENTS cpp) -# MOOS-IvP's helm libraries (IVP_BUILD_HELM_LIBS_ONLY) -find_package(IVP CONFIG REQUIRED) +# MOOS-IvP's helm libraries (IVP_BUILD_HELM_LIBS_ONLY); libivp-helm-dev installs them in a +# prefix of their own, apart from a full MOOS-IvP +find_package(IVP CONFIG REQUIRED HINTS /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/ivp-helm) find_package(GOBY 3.0 COMPONENTS zeromq OPTIONAL_COMPONENTS moos) if(NOT GOBY_FOUND) diff --git a/README.md b/README.md index e6c3ea3..3e8d15f 100644 --- a/README.md +++ b/README.md @@ -18,19 +18,17 @@ One way to think of this project is as a generator for the equivalent of the MOO - ros: ROS middleware node - test: Tests, including replays of MOOS-IvP missions (`test/missions`) - launch: Example missions -- external: Submodules - - openocean-messages: [openocean-messages](https://github.com/openocean-software/openocean-messages), for the `Navigation` and `ControlSetpoint` messages - - moos-ivp: [MOOS-IvP](https://github.com/GobySoft/moos-ivp), for the IvP solver and behaviors ## Building *This section was written by Claude.* -`init.sh` checks out the submodules and installs the Ubuntu packages needed to build them and IvPico. These include Goby3, for the Goby app, adding [packages.gobysoft.org](http://packages.gobysoft.org)'s continuous builds if apt doesn't already have it; `init.sh --no-goby` leaves Goby3 out, and `build.sh` then skips the Goby app. `build.sh` then builds, all in `build/`, and installs each into `build/usr`: +`init.sh` installs the Ubuntu packages needed to build IvPico: -- openocean-messages, into `build/external/openocean-messages`; -- MOOS-IvP's helm libraries (`IVP_BUILD_HELM_LIBS_ONLY`, as shared libraries, without MOOS or its apps), into `build/external/moos-ivp`, installed first so that IvPico can `find_package(IVP)`; -- IvPico, against both. +- [openocean-messages](https://github.com/openocean-software/openocean-messages), for the `Navigation` and `ControlSetpoint` messages, and MOOS-IvP's helm libraries built without MOOS ([GobySoft's `ivp-without-moos`](https://github.com/GobySoft/moos-ivp/tree/ivp-without-moos)), for the IvP solver and behaviors. Both come from [Open Ocean Software](https://github.com/openocean-software/openocean-build)'s continuous builds (apt.oceansoft.org), added if apt doesn't already have them. +- Goby3, for the Goby app, adding [packages.gobysoft.org](http://packages.gobysoft.org)'s continuous builds if apt doesn't already have it. `init.sh --no-goby` leaves Goby3 out, and `build.sh` then skips the Goby app. + +`build.sh` then builds IvPico in `build/` and installs it into `build/usr`. ``` ./init.sh @@ -40,8 +38,6 @@ ctest --test-dir build `build.sh` passes any arguments on to IvPico's CMake, and `BUILD_DIR` overrides the build directory. Add `build/usr/bin` to your `PATH` to run the installed apps. -To update a submodule, check out the commit you want in it and commit the new pointer, e.g. `git -C external/openocean-messages pull origin main && git add external/openocean-messages`. - ## Goby app *This section was written by Claude.* diff --git a/build.sh b/build.sh index 3076bf5..ef41fd2 100755 --- a/build.sh +++ b/build.sh @@ -1,37 +1,11 @@ #!/usr/bin/env bash -# Builds the dependencies from their submodules (openocean-messages, and MOOS-IvP's helm libraries), -# then IvPico against them, all in BUILD_DIR (default build), and installs them all into -# BUILD_DIR/usr (e.g. add build/usr/bin to PATH). Arguments are passed on to IvPico's cmake. +# Builds IvPico in BUILD_DIR (default build) and installs it into BUILD_DIR/usr (e.g. add +# build/usr/bin to PATH). Arguments are passed on to IvPico's cmake. set -euo pipefail cd "$(dirname "$0")" -for submodule in openocean-messages moos-ivp; do - if [ -z "$(ls -A "external/${submodule}")" ]; then - echo "external/${submodule} is empty: run ./init.sh first" >&2 - exit 1 - fi -done BUILD_DIR=$(realpath -m "${BUILD_DIR:-build}") -OPENOCEAN_BUILD_DIR=${BUILD_DIR}/external/openocean-messages -IVP_BUILD_DIR=${BUILD_DIR}/external/moos-ivp -PREFIX=${BUILD_DIR}/usr -BUILD_DIR=${OPENOCEAN_BUILD_DIR} external/openocean-messages/build.sh -DBUILD_TESTING=OFF -cmake --install "${OPENOCEAN_BUILD_DIR}" --prefix "${PREFIX}" > /dev/null - -cmake -S external/moos-ivp/ivp/src -B "${IVP_BUILD_DIR}" -G Ninja \ - -DIVP_BUILD_HELM_LIBS_ONLY=ON -DBUILD_SHARED_LIBS=ON \ - -DIVP_LIB_DIRECTORY="${IVP_BUILD_DIR}/lib" \ - -DIVP_INC_DIRECTORY="${IVP_BUILD_DIR}/include" \ - -DIVP_BIN_DIRECTORY="${IVP_BUILD_DIR}/bin" -ninja -C "${IVP_BUILD_DIR}" -# find_package(IVP) only works from an installation -cmake --install "${IVP_BUILD_DIR}" --prefix "${PREFIX}" > /dev/null - -cmake -S . -B "${BUILD_DIR}" -G Ninja \ - -Dopenocean_messages_DIR="${OPENOCEAN_BUILD_DIR}" \ - -DIVP_DIR="${PREFIX}/lib/cmake/IVP" \ - -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ - "$@" +cmake -S . -B "${BUILD_DIR}" -G Ninja -DCMAKE_INSTALL_PREFIX="${BUILD_DIR}/usr" "$@" ninja -C "${BUILD_DIR}" cmake --install "${BUILD_DIR}" > /dev/null diff --git a/external/moos-ivp b/external/moos-ivp deleted file mode 160000 index 06f25ec..0000000 --- a/external/moos-ivp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 06f25ec0da52ec44d421cbe24f3522dd47bef11f diff --git a/external/openocean-messages b/external/openocean-messages deleted file mode 160000 index 11a1328..0000000 --- a/external/openocean-messages +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 11a132839af11befb3d858f4a4b3570d9dc013e5 diff --git a/init.sh b/init.sh index 7eec28b..d426ef8 100755 --- a/init.sh +++ b/init.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Checks out the submodules and installs the Ubuntu packages needed to build them and IvPico. +# Installs the Ubuntu packages needed to build IvPico. # # Usage: init.sh [--no-goby] # --no-goby don't install Goby3 (build.sh then skips the Goby app) @@ -24,8 +24,6 @@ for arg in "$@"; do esac done -git submodule update --init --recommend-shallow - SUDO="" if [ "$(id -u)" -ne 0 ]; then SUDO=sudo @@ -35,12 +33,33 @@ apt_install() { $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@" } -# moos-ivp's helm libraries (IVP_BUILD_HELM_LIBS_ONLY) need only CMake and a compiler # xz-utils: the replay tests' recorded missions are compressed packages=(cmake ninja-build g++ git ca-certificates protobuf-compiler libprotobuf-dev xz-utils) $SUDO apt-get update apt_install "${packages[@]}" +. /etc/os-release + +# openocean-messages and MOOS-IvP's helm libraries (built without MOOS), from Open Ocean +# Software's continuous builds (apt.oceansoft.org) if apt doesn't have them yet +oo_policy=$(apt-cache policy libivp-helm-dev) +if ! grep -q "Candidate: [^(]" <<< "${oo_policy}"; then + apt_install curl gpg + keyring=/usr/share/keyrings/openocean-continuous.asc + fingerprint=DAF08DD7788E6C84C6F8E8D3E59E1A81FECDB228 + key=$(curl -fsSL https://raw.githubusercontent.com/openocean-software/openocean-build/main/keys/continuous.asc) + if ! gpg --show-keys --with-colons <<< "${key}" | grep -q "^fpr:*${fingerprint}:"; then + echo "The Open Ocean Software continuous key's fingerprint isn't ${fingerprint}" >&2 + exit 1 + fi + $SUDO tee "${keyring}" <<< "${key}" > /dev/null + printf "Types: deb\nURIs: https://apt.oceansoft.org/continuous/%s-%s\nSuites: %s\nComponents: main\nSigned-By: %s\n" \ + "${ID}" "${VERSION_CODENAME}" "${VERSION_CODENAME}" "${keyring}" | + $SUDO tee /etc/apt/sources.list.d/openocean.sources > /dev/null + $SUDO apt-get update +fi +apt_install libopenocean-messages-dev libivp-helm-dev + if ${goby}; then # Goby3, for src/bin/goby. If apt doesn't have it yet, add packages.gobysoft.org's # continuous builds, which have 'goby test' (newer than 3.6.1) @@ -52,7 +71,6 @@ if ${goby}; then curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x19478082E2F8D3FE" | gpg --dearmor | $SUDO tee "${keyring}" > /dev/null fi - . /etc/os-release echo "deb [signed-by=${keyring}] http://packages.gobysoft.org/${ID}/continuous/ ${VERSION_CODENAME}/" | $SUDO tee /etc/apt/sources.list.d/gobysoft_continuous.list > /dev/null $SUDO apt-get update @@ -64,5 +82,3 @@ if ${goby}; then # MOOS-IvP's apps need libmoos-ivp but don't depend on it apt_install libgoby3-moos-dev goby3-moos moosdb10 moos-ivp-apps moos-ivp-gui libmoos-ivp fi - -external/openocean-messages/init.sh --cxx diff --git a/launch/goby/alpha/.gitignore b/launch/goby/alpha/.gitignore new file mode 100644 index 0000000..47241b6 --- /dev/null +++ b/launch/goby/alpha/.gitignore @@ -0,0 +1 @@ +images/ diff --git a/launch/goby/alpha/README.md b/launch/goby/alpha/README.md index f19539a..0bc01b3 100644 --- a/launch/goby/alpha/README.md +++ b/launch/goby/alpha/README.md @@ -38,9 +38,10 @@ As in MOOS-IvP's alpha, the helm parks when the survey is done (pHelmIvP's `park ## Viewing in pMarineViewer -`viewer.launch` shows the vehicle in pMarineViewer as in MOOS-IvP's alpha mission, with its buttons (DEPLOY, RETURN, ...) working. Start it after `alpha.launch`: +`viewer.launch` shows the vehicle in pMarineViewer as in MOOS-IvP's alpha mission, with its buttons (DEPLOY, RETURN, ...) working. Start it after `alpha.launch`, having fetched MOOS-IvP's background images once with `get_images.sh`: ``` +./get_images.sh goby_launch viewer.launch ``` diff --git a/launch/goby/alpha/get_images.sh b/launch/goby/alpha/get_images.sh new file mode 100755 index 0000000..4793b74 --- /dev/null +++ b/launch/goby/alpha/get_images.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Downloads the MOOS-IvP background images that set_datum_warp.sh can choose between (those with +# lat/lon bounds) into images/, for pMarineViewer (viewer.launch). +set -euo pipefail + +cd "$(dirname "$0")" +mkdir -p images +url=https://raw.githubusercontent.com/GobySoft/moos-ivp/ivp-without-moos/ivp/data +for image in forrest19 MIT_SP; do + for ext in tif info; do + [ -s "images/${image}.${ext}" ] || curl -fsSL -o "images/${image}.${ext}" "${url}/${image}.${ext}" + done +done +ls images diff --git a/launch/goby/alpha/set_datum_warp.sh b/launch/goby/alpha/set_datum_warp.sh index 36ca7c3..28faad8 100755 --- a/launch/goby/alpha/set_datum_warp.sh +++ b/launch/goby/alpha/set_datum_warp.sh @@ -38,7 +38,7 @@ while [ $# -gt 0 ]; do done goby_cfgs=(config/*.pb.cfg) -image_dir=${IVP_IMAGE_DIRS:-../../../external/moos-ivp/ivp/data} +image_dir=${IVP_IMAGE_DIRS:-images} # the smallest image whose .info bounds contain the datum image_for() { diff --git a/launch/goby/alpha/viewer.launch b/launch/goby/alpha/viewer.launch index 8a67761..6c69f65 100755 --- a/launch/goby/alpha/viewer.launch +++ b/launch/goby/alpha/viewer.launch @@ -3,5 +3,5 @@ # pMarineViewer, as in MOOS-IvP's alpha mission (see README.md): start after alpha.launch MOOSDB alpha.moos pNodeReporter alpha.moos -[env=IVP_IMAGE_DIRS=${IVP_IMAGE_DIRS:-$PWD/../../../external/moos-ivp/ivp/data}] pMarineViewer alpha.moos +[env=IVP_IMAGE_DIRS=${IVP_IMAGE_DIRS:-$PWD/images}] pMarineViewer alpha.moos [env=GOBY_MOOS_GATEWAY_PLUGINS=${GOBY_MOOS_GATEWAY_PLUGINS:-$PWD/../../../build/usr/lib/libivpico_moos_gateway_plugin.so}] goby_moos_gateway config/moos_gateway.pb.cfg diff --git a/src/test/missions/README.md b/src/test/missions/README.md index 0be77bf..eb610fe 100644 --- a/src/test/missions/README.md +++ b/src/test/missions/README.md @@ -13,10 +13,10 @@ flowchart LR ``` - `missions.txt` lists the missions and the variables poked to start them. -- `record.sh [mission...]` builds all of MOOS-IvP from `external/moos-ivp` into `build/missions`, runs each mission under pHelmIvP with time warp, and keeps each vehicle's helm inputs and outputs in `fixtures/`. The "Record missions" workflow runs it on GitHub and uploads the fixtures as an artifact. +- `record.sh [mission...]` builds all of MOOS-IvP from GobySoft's `ivp-without-moos` branch (the source of the `libivp-helm-dev` package) into `build/missions`, runs each mission under pHelmIvP with time warp, and keeps each vehicle's helm inputs and outputs in `fixtures/`. The "Record missions" workflow runs it on GitHub and uploads the fixtures as an artifact. - `replay ` feeds the recorded inputs to the IvPico helm at pHelmIvP's iteration times and compares what each helm posted. `replay.cpp` describes what's compared and the tolerances. -Re-record the fixtures whenever `external/moos-ivp` moves. +Re-record the fixtures whenever `libivp-helm-dev` moves to a new MOOS-IvP. ## Closed-loop runs under Goby diff --git a/src/test/missions/record.sh b/src/test/missions/record.sh index fbce1d9..1d28e18 100755 --- a/src/test/missions/record.sh +++ b/src/test/missions/record.sh @@ -1,11 +1,13 @@ #!/usr/bin/env bash # Records MOOS-IvP missions under pHelmIvP for the replay tests: builds all of -# MOOS-IvP from external/moos-ivp, runs each mission in missions.txt headless, -# and keeps each vehicle's helm inputs and outputs in fixtures/. +# MOOS-IvP from GobySoft's ivp-without-moos branch (libivp-helm-dev's source), +# runs each mission in missions.txt headless, and keeps each vehicle's helm +# inputs and outputs in fixtures/. # # Usage: record.sh [mission...] (default: every mission in missions.txt) # # WORK_DIR (default build/missions) holds the MOOS-IvP build and the runs. +# MOOS_IVP_BRANCH overrides the branch. # MOOS_BUILD_ARGS are passed to build-moos.sh, e.g. --with-proj=off. set -euo pipefail @@ -14,14 +16,13 @@ root=$(cd "${here}/../../.." && pwd) work=$(realpath -m "${WORK_DIR:-${root}/build/missions}") moos_ivp=${work}/moos-ivp -# A copy, so that building leaves the submodule clean if [ ! -x "${moos_ivp}/ivp/bin/pHelmIvP" ]; then rm -rf "${moos_ivp}" - mkdir -p "${moos_ivp}" - git -C "${root}/external/moos-ivp" archive HEAD | tar -x -C "${moos_ivp}" + git clone --depth 1 --branch "${MOOS_IVP_BRANCH:-ivp-without-moos}" \ + https://github.com/GobySoft/moos-ivp.git "${moos_ivp}" (cd "${moos_ivp}" && ./build-moos.sh --minrobot ${MOOS_BUILD_ARGS:-} && ./build-ivp.sh --nogui) fi -export PATH="${moos_ivp}/ivp/bin:${moos_ivp}/build/MOOS/MOOSCore/bin:${moos_ivp}/build/MOOS/MOOSEssentials/bin:${PATH}" +export PATH="${moos_ivp}/ivp/bin:${moos_ivp}/bin:${moos_ivp}/build/MOOS/MOOSCore/bin:${moos_ivp}/build/MOOS/MOOSEssentials/bin:${PATH}" # Keeps the log header, pHelmIvP's posts, and every post to a variable pHelmIvP # registered, without the duplicate lines pLogger sometimes writes