ROS: Create a Simple Publisher/Subscriber in C++

Last Updated on 8. October 2026 by SuffocationLink status: OK

Hier soll kurz beschrieben werden, wie ein Publisher (Nachrichten-Erzeuger) und ein Subscriber (Nachrichten-Abonnent) in C++ erstellt werden.

Für eine ausführliche Anleitung sei auf die offizielle Website verwiesen.

http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

Prerequisite

Ihr benötigt einen Workspace und ein Paket, in meinem Fall ist das Workspace test_ws und Paket beginner_tutorial. Weiterhin könnten auch helfen:

ROS: Create ServiceLink status: OK
ROS: Creating MessagesLink status: OK
ROS: CatkinLink status: OK

Preparation

Ins Paketverzeichnis wechseln

source ~/test_ws/devel/setup.bash
roscd beginner_tutorial

Falls noch nicht vorhanden, ein Quellcode-Verzeichnis im Paket erstellen und in das Verzeichnis wechseln.

mkdir -p src
cd src

This directory will contain all of the package's source code files.

Publisher Knot

Publisher Knoten erstellen

Nun ein Beispiel für einen einfachen Publisher von unten kopieren oder einfach mit folgendem Befehl vom original ROS Tutorial herunterladen.

 wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp

Die Datei sollte im Prinzip folgenden Code enthalten. Ich habe meinen Code nur an der original Datei orientiert und die Texte zur besseren Lesbarkeit weggelassen, Please observe the copyright and disclaimer of the original fileLink status: OK, solltet ihr diese verwenden.

/* Simple Publisher
*  Based on the example by Morgan Quigley and Willow Garage, Inc. No guarantees are given for this code. 
*  The basis for this code can be found at:
*  https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp 
*/ 

#include "ros/ros.h"
#include "std_msgs/String.h"
#include  

int main(int argc, char **argv)
{

  ros::init(argc, argv, "Publisher");
  ros::NodeHandle n;
  ros::Publisher pub = n.advertise("ChatTopic", 1000);

  ros::Rate loop_rate(10);

  int count = 0;
  while (ros::ok())
  {
    std_msgs::String msg;

    std::stringstream strStream;
    strStream << "Chat Message " << count;
    msg.data = strStream.str();

    ROS_INFO("%s", msg.data.c_str());

    pub.publish(msg);

    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }

  return 0;
}

Publisher Code erklärt

Wir benötigen die ROS Bibliothek, eine einfache Textnachricht und die Stream Bibliothek für Ausgaben.

#include "ros/ros.h"
#include "std_msgs/String.h"
#include

Der restliche Code wird in der Main Funktion, die nach Programmstart aufgerufen wird, platziert. Der folgende Befehl initialisiert ROS. Er bekommt als Argumentliste die Consolen Argumente des Knotens und einen eindeutigen Namen (hier Publizierer). Dieser darf kein / enthalten.

int main(int argc, char **argv)
{
   ros::init(argc, argv, "Publisher"); // <--.

Now, we will create a NodeHandle, which allows us to access the node process. On its first creation, the node will be initialised.

ros::NodeHandle n;

Mit dessen Hilfe registrieren wir uns nun als PublishDie Frequenz beschreibt die Anzahl der Schwingungen in einer Zeiteinheit. Frequenz und Wellenlänge sind miteinander verknüpft. Die Maßeinheit der Frequenz ist das Hertz (Hz): 1 Hz = 1 Schwingung pro Sekunde = 1/s.er. Die Argumente sind der Topic Name („ChatTopic“) und die Größe des Nachrichten-Puffers in Anzahl Nachrichten. Wird die Anzahl nicht abgeholter Nachrichten überschritten, werden alte Nachrichten verworfen. Der Aufruf gibt ein Publisher-Objekt zurück, mit dessen Hilfe wir später Nachrichten veröffentlichen können.

ros::Publisher pub = n.advertise("ChatTopic", 1000);

Der folgende Befehl gibt an, wie lange gewartet werden soll, nachdem ein sleep aufgerufen wurde. In diesem Fall 10 Hz (10/Sekunde = 100 ms warten)

ros::Rate loop_rate(10);


// loop_rate.sleep(); // comes later

Unsere eigene Logik läuft in einer Schleife ab. Diese wird so lange durchlaufen, bis eines der folgenden Ereignisse eintritt, mit diesem wird ros::ok() dann auf false gesetzt.

  • Node program stopped (e.g. Control + C)
  • Ejected from the network due to another node with the same name.
  • ros::shutdown() has been called
  • Alle ros::NodeHandles wurden zerstört
  int count = 0;
  while (ros::ok())
  {
    // ...
  }

Nun erzeugen wir eine Nachricht und verschicken diese mit pub.publish(msg). ROS_INFO schreibt die Nachricht noch auf dem Standardoutput.

  std_msgs::String msg;
  std::stringstream strStream;
  strStream << "Chat Message " << count;
  msg.data = strStream.str();

  ROS_INFO("%s", msg.data.c_str());
  pub.publish(msg);

SpinOnce wird hier eigentlich nicht benötigt und wird hier nur der Vollständigkeit halber angegeben. Es sieht für mich so aus, als würde hier einmal die EventLoop durchlaufen um Nachrichten/Events … zu aktualisieren.

 ros::spinOnce();

Now we wait 100 milliseconds (10Hz) until the next loop iteration

loop_rate.sleep();

Subscriber node

Create subscriber node

Nun ein Beispiel für einen einfachen Subscriber von unten kopieren oder einfach mit folgendem Befehl vom original ROS Tutorial herunterladen.

wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/listener/listener.cpp

Die Datei sollte im Prinzip folgenden Code enthalten. Ich habe meinen Code an der original Datei orientiert und die Texte zur besseren Lesbarkeit weggelassen, Please observe the copyright and disclaimer of the original fileLink status: OK, solltet ihr diese verwenden.

/* Simple subscriber 
* Based on the example by Morgan Quigley and Willow Garage, Inc. No guarantees are given for this code. 
*  The basis for this code can be found at:
*  https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/listener/listener.cpp 
*/ 

#include "ros/ros.h"
#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "Subscriber");
  ros::NodeHandle n;

  ros::Subscriber sub = n.subscribe("ChatTopic", 1000, chatterCallback);
  ros::spin();

  return 0;
}

Subscriber Code erklärt

Wir brauchen wieder die ROS Bibliothek und auch die Standard String Nachricht.

#include "ros/ros.h"
#include "std_msgs/String.h""

Für den Subscriber brauchen wir eine sogenannte CallBack Funktion, diese wird bei jedem Eintreffen einer Nachricht gerufen. In unserem Fall macht sie nichts anderes als die Nachricht auf der Standardausgabe auszugeben.

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

Auch um einen Subscriber zu erzeugen, muss ROS initialisiert und ein Handle erstellt werden.

int main(int argc, char **argv)
{
  ros::init(argc, argv, "Subscriber");
  ros::NodeHandle n;
..

Nun erstellen wir noch den Subscriber, geben ihm den Topic Namen, die Größe des Nachrichtenpuffers, den Namen der CallBack Funktion mit und lassen ROS die Eventloop peitschen.

  ros::Subscriber sub = n.subscribe("ChatTopic", 1000, chatterCallback);
  ros::spin();

Das war’s.

Build

CMake anpassen

Inform CMakeList.txt about the created files.

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

Here's what my file looks like then

cmake_minimum_required(VERSION 3.0.2)
project(beginner_tutorial)

find_package(catkin REQUIRED)

## Find catkin and any catkin packages
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg message_generation)

add_message_files(FILES Num.msg)
add_service_files(FILES AddTwoInts.srv)

generate_messages(DEPENDENCIES std_msgs)

catkin_package()

include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorial_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorial_generate_messages_cpp)

Kompilieren

Change to the main directory of the workspace and run catkin_make

cd ~/test_ws
catkin_make

Die Programme sollten ohne Fehler kompilieren.

Try

Start ROS core

Open a new console and start the core

roscore

Console output

Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

Started roslaunch server http://ros1:36971/
ros_comm version 1.14.13


SUMMARY
========

PARAMETERS
 * /rosdistro: melodic
 * /rosversion: 1.14.13

NODES

auto-starting new master
process[master]: started with pid [21703]
ROS_MASTER_URI=http://ros1:11311/

setting /run_id to b388e65a-e1ed-11ed-9402-2cf05d21f9e7
process[rosout-1]: started with pid [21714]
started core service [/rosout]

Start Publisher

Open new console and start publisher

source devel/setup.bash
rosrun beginner_tutorial talker

Console output

stefan@ros1:~/test_ws$ rosrun beginner_tutorial talker
[ INFO] [1682264871.725780407]: Chat Message 0
[ INFO] [1682264871.825829919]: Chat Message 1
[ INFO] [1682264871.926003834]: Chat Message 2
[ INFO] [1682264872.025829924]: Chat Message 3
[ INFO] [1682264872.125823473]: Chat Message 4
[ INFO] [1682264872.225830377]: Chat Message 5
[ INFO] [1682264872.325854816]: Chat Message 6
[ INFO] [1682264872.425830687]: Chat Message 7
[ INFO] [1682264872.526317126]: Chat Message 8
[ INFO] [1682264872.626305447]: Chat Message 9
[ INFO] [1682264872.725830634]: Chat Message 10
[ INFO] [1682264872.826306242]: Chat Message 11
[ INFO] [1682264872.925858434]: Chat Message 12
[ INFO] [1682264873.025830754]: Chat Message 13

Start Subscriber

Neue Console öffnen und den Subscriber starten

source devel/setup.bash
rosrun beginner_tutorial listener

Console output

stefan@ros1:~/test_ws$ rosrun beginner_tutorial listener
[ INFO] [1682264872.026229599]: I heard: [Chat Message 3]
[ INFO] [1682264872.126169068]: I heard: [Chat Message 4]
[ INFO] [1682264872.226189402]: I heard: [Chat Message 5]
[ INFO] [1682264872.326278372]: I heard: [Chat Message 6]
[ INFO] [1682264872.426155092]: I heard: [Chat Message 7]
[ INFO] [1682264872.526503319]: I heard: [Chat Message 8]
[ INFO] [1682264872.626625331]: I heard: [Chat Message 9]
[ INFO] [1682264872.726196509]: I heard: [Chat Message 10]
[ INFO] [1682264872.826496384]: I heard: [Chat Message 11]
[ INFO] [1682264872.926120007]: I heard: [Chat Message 12]
[ INFO] [1682264873.026085367]: I heard: [Chat Message 13]

Conclusion

A publisher/subscriber framework is quickly created and serves as a basis for upcoming projects.

Related Posts

ROS: Create ServiceLink status: OK
ROS: Creating MessagesLink status: OK
ROS: CatkinLink status: OK

Sources

http://wiki.ros.org/melodic/Installation/Ubuntu

http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

Link status: OK

DateChangeAuthor
08.10.2026Überschriften-Hierarchie korrigiert (H1→H2, Unterebenen eine Stufe tiefer)Suffocation
04.10.2026Rechtschreibung korrigiert: Tippfehler, Kommas, Grammatik, Groß-/KleinschreibungSuffocation
03.10.2026Log-Liste eingefügtSuffocation
22.04.2023Post createdSuffocation
Changelog

Leave a Reply

Your email address will not be published. Required fields are marked *