ros(robot operation system机器人操作系统)订阅函数的多线程使用方法(C++: 外部变量统制跳出for循环)

ros(robot operation system机器人操作系统)订阅函数的多线程使用方法(C++: 外部变量控制跳出for循环)

     

最初是想实现接收到某个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


若各位有好的方法解决我的问题,请不吝赐教.相互交流,非常感谢!