Publish messages immediately within a subscribe callback?
What's the cleanest way to publish a message immediately, without triggering any subscriber callbacks? I would expect calling ros::spinOnce() inside a callback to (potentially) result in stack overflow as the callback calls itself.
Use case: I am trying to make heartbeat function that "just works" in callbacks and such. Here is a broken initial design:
class Heart {
private:
ros::NodeHandle nh;
std::unordered_map<std::string, ros::Publisher> publishers;
const char* file_;
public:
Heart(const char* file) {
file_ = file;
}
void beat(int line) {
string keystring = std::string("heartbeat_") + file_ + "_" + std::to_string(line);
std::replace(keystring.begin(), keystring.end(),'.', '_');
auto resultpair = publishers.find(keystring);
if (resultpair == publishers.end())
{
publishers[keystring] = nh.advertise<std_msgs::Empty>(keystring, 1);
}
publishers[keystring].publish(std_msgs::Empty());
ros::spinOnce();
};
};
Heart heart(__FILE__);
heart.beat(__LINE__);
The idea is that you spray a bunch of:
heart.beat(__LINE__);
all over your code, record with:
rosbag record --regex "/heartbeat_(.*)" -O heartbeats.bag
And look at the gloriously clearly sorted lines in:
rqt_bag heartbeats.bag
It is broken in the sense that spinOnce() isn't enough to result in even remotely reliable timings.