Explanation of service example in ROS2
I am trying to work with ROS and ROS2 for sometime now. Honestly I had zero programming experience about a month ago but i have learnt a lot in this period. Thanks to the excellent Wiki and the supporters. I have tried to understand certain concepts like shared pointers
but when it comes to implementation, it gets a bit difficult for me.
Through this question i would like if someone can patiently explain each line of the following code and thus it would be more clear to me. I found the best practise as trying to answer some questions myself and i would be happy to be corrected.
add_two_ints_server
class ServerNode : public rclcpp::Node { public: explicit ServerNode(const std::string & service_name) : Node("add_two_ints_server")
/* In this section, first a class ServerNode is created which inherits from the base class rclcpp::Node. An explicit constructor is called (why not implicitly ?) and the member function Node() is initialised with the name "add_two_ints_server". */
{
// Create a callback function for when service requests are received.
auto handle_add_two_ints =
[this](const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
std::shared_ptr<example_interfaces::srv::AddTwoInts::Response> response) -> void
{
(void)request_header;
RCLCPP_INFO(this->get_logger(), "Incoming request\na: %" PRId64 " b: %" PRId64,
request->a, request->b);
response->sum = request->a + request->b;
};
/* Here we create a callback function and pass 3 pointer parameters, namely request_header, request and response which are taken from the serviceFile.srv. Here why an "auto" specifier is used ? Also instead of a handle, we could also use a"void service_callback()" function ? What does "this
// Create a service that will use the callback function to handle requests.
srv_ = create_service<example_interfaces::srv::AddTwoInts>(service_name, handle_add_two_ints);
}
private:
rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr srv_;
};
/Here the service is created/
int main(int argc, char * argv[]) { if (rcutils_cli_option_exist(argv, argv + argc, "-h")) { print_usage(); return 0; }
/*What does this exactly means? */
rclcpp::init(argc, argv); //library initialisation call
auto service_name = std::string("add_two_ints"); //naming the service ?
if (rcutils_cli_option_exist(argv, argv + argc, "-s")) {
service_name = std::string(rcutils_cli_get_option(argv, argv + argc, "-s"));
}
/* what happens here? */
auto node = std::make_shared<ServerNode>(service_name); //passing the service name to the node ?
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
As has been said before ROS is not a good way of learning C++, it's a very complex system. We really recommend learning the basics of C++ before getting too involved! There are some very high level concepts involved in some of these questions...
It would be good the read up on object orientated programming theory and work through some C++ courses first.