Intro

References

Create a ROS2 C++ Package

Create a Minimal ROS Node

  • Create a my_cpp_node node using the rclcpp API by creating a src/my_cpp_node.cpp file in the package

my_cpp_node.cpp

#include "rclcpp/rclcpp.hpp"
 
int main(int argc, char **argv)
{
    // Initiate ROS2 communication
    rclcpp::init(argc, argv);
 
    // Create shared pointer (of type std::shared_ptr<rclcpp::Node> ) to a new ROS node
    auto node = std::make_shared<rclcpp::Node>("my_node_name");
 
    // Keep node alive to process callbacks (subscribers, timers, services, etc.)
    rclcpp::spin(node);
 
    // Shutdown ROS2 communication and clean up resources
    rclcpp::shutdown();
 
    return 0;
}
  • rclcpp::init
  • Note on Smart Pointer: ROS2 uses std::shared_ptr for most ROS objects like nodes to simplify lifecycle management

Add a ROS2 Executable in CMakeLists.txt

• In, CMakeLists.txt, add the executable and name it my_cpp_node (build the node from source): 1

#               executable name        source file
add_executable(my_cpp_node src/my_cpp_node.cpp)

• Link required ROS2 dependencies (e.g. rclcpp, std_msgs):

ament_target_dependencies(my_cpp_node
  rclcpp
  std_msgs
)

• Install the executable so it can be run using ros2 run:

install(TARGETS my_cpp_node
  DESTINATION lib/${PROJECT_NAME}
)

Build and Run

  • From the root of your workspace (ros2_ws), compile the package
colcon build 
# colcon build --packages-select my_package
  • Source the ROS2 workspace setup script
source install/setup.bash
  • Run the my_cpp_node node

Add Functionality

#include "rclcpp/rclcpp.hpp"
 
std::shared_ptr<rclcpp::Node> node = nullptr;
 
void timerCallback()
{
    RCLCPP_INFO(node->get_logger(), "Test");
}
 
 
int main(int argc, char** argv){
    // Initialize ROS communications
    rclcpp::init(argc, argv);
 
    // Instantiate a node
    node = std::make_shared<rclcpp::Node>("my_node_name");
 
    // Write a message
    auto timer = node->create_wall_timer(std::chrono::milliseconds(200), timerCallback);
 
    // Keep alive
    rclcpp::spin(node);
 
    // Destroy node
    rclcpp::shutdown();
 
    return 0;
}   

ROS2 C++ Node with OOP

#include "rclcpp/rclcpp.hpp"
 
class MyNode: public rclcpp::Node 
{
    public:
        MyNode() : Node("my_node") {}
 
    private:
};
 
int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<MyNode>();
    RCLCPP_INFO(node->get_logger(), "OOP test");
    rclcpp::spin(node);
    
    rclcpp::shutdown();
 
    return 0;
}
 
 

Add Functionality

  • Make node print “Hello World” at 5 Hz
#include "rclcpp/rclcpp.hpp"
 
class MyNode : public rclcpp::Node
{
    public:
        MyNode() : Node("my_node")
        {
            // timer_ = this->create_wall_timer(std::chrono::milliseconds(200), std::bind(&MyNode::timerCallback, this));
            
            // Use C++11 lambda function instead
            timer_ = this->create_wall_timer(
                std::chrono::milliseconds(200),
                [this]() { 
                    this->timerCallback(); 
                }
            );
 
        }
 
    private:
        // _timer
        void timerCallback()
        {
            RCLCPP_INFO(this->get_logger(), "Hello World");
        }
 
        rclcpp::TimerBase::SharedPtr timer_;
};
 
int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<MyNode>();
    rclcpp::spin(node);
    rclcpp::shutdown();
}

Next- Create a publsher and subscriber (C++)

Footnotes

  1. https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html#id2 ↩