/* * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ // %Tag(FULLTEXT)% // %Tag(ROS_HEADER)% #include"ros/ros.h"// 包括 ROS 中常用的头文件 // %EndTag(ROS_HEADER)% // %Tag(MSG_HEADER)% #include"std_msgs/String.h"// 是 std_msgs 包里的 String.msg 自动生成的头文件 // %EndTag(MSG_HEADER)%
#include<sstream>
/** * This tutorial demonstrates simple sending of messages over the ROS system. */ intmain(int argc, char **argv) { /** * The ros::init() function needs to see argc and argv so that it can perform * any ROS arguments and name remapping that were provided at the command line. * For programmatic remappings you can use a different version of init() which takes * remappings directly, but for most command-line programs, passing argc and argv is * the easiest way to do it. The third argument to init() is the name of the node. * * You must call one of the versions of ros::init() before using any other * part of the ROS system. */ // %Tag(INIT)% ros::init(argc, argv, "talker"); // 初始化 ROS,指定了节点名称(不能包含'/') // %EndTag(INIT)%
/** * NodeHandle is the main access point to communications with the ROS system. * The first NodeHandle constructed will fully initialize this node, and the last * NodeHandle destructed will close down the node. */ // %Tag(NODEHANDLE)% ros::NodeHandle n; // 创建这个进程的节点句柄,创建时会初始化 node,销毁时会清除资源 // %EndTag(NODEHANDLE)%
/** * The advertise() function is how you tell ROS that you want to * publish on a given topic name. This invokes a call to the ROS * master node, which keeps a registry of who is publishing and who * is subscribing. After this advertise() call is made, the master * node will notify anyone who is trying to subscribe to this topic name, * and they will in turn negotiate a peer-to-peer connection with this * node. advertise() returns a Publisher object which allows you to * publish messages on that topic through a call to publish(). Once * all copies of the returned Publisher object are destroyed, the topic * will be automatically unadvertised. * * The second parameter to advertise() is the size of the message queue * used for publishing messages. If messages are published more quickly * than we can send them, the number here specifies how many messages to * buffer up before throwing some away. */ // %Tag(PUBLISHER)% ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); // 告诉主节点我们将要发布的话题类型为 std_msgs/String,话题名为 chatter,1000 指代发布队列的大小。 // %EndTag(PUBLISHER)%
/** * A count of how many messages we have sent. This is used to create * a unique string for each message. */ // %Tag(ROS_OK)% int count = 0; while (ros::ok()) // roscpp 将安装一个 SIGINT 处理程序,当接收到 ctrl+C 时 ros::ok() 返回 false { // %EndTag(ROS_OK)% /** * This is a message object. You stuff it with data, and then publish it. */ // %Tag(FILL_MESSAGE)% std_msgs::String msg; // 该类型通常由 msg 文件生成,String 消息有一个成员:data
std::stringstream ss; ss << "hello world " << count; msg.data = ss.str(); // %EndTag(FILL_MESSAGE)%
/** * The publish() function is how you send messages. The parameter * is the message object. The type of this object must agree with the type * given as a template parameter to the advertise<>() call, as was done * in the constructor above. */ // %Tag(PUBLISH)% chatter_pub.publish(msg); // 将信息广播给所有已连接的节点 // %EndTag(PUBLISH)%
/* * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */
/** * This tutorial demonstrates simple receipt of messages over the ROS system. */ // %Tag(CALLBACK)% voidchatterCallback(const std_msgs::String::ConstPtr& msg)// 回调函数,通过 shared_ptr 来传递消息 { ROS_INFO("I heard: [%s]", msg->data.c_str()); } // %EndTag(CALLBACK)%
intmain(int argc, char **argv) { /** * The ros::init() function needs to see argc and argv so that it can perform * any ROS arguments and name remapping that were provided at the command line. * For programmatic remappings you can use a different version of init() which takes * remappings directly, but for most command-line programs, passing argc and argv is * the easiest way to do it. The third argument to init() is the name of the node. * * You must call one of the versions of ros::init() before using any other * part of the ROS system. */ ros::init(argc, argv, "listener");
/** * NodeHandle is the main access point to communications with the ROS system. * The first NodeHandle constructed will fully initialize this node, and the last * NodeHandle destructed will close down the node. */ ros::NodeHandle n;
/** * The subscribe() call is how you tell ROS that you want to receive messages * on a given topic. This invokes a call to the ROS * master node, which keeps a registry of who is publishing and who * is subscribing. Messages are passed to a callback function, here * called chatterCallback. subscribe() returns a Subscriber object that you * must hold on to until you want to unsubscribe. When all copies of the Subscriber * object go out of scope, this callback will automatically be unsubscribed from * this topic. * * The second parameter to the subscribe() function is the size of the message * queue. If messages are arriving faster than they are being processed, this * is the number of messages that will be buffered up before beginning to throw * away the oldest ones. */ // %Tag(SUBSCRIBER)% ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); // 将 topic 和回调绑定,1000 指明队列大小 // %EndTag(SUBSCRIBER)%
/** * ros::spin() will enter a loop, pumping callbacks. With this version, all * callbacks will be called from within this thread (the main one). ros::spin() * will exit when Ctrl-C is pressed, or the node is shutdown by the master. */ // %Tag(SPIN)% ros::spin(); // 启动一个自循环,尽可能快地调用消息回调函数,会自动处理 ros::ok() // %EndTag(SPIN)%
cd ~/catkin_ws/ source ./devel/setup.bash rosrun beginner_tutorials listener
1 2 3 4 5 6
[ INFO] [1720424275.169713314]: I heard: [hello world 1588] [ INFO] [1720424275.269446815]: I heard: [hello world 1589] [ INFO] [1720424275.369373090]: I heard: [hello world 1590] [ INFO] [1720424275.469374169]: I heard: [hello world 1591] [ INFO] [1720424275.569499517]: I heard: [hello world 1592] [ INFO] [1720424275.669370214]: I heard: [hello world 1593]