ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I have also faced a similar challenge during my initial days in ROS2 with C++ OOP.

Seems like you have both rclcpp::spin and rclcpp::spin_until_future_complete in your code here. This can possibly lead to a race condition

https://github.com/ros2/rclcpp/issues/206

There are multiple possible solutions .Either run your rclcpp::spin in a separate thread

https://gist.github.com/wjwwood/5667039b95a682e3034b

OR

How I have worked around is using the std::future<t>::get

auto request = std::make_shared<turtlesim::srv::Spawn::Request>();
request->x = x;
request->y = y;
request->theta = theta;
request->name = name;

RCLCPP_WARN(this->get_logger(), "Spawning '%s'  to '%d'   '%d'", name.c_str(), x, y);
while (!spawnSrvc->wait_for_service(1s))
{
    if (!rclcpp::ok())
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
        return;
    }
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
}

auto future = spawnSrvc->async_send_request(request);
try
{
    auto response = future.get();
    if (response->name != "")
    {
        RCLCPP_INFO(this->get_logger(), "Turtle %s is now alive.", response->name.c_str());
    }
}
catch (const std::exception &e)
{
    RCLCPP_ERROR(this->get_logger(), "Service call failed.");
}

I have also faced a similar challenge during my initial days in ROS2 with C++ OOP.

Seems like you have both rclcpp::spin and rclcpp::spin_until_future_complete in your code here. This can possibly lead to a race condition

https://github.com/ros2/rclcpp/issues/206

There are multiple possible solutions .Either run your rclcpp::spin in a separate thread

https://gist.github.com/wjwwood/5667039b95a682e3034b

OR

How I have worked around is using the std::future<t>::get*std::future<t>::get()

auto request = std::make_shared<turtlesim::srv::Spawn::Request>();
request->x = x;
request->y = y;
request->theta = theta;
request->name = name;

RCLCPP_WARN(this->get_logger(), "Spawning '%s'  to '%d'   '%d'", name.c_str(), x, y);
while (!spawnSrvc->wait_for_service(1s))
{
    if (!rclcpp::ok())
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
        return;
    }
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
}

auto future = spawnSrvc->async_send_request(request);
try
{
    auto response = future.get();
    if (response->name != "")
    {
        RCLCPP_INFO(this->get_logger(), "Turtle %s is now alive.", response->name.c_str());
    }
}
catch (const std::exception &e)
{
    RCLCPP_ERROR(this->get_logger(), "Service call failed.");
}

I have also faced a similar challenge during my initial days in ROS2 with C++ OOP.

Seems like you have both rclcpp::spin and rclcpp::spin_until_future_complete in your code here. This can possibly lead to a race condition

https://github.com/ros2/rclcpp/issues/206

There are multiple possible solutions .Either run your rclcpp::spin in a separate thread

https://gist.github.com/wjwwood/5667039b95a682e3034b

OR

How I have worked around is using the *std::future<t>::get()

auto request = std::make_shared<turtlesim::srv::Spawn::Request>();
request->x = x;
request->y = y;
request->theta = theta;
request->name = name;

RCLCPP_WARN(this->get_logger(), "Spawning '%s'  to '%d'   '%d'", name.c_str(), x, y);
while (!spawnSrvc->wait_for_service(1s))
(!client->wait_for_service(1s))
{
    if (!rclcpp::ok())
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
        return;
    }
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
}

auto future = spawnSrvc->async_send_request(request);
client->async_send_request(request);
try
{
    auto response = future.get();
    if (response->name != "")
    {
        RCLCPP_INFO(this->get_logger(), "Turtle %s is now alive.", response->name.c_str());
    }
}
catch (const std::exception &e)
{
    RCLCPP_ERROR(this->get_logger(), "Service call failed.");
}

I have also faced a similar challenge during my initial days in ROS2 with C++ OOP.OOP,while trying to service call from a member function

Seems like you have both rclcpp::spin and rclcpp::spin_until_future_complete in your code here. This can possibly lead to a race condition

https://github.com/ros2/rclcpp/issues/206

There are multiple possible solutions .Either run your rclcpp::spin in a separate thread

https://gist.github.com/wjwwood/5667039b95a682e3034b

OR

How I have worked around is using the *std::future<t>::get()

auto request = std::make_shared<turtlesim::srv::Spawn::Request>();
request->x = x;
request->y = y;
request->theta = theta;
request->name = name;

RCLCPP_WARN(this->get_logger(), "Spawning '%s'  to '%d'   '%d'", name.c_str(), x, y);
while (!client->wait_for_service(1s))
{
    if (!rclcpp::ok())
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
        return;
    }
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
}

auto future = client->async_send_request(request);
try
{
    auto response = future.get();
    if (response->name != "")
    {
        RCLCPP_INFO(this->get_logger(), "Turtle %s is now alive.", response->name.c_str());
    }
}
catch (const std::exception &e)
{
    RCLCPP_ERROR(this->get_logger(), "Service call failed.");
}