TipsAndTricks/Creating Recipes for ROS modules: Difference between revisions
Henry Bruce (talk | contribs) (Created page with "== Introduction == [http://www.ros.org/ Robot Operating System] (ROS) isn't an OS but a set of modules for robotics applications that interact via a pub/sub interface. Thanks ...") |
Henry Bruce (talk | contribs) |
||
(15 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Introduction == | == Introduction == | ||
[http://www.ros.org/ 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 [https://github.com/dawonn/vectornav vectornav] module as an example. | [http://www.ros.org/ 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 [https://github.com/bmwcarit/meta-ros 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 [https://github.com/dawonn/vectornav 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. | 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/ | $ devtool add https://github.com/dawonn/vectornav | ||
This completes OK, let's | This completes OK, let's take a look at the recipe. | ||
$ devtool edit- | $ devtool edit-recipe vectornav | ||
<pre> | <pre> | ||
# Recipe created by recipetool | # Recipe created by recipetool | ||
Line 31: | Line 31: | ||
EXTRA_OECMAKE = "" | EXTRA_OECMAKE = "" | ||
</pre> | </pre> | ||
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.
- Detect ROS module by checking for package.xml in root of source with tag buildtool_depend set to catkin
- Create basis of recipe in similar way to cmake (execluding inherit cmake
- Follow mapping in package.xml mapping table
Start with existing recipetool code, get smart with python3 and good luck!