fingerprint_rviz.cpp
Go to the documentation of this file.
00001 /*
00002  fingerprint_rviz vizualizes the fingerprints.
00003  Copyright (C) 2013  Rafael Berkvens rafael.berkvens@ua.ac.be
00004 
00005  This program is free software: you can redistribute it and/or modify
00006  it under the terms of the GNU General Public License as published by
00007  the Free Software Foundation, either version 3 of the License, or
00008  (at your option) any later version.
00009 
00010  This program is distributed in the hope that it will be useful,
00011  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  GNU General Public License for more details.
00014 
00015  You should have received a copy of the GNU General Public License
00016  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include <string>
00020 #include <map>
00021 #include <sstream>
00022 #include <vector>
00023 
00024 #include <ros/ros.h>
00025 #include <ros/time.h>
00026 #include <ros/console.h>
00027 #include <tf/transform_broadcaster.h>
00028 
00029 #include <visualization_msgs/Marker.h>
00030 #include <nav_msgs/Odometry.h>
00031 
00032 #include <wifi_scan/Fingerprint.h>
00033 
00034 namespace jet
00035 {
00036 double interpolate(double val, double y0, double x0, double y1, double x1)
00037 {
00038   return (val - x0) * (y1 - y0) / (x1 - x0) + y0;
00039 }
00040 
00041 double base(double val)
00042 {
00043   if (val <= -0.75)
00044     return 0;
00045   else if (val <= -0.25)
00046     return interpolate(val, 0.0, -0.75, 1.0, -0.25);
00047   else if (val <= 0.25)
00048     return 1.0;
00049   else if (val <= 0.75)
00050     return interpolate(val, 1.0, 0.25, 0.0, 0.75);
00051   else
00052     return 0.0;
00053 }
00054 
00055 double red(double gray)
00056 {
00057   return base(gray - 0.5);
00058 }
00059 double green(double gray)
00060 {
00061   return base(gray);
00062 }
00063 double blue(double gray)
00064 {
00065   return base(gray + 0.5);
00066 }
00067 }
00068 
00073 class FingerprintRviz
00074 {
00075 //   ros::NodeHandle *node_;
00076   ros::Publisher *pub_rviz_msgs_;
00077   //   ros::Subscriber sub_fingerprint_;
00078 
00079   tf::TransformBroadcaster odom_br_;
00080   tf::Transform odom_tr_;
00081 
00082   std::map<std::string, double> fingerprint_;
00083 
00084   visualization_msgs::Marker marker_;
00085 
00086   std::stringstream hexstream_;
00087 
00088   int index_;
00089 
00090   std::map<std::string, int> device_addresses_;
00091   int n_devices_;
00092 
00093 public:
00094   FingerprintRviz(ros::Publisher *pub);
00095   virtual ~FingerprintRviz();
00096 
00097   void fingerprint_rvizCallback(
00098                                 const wifi_scan::Fingerprint &fingerprint);
00103   void odom_tfCallback(
00104                        const nav_msgs::Odometry &odom);
00105 };
00106 
00107 FingerprintRviz::FingerprintRviz(ros::Publisher *pub)
00108 {
00109 //   node_ = node;
00110 
00111   pub_rviz_msgs_ = pub;
00112 //   sub_fingerprint_ = node_->subscribe(
00113 //                        topic_name, 1000,
00114 //                        fingerprint_rvizCallback);
00115 
00116   marker_.header.frame_id = "/base_link";
00117   marker_.header.stamp = ros::Time();
00118   marker_.ns = "fingerprint_rviz";
00119   marker_.id = 0;
00120   marker_.type = visualization_msgs::Marker::SPHERE;
00121   marker_.action = visualization_msgs::Marker::ADD;
00122   marker_.pose.position.x = 0;
00123   marker_.pose.position.y = 0;
00124   marker_.pose.position.z = 0;
00125   marker_.pose.orientation.x = 0.0;
00126   marker_.pose.orientation.y = 0.0;
00127   marker_.pose.orientation.z = 0.0;
00128   marker_.pose.orientation.w = 0.0;
00129   marker_.scale.x = 0.1;
00130   marker_.scale.y = 0.1;
00131   marker_.scale.z = 0.1;
00132   marker_.color.a = 1.0;
00133   marker_.color.r = 0.0;
00134   marker_.color.g = 0.0;
00135   marker_.color.b = 0.0;
00136 
00137   hexstream_ << std::hex;
00138 
00139   index_ = 0;
00140   n_devices_ = 0;
00141 }
00142 
00143 FingerprintRviz::~FingerprintRviz()
00144 {
00145   delete pub_rviz_msgs_;
00146 }
00147 
00148 void FingerprintRviz::fingerprint_rvizCallback(
00149     const wifi_scan::Fingerprint &fingerprint)
00150 {
00151   fingerprint_.clear();
00152   if (fingerprint.list.empty())
00153   {
00154     ROS_WARN_STREAM("Empty list!");
00155   }
00156   wifi_scan::AddressRSSI address_rssi;
00157   for (int i = 0; i < fingerprint.list.size(); i++)
00158   {
00159     address_rssi = fingerprint.list[i];
00160 
00161     /* Put address and RSSI in fingerprint if address is unique*/
00162     std::pair<std::map<std::string, double>::iterator, bool> ret;
00163     ret = fingerprint_.insert(
00164         std::pair<std::string, double>(
00165                                        std::string(address_rssi.address),
00166                                        address_rssi.rssi));
00167     if (ret.second == false)
00168     {
00169       ROS_WARN_STREAM("Address not unique.");
00170     }
00171   }
00172 
00173   std::map<std::string, double>::iterator access_point;
00174   int i;
00175   for (access_point = fingerprint_.begin();
00176       access_point != fingerprint_.end();
00177       access_point++, index_++)
00178   {
00179     ROS_DEBUG_STREAM("device mac address: " << access_point->first);
00180     std::pair<std::map<std::string, int>::iterator, bool> check;
00181     check = device_addresses_.insert(
00182         std::pair<std::string, int>(access_point->first, n_devices_));
00183     if (check.second)
00184     {
00185       n_devices_++;
00186       ROS_DEBUG_STREAM("n_device_: " << n_devices_);
00187     }
00188 
00189     marker_.id = index_;
00190     //marker_.pose.position.z = (access_point->second + 100) / 10;
00191     marker_.pose.position.z =
00192         device_addresses_.find(access_point->first)->second / 10.0;
00193     ROS_DEBUG_STREAM("z position: " << marker_.pose.position.z);
00194 
00195     unsigned int colorr, colorg, colorb;
00196     // values: 30 since -30 highest seen value; 100.0 since values between
00197     // 0 and -100 theoretically; 0.6 since -90 (+30/100) lowest seen value
00198     colorr = jet::red(((access_point->second + 80) / 100.0)) * 255;
00199     colorg = jet::green(((access_point->second + 80) / 100.0)) * 255;
00200     colorb = jet::blue(((access_point->second + 80) / 100.0)) * 255;
00201 //    hexstream_ << access_point->first[2] << access_point->first[3];
00202 //    hexstream_ >> colorr;
00203 //    hexstream_.clear(); // clear error flags
00204 //    hexstream_ << access_point->first[4] << access_point->first[5];
00205 //    hexstream_ >> colorg;
00206 //    hexstream_.clear(); // clear error flags
00207 //    hexstream_ << access_point->first[6] << access_point->first[7];
00208 //    hexstream_ >> colorb;
00209 //    hexstream_.clear(); // clear error flags
00210     ROS_DEBUG_STREAM("colors for " << access_point->second << ": "
00211                      << colorr << " " << colorg << " " << colorb);
00212     marker_.color.r = static_cast<int>(colorr) / 255.0;
00213     marker_.color.g = static_cast<int>(colorg) / 255.0;
00214     marker_.color.b = static_cast<int>(colorb) / 255.0;
00215 
00216     pub_rviz_msgs_->publish(marker_);
00217   }
00218 }
00219 
00220 void FingerprintRviz::odom_tfCallback(const nav_msgs::Odometry &odom)
00221 {
00222   odom_tr_.setOrigin(tf::Vector3(odom.pose.pose.position.x,
00223                                  odom.pose.pose.position.y,
00224                                  odom.pose.pose.position.z));
00225   odom_tr_.setRotation(tf::Quaternion(odom.pose.pose.orientation.x,
00226                                       odom.pose.pose.orientation.y,
00227                                       odom.pose.pose.orientation.z,
00228                                       odom.pose.pose.orientation.w));
00229   odom_br_.sendTransform(tf::StampedTransform(odom_tr_, ros::Time::now(),
00230                                               "/odom",
00231                                               "/base_link"));
00232 }
00233 
00240 int main(int argc, char **argv)
00241 {
00242   /* Set up ROS, get handle, set desired rate. */
00243   ros::init(argc, argv, "fingerprint_rviz");
00244   ros::NodeHandle node;
00245   ros::Rate rate(1);
00246 
00247   /* Get parameters from command line. */
00248   ros::NodeHandle private_node_handle_("~");
00249   std::string topic_name;
00250   private_node_handle_.param<std::string>("topic", topic_name, "wifi_fp");
00251   std::string pub_topic_name = topic_name + "_rviz";
00252   ros::Publisher pub_rviz_msgs = node.advertise<visualization_msgs::Marker>(
00253       pub_topic_name, 0);
00254   FingerprintRviz fingerprint_rviz(&pub_rviz_msgs);
00255   ros::Subscriber sub_fingerprint = node.subscribe(
00256       topic_name, 1000,
00257       &FingerprintRviz::fingerprint_rvizCallback,
00258       &fingerprint_rviz);
00259 //  ros::Subscriber sub_odom = node.subscribe("/p3dx/odom", 1000,
00260 //                                            &FingerprintRviz::odom_tfCallback,
00261 //                                            &fingerprint_rviz);
00262 
00263   ros::spin();
00264 }
00265 // kate: indent-mode cstyle; indent-width 2; replace-tabs on; 


wifi_scan
Author(s): Rafael Berkvens
autogenerated on Fri Aug 28 2015 13:41:23