Robotics StackExchange | Archived questions

sdk from meta-ros

Hi,

I'm trying to get a minimal setup of ROS 2 working for my companies eco system, which requires an OpenEmbedded toolchain. meta-ros has been integrated into our project and an image with ros-base could be build and seems to work.

The setup is based on OpenEmbedded dunfell with ROS 2 foxy. The branch dunfell from the meta-ros-repo is used. A newer ROS 2 version (also rolling) could be used, however dunfell can not be changed.

The next step would be to extent our toolchain/sdk with the requirements to build ROS nodes.

However not much could be found regarding this. And some other answers suggest to create a recipe to build custom-ros-nodes. This would not be suitable for us. In https://github.com/ros/meta-ros/wiki/Superflore-OE-Recipe-Generation-Scheme#defer-until-ros_superflore_generation_scheme-3 it is mentioned that nativesdk will be included for ROS_SUPERFLORE_GENERATION_SCHEME 3 however I could not find what 3 means and I assume based on the surrounding documentation that the current version is 2, but I could not find a clear statement regarding that or a planned timetable for the implementation of generation 3.

So after a long intro to my question. Is there a working way to create an OpenEmbedded SDK for ROS 2 and where could I find it?

What I did till now is to extent ament-cmake and its depending packages by BBCLASSEXTEND = "native nativesdk" and included these nativesdk-ament-* packages within the dependencies of the SDK. ament seems to be found when the toolchain is used to corsscompile, and I'm currently stopped by cmake not finding middlewares with the following error:

CMake Error at /home/ilocalstorage-ssd/tneumann/sdk/17.266f5bc31/sysroots/core2-64-oe-linux/usr/share/rmwimplementation/cmake/rmwimplementation-extras.cmake:54 (message):
  The RMW implementation has been specified as 'rmwfastrtpscpp' via
  environment variable 'RMW_IMPLEMENTATION', but it is not available at this
  time.

Currently available middlewares:

''

Help regarding this specific problem would be nice, but the main focus of the question should be "is that the correct path I'm following, or should I look into a different direction?".

it's quite a complex questions, but I tried to describe the general problem as good as I could so that it would also be helpful for the next persons running into the same problems.

best regards Tobias

Asked by Tobias Neumann on 2021-08-05 03:04:31 UTC

Comments

The problem regarding the not found RMW_IMPLEMENTATION where caused by the ament_index not been set up correctly. I could bypass this by setting export AMENT_PREFIX_PATH=<path-to-my-sdk>/sysroots/core2-64-oe-linux/usr/

Asked by Tobias Neumann on 2021-08-05 10:45:14 UTC

After that, it seems like only foonathan-memory-staticdev where missing for a first minimal working version. However the main question, if that is the correct way to generate and sdk, would still stand.

Asked by Tobias Neumann on 2021-08-06 10:53:11 UTC

Building single ROS dependent cmake projekts seems to works now, with the above described steps (only tested with a very small Hello-World like example). Next step will be to include colcon in the toolchain and support an overlay-workspace (during compilation with the toolchain and in the resulting img)

Asked by Tobias Neumann on 2021-08-12 09:41:46 UTC

can you please share your findings about what exactly steps need to be done to build sdk (by the way you using standard or extensible variant?) and how to create recipe whit all dependencies for builinding ros2-nodes?

Asked by Endag on 2021-11-03 00:40:04 UTC

Hi, sry for my late reply. I missed your request. I've added a description of the steps I took till now.

Asked by Tobias Neumann on 2021-11-16 11:15:27 UTC

Answers

I've never build a ROS 2 only ROOTFS/toolchain, it was always included in the company internal project. And it is also not really finished or reviewed, so there might be clutter or better solutions to get stuff done. With this it is possible to link against packages within the toolchain, to create an full overlay workspace with several packages depending on each other isn't yet finished (but this might work for you as well, it is just currently incompatible with out company internal crosscompile workflow) Feel free to improve this.

The following description is taken from my git history, so this might not be the optimal step for everything, but here it goes.

  • Created a new packagegroup for the ROS related stuff.
  • Add the following to the RDEPENDS_${PN} of this packagegroup: ros-base, ros-workspace-implicitworkspace, foonathan-memory-staticdev.
  • Added this packagegroup to the SDK_RDEPENDS (this might be called differently, we use an alias in our yocto project)
  • Added nativesdk-ament-package, nativesdk-ament-cmake, nativesdk-rosidl-default-generators, nativesdk-rosidl-typesupport-fastrtps-c, nativesdk-rosidl-typesupport-fastrtps-cpp and nativesdk-colcon-ros to the RDEPENDS_${PN} of the nativesdk- of this packagegroup
  • Added the following files

ament-cmake_%.bbappend

RDEPENDS_${PN}_append = " \
    ament-cmake-core \
    ament-cmake-export-definitions \
    ament-cmake-export-dependencies \
    ament-cmake-export-include-directories \
    ament-cmake-export-interfaces \
    ament-cmake-export-libraries \
    ament-cmake-export-link-flags \
    ament-cmake-export-targets \
    ament-cmake-libraries \
    ament-cmake-python \
    ament-cmake-target-dependencies \
    ament-cmake-test \
    ament-cmake-version \
    ament-cmake-include-directories \
"

spdlog_%.bbappend

BUILDSDK_CXXFLAGS_append = " -fuse-ld=gold"

BBCLASSEXTEND = " nativesdk "

spdlog-vendor_%.bbappend (I'm not sure if everything is required from that, spdlog was driving me crazy)

ROS_BUILD_DEPENDS_remove = "spdlog"
ROS_EXPORT_DEPENDS_remove = "spdlog"
DEPENDS_append_class-target = " spdlog "
DEPENDS_append_class-nativesdk = " spdlog "
#DEPENDS_append = "spdlog"
# spdlog is header only library and PN is empty, so it wasn't created
RDEPENDS_${PN}_remove = "spdlog"
RDEPENDS_${PN}_remove = "nativesdk-spdlog"

rcl-logging-spdlog_%.bbappend

# spdlog is header only library and PN is empty, so it wasn't created
ROS_BUILD_DEPENDS_remove = "spdlog"
DEPENDS_append_class-target = " spdlog "
RDEPENDS_${PN}_remove = "spdlog"
RDEPENDS_${PN}_remove = "nativesdk-spdlog"

foonathan-memory_%.bbappend

BUILDSDK_CXXFLAGS_append = " -fPIC "

python3-pytest-cov_%.bbappend

RDEPENDS_${PN}_append = " \
    ${PYTHON_PN}-pytest \
    ${PYTHON_PN}-coverage \
"

python3-coverage_5.2.1.bb

SUMMARY = "Code coverage measurement for Python"
HOMEPAGE = "https://coverage.readthedocs.io"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=2ee41112a44fe7014dce33e26468ba93"

SRC_URI[md5sum] = "9e6165146b9bda60a779953c79e8ca54"
SRC_URI[sha256sum] = "a34cb28e0747ea15e82d13e14de606747e9e484fb28d63c999483f5d5188e89b"

inherit pypi setuptools3

python3-pytest-rerunfailures_10.2.bb

inherit setuptools3

SUMMARY = "pytest-rerunfailures is a plugin for pytest that re-runs tests to eliminate intermittent failures."
HOMEPAGE = "https://github.com/pytest-dev/pytest-rerunfailures"
LICENSE = "MPL-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=06238b648baf0545473491607f3093c5"

RDEPENDS_${PN}_append = " \
    ${PYTHON_PN}-pytest \
    ${PYTHON_PN}-setuptools \
"

SRC_URI = "git://github.com/pytest-dev/pytest-rerunfailures.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"

BBCLASSEXTEND = "nativesdk"

python3-pytest-repeat_0.9.1.bb

inherit setuptools3

SUMMARY = "pytest-repeat is a plugin for pytest that makes it easy to repeat a single test, or multiple tests, a specific number of times."
HOMEPAGE = "https://github.com/pytest-dev/pytest-repeat"
LICENSE = "MPL-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=2a0bb0f2949a8babbc1df9a81a569b25"

DEPENDS_append = " \
    ${PYTHON_PN}-setuptools-scm-native \
"

RDEPENDS_${PN}_append = " \
    ${PYTHON_PN}-pytest \
    ${PYTHON_PN}-setuptools-scm \
"

SRC_URI = " git://github.com/pytest-dev/pytest-repeat.git;tag=v${PV};protocol=https; "
S="${WORKDIR}/git"

BBCLASSEXTEND = "nativesdk"

python3-distlib_0.3.2.bb

inherit setuptools3

SUMMARY = "Distlib is a library which implements low-level functions that relate to packaging and distribution of Python software. It is intended to be used as the basis for third-party packaging tools. The documentation is available at."
HOMEPAGE = "https://github.com/vsajip/distlib"
LICENSE = "Python-2.0"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=f6a11430d5cd6e2cd3832ee94f22ddfc"

SRC_URI = "git://github.com/vsajip/distlib.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"

BBCLASSEXTEND = "nativesdk"

files/python3-pytest-repeat-setuptools-scm-import.patch

--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,4 @@ setup(name='pytest-repeat',
 from setuptools import setup
+import setuptools_scm

 setup(name='pytest-repeat',
       use_scm_version=True,

files/python3-pytest-repeat-setup-requires.patch

diff --git a/setup.py b/setup.py
index 4b3db37..ec8d06d 100644
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,6 @@ setup(name='pytest-repeat',
       url='https://github.com/pytest-dev/pytest-repeat',
       py_modules=['pytest_repeat'],
       entry_points={'pytest11': ['repeat = pytest_repeat']},
-      setup_requires=['setuptools_scm'],
       install_requires=['pytest>=3.6'],
       license='Mozilla Public License 2.0 (MPL 2.0)',
       keywords='pytest pytest repeat',

colcon-test-result_0.3.8.bb

inherit setuptools3

SUMMARY = "An extension for colcon-core to provide information about the test results."
HOMEPAGE = "https://github.com/colcon/colcon-test-result"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    colcon-core \
"

SRC_URI = "git://github.com/colcon/colcon-test-result.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-test-result/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "b10643fd8de667e320843558aafbf7dd4f756b6addbbe7e03e08f5de6e375d06"

BBCLASSEXTEND = "nativesdk"

colcon-ros_0.3.21.bb

inherit setuptools3

SUMMARY = "An extension for `colcon-core <https://github.com/colcon/colcon-core>`_ to support `ROS packages <http://www.ros.org>`_."
HOMEPAGE = "https://github.com/colcon/colcon-ros"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    ${PYTHON_PN}-catkin-pkg \
    colcon-cmake \
    colcon-core \
    colcon-pkg-config \
    colcon-python-setup-py \
    colcon-recursive-crawl \
"

SRC_URI = "git://github.com/colcon/colcon-ros.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-ros/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "b0f13861e5adc9b89db686caf3d8b66cb3c40f803917925be2846d7fafe43499"

BBCLASSEXTEND = "nativesdk"

colcon-recursive-crawl_0.2.1.bb

inherit setuptools3

SUMMARY = "An extension for colcon-core to recursively crawl for packages."
HOMEPAGE = "https://github.com/colcon/colcon-recursive-crawl"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    colcon-core \
"

SRC_URI = "git://github.com/colcon/colcon-recursive-crawl.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-recursive-crawl/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "cdce1cd4e1c6f64b6f48425189a94a7c405e62ce3adf447a114c98881fff6730"

BBCLASSEXTEND = "nativesdk"

colcon-python-setup-py_0.2.7.bb

inherit setuptools3

SUMMARY = "An extension for colcon-core to identify packages with a setup.py file by introspecting the arguments to the setup() function call of setuptools."
HOMEPAGE = "https://github.com/colcon/colcon-python-setup-py"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    colcon-core \
    ${PYTHON_PN}-setuptools \
"

SRC_URI = "git://github.com/colcon/colcon-python-setup-py.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-python-setup-py/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "892d5d5870521689e578f5da6fb17bb914a89b9a5c61ba3b3fa774c911522bc5"

BBCLASSEXTEND = "nativesdk"

colcon-pkg-config_0.1.0.bb

inherit setuptools3

SUMMARY = "An extension for colcon-core to set an environment variable to find pkg-config files."
HOMEPAGE = "https://github.com/colcon/colcon-pkg-config"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    colcon-core \
"

SRC_URI = "git://github.com/colcon/colcon-pkg-config.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-pkg-config/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "c1d864aef5aa6209cb574eaac8fc7b6374f59a50f5c08d23d00684463926f33b"

BBCLASSEXTEND = "nativesdk"

colcon-library-path_0.2.1.bb

inherit setuptools3

SUMMARY = "An extension for colcon-core to set an environment variable to find shared libraries at runtime."
HOMEPAGE = "https://github.com/colcon/colcon-library-path"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    colcon-core \
"

SRC_URI = "git://github.com/colcon/colcon-library-path.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-library-path/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "6948297878f17dd1f8fd94feb1451202977b68275ea9bcfe55a00125a2f70edf"

BBCLASSEXTEND = "nativesdk"

colcon-core_0.6.1.bb

inherit setuptools3

SUMMARY = "``colcon`` is a command line tool to improve the workflow of building, testing and using multiple software packages. It automates the process, handles the ordering and sets up the environment to use the packages."
HOMEPAGE = "https://github.com/colcon/colcon-core"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    ${PYTHON_PN}-coloredlogs \
    ${PYTHON_PN}-distlib \
    ${PYTHON_PN}-empy \
    ${PYTHON_PN}-pytest \
    ${PYTHON_PN}-pytest-cov \
    ${PYTHON_PN}-pytest-repeat \
    ${PYTHON_PN}-pytest-rerunfailures \
    ${PYTHON_PN}-setuptools \
"

SRC_URI = "git://github.com/colcon/colcon-core.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"

BBCLASSEXTEND = "nativesdk"

colcon-cmake_0.2.26.bb

inherit setuptools3

SUMMARY = "An extension for colcon-core to support CMake projects."
HOMEPAGE = "https://github.com/colcon/colcon-cmake"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

RDEPENDS_${PN}_append = " \
    colcon-core \
    colcon-library-path \
    colcon-test-result \    
"

SRC_URI = "git://github.com/colcon/colcon-cmake.git;tag=${PV};protocol=https"
S="${WORKDIR}/git"
#SRC_URI = "https://github.com/colcon/colcon-cmake/archive/refs/tags/${PV}.tar.gz"
#SRC_URI[sha256sum] = "5e392f1fe1dc6870d7f67859c233946b2383b75c4bc989ef751b8befe0152b95"

BBCLASSEXTEND = "nativesdk"

fastrtps_%.bbappend

# when build for the SDK fastrtps failed with relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
#CXXFLAGS += "-fPIC"
#BUILD_CXXFLAGS += "-fPIC"
  • And then there is a problem with the way superflore exports the package.xml to openembedded recepies. Because of this, there are a lot (all?) of recepies which require the extention BBCLASSEXTEND = "native nativesdk". In my workspace I have a lot of changed files, but I also experimented with automating this with an python function. Unforenetly I can't remember which worked, so you could try the automated version. But if this dosn't work, expect to create hunders of %.bbappend files with the above mentioned extention.

For the automated version I've did the following

Create the file classes/ros_nativesdk_pkg_fix.bbclass

GSETTINGS_PACKAGE ?= "${PN}"
ROS_NATIVESDK_PACKAGES = ""
python __anonymous() {
    pkg = d.getVar("GSETTINGS_PACKAGE")
    exports = d.getVar("ROS_EXPORT_DEPENDS") + " " + d.getVar("ROS_BUILDTOOL_EXPORT_DEPENDS")
    nativeLen = len("-native")
    for export in exports.split():
        totalLen = len(export)
        if totalLen <= nativeLen:
            continue
        if export[totalLen-nativeLen:] != "-native":
            continue
        packageName = export[:totalLen-nativeLen]
        if packageName in ["gtest", "chrpath-replacement", "spdlog", "spdlog-vendor"]:
            continue
        d.appendVar("ROS_NATIVESDK_PACKAGES", " "+packageName+" ")
}

RDEPENDS_${PN} += " ${ROS_NATIVESDK_PACKAGES} "
BBCLASSEXTEND = " nativesdk "

Added this file to meta-ros2/classes/ros_ament_python.bbclass and meta-ros2/classes/ros_ament_cmake.bbclass by inserting inherit ros_nativesdk_pkg_fix into these files. Unforenetly bbclass files can not be appended and hence the original files need to be changed.

I hope that I didn't forget anything and this will be usefull for you. Have fun and good luck ;)

best regards Tobias

Asked by Tobias Neumann on 2021-11-16 11:12:55 UTC

Comments