我在项目中使用ROS,并且需要不时发送一条消息。我有这个功能:
void RosNetwork::sendMessage(string msg, string channel) {
_mtx.lock();
ros::Publisher chatter_pub = _n.advertise<std_msgs::String>(channel.c_str(),10);
ros::Rate loop_rate(10);
std_msgs::String msgToSend;
msgToSend.data = msg.c_str();
chatter_pub.publish(msgToSend);
loop_rate.sleep();
cout << "Message Sent" << endl;
_mtx.unlock();
}
而且我在python中有这个:
def callbackFirst(data):
#rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
print("Received message from first filter")
def callbackSecond(data):
#rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
print("Received message from second filter")
def listener():
rospy.Subscriber("FirstTaskFilter", String, callbackFirst)
print("subscribed to FirstTaskFilter")
rospy.Subscriber("SecondTaskFilter", String, callbackSecond)
print("subscribed to SecondTaskFilter")
rospy.spin()
侦听器是python中的线程。我使用了函数sendMessage
(我在终端“ Message Sent”中看到了很多次),但是我没有看到python脚本接收到该消息。
更新:我用rostopic pub /FirstTaskFilter std_msgs/String "test"
测试了python回调,并且运行良好。
任何想法?
您每次都在重新发布发布者,然后立即使用它发布某些内容。这是有问题的,因为订阅者需要一些时间来订阅新兴出版者。如果您在订阅者完成此操作之前发布消息,则这些消息将不会到达。
为了避免此问题,请不要每次都通告一个新的发布者,而只能在您的类的构造函数中发布一次,并将该发布者存储在一个成员变量中。您的代码可能看起来像这样:
RosNetwork() {
_chatter_pub = _n.advertise<std_msgs::String>(channel.c_str(),10);
ros::Duration(1).sleep(); // optional, to make sure no message gets lost
}
void RosNetwork::sendMessage(string msg, string channel) {
...
_chatter_pub.publish(msgToSend);
...
}
advertise
之后一秒钟的睡眠确保在开始发布消息之前,所有现有订户都可以订阅。仅在不丢失任何一条消息很重要的情况下,才有必要。在大多数实际情况下,可以将其省略。
解决您问题的正确方法是使用pub.getNumSubscribers()并等待,直到>0。然后发布。