Hardware Access for Robotics, Vision & Multimedia Workloads
This guide outlines best practices for building containerized workloads on the Admiral platform that require direct, low-latency hardware access for Robotics (ROS/ROS2), Computer Vision, Motor Controllers, GPU/NPU Acceleration, and Multimedia Subsystems.
Unlike standard cloud containers, Admiral workloads run on physical edge nodes, autonomous mobile robots (AMRs), interactive kiosks, and embedded SBCs. This architecture bypasses heavyweight hypervisors and abstraction layers to communicate directly with hardware interfaces (SocketCAN, V4L2, Serial/UART, DRM/KMS, ALSA, and Evdev).
1. Robotics & Autonomous Hardware Access
Robotics systems require real-time determinism, low-latency sensor ingestion, and high-bandwidth inter-process communication (IPC).
Serial & Motor Controllers (/dev/ttyUSB*, /dev/ttyACM*)
Motor controllers, microcontrollers (STM32, Arduino, Teensy), and IMUs typically communicate over USB serial bridges.
Configuration in Admiral:
- Full device access is the default (Device Isolation off), so every node under
/devis already visible. - With Device Isolation on, bind individual device nodes back in via System Mounts:
/dev/ttyUSB0 → Motor Controller / Odometry Board/dev/ttyACM0 → Microcontroller / IMU Sensor/dev/ttyS0 → Hardware UART Header
CAN Bus & Actuators (SocketCAN)
Industrial robots, mobile robotic bases (AGVs/AMRs), and vehicle automation systems rely on Controller Area Network (CAN) bus protocols.
- Admiral OS natively loads the kernel
canandcan_rawdrivers. - Workloads configured with Host Network (
hostNetwork: true) can directly bind tocan0andcan1interfaces using standard Linux SocketCAN utilities (candump,cansend, orpython-can).
Vision Sensors, LiDAR & Depth Cameras (V4L2 / USB)
Autonomous navigation and perception workloads depend on high-throughput cameras (Intel RealSense, OAK-D, StereoLabs ZED, industrial GigE/UVC cameras):
/dev/video0 → RGB Color Stream
/dev/video1 → Depth Map / IR Stream
/dev/video2 → Metadata Stream
/dev/bus/usb → Direct USB Device Tree (Firmware upload & USB3 transfers)
| Interface | Linux device node | Typical use |
|---|---|---|
| USB 3.0 depth cameras | /dev/video*, /dev/bus/usb | Intel RealSense D435/D455, Luxonis OAK-D stereo cameras with raw depth maps and IMU sync. |
| MIPI CSI-2 | /dev/video*, /dev/media* | Direct sensor deserialisation (GMSL2 / FPD-Link III) for high-bandwidth automotive and drone cameras. |
| Network IP cameras | Host Network (UDP/RTSP) | Multi-camera RTSP and WebRTC decoding. |
Dockerfile Best Practice for Camera Drivers: Ensure user permissions and udev rule compatibility by running workloads with rootless or properly mapped device groups:
# Grant container process access to video and dialout groups
RUN usermod -aG video,dialout,plugdev root
USB Peripherals, Adapters & Dynamic Hotplug (libusb / USB Devices)
Edge nodes deploying industrial serial bridges, USB sensors, smartcard readers, hardware dongles, and specialized peripherals interface via raw USB interfaces (libusb) or Linux subsystem drivers.
Dynamic USB Hotplug & Reconnection
Under conventional Docker, binding a static device path like --device /dev/bus/usb/001/004 breaks as soon as a peripheral power-cycles or disconnects, because the Linux kernel re-enumerates the hardware with a new device node number (e.g. 001/005).
On Admiral:
- Default
/devBind Mount Strategy: Admiral mounts the host/devtree into the workload using recursive slave propagation (rbind, rslave). - When a USB device is plugged in, power-cycled, or re-enumerated, the new
/dev/bus/usb/<bus>/<devnum>node is immediately visible inside the running workload namespace without requiring a container restart. - Cgroup Device Rules: Admiral's cgroup v2 controller permits all character USB devices (
c 189:* rwm) by default unless Device Isolation (isolateDevices: true) is explicitly configured.
User & Device Permissions
Inside your container userspace, ensure the application or daemon user belongs to the necessary device groups:
# Ensure system groups exist and add application service user
RUN usermod -aG dialout,plugdev,lp appuser
Persistent Peripheral State & Configurations
Hardware calibration profiles, sensor databases, and persistent logs should survive container restarts and software updates. In your Admiral configuration, bind dedicated Custom Volumes:
Volume: device-data → Mount Path: /var/lib/device-service
Volume: device-config → Mount Path: /etc/device-service
Multi-Service Appliance Pattern (Application + Background Daemon + SSH)
Because Admiral treats OCI images as a full userspace rootfs, you can run an application, a local hardware daemon, and an emergency SSH daemon together under an entrypoint script:
#!/bin/bash
set -e
# 1. Generate or restore SSH host keys on a persistent volume
if [ ! -f /etc/ssh/keys/ssh_host_rsa_key ]; then
mkdir -p /etc/ssh/keys
ssh-keygen -A
cp -n /etc/ssh/ssh_host_* /etc/ssh/keys/
else
cp -u /etc/ssh/keys/* /etc/ssh/
fi
/usr/sbin/sshd -D &
# 2. Start any local background services or hardware daemons
/usr/bin/hardware-daemon --background &
# 3. Launch your primary application using absolute executable paths
exec /opt/venv/bin/python -m app.service --port 8080
High-Speed Zero-Copy Shared Memory (/dev/shm)
Robotics perception stacks (like ROS2 point cloud processing and OpenCV video pipelines) pass gigabytes of data per second between processes.
- Docker defaults
/dev/shmto 64MB, which drops ROS 2 shared-memory messages under load. - Admiral default: every workload gets a private
/dev/shmsized to half of the workload's memory limit, which is roughly 40% of physical RAM on most boards. CycloneDDS, FastDDS, and Iceoryx zero-copy transports work without extra configuration. - Camera and LiDAR drivers can write raw frames straight into shared memory, so perception and SLAM nodes read them with no serialisation or copy.
- Explicit sizing: to pin a specific size, add a System Mount of type
tmpfsat/dev/shmwith asize=option. It replaces the default:Mount: tmpfs → /dev/shm (Type: tmpfs, Options: size=4g)
ROS 2 DDS Discovery & Multicast
ROS 2 nodes discover each other using DDS discovery over UDP multicast, which the default bridged network blocks. Enable Host Network (hostNetwork: true) in your configuration. There is then no network namespace, bridge, or NAT between the workload and the robot's network:
- FastDDS and CycloneDDS multicast discovery reaches on-chassis compute, other robots, operator stations, and charging docks on the same network.
- Unicast peer lists and discovery servers (for networks that block multicast) work as they do on a bare Linux host.
- Off-board tools such as RViz2, PlotJuggler, and Foxglove Studio see the robot's topics when
ROS_DOMAIN_IDmatches.
See Networking for the network modes.
Real-Time Scheduling
Control loops (ros2_control, drive controllers, balancers) need bounded scheduling latency. Workloads have CAP_SYS_NICE and CAP_SYS_RESOURCE with unlimited locked memory, so nodes can set SCHED_FIFO / SCHED_RR priorities and lock their memory to avoid page-fault stalls. Admiral kernels are fully preemptible; for hard real-time guarantees, see Real-time kernels.
2. GPU & NPU Acceleration
Computer vision, depth perception, and neural inference need direct access to GPUs and NPUs. Admiral supplies the device nodes and, on NVIDIA hardware, the matching host driver libraries, so images do not bundle host kernel drivers. Frameworks such as CUDA, TensorRT, and PyTorch stay in your image.
NVIDIA x86 GPUs
On x86 machines with NVIDIA GPUs, Admiral OS detects the host driver and injects kernel device nodes into the workload namespace:
/dev/nvidia0 # Primary GPU execution device
/dev/nvidiactl # NVIDIA control device
/dev/nvidia-uvm # Unified memory management device
/dev/nvidia-uvm-tools # Profiling and diagnostic interface
- No container driver bloat: Images do not need to bundle host kernel drivers. CUDA, TensorRT, and ROS perception stacks run against host-injected device nodes and libraries.
- Unified memory (
/dev/nvidia-uvm): Zero-copy transfers between system RAM and GPU memory for point-cloud processing and camera-frame inference.
Admiral injects device nodes and host driver libraries. Application frameworks stay in your image.
NVIDIA Jetson Orin (developer preview)
Jetson AGX Orin, Orin NX, and Orin Nano use a native NVGPU path rather than the x86 /dev/nvidia0 + UVM layout.
- The platform supplies GPU firmware, kernel modules, and
libcuda.so.1, mounted directly into standard multiarch paths (/usr/lib/aarch64-linux-gnu/and/usr/lib/) for zero-configuration drop-in support. - Your
linux/arm64glibc image supplies the CUDA runtime, application, and any graphics userspace (EGL, OpenGL, Vulkan). - CUDA compute and GPU display output share this driver path.
nvidia-smiis not part of the Orin layout.
See Running GPU applications on Jetson Orin for the image contract, mount paths, group membership, and verification steps.
Rockchip RK3588 NPU
For low-power autonomous systems, smart cameras, and drone companion computers operating under strict 15W thermal budgets, Admiral provides native pass-through for the Rockchip RK3588 6 TOPS NPU:
- Direct
/dev/rknpuNode: The Rockchip Neural Processing Unit is mounted directly into container workloads with full read/write permissions. - RKNN runtime in your image: Ship
librknnrt.soin the container and run INT8 and FP16 quantized YOLOv8, MobileNet, and custom vision models with sub-10ms inference times at minimal power draw.
3. Fullscreen Graphics & DRM Display Pipelines
When running graphical user interfaces (Qt, Chromium, Flutter, or custom OpenGL/Vulkan apps) on bare metal without a desktop environment (GNOME/XFCE):
Direct Rendering Manager (DRM/KMS)
Workloads talk directly to the Linux Kernel Mode Setting (KMS) display drivers:
/dev/dri/card0 → Display Output Pipeline (Resolution & Mode Setting)
/dev/dri/renderD128 → 3D Hardware Acceleration & Video Decode
Eliminating X11 Overhead with Wayland
For touch displays and modern UI frameworks, deploy lightweight Wayland compositors (such as cage or weston) directly inside the container:
# Install lightweight kiosk compositor
RUN apt-get update && apt-get install -y cage
Set container environment variables:
WLR_DRM_NO_MODIFIERS=1
XDG_RUNTIME_DIR=/tmp
4. Audio Strategy: Direct ALSA Implementation
To guarantee reliable audio playback and microphone capture across industrial PCs, kiosks, and robotic voice interaction systems, communicate directly with the ALSA kernel drivers.
The "PulseAudio Trap"
Standard desktop Linux images include libasound2-plugins, which attempt to route all audio through a non-existent PulseAudio/PipeWire daemon.
Best Practice: Remove the plugin package in your Dockerfile:
RUN apt-get update && apt-get remove -y libasound2-plugins || true
The "Plug" Conversion Layer
Hardware sound cards often demand strict sample formats (e.g., Integer 16-bit @ 48kHz). If your application streams 32-bit float audio, the driver will fail.
Configure /etc/asound.conf inside your container to enable transparent format and sample rate conversion:
pcm.!default {
type plug
slave {
pcm "hw:0,0"
rate 48000
}
}
ctl.!default {
type hw
card 0
}
5. Input Devices & Emergency Controls (Evdev)
Touchscreens, rotary dials, hardware keypads, and physical Emergency Stop (E-Stop) switches interface via the Linux event interface (/dev/input/event*).
- Bind
/dev/inputinto the container. - In-container event listeners read raw evdev events with zero windowing latency:
from evdev import InputDevice, categorize, ecodesdev = InputDevice('/dev/input/event0')for event in dev.read_loop():if event.type == ecodes.EV_KEY:print(f"Hardware Input Event: {event.code} Value: {event.value}")
Next Steps
Learn how to bundle these hardware capabilities into versioned Configurations and deploy them to Fleets. For what stays in your workload versus the platform (Wi-Fi, reboots, kernel patches, carrier boards, boot branding), see Platform Boundary & Customisation.