71 lines
3.9 KiB
Docker
71 lines
3.9 KiB
Docker
# Inspire hand service + web dashboard, self-contained (aarch64 / Jetson).
|
|
# Build context is assembled by build_image.sh (pulls unitree_sdk2 + CycloneDDS
|
|
# from the robot). Run with: --network host --privileged -v /dev:/dev
|
|
FROM arm64v8/ubuntu:20.04
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive TZ=UTC
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential cmake \
|
|
libboost-all-dev libspdlog-dev libeigen3-dev \
|
|
python3 python3-flask \
|
|
iproute2 procps ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# CycloneDDS (ddscxx + iceoryx) headers & runtime libs from the robot's /usr/local
|
|
COPY deps/usr_local_include/ /usr/local/include/
|
|
COPY deps/usr_local_lib/ /usr/local/lib/
|
|
RUN ldconfig
|
|
|
|
# unitree_sdk2 headers + prebuilt static lib (for build.sh linking)
|
|
COPY deps/unitree_sdk2/ /opt/unitree_sdk2/
|
|
|
|
# Record/replay panel: the recorder is a python child process that speaks DDS itself, so
|
|
# the image needs the bindings as well as the script. Skipped cleanly when build_image.sh
|
|
# could not find the sources (empty dirs) — the panel then reports "recorder not found".
|
|
# NOTE: this layer pip-installs, so the robot needs network access at BUILD time. Offline
|
|
# alternative: copy the robot's own site-packages in the same way the C libs are copied.
|
|
COPY deps/recorder/ /opt/recorder/
|
|
COPY deps/unitree_sdk2_python/ /opt/unitree_sdk2_python/
|
|
# cyclonedds is pinned to what unitree_sdk2py demands (0.10.2) — installing anything else
|
|
# just gets downgraded when the SDK lands. It is built from sdist here, so it compiles
|
|
# against the robot's own CycloneDDS headers (0.10.5) and links its libddsc.
|
|
ARG CYCLONEDDS_PY=0.10.2
|
|
ENV CYCLONEDDS_HOME=/usr/local
|
|
# The SDK is COPIED into dist-packages rather than pip-installed, and both alternatives
|
|
# were tried on the robot first:
|
|
# * a wheel install loses four subpackages — b2, comm, g1, h1 ship with no __init__.py,
|
|
# so find_packages() drops them and the package's own
|
|
# `from . import idl, utils, core, rpc, go2, b2` dies with "cannot import name 'b2'";
|
|
# * `pip install -e` reports success (runs setup.py develop) but never lands on sys.path
|
|
# in this image — the very next line still gets "No module named 'unitree_sdk2py'".
|
|
# A copy is deterministic and keeps every subdirectory, including the ones that resolve as
|
|
# implicit namespace packages. numpy comes from apt; opencv-python (its other declared
|
|
# dependency, ~100MB+) is skipped because nothing in the SDK imports cv2 — verified.
|
|
# The destination is derived from the freshly-installed cyclonedds rather than from
|
|
# sysconfig: on Debian/Ubuntu sysconfig's purelib is /usr/lib/python3.8/site-packages,
|
|
# which is not even on sys.path (it is dist-packages here), so the copy landed nowhere.
|
|
RUN if [ -d /opt/unitree_sdk2_python/unitree_sdk2py ]; then \
|
|
apt-get update && apt-get install -y --no-install-recommends \
|
|
python3-pip python3-dev python3-numpy && \
|
|
pip3 install --no-cache-dir "cyclonedds==${CYCLONEDDS_PY}" && \
|
|
cp -r /opt/unitree_sdk2_python/unitree_sdk2py \
|
|
"$(python3 -c 'import cyclonedds,os;print(os.path.dirname(os.path.dirname(cyclonedds.__file__)))')/" && \
|
|
python3 -c "import unitree_sdk2py, cyclonedds; print('python DDS ok')" && \
|
|
rm -rf /var/lib/apt/lists/* ; \
|
|
else echo "no unitree_sdk2_python in context — record/replay disabled"; fi
|
|
ENV RECORDER_DIR=/opt/recorder RECORDER_PY=python3
|
|
|
|
# the service sources (everything except web/), then build the binaries in-image
|
|
COPY app/ /opt/hand/
|
|
WORKDIR /opt/hand
|
|
RUN chmod +x build.sh docker/start.sh manage.sh 2>/dev/null; \
|
|
UNITREE_SDK2_DIR=/opt/unitree_sdk2 ./build.sh
|
|
|
|
# The dashboard goes in LAST, on purpose: it is the part that changes every other day, and
|
|
# from here a redeploy is a seconds-long layer copy instead of a full C++ recompile.
|
|
COPY app_web/ /opt/hand/web/
|
|
|
|
ENV HAND_REPO=/opt/hand
|
|
EXPOSE 8088
|
|
CMD ["/opt/hand/docker/start.sh"]
|