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 #include "ros/ros.h"
00033 #include "ros/package.h"
00034 #include "tf/transform_broadcaster.h"
00035 #include "tf/transform_listener.h"
00036 #include "tf/message_filter.h"
00037 #include "tf/tf.h"
00038 #include "message_filters/subscriber.h"
00039 #include "sensor_msgs/PointCloud2.h"
00040 #include <pcl_ros/point_cloud.h>
00041 #include <pcl/point_types.h>
00042 #include <pcl/io/pcd_io.h>
00043 #include "std_srvs/Empty.h"
00044
00045
00046 #include "wifi_tools/WifiData.h"
00047 #include "wifi_tools/Out2File.h"
00048
00049
00050
00051 class WiFiMappingNode
00052 {
00053 public:
00054 WiFiMappingNode();
00055 ~WiFiMappingNode();
00056
00057 void wifiScanReceived(const wifi_tools::WifiDataConstPtr& wifi_msg);
00058 bool outputFile(std_srvs::Empty::Request& req, std_srvs::Empty::Response& res);
00059
00060 private:
00061 message_filters::Subscriber<wifi_tools::WifiData>* wifiscan_sub_;
00062 tf::MessageFilter<wifi_tools::WifiData>* wifi_filter_;
00063
00064 ros::NodeHandle nh_;
00065 tf::TransformListener* tf_;
00066
00067
00068 std::string odom_frame_id_;
00069
00070 std::string base_frame_id_;
00071
00072
00073 std::string wifiscan_topic_;
00074
00075
00076 std::map<std::string,pcl::PointCloud<pcl::PointXYZ> > ap_map_;
00077
00078
00079 ros::Publisher wifi_map_pub_;
00080
00081 ros::ServiceServer out2file_srv_;
00082 };
00083
00084
00085
00086 WiFiMappingNode::WiFiMappingNode()
00087 {
00088 nh_.param("wifiscan_topic",wifiscan_topic_,std::string("/wifi_tools/wifi_data"));
00089 nh_.param("odom_frame_id", odom_frame_id_, std::string("/odom"));
00090 nh_.param("base_frame_id", base_frame_id_, std::string("/base_link"));
00091
00092 tf_ = new tf::TransformListener();
00093
00094
00095 wifiscan_sub_ = new message_filters::Subscriber<wifi_tools::WifiData>(nh_, wifiscan_topic_, 100);
00096
00097
00098 wifi_filter_ = new tf::MessageFilter<wifi_tools::WifiData>(*wifiscan_sub_, *tf_, odom_frame_id_, 100);
00099 wifi_filter_->registerCallback(boost::bind(&WiFiMappingNode::wifiScanReceived,this, _1));
00100
00101
00102 wifi_map_pub_ = nh_.advertise<sensor_msgs::PointCloud2>("/wifi_map", 10);
00103
00104
00105 out2file_srv_ = nh_.advertiseService("/wifi_mapping/o2file", &WiFiMappingNode::outputFile,this);
00106
00107 }
00108
00109
00110
00111 WiFiMappingNode::~WiFiMappingNode()
00112 {
00113 }
00114
00115
00116
00117 bool WiFiMappingNode::outputFile(std_srvs::Empty::Request& req, std_srvs::Empty::Response& res)
00118 {
00119
00120 std::string file_base = ros::package::getPath("wifi_tools") + "/map/";
00121 std::map<std::string,pcl::PointCloud<pcl::PointXYZ> >::iterator it = ap_map_.begin();
00122 while(it != ap_map_.end())
00123 {
00124 std::string filename = file_base + (std::string)(*it).first + ".pcd";
00125 pcl::io::savePCDFileASCII (filename, (*it).second);
00126 ++it;
00127 }
00128 ROS_INFO("WiFi maps have written to %s",file_base.c_str());
00129 return true;
00130 }
00131
00132
00133
00134 void WiFiMappingNode::wifiScanReceived(const wifi_tools::WifiDataConstPtr& wifi_msg)
00135 {
00136
00137 tf::Stamped<tf::Pose> odom_pose;
00138 tf::Stamped<tf::Pose> base_pose (tf::Transform(tf::createIdentityQuaternion(),tf::Vector3(0,0,0)), wifi_msg->header.stamp, base_frame_id_);
00139 try
00140 {
00141 this->tf_->transformPose(odom_frame_id_, base_pose, odom_pose);
00142 }
00143 catch(tf::TransformException e)
00144 {
00145 ROS_WARN("can't get transform. (%s)", e.what());
00146 }
00147
00148
00149 std::map<std::string,pcl::PointCloud<pcl::PointXYZ> >::iterator it;
00150 std::string mac;
00151 double z_x,z_y,z_ss;
00152 for(int i=0; i<wifi_msg->data.size();i++)
00153 {
00154 mac = wifi_msg->data[i].mac_address;
00155 it = ap_map_.find(mac);
00156 z_x = (double)odom_pose.getOrigin().x();
00157 z_y = (double)odom_pose.getOrigin().y();
00158 z_ss = (double)wifi_msg->data[i].ss;
00159 if( it == ap_map_.end())
00160 {
00161
00162 pcl::PointCloud<pcl::PointXYZ> ap;
00163 ap_map_.insert(std::map<std::string,pcl::PointCloud<pcl::PointXYZ> >::value_type(mac,ap));
00164 ROS_INFO("new ap %s",mac.c_str());
00165 }
00166 else
00167 {
00168 pcl::PointCloud<pcl::PointXYZ> cloud;
00169 cloud.width = 1;
00170 cloud.height = 1;
00171 cloud.is_dense = false;
00172 cloud.points.resize (cloud.width * cloud.height);
00173 cloud.points[0].x = z_x;
00174 cloud.points[0].y = z_y;
00175 cloud.points[0].z = z_ss;
00176 (*it).second += cloud;
00177 }
00178 }
00179
00180 }
00181
00182
00183
00184 int main(int argc, char** argv)
00185 {
00186 ros::init(argc, argv, "WiFi_mapping_node");
00187 ros::NodeHandle nh;
00188 WiFiMappingNode wifi_mapping;
00189
00190 ROS_INFO("Waiting for WiFi signals...");
00191 ros::spin();
00192 return (0);
00193 }