grapher_node.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #include "scanGrapher.h"
  2. #include <ros/ros.h>
  3. #include <sensor_msgs/PointCloud2.h>
  4. #include <sensor_msgs/LaserScan.h>
  5. #include <nav_msgs/OccupancyGrid.h>
  6. #include <tf/transform_datatypes.h>
  7. #include <tf/transform_broadcaster.h>
  8. #include <pcl/common/transforms.h>
  9. #include <pcl_conversions/pcl_conversions.h>
  10. #include <pcl/io/pcd_io.h>
  11. #include <boost/thread.hpp>
  12. ////// thread_queue
  13. #include "./TaskQueue/TaskPool.h"
  14. #include "./TaskQueue/TQFactory.h"
  15. #include "locateTask.h"
  16. #include <cstdio>
  17. #include <thread>
  18. using namespace tq;
  19. #include <chrono>
  20. #undef max()
  21. #undef min()
  22. #include "kalmanFilter.h"
  23. #include "cfg/grapher_cfg.pb.h"
  24. #include "cfg/protobuf_io.h"
  25. grapher::grapherCfg grapher_config;
  26. ros::Publisher pubCloudL;
  27. ros::Publisher pubCloudG;
  28. ros::Publisher grid_pub;
  29. pcl::PointXYZ minp=pcl::PointXYZ(-10.0,-10.0,0);
  30. pcl::PointXYZ maxp=pcl::PointXYZ(10.0,10.0,0);
  31. double resolution=0.01;
  32. ScanGrapher* pGrapher=new ScanGrapher(minp,maxp,resolution);
  33. KalmanFilter klmFilter;
  34. pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud (new pcl::PointCloud<pcl::PointXYZ>);
  35. /* void laserScanToLDP(const sensor_msgs::LaserScan::ConstPtr& scan_msg,LDP& ldp)
  36. {
  37. unsigned int n = scan_msg->ranges.size();
  38. ldp = ld_alloc_new(n);
  39. for (unsigned int i = 0; i < n; i++)
  40. {
  41. // calculate position in laser frame
  42. double r = scan_msg->ranges[i];
  43. if (r > scan_msg->range_min && r < scan_msg->range_max)
  44. {
  45. // fill in laser scan data
  46. ldp->valid[i] = 1;
  47. ldp->readings[i] = r;
  48. }
  49. else
  50. {
  51. ldp->valid[i] = 0;
  52. ldp->readings[i] = -1; // for invalid range
  53. }
  54. ldp->theta[i] = scan_msg->angle_min + i * scan_msg->angle_increment;
  55. ldp->cluster[i] = -1;
  56. }
  57. ldp->min_theta = ldp->theta[0];
  58. ldp->max_theta = ldp->theta[n-1];
  59. ldp->odometry[0] = 0.0;
  60. ldp->odometry[1] = 0.0;
  61. ldp->odometry[2] = 0.0;
  62. ldp->true_pose[0] = 0.0;
  63. ldp->true_pose[1] = 0.0;
  64. ldp->true_pose[2] = 0.0;
  65. }*/
  66. pcl::PointCloud<pcl::PointXYZ>::Ptr transformCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr input,tf::Pose pose)
  67. {
  68. Eigen::Matrix4f transform=TFToEigen(pose);
  69. pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
  70. pcl::transformPointCloud (*input, *transformed_cloud, transform);
  71. return transformed_cloud;
  72. }
  73. void scanHandler(const sensor_msgs::LaserScan::ConstPtr& msg)
  74. {
  75. static int systemInitCount=0;
  76. static bool systemInited=false;
  77. int systemDelay=20;
  78. if (!systemInited)
  79. {//丢弃前20个点云数据
  80. systemInitCount++;
  81. if (systemInitCount >= systemDelay) {
  82. systemInited = true;
  83. }
  84. return;
  85. }
  86. //当前点云时间
  87. double timeScanCur = msg->header.stamp.toSec();
  88. int N = int( (msg->angle_max-msg->angle_min)/msg->angle_increment )+1;
  89. pcl::PointCloud<pcl::PointXYZ> laserCloud1;
  90. for(int i=0;i<N;++i)
  91. {
  92. float distance = msg->ranges[i];
  93. float angle = msg->angle_min+ i*msg->angle_increment;
  94. if(distance >20.0)
  95. continue;
  96. //第一帧 用作 target 使用所有点,非第一帧只保留前方一半点
  97. pcl::PointXYZ point ;
  98. point.x= -sin(angle-M_PI_2)*distance;
  99. point.y= cos(angle-M_PI_2)*distance;
  100. point.z=0;
  101. if(fabs(point.x)>1.0 || fabs(point.y)>1.0)
  102. {
  103. laserCloud1.points.push_back(point);
  104. }
  105. }
  106. if(laserCloud1.size()<10)
  107. return ;
  108. if(systemInitCount<systemDelay+20)
  109. {
  110. pGrapher->pushScan(laserCloud1.makeShared(),pcl::PointXYZ(0,0,0));
  111. systemInitCount++;
  112. return ;
  113. }
  114. static bool first_frame=true;
  115. if(first_frame==true)
  116. {
  117. pGrapher->getCloud(*target_cloud);
  118. if(target_cloud->size()==0)
  119. {
  120. return ;
  121. }
  122. first_frame=false;
  123. }
  124. static tf::Pose init_pose=tf::Pose::getIdentity();
  125. //线程队列
  126. IQueue* q = TQFactory::CreateDefaultQueue();
  127. q->Start(grapher_config.grapher_functions_size());
  128. std::vector<LocateTask*> pTasks;
  129. for(int i=0;i<grapher_config.grapher_functions_size();++i)
  130. {
  131. LocateTask* pTask=0;
  132. if(grapher_config.grapher_functions(i).type()=="ndt")
  133. pTask=new NdtTask(laserCloud1.makeShared(),target_cloud,init_pose); // ndt 算法
  134. else if(grapher_config.grapher_functions(i).type()=="icp")
  135. pTask=new IcpTask(laserCloud1.makeShared(),target_cloud,init_pose); // icp 算法
  136. else continue;
  137. pTasks.push_back(pTask);
  138. q->AddTask(pTask);
  139. }
  140. q->WaitForFinish();
  141. //获取结果,发布tf
  142. static tf::TransformBroadcaster tfBroadcaster;
  143. std::vector<tf::Pose> poses;
  144. tf::Pose lastPose=tf::Pose::getIdentity();
  145. for(int i=0;i<grapher_config.grapher_functions_size();++i)
  146. {
  147. LocateTask* pTask=pTasks[i];
  148. tf::Pose pose;
  149. if(pTask->GetResult(pose))
  150. {
  151. lastPose=pose;
  152. poses.push_back(pose);
  153. std::string header_id=grapher_config.grapher_functions(i).tfheaderid();
  154. std::string frame_id=grapher_config.grapher_functions(i).tfid();
  155. tf::StampedTransform laserOdometryTrans;
  156. laserOdometryTrans.frame_id_ = header_id;
  157. laserOdometryTrans.child_frame_id_ = frame_id;
  158. laserOdometryTrans.stamp_ = ros::Time::now();
  159. laserOdometryTrans.setRotation(pose.getRotation());
  160. laserOdometryTrans.setOrigin(pose.getOrigin());
  161. tfBroadcaster.sendTransform(laserOdometryTrans);
  162. }
  163. //析构
  164. delete pTask;
  165. }
  166. TQFactory::ReleaseQueue(q);
  167. //滤波
  168. if(poses.size()==2)
  169. lastPose=klmFilter.filter(poses[0],poses[1]);
  170. // lastPose = poses[0];
  171. tf::StampedTransform laserOdometryTrans;
  172. laserOdometryTrans.frame_id_ = "/map";
  173. laserOdometryTrans.child_frame_id_ = "/laser";
  174. laserOdometryTrans.stamp_ =ros::Time::now();
  175. laserOdometryTrans.setRotation(lastPose.getRotation());
  176. laserOdometryTrans.setOrigin(lastPose.getOrigin());
  177. tfBroadcaster.sendTransform(laserOdometryTrans);
  178. ///变换点云
  179. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_T=transformCloud(laserCloud1.makeShared(),lastPose);
  180. pGrapher->pushScan(cloud_T,pcl::PointXYZ(lastPose.getOrigin().x(),lastPose.getOrigin().y(),0));
  181. init_pose=lastPose;
  182. sensor_msgs::PointCloud2 cloudLocalMsg;
  183. pcl::toROSMsg(*cloud_T, cloudLocalMsg);
  184. cloudLocalMsg.header.stamp = msg->header.stamp;
  185. cloudLocalMsg.header.frame_id = "/map";
  186. pubCloudL.publish(cloudLocalMsg);
  187. }
  188. void transforMatToGrid(cv::Mat& image,nav_msgs::OccupancyGrid& map)
  189. {
  190. map.header.frame_id="map";
  191. map.header.stamp = ros::Time::now();
  192. map.info.resolution = pGrapher->resolution_; // float32
  193. map.info.width = image.cols; // uint32
  194. map.info.height = image.rows; // uint32
  195. map.info.origin.position.x=-image.cols*pGrapher->resolution_/2.0;
  196. map.info.origin.position.y=-image.rows*pGrapher->resolution_/2.0;
  197. static signed char* pdata=0;
  198. if(pdata!=0) free(pdata);
  199. pdata=(signed char*)malloc(image.cols*image.rows*sizeof(signed char));
  200. for(int i=0;i<image.rows;++i)
  201. {
  202. for(int j=0;j<image.cols;++j)
  203. {
  204. if(image.at<uchar>(i,j)==0)
  205. pdata[i*image.cols+j]=-1;
  206. else if(image.at<uchar>(i,j)<10)
  207. pdata[i*image.cols+j]=0;
  208. else
  209. pdata[i*image.cols+j]=int(double(image.at<uchar>(i,j))*(100./255.0));
  210. }
  211. }
  212. map.data = std::vector<signed char>(pdata,pdata+image.cols*image.rows);
  213. }
  214. void publish()
  215. {
  216. ros::Rate loop_rate(10);
  217. int last_cloud_size=-1;
  218. while(ros::ok())
  219. {
  220. cv::Mat grid=pGrapher->getGrid();
  221. nav_msgs::OccupancyGrid map;
  222. transforMatToGrid(grid,map);
  223. grid_pub.publish(map);
  224. ///发布地图点云
  225. /*pcl::PointCloud<pcl::PointXYZ>::Ptr cloud=pGrapher->getCloud();
  226. if(cloud->size()>0)
  227. {
  228. sensor_msgs::PointCloud2 cloudglobalMsg;
  229. pcl::toROSMsg(*cloud, cloudglobalMsg);
  230. cloudglobalMsg.header.stamp = ros::Time::now();
  231. cloudglobalMsg.header.frame_id = "/map";
  232. pubCloudG.publish(cloudglobalMsg);
  233. }*/
  234. ros::spinOnce();
  235. loop_rate.sleep();
  236. }
  237. }
  238. //#include <stdio.h>
  239. int main(int argc, char** argv)
  240. {
  241. // if(false==ReadProtoConfig("/home/zx/zzw/catkin_ws/src/grapher/grapher.cfg",grapher_config))
  242. if(false==ReadProtoConfig("/home/youchen/Documents/git_ws/src/grapher/grapher.cfg",grapher_config))
  243. {
  244. printf(" config file load failed ... \n");
  245. return -1;
  246. }
  247. ros::init(argc, argv, "grapher_node");
  248. ros::NodeHandle nh;
  249. pubCloudL = nh.advertise<sensor_msgs::PointCloud2>
  250. ("/cloud_local", 2);
  251. pubCloudG = nh.advertise<sensor_msgs::PointCloud2>
  252. ("/cloud_global", 2);
  253. grid_pub=nh.advertise<nav_msgs::OccupancyGrid>("/grid",1);
  254. //pcl::io::loadPCDFile("/home/zx/zzw/ws/src/grapher/map.pcd", *target_cloud);
  255. //std::cout<<" target cloud size :"<<target_cloud->size()<<std::endl;
  256. boost::thread* thread_=new boost::thread(publish);
  257. std::string scanID=grapher_config.scanid();
  258. ros::Subscriber subLaserCloud = nh.subscribe<sensor_msgs::LaserScan>(scanID, 2,scanHandler);
  259. ros::spin();
  260. // pGrapher->saveImage("/home/zx/zzw/map.bmp");
  261. // pGrapher->saveCloudTxt("/home/zx/zzw/map.txt");
  262. // pGrapher->saveCloudPcd("/home/zx/zzw/map.pcd");
  263. pGrapher->saveImage("/home/youchen/Documents/git_ws/src/grapher/map.bmp");
  264. pGrapher->saveCloudTxt("/home/youchen/Documents/git_ws/src/grapher/map.txt");
  265. pGrapher->saveCloudPcd("/home/youchen/Documents/git_ws/src/grapher/map.pcd");
  266. delete pGrapher;
  267. return 0;
  268. }