wifi_gpmap_node.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2013, Seigo ITO
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of Seigo ITO nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 
00031 
00032 // ROS
00033 #include "ros/ros.h"
00034 #include "ros/package.h"
00035 #include "sensor_msgs/PointCloud2.h"
00036 // PCL
00037 #include "pcl/io/pcd_io.h"
00038 #include "pcl/point_types.h"
00039 #include "pcl/filters/voxel_grid.h"
00040 // boost
00041 #include "boost/filesystem.hpp"
00042 #include "boost/filesystem/path.hpp"
00043 #include "boost/filesystem/operations.hpp"
00044 #include "boost/filesystem/fstream.hpp"
00045 #include "boost/tokenizer.hpp"
00046 // Gaussian Process
00047 #include "gaussian_process/SingleGP.h"
00048 
00049 
00050 
00051 class WifiGpmapNode
00052 {
00053 public:
00054   WifiGpmapNode();
00055   ~WifiGpmapNode();
00056   void loadmap();
00057   void evalGaussian();
00058   void publish();
00059 private:
00060   ros::NodeHandle nh_;
00061 
00062   // size of boxel grid filter
00063   float box_x_,box_y_,box_z_;
00064 
00065   // signal strength map
00066   std::map<std::string,sensor_msgs::PointCloud2> ap_raw_map_;
00067   std::map<std::string,sensor_msgs::PointCloud2> gp_mean_map_;
00068   std::map<std::string,sensor_msgs::PointCloud2> gp_cov_map_;
00069 
00070   // wifi gpmap publisher
00071   std::vector<ros::Publisher> wifi_gpmean_pub_;
00072   std::vector<ros::Publisher> wifi_gpcov_pub_;
00073 
00074   // GP map parameter
00075   double gp_x_min_, gp_x_max_,gp_x_interval_, gp_y_min_, gp_y_max_,gp_y_interval_;
00076   std::string path_wifimap_;
00077 };
00078 
00079 
00080 
00081 WifiGpmapNode::WifiGpmapNode() :
00082     nh_("~")
00083 {
00084   nh_.param("gp_x_min", gp_x_min_, 0.0);
00085   nh_.param("gp_x_max", gp_x_max_, 20.0);
00086   nh_.param("gp_x_interval", gp_x_interval_, 1.0);
00087   nh_.param("gp_y_min", gp_y_min_, 0.0);
00088   nh_.param("gp_y_max", gp_y_max_, 20.0);
00089   nh_.param("gp_y_interval", gp_y_interval_, 1.0);
00090   nh_.param("path_wifimap",path_wifimap_,ros::package::getPath("wifi_tools") + "/map");
00091 
00092 
00093   // size of voxel grid filter
00094   box_x_ = 1.0;
00095   box_y_ = 1.0;
00096   box_z_ = 256.0;
00097 
00098   // load Wifi Map
00099   loadmap();
00100 
00101   // Mac address map publisher
00102   std::map<std::string,sensor_msgs::PointCloud2>::iterator it;
00103   it = ap_raw_map_.begin();
00104   while(it != ap_raw_map_.end())
00105   {
00106     std::ostringstream mean_topic,cov_topic;
00107     mean_topic << "wifi_gpmean" << (*it).first;
00108     cov_topic << "wifi_gpcov" << (*it).first;
00109     std::string t1 = boost::algorithm::replace_all_copy(mean_topic.str(),":","");
00110     std::string t2 = boost::algorithm::replace_all_copy(cov_topic.str(),":","");
00111     ros::Publisher each_mean_pub = nh_.advertise<sensor_msgs::PointCloud2>(t1.c_str(), 1);
00112     ros::Publisher each_cov_pub = nh_.advertise<sensor_msgs::PointCloud2>(t2.c_str(), 1);
00113     wifi_gpmean_pub_.push_back(each_mean_pub);
00114     wifi_gpcov_pub_.push_back(each_cov_pub);
00115     ++it;
00116   }
00117 }
00118 
00119 
00120 
00121 WifiGpmapNode::~WifiGpmapNode()
00122 {
00123 }
00124 
00125 
00126 
00127 void WifiGpmapNode::loadmap()
00128 {
00129   int ap_count = 0;
00130   namespace f = boost::filesystem;
00131   f::path map_dir = path_wifimap_;
00132   f::directory_iterator end;
00133   for( f::directory_iterator it(map_dir); it!=end; ++it )
00134   {
00135     if( !(f::is_directory(*it)) )
00136     {
00137       //mac address
00138       std::string leaf = (*it).path().leaf().c_str();
00139       boost::char_separator< char > sep(".");
00140       boost::tokenizer< boost::char_separator< char > > tokens(leaf, sep);
00141       boost::tokenizer< boost::char_separator< char > >::iterator file_it;
00142       file_it = tokens.begin();
00143       std::string mac_address = (std::string)(*file_it);
00144 
00145       // load WiFi data
00146       std::ifstream ap_ifs((*it).path().c_str());
00147       pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>),cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
00148       pcl::io::loadPCDFile<pcl::PointXYZ> ((*it).path().c_str(), *cloud);
00149 
00150       // boxel grid filter
00151       pcl::VoxelGrid<pcl::PointXYZ> box;
00152       box.setInputCloud (cloud);
00153       box.setLeafSize (box_x_,box_y_,box_z_);
00154       box.filter (*cloud_filtered);
00155 
00156       // cache data
00157       sensor_msgs::PointCloud2::Ptr cloud_msg(new sensor_msgs::PointCloud2());
00158       pcl::toROSMsg(*cloud_filtered, *cloud_msg);
00159       (*cloud_msg).header.frame_id = "/map";
00160       (*cloud_msg).header.stamp = ros::Time::now();
00161       ap_raw_map_.insert(std::map<std::string,sensor_msgs::PointCloud2 >::value_type(mac_address,*cloud_msg));
00162       ap_count++;
00163     }
00164   }
00165   ROS_INFO("%d access points data have loaded.",ap_count);
00166 }
00167 
00168 
00169 
00170 void WifiGpmapNode::evalGaussian()
00171 {
00172   std::map<std::string,sensor_msgs::PointCloud2>::iterator it;
00173   it = ap_raw_map_.begin();
00174   while(it != ap_raw_map_.end())
00175   {
00176     pcl::PointCloud<pcl::PointXYZ>::Ptr wifi_pcl(new pcl::PointCloud<pcl::PointXYZ>);
00177     pcl::fromROSMsg((*it).second,*wifi_pcl);
00178 
00179     std::vector<gaussian_process::SingleGP*> gp;
00180     size_t training_samples;
00181 
00182     // Initialize GP
00183     CovFuncND initialCovFunc;
00184     double initialSigmaNoise;
00185 
00186     // GP parameter
00187     vector<double> params = vector<double>(3);
00188     params[0] = 0.5;
00189     params[1] = 0.5;
00190     params[2] = 0.0;
00191     initialCovFunc.setHyperparameter(params);
00192     initialSigmaNoise = -5;
00193     for (size_t i = 0; i < 7; i++) {
00194       gp.push_back(   new gaussian_process::SingleGP(initialCovFunc,initialSigmaNoise));
00195     }
00196 
00197     // GP learn
00198     ROS_INFO("Learning gaussian process model... %s",(*it).first.c_str());
00199     int training_size = wifi_pcl->points.size();
00200     TVector < TDoubleVector > input(training_size);
00201     TVector<double> output[7];
00202     for (size_t j = 0; j < 7; j++) {
00203             output[j] = TDoubleVector(training_size);
00204     }
00205 
00206     for (size_t i = 0; i < training_size; i++) {
00207       input[i] = TDoubleVector(2);
00208       input[i][0] = wifi_pcl->points[i].x;
00209       input[i][1] = wifi_pcl->points[i].y;
00210       output[0][i] = wifi_pcl->points[i].z;
00211       output[1][i] = 0;
00212       output[2][i] = 0;
00213       output[3][i] = 0;
00214       output[4][i] = 0;
00215       output[5][i] = 0;
00216       output[6][i] = 0;
00217     }
00218     for(size_t j=0;j<7;j++) {
00219             gp[j]->SetData(input,output[j]);
00220     }
00221 
00222     // GP Evaluate
00223     ROS_INFO("Evaluating gaussian process model... %s",(*it).first.c_str());
00224     TDoubleVector inp(2);
00225     double mean_ss=0,var_ss=0;
00226     pcl::PointCloud<pcl::PointXYZ>::Ptr mean_cloud (new pcl::PointCloud<pcl::PointXYZ>),cov_cloud (new pcl::PointCloud<pcl::PointXYZ>);
00227     for(double i=gp_x_min_;i<gp_x_max_;i+=gp_x_interval_)
00228     {
00229       for(double j=gp_y_min_;j<gp_y_max_;j+=gp_y_interval_)
00230       {
00231         pcl::PointCloud<pcl::PointXYZ> p1,p2;
00232           p1.width = p2.width = 1;
00233           p1.height = p2.height = 1;
00234           p1.is_dense = p2.is_dense = false;
00235           p1.points.resize (p1.width * p1.height);
00236           p2.points.resize (p2.width * p2.height);
00237           p1.points[0].x = p2.points[0].x = i;
00238           p1.points[0].y = p2.points[0].y = j;
00239           inp(0) = i;
00240           inp(1) = j;
00241           gp[0]->Evaluate( inp, mean_ss, var_ss );
00242           p1.points[0].z = mean_ss;
00243           p2.points[0].z = var_ss;
00244           (*mean_cloud) += p1;
00245           (*cov_cloud) += p2;
00246       }
00247     }
00248     sensor_msgs::PointCloud2::Ptr gp_mean_msg(new sensor_msgs::PointCloud2()),gp_cov_msg(new sensor_msgs::PointCloud2());
00249     pcl::toROSMsg(*mean_cloud, *gp_mean_msg);
00250     pcl::toROSMsg(*cov_cloud, *gp_cov_msg);
00251     gp_mean_msg->header.frame_id = gp_cov_msg->header.frame_id = "/map";
00252     gp_mean_map_.insert(std::map<std::string,sensor_msgs::PointCloud2 >::value_type((*it).first,*gp_mean_msg));
00253     gp_cov_map_.insert(std::map<std::string,sensor_msgs::PointCloud2 >::value_type((*it).first,*gp_cov_msg));
00254     ++it;
00255   }
00256 
00257 
00258 }
00259 
00260 
00261 
00262 void WifiGpmapNode::publish()
00263 {
00264   std::map<std::string,sensor_msgs::PointCloud2>::iterator it1,it2;
00265   std::vector<ros::Publisher>::iterator pub_it1,pub_it2;
00266   it1 = gp_mean_map_.begin();
00267   it2 = gp_cov_map_.begin();
00268   pub_it1 = wifi_gpmean_pub_.begin();
00269   pub_it2 = wifi_gpcov_pub_.begin();
00270   while(it1 != gp_mean_map_.end())
00271   {
00272     (*pub_it1).publish((*it1).second);
00273     (*pub_it2).publish((*it2).second);
00274     ++pub_it1;++pub_it2;
00275     ++it1;++it2;
00276   }
00277 }
00278 
00279 
00280 
00281 int main(int argc, char** argv)
00282 {
00283   ros::init(argc, argv, "wifi_gpmap");
00284   ros::NodeHandle nh;
00285   WifiGpmapNode wifi_gpmap;
00286   wifi_gpmap.evalGaussian();
00287   ros::Rate rate_Hz(1);
00288   ROS_INFO("Start publish.");
00289   while (ros::ok())
00290   {
00291     wifi_gpmap.publish();
00292     rate_Hz.sleep();
00293   }
00294   return (0);
00295 }


wifi_tools
Author(s): Seigo ITO
autogenerated on Mon Oct 6 2014 12:23:56