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 #include "ros/ros.h"
00034 #include "ros/package.h"
00035 #include "sensor_msgs/PointCloud2.h"
00036
00037 #include "pcl/io/pcd_io.h"
00038 #include "pcl/point_types.h"
00039 #include "pcl/filters/voxel_grid.h"
00040
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
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
00063 float box_x_,box_y_,box_z_;
00064
00065
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
00071 std::vector<ros::Publisher> wifi_gpmean_pub_;
00072 std::vector<ros::Publisher> wifi_gpcov_pub_;
00073
00074
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
00094 box_x_ = 1.0;
00095 box_y_ = 1.0;
00096 box_z_ = 256.0;
00097
00098
00099 loadmap();
00100
00101
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
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
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
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
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
00183 CovFuncND initialCovFunc;
00184 double initialSigmaNoise;
00185
00186
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
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
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 }