2017-02-15 86 views
1

我在嘗試在Indigo中創建訂戶時遇到問題。我有一個類中的shared_ptr來容納NodeHandle對象。我這樣做是爲了讓NodeHandle可以用於其他類的成員。問題是線程啓動時,它似乎掛在MyClass構造函數中的NodeHandle對象的make_shared調用上,因爲它從未到達下一行。爲什麼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() 
{ 
    // ... 
} 

我啓動線程鏈接纔可所以......

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

的思考?

回答

0

看來,這個問題是由於已具備了我自己的提升測井系統不使用ROS記錄器(這使得它很難找到,因爲它看似無關具有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

嗯,它應該按照[這個](http://docs.ros.org/api/roscpp/html/namespaceros.html#a61a193529a9aad90ddace7724c7fc759)... – Vtik