RosTaxelsTransformNode.cpp
Go to the documentation of this file.
00001 /*
00002  * M3 Component to abstract PDO over serial (rather than ethercat)
00003  * Copyright (C) 2011  Meka Robotics
00004  * Author: Pierre-Luc Bacon <pierrelucbacon@mekabot.com>
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  */
00020 
00021 #include "RosTaxelsTransformNode.h"
00022 #include <m3skin_ros/None_TransformArray.h>
00023 #include <m3skin_ros/None_String.h>
00024 #include <math.h>
00025 namespace m3 {
00026 
00027 double RosTaxelsTransformNode::GetUnbiased(unsigned value, unsigned index)
00028 {
00029     double unbiased = (((double) value) - ((double)biases[index]))/(65535.0 - ((double) biases[index]));
00030     if (unbiased < 0.0) {
00031         unbiased = 0.0;
00032     }
00033 
00034     //ROS_INFO("Before : %d After %f Bias %d In Newtons %f", value, unbiased, biases[index], unbiased*MAX_VALUE);
00035 
00036     return unbiased;
00037 }
00038 
00039 m3skin_ros::RawTaxelArray RosTaxelsTransformNode::FilterRaw(const m3skin_ros::RawTaxelArray::ConstPtr& msg)
00040 {
00041         m3skin_ros::RawTaxelArray outMsg;
00042         outMsg.val_x = msg->val_x;
00043         outMsg.val_y = msg->val_y;
00044 
00045         std::size_t n = msg->val_z.size();
00046         for (unsigned i = 0; i < n; i++) {
00047                 outMsg.val_z.push_back(GetUnbiased(msg->val_z[i], i)*MAX_VALUE);
00048         }
00049 
00050         return outMsg;
00051 }
00052 
00053 void RosTaxelsTransformNode::TransformMessage(
00054                 const m3skin_ros::RawTaxelArray::ConstPtr& msg) {
00055 
00056         if (IsCalibrateMode()) {
00057                 CalibrateBias(msg->val_z);
00058                 return;
00059         }
00060 
00061         m3skin_ros::RawTaxelArray filteredMsg = FilterRaw(msg);
00062         std::size_t n = filteredMsg.val_z.size();
00063 
00064         m3skin_ros::TaxelArray output_msg;
00065         // Header
00066         output_msg.header.frame_id = linkName;
00067         output_msg.header.stamp = ros::Time::now();
00068 
00069         // Body
00070         for (unsigned i = 0; i < n; i++) {
00071                 if (i >= fullTfs.size()) {
00072                         ROS_ERROR("No transform for taxel %d", i);
00073                         break;
00074                 }
00075                 tf::Vector3 center = centers[i];
00076                 tf::Vector3 normal = normals[i];
00077                 tf::Vector3 force = fullTfs[i](tf::Vector3(0, 0, filteredMsg.val_z[i]));
00078 
00079                 output_msg.centers_x.push_back(center.getX());
00080                 output_msg.centers_y.push_back(center.getY());
00081                 output_msg.centers_z.push_back(center.getZ());
00082 
00083                 output_msg.normals_x.push_back(normal.getX());
00084                 output_msg.normals_y.push_back(normal.getY());
00085                 output_msg.normals_z.push_back(normal.getZ());
00086 
00087                 output_msg.values_x.push_back(force.getX());
00088                 output_msg.values_y.push_back(force.getY());
00089                 output_msg.values_z.push_back(force.getZ());
00090         }
00091 
00092         publisher.publish(output_msg);
00093 }
00094 
00095 tf::Transform RosTaxelsTransformNode::GeometryTransformToTf(geometry_msgs::Transform& gtf) {
00096         tf::Transform tf;
00097 
00098         tf.setOrigin(tf::Vector3(gtf.translation.x,
00099                         gtf.translation.y,
00100                         gtf.translation.z));
00101 
00102         tf.setRotation(tf::Quaternion(gtf.rotation.x,
00103                         gtf.rotation.y,
00104                         gtf.rotation.z,
00105                         gtf.rotation.w));
00106 
00107         return tf;
00108 }
00109 
00110 void RosTaxelsTransformNode::GetTaxelTransforms() {
00111         m3skin_ros::None_TransformArray srv;
00112 
00113         if (local_coords_client.call(srv)) {
00114                 ROS_INFO("Got taxels frames.");
00115 
00116                 transforms = srv.response.data;
00117                 std::vector<geometry_msgs::Transform>::iterator it;
00118                 for (it = transforms.begin(); it != transforms.end(); it++) {
00119                         fullTfs.push_back(GeometryTransformToTf(*it));
00120                 }
00121         } else {
00122                 ROS_ERROR("Failed to get taxels frames");
00123         }
00124 }
00125 
00126 void RosTaxelsTransformNode::InitStaticVectors() {
00127         centers.clear();
00128         normals.clear();
00129 
00130         std::vector<tf::Transform>::iterator it;
00131         for (it = fullTfs.begin(); it != fullTfs.end(); it++) {
00132                 centers.push_back((*it)(tf::Vector3(0, 0, 0)));
00133                 normals.push_back((*it)(tf::Vector3(0, 0, 1)));
00134         }
00135 }
00136 
00137 void RosTaxelsTransformNode::GetLinkName() {
00138         m3skin_ros::None_String srv;
00139 
00140         if (link_name_client.call(srv)) {
00141                 linkName = srv.response.data;
00142 
00143                 ROS_INFO("Got link name %s", linkName.c_str());
00144         } else {
00145                 ROS_ERROR("Failed to get link name");
00146         }
00147 }
00148 
00149 void RosTaxelsTransformNode::SetCalibrateMode(bool on)
00150 {
00151         if (on) {
00152                 number_samples = 0;
00153         }
00154 
00155         calibrating = on;
00156 }
00157 
00158 bool RosTaxelsTransformNode::IsCalibrateMode() {
00159         return calibrating;
00160 }
00161 
00162 void RosTaxelsTransformNode::CalibrateBias(std::vector<int> values) {
00163 
00164         if (number_samples == 0) {
00165                 biases.clear();
00166 
00167                 std::vector<int>::iterator it;
00168                 for (it = values.begin(); it != values.end(); it++) {
00169                         biases.push_back((*it));
00170                 }
00171 
00172                 ROS_INFO("Initialized bias");
00173                 number_samples = 1;
00174                 return;
00175         }
00176 
00177         ROS_INFO("Calibrating bias %d/%d", number_samples, number_samples_target);
00178 
00179         for (unsigned i = 0; i < values.size(); i++) {
00180                 //ROS_INFO("%d %d = %d", biases[i], values[i], (biases[i] + values[i])/2);
00181 //              if ((biases[i] + values[i])/2.0 != 65535) {
00182 //                      ROS_INFO("index value %d %f %d %d", i, biases[i], values[i], (unsigned) floor(biases[i] + 0.5));
00183 //              }
00184 
00185                 biases[i] = floor(((biases[i] + values[i])/2.0) + 0.5);
00186         }
00187 
00188         number_samples += 1;
00189 
00190         if (number_samples == number_samples_target) {
00191                 SetCalibrateMode(false);
00192                 number_samples = 0;
00193         }
00194 }
00195 
00196 
00197 void RosTaxelsTransformNode::Init(unsigned calibration_samples) {
00198     std::string local_coord_srv_name = "/skin_patch_forearm_right/taxels/srv/local_coord_frames";
00199     std::string link_name_srv_name = "/skin_patch_forearm_right/taxels/srv/link_name";
00200 
00201     local_coords_client = n.serviceClient<m3skin_ros::None_TransformArray> (local_coord_srv_name.c_str());
00202     link_name_client = n.serviceClient<m3skin_ros::None_String> (link_name_srv_name.c_str());
00203 
00204         publisher = n.advertise<m3skin_ros::TaxelArray> (
00205                         "/skin_patch_forearm_right/taxels/forces", 1000);
00206 
00207         subscriber = n.subscribe<m3skin_ros::RawTaxelArray> (
00208                         "/skin_patch_forearm_right/taxels/raw_data", 1000,
00209                         &RosTaxelsTransformNode::TransformMessage, this);
00210 
00211     ROS_INFO("Waiting for services");
00212     ros::service::waitForService(local_coord_srv_name.c_str());
00213     ros::service::waitForService(link_name_srv_name.c_str());
00214     ROS_INFO("Done waiting");
00215 
00216         GetTaxelTransforms();
00217         InitStaticVectors();
00218         GetLinkName();
00219 
00220         // Initialize the biases full of 0
00221         biases = std::vector<double>(number_taxels, 0);
00222 
00223         number_samples_target = calibration_samples;
00224 
00225         if (number_samples_target) {
00226             SetCalibrateMode(true);
00227         }
00228 }
00229 
00230 
00231 RosTaxelsTransformNode::RosTaxelsTransformNode() : number_samples(0), calibrating(false) {
00232 
00233 }
00234 
00235 RosTaxelsTransformNode::~RosTaxelsTransformNode() {
00236         // TODO Auto-generated destructor stub
00237 }
00238 
00239 }


m3skin_calibration
Author(s): Meka Robotics
autogenerated on Wed Nov 27 2013 11:35:46