RosPressureVisualizer.cpp
Go to the documentation of this file.
00001 /*
00002  * Sends markers to RViz to visualize the pressure
00003  * being applied on a taxel array sensor.
00004  *
00005  * Copyright (C) 2011  Meka Robotics
00006  * Author: Pierre-Luc Bacon <pierrelucbacon@mekabot.com>
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License
00010  * as published by the Free Software Foundation; either version 2
00011  * of the License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00021  */
00022 
00023 #include "RosPressureVisualizer.h"
00024 #include <m3skin_ros/None_TransformArray.h>
00025 #include <m3skin_ros/None_String.h>
00026 
00027 #include <visualization_msgs/MarkerArray.h>
00028 
00029 namespace m3 {
00030 
00031 visualization_msgs::Marker RosPressureVisualizer::GetArrowMarker(tf::Vector3 position, tf::Quaternion orientation, double scale)
00032 {
00033         visualization_msgs::Marker m;
00034     m.type = visualization_msgs::Marker::ARROW;
00035     m.action = visualization_msgs::Marker::ADD;
00036 
00037         m.pose.position.x = position.x();
00038         m.pose.position.y = position.y();
00039         m.pose.position.z = position.z();
00040 
00041         m.pose.orientation.x = orientation.x();
00042         m.pose.orientation.y = orientation.y();
00043         m.pose.orientation.z = orientation.z();
00044         m.pose.orientation.w = orientation.w();
00045 
00046         m.scale.x = scale;
00047         m.scale.y = SCALE_ARROW_Y;
00048         m.scale.z = SCALE_ARROW_Z;
00049 
00050         m.color.r = 1.0;
00051         m.color.g = 0;
00052         m.color.b = 0;
00053         m.color.a = 0.5;
00054 
00055         m.lifetime = ros::Duration(DURATION_ARROW);
00056 
00057         return m;
00058 }
00059 
00060 void RosPressureVisualizer::GetArrowTextMarkers(tf::Vector3 position,
00061                             tf::Quaternion orientation, double scale,
00062                             visualization_msgs::Marker *arrow,
00063                             visualization_msgs::Marker *text,
00064                             double nx, double ny, double nz)
00065 {
00066     arrow->type = visualization_msgs::Marker::ARROW;
00067     arrow->action = visualization_msgs::Marker::ADD;
00068 
00069         arrow->pose.position.x = position.x();
00070         arrow->pose.position.y = position.y();
00071         arrow->pose.position.z = position.z();
00072 
00073         arrow->pose.orientation.x = orientation.x();
00074         arrow->pose.orientation.y = orientation.y();
00075         arrow->pose.orientation.z = orientation.z();
00076         arrow->pose.orientation.w = orientation.w();
00077 
00078     /*
00079     //   Diamondback
00080         arrow->scale.x = scale;
00081         arrow->scale.y = SCALE_ARROW_Y;
00082         arrow->scale.z = SCALE_ARROW_Z;
00083     */
00084 
00085     // Electric
00086         arrow->scale.x = SCALE_ARROW_Y;
00087         arrow->scale.y = SCALE_ARROW_Z;
00088         arrow->scale.z = scale;
00089 
00090         arrow->color.r = 1.0;
00091         arrow->color.g = 0;
00092         arrow->color.b = 0;
00093         arrow->color.a = 1.0;
00094 
00095         arrow->lifetime = ros::Duration(DURATION_ARROW);
00096 
00097     text->type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00098     text->action = visualization_msgs::Marker::ADD;
00099 
00100         text->pose.position.x = position.x() + nx * (scale + 0.04) * 1.4;
00101         text->pose.position.y = position.y() + ny * (scale + 0.04) * 1.4;
00102         text->pose.position.z = position.z() + nz * (scale + 0.04) * 1.4;
00103 
00104         text->pose.orientation.x = orientation.x();
00105         text->pose.orientation.y = orientation.y();
00106         text->pose.orientation.z = orientation.z();
00107         text->pose.orientation.w = orientation.w();
00108 
00109         text->scale.x = 0.03;
00110         text->scale.y = 0.03;
00111         text->scale.z = 0.03;
00112 
00113         text->color.r = 1.0;
00114         text->color.g = 0;
00115         text->color.b = 0;
00116         text->color.a = 1.0;
00117 
00118         text->lifetime = ros::Duration(DURATION_ARROW);
00119 
00120     char s[20];
00121     sprintf(s, "%.1fN", scale/SCALING_FACTOR);
00122     text->text = s;
00123     
00124 }
00125 
00126 void RosPressureVisualizer::DisplayPressure(
00127                 const hrl_haptic_manipulation_in_clutter_msgs::TaxelArray::ConstPtr& msg) {
00128         if (frequency_count < FREQUENCY_DIVISOR) {
00129                 frequency_count += 1;
00130                 return;
00131         }
00132 
00133         //ROS_INFO("Unlatching");
00134 
00135         frequency_count = 0;
00136 
00137         visualization_msgs::MarkerArray markerArray;
00138         visualization_msgs::MarkerArray textMarkerArray;
00139 
00140         // Compute the norm over all taxels and find out
00141         // which one we should display
00142         int size = msg->values_z.size();
00143         for (int i = 0; i < size; i++) {
00144                 double n = norm(msg->values_x[i], msg->values_y[i], msg->values_z[i]);
00145         double dot_prod = msg->values_x[i] * msg->normals_x[i] + \
00146                           msg->values_y[i] * msg->normals_y[i] + \
00147                           msg->values_z[i] * msg->normals_z[i];
00148         double sign = 1;
00149         if (dot_prod < 0)
00150             sign = -1;
00151 
00152                 //ROS_INFO("Norm %f", n);
00153                 if (n > MIN_PRESSURE_VALUE) {
00154             visualization_msgs::Marker m1, m2;
00155             GetArrowTextMarkers(taxels_transforms[i].getOrigin(),
00156                     taxels_arrows_quaternions[i],
00157                                         n * SCALING_FACTOR * sign, &m1, &m2, msg->normals_x[i],
00158                     msg->normals_y[i], msg->normals_z[i]);
00159                         m1.header.stamp = msg->header.stamp - ros::Duration(TF_TIME_OFFSET);
00160                         m1.header.frame_id = msg->header.frame_id;
00161                         m1.id = i;
00162                         markerArray.markers.push_back(m1);
00163 
00164                         m2.header.stamp = msg->header.stamp - ros::Duration(TF_TIME_OFFSET);
00165                         m2.header.frame_id = msg->header.frame_id;
00166                         m2.id = i;
00167                         textMarkerArray.markers.push_back(m2);
00168                         //ROS_INFO("Sending marker. Taxel %d, norm %f", i, n);
00169                 }
00170 
00171         }
00172 
00173         publisher_marker_array.publish(markerArray);
00174         publisher_text_marker_array.publish(textMarkerArray);
00175 }
00176 
00177 
00178 void RosPressureVisualizer::GetTaxelTransforms() {
00179         m3skin_ros::None_TransformArray srv;
00180 
00181                 if (local_coords_client.call(srv)) {
00182                         ROS_INFO("Got taxels frames.");
00183 
00184                         transforms = srv.response.data;
00185                         std::vector<geometry_msgs::Transform>::iterator it;
00186                         for (it = transforms.begin(); it != transforms.end(); it++) {
00187                                 //tf::Transform tf = GeometryTransformToTf(*it);
00188                                 tf::Transform tf;
00189                 tf::transformMsgToTF(*it, tf);
00190 
00191                                 taxels_transforms.push_back(tf);
00192                                 taxels_transforms_inv.push_back(tf.inverse());
00193                                 taxels_arrows_quaternions.push_back(tf*tf::Quaternion(0, -1, 0, 1));
00194                         }
00195                 } else {
00196                         ROS_ERROR("Failed to get taxels frames");
00197                 }
00198 }
00199 
00200 void RosPressureVisualizer::GetLinkName() {
00201         m3skin_ros::None_String srv;
00202 
00203         if (link_name_client.call(srv)) {
00204                 linkName = srv.response.data;
00205 
00206                 ROS_INFO("Got link name %s", linkName.c_str());
00207         } else {
00208                 ROS_ERROR("Failed to get link name");
00209         }
00210 }
00211 
00212 void RosPressureVisualizer::Init() {
00213     std::string local_coord_srv_name = "taxels/srv/local_coord_frames";
00214     std::string link_name_srv_name = "taxels/srv/link_name";
00215 
00216         local_coords_client = n.serviceClient<m3skin_ros::None_TransformArray> (local_coord_srv_name.c_str());
00217         link_name_client = n.serviceClient<m3skin_ros::None_String> (link_name_srv_name.c_str());
00218 
00219         publisher_marker_array = n.advertise<visualization_msgs::MarkerArray> (
00220                         "viz/taxel_array_array", 1000);
00221 
00222         publisher_text_marker_array = n.advertise<visualization_msgs::MarkerArray> (
00223                         "viz/taxel_array_text_array", 1000);
00224 
00225         subscriber = n.subscribe<hrl_haptic_manipulation_in_clutter_msgs::TaxelArray> (
00226                         "taxels/forces", 1000,
00227                         &RosPressureVisualizer::DisplayPressure, this);
00228 
00229     ROS_INFO("Waiting for services");
00230     ros::service::waitForService(local_coord_srv_name.c_str());
00231     ros::service::waitForService(link_name_srv_name.c_str());
00232     ROS_INFO("Done waiting");
00233 
00234         GetTaxelTransforms();
00235         GetLinkName();
00236 
00237         frequency_count = 0;
00238 }
00239 
00240 
00241 RosPressureVisualizer::RosPressureVisualizer() {
00242 
00243 }
00244 
00245 RosPressureVisualizer::~RosPressureVisualizer() {
00246         // TODO Auto-generated destructor stub
00247 }
00248 
00249 }


m3skin_viz
Author(s): Meka Robotics
autogenerated on Wed Nov 27 2013 11:35:59