39 #include <boost/thread.hpp> 41 #include <sensor_msgs/Image.h> 44 #include <sensor_msgs/PointField.h> 45 #include <nav_msgs/OccupancyGrid.h> 59 if(std::fabs(p1[0]-p2[0])<0.000001)
68 B_=(p2[1]-p1[1])/(p2[0]-p1[0]);
103 virtual void onInit();
107 void depthCb(
const sensor_msgs::ImageConstPtr& depth_msg,
108 const sensor_msgs::CameraInfoConstPtr& info_msg);
130 std::vector<double>
R_;
131 std::vector<double>
T_;
153 float center_x = model.
cx();
154 float center_y = model.
cy();
158 float constant_x = unit_scaling / model.
fx();
159 float constant_y = unit_scaling / model.
fy();
160 float bad_point = std::numeric_limits<float>::quiet_NaN();
165 const uint16_t* depth_row =
reinterpret_cast<const uint16_t*
>(&depth_msg->data[0]);
166 int row_step = depth_msg->step /
sizeof(uint16_t);
172 nnIdx =
new ANNidx[ANN_k_];
174 float resolution_square=resolution_*resolution_;
175 int index_temp1,index_temp2;
186 for (
int v = 0; v < (int)cloud_msg->height; ++v, depth_row += row_step)
188 for (
int u = 0; u < (int)cloud_msg->width; u+=2, ++iter_x, ++iter_y, ++iter_z)
190 uint16_t depth = depth_row[u];
195 if (range_max != 0.0)
201 *iter_x = *iter_y = *iter_z = bad_point;
207 x = (u - center_x) * depth * constant_x;
208 y = (v - center_y) * depth * constant_y;
211 *iter_x = R_[0]*x+R_[1]*y+R_[2]*z;
212 *iter_y = R_[3]*x+R_[4]*y+R_[5]*z;
213 *iter_z = R_[6]*x+R_[7]*y+R_[8]*z+kinectHeight_;
220 if(z< barHeight_max_)
222 if(z< barHeight_min_)
228 *iter_x = *iter_y = *iter_z = bad_point;
231 if(!((x<(gridHeight_+lowerLeftPos_[0]) &&x>lowerLeftPos_[0])&&(y<lowerLeftPos_[1] && y> -lowerLeftPos_[1])))
continue;
232 float_temp=(x-lowerLeftPos_[0])/resolution_;
233 x_num=
static_cast<int>(float_temp);
234 float_temp=y/resolution_+width_temp_;
235 y_num=
static_cast<int>(float_temp);
236 index_temp1=x_num+y_num*height_temp_;
237 if(mapGrid_[index_temp1]<0) mapGrid_[index_temp1]=0;
243 if(!((x<(gridHeight_+lowerLeftPos_[0]) &&x>lowerLeftPos_[0])&&(y<lowerLeftPos_[1] && y> -lowerLeftPos_[1])))
continue;
244 float_temp=(x-lowerLeftPos_[0])/resolution_;
245 x_num=
static_cast<int>(float_temp);
246 float_temp=y/resolution_+width_temp_;
247 y_num=
static_cast<int>(float_temp);
248 index_temp1=x_num+y_num*height_temp_;
249 mapGrid_[index_temp1]+=single_score_;
250 if(mapGrid_[index_temp1]>100) mapGrid_[index_temp1]=100;
273 for(std::vector<int>::iterator it = mustseenGrid_indexs_.begin() ; it !=mustseenGrid_indexs_.end() ; it++)
276 if(mapGrid_[index_temp1]<0)
278 filter_mapGrid_[index_temp1]-=1;
279 if(filter_mapGrid_[index_temp1]<-10) filter_mapGrid_[index_temp1]=-10;
283 filter_mapGrid_[index_temp1]+=1;
284 if(filter_mapGrid_[index_temp1]>0) filter_mapGrid_[index_temp1]=0;
286 if(filter_mapGrid_[index_temp1]<-9)
288 mapGrid_[index_temp1]=100;
292 std::vector<int> clearArea,barArea;
294 for(std::vector<int>::iterator it = seenGrid_indexs_.begin() ; it !=seenGrid_indexs_.end() ; it++)
297 if(mapGrid_[index_temp1]<bar_threshold_&&mapGrid_[index_temp1]>=0)
299 clearArea.push_back(index_temp2);
301 else if(mapGrid_[index_temp1]>=bar_threshold_)
303 barArea.push_back(index_temp2);
308 if(barArea.size()>1||(barArea.size()==1&&num_frame_%4==0))
312 barcloud_msg->header = depth_msg->header;
313 barcloud_msg->height = 1;
314 barcloud_msg->width = barArea.size();
315 barcloud_msg->is_dense =
true;
316 barcloud_msg->is_bigendian =
false;
317 barcloud_msg->header.frame_id=frame_id_;
323 for(std::vector<int>::iterator it = barArea.begin() ; it !=barArea.end() ; ++bariter_x, ++bariter_y,++bariter_z,it++)
326 PP=gridCenters_[index_temp1];
331 pub_barpoint_cloud_.publish(barcloud_msg);
353 if(clearArea.size()>0)
356 PointCloud::Ptr clearcloud_msg(
new PointCloud);
357 clearcloud_msg->header = depth_msg->header;
358 clearcloud_msg->height = 1;
359 clearcloud_msg->width = clearArea.size();
360 clearcloud_msg->is_dense =
true;
361 clearcloud_msg->is_bigendian =
false;
362 clearcloud_msg->header.frame_id=frame_id_;
368 for(std::vector<int>::iterator it = clearArea.begin() ; it !=clearArea.end() ; ++cleariter_x, ++cleariter_y,it++)
371 PP=gridCenters_[index_temp1];
374 *cleariter_z=mapGrid_[seenGrid_indexs_[index_temp1]];
376 pub_clearpoint_cloud_.publish(clearcloud_msg);
381 void OccupancyXyzNodelet::onInit()
388 private_nh.
getParam(
"lowerLeftPos", lowerLeftPos_);
391 private_nh.
param(
"resolution", resolution_, 0.1);
392 private_nh.
param(
"gridHeight", gridHeight_, 2.0);
393 private_nh.
param(
"usingWidth", usingWidth_, 0.3);
394 nh.
param(
"usingHeight_down",usingHeight_down_, 0.10);
395 nh.
param(
"usingHeight_up",usingHeight_up_, 0.25);
396 private_nh.
param(
"frame_id",frame_id_,std::string(
"kinect_link_new"));
397 private_nh.
param(
"kinectHeight", kinectHeight_, 0.3769);
398 private_nh.
param(
"barHeight_max", barHeight_max_, 0.50);
399 private_nh.
param(
"barHeight_min", barHeight_min_, 0.05);
400 private_nh.
param(
"point_mode", point_mode_, 0);
401 private_nh.
param(
"bar_threshold", bar_threshold_, 10.0);
402 private_nh.
param(
"single_score", single_score_, 2.0);
413 int width_temp,height_temp;
415 if(fmod(lowerLeftPos_[1],resolution_)>0.001)
417 width_temp=lowerLeftPos_[1]/resolution_+1;
421 width_temp=lowerLeftPos_[1]/resolution_;
423 if(fmod(gridHeight_,resolution_)>0.001)
425 height_temp=gridHeight_/resolution_+1;
429 height_temp=gridHeight_/resolution_;
431 width_temp =std::max(width_temp,1);
432 height_temp =std::max(height_temp,1);
433 mapGrid_=
new int8_t[2*height_temp*width_temp];
434 unkown_mapGrid_=
new int8_t[2*height_temp*width_temp];
435 filter_mapGrid_=
new int8_t[2*height_temp*width_temp];
438 double p1[2]={lowerLeftPos_[0],usingWidth_},p2[2]={lowerLeftPos_[0]+gridHeight_,lowerLeftPos_[1]};
439 double p3[2]={lowerLeftPos_[0],-usingWidth_},p4[2]={lowerLeftPos_[0]+gridHeight_,-lowerLeftPos_[1]};
444 double p[2]={0.0,0.0};
445 for(
int i=0;i<(2*height_temp*width_temp);i++)
448 unkown_mapGrid_[i]=-1;
449 filter_mapGrid_[i]=-1;
450 y_num=i/(height_temp);
451 x_num=i%(height_temp);
452 x=(x_num+0.5)*resolution_+lowerLeftPos_[0];
453 y=(-width_temp+y_num+0.5)*resolution_;
463 seenGrid_indexs_.push_back(i);
464 if(x<(usingHeight_up_+lowerLeftPos_[0]) && x>(usingHeight_down_+lowerLeftPos_[0]) ) mustseenGrid_indexs_.push_back(i);
468 ANN_num_=seenGrid_indexs_.size();
472 for(std::vector<int>::iterator it = seenGrid_indexs_.begin() ; it !=seenGrid_indexs_.end() ; it++)
475 pp=gridCenters_[num];
476 y_num=i/(height_temp);
477 x_num=i%(height_temp);
478 pp[0]=(x_num+0.5)*resolution_+lowerLeftPos_[0];
479 pp[1]=(-width_temp+y_num+0.5)*resolution_;
489 occupancygrid_msg_.info.resolution=resolution_;
490 occupancygrid_msg_.info.height=2*width_temp;
491 occupancygrid_msg_.info.width=height_temp;
492 occupancygrid_msg_.info.origin.position.x=lowerLeftPos_[0];
493 occupancygrid_msg_.info.origin.position.y=-width_temp*resolution_;
494 occupancygrid_msg_.info.origin.position.z=0;
497 height_temp_=height_temp;
498 width_temp_=width_temp;
500 boost::lock_guard<boost::mutex> lock(connect_mutex_);
502 pub_occupancy_grid_ = nh.
advertise<nav_msgs::OccupancyGrid>(
"occupancygrid", 1,connect_cb, connect_cb);
504 pub_clearpoint_cloud_ = nh.
advertise<
PointCloud>(
"clearpoints", 1, connect_cb, connect_cb);
510 void OccupancyXyzNodelet::connectCb()
512 boost::lock_guard<boost::mutex> lock(connect_mutex_);
513 if ((pub_point_cloud_.getNumSubscribers() == 0 )&& (pub_barpoint_cloud_.getNumSubscribers() ==0) && (pub_clearpoint_cloud_.getNumSubscribers() ==0) && (pub_occupancy_grid_.getNumSubscribers()==0))
515 sub_depth_.shutdown();
517 else if (!sub_depth_)
520 sub_depth_ = it_->subscribeCamera(
"image_rect", queue_size_, &OccupancyXyzNodelet::depthCb,
this, hints);
524 void OccupancyXyzNodelet::depthCb(
const sensor_msgs::ImageConstPtr& depth_msg,
525 const sensor_msgs::CameraInfoConstPtr& info_msg)
528 if (!ANN_ready_)
return;
530 cloud_msg->header = depth_msg->header;
531 cloud_msg->height = depth_msg->height;
532 cloud_msg->width = depth_msg->width;
533 cloud_msg->is_dense =
false;
534 cloud_msg->is_bigendian =
false;
535 cloud_msg->header.frame_id=frame_id_;
540 std::vector<int8_t> a(height_temp_*2*width_temp_,-1);
541 occupancygrid_msg_.data = a;
542 memcpy(mapGrid_,unkown_mapGrid_,
sizeof(int8_t)*(occupancygrid_msg_.info.height*occupancygrid_msg_.info.width));
544 model_.fromCameraInfo(info_msg);
546 if (depth_msg->encoding == enc::TYPE_16UC1)
548 this->convert2(depth_msg, cloud_msg, model_);
557 if((num_frame_%2==0))
563 occupancygrid_msg_.header = depth_msg->header;
564 occupancygrid_msg_.header.frame_id=frame_id_;
565 occupancygrid_msg_.info.map_load_time=current_time;
566 memcpy(&occupancygrid_msg_.data[0],mapGrid_,
sizeof(int8_t)*(occupancygrid_msg_.info.height*occupancygrid_msg_.info.width));
567 pub_point_cloud_.publish (cloud_msg);
568 pub_occupancy_grid_.publish(occupancygrid_msg_);
std::vector< int > seenGrid_indexs_
ros::Publisher pub_clearpoint_cloud_
boost::function< void(const SingleSubscriberPublisher &)> SubscriberStatusCallback
image_transport::CameraSubscriber sub_depth_
ros::Publisher pub_occupancy_grid_
std::vector< double > lowerLeftPos_
#define NODELET_ERROR_THROTTLE(rate,...)
PLUGINLIB_EXPORT_CLASS(xiaoqiang_depth_image_proc::OccupancyXyzNodelet, nodelet::Nodelet)
image_geometry::PinholeCameraModel model_
DLL_API ANNpointArray annAllocPts(int n, int dim)
ros::Publisher pub_point_cloud_
LineFunc(double p1[], double p2[])
sensor_msgs::PointCloud2 PointCloud
ros::Publisher pub_barpoint_cloud_
boost::shared_ptr< image_transport::ImageTransport > it_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
nav_msgs::OccupancyGrid occupancygrid_msg_
ANNpointArray gridCenters_
DLL_API ANNpoint annAllocPt(int dim, ANNcoord c=0)
bool getParam(const std::string &key, std::string &s) const
boost::mutex connect_mutex_
void setPointCloud2FieldsByString(int n_fields,...)
std::vector< int > mustseenGrid_indexs_
double getPointPos(double p[])