0% found this document useful (0 votes)
5 views11 pages

ROS Report

The document provides a comprehensive guide on adding custom message and service files in ROS, including detailed steps for creating and testing custom messages and services. It also covers working with ROS services and actionlib, explaining how to implement service and action servers and clients. Key concepts include defining message structures, handling request-response interactions, and managing preemptive tasks in robotic applications.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views11 pages

ROS Report

The document provides a comprehensive guide on adding custom message and service files in ROS, including detailed steps for creating and testing custom messages and services. It also covers working with ROS services and actionlib, explaining how to implement service and action servers and clients. Key concepts include defining message structures, handling request-response interactions, and managing preemptive tasks in robotic applications.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 11

CONTENTS

SL.N PAGE
DESCRIPRITIONS
O. NO.

1 Adding custom Message and Service Files 1-3

2 Working with ROS services 4-5

3 Working with ROS actionlib 6-7

4 Creating the ROS action server 8-9


Adding custom Message and Service Files

→ To add custom message and services in ROS, you need to follow a series of steps
for both .msg and .srv files.
→ From defining the files to modifying the package.xml and CMakeLists.txt files,
and then building and testing the package.

Custom Message File:


Defines a new data structure for ROS communication.
Custom Service File:
Defines a new Request - Response interface for ROS nodes.
Adding custom msg/srv File:
Create and add custom msg/srv files to your ROS package to enable specialized data
exchange and node interactions.

Steps to create a custom message:

Step 1: a) Open a text editor.


b) Create a new file with .msg
Step 2: a) Define message structure.
b) * Define the msg files using ROS Primitive type.
* Use array [ ] or vectors [ ] for repeated fields.
* Use comments # for explanation.
Step 3: Update package .xml
Add dependency:
<depend>message_runtime</depend>
Step 4: Build Package.
Run
bash
catkin_make
Step 5: Test the custom message.
Create publisher and subscriber nodes (e.g., demo_msg_publisher.cpp and
demo_msg_subscriber.cpp) to test your msg.
Step 6: Use custom message:
In your Ros node (c++ or python)
#include <my_package/MyMessage.h>
OR
from my_package.msg import MyMessage

Steps to create a custom service:

Step 1: Create a service file.


a) Open a text editor.
b) Create a new file with a .srv extension
c) Save it in the srv directory of your ROS package
Step 2: a) Define the request field using ROS primitive type
b) Use ------ to seperate request and response sections.
c) Define the response field using ROS primitive type
Example:- String in
-----------
String out
Step 3: Update package.xml
a) Open package.xml in your ROS package directory.
b) Add the service_runtime dependency.
<depend>service_runtime</depend>
Step 4: Build package.
Run CatKin_make in your bash ROS workspace
bash
cd ~/CatKin
CatKin_make
Step 5: Testing the custom srv files.
*To test the custom service, you’ll need a service client and server.
*The server provide the service, while the client calls it.
a) Create a srv server node and a client node in your расkage.

Example: demo_srv_server.cpp and demo_srv_client.cpp


b) In CMakeLists.txt add the server and client executables.
c) Link the executable with the ROS libraries.
d) Start the service server and client.
Step 6: Implement service.
a) Create a new C++ / python file
(e.g., my-service.cpp/(link unavailable)).
b) Include the generated header file (MyService.h)
c) Implement the service callback function.
C++
ros:: Service server service("my_service", and myServiceCallback);
Python
rospy.Service(my_service’,MyService, Callback)
Step7: Use service:
a) Create a client node to call the service
b) Use ros::ServiceClient (C++)
OR
rospy.ServiceProxy (Python) to call the Service.
C++
ros::ServiceClient client(“my_service”);
Python
Client=rospy.ServiceProxy(‘my_srv’,MyService).
Working with ROS services

In this section, we are going to create ROS nodes, which can use the services definition
that we defined already. The service nodes we are going to create can send a string
message as a request to the server and the server node will send another message as a
response.
Navigate to mastering_ros_demo_pkg/src, and find nodes with the names
demo_service_server.cpp and demo_service_client.cpp

The demo_service_server.cpp is the server, and its definition is as follows:

#include "ros/ros.h"
#include "mastering_ros_demo_pkg/demo_srv.h"
#include <iostream>
#include <sstream>
using namespace std;

bool demo_service_callback(mastering_ros_demo_pkg::demo_srv::Request &req,


mastering_ros_demo_pkg::demo_srv::Response &res) {
std::stringstream ss;
ss << "Received Here";
res.out = ss.str();
ROS_INFO("From Client [%s], Server says
[%s]",req.in.c_str(),res.out.c_str());
return true;
}

int main(int argc, char **argv)


{
ros::init(argc, argv, "demo_service_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("demo_service",
demo_service_callback);
ROS_INFO("Ready to receive from client.");
ros::spin();
return 0;
}
Next, we can see how demo_service_client.cpp is working.

Here is the definition of this code:

#include "ros/ros.h"
#include <iostream>
#include "mastering_ros_demo_pkg/demo_srv.h"
#include <iostream>
#include <sstream>
using namespace std;

int main(int argc, char **argv)


{
ros::init(argc, argv, "demo_service_client");
ros::NodeHandle n;
ros::Rate loop_rate(10);
ros::ServiceClient client =
n.serviceClient<mastering_ros_demo_pkg::demo_srv> ("demo_service");
while (ros::ok())
{
mastering_ros_demo_pkg::demo_srv srv;
std::stringstream ss;
ss << "Sending from Here";
srv.request.in = ss.str();
if (client.call(srv))
{
ROS_INFO("From Client [%s], Server says
[%s]",srv.request.in.c_str(),srv.response.out.c_str());

}
else
{
ROS_ERROR("Failed to call service");
return 1;
}

ros::spinOnce();
loop_rate.sleep();

}
return 0;
}
Working with ROS actionlib
In ROS services, the user implements a request/reply interaction between two nodes,
but if the reply takes too much time or the server is not finished with the given work,
we have to wait until it completes, blocking the main application while waiting for the
termination of the requested action. In addition, the calling client could be
implemented to monitor the execution of the remote process. In these cases, we should
implement our application using actionlib. This is another method in ROS in which we
can preempt the running request and start sending another one if the request is not
finished on time as we expected. Actionlib packages provide a standard way to
implement these kinds of preemptive tasks. Actionlib is highly used in robot arm
navigation and mobile robot navigation. We can see how to implement an action server
and action client implementation.

There is another method in ROS in which we can preempt the running request and start
sending another one if the request is not finished on time as we expected. Actionlib
packages provide a standard way to implement these kinds of preemptive tasks.
Actionlib is highly used in robot arm navigation and mobile robot navigation. We can
see how to implement an action server and action client implementation.

Like ROS services, in actionlib, we have to specify the action specification. The action
specification is stored inside the action file having an extension of .action. This file
must be kept inside the action folder, which is inside the ROS package. The action file
has the following parts:

 Goal: The action client can send a goal that has to be executed by the action server.
This is similar to the request in the ROS service. For example, if a robot arm joint
wants to move from 45 degrees to 90 degrees, the goal here is 90 degrees.
 Feedback: When an action client sends a goal to the action server, it will start
executing a callback function. Feedback is simply giving the progress of the
current operation inside the callback function. Using the feedback definition, we
can get the current progress. In the preceding case, the robot arm joint has to move
to 90 degrees; in this case, the feedback can be the intermediate value between 45
and 90 degrees in which the arm is moving.
 Result: After completing the goal, the action server will send a final result of
completion, it can be the computational result or an acknowledgment. In the
preceding example, if the joint reaches 90 degrees it achieves the goal and the
result can be anything indicating it finished the goal.
We can discuss a demo action server and action client here. The demo action client
will send a number as the goal. When an action server receives the goal, it will
count from 0 to the goal number with a step size of 1 and with a 1 second delay. If
it completes before the given time, it will send the result; otherwise, the task will
be preempted by the client. The feedback here is the progress of counting. The
action file of this task is as follows. The action file is named Demo_action.action:

#goal definition
int32 count
--
#result definition
int32 final_count
--
#feedback
int32 current_number

Here, the count value is the goal in which the server has to count from zero to this
number. final_count is the result, in which the final value after completion of a task
and current_number is the feedback value. It will specify how much the progress
is.

Navigate to mastering_ros_demo_pkg/src and you can find the action server node
as demo_action_server.cpp and action client node as demo_action_client.cpp.
Creating the ROS action server
In this section, we will discuss demo_action_server.cpp. The action server receives
a goal value that is a number. When the server gets this goal value, it will start
counting from zero to this number. If the counting is complete, it will successfully
finish the action, if it is preempted before finishing, the action server will look for
another goal value.

This code is a bit lengthy, so we can discuss the important code snippet of this
code.

Let's start with the header files:

#include <actionlib/server/simple_action_server.h>
#include "mastering_ros_demo_pkg/Demo_actionAction.h"

The first header is the standard action library to implement an action server node.
The second header is generated from the stored action files. It should include
accessing our action definition:

class Demo_actionAction
{

This class contains the action server definition:

actionlib::SimpleActionServer as; <mastering_ros_demo_pkg::Demo_actionAction>

Create a simple action server instance with our custom action message type:

mastering_ros_demo_pkg::Demo_actionFeedback feedback;

Create a feedback instance for sending feedback during the operation:

mastering_ros_demo_pkg::Demo_actionResult result;

Create a result instance for sending the final result:

Demo_actionAction(std::string name) :
as(nh_, name, boost::bind(&Demo_actionAction::executeCB, this, _1), false),
action_name(name)
This is an action constructor, and an action server is created here by taking an
argument such as Nodehandle, action_name, and executeCB, where executeCB is the
action callback where all the processing is done:

as.registerPreemptCallback(boost::bind(&Demo_actionAction::preemptCB, this));

This line registers a callback when the action is preempted. The preemtCB is the
callback name executed when there is a preempt request from the action client:

void executeCB(const mastering_ros_demo_pkg::Demo_actionGoalConstPtr &goal)


{
if(!as.isActive() || as.isPreemptRequested()) return;

This is the callback definition which is executed when the action server receives a
goal value. It will execute callback functions only after checking whether the
action server is currently active or it is preempted already:

for(progress = 0 ; progress < goal->count; progress++){


//Check for ros
if(!ros::ok()){

This loop will execute until the goal value is reached. It will continuously send the
current progress as feedback:

if(!as.isActive() || as.isPreemptRequested()){
return;
}

Inside this loop, it will check whether the action server is active or it is preempted.
If it occurs, the function will return:

if(goal->count == progress){
result.final_count = progress;
as.setSucceeded(result);
}

If the current value reaches the goal value, then it publishes the final result:

Demo_actionAction demo_action_obj(ros::this_node::getName());

In main(),we create an instance of Demo_actionAction, which will start the action


server.
*********************************************************

You might also like