[Dashing][Client Libraries] 2. Creating your first ROS 2 package
이 글은 아래의 자료를 참고로 만들어졌습니다.
https://docs.ros.org/en/dashing/Tutorials/Creating-Your-First-ROS2-Package.html
Creating your first ROS 2 package
Goal: Create a new package using either CMake or Python, and run its executable.
Tutorial level: Beginner
Background
1 What is a ROS 2 package?
A package can be considered a container for your ROS 2 code.
If you want to be able to install your code or share it with others, then you’ll need it organized in a package.
With packages, you can release your ROS 2 work and allow others to build and use it easily.
Package creation in ROS 2 uses ament as its build system and colcon as its build tool.
You can create a package using either CMake or Python, which are officially supported, though other build types do exist.
2 What makes up a ROS 2 package?
ROS 2 Python and CMake packages each have their own minimum required contents:
CMake
|
Python
|
The simplest possible package may have a file structure that looks like:
CMake
my_package/
CMakeLists.txt
package.xml
Python
my_package/
setup.py
package.xml
resource/my_package
3 Packages in a workspace
A single workspace can contain as many packages as you want, each in their own folder.
You can also have packages of different build types in one workspace (CMake, Python, etc.).
You cannot have nested packages.
Best practice is to have a src
folder within your workspace, and to create your packages in there.
This keeps the top level of the workspace “clean”.
A trivial workspace might look like:
workspace_folder/
src/
package_1/
CMakeLists.txt
package.xml
package_2/
setup.py
package.xml
resource/package_2
...
package_n/
CMakeLists.txt
package.xml
Prerequisites
You should have a ROS 2 workspace after following the instructions in the previous tutorial.
You will create your package in this workspace.
Tasks
1 Create a package
First, source your ROS 2 installation.
Let’s use the workspace you created in the previous tutorial, dev_ws
, for your new package.
Make sure you are in the src
folder before running the package creation command.
$ cd ~/dev_ws/src
The command syntax for creating a new package in ROS 2 is:
CMake
$ ros2 pkg create --build-type ament_cmake <package_name>
Python
$ ros2 pkg create --build-type ament_python <package_name>
For this tutorial, you will use the optional argument --node-name
which creates a simple Hello World type executable in the package.
Enter the following command in your terminal:
CMake
$ ros2 pkg create --build-type ament_cmake --node-name my_node my_package_cm
going to create a new package
package name: my_package_cm
destination directory: /home/ros/dev_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['ros <jstar0525@gmail.com>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: []
node_name: my_node
creating folder ./my_package_cm
creating ./my_package_cm/package.xml
creating source and include folder
creating folder ./my_package_cm/src
creating folder ./my_package_cm/include/my_package_cm
creating ./my_package_cm/CMakeLists.txt
creating ./my_package_cm/src/my_node.cpp
Python
$ ros2 pkg create --build-type ament_python --node-name my_node my_package_py
going to create a new package
package name: my_package_py
destination directory: /home/ros/dev_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['ros <jstar0525@gmail.com>']
licenses: ['TODO: License declaration']
build type: ament_python
dependencies: []
node_name: my_node
creating folder ./my_package_py
creating ./my_package_py/package.xml
creating source folder
creating folder ./my_package_py/my_package_py
creating ./my_package_py/setup.py
creating ./my_package_py/setup.cfg
creating folder ./my_package_py/resource
creating ./my_package_py/resource/my_package_py
creating ./my_package_py/my_package_py/__init__.py
creating folder ./my_package_py/test
creating ./my_package_py/test/test_copyright.py
creating ./my_package_py/test/test_flake8.py
creating ./my_package_py/test/test_pep257.py
creating ./my_package_py/my_package_py/my_node.py
You will now have a new folder within your workspace’s src
directory called my_package
.
After running the command, your terminal will return the message:
You can see the automatically generated files for the new package.
2 Build a package
Putting packages in a workspace is especially valuable because you can build many packages at once by running colcon build
in the workspace root.
Otherwise, you would have to build each package individually.
Return to the root of your workspace:
$ cd ~/dev_ws
Now you can build your packages:
$ colcon build
Starting >>> my_package_cpp
Starting >>> my_package_py
Starting >>> turtlesim
Finished <<< my_package_py [0.56s]
Finished <<< turtlesim [1.07s]
Finished <<< my_package_cpp [1.35s]
Summary: 3 packages finished [1.45s]
Recall from the last tutorial that you also have the ros_tutorials
packages in your dev_ws
.
You might’ve noticed that running colcon build
also built the turtlesim
package.
That’s fine when you only have a few packages in your workspace, but when there are many packages, colcon build
can take a long time.
To build only the my_package
package next time, you can run:
$ colcon build --packages-select my_package_cm my_package_py
Starting >>> my_package_cm
Starting >>> my_package_py
Finished <<< my_package_cm [0.34s]
Finished <<< my_package_py [0.44s]
Summary: 2 packages finished [0.55s]
3 Source the setup file
To use your new package and executable, first open a new terminal and source your main ROS 2 installation.
Then, from inside the dev_ws
directory, run the following command to source your workspace:
$ . install/setup.bash
Now that your workspace has been added to your path, you will be able to use your new package’s executables.
4 Use the package
To run the executable you created using the --node-name
argument during package creation, enter the command:
Which will return a message to your terminal:
CMake
$ ros2 run my_package_cm my_node
hello world my_package_cm package
Python
$ ros2 run my_package_py my_node
Hi from my_package_py.
5 Examine package contents
Inside dev_ws/src/my_package
, you will see the files and folders that ros2 pkg create
automatically generated:
CMake
$ ls ~/dev_ws/src/my_package_cm
CMakeLists.txt include package.xml src
my_node.cpp is inside the src directory. This is where all your custom C++ nodes will go in the future.
Python
$ ls ~/dev_ws/src/my_package_py
my_package package.xml resource setup.cfg setup.py test
my_node.py is inside the my_package directory. This is where all your custom Python nodes will go in the future.
6 Customize package.xml
You may have noticed in the return message after creating your package that the fields description
and license
contain TODO
notes.
That’s because the package description and license declaration are not automatically set, but are required if you ever want to release your package.
The maintainer
field may also need to be filled in.
From dev_ws/src/my_package
, open package.xml
using your preferred text editor:
CMake
1<?xml version="1.0"?>
2<?xml-model
3 href="http://download.ros.org/schema/package_format3.xsd"
4 schematypens="http://www.w3.org/2001/XMLSchema"?>
5<package format="3">
6 <name>my_package</name>
7 <version>0.0.0</version>
8 <description>TODO: Package description</description>
9 <maintainer email="user@todo.todo">user</maintainer>
10 <license>TODO: License declaration</license>
11
12 <buildtool_depend>ament_cmake</buildtool_depend>
13
14 <test_depend>ament_lint_auto</test_depend>
15 <test_depend>ament_lint_common</test_depend>
16
17 <export>
18 <build_type>ament_cmake</build_type>
19 </export>
20</package>
Python
1<?xml version="1.0"?>
2<?xml-model
3 href="http://download.ros.org/schema/package_format3.xsd"
4 schematypens="http://www.w3.org/2001/XMLSchema"?>
5<package format="3">
6 <name>my_package</name>
7 <version>0.0.0</version>
8 <description>TODO: Package description</description>
9 <maintainer email="user@todo.todo">user</maintainer>
10 <license>TODO: License declaration</license>
11
12 <test_depend>ament_copyright</test_depend>
13 <test_depend>ament_flake8</test_depend>
14 <test_depend>ament_pep257</test_depend>
15 <test_depend>python3-pytest</test_depend>
16
17 <export>
18 <build_type>ament_python</build_type>
19 </export>
20</package>
Input your name and email on line 9 if it hasn't been automatically populated for you.
Then, edit the description on line 8 to summarize the package:
<description>Beginner client libraries tutorials practice package</description>
Then, update the license on line 10.
You can read more about open source licenses here.
Since this package is only for practice, it’s safe to use any license. We use Apache License 2.0
:
<license>Apache License 2.0</license>
Don’t forget to save once you’re done editing.
Below the license tag, you will see some tag names ending with _depend
.
This is where your package.xml
would list its dependencies on other packages, for colcon to search for.my_package
is simple and doesn’t have any dependencies, but you will see this space being utilized in upcoming tutorials.
CMake
You’re all done for now!
Python
The setup.py file contains the same description, maintainer and license fields as package.xml, so you need to set those as well. They need to match exactly in both files. The version and name (package_name) also need to match exactly, and should be automatically populated in both files.
Open setup.py with your preferred text editor.
1from setuptools import setup
2
3package_name = 'my_py_pkg'
4
5setup(
6 name=package_name,
7 version='0.0.0',
8 packages=[package_name],
9 data_files=[
10 ('share/ament_index/resource_index/packages',
11 ['resource/' + package_name]),
12 ('share/' + package_name, ['package.xml']),
13 ],
14 install_requires=['setuptools'],
15 zip_safe=True,
16 maintainer='TODO',
17 maintainer_email='TODO',
18 description='TODO: Package description',
19 license='TODO: License declaration',
20 tests_require=['pytest'],
21 entry_points={
22 'console_scripts': [
23 'my_node = my_py_pkg.my_node:main'
24 ],
25 },
26)
Edit lines 16-19 to match package.xml.
Don’t forget to save the file.
Summary
You’ve created a package to organize your code and make it easy to use for others.
Your package was automatically populated with the necessary files, and then you used colcon to build it so you can use its executables in your local environment.
Next steps
Next, let's add something meaningful to a package.
You'll start with a simple publisher/subscriber system, which you can choose to write in either C++ or Python.