2015-08-04 5 views
1

Я использую ROS в своем проекте, и мне нужно время от времени отправлять сообщение. У меня есть эта функция:Сообщение 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() 

Слушатель нить в питона. Я получаю функцию sendMessage (я вижу в терминале «Сообщение отправлено» много раз), но я не вижу, что скрипт python получает сообщение.

Обновление: я проверил обратный вызов python с rostopic pub /FirstTaskFilter std_msgs/String "test", и это работает отлично.

Любые мысли?

ответ

1

Вы повторно рекламируете издателя каждый раз, а затем немедленно используете его для публикации.
Это проблематично, так как для подписчиков требуется некоторое время подписываться на новых издателей. Если вы публикуете сообщения до того, как абонент завершит это, эти сообщения не поступят.

Чтобы избежать этой проблемы, не рекламируйте нового издателя каждый раз, но делайте это только один раз в конструкторе своего класса и храните издателя в переменной-члене. Ваш код может выглядеть примерно так:

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 убеждается, что все существующие абоненты могут подписаться, прежде чем начать публикацию сообщений. Это необходимо, только если важно, чтобы ни одно сообщение не потерялось. В большинстве практических случаев его можно опустить.

+0

Это все. Благодаря! – Javi

 Смежные вопросы

  • Нет связанных вопросов^_^