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 #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
00076 ros::Publisher *pub_rviz_msgs_;
00077
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
00110
00111 pub_rviz_msgs_ = pub;
00112
00113
00114
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
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
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
00197
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
00202
00203
00204
00205
00206
00207
00208
00209
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
00243 ros::init(argc, argv, "fingerprint_rviz");
00244 ros::NodeHandle node;
00245 ros::Rate rate(1);
00246
00247
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
00260
00261
00262
00263 ros::spin();
00264 }
00265