Add the MKV recorder so a node can Record, not only preview
The recorder was the gap: it is FTF's own customised SDK example (a 1139-line K4A MKV writer), not a stock sample, and it lived only in one machine's build tree. Bring its source into the repo and build it as part of install. It writes K4A-format MKV — the format the rest of Ithaca reads — so it stays, and gets its libk4a from the Orbbec K4A wrapper rather than Microsoft's Azure Kinect SDK, which is set aside. build_k4a_wrapper.sh builds that wrapper; build_sdk.sh injects the recorder into the SDK examples tree and builds it there against the wrapper (it depends on the SDK's own cmake targets). Found by rpath at runtime, so no LD_LIBRARY_PATH. install.sh now builds wrapper -> SDK+recorder -> preview server, each reusing an existing build so the Nano is untouched. If the wrapper is unavailable the install still completes preview-only and says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c167c836e6
commit
23b30ac1e8
7 files changed
+1460
-49
No files matched your search
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# Makes sure the Orbbec K4A wrapper is built for THIS platform, and prints where
|
||||
# it is as K4A_WRAPPER_DIR=... for build_sdk.sh (the recorder example needs its
|
||||
# headers) and for the recorder's runtime rpath (its libk4a.so/libk4arecord.so).
|
||||
#
|
||||
# This is the libk4a provider — Orbbec's own, NOT Microsoft's Azure Kinect SDK.
|
||||
# It bundles its own OrbbecSDK internally, so it builds standalone. The recorder
|
||||
# dlopens the libk4a it produces (RTLD_DEEPBIND) rather than link-time linking it,
|
||||
# which is why only its build/lib path matters at runtime, not link time.
|
||||
#
|
||||
# Reuses an existing build (leaving a working node untouched) or clones + builds.
|
||||
set -euo pipefail
|
||||
|
||||
here=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
eval "$("$here/detect_platform.sh")"
|
||||
|
||||
REPO_URL="${OB_K4A_REPO:-https://github.com/orbbec/OrbbecSDK-K4A-Wrapper}"
|
||||
# The tag the Nano runs. A caller can override to one known to build on a newer
|
||||
# JetPack.
|
||||
REF="${OB_K4A_REF:-v1.10.4}"
|
||||
|
||||
find_wrapper() {
|
||||
local d="$1"
|
||||
[[ -f "$d/include/k4a/k4a.h" ]] || return 1
|
||||
[[ -f "$d/build/lib/libk4a.so" ]] || return 1
|
||||
echo "$d"
|
||||
}
|
||||
|
||||
for candidate in "${K4A_WRAPPER_DIR:-}" \
|
||||
"$HOME/OrbbecSDK-K4A-Wrapper" \
|
||||
"$HOME/Downloads/OrbbecSDK-K4A-Wrapper"; do
|
||||
[[ -z "$candidate" ]] && continue
|
||||
if find_wrapper "$candidate" >/dev/null 2>&1; then
|
||||
echo ">> Wrapper K4A deja bati, reutilise: $candidate" >&2
|
||||
echo "K4A_WRAPPER_DIR=$candidate"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
dir="${K4A_WRAPPER_DIR:-$HOME/OrbbecSDK-K4A-Wrapper}"
|
||||
echo ">> Wrapper K4A absent — clone et compilation (JetPack ${JETPACK}, ${SOC})" >&2
|
||||
echo ">> ${REPO_URL} @ ${REF} -> ${dir}" >&2
|
||||
|
||||
if [[ ! -d "$dir/.git" ]]; then
|
||||
# --recursive: the wrapper carries its OrbbecSDK and depth engine as submodules.
|
||||
git clone --recursive --depth 1 --branch "$REF" "$REPO_URL" "$dir" >&2
|
||||
fi
|
||||
|
||||
mkdir -p "$dir/build"
|
||||
(
|
||||
cd "$dir/build"
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release >&2
|
||||
make -j"$(nproc)" k4a k4arecord >&2
|
||||
)
|
||||
|
||||
if ! find_wrapper "$dir" >/dev/null 2>&1; then
|
||||
cat >&2 <<EOF
|
||||
|
||||
!! La compilation du wrapper K4A ne s'est pas terminee comme attendu
|
||||
!! (libk4a.so absent de $dir/build/lib).
|
||||
!! Bâtis-le une fois a la main, puis relance install.sh avec :
|
||||
!! K4A_WRAPPER_DIR=$dir ./install.sh
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
echo ">> Wrapper K4A bati: $dir" >&2
|
||||
echo "K4A_WRAPPER_DIR=$dir"
|
||||
+62
-23
@@ -1,71 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
# Makes sure an OrbbecSDK v2 build exists for THIS platform, and prints where it
|
||||
# is as OB_SDK_ROOT=... / OB_SDK_BUILD=... / OB_SDK_GENERATED=... for build_server.sh.
|
||||
# Makes sure an OrbbecSDK v2 build exists for THIS platform — INCLUDING the custom
|
||||
# MKV recorder example — and prints where it all is:
|
||||
#
|
||||
# OB_SDK_ROOT / OB_SDK_BUILD / OB_SDK_GENERATED the SDK
|
||||
# RECORDER_BIN the recorder binary, or empty
|
||||
#
|
||||
# Never ships a prebuilt binary between Jetsons: CUDA and glibc differ by
|
||||
# generation, so the SDK is built from source on the machine that will run it.
|
||||
# The heavy artifact stays out of git.
|
||||
# generation, so everything is built from source on the machine that runs it. The
|
||||
# heavy artifacts stay out of git.
|
||||
#
|
||||
# Order of preference:
|
||||
# 1. An existing build pointed to by $OB_SDK_ROOT — reused as-is. This is what
|
||||
# keeps a working node (the Nano already has one) untouched.
|
||||
# 2. A build at one of the known locations, likewise reused.
|
||||
# 3. A fresh clone + build. On a new JetPack this is the step to watch; if it
|
||||
# fails, build the SDK by hand once and re-run install.sh with OB_SDK_ROOT set.
|
||||
# The recorder is FTF's own source (recorder/ in this repo), not a stock SDK
|
||||
# example, so it is injected into the SDK's examples tree before the build and
|
||||
# compiled there — it depends on the SDK's own cmake targets (ob::examples::utils).
|
||||
# It needs the Orbbec K4A wrapper's headers; build_k4a_wrapper.sh provides them.
|
||||
#
|
||||
# Order of preference for the SDK itself:
|
||||
# 1. $OB_SDK_ROOT if it already holds a build — reused, which keeps a working
|
||||
# node (the Nano) untouched.
|
||||
# 2. A build at a known location, likewise reused.
|
||||
# 3. A fresh clone + build.
|
||||
set -euo pipefail
|
||||
|
||||
here=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
repo=$(cd "$here/.." && pwd)
|
||||
eval "$("$here/detect_platform.sh")"
|
||||
|
||||
# The official v2 source. Pinned loosely: a caller can override both to match a
|
||||
# tag known to build on their JetPack.
|
||||
SDK_REPO="${OB_SDK_REPO:-https://github.com/orbbec/OrbbecSDK_v2.git}"
|
||||
SDK_REF="${OB_SDK_REF:-main}"
|
||||
|
||||
find_build() {
|
||||
local root="$1"
|
||||
local root="$1" b
|
||||
[[ -f "$root/include/libobsensor/ObSensor.hpp" ]] || return 1
|
||||
local b
|
||||
b=$(ls -d "$root"/build/linux_* 2>/dev/null | head -1)
|
||||
[[ -z "$b" ]] && b="$root/build"
|
||||
[[ -f "$b/lib/libOrbbecSDK.so" ]] || return 1
|
||||
echo "$b"
|
||||
}
|
||||
|
||||
recorder_bin_in() { # echoes the recorder path under a build dir if present
|
||||
local b="$1"
|
||||
[[ -x "$b/bin/ob_stream_depth_color_k4arec_pipeline" ]] \
|
||||
&& echo "$b/bin/ob_stream_depth_color_k4arec_pipeline"
|
||||
}
|
||||
|
||||
emit() {
|
||||
local root="$1" build="$2"
|
||||
echo "OB_SDK_ROOT=$root"
|
||||
echo "OB_SDK_BUILD=$build"
|
||||
echo "OB_SDK_GENERATED=$root/build/src/generated"
|
||||
echo "RECORDER_BIN=$(recorder_bin_in "$build")"
|
||||
}
|
||||
|
||||
# 1 & 2: reuse whatever is already built.
|
||||
# Drops the FTF recorder into the SDK examples tree and registers it, so a plain
|
||||
# example build picks it up. Idempotent.
|
||||
inject_recorder() {
|
||||
local root="$1"
|
||||
local dst="$root/examples/1.stream.depth_color.k4arec.pipeline"
|
||||
mkdir -p "$dst"
|
||||
cp "$repo/recorder/depth_color_k4arec_pipeline.cpp" "$dst/"
|
||||
cp "$repo/recorder/CMakeLists.txt" "$dst/"
|
||||
local ex_cmake="$root/examples/CMakeLists.txt"
|
||||
if [[ -f "$ex_cmake" ]] \
|
||||
&& ! grep -q "1.stream.depth_color.k4arec.pipeline" "$ex_cmake"; then
|
||||
echo "add_subdirectory(1.stream.depth_color.k4arec.pipeline)" >> "$ex_cmake"
|
||||
fi
|
||||
}
|
||||
|
||||
# 1 & 2: reuse an existing SDK build. Only inject/rebuild the recorder if it is
|
||||
# missing there — never disturb the library build.
|
||||
for candidate in "${OB_SDK_ROOT:-}" \
|
||||
"$HOME/OrbbecSDK_v2" \
|
||||
"$HOME/OrbbecSDK_v2_jetson"; do
|
||||
[[ -z "$candidate" ]] && continue
|
||||
if b=$(find_build "$candidate" 2>/dev/null); then
|
||||
echo ">> SDK deja bati, reutilise: $candidate" >&2
|
||||
if [[ -z "$(recorder_bin_in "$b")" && -n "${K4A_WRAPPER_DIR:-}" ]]; then
|
||||
echo ">> Recorder absent de ce build — injection et compilation…" >&2
|
||||
inject_recorder "$candidate"
|
||||
( cd "$b" && cmake .. -DOB_BUILD_EXAMPLES=ON \
|
||||
-DK4A_WRAPPER_DIR="$K4A_WRAPPER_DIR" >&2 \
|
||||
&& make -j"$(nproc)" ob_stream_depth_color_k4arec_pipeline >&2 ) || true
|
||||
fi
|
||||
emit "$candidate" "$b"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
# 3: clone + build from source.
|
||||
# 3: clone + build from source, with examples and the recorder.
|
||||
root="${OB_SDK_ROOT:-$HOME/OrbbecSDK_v2}"
|
||||
echo ">> Aucun SDK bati — clone et compilation (JetPack ${JETPACK}, ${SOC})" >&2
|
||||
echo ">> ${SDK_REPO} @ ${SDK_REF} -> ${root}" >&2
|
||||
[[ -d "$root/.git" ]] || git clone --depth 1 --branch "$SDK_REF" "$SDK_REPO" "$root" >&2
|
||||
|
||||
if [[ ! -d "$root/.git" ]]; then
|
||||
git clone --depth 1 --branch "$SDK_REF" "$SDK_REPO" "$root" >&2
|
||||
fi
|
||||
inject_recorder "$root"
|
||||
|
||||
# The recorder needs the wrapper; without it the SDK still builds (its CMakeLists
|
||||
# skips the recorder with a warning), giving preview-only.
|
||||
cmake_k4a=()
|
||||
[[ -n "${K4A_WRAPPER_DIR:-}" ]] && cmake_k4a=(-DK4A_WRAPPER_DIR="$K4A_WRAPPER_DIR")
|
||||
|
||||
build="$root/build/linux_$(uname -m)"
|
||||
mkdir -p "$build"
|
||||
(
|
||||
cd "$build"
|
||||
# -DOB_BUILD_EXAMPLES=ON gives the k4a recorder sample used as recorder_bin.
|
||||
cmake ../.. -DCMAKE_BUILD_TYPE=Release -DOB_BUILD_EXAMPLES=ON >&2
|
||||
cmake ../.. -DCMAKE_BUILD_TYPE=Release -DOB_BUILD_EXAMPLES=ON "${cmake_k4a[@]}" >&2
|
||||
make -j"$(nproc)" >&2
|
||||
)
|
||||
|
||||
@@ -74,9 +111,11 @@ if ! b=$(find_build "$root" 2>/dev/null); then
|
||||
|
||||
!! La compilation du SDK ne s'est pas terminee comme attendu.
|
||||
!! Bâtis-le une fois a la main, puis relance install.sh en pointant dessus :
|
||||
!! OB_SDK_ROOT=<chemin> ./install.sh
|
||||
!! OB_SDK_ROOT=$root ./install.sh
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
echo ">> SDK bati: $b" >&2
|
||||
[[ -z "$(recorder_bin_in "$b")" ]] && \
|
||||
echo ">> NOTE: recorder non produit (wrapper K4A absent) — preview seule." >&2
|
||||
emit "$root" "$b"
|
||||
@@ -17,9 +17,12 @@ echo ">> Dependances pour JetPack ${JETPACK} (L4T ${L4T}, ${SOC})"
|
||||
# back to pip when the distro is too old to carry it.
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential cmake pkg-config \
|
||||
build-essential cmake pkg-config git \
|
||||
libusb-1.0-0-dev libudev-dev liblz4-dev libjpeg-turbo8-dev \
|
||||
libopencv-dev \
|
||||
python3 python3-pip
|
||||
# libopencv-dev: the MKV recorder links OpenCV (image handling). liblz4/libjpeg:
|
||||
# the preview server. libusb/libudev: the SDK and the K4A wrapper.
|
||||
|
||||
if ! python3 -c 'import websockets' 2>/dev/null; then
|
||||
echo ">> websockets absent — installation via pip"
|
||||
|
||||
Reference in new issue
Block a user