fleet/agents/go2/Dockerfile

48 lines
2.1 KiB
Docker

# sanad_api_go2 — Go2 fleet telemetry agent (reads DDS: rt/lowstate, unitree_go).
#
# BUILD ON THE GO2 COMPUTE (native arm64). The DDS stack: prebuilt CycloneDDS
# (apt) + the CycloneDDS python binding (pip) + the vendored unitree_sdk2py wheel
# (includes both unitree_go and unitree_hg idl). Run with --network host so the
# robot's DDS is visible (see docker-compose.yml).
FROM python:3.10-slim-bookworm
# CycloneDDS C lib + idlc (bookworm ships 0.10.2 — matches the robot), build tools
# for the python binding, iproute2 for iface checks, libgomp1 for the TLS guard.
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake \
cyclonedds-dev cyclonedds-tools \
iproute2 libgomp1 ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# aarch64 "static TLS block" guard (harmless on amd64).
ENV LD_PRELOAD=libgomp.so.1
# cyclonedds build helper looks for libddsc.so under $CYCLONEDDS_HOME/lib; Debian
# installs into the multiarch dir — symlink whatever arch built into /usr/lib.
ENV CYCLONEDDS_HOME=/usr
RUN set -e; for lib in libddsc.so libcycloneddsidl.so; do \
f=$(ls /usr/lib/*/"$lib" 2>/dev/null | head -1); \
[ -n "$f" ] && ln -sf "$f" /usr/lib/"$lib" || true; \
done
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# CycloneDDS python binding, compiled against the C lib above. 0.10.2's build
# helper imports wheel.bdist_wheel (removed in wheel>=0.46) → pin the toolchain.
RUN pip install --no-cache-dir "setuptools<80" "wheel<0.46" \
&& pip install --no-cache-dir --no-build-isolation cyclonedds==0.10.2
# Unitree SDK (vendored wheel — not on PyPI) + native crc lib (wheel omits it).
# Both arch crc libs are copied; unitree_sdk2py loads the one matching the image.
COPY vendor/unitree_sdk2py-*.whl /tmp/
RUN pip install --no-cache-dir --no-deps /tmp/unitree_sdk2py-*.whl
COPY vendor/crc_aarch64.so vendor/crc_amd64.so \
/usr/local/lib/python3.10/site-packages/unitree_sdk2py/utils/lib/
COPY sanad_api_go2.py .
ENV PYTHONUNBUFFERED=1 \
DDS_INTERFACE=eth0 \
DDS_DOMAIN=0
ENTRYPOINT ["python", "-u", "sanad_api_go2.py"]