Real-time 3D visualization of LRAUV (Long Range Autonomous Underwater Vehicle) mission logs using ROS2 and RViz2.
# 1. Pull the image
docker pull mbari/tethystales:latest
# 2. Allow X11 access (required for GUI)
xhost +local:docker
# 3. Run with your LRAUV data
docker run -it --rm \
-e DISPLAY="$DISPLAY" \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v "$HOME/.Xauthority:/root/.Xauthority:ro" \
-v /mbari/LRAUV:/mbari/LRAUV:ro \
--network host \
mbari/tethystales:latest \
ros2 launch tethystales tethystales.launch.py vehicle:=tethys logset:=20250304T211257
The easiest way to load a mission log - just specify the vehicle name and logset timestamp:
docker run -it --rm \
-e DISPLAY="$DISPLAY" \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v "$HOME/.Xauthority:/root/.Xauthority:ro" \
-v /mbari/LRAUV:/mbari/LRAUV:ro \
--network host \
mbari/tethystales:latest \
ros2 launch tethystales tethystales.launch.py vehicle:=pontus logset:=20251117T180000
The system will automatically find the .nc4 file in the standard LRAUV directory structure. If the exact logset isn't found, it will search for the nearest match within 24 hours.
docker run -it --rm \
-e DISPLAY="$DISPLAY" \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v "$HOME/.Xauthority:/root/.Xauthority:ro" \
-v /mbari/LRAUV:/mbari/LRAUV:ro \
--network host \
mbari/tethystales:latest \
ros2 launch tethystales tethystales.launch.py log_file:=/mbari/LRAUV/tethys/missionlogs/2025/path/to/file.nc4
Opens RViz2 where you can load files via the UI panel:
docker run -it --rm \
-e DISPLAY="$DISPLAY" \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v "$HOME/.Xauthority:/root/.Xauthority:ro" \
-v /mbari/LRAUV:/mbari/LRAUV:ro \
--network host \
mbari/tethystales:latest
By default, the container expects LRAUV data at /mbari/LRAUV. To use a different location:
docker run -it --rm \
-e DISPLAY="$DISPLAY" \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v "$HOME/.Xauthority:/root/.Xauthority:ro" \
-v /path/to/your/data:/mbari/LRAUV:ro \
--network host \
mbari/tethystales:latest
| Parameter | Default | Description |
|---|---|---|
vehicle | '' | Vehicle name (tethys, pontus, daphne, etc.) |
logset | '' | Logset timestamp (e.g., 20250304T211257) |
log_file | '' | Direct path to .nc4 file |
playback_speed | 1.0 | Playback speed multiplier |
downsample_factor | 1 | Data downsampling (1-100) |
loop_playback | false | Loop at end of file |
cannot open display: :0
Solution: Run xhost +local:docker before starting the container.
The latest image uses software rendering by default, which works on any system. If you see GLX errors, ensure you're using the latest tag (not latest-nvidia).
Verify your data volume is mounted correctly:
docker run --rm -v /mbari/LRAUV:/mbari/LRAUV:ro mbari/tethystales:latest ls /mbari/LRAUV
#!/bin/bash
# Tethys Tales - Docker Run Script
# Runs the container with X11 forwarding and NVIDIA GPU support (if available)
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Default values
IMAGE_NAME="${IMAGE_NAME:-mbari/tethystales}"
IMAGE_TAG="${IMAGE_TAG:-latest}"
DATA_PATH="${LRAUV_DATA_PATH:-/mbari/LRAUV}"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
print_msg() {
echo -e "${GREEN}[Tethys Tales Docker]${NC} $1"
}
print_warn() {
echo -e "${YELLOW}[Tethys Tales Docker]${NC} $1"
}
print_error() {
echo -e "${RED}[Tethys Tales Docker]${NC} $1"
}
usage() {
echo "Usage: $0 [OPTIONS] [ROS_LAUNCH_ARGS...]"
echo ""
echo "Run the Tethys Tales Docker container"
echo ""
echo "Options:"
echo " --nvidia Force NVIDIA GPU support (use -nvidia tagged image)"
echo " --no-gpu Disable GPU detection, use software rendering"
echo " --shell Start a bash shell instead of launching ROS2"
echo " --scale FACTOR Set Qt UI scale factor (e.g., 1.0, 1.5, 2.0)"
echo " -h, --help Show this help message"
echo ""
echo "Environment variables:"
echo " IMAGE_NAME Override image name (default: mbari/tethystales)"
echo " IMAGE_TAG Override image tag (default: latest)"
echo " LRAUV_DATA_PATH Path to LRAUV data directory (default: /mbari/LRAUV)"
echo " QT_SCALE_FACTOR Qt UI scale factor (default: auto)"
echo ""
echo "Examples:"
echo " $0 # Launch with default settings"
echo " $0 log_file:=/mbari/LRAUV/path.nc4 # Launch with specific log file"
echo " $0 --nvidia # Force NVIDIA GPU"
echo " $0 --shell # Start interactive shell"
echo " $0 --scale 1.5 # Launch with 150% UI scaling"
echo " $0 playback_speed:=10.0 # Launch with 10x playback speed"
}
# Parse options
USE_NVIDIA=""
FORCE_NO_GPU=false
SHELL_MODE=false
SCALE_FACTOR="${QT_SCALE_FACTOR:-}"
ROS_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
--nvidia)
USE_NVIDIA="-nvidia"
shift
;;
--no-gpu)
FORCE_NO_GPU=true
shift
;;
--shell)
SHELL_MODE=true
shift
;;
--scale)
SCALE_FACTOR="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
ROS_ARGS+=("$1")
shift
;;
esac
done
print_msg "Starting Tethys Tales..."
# Enable X11 forwarding
print_msg "Enabling X11 forwarding..."
xhost +local:docker 2>/dev/null || {
print_warn "Could not run xhost. X11 forwarding may not work."
print_warn "Try running: xhost +local:docker"
}
# Detect NVIDIA GPU and DRI devices
NVIDIA_ARGS=""
DRI_ARGS=""
if [ "$FORCE_NO_GPU" = false ]; then
if command -v nvidia-smi &> /dev/null && nvidia-smi &> /dev/null; then
print_msg "NVIDIA GPU detected - enabling hardware acceleration"
NVIDIA_ARGS="--gpus all"
# Pass through DRI devices for OpenGL rendering
if [ -d "/dev/dri" ]; then
DRI_ARGS="--device /dev/dri:/dev/dri"
print_msg "Passing through /dev/dri for OpenGL rendering"
fi
# Use nvidia-tagged image if available and not explicitly set
if [ -z "$USE_NVIDIA" ]; then
# Check if nvidia image exists
if docker image inspect "${IMAGE_NAME}:${IMAGE_TAG}-nvidia" &> /dev/null; then
USE_NVIDIA="-nvidia"
print_msg "Using NVIDIA-optimized image"
fi
fi
else
print_warn "No NVIDIA GPU detected - using software rendering"
fi
else
print_msg "GPU disabled - using software rendering"
fi
# Check data path
if [ ! -d "$DATA_PATH" ]; then
print_warn "Data path not found: $DATA_PATH"
print_warn "Container will still run, but log files won't be accessible."
print_warn "Set LRAUV_DATA_PATH environment variable to your data directory."
fi
# Build the full image name
FULL_IMAGE="${IMAGE_NAME}:${IMAGE_TAG}${USE_NVIDIA}"
# Check if image exists
if ! docker image inspect "$FULL_IMAGE" &> /dev/null; then
print_error "Image not found: $FULL_IMAGE"
print_msg "You can build it with: ./docker/build.sh"
print_msg "Or pull it with: docker pull $FULL_IMAGE"
exit 1
fi
print_msg "Using image: $FULL_IMAGE"
print_msg "Data path: $DATA_PATH"
# Determine command to run
if [ "$SHELL_MODE" = true ]; then
DOCKER_CMD="bash"
print_msg "Starting interactive shell..."
elif [ ${#ROS_ARGS[@]} -gt 0 ]; then
DOCKER_CMD="ros2 launch tethystales tethystales.launch.py ${ROS_ARGS[*]}"
print_msg "Launching with arguments: ${ROS_ARGS[*]}"
else
DOCKER_CMD="ros2 launch tethystales tethystales.launch.py"
print_msg "Launching Tethys Tales..."
fi
echo ""
# Build scale factor argument
SCALE_ARG=""
if [ -n "$SCALE_FACTOR" ]; then
SCALE_ARG="-e QT_SCALE_FACTOR=${SCALE_FACTOR}"
print_msg "UI scale factor: ${SCALE_FACTOR}"
fi
# Run the container
docker run -it --rm \
${NVIDIA_ARGS} \
${DRI_ARGS} \
-e DISPLAY="${DISPLAY}" \
-e QT_X11_NO_MITSHM=1 \
${SCALE_ARG} \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v "${HOME}/.Xauthority:/root/.Xauthority:ro" \
-v "${DATA_PATH}:/mbari/LRAUV:ro" \
--network host \
"$FULL_IMAGE" \
$DOCKER_CMD
# Cleanup
print_msg "Revoking X11 access..."
xhost -local:docker 2>/dev/null || true
print_msg "Done!"
Content type
Image
Digest
sha256:00be33a90…
Size
400.5 MB
Last updated
4 months ago
docker pull mbari/tethystales