Structure of a ROS Package
In ROS (Robot Operating System), a package is the most basic unit of software organization. It contains everything you need to run a specific part of a robot system, including nodes, libraries, scripts, configuration files, and launch files. Understanding the package filesystem is crucial because it determines how your code and resources are organized for easy integration within the ROS ecosystem.
Structure of a ROS Package
A typical ROS package will contain the following files and directories:
my_ros_package/
├── CMakeLists.txt
├── package.xml
├── launch/
├── src/
├── include/
├── msg/
├── srv/
├── scripts/
└── config/Explanation of Each Component
1. CMakeLists.txt
- This is the build configuration file for CMake, which ROS uses as its build system.
- It defines how to compile and link your code, which dependencies to include, and how to generate messages, services, and actions if present.
Example:
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs)
catkin_package()
include_directories(${catkin_INCLUDE_DIRS})2. package.xml
- Describes the metadata about the package (name, version, dependencies, author, etc.).
- This file is important for package management and dependency resolution.
Example:
<package format="2">
<name>my_ros_package</name>
<version>0.1.0</version>
<description>A simple ROS package</description>
<maintainer email="[email protected]">Your Name</maintainer>
<license>MIT</license>
<build_depend>roscpp</build_depend>
<exec_depend>rospy</exec_depend>
</package>3. launch/
- Contains launch files used to start multiple nodes at once, usually with configurations.
- Launch files are written in XML or YAML and help in managing large robot systems.
Example: launch/my_robot.launch
<launch>
<node pkg="my_ros_package" type="my_node" name="my_node_instance" output="screen"/>
</launch>4. src/
- Contains the source code files, typically written in C++ or Python, for the nodes.
Example: src/my_node.cpp
#include <ros/ros.h>
int main(int argc, char **argv) {
ros::init(argc, argv, "my_node");
ros::NodeHandle nh;
ROS_INFO("Node is running");
ros::spin();
return 0;
}5. include/
- Stores header files if you're writing code in C++.
- Helps with organizing your code, especially for larger projects.
Example: include/my_ros_package/my_node.hpp
6. msg/
- Contains message definitions used by ROS nodes to communicate via topics.
Example: msg/MyMessage.msg
int32 data- Once defined, you can use the message in your code with:
#include <my_ros_package/MyMessage.h>
7. srv/
- Contains service definitions for two-way communication between nodes (request-response).
Example: srv/AddTwoInts.srv
int32 a
int32 b
---
int32 sum8. scripts/
- Contains executable scripts, typically written in Python, to implement nodes or tools.
Example: scripts/my_script.py
#!/usr/bin/env python
import rospy
rospy.init_node('my_python_node')
rospy.loginfo("Python node is running")
rospy.spin()9. config/
- Stores configuration files (e.g., YAML files) used to pass parameters to nodes.
Example: config/params.yaml
param1: 10
param2: "Hello ROS"ROS Package Example Walkthrough
-
Creating a Package: You can create a ROS package using the following command:
catkin_create_pkg my_ros_package roscpp rospy std_msgs -
Building the Package: After writing your code, build your package using:
cd ~/catkin_ws catkin_make -
Running a Node: You can launch a node from your package using:
rosrun my_ros_package my_node -
Using a Launch File: To start your nodes with a launch file:
roslaunch my_ros_package my_robot.launch
Summary
- CMakeLists.txt: Build instructions for the package.
- package.xml: Metadata and dependencies.
- launch/: Launch multiple nodes together.
- src/: Node source code (C++ or Python).
- msg/: Define custom message types.
- srv/: Define service types for two-way communication.
- scripts/: Python scripts or tools.
- config/: Configuration files with parameters.
A ROS package neatly organizes your code, making it easy to develop and share different parts of your robotic system.
1. Setup ROS Workspace
mmabas77@mmabas77-ROS:~/ros$ mkdir ros_ws
mmabas77@mmabas77-ROS:~/ros$ cd ros_ws/
mmabas77@mmabas77-ROS:~/ros/ros_ws$ mkdir src2. Build the Workspace
mmabas77@mmabas77-ROS:~/ros/ros_ws$ catkin_make
mmabas77@mmabas77-ROS:~/ros/ros_ws$ ls3. Move into the Source Directory
mmabas77@mmabas77-ROS:~/ros/ros_ws$ cd src/
mmabas77@mmabas77-ROS:~/ros/ros_ws/src$ ls4. Create a ROS Package
mmabas77@mmabas77-ROS:~/ros/ros_ws/src$ catkin_create_pkg helloworld_pkg roscpp rospy std_msgs
mmabas77@mmabas77-ROS:~/ros/ros_ws/src$ cd helloworld_pkg/
mmabas77@mmabas77-ROS:~/ros/ros_ws/src/helloworld_pkg$ ls
5. Create a Scripts Directory (Python - Optional)
mmabas77@mmabas77-ROS:~/ros/ros_ws/src/helloworld_pkg$ mkdir scripts6. Create a publisher node
7. Create a subscriber node
8. Build the Package
mmabas77@mmabas77-ROS:~/ros/ros_ws$ catkin_makeSource the Workspace (Very important)
mmabas77@mmabas77-ROS:~/ros/ros_ws$ source devel/setup.bash9. Run the Publisher Node
mmabas77@mmabas77-ROS:~/ros/ros_ws$ rosrun helloworld_pkg publisher_node10. Run the Subscriber Node
mmabas77@mmabas77-ROS:~/ros/ros_ws$ rosrun helloworld_pkg subscriber_node