element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Robotics
  • Technologies
  • More
Robotics
Blog ROS2 Learning Series - Blog 4 - Basic Programming - Part 1
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Robotics to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: crisdeodates
  • Date Created: 9 Apr 2024 1:24 PM Date Created
  • Views 430 views
  • Likes 3 likes
  • Comments 1 comment
  • Robot operating System
  • robotics
  • ROS2
  • ROS
Related
Recommended

ROS2 Learning Series - Blog 4 - Basic Programming - Part 1

crisdeodates
crisdeodates
9 Apr 2024
ROS2 Learning Series - Blog 4 - Basic Programming - Part 1

ROS2 - Publisher Subscriber Project

Let's put everything we have gone through so far into creating some interesting projects. A basic knowledge of linux terminal and python programming language is required for completing the projects. In all the code snippets provided, I have given comments wherever necessary. Consider this as a general guide and feel free to modify the code as per your requirements.  

 

We are going to write a simple publisher - subscriber program for finding the sum of n positive numbers. The program takes a positive integer as input and publishes it via a topic in a publisher node. Another subscriber node subscribes to the topic having the input data, calculates the sum of integers until the input number and displays it in the terminal. 

 

Create and set up a ROS2 workspace folder named ros2_ws and a src folder inside it. 

$ mkdir -p ~/ros2_ws/src 
$ cd ~/ros2_ws 

 

From the root of your workspace (ros2_ws), we can now build your packages using the command 

$ colcon build 

 

We can see that colcon has created some new directories.

Let’s keep in mind that the ‘install’ directory is where our workspace’s setup files will be present. 

 

To enable ROS2 commands, source the ROS2 setup file. 

$ source /opt/ros/humble/setup.bash 

 

Create a package called ‘sum_nums’ for our project and use the ament python build system. If the project has multiple packages in the future, putting all the relevant project packages in a workspace is very important because you can build multiple packages at once using the colcon build in the workspace root. Else, all the packages needs to be built individually. 

$ cd src 
$ ros2 pkg create --build-type ament_python --license Apache-2.0 sum_nums
 

 

This will automatically generate the necessary files.  

If we see the directory structure of our src folder, it will look something like this. 

sum_nums/ 
├── LICENSE 
├── package.xml 
├── resource 
│   └── sum_nums 
├── setup.cfg 
├── setup.py 
├── sum_nums 
│   └── __init__.py 
└── test 
    ├── test_copyright.py 
    ├── test_flake8.py 
    └── test_pep257.py 

 

The relevant files are the following: 

  • package.xml -> containing meta information about the package. 
  • resource/sum_nums -> marker file for the package. 
  • setup.cfg -> required when a package has executables, so ros2 run can find them. 
  • setup.py -> contains instructions for how to install the package. 
  • sum_nums - directory with the same name as the package, used by ROS 2 tools to find the package, and contains __init__.py file. 

 

We will create two python ROS2 node files named ‘sum_nums_publisher.py’ and ‘sum_nums_subscriber.py’. The sum_nums_publisher.py node will accept a number from the user and publish it to a topic named ‘input_number’. The sum_nums_subscriber.py node subscribes to the topic ‘input_number’, calculates the sum of n numbers up to the input number and displays the final sum. 

 

Create a python ROS2 publisher node file named ‘sum_nums_publisher.py’ inside ‘sum_nums/sum_nums’ folder, adjacent to where the file __init.py__ is present. 

$ cd sum_nums/sum_nums 
$ touch sum_nums_publisher.py sum_nums_subscriber.py
 

Open ‘sum_nums_publisher.py’ and populate it with the publisher code:

import rclpy 
from rclpy.node import Node 
from std_msgs.msg import Int8 
 
class SumNumsPub(Node): 
    """ 
    Node to publish positive integer numbers. 
    """ 
    def __init__(self): 
        """ 
        Initializes the SumNumsPub class. 
        """ 
        super().__init__('sum_nums_publisher_node') 
        # Create a publisher for data type Int8 
        self.publisher_ = self.create_publisher(Int8, 'input_number', 10) 
 
    def sum_nums_publish(self, data): 
        """ 
        Publishes the given data. 
 
        Parameters: 
            data: Data to be published. 
        """ 
        self.publisher_.publish(data) 
 
def main(args=None): 
    """ 
    Main function to initialize the node and publish a positive integer number. 
    """ 
    rclpy.init(args=args) 
    sum_nums_publisher_node = SumNumsPub() 
    num_data = Int8() 
 
    # Accept a keyboard input 
    num_input = int(input("Enter a positive integer number: ")) 
    if num_input < 0: 
        print("Input number is not positive") 
    else: 
        print('Entered:', num_input) 
        num_data.data = num_input 
        # Publish the integer to the topic 
        sum_nums_publisher_node.sum_nums_publish(num_data) 
 
    # Destroy the node explicitly 
    sum_nums_publisher_node.destroy_node() 
    rclpy.shutdown() 
 
if __name__ == '__main__': 
    main() 

 

Open ‘‘sum_nums_subscriber.py’ and populate it with the subscriber code: 

import rclpy 
from rclpy.node import Node 
from std_msgs.msg import Int8 
 
class SumNumsSub(Node): 
    """ 
    Node to subscribe to a topic and compute the sum of first n integer numbers. 
    """ 
    def __init__(self): 
        """ 
        Initializes the SumNumsSub class. 
        """ 
        super().__init__('sum_nums_publisher_node') 
        # Create a subscription to the 'input_number' topic 
        self.subscription = self.create_subscription( 
            Int8, 
            'input_number', 
            self.subscriber_callback, 
            10) 
        self.subscription  # prevent unused variable warning 
        self.num = 0 
        self.sum = 0 
 
    def subscriber_callback(self, msg): 
        """ 
        Callback function to compute the sum of first n integer numbers. 
 
        Parameters: 
            msg: The received message containing the number n. 
        """ 
        self.num = int(msg.data) 
        self.sum = self.recursive_sum(self.num) 
        print("Sum of first", self.num, "integer numbers is:", self.sum) 
 
    def recursive_sum(self, n): 
        """ 
        Recursive function to compute the sum of first n integer numbers. 
 
        Parameters: 
            n: The number of integer numbers to sum. 
 
        Returns: 
            The sum of the first n integer numbers. 
        """ 
        if n <= 1: 
            return n 
        else: 
            return n + self.recursive_sum(n - 1) 
 
def main(args=None): 
    """ 
    Main function to initialize the node and spin it to handle messages. 
    """ 
    rclpy.init(args=args) 
 
    sum_nums_subscriber_node = SumNumsSub() 
 
    rclpy.spin(sum_nums_subscriber_node) 
    # Destroy the node explicitly 
    sum_nums_subscriber_node.destroy_node() 
    rclpy.shutdown() 
 
if __name__ == '__main__': 
    main() 

 

We need to configure additional files in the package to enable the node executables to be setup and built correctly. We need to add our dependencies to package.xml file and the node entry points to setup.py file inside the package root folder. 

 

Modify the package.xml, populate the <description>, <maintainer> and <license> tags and after those lines, add the following dependencies that we imported in our sum_nums_publisher.py file and save the file. 

<exec_depend>rclpy</exec_depend> 
<exec_depend>std_msgs</exec_depend> 

 

Modify the setup.py file, matching the maintainer, maintainer_email, description and license fields to your package.xml. Then Add the following line within the console_scripts bracket of the entry_points field and save it: 

'sum_nums_pub = sum_nums.sum_nums_publisher:main', 
'sum_nums_sub = sum_nums.sum_nums_subscriber:main', 
 

Here 'sum_nums_pub’ and ‘sum_nums_sub’ are the names of our executables. 

Also check the setup.cfg file to see if it’s populated automatically. The settings in setup.cfg file will put the executables in install/sum_nums/lib/sum_nums/ folder, allowing ‘ros2 run’ command to access them. 

 

Return to the root of our workspace, build our project and source the installation folder to add it to the path for finding the new executables. 

$ cd ~/ros2_ws 
$ colcon build 
$ source install/setup.bash 

 

Once the build is done, let’s try to run our node executables.  

In a same terminal, run the sum nums subscriber node. 

$ ros2 run sum_nums sum_nums_sub 

 

In a new terminal, run the sum nums publisher node. 

$ cd ~/ros2_ws 
$ source install/setup.bash 
$ ros2 run sum_nums sum_nums_pub 

Enter a positive integer and press Enter. 

The sum will be displayed by the sum_nums_sub node in the first terminal. 

image

 

NOTE: You can publish to the topic ‘input_number’ manually using ‘ros2 topic echo’ command, however this tutorial is meant to get a grasp on the basics by covering all the areas that we went through in the previous blogs. 

 

  • Sign in to reply
  • DAB
    DAB over 1 year ago

    Looks clean to implement.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube