Simple ROS topic publishing and subscription case

Some basic ROS commands

roscd is part of the rosbash command set, which allows you to directly switch directories (cd) to a certain software package or set of software packages.

//Usage:
$ roscd [locationname[/subdir]]

rosls is part of the rosbash command set, which allows you to execute the ls command directly by the name of the package (without having to enter the absolute path).

//Usage:
$ rosls [locationname[/subdir]]

rospack allows you to obtain relevant information about the software package. You can add parameters later. If you add the find parameter,

//Usage:
$ rospack find [package_name]
//Can return the path of the software package

Some ROS concepts

catkin software package

What does a catkin software package consist of?

For a package to be called a catkin package, it must meet the following requirements:

  • This package must have a package.xml file that conforms to the catkin specification

    • This package.xml file provides meta-information about the package

  • This package must have a catkin version of the CMakeLists.txt file

    • If it is a Catkin metapackage, there needs to be a relevant template for the CMakeList.txt file

  • Each package must have its own directory
    • This means that there cannot be nested or multiple packages in the same directory

catkin workspace

The recommended way to develop catkin packages is to use a catkin workspace

Steps to create a blank catkin workspace

Open the terminal and execute the command

$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/
$ catkin_make

Execute catkin_make

A CMakelists.txt file will be generated in the src directory.

And generate a build and devel directory

There is setup.bash in the devel directory

Next, source it first

source ./devel/setup.bash

Create catkin software package

First, switch to the src directory of the catkin workspace you just created.

$ cd ~/catkin_ws/src

Now use the catkin_create_pkg command to create a new package named beginner_tutorials. This package depends on std_msgs, roscpp and rospy

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

This will create a folder named beginner_tutorials, which contains a package.xml file and a CMakeLists.txt file. Both files have been partially filled in when you execute catkin_create_pkg command.

ROS node

A node is actually nothing more than an executable file in a ROS package. ROS nodes use the ROS client library to communicate with other nodes. Nodes can publish or subscribe to topics, and can also provide or use services.

Note: Node is a very important concept in ROS. To help beginners understand this concept, here is a popular example:

For example, we have a robot and a remote control. After the robot and the remote control start working, they are two nodes. The remote control plays the role of issuing instructions; the robot is responsible for monitoring the instructions issued by the remote control and completing the corresponding actions. From here we can see that a node is a work unit that can perform specific work tasks and can communicate with each other to realize the overall function of a robot system. Here we simply define the remote control and the robot as two nodes. In fact, the robot can be further subdivided into more nodes according to different components such as controllers, sensors, actuators, etc. This is based on the user defined by the program written. )

Topic publishing and subscribing

First switch to the previously created package beginner_tutorials

Create a src to store source code

$ mkdir src
$ cd src

Write the source code talker.cpp and listener.cpp under src

talker.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

/*
    Header file explanation:
    ros/ros.h is a convenient include that contains all the header files needed to use the most common common parts of the ROS system.
    
    std_msgs/String.h references the std_msgs/String message located in the std_msgs package. This is from the std_msgs package
    The header file automatically generated in the String.msg file. std_msgs is the message type in ros and contains various data types.
*/


int main(int argc, char **argv)
{
 
  ros::init(argc, argv, "talker");
  //Initialize ROS. This allows ROS to do name remapping via the command line, which is where we assign names to nodes. The node name is in
  //Must be unique in the running system

  ros::NodeHandle n;
  //Create a handle for the node of this process. The first NodeHandle created will actually perform the initialization of the node, while the last one is destroyed
  //The NodeHandle will clear any resources used by the node.

  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
  //Tell the master node that we are going to publish a message of type std_msgs/String on the chatter topic. This will let the master node tell anyone
  //What node is listening to chatter, we will publish data on this topic. The second parameter is the size of the publishing queue. In this case,
  //If we publish too fast, it will cache up to 1000 messages, otherwise it will discard old messages.

  //NodeHandle::advertise() returns a ros::Publisher object, which has 2 purposes: First, it contains a
  //publish() method can publish the message to the topic where it was created; secondly, when it goes out of scope, it will automatically cancel the announcement operation.
  //do.

  ros::Rate loop_rate(10);
  //The ros::Rate object allows you to specify the frequency of the loop. It records how long it has been since the last call to Rate::sleep(),
  //And sleep for the correct amount of time. In this case, we tell it we want to run at 10Hz.


  int count = 0;
  while (ros::ok())
  {
  /*
    By default, roscpp will install a SIGINT handler, which is able to handle Ctrl + C operations, causing ros::ok() to return false.

    ros::ok() will return false in the following situations:

        SIGINT signal received (Ctrl + C)
        Kicked out of the network by another node with the same name
        ros::shutdown() is called by another part of the program
        All ros::NodeHandles have been destroyed
        Once ros::ok() returns false, all ROS calls will fail.
    */
    
    std_msgs::String msg;

    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

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

 
    chatter_pub.publish(msg);
    //Broadcast this information to any connected nodes.

    ros::spinOnce();
    //Calling ros::spinOnce() here is not necessary for this simple program because we do not receive any callbacks. However, if
    //If you want to add a subscription to this program, but there is no ros::spinOnce(), the callback function will never be called.

    loop_rate.sleep();
     + + count;
  }


  return 0;
}

listener.cpp

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


void chatterCallback(const std_msgs::String::ConstPtr & amp; msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}
/*
This is a callback function that will be called when a new message arrives in the chatter topic.
*/

int main(int argc, char **argv)
{
  
  ros::init(argc, argv, "listener");
  ros::NodeHandle n;
  
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  /*
   Subscribe to the chatter topic through the master node. Whenever a new message arrives, ROS will call the chatterCallback() function. second parameter
   is the queue size, in case we can't process messages fast enough. In this example, if the queue reaches 1000, when new messages arrive, the old messages
   The information will be discarded.

   NodeHandle::subscribe() returns a ros::Subscriber object, which you must keep unless you want to unsubscribe. when 
   The Subscriber object is destructed and it will automatically unsubscribe from the chatter topic.
  */

  ros::spin();
  //ros::spin() starts a self-loop that calls the message callback function as quickly as possible. But don't worry, if nothing happens
  //It won't take up too much CPU. Also, ros::spin() will exit once ros::ok() returns false, which means
  //ros::shutdown() is called and the master node shuts us down (or it is called manually because Ctrl + C is pressed).

  return 0;
}

Next, build two nodes, listener and talker, to realize communication between the two nodes.

Modify the CMakelists.txt file under the software package

final look

cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)

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

## Declare ROS messages and services
add_message_files(FILES Num.msg)
add_service_files(FILES AddTwoInts.srv)

## Generate added messages and services
generate_messages(DEPENDENCIES std_msgs)

## Declare a catkin package
catkin_package()

## Build talker and listener
include_directories(include ${catkin_INCLUDE_DIRS})

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)

This will create two executable files, talker and listener. By default, they will be placed in the devel space under the package directory, i.e. ~/catkin_ws/devel/lib/.

add_dependencies(talker beginner_tutorials_generate_messages_cpp)

This ensures that the package’s message headers are generated before using this package. If you use messages from other packages in your catkin workspace, you will also need to add the dependencies to the respective build targets, as catkin builds all projects in parallel

Now you can run catkin_make:

# Under catkin workspace
$ cd ~/catkin_ws
$ catkin_make

Run ROS node

Run node command

$ rosrun [package_name] [node_name]

Notice:

Before running all ros programs, roscore must be executed first.

Open a terminal, enter the catkin workspace and execute roscore

Open another terminal, enter the catkin workspace, first execute source ./devel/setup.bash, and then

rosrun package name talker This opens the publisher node

Open another terminal, enter the catkin workspace, first execute source ./devel/setup.bash, and then

rosrun package name listener This opens the subscriber node

At this point, the publisher and subscriber begin to communicate

The knowledge points of the article match the official knowledge archive, and you can further learn relevant knowledge. Python entry skill treeArtificial intelligenceMachine learning toolkit Scikit-learn377459 people are learning the system