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

ros2 subscriber callback blocking one another

asked 2022-07-21 06:14:50 -0500

cjoshi17 gravatar image

Hello,

I am using ROS2 galactic on Ubuntu 20.04. I have 2 callbacks, one which subscribes to the movement message and another which subscribes to a custom path message. In the first call I can see that both these callbacks get data and are updated but however my second call back has a function which moves the robot on that particular path. When this line executes, I stop getting data in my first callback because it is blocking it I guess?? I tried callback groups but it didn't work. Here is my code:

1st callback

void Robot::moveStatusCb(const fleet_msgs::msg::MoveStatus &msg) {
    moveable = msg.movestatus[robotId - 1];
     std::cout << "MOVABLE CALLBACK: " << moveable << std::endl;
}

2nd callback

void Robot::robotPathCb(const fleet_msgs::msg::RobotPath &msg) {
std::cout << "Entered path callback" << std::endl;
for (int i = 0; i < msg.paths.size(); ++i)
{
    if (robotId == msg.paths[i].robotid)
    {
        robotPath = msg.paths[i];
        task = 1;
        robotInstructions();
        assigned = true;
        break;
    }
    else {
        task = 0;
        robotInstructions();
        robotStatus.robotid = robotId;
        robotStatus.orderid = -1;
        robotStatus.toteid = -1;
        robotStatus.state = state;
        robotStatPub->publish(robotStatus);
    }
}
robotMovement();
}

The robotMovement function is the one which makes the robot move. However when the code enters this function, I stop getting data on movementStatusCb. Can anyone please tell me how to solve this??

Thanks.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2022-08-09 19:10:49 -0500

ChuiV gravatar image

If theRobotMovement() method takes a long time to run, or it shouldn't be called multiple times concurrently, you may consider re-architecting this a bit in conjunction with a MultiThreaded executor, or a second Thread.

Instead of calling RobotMovement() inside your topic callback, you could put the data into a queue, and read that queue from a dedicated timer or thread. This way you've got the subscriptions getting handled by an executor, and the RobotMovement thread/timer can take as much time as it needs to push the robot through all the data in the queue without blocking the subscriptions.

If you use a timer for the RobotMovement, you'll need to put it in it's own callback group (type doesn't matter), and use a MultiThreaded Executor. In both cases, be sure to use mutexes to ensure that only one thread/callback is modifying the queue at a time.

edit flag offensive delete link more
0

answered 2022-07-21 14:16:15 -0500

Pepis gravatar image

What kind of executor are you using? If you are using the default rclcpp::spin() I think that uses a single threaded executor by default, which will call only one callback at a time. I would suggest trying a multithreaded executor, something like this:

rclcpp::executors::MultiThreadedExecutor executor;
executor.add_node(node);
executor.spin();

See the docs for more information

edit flag offensive delete link more

Comments

I tried this but it did not work for me:

rclcpp::init(argc, argv);
rclcpp::executors::MultiThreadedExecutor executor;
executor.add_node(std::make_shared<Robot>());
executor.spin();
rclcpp::shutdown();

When I did this, I wasn't getting any data in my callbacks.

cjoshi17 gravatar image cjoshi17  ( 2022-07-21 23:43:27 -0500 )edit

Hey, you are right. The default callback group for nodes is a mutually exclusive callback group, which as the docs state prevents callbacks from running concurrently. While keeping the multithreaded executor, try adding your subscriptions to a reentrant callback group. Inside your node's constructor:

auto my_callback_group = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant);
rclcpp::SubscriptionOptions options;
options.callback_group = my_callback_group;

my_sub1 = this->create_subscription<fleet_msgs::msg::MoveStatus>(/my_topic1, my_qos, std::bind(&Robot::moveStatusCb, this, _1), options);

my_sub2= this->create_subscription<fleet_msgs::msg::RobotPath>(/my_topic2, my_qos, std::bind(&Robot::robotPathCb, this, _1), options);
Pepis gravatar image Pepis  ( 2022-07-22 09:39:45 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2022-07-21 06:14:50 -0500

Seen: 1,094 times

Last updated: Aug 09 '22