Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <leg_detector/laser_processor.h>
00036
00037 #include <stdexcept>
00038
00039 using namespace ros;
00040 using namespace std;
00041 using namespace laser_processor;
00042
00043 Sample* Sample::Extract(int ind, const sensor_msgs::LaserScan& scan)
00044 {
00045 Sample* s = new Sample();
00046
00047 s->index = ind;
00048 s->range = scan.ranges[ind];
00049 s->x = cos(scan.angle_min + ind * scan.angle_increment) * s->range;
00050 s->y = sin(scan.angle_min + ind * scan.angle_increment) * s->range;
00051 if (s->range > scan.range_min && s->range < scan.range_max)
00052 return s;
00053 else
00054 {
00055 delete s;
00056 return NULL;
00057 }
00058 }
00059
00060 void SampleSet::clear()
00061 {
00062 for (SampleSet::iterator i = begin();
00063 i != end();
00064 i++)
00065 {
00066 delete(*i);
00067 }
00068 set<Sample*, CompareSample>::clear();
00069 }
00070
00071 void SampleSet::appendToCloud(sensor_msgs::PointCloud& cloud, int r, int g, int b)
00072 {
00073 float color_val = 0;
00074
00075 int rgb = (r << 16) | (g << 8) | b;
00076 color_val = *(float*) & (rgb);
00077
00078 for (iterator sample_iter = begin();
00079 sample_iter != end();
00080 sample_iter++)
00081 {
00082 geometry_msgs::Point32 point;
00083 point.x = (*sample_iter)->x;
00084 point.y = (*sample_iter)->y;
00085 point.z = 0;
00086
00087 cloud.points.push_back(point);
00088
00089 if (cloud.channels[0].name == "rgb")
00090 cloud.channels[0].values.push_back(color_val);
00091 }
00092 }
00093
00094 tf::Point SampleSet::center()
00095 {
00096 float x_mean = 0.0;
00097 float y_mean = 0.0;
00098 for (iterator i = begin();
00099 i != end();
00100 i++)
00101
00102 {
00103 x_mean += ((*i)->x) / size();
00104 y_mean += ((*i)->y) / size();
00105 }
00106
00107 return tf::Point(x_mean, y_mean, 0.0);
00108 }
00109
00110
00111 void ScanMask::addScan(sensor_msgs::LaserScan& scan)
00112 {
00113 if (!filled)
00114 {
00115 angle_min = scan.angle_min;
00116 angle_max = scan.angle_max;
00117 size = scan.ranges.size();
00118 filled = true;
00119 }
00120 else if (angle_min != scan.angle_min ||
00121 angle_max != scan.angle_max ||
00122 size != scan.ranges.size())
00123 {
00124 throw std::runtime_error("laser_scan::ScanMask::addScan: inconsistantly sized scans added to mask");
00125 }
00126
00127 for (uint32_t i = 0; i < scan.ranges.size(); i++)
00128 {
00129 Sample* s = Sample::Extract(i, scan);
00130
00131 if (s != NULL)
00132 {
00133 SampleSet::iterator m = mask_.find(s);
00134
00135 if (m != mask_.end())
00136 {
00137 if ((*m)->range > s->range)
00138 {
00139 delete(*m);
00140 mask_.erase(m);
00141 mask_.insert(s);
00142 }
00143 else
00144 {
00145 delete s;
00146 }
00147 }
00148 else
00149 {
00150 mask_.insert(s);
00151 }
00152 }
00153 }
00154 }
00155
00156
00157 bool ScanMask::hasSample(Sample* s, float thresh)
00158 {
00159 if (s != NULL)
00160 {
00161 SampleSet::iterator m = mask_.find(s);
00162 if (m != mask_.end())
00163 if (((*m)->range - thresh) < s->range)
00164 return true;
00165 }
00166 return false;
00167 }
00168
00169
00170
00171 ScanProcessor::ScanProcessor(const sensor_msgs::LaserScan& scan, ScanMask& mask_, float mask_threshold)
00172 {
00173 scan_ = scan;
00174
00175 SampleSet* cluster = new SampleSet;
00176
00177 for (uint32_t i = 0; i < scan.ranges.size(); i++)
00178 {
00179 Sample* s = Sample::Extract(i, scan);
00180
00181 if (s != NULL)
00182 {
00183 if (!mask_.hasSample(s, mask_threshold))
00184 {
00185 cluster->insert(s);
00186 }
00187 else
00188 {
00189 delete s;
00190 }
00191 }
00192 }
00193
00194 clusters_.push_back(cluster);
00195
00196 }
00197
00198 ScanProcessor::~ScanProcessor()
00199 {
00200 for (list<SampleSet*>::iterator c = clusters_.begin();
00201 c != clusters_.end();
00202 c++)
00203 delete(*c);
00204 }
00205
00206 void
00207 ScanProcessor::removeLessThan(uint32_t num)
00208 {
00209 list<SampleSet*>::iterator c_iter = clusters_.begin();
00210 while (c_iter != clusters_.end())
00211 {
00212 if ((*c_iter)->size() < num)
00213 {
00214 delete(*c_iter);
00215 clusters_.erase(c_iter++);
00216 }
00217 else
00218 {
00219 ++c_iter;
00220 }
00221 }
00222 }
00223
00224
00225 void
00226 ScanProcessor::splitConnected(float thresh)
00227 {
00228 list<SampleSet*> tmp_clusters;
00229
00230 list<SampleSet*>::iterator c_iter = clusters_.begin();
00231
00232
00233 while (c_iter != clusters_.end())
00234 {
00235
00236 while ((*c_iter)->size() > 0)
00237 {
00238
00239 SampleSet::iterator s_first = (*c_iter)->begin();
00240
00241
00242 list<Sample*> sample_queue;
00243 sample_queue.push_back(*s_first);
00244
00245 (*c_iter)->erase(s_first);
00246
00247
00248 list<Sample*>::iterator s_q = sample_queue.begin();
00249 while (s_q != sample_queue.end())
00250 {
00251 int expand = (int)(asin(thresh / (*s_q)->range) / std::abs(scan_.angle_increment));
00252
00253 SampleSet::iterator s_rest = (*c_iter)->begin();
00254
00255 while ((s_rest != (*c_iter)->end() &&
00256 (*s_rest)->index < (*s_q)->index + expand))
00257 {
00258 if ((*s_rest)->range - (*s_q)->range > thresh)
00259 {
00260 break;
00261 }
00262 else if (sqrt(pow((*s_q)->x - (*s_rest)->x, 2.0f) + pow((*s_q)->y - (*s_rest)->y, 2.0f)) < thresh)
00263 {
00264 sample_queue.push_back(*s_rest);
00265 (*c_iter)->erase(s_rest++);
00266 break;
00267 }
00268 else
00269 {
00270 ++s_rest;
00271 }
00272 }
00273 s_q++;
00274 }
00275
00276
00277 SampleSet* c = new SampleSet;
00278 for (s_q = sample_queue.begin(); s_q != sample_queue.end(); s_q++)
00279 c->insert(*s_q);
00280
00281
00282 tmp_clusters.push_back(c);
00283 }
00284
00285
00286 delete(*c_iter);
00287
00288
00289 clusters_.erase(c_iter++);
00290 }
00291
00292 clusters_.insert(clusters_.begin(), tmp_clusters.begin(), tmp_clusters.end());
00293 }