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 #ifndef MAPBUILDERWIFI_H_
00029 #define MAPBUILDERWIFI_H_
00030
00031 #include "../RGBDMapping/MapBuilder.h"
00032
00033 using namespace rtabmap;
00034
00035
00036
00037
00038
00039
00040
00041
00042 inline int dBm2Quality(int dBm)
00043 {
00044
00045 if(dBm <= -100)
00046 return 0;
00047 else if(dBm >= -50)
00048 return 100;
00049 else
00050 return 2 * (dBm + 100);
00051 }
00052
00053 class MapBuilderWifi : public MapBuilder
00054 {
00055 Q_OBJECT
00056 public:
00057
00058 MapBuilderWifi(CameraThread * camera = 0) :
00059 MapBuilder(camera)
00060 {}
00061
00062 virtual ~MapBuilderWifi()
00063 {
00064 this->unregisterFromEventsManager();
00065 }
00066
00067 protected slots:
00068 virtual void processStatistics(const rtabmap::Statistics & stats)
00069 {
00070 processingStatistics_ = true;
00071
00072 const std::map<int, Transform> & poses = stats.poses();
00073 QMap<std::string, Transform> clouds = cloudViewer_->getAddedClouds();
00074
00075
00076
00077
00078 std::map<double, int> nodeStamps;
00079 std::map<int, std::pair<int, double> > wifiLevels;
00080
00081 UASSERT(stats.getStamps().size() == stats.getUserDatas().size());
00082 std::map<int, double>::const_iterator iterStamps = stats.getStamps().begin();
00083 std::map<int, std::vector<unsigned char> >::const_iterator iterUserDatas = stats.getUserDatas().begin();
00084 for(; iterStamps!=stats.getStamps().end() && iterUserDatas!=stats.getUserDatas().end(); ++iterStamps, ++iterUserDatas)
00085 {
00086
00087 nodeStamps.insert(std::make_pair(iterStamps->second, iterStamps->first));
00088
00089
00090 if(iterUserDatas->second.size())
00091 {
00092 UASSERT(iterUserDatas->second.size() == sizeof(int)+sizeof(double));
00093
00094
00095 int level;
00096 double stamp;
00097 memcpy(&level, iterUserDatas->second.data(), sizeof(int));
00098 memcpy(&stamp, iterUserDatas->second.data()+sizeof(int), sizeof(double));
00099
00100 wifiLevels.insert(std::make_pair(iterUserDatas->first, std::make_pair(level, stamp)));
00101 }
00102 }
00103
00104 for(std::map<int, std::pair<int, double> >::iterator iter=wifiLevels.begin(); iter!=wifiLevels.end(); ++iter)
00105 {
00106
00107 double stampWifi = iter->second.second;
00108 std::map<double, int>::iterator previousNode = nodeStamps.lower_bound(stampWifi);
00109 if(previousNode!=nodeStamps.end() && previousNode->first > stampWifi && previousNode != nodeStamps.begin())
00110 {
00111 --previousNode;
00112 }
00113 std::map<double, int>::iterator nextNode = nodeStamps.upper_bound(iter->second.second);
00114
00115 if(previousNode != nodeStamps.end() && nextNode != nodeStamps.end() &&
00116 previousNode->second != nextNode->second &&
00117 uContains(poses, previousNode->second) && uContains(poses, nextNode->second))
00118 {
00119 Transform poseA = poses.at(previousNode->second);
00120 Transform poseB = poses.at(nextNode->second);
00121 double stampA = previousNode->first;
00122 double stampB = nextNode->first;
00123 UASSERT(stampWifi>=stampA && stampWifi <=stampB);
00124
00125 Transform v = poseA.inverse() * poseB;
00126 double ratio = (stampWifi-stampA)/(stampB-stampA);
00127
00128 v.x()*=ratio;
00129 v.y()*=ratio;
00130 v.z()*=ratio;
00131
00132 Transform wifiPose = (poseA*v).translation();
00133
00134 std::string cloudName = uFormat("level%d", iter->first);
00135 if(clouds.contains(cloudName))
00136 {
00137 if(!cloudViewer_->updateCloudPose(cloudName, wifiPose))
00138 {
00139 UERROR("Updating pose cloud %d failed!", iter->first);
00140 }
00141 }
00142 else
00143 {
00144
00145 int quality = dBm2Quality(iter->second.first)/10;
00146 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
00147 for(int i=0; i<10; ++i)
00148 {
00149
00150
00151 pcl::PointXYZRGB pt;
00152 pt.z = float(i+1)*0.02f;
00153 if(i<quality)
00154 {
00155
00156 pt.r = 255;
00157 pt.g = 255;
00158 }
00159 else
00160 {
00161
00162 pt.r = pt.g = pt.b = 100;
00163 }
00164 cloud->push_back(pt);
00165 }
00166 pcl::PointXYZRGB anchor(255, 0, 0);
00167 cloud->push_back(anchor);
00168
00169 if(!cloudViewer_->addOrUpdateCloud(cloudName, cloud, wifiPose, Qt::yellow))
00170 {
00171 UERROR("Adding cloud %d to viewer failed!", iter->first);
00172 }
00173 else
00174 {
00175 cloudViewer_->setCloudPointSize(cloudName, 5);
00176 }
00177 }
00178 }
00179 else
00180 {
00181 UWARN("Bounds not found!");
00182 }
00183 }
00184
00185
00186
00187
00188 MapBuilder::processStatistics(stats);
00189 }
00190 };
00191
00192
00193 #endif