在ros节点中,主函数中不能设置长时间的循环,否则会影响回调函数的执行
主函数如下
#include <iostream>
#include "senser_bridge.h"
#include "nav.h"
int main(int argc, char *argv[])
{
ros::init(argc,argv,"nav_test");
ROS_INFO("*******");
SenserBridge senser_bridge;
while(true){
cout << "主函数" <<endl;
sleep(1);
}
ros::spin();
}
SenserBridge类如下
SenserBridge::SenserBridge()
{
imu_sub_ = nh_.subscribe("/insprobe/imu0", 200, &SenserBridge::ImuDataCollect, this);
pose_pub_ = nh_.advertise<sensor_msgs::PointCloud2>("/pose",200);
}
//回调函数
void SenserBridge::ImuDataCollect(const sensor_msgs::Imu::ConstPtr &msg)
{
sensor_msgs::Imu imu_data;
imu_data = *msg;
imu_data_.push_back(imu_data);
UpdataImuNow();
cout << "***回调函数***"<<endl;
}
执行该节点则会出现如下问题:
[ INFO] [1576593799.328774366]: *******
Start time is 1575361874
主函数
主函数
主函数
主函数
主函数
主函数
主函数
主函数
....
如果将主函数中ros::spin()放到while循环前面,则会导致while()循环不执行,主函数代码修改如下:
#include "senser_bridge.h"
#include "nav.h"
int main(int argc, char *argv[])
{
ros::init(argc,argv,"nav_test");
ROS_INFO("*******");
SenserBridge senser_bridge;
ros::spin();//放到while()循环前面了
while(true){
cout << "主函数" <<endl;
sleep(1);
}
}
则输出结果只有回调函数中的值了
[ INFO] [1576594011.172570488]: *******
Start time is 1575361874
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
ps.在同一个节点中,ros::spin()相当于单线程的subcriber循环,所有的subcriber和对应的回调函数都在这个线程中循环执行,当subcriber接受的topic频率很高时,可能会出现上一个subcriber的回调函数还没执行完,下一个subcriber的msg就来的情况,造成阻塞。可能通过多线程方式避免这种情况。参考:http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning
https://blog.csdn.net/wengge987/article/details/50619851
http://m.blog.chinaunix.net/uid-27875-id-5817906.html
https://yuzhangbit.github.io/tools/several-ways-of-writing-a-ros-node/
使用boost::thread的C++多线程
#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include "senser_bridge.h"
#include "nav.h"
void A()
{
while(true)
{
sleep(1);
cout<< "线程函数" <<endl;
}
}
int main(int argc, char *argv[])
{
ros::init(argc,argv,"nav_test");
ROS_INFO("*******");
SenserBridge senser_bridge;
boost::thread server(A);//创建额外的线程,即可一起执行了
ros::spin();
}
结果如下
[ INFO] [1576674662.700959004]: *******
Start time is 1575361874
线程函数
线程函数
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
***回调函数***
线程函数
***回调函数***
可见在执行回调函数中也会有线程函数的执行,即可将回调函数获取的数据,放到线程函数中处理,而不用担心计算阻塞导致消息接收不到。
https://www.jianshu.com/p/5e394f6aa4dc
https://www.cnblogs.com/liaocheng/p/4978398.html
来源:CSDN
作者:文锦渡
链接:https://blog.csdn.net/mxdsdo09/article/details/103589134