📜 ⬆️ ⬇️

Robotic Operating System 2 Basics: Tell the World "Hello, world!"

Good all the phases of rotation of the Earth!
Today, we will continue our acquaintance with the ROS system, which allows us to easily and easily create robot control systems. For those who missed the previous lesson - an approximate work plan.
  1. Installation, basic concepts
  2. Create your package, get acquainted with the messages, a simple program
  3. Services and options

Last time we found that the basic element of the ROS is a packet. The educational process can not pass by this interesting fact, so get a magnifying glass or microscope stronger - we will study!

In this case, the most convenient will be to build your package. In order not to spoil anything, and to maintain the ROS microflora in good condition, we will create a separate directory for all experiments. In my case it will be ~ / ros.

. /opt/ros/electric/setup.sh cd mkdir ros cd ./ros export ROS_PACKAGE_PATH="~/ros:/opt/ros/electric/stacks" 

The last line sets the environment variable that stores the paths to the standard package repository (number 2) and to the user’s ones (in this case, path number 1). A particularly inquisitive reader may suggest that we have created a custom stack. Alas, it will be an erroneous assumption - we lack the stack.xml manifest file. However, it is fixable, but now it is absolutely not necessary. And now is the time for the sacrament.

Wrap up please


Packages are created with the roscreate-pkg command and called as follows:
 $ roscreate-pkg tutorial std_msgs rospy roscpp 

The first argument is the name of the package, then the list of dependencies follows (we'll talk about them a bit later). Now we need to register our package with the help of the rospack command already known from the last lesson.
 rospack profile rospack find tutorial /home/crady/ros/tutorial 

Everything seems to be going well. But what happens if we run our package on another machine? And if there is another version of ROS? And if it is, and then immediately in-oh-oh-oh-oh? Dependency tracking should help with all this. ROS identifies 2 types of connections between packets - the first stage and all the rest. The division immediately becomes clear if you look in the manifest of our module:
  cat ./ros/tutorial/manifest.xml 

 <package> <description brief="tutorial"> tutorial </description> <author>crady</author> <license>BSD</license> <review status="unreviewed" notes=""/> <url>http://ros.org/wiki/tutorial</url> <depend package="std_msgs"/> <depend package="rospy"/> <depend package="roscpp"/> </package> </source> 

Here in the attribute <depend> the dependencies of the first queue are listed. All that they already require for themselves are “indirect” requirements. In order not to climb every time in the manifest, you can again use the rospack command:
 $ rospack depends1 tutorial std_msgs rospy roscpp $ rospack depends tutorial rospack roslib std_msgs rosgraph_msgs rosbuild roslang rospy cpp_common roscpp_traits rostime roscpp_serialization xmlrpcpp rosconsole roscpp 

There is just a little bit of theory left and we will move on to the most delicious thing - writing code.
')

That's when he tells me ...


Suppose that our package is ready and can ... can ... knows how to calculate the energy of a picture using MRF. Maybe someday I will tell you how and why this is not the point. In order for this to have any benefit, obviously, our executable file (as you remember from the last lesson, it is called a [node] in terms of ROS) must receive something (for example, a picture) at the input and that something to give (say, a number or even a series of numbers). Since we have a lot of various libraries, it makes sense to standardize the format of input and output data. This is done using the message mechanism (msg). In fact, we get the following system: the publisher (Publisher) talks to the subscriber (Subscriber) on a specific topic (Topic).
So, we have a framework for the future application and some theoretical knowledge. It's time to build on these ridiculous bones a bit of meat and see what the programs look like in ROS.

And so you code ...


The message publisher will write in the wonderful Python language. In fact, it would have to be a hello-world, but we will go our own way and change the text of the message! Go to the folder with our package:
 $ cd $(rospack find tutorial) 

Create a folder for the script:
 $ mkdir scripts 

And create in it a text file of a simple content:
 $ vi ./scripts/talker.py 

 #!/usr/bin/env python #    #      import roslib roslib.load_manifest('tutorial') #   . rospy  ROS  Python, #String -         import rospy from std_msgs.msg import String def talker(): #    chatter     String pub = rospy.Publisher('chatter', String) # ROS,     rospy.init_node('talker') # ROS ,   while not rospy.is_shutdown(): str = "Zooo! %s"%rospy.get_time() rospy.loginfo(str) pub.publish(String(str)) rospy.sleep(1.0) if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass 


Since this is a talker module, you must specify the format of the messages it publishes:
 $ echo "string str" > ./msg/Str.msg 

The following data types are supported:

All that is needed is to simply list the required fields in the text field, with 1 line corresponding to one parameter. “Is that all?”, The reader will ask. Well, by and large, yes. The msg code generation takes over the local make. By the way, it's time for us to do it.
  $ vi ./CMakeLists.txt 

All you need is to uncomment the following line:
 rosbuild_genmsg() 

This will make the system understand that the node wants to share information with someone and need to compile the appropriate code.
Everything, we enter into consoles
 $ make $ chmod +x ./scripts/listener.py 

and enjoy. Yes, Python here also requires make, in fact, for messages. chmod marks the file as executable (this is important!).
In the meantime, we will deal with the interlocutor in an equally remarkable C ++ language. Yes, the msgs mechanism allows you to communicate with completely different nodes without problems and unnecessary gestures.
Create a new package:
 $ roscreate-pkg tutorialSubscriber roscpp std_msgs $ cd tutorialSubscriber/ $ vi ./src/listener.cpp 

 #include "ros/ros.h" #include "std_msgs/String.h" void chatterCallback(const std_msgs::String::ConstPtr& msg) { //  ROS_INFO("There something on the line! [%s]", msg->data.c_str()); } int main(int argc, char **argv) { //  listener ros::init(argc, argv, "listener"); ros::NodeHandle n; //,     chatter,        1000, //   -   chatterCallback ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); //spin     callback   ,  ROS    ros::spin(); return 0; } 

It remains to change a little make:
 vi ./CMakeLists.txt 

It is necessary to bring the penultimate line to the following form:
 rosbuild_add_executable(listener src/listener.cpp) 

Run make here, but to compile the executable file.
Everything, it remains to evaluate our works, we open as many as 4 terminals:
  1. roscore will launch a master process
  2. rosrun tutorial talker.py will launch Publisher
  3. rosrun tutorialSubcriber listener will launch the subscriber
  4. rxgraph will show us the connection scheme of nodes

The diagram shows that the message text will be printed twice - on the listener node and on / rosout, an analogue of stdout.

Meanwhile...


Meanwhile, the party is gaining momentum. People got to the condition and decided to play pool in the pool. But something went wrong ...

Source: https://habr.com/ru/post/128046/


All Articles