00001 #include "BetaGrid.h"
00002
00003 #include <sstream>
00004 #include <cstdio>
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007
00008
00009 BetaGridGenerator::BetaGridGenerator(double minRho, double maxRho, unsigned int binRho, unsigned int binPhi)
00010 {
00011 setEdges(minRho, maxRho, binRho, binPhi);
00012 }
00013
00014 BetaGridGenerator::BetaGridGenerator(const std::vector<double>& rhoEdges, const std::vector<double>& phiEdges):
00015 m_rhoEdges(rhoEdges),
00016 m_phiEdges(phiEdges)
00017 {
00018
00019 }
00020
00021 void BetaGridGenerator::setEdges(double minRho, double maxRho, unsigned int binRho, unsigned int binPhi){
00022 m_rhoEdges.resize(binRho+1);
00023 m_phiEdges.resize(binPhi+1);
00024 double minPhi = -M_PI, maxPhi = M_PI;
00025 for(unsigned int i = 0; i <= binRho; i++){
00026 m_rhoEdges[i] = minRho + double(i)*(maxRho - minRho)/double(binRho);
00027 }
00028 for(unsigned int i = 0; i <= binPhi; i++){
00029 m_phiEdges[i] = minPhi + double(i)*(maxPhi - minPhi)/double(binPhi);
00030 }
00031 }
00032
00033
00034 Descriptor* BetaGridGenerator::describe(const InterestPoint& point, const LaserReading& reading){
00035 return describe(point.getPosition(), reading);
00036 }
00037
00038 Descriptor* BetaGridGenerator::describe(const OrientedPoint2D& point, const LaserReading& reading){
00039 BetaGrid * shape = new BetaGrid();
00040 shape->getHistogram().resize(m_phiEdges.size() - 1, std::vector<double>(m_rhoEdges.size() - 1, 0.));
00041 shape->getVariance().resize(m_phiEdges.size() - 1, std::vector<double>(m_rhoEdges.size() - 1, 0.));
00042 shape->getHit().resize(m_phiEdges.size() - 1, std::vector<double>(m_rhoEdges.size() - 1, 0.));
00043 shape->getMiss().resize(m_phiEdges.size() - 1, std::vector<double>(m_rhoEdges.size() - 1, 0.));
00044
00045 const Point2D& position = reading.getLaserPose();
00046
00047 for(unsigned int rho = 0; rho < m_rhoEdges.size() - 1; rho++){
00048 for(unsigned int phi = 0; phi < m_phiEdges.size() - 1; phi++){
00049
00050
00051 double angle1 = m_phiEdges[phi] + point.theta;
00052 double angle2 = m_phiEdges[phi+1] + point.theta;
00053 double cos1 = cos(angle1), sin1 = sin(angle1), cos2 = cos(angle2), sin2 = sin(angle2);
00054 const Point2D point1(point.x + cos1 * m_rhoEdges[rho], point.y + sin1 * m_rhoEdges[rho]);
00055 const Point2D point2(point.x + cos1 * m_rhoEdges[rho+1], point.y + sin1 * m_rhoEdges[rho+1]);
00056 const Point2D point3(point.x + cos2 * m_rhoEdges[rho+1], point.y + sin2 * m_rhoEdges[rho+1]);
00057 const Point2D point4(point.x + cos2 * m_rhoEdges[rho], point.y + sin2 * m_rhoEdges[rho]);
00058 for(unsigned int i = 0; i < reading.getWorldCartesian().size(); i++){
00059 int accumulator = 0;
00060 const Point2D& endPoint = reading.getWorldCartesian()[i];
00061 if(reading.getRho()[i] >= reading.getMaxRange()) continue;
00062 accumulator += intersectSegment2Segment(position, endPoint, point1, point2);
00063 accumulator += intersectSegment2Arc(position, endPoint, point2, point3, point);
00064 accumulator += intersectSegment2Segment(position, endPoint, point4, point3);
00065 accumulator += intersectSegment2Arc(position, endPoint, point1, point4, point);
00066 shape->getMiss()[phi][rho] += accumulator >= 2.;
00067 shape->getHit()[phi][rho] += accumulator == 1.;
00068 }
00069 }
00070 }
00071
00072 for(unsigned int rho = 0; rho < m_rhoEdges.size() - 1; rho++){
00073 for(unsigned int phi = 0; phi < m_phiEdges.size() - 1; phi++){
00074 if(shape->getHit()[phi][rho] != 0 || shape->getMiss()[phi][rho] != 0){
00075 shape->getHistogram()[phi][rho] = (shape->getHit()[phi][rho])/(shape->getHit()[phi][rho] + shape->getMiss()[phi][rho]);
00076 shape->getVariance()[phi][rho] = (shape->getHit()[phi][rho] * shape->getMiss()[phi][rho])/
00077 ( (shape->getHit()[phi][rho] + shape->getMiss()[phi][rho]) * (shape->getHit()[phi][rho] + shape->getMiss()[phi][rho]) *
00078 (shape->getHit()[phi][rho] + shape->getMiss()[phi][rho] + 1));
00079 } else{
00080 shape->getHistogram()[phi][rho] = 0.5;
00081 shape->getVariance()[phi][rho] = 1./(2 * 2 * 3);
00082 }
00083 }
00084 }
00085
00086
00087 double accumulator = 0.;
00088
00089
00090
00091 for(unsigned int rho = 0; rho < m_rhoEdges.size() - 1; rho++){
00092 for(unsigned int phi = 0; phi < m_phiEdges.size() - 1; phi++){
00093 accumulator += shape->getHistogram()[phi][rho];
00094
00095
00096 }
00097 }
00098
00099
00100 for(unsigned int rho = 0; rho < m_rhoEdges.size() - 1; rho++){
00101 for(unsigned int phi = 0; phi < m_phiEdges.size() - 1; phi++){
00102 shape->getHistogram()[phi][rho] = shape->getHistogram()[phi][rho]/accumulator;
00103
00104
00105
00106 }
00107 }
00108
00109
00110 shape->setDistanceFunction(m_distanceFunction);
00111 return shape;
00112 }
00113
00114 bool BetaGridGenerator::intersectSegment2Segment(const Point2D& segment1Start, const Point2D& segment1End, const Point2D& segment2Start, const Point2D& segment2End)
00115 {
00116 Point2D segment1Direction = segment1End - segment1Start;
00117 Point2D segment2Direction = segment2End - segment2Start;
00118 Point2D delta = segment2Start - segment1Start;
00119 double dotPerpProduct = segment1Direction * segment2Direction.ortho();
00120 if (dotPerpProduct != 0.){
00121 double ascissa1 = (delta * segment1Direction.ortho()) / dotPerpProduct;
00122 double ascissa2 = (delta * segment2Direction.ortho()) / dotPerpProduct;
00123 return (ascissa1 >= 0 && ascissa1 <= 1 && ascissa2 >= 0 && ascissa2 <= 1 );
00124 } else if(delta * segment1Direction == 0.){
00125 double ascissa1 = (segment1Direction * delta) / (segment1Direction * segment1Direction);
00126 Point2D delta2 = segment2Direction - segment1Start;
00127 double ascissa2 = (segment1Direction * delta2) / (segment1Direction * segment1Direction);
00128 return (ascissa1 >= 0. && ascissa1 <= 1.) || (ascissa2 >= 0. && ascissa2 <= 1.);
00129 }
00130 return false;
00131 }
00132
00133 int BetaGridGenerator::intersectSegment2Arc(const Point2D& segmentStart, const Point2D& segmentEnd, const Point2D& arcStart, const Point2D& arcEnd, const Point2D& arcCenter)
00134 {
00135 Point2D segmentDirection = segmentEnd - segmentStart;
00136 Point2D delta = segmentStart - arcCenter;
00137 double radiusSquare = (arcStart - arcCenter) * (arcStart - arcCenter);
00138 double discriminant = (segmentDirection * delta) * (segmentDirection * delta) - (segmentDirection * segmentDirection) * (delta * delta - radiusSquare);
00139 if(discriminant == 0.){
00140 double ascissa = -(segmentDirection * delta)/(segmentDirection * segmentDirection);
00141 Point2D intersectionDelta = segmentStart + ascissa * segmentDirection - arcStart;
00142 Point2D arcDelta = arcEnd - arcStart;
00143 return (intersectionDelta.x * arcDelta.y >= intersectionDelta.y * arcDelta.x) * (ascissa >= 0. && ascissa <= 1.);
00144 } else if(discriminant > 0.){
00145 double ascissa1 = (-(segmentDirection * delta) + sqrt(discriminant))/(segmentDirection * segmentDirection);
00146 double ascissa2 = (-(segmentDirection * delta) - sqrt(discriminant))/(segmentDirection * segmentDirection);
00147 int result = 0;
00148 Point2D intersectionDelta1 = segmentStart + ascissa1 * segmentDirection - arcStart;
00149 Point2D intersectionDelta2 = segmentStart + ascissa2 * segmentDirection - arcStart;
00150 Point2D arcDelta = arcEnd - arcStart;
00151 result += (intersectionDelta1.x * arcDelta.y >= intersectionDelta1.y * arcDelta.x) * (ascissa1 >= 0. && ascissa1 <= 1.);
00152 result += (intersectionDelta2.x * arcDelta.y >= intersectionDelta2.y * arcDelta.x) * (ascissa2 >= 0. && ascissa2 <= 1.);
00153 return result;
00154 }
00155 return 0;
00156 }
00157
00158 Descriptor* BetaGrid::clone() const{
00159 return new BetaGrid(*this);
00160 }
00161
00162 double BetaGrid::distance(const Descriptor* descriptor) const {
00163 const BetaGrid *betaGrid = dynamic_cast<const BetaGrid *>(descriptor);
00164 if(!m_distanceFunction || !betaGrid){
00165 return 10e16;
00166 }
00167 return m_distanceFunction->distance(this->getHistogram(), betaGrid->getHistogram());
00168 }