Key Engineering Takeaways
- •ROS 2 eliminates the single point of failure (ROS Master) by leveraging industry-standard DDS decentralized discovery.
- •Always inherit from `rclcpp::Node` or `rclpy.node.Node` and use wall timers for deterministic periodic callbacks.
- •Use `SensorDataQoS` (Best Effort, Volatile) for high-rate sensor streams (LiDAR, Camera) and `Reliable` for critical commands (cmd_vel, E-stop).
Prerequisites
- • Linux Ubuntu terminal basics
- • Modern C++ or Python 3
Required Hardware / Tools
- • Ubuntu 22.04 LTS (Native or Dual-Boot / WSL2) with ROS 2 Humble Desktop
Why ROS 2? DDS Middleware & No Master Node
In ROS 1, if the central `roscore` process crashed, all inter-node communication halted. ROS 2 replaces this with **Data Distribution Service (DDS)**—an industrial real-time standard used in aerospace and defense.
Nodes discover each other dynamically across the local network subnet via UDP multicast without needing a central coordinator.
Writing Robust C++ (rclcpp) Publisher & Subscriber Nodes
Here is a complete, modern ROS 2 C++ publisher node using smart pointers and wall timers:
velocity_commander_node.cpp
cpp
#include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
using namespace std::chrono_literals;
class VelocityCommander : public rclcpp::Node {
public:
VelocityCommander() : Node("velocity_commander") {
// Declare and get ROS 2 parameters
this->declare_parameter<double>("linear_speed", 0.5);
this->declare_parameter<double>("angular_speed", 0.2);
// Create publisher on /cmd_vel topic with standard queue depth of 10
publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", 10);
// Create 50Hz periodic timer (20ms interval)
timer_ = this->create_wall_timer(
20ms, std::bind(&VelocityCommander::publish_velocity, this)
);
RCLCPP_INFO(this->get_logger(), "Velocity Commander Node initialized at 50Hz.");
}
private:
void publish_velocity() {
auto msg = geometry_msgs::msg::Twist();
msg.linear.x = this->get_parameter("linear_speed").as_double();
msg.angular.z = this->get_parameter("angular_speed").as_double();
publisher_->publish(msg);
}
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_;
rclcpp::TimerBase::SharedPtr timer_;
};
int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<VelocityCommander>());
rclcpp::shutdown();
return 0;
}Tags:#ROS 2#Humble#rclcpp#rclpy#DDS#Nodes#Topics#QoS