最初是想实现接收到某个some_topic然后解析内容,若是内容为指令action,action函数进入for循环,若是再接收到some_topic,里面指令为stop则stop=true停止正在进行的action,跳出for循环(想用外部变量控制for循环的结束).
类似: ros::NodeHandle n;
ros::Subscriber sub = nh.subscribe(."some_topic",actionCallback..);
.
.
.
void actionCallback(..)
{
ROS_INFO("RECEVIED");
if(command = "action")
{
action(3);
....
}
else if(command = "stop")
{
stop = true;
}
}
void action(int received)
{
for(int i=0; i<5;i++)
{
for(int j=0; j<4;j++)
{
std::cout<<received*i*j<<std::cout;
....
if(stop)
{
break;//跳出第一层循环
}
}
if(stop)
{
ROS_INFO("stop");
break;//跳出第二层循环
}
ros::Duration(0.2).sleep();
}
stop = false;
}
然而不论stop为什么变量,总会发现,进入for循环之后,若是循环没有完成,即action没有返回值.是不是接收下一个消息的,从ROS_INFO的时间戳可以看出.
第二次打印的时间戳总是接着第一个时间戳,也就是说,若第一个消息是action,第二个是stop,第三个是action,那么第一action循环会完整执行一遍,第三个action的for循环一遍都不会执行.因此一个线程是完成不了stop想要的功能,因此想到一个方法,专门为stop开辟一个线程,用一个some_stop_topic,那么就有两个线程.
ros::NodeHandle n;
ros::Subscriber action_sub = n.subscribe(..."some_topic",actionCallback. ...);
ros::Subscriber stop_action_sub = .subscribe(... "some_stop_topic",actionStopCallback....);
ros::spin();
此时同样进行测试,发现仍然没有实现想要的功能,最后发现 ros::spin()还只是开辟了一个线程,我原本以为每一个callback均为一个线程,至今才恍然大悟.
参考文献[1],发现此方法可以实线此功能:
ros::NodeHandle n;
ros::Subscriber action_sub = n.subscribe(..."some_topic",actionCallback. ...);
ros::Subscriber stop_action_sub = .subscribe(... "some_stop_topic",actionStopCallback....);
ros::MultiThreadedSpinner spinner(2); // Use 2 threads
spinner.spin(); // spin() will not return until the node has been shutdown
用MultiThreadedSpinner说明此节点有两个线程,也可用(boost::thread),最后堪堪实现了所需功能,但是由于for循环速度较快,而且没有用lock,每次同样时间发送的stop,退出for循环的层次不一样,因此还需好好思考.
[1] http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning
若各位有好的方法解决我的问题,请不吝赐教.相互交流,非常感谢!
欢迎大家批评,指正,交流!
联系方式:
emai: tongzhuodenilove@163.com