2

I have made a ROS workspace and inside a package. I did catkin_make and everything is working well.

I would like to give this package (or should I give the entire workspace?) to another person.

I am thinking to give him a zip file of the files and folders (it contains launch files, python scripts, rviz files etc) so I am expecting he will unzip it in his machine

I would like he can run the launch files without problems

What is what he needs to do for this? (of course he will have ROS installed, that is no problem)

I am thinking perhaps he should do source devel/setup.bash but is this enough?

KansaiRobot
  • 7,564
  • 11
  • 71
  • 150
  • A zip-file of the contents of the `src` folder should be sufficient. If you have listed the dependencies inside your `package.xml` they will have to execute [`$ rosdep install`](http://wiki.ros.org/rosdep) and build the workspace with `$ catkin_make` (or `$ catkin build`) and finally source it with `$ source devel/setup.bash`. I can give you a more detailed answer on it (including ways of sharing packages/workspaces with Git and continuous integration and unit testing) later on in the evening. – 2b-t Jul 20 '21 at 11:04
  • @2b-t Thanks. I am looking forward to your answerr – KansaiRobot Jul 20 '21 at 11:18
  • Did you manage to share your package successfully or do you still have some open questions? – 2b-t Jul 26 '21 at 19:55
  • 1
    Due to sudden tasks scheduled at work that made me take an interval, I am going to continue addressing this from friday. I will have some feedback by then I think – KansaiRobot Jul 28 '21 at 06:34

1 Answers1

4

When sharing a workspace with somebody only the source space src has to be shared. It should contain all our packages with their launch files (*.launch), Python (*.py) and C++ nodes (*.cpp, *.hpp), YAML configuration files (*.yaml), RViz configurations (*.rviz), robot descriptions (*.urdf, *.xacro) and describe how each node should be compiled in a CMakeLists.txt. Additionally you are supposed to keep track of all the Debian packages you install inside the package.xml file of each package.

If for some obscure reason there are things that I have to do that can't be accommodated in the standard installation instructions given above, I will actually write a bash script that performs these steps for me and add it either to the package itself or the workspace. This way I can automate also more complex steps such as installing OpenCV or modifying the .bashrc. Here a small example of what such a minimal script (I generally name them install_dependencies.sh) might look like:

#!/bin/bash

# Get current workspace
WS_DIR="$(dirname "$(dirname "$(readlink -fm "$0")")")"

# Check if script is run as root '$ sudo ...'
if ["$EUID" -ne 0]
  then
    echo "Error: This script has to be run as root '$ sudo ./install_dependencies.sh'
    exit 1
fi

echo "Installing dependencies..."

# Modify .bashrc
echo "- Modifying '~/.bashrc'..."
echo "source ${WS_DIR}/devel/setup.bash" >> ~/.bashrc

echo ""
echo "Dependencies installed."

If for some reason even that is not possible I make always sure to document it properly either in a Markdown *.md read-me either in a /doc folder inside your package, in the read-me.md inside the base folder of your repository or inside the root folder of your workspace.

The receiver then only has to

  • Create a new workspace
  • Copy or clone the package files to its src folder
  • Install all the Debian package dependencies listed in the package.xml files with $ rosdep install
  • (If any: Execute the bash scripts I created by hand $ sudo ./install_dependencies.sh or perform the steps given in the documentation)
  • Build the workspace with $ catkin_make or $ catkin build from catkin-tools
  • Source the current environment variables with $ source devel/setup.bash
  • Make sure that the Python nodes are executable either by $ chmod +x <filename> or right-clicking the corresponding Python nodes (located in src or scripts of your package), selecting Properties/Permissions and enabling Allow executing file as program.
  • Run the desired Python or C++ nodes ($ rosrun <package_name> <executable_name>) and launch files ($ roslaunch <package_name> <launch_file_name>)

It is up to you to share the code as a compressed file, in form of a Git repository or a more advanced way (see below) but I will introduce some best practices in the following paragraphs that will pay off in the long run with larger packages.


  1. Sharing a package or sharing a workspace?

One can either share a single package or an entire workspace. I personally think that most of the time one should share the entire workspace instead of the package alone even if you only cloned the other packages from a public Github repo. This might save the receiver a lot of headache e.g. when checking out the wrong branch.

  1. Version control with Git

Arguably the best way to arrange your packages is by using Git. I'd actually make a repository for every package you create (if a couple of packages are virtually inseparable you can also bundled them to a single Git repo or better use metapackages). Then create an additional repository for your workspace and include your own packages and packages from other sources as submodules. This allows your code to be modular and re-usable: You can share only a package or the entire workspace!

As a first step I always add a .gitignore file to each package repository which excludes *.pyc files and another one to the workspace repository that ignores the build, devel and install folders.

You can add a particular repository as submodule to your workspace Git repository by opening a console inside the src folder of your workspace repository and typing

$ git submodule add -b <branch_name> <git_url_to_package> <optional_directory_rename>

Note that you can actually track a particular branch of a repository that you include as a submodule. In case you need a submodule at some point follow this guide.

If you share the workspace repository with someone they will have to have access to each individual submodule repository and they will have to not only pull the repository but also update the submodules with

$ git clone --recurse-submodules <git_url_to_workspace_repository>

and potentially update them to the latest commit with

$ git submodule update --remote

After these two steps they should have a full version of the repository with submodules and they should be able to progress with the steps listed in the section above.

1.1 Unit-testing and continuous integration

Before sharing a repository you will have to verify that everything is working correctly. This can take a decent amount of time, in particular if the code base is large and you are modifying it frequently. In the ideal case you would have to install it on a brand new machine or inside a virtual box in order to make sure that the set-up works which would take quite some time. This is where unit testing comes into play: For every class and function you program you will write a test. This way you can simply run these tests and make sure everything is working correctly. Generally these unit tests will be performed automatically and the working branches merged continuously. Generally the test routines are written with the libraries Boost::Test (C++), GoogleTest (generally used in ROS with C++), unittest (for Python) and QtTest (for GUIs). For ROS launch files there is additionally rostest. How this can be done in ROS is described here and here.

  1. ROSjects

If you do not even want the person you are sending the code to to go through the hassle to set it up you might consider sending them a ROSject. A ROSject is an online virtual ROS environment (by the guys behind The Construct, the main source of ROS courses and of ROS tutorials on Youtube) that can be created and shared very easily from your existing Git repository as can be seen here. The simulation runs entirely in the cloud on a virtual machine. This way the potential of failure is very low but it is not a choice if your code is supposed to run on hardware and not only in simulation.

  1. Docker

If your installation procedure is complex you might as well use a container such as a Docker. More information about using Docker in combination with ROS can be found here. The Docker container might introduce though a bit of overhead and it is probably no choice for code which should have real-time priority in combination with a real-time patched operating system.

  1. Debian or snap package

Another way of sending somebody a ROS package is by packing it into a Debian or snap package. This process takes a while and is in particular favourable if you want to give your code to a large number of users that should use the code out of the box. Instructions on how this can be done for Debian packages can be found here and here, while a guide for snap can be found here.

2b-t
  • 2,414
  • 1
  • 10
  • 18
  • Thanks for the great answer. I have upvoted it. I am in the process of creating a package and next week I will share it with my colleague. I will use your recommendations and mark it as an answer then. Btw, so sharing is all packages inside th `src` directory then, not just one package? – KansaiRobot Jul 30 '21 at 02:40
  • @KansaiRobot You are welcome. No, you can share a single package as well but generally I would share the entire `src` folder. It never hurts. Later is referred to as "sharing a workspace". – 2b-t Jul 30 '21 at 06:25