Integrate the RealSense library in Balena ecosystem

I’m trying to integrate the intel RealSense Library into the Balena ecosystem, primarily to make it run in the Asus Tinker S, or if it is not possible in the Up Board.

Let’s start with what I have done up to now. I create a Balena project where I use an Ubuntu Xenial image.

There are 2 ways to install the library. The First method is adding a repository after updating, install software-properties-common, I tried to install the package but:

N: Skipping acquire of configured file ‘main/binary-armhf/Packages’ as repository ‘http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo xenial InRelease’ doesn’t support architecture ‘armhf’
And RealSense is not giving support for ARM architectures, So I got stuck in this way.

The second way is to build the libraries. The problem are the Prerequisites, I think (guess) that are Kernel libraries (so cant be changed from the Docker image?). When I tried to install the first ones I got these errors that were encountered while processing:

/var/cache/apt/archives/linux-modules-4.4.0-154-generic_4.4.0-154.181_armhf.deb
/var/cache/apt/archives/linux-image-4.4.0-154-generic_4.4.0-154.181_armhf.deb
/var/cache/apt/archives/linux-firmware_1.157.21_all.deb
/var/cache/apt/archives/linux-headers-4.4.0-154-generic_4.4.0-154.181_armhf.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

each of these libraries show this error: >

Preparing to unpack …/linux-headers-4.4.0-154-generic_4.4.0-154.181_armhf.deb …
Unpacking linux-headers-4.4.0-154-generic (4.4.0-154.181) …
dpkg: error processing archive /var/cache/apt/archives/linux-headers-4.4.0-154-generic_4.4.0-154.181_armhf.deb (–unpack):
unable to clean up mess surrounding ‘./lib/modules/4.4.0-154-generic’ before installing another version: Read-only file system
dpkg-deb: error: subprocess paste was killed by signal (Broken pipe)

I know I can change from the image the host kernel libraries, but I cant neither update the host OS that is a Yocto Linux version. I also know that RealSense require kernel version 4.18 in order to use the new cameras.

So I run out of ideas, any suggestion? when I use the apt-get install from the terminal console, when the image is restarted I lost all the changes (layers)?

Hi. We have an example project that allows one to build OOT kernel modules. https://github.com/balena-io-projects/kernel-module-build . Have you given this a look yet?

Thanks Ill check it out.

I’m executing these steps in the web ssh console and they execute correctly in the Ubuntu image:

sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y
sudo apt-get install -y git libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev cmake libglfw3-dev build-essential
git clone https://github.com/IntelRealSense/librealsense.git
cd librealsense/ && ./scripts/setup_udev_rules.sh
mkdir build && cd build
cmake …/ -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=false -DCMAKE_BUILD_TYPE=Release && make all -j4 && sudo make all

However when I try to push this dockerfile:

FROM resin/%%RESIN_MACHINE_NAME%%-ubuntu:xenial

RUN sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y
RUN sudo apt-get install -y git libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev cmake libglfw3-dev build-essential
RUN git clone https://github.com/IntelRealSense/librealsense.git
RUN cd librealsense/ && ./scripts/setup_udev_rules.sh
CMD mkdir build && cd build
RUN cmake /librealsense/ -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=false -DCMAKE_BUILD_TYPE=Release && make all -j4 && sudo make all

#switch on systemd init system in container
ENV INITSYSTEM on

#Run our binary on container startup
CMD /librealsense/examples/hello-realsense/rs-hello-realsense

And I got this error:

[main] make[1]: *** No rule to make target ‘//all’. Stop.
[main]
[main] make: *** [all] Error 2
[main]
[main] Makefile:127: recipe for target ‘all’ failed
[main] Removing intermediate container 35935127c9a3
[Info] Uploading images
[main] The command ‘/bin/sh -c cmake /librealsense/ -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=false -DCMAKE_BUILD_TYPE=Release && make all -j4 && sudo make all’ returned a non-zero code: 2
[Success] Successfully uploaded images
[Error] Some services failed to build:
[Error] Service: main
[Error] Error: The command ‘/bin/sh -c cmake /librealsense/ -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=false -DCMAKE_BUILD_TYPE=Release && make all -j4 && sudo make all’ returned a non-zero code: 2
[Error] Not deploying release.

I think the problem you have is that the working directory is not preserved between steps, so when you run CMD mkdir build && cd build the next step won’t be executed inside the build directory. Try changing it to:

RUN mkdir build &&\
    cd build &&\
    cmake /librealsense/ -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=false -DCMAKE_BUILD_TYPE=Release &&\
    make all -j4 &&\
    sudo make all

Additionally you can only have one CMD statement in your dockerfile, which should start the process that runs in your container. In this instance I think you just needed to use a RUN statement instead.

1 Like

Thanks for the explanation!!! It compiled. Now I have another question. The libraries were installed correctly. I would like to change this to a Build image and then copy them to the final machine because the current image is of 2G.

I have the full list of libraries and headers and their locations that were installed, these are few of them:

[main] – Installing: /usr/local/lib/librealsense2.so.2.24.0
[main] – Installing: /usr/local/lib/librealsense2.so.2.24
[main] – Installing: /usr/local/lib/librealsense2.so
[main] – Installing: /usr/local/include/librealsense2
[main] – Installing: /usr/local/include/librealsense2/h
[main] – Installing: /usr/local/include/librealsense2/h/rs_config.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_frame.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_sensor.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_record_playback.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_pipeline.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_device.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_types.h
[main] – Installing: /usr/local/include/librealsense2/h/rs_option.h

What I imagined is to make a copy of each one of them from the build image to the final one, but there is a smarter way to do it?

You could use CMAKE_INSTALL_PREFIX (https://cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html) to install the package to a custom location and then you can just copy the whole directory over.

1 Like

Adding to the advice from @telphan , take a look at multi-stage builds, as they are a convenient way to reduce your final image size: https://www.balena.io/blog/multi-stage-docker-builds-for-tiny-iot-images/

Hi @telpha, so I tried and it worked partially. I’m able to have all I need in a specific folder, but the CMAKEFiles generated get a wrong path. So might need to install it without the prefix and also again with a prefix in orther to copy them to the next stage and also copy the first installation CMAKEFILES ="/usr/local/lib/cmake/realsense2/realsense2". It makes any sense? I’m got it so wrong?

This is the error when I’m going to compile my application that uses the precompiled RealSense library:

– Configuring incomplete, errors occurred!
[main] See also “/usr/src/app/countingsystem/build/CMakeFiles/CMakeOutput.log”.
[main] CMake Error at CMakeLists.txt:73 (find_package):
[main] By not providing “Findrealsense2.cmake” in CMAKE_MODULE_PATH this project
[main] has asked CMake to find a package configuration file provided by
[main] “realsense2”, but CMake did not find one.
[main] Could not find a package configuration file provided by “realsense2” with
[main] any of the following names:
[main] realsense2Config.cmake
[main] realsense2-config.cmake
[main] Add the installation prefix of “realsense2” to CMAKE_PREFIX_PATH or set
[main] “realsense2_DIR” to a directory containing one of the above files. If
[main] “realsense2” provides a separate development package or SDK, be sure it has
[main] been installed.

Hi Andres, I’m not sure if I follow the issue you are experiencing. Are you using multi-stage docker builds already?

Please take a look at the link from Lucian and this one for demonstration:

This example shows how to copy files over to the final image.

Hi @gelbal!
I’m already using the multistage building. Maybe I’m not being clear with the following:

1)I need to compile the RealSense library and install it in the base and the final machine. To install In both machines I’m using:

RUN sudo make DESTDIR=/usr/src/librs install

and then

COPY --from=buildrs /usr/src/librs /usr/local

2) I need to compile my own app that is based on the RealSense Library. It is successfully compiling

3) I’m able to copy my app, but it seems that the step 1 is somehow not working. When I run the application, the application is not capable to find the library:

16.07.19 15:20:55 (+0200) main /usr/src/app/cbox_stereo_armhf: error while loading shared libraries: librealsense2.so.2.24: cannot open shared object file: No such file or directory

Just to let you know It finally worked. I reduce from 1.7GB to 800MB, the mistake was here:

When we add a “DESTDIR” it also add “/usr/local” at the end, therefore the solution was:

COPY --from=buildrs /usr/src/librs/usr/local /usr/local

Good to hear you made it work : )