Last Updated on 23 April 2023 by Suffocation
A Publisher (message producer) and a Subscriber (message consumer) will be briefly described and created here in C++.
Für eine ausführliche Anleitung sei auf die offizelle 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 is das Workspace test_ws und Paket beginner_tutorial. Weiterhin könnten auch helfen:
Preparation
Change directory into the package directory
source ~/test_ws/devel/setup.bash
roscd beginner_tutorial
If a source code directory does not exist in the package, create it and change into the directory.
mkdir -p src
cd src
This directory will contain all of the package's source code files.
Publisher Knot
Create Publisher Nodes
Nun ein Beispiel für einen einfachen Publisher von unten Kopiern oder einfach mit folgenden Befehl vom original ROS Tutorial herunterladen.
wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp
The file should, in principle, contain the following code. I have only oriented my code to the original file and omitted the texts for better readability. Please observe the copyright and disclaimer of the original file you should use these.
/* 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
The remaining code is placed in the main function, which is called after the program starts. The following command initialises ROS. It receives the console arguments of the node and a unique name (here publisher) as an argument list. This must not contain a /.
int main(int argc, char **argv)
{
ros::init(argc, argv, "Publisher"); // <--.
Nun erstellen wir einen NodeHandle, dies ermöglicht uns den Zugriff auf den Knotenprozess. Mit der ersten Erstellung wird der Knoten initialisiert.
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 Göß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 hilfen dessen wir später Nachrichten veröffentlichen können.
ros::Publisher pub = n.advertise("ChatTopic", 1000);
The following command specifies how long to wait after a sleep has been called. In this case, 10 Hz (10/second = 100 ms wait).
ros::Rate loop_rate(10);
// loop_rate.sleep(); // kommt später
Unser eigene Logik läuft in einer Schleife ab. Diese wird so lange durchlaufen bis eines der folgenden Ereignisse eintritt, mit diesem wir 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::NodeHandels wurden zerstört
int count = 0;
while (ros::ok())
{
// ...
}
Now we generate a message and send it with pub.publish(msg). ROS_INFO prints the message to standard output.
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 durchaufen um Nachrichten/Events … zu aktualisieren.
ros::spinOnce();
Nun warten wir 100 Millisekunden (10Hz) bis zum nächsten Durchlauf der Schleife
loop_rate.sleep();
Subscriber node
Create subscriber node
Nun ein Beispiel für einen einfachen Subscriber von unten Kopiern oder einfach mit folgenden Befehl vom original ROS Tutorial herunterladen.
wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/listener/listener.cpp
The file should essentially contain the following code. I have based my code on the original file and omitted the text for better readability. Please observe the copyright and disclaimer of the original file you should use these.
/* 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
We need the ROS library again and also the standard string message.
#include "ros/ros.h"
#include "std_msgs/String.h""
Für den Subscriber braucen wir eine sogenannte CallBack Funktion, dies 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());
}
To create a subscriber, ROS must also be initialised and a handle created.
int main(int argc, char **argv)
{
ros::init(argc, argv, "Subscriber");
ros::NodeHandle n;
..
Nun erstellen wir noch den Subcriber, 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();
That's it.
Build
CMake customisation
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)
Compile
In das Hauptverzeichnis des Workspaces wechseln und catkin_make ausführen
cd ~/test_ws
catkin_make
Two programmes should compile without errors.
Try
Start ROS core
Neue Konsole öffnen und den Kern starten
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
Neue Console öffnen und den Publisher starten
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 öffenen 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
Ein Publisher-/Subscriber-Gerüst ist schnell erstellt und dient als Basis für kommende Projekte.
Verwandte Beiträge
Sources
http://wiki.ros.org/melodic/Installation/Ubuntu
http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
| Date | Change | Author |
|---|---|---|
| 22.04.2023 | Post created | Suffocation |
