TipsAndTricks/Creating Recipes for ROS modules: Difference between revisions

From Yocto Project
Jump to navigationJump to search
 
(12 intermediate revisions by the same user not shown)
Line 5: Line 5:
Standard practice for a creating a recipe is use devtool add. The github project doesn't have any releases, so let's use the git repo.
Standard practice for a creating a recipe is use devtool add. The github project doesn't have any releases, so let's use the git repo.
  $ devtool add https://github.com/dawonn/vectornav
  $ devtool add https://github.com/dawonn/vectornav
This completes OK, let's takr quick look at the recipe.
This completes OK, let's take a look at the recipe.
  $ devtool edit-recpe vectornav
  $ devtool edit-recipe vectornav
<pre>
<pre>
# Recipe created by recipetool
# Recipe created by recipetool
Line 31: Line 31:
EXTRA_OECMAKE = ""
EXTRA_OECMAKE = ""
</pre>
</pre>
It seems to have correctly detected a cmake project. Let's try and built it
Note the comment
# NOTE: unable to map the following CMake package dependencies: catkin
And sure enough, the build fails as the comment predicted.
<pre>
<pre>
$ devtool build vectornav
$ devtool build vectornav
Line 39: Line 41:
|  CMake did not find one.
|  CMake did not find one.
</pre>
</pre>
Assuming you've worked with ROS, you'll know that it builds with a cmake based tool called [http://wiki.ros.org/catkin catkin]. This is usually installed as a developer package so some Yocto work will need to be done to "build the builder". This seems like a tough task, so let's see how other ROS modules have done this.
== Understanding Existing ROS Recipes ==
=== Recipe Structure ===
Let's look at a an existing meta-ros recipe [https://github.com/bmwcarit/meta-ros/blob/master/recipes-ros/zeroconf-msgs/zeroconf-msgs_0.2.1.bb zeroconf-msgs] to see how they support catkin.
<pre>
DESCRIPTION = "General ros communications used by the various zeroconf implementations."
SECTION = "devel"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://package.xml;beginline=8;endline=8;md5=5ee5b8b046ae48ad94a2037ca953a67b"
DEPENDS = "std-msgs message-generation"
SRC_URI = "https://github.com/stonier/${ROS_SPN}/archive/${PV}.tar.gz;downloadfilename=${ROS_SP}.tar.gz"
SRC_URI[md5sum] = "38e89e637f855c2ea0e8cb65c02dfd08"
SRC_URI[sha256sum] = "a5bfd788bc2e2aefb07cb3a302a25cbeef2ce7e931a3a273cb1ae9669645a696"
S = "${WORKDIR}/${ROS_SP}"
inherit catkin
</pre>
A few things to note
* The directive <tt>inherit catkin</tt> includes bitbake logic and it's a reasonable guess that this does all the catkin stuff just as <tt>inherit cmake</tt> enables cmake.
* As package.xml if referred to by <tt>LIC_FILES_CHKSUM</tt> must include some licence info. Let's dig into this.
* How are the DEPENDS defined? Let's dig into this as well.
=== Getting meta-data from package.xml ===
Let's take a look at it
<pre>
<package>
  <name>zeroconf_msgs</name>
  <version>0.2.1</version>
  <description>
    General ros communications used by the various zeroconf implementations.   
  </description>
  <maintainer email="d.stonier@gmail.com">Daniel Stonier</maintainer>
  <license>BSD</license> 
  <url type="website">http://www.ros.org/wiki/zeroconf_msgs</url>
  <url type="repository">https://github.com/stonier/zeroconf_msgs</url>
  <url type="bugtracker">https://github.com/stonier/zeroconf_msgs/issues</url>
  <author email="d.stonier@gmail.com">Daniel Stonier</author>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>std_msgs</build_depend>
  <run_depend>message_runtime</run_depend>
  <run_depend>std_msgs</run_depend>
  <export>
    <architecture_independent/>
  </export>in the <tt>run_depend</tt> that are not also in <tt>
</package>
</pre>
There is some useful information to create a recipe. Let's create a mapping between package.xml tags and recipe variables.
{|class="wikitable"
|'''package.xml Tag'''||'''Recipe directive'''||'''Comment'''
|-
|name||PN||This is defined by recipe filename
|-
|version||PV||Usually defined by recipe filename
|-
|description||SUMMARY||This should map to SUMMARY, not DESCRIPTION which adds detail
|-
|license||LICENSE||Use package.xml for LIC_FILES_CHKSUM
|-
|url||HOMEPAGE||type="website". Seems to be an optional tag
|-
|url||SRC_URI||type="repository". Seems to be an optional tag
|-
|buildtool_depend||inherit||Will always be catkin(?), which inherits cmake
|-
|build_depend||DEPENDS||1. Append to any values created by devtool
2. If ROS module name contains an underscore, convert to a dash
|-
|runs_depend||RDEPENDS_{PN}||This should only contain entries that are not already in build_depend
|}
== Putting it all together  ==
So let's take a look at the package.xml for our module
<pre>
<package>
  <name>vectornav</name>
  <version>0.1.0</version>
  <description>ROS interface for the VectorNav INS/GPS</description>
  <maintainer email="dereck@gmail.com">Dereck Wonnacott</maintainer>
  <license>MIT</license>
  <!-- <url type="website">http://ros.org/wiki/vectornav</url> -->
  <author email="dereck@gmail.com">Dereck Wonnacott</author>
  <buildtool_depend>catkin</buildtool_depend>
 
  <build_depend>roscpp</build_depend> 
  <build_depend>geometry_msgs</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>tf</build_depend>
 
  <run_depend>roscpp</run_depend>
  <run_depend>sensor_msgs</run_depend>
  <run_depend>geometry_msgs</run_depend>
  <run_depend>tf</run_depend>
 
  <!-- Maintainer Note:
      The vnccpplib directory is from http://www.vectornav.com/support/downloads
      I removed the version string from the directory name, sanitized file
      permissions, and removed all but the src and include directories.
  -->
</package>
</pre>
And map it to recipe directives
{|
|-
|PV||0.1.0
|-
|SUMMARY||ROS interface for the VectorNav INS/GPS
|-
|LICENSE||MIT
|-
|HOMEPAGE||http://ros.org/wiki/vectornav
|-
|inherit||catkin
|-
|DEPENDS||roscpp geometry-msgs sensor-msgs tf
|-
|}
Now let's update the recipe the devtool created with these values
<pre>
SUMMARY = "ROS interface for the VectorNav INS/GPS"
HOMEPAGE = "http://ros.org/wiki/vectornav"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://package.xml;md5=5431059e1a277b5a31f4ad759bc9c76d \
                    file://vnccpplib/LICENSE.txt;md5=a3e2f266f2adb30b4ae17db437fa9727"
SRC_URI = "git://github.com/dawonn/vectornav;protocol=https"
PV = "0.1.0"
SRCREV = "497173f3ddbe21216d77d3b2021a5ef48a17ec4a"
DEPENDS = "roscpp geometry-msgs sensor-msgs tf"
S = "${WORKDIR}/git"
inherit catkin
</pre>
Now let's build it.
$ devtool build vectornav
Success !
== Recipetool Integration ==
As "devtool add" failed to create a functional recipe but the above steps follow a set process, there is scope for extending recipetool to support ROS modules.
# Detect ROS module by checking for package.xml in root of source with tag <tt>buildtool_depend</tt> set to <tt>catkin</tt>
# Create basis of recipe in similar way to cmake (execluding <tt>inherit cmake</tt>
# Follow mapping in [[TipsAndTricks/Creating_Recipes_for_ROS_modules#Getting_meta-data_from_package.xml|package.xml mapping table]]
Start with [http://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/scripts/lib/recipetool/create_buildsys.py existing recipetool code], get smart with python3 and good luck!

Latest revision as of 23:20, 15 June 2017

Introduction

Robot Operating System (ROS) isn't an OS but a set of modules for robotics applications that interact via a pub/sub interface. Thanks to meta-ros you can add a wide range of ROS modules to your OS build. But how do you add your own ROS module? This article covers creating a recipe for a ROS module. For this article we'll use the vectornav module as an example. We'll also assume you already have meta-ros in your bblayers.conf.

Starting with "devtool add"

Standard practice for a creating a recipe is use devtool add. The github project doesn't have any releases, so let's use the git repo.

$ devtool add https://github.com/dawonn/vectornav

This completes OK, let's take a look at the recipe.

$ devtool edit-recipe vectornav
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://vnccpplib/LICENSE.txt;md5=a3e2f266f2adb30b4ae17db437fa9727"

SRC_URI = "git://github.com/dawonn/vectornav;protocol=https"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "497173f3ddbe21216d77d3b2021a5ef48a17ec4a"

S = "${WORKDIR}/git"

# NOTE: unable to map the following CMake package dependencies: catkin
inherit cmake

# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""

Note the comment

# NOTE: unable to map the following CMake package dependencies: catkin

And sure enough, the build fails as the comment predicted.

$ devtool build vectornav
| CMake Error at CMakeLists.txt:7 (find_package):
|   By not providing "Findcatkin.cmake" in CMAKE_MODULE_PATH this project has
|   asked CMake to find a package configuration file provided by "catkin", but
|   CMake did not find one.

Assuming you've worked with ROS, you'll know that it builds with a cmake based tool called catkin. This is usually installed as a developer package so some Yocto work will need to be done to "build the builder". This seems like a tough task, so let's see how other ROS modules have done this.

Understanding Existing ROS Recipes

Recipe Structure

Let's look at a an existing meta-ros recipe zeroconf-msgs to see how they support catkin.

DESCRIPTION = "General ros communications used by the various zeroconf implementations."
SECTION = "devel"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://package.xml;beginline=8;endline=8;md5=5ee5b8b046ae48ad94a2037ca953a67b"

DEPENDS = "std-msgs message-generation"

SRC_URI = "https://github.com/stonier/${ROS_SPN}/archive/${PV}.tar.gz;downloadfilename=${ROS_SP}.tar.gz"
SRC_URI[md5sum] = "38e89e637f855c2ea0e8cb65c02dfd08"
SRC_URI[sha256sum] = "a5bfd788bc2e2aefb07cb3a302a25cbeef2ce7e931a3a273cb1ae9669645a696"

S = "${WORKDIR}/${ROS_SP}"

inherit catkin

A few things to note

  • The directive inherit catkin includes bitbake logic and it's a reasonable guess that this does all the catkin stuff just as inherit cmake enables cmake.
  • As package.xml if referred to by LIC_FILES_CHKSUM must include some licence info. Let's dig into this.
  • How are the DEPENDS defined? Let's dig into this as well.

Getting meta-data from package.xml

Let's take a look at it

<package>
  <name>zeroconf_msgs</name>
  <version>0.2.1</version>
  <description>
    General ros communications used by the various zeroconf implementations.    
  </description>
  <maintainer email="d.stonier@gmail.com">Daniel Stonier</maintainer>
  <license>BSD</license>  

  <url type="website">http://www.ros.org/wiki/zeroconf_msgs</url>
  <url type="repository">https://github.com/stonier/zeroconf_msgs</url>
  <url type="bugtracker">https://github.com/stonier/zeroconf_msgs/issues</url>
  <author email="d.stonier@gmail.com">Daniel Stonier</author>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>std_msgs</build_depend>

  <run_depend>message_runtime</run_depend>
  <run_depend>std_msgs</run_depend>

  <export>
    <architecture_independent/>
  </export>in the <tt>run_depend</tt> that are not also in <tt>
</package>

There is some useful information to create a recipe. Let's create a mapping between package.xml tags and recipe variables.

package.xml Tag Recipe directive Comment
name PN This is defined by recipe filename
version PV Usually defined by recipe filename
description SUMMARY This should map to SUMMARY, not DESCRIPTION which adds detail
license LICENSE Use package.xml for LIC_FILES_CHKSUM
url HOMEPAGE type="website". Seems to be an optional tag
url SRC_URI type="repository". Seems to be an optional tag
buildtool_depend inherit Will always be catkin(?), which inherits cmake
build_depend DEPENDS 1. Append to any values created by devtool

2. If ROS module name contains an underscore, convert to a dash

runs_depend RDEPENDS_{PN} This should only contain entries that are not already in build_depend

Putting it all together

So let's take a look at the package.xml for our module

<package>
  <name>vectornav</name>
  <version>0.1.0</version>
  <description>ROS interface for the VectorNav INS/GPS</description>

  <maintainer email="dereck@gmail.com">Dereck Wonnacott</maintainer>

  <license>MIT</license>

  <!-- <url type="website">http://ros.org/wiki/vectornav</url> -->

  <author email="dereck@gmail.com">Dereck Wonnacott</author>

  <buildtool_depend>catkin</buildtool_depend>
  
  <build_depend>roscpp</build_depend>  
  <build_depend>geometry_msgs</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>tf</build_depend>
  
  <run_depend>roscpp</run_depend>
  <run_depend>sensor_msgs</run_depend>
  <run_depend>geometry_msgs</run_depend>
  <run_depend>tf</run_depend>
  
  <!-- Maintainer Note:
      The vnccpplib directory is from http://www.vectornav.com/support/downloads
      I removed the version string from the directory name, sanitized file 
      permissions, and removed all but the src and include directories.
   -->
</package>

And map it to recipe directives

PV 0.1.0
SUMMARY ROS interface for the VectorNav INS/GPS
LICENSE MIT
HOMEPAGE http://ros.org/wiki/vectornav
inherit catkin
DEPENDS roscpp geometry-msgs sensor-msgs tf

Now let's update the recipe the devtool created with these values

SUMMARY = "ROS interface for the VectorNav INS/GPS"
HOMEPAGE = "http://ros.org/wiki/vectornav"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://package.xml;md5=5431059e1a277b5a31f4ad759bc9c76d \
                    file://vnccpplib/LICENSE.txt;md5=a3e2f266f2adb30b4ae17db437fa9727"

SRC_URI = "git://github.com/dawonn/vectornav;protocol=https"
PV = "0.1.0"
SRCREV = "497173f3ddbe21216d77d3b2021a5ef48a17ec4a"

DEPENDS = "roscpp geometry-msgs sensor-msgs tf"

S = "${WORKDIR}/git"

inherit catkin

Now let's build it.

$ devtool build vectornav

Success !

Recipetool Integration

As "devtool add" failed to create a functional recipe but the above steps follow a set process, there is scope for extending recipetool to support ROS modules.

  1. Detect ROS module by checking for package.xml in root of source with tag buildtool_depend set to catkin
  2. Create basis of recipe in similar way to cmake (execluding inherit cmake
  3. Follow mapping in package.xml mapping table

Start with existing recipetool code, get smart with python3 and good luck!