2017-02-15 6 views
1

У меня проблема с созданием подписчика в Индиго. У меня есть shared_ptr внутри класса, чтобы удерживать объект NodeHandle. Я делаю это так, чтобы NodeHandle можно было использовать в других классах. Проблема заключается в том, когда начинается поток, он, похоже, зависает при вызове make_shared с объектом NodeHandle внутри конструктора MyClass, поскольку он никогда не достигает следующей строки после.Почему NodeHandle висит?

class MyClass 
{ 
    private: 
     std::shared_ptr<ros::NodeHandle> nh; 
     std::map<std::string, std::string> remap; 
    // ... 
}; 

MyClass::MyClass() 
{ 
    // remap is empty 
    ros::init(remap, "my_node"); 

    nh = make_shared<ros::NodeHandle>(); 

    cout << "does not reach this line" << endl; 
} 

int MyClass::run() 
{ 
    // ... 
} 

я начинаю нить Liks так ...

{ 
    // ... 
    myobj = make_shared<MyClass>(); 
    my_thread = thread(&MyClass::run, myobj); 
    // ... 
} 

Мысли?

ответ

0

Похоже, что проблема была из-за наличия моей собственной системы наддува протоколирования на месте, а не с помощью регистратора ROS (который сделал его трудно найти, как это, казалось бы, не имеет ничего общего с РОС :: NodeHandle, но, вероятно, делает это внизу). Я бы прокомментировал всю свою базу кода и начал добавлять, чтобы увидеть, когда будет запускаться ros :: NodeHandle, и в момент удаления моего регистратора и добавления его обратно я увижу разницу между его запуском и зависанием.

0

Ну, вот пример использования Boost :: make_shared для дескриптора узла. Обратите внимание, что он использует ros::NodeHandlePtr, уже существующий общий указатель Boost, не использующий «std :: make_shared».

Возможно, это действительно не отвечает на вопрос, но я предлагаю другой способ использования библиотеки boost.

#include <ros/ros.h> 
#include <std_msgs/Empty.h> 
#include <boost/thread/thread.hpp> 

void do_stuff(int* publish_rate) 
{ 
    ros::NodeHandlePtr node = boost::make_shared<ros::NodeHandle>(); 
    ros::Publisher pub_b = node->advertise<std_msgs::Empty>("topic_b", 10); 

    ros::Rate loop_rate(*publish_rate); 
    while (ros::ok()) 
    { 
    std_msgs::Empty msg; 
    pub_b.publish(msg); 
    loop_rate.sleep(); 
    } 
} 

int main(int argc, char** argv) 
{ 
    int rate_b = 1; // 1 Hz 

    ros::init(argc, argv, "mt_node"); 

    // spawn another thread 
    boost::thread thread_b(do_stuff, &rate_b); 

    ros::NodeHandlePtr node = boost::make_shared<ros::NodeHandle>(); 
    ros::Publisher pub_a = node->advertise<std_msgs::Empty>("topic_a", 10); 

    ros::Rate loop_rate(10); // 10 Hz 
    while (ros::ok()) 
    { 
    std_msgs::Empty msg; 
    pub_a.publish(msg); 
    loop_rate.sleep(); 

    // process any incoming messages in this thread 
    ros::spinOnce(); 
    } 

    // wait the second thread to finish 
    thread_b.join(); 

    return 0; 
} 

В случае, если вы получите проблемы с CMakeLists, вот оно:

cmake_minimum_required(VERSION 2.8.3) 
project(test_thread) 

find_package(catkin REQUIRED COMPONENTS 
    roscpp 
    rospy 
) 

find_package(Boost COMPONENTS thread REQUIRED) 
include_directories(${Boost_INCLUDE_DIR}) 

catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs) 
include_directories(include ${catkin_INCLUDE_DIRS}) 

add_executable(thread src/thread_test.cpp) 
target_link_libraries(thread ${catkin_LIBRARIES} ${BOOST_LIBRARIES}) 

Надежда, что помогает!

Приветствия,

+0

Я сделал то, что вы сделали, тогда я еще больше упростил свою проблему, поставив ros :: init внутри main, а затем создав экземпляр NodeHandle, а затем подписался, и он все еще зависает (на этот раз не задействованы нити). Вы видите что-то не так с тем, как я использую ros :: init() и пустую карту передается? – Ender

+0

hmmm, он должен работать согласно [this] (http://docs.ros.org/api/roscpp/html/namespaceros.html#a61a193529a9aad90ddace7724c7fc759) ... – Vtik

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