The topic in the previous section is applicable to the sensor data transmission of robots. The communication is generally a single item, which defines the sending or receiving of a node.
For example, A: what's the weather like today, B: today's temperature is 20 degrees and there is light rain.
The nodes are divided into server-side and client-side. The basic supplementary reference is as follows:
background knowledge
Service is another method of node communication in ROS diagram.
- The service is based on the invocation response model, not the publisher subscriber model of the topic.
- Topics allow nodes to subscribe to data streams and get continuous updates, but services provide data only when clients specifically call them.
The above are typical differences between themes and services. The illustration of referencing ROS2Wiki is as follows:
One to one mode the first mock exam server and one client.
One to many mode - one server and multiple clients
Preparatory knowledge
Before that, you should master the contents of the first seven lectures. Of course, take the two-dimensional robot as an example.
Master code writing and robot programming. It is not recommended to install the function package, but to compile the source code.
Practical tasks
1 on
When the robot node is started, the previous track is incomplete, and the following code is modified:
path_image_(888, 666, QImage::Format_ARGB32)
Run on two terminals respectively:
-
ros2 run turtlesim turtlesim_node
-
ros2 run turtlesim turtle_teleop_key
2 service list
Open the third window and enter ros2 service list. The following contents will appear:
- /teleop_turtle
- /turtle1
- /turtlesim
Here, this article focuses on the following services.
/clear, /kill, /reset, /spawn, /turtle1/set_pen, /turtle1/teleport_absolute, and / turnle1 / Report_ relative
3 service message type
Topics communicate with topic messages, and services communicate with service messages.
- .msg
- .srv
Subject location case pose msg
float32 x float32 y float32 theta float32 linear_velocity float32 angular_velocity
Add a robot case to the service: spawn srv
float32 x float32 y float32 theta string name --- string name
Typical usage is as follows:
-
ros2 service type <service_name>
-
ros2 service type /clear
-
std_srvs/srv/Empty
Responds to the service, but does not return a message.
List details
ros2 service list -t
4 service search
ros2 service find <type_name>
Such as std_srvs/srv/Empty
ros2 service find std_srvs/srv/Empty
5 service interface type display
The command is as follows:
-
ros2 interface show <type_name>.srv
Here with spawn SRV as an example:
-
ros2 interface show turtlesim/srv/Spawn
Wait until the following appears:
Use --- to distinguish the message types of call and reply.
6 service call
General command format:
-
ros2 service call <service_name> <service_type> <arguments>
Robot traverses a week:
Call the following services to clear the track:
-
ros2 service call /clear std_srvs/srv/Empty
Those past events are empty in the twinkling of an eye
Then, use the extended robot to add robots to the environment:
- ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: 'robot1'}"
- ros2 service call /spawn turtlesim/srv/Spawn "{x: 4, y: 2, theta: 0.4, name: 'robot2'}"
- ros2 service call /spawn turtlesim/srv/Spawn "{x: 6, y: 2, theta: 0.6, name: 'robot3'}"
- ros2 service call /spawn turtlesim/srv/Spawn "{x: 8, y: 2, theta: 0.8, name: 'robot4'}"
- ros2 service call /spawn turtlesim/srv/Spawn "{x: 10, y: 2, theta: 1.0, name: 'robot5'}"
Call the service to generate a new robot.
Response and generate corresponding robots 1-5.
Then the service exploded:
Summary
Nodes can communicate using the services in ROS 2. Different from the topic (this mode is a communication mode in which the node publishes one or more subscribers to obtain information), the service is a request / response mode, in which the client sends a request to the node. The server provides a service, and the service processes the request and generates a response. Generally, it is not desirable to use services for continuous communication (understood as robot task acquisition); Topics and even actions will be more suitable for continuous communication mode. In this tutorial, command line tools are used to identify, specify and invoke services.
Node topic service diagram
Service program code example:
newly build
clear_srv_ = nh_->create_service<std_srvs::srv::Empty>("clear", std::bind(&TurtleFrame::clearCallback, this, std::placeholders::_1, std::placeholders::_2)); reset_srv_ = nh_->create_service<std_srvs::srv::Empty>("reset", std::bind(&TurtleFrame::resetCallback, this, std::placeholders::_1, std::placeholders::_2)); spawn_srv_ = nh_->create_service<turtlesim::srv::Spawn>("spawn", std::bind(&TurtleFrame::spawnCallback, this, std::placeholders::_1, std::placeholders::_2)); kill_srv_ = nh_->create_service<turtlesim::srv::Kill>("kill", std::bind(&TurtleFrame::killCallback, this, std::placeholders::_1, std::placeholders::_2));
realization
bool TurtleFrame::spawnCallback(const turtlesim::srv::Spawn::Request::SharedPtr req, turtlesim::srv::Spawn::Response::SharedPtr res) { std::string name = spawnTurtle(req->name, req->x, req->y, req->theta); if (name.empty()) { RCLCPP_ERROR(nh_->get_logger(), "A turtle named [%s] already exists", req->name.c_str()); return false; } res->name = name; return true; }
void TurtleFrame::clear() { // make all pixels fully transparent path_image_.fill(qRgba(255, 255, 255, 0)); update(); }
Two dimensional interface display robot
bool TurtleFrame::hasTurtle(const std::string& name) { return turtles_.find(name) != turtles_.end(); } std::string TurtleFrame::spawnTurtle(const std::string& name, float x, float y, float angle) { return spawnTurtle(name, x, y, angle, rand() % turtle_images_.size()); } std::string TurtleFrame::spawnTurtle(const std::string& name, float x, float y, float angle, size_t index) { std::string real_name = name; if (real_name.empty()) { do { std::stringstream ss; ss << "turtle" << ++id_counter_; real_name = ss.str(); } while (hasTurtle(real_name)); } else { if (hasTurtle(real_name)) { return ""; } } TurtlePtr t = std::make_shared<Turtle>(nh_, real_name, turtle_images_[static_cast<int>(index)], QPointF(x, height_in_meters_ - y), angle); turtles_[real_name] = t; update(); RCLCPP_INFO(nh_->get_logger(), "Spawning turtle [%s] at x=[%f], y=[%f], theta=[%f]", real_name.c_str(), x, y, angle); return real_name; }
-End-