Running custom apps on HemiStereo devices
Base images
Full root access enables you to run your own applications on HemiStereo NX. While it is possible to run your app directly on the host OS, it is preferred to use containers for developing and deploying apps. We provide some pre-configured container images which can be used as base for your custom application:
Image |
Description |
---|---|
Ubuntu 18.04 image with Nvidia repositories enabled. |
|
3dvl/l4t-base + CUDA runtime packages installed. |
|
3dvl/l4t-cuda-base + CUDA development packages installed. |
|
3dvl/l4t-cuda-base + jetson-multimedia-api, Boost, gRPC, OpenCV, TensorRT, VisionWorks runtime libraries. |
|
3dvl/l4t-cuda-dev + CMake, jetson-multimedia-api, Boost, gRPC, OpenCV, TensorRT, VisionWorks development libraries. |
Depending on your needs, choose on of the *-dev
images above for
development. Compiled binaries can then be used in the corresponding runtime
images to deploy it to other devices. The image tags are defined by the following
scheme:
<MACHINE>-<L4T-VERSION>[-<IMAGE_VERSION>]
Set MACHINE
depending on your device to jetson-xavier-nx
for
the HemiStereo NX***-X or jetson-nano
for the HemiStereo NX***-N. At the
moment L4T-VERSION
must be set to r32.4
. IMAGE_VERSION
can be set to latest
to get the latest version of the base images.
Note
The l4t-*
images do not have an image version. So this part of the
image tag has to be omitted.
Container networking
Internal docker network
Containers can communicate with each other over network communication protocols.
To see each other, they have to be in the same docker network. By default, a
docker network hemistereo_backend
exists which can be used for internal
communication. For example, adding your container to the
hemistereo_backend
allows you to access the stereo application directly
using the hostname stereo_backend
and port 51346
.
Note
Because in this case, the stereo application is access directly, the
app
field in the HTTP header can also be omitted.
Note
To make a service running in your container accessible from outside, you have to publish its ports.
Host network
Another possible solution for accessing other services is to enable host
networking for your container. In this
case you can only access the published ports of other containers. For example,
to access the stereo application from your container, you have to connect to
localhost:8888
and set the app
field in the HTTP header to
stereo
. See Setup client context.
Note
All ports that are opened inside the container will be opened also on the host which can lead to conflicts.
Example
In this section we want to have a look at the grpc_cpp_sample. In this sample, stereo frames are read from the stereo application by using its gRPC interface. In this section, we focus on making the sample running on the device. For the usage of the gRPC application service, please read the chapter Application service.
Besides the C++ sources of the application, the repository contains also the following files:
File |
Description |
---|---|
docker/<MACHINE>/Dockerfile |
Contains the build instructions for container image. |
docker/<MACHINE>/docker-compose.yml |
The Docker Compose file containing the app configuration, e.g. volumes, ports, networks… |
Dockerfile
For different machines, different Dockerfile`s exist under
:code:`docker/<MACHINE>
. Let’s have a look at the Dockerfile
for the
Jetson Xavier NX:
FROM 3dvl/hemistereo-base-dev:jetson-xavier-nx-r32.4-latest AS builder
COPY . /src
WORKDIR /build
RUN cmake -DCMAKE_GENERATOR=Ninja /src && ninja
FROM 3dvl/hemistereo-base:jetson-xavier-nx-r32.4-latest
COPY --from=builder /build/grpc_cpp_sample /app/
ENTRYPOINT [ "/app/grpc_cpp_sample" ]
The Dockerfile
contains the build instructions for our docker image. As
you can see, a multi-stage build is used. First we use the
3dvl/hemistereo-base-dev
image to build the example code using CMake and Ninja, then we copy the
binary to a smaller runtime image based on 3dvl/hemistereo-base
. The
runtime images will execute the binary automatically when it is started.
docker-compose.yml
The docker-compose.yml
is used for defining the application itself.
Multiple containers can be defined in the service
section of the
docker-compose.yml
. In our case, we have only need to have one
definition for the grpc_cpp_example
container:
version: "3.0"
services:
grpc_cpp_sample:
image: grpc_cpp_sample:latest
build:
context: ../../
dockerfile: ./docker/jetson-xavier-nx/Dockerfile
networks:
- hemistereo_backend
volumes:
- ./record:/record
command: stereo_backend:51346
networks:
hemistereo_backend:
external: true
Let’s have a closer look at our service description:
- image
The image name is set to
grpc_cpp_sample
and the tag tolatest
. When the file is executed by Docker Compose, Docker will run the image if it exists or build it if not.- build
build
contains some information that is necessary to build the container. Thecontext
is set to the root directory of the repository.dockerfile
points to the corresponding Dockerfile.- networks
The container is added to the
hemistereo_backend
network. Note that this network is also defined in the network section of thedocker-compose.yml
.- volumes
The sample application records images to the
/record
directory in the container. To access the images from host, we mount the/record
directory as volume from a local folder./record
.- command
The last entry in the service section of the
docker-compose.yml
is thecommand
. In theDockerfile
the entrypoint was set to the application executable. The application requires the service address of the stereo application. Thecommand
is appended to the entrypoint by Docker, so the address is provided here. Because thestereo_backend
container is part of the same network, we can use its name for addressing. The service port for the direct connection is51346
. If the connection is established from an external network, the device’s IP and port8888
have to be used.
Building the image and running the container
To build the image, go to the docker directory of your machine and run
docker-compose build
and docker-compose run
:
cd docker/jetson-xavier-nx
docker-compose build
docker-compose run
A record
folder will be created under the current directory and the
application will start writing images into it.
Start the application automatically
If you want to run you application automatically after booting the device, you
can set a restart policy in the
docker-compose.yml
. For example, you could set restart
to
unless-stopped
to restart the container alway unless you stop it
manually.
Stopping the application
To stop the application, navigate to the machine’s docker directory and call
docker-compose stop
:
cd docker/jetson-xavier-nx
docker-compose stop
This will stop the application but does not remove the containers. If you also
want to remove the containers, use docker-compose down
instead.