SensorHandlers.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, LABUST, UNIZG-FER
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the LABUST nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 #include <labust/navigation/SensorHandlers.hpp>
00035 #include <labust/math/NumberManipulation.hpp>
00036 #include <labust/tools/GeoUtilities.hpp>
00037 #include <labust/tools/conversions.hpp>
00038 
00039 #include <geometry_msgs/TransformStamped.h>
00040 #include <Eigen/Dense>
00041 
00042 using namespace labust::navigation;
00043 
00044 void GPSHandler::configure(ros::NodeHandle& nh)
00045 {
00046         gps = nh.subscribe<sensor_msgs::NavSatFix>("gps", 1,
00047                         &GPSHandler::onGps, this);
00048 }
00049 
00050 void GPSHandler::onGps(const sensor_msgs::NavSatFix::ConstPtr& data)
00051 {
00052         //Calculate to X-Y tangent plane
00053         geometry_msgs::TransformStamped transformDeg, transformLocal, transformGPS;
00054         try
00055         {
00056                 transformLocal = buffer.lookupTransform("local", "gps_frame", ros::Time(0));
00057                 transformGPS = buffer.lookupTransform("base_link", "gps_frame", ros::Time(0));
00058                 transformDeg = buffer.lookupTransform("worldLatLon", "local", ros::Time(0));
00059                 posxy = labust::tools::deg2meter(data->latitude - transformDeg.transform.translation.y,
00060                                         data->longitude - transformDeg.transform.translation.x,
00061                                         transformDeg.transform.translation.y);
00062         /*      Eigen::Quaternion<double> rot(transformLocal.transform.rotation.w,
00063                                 transformLocal.transform.rotation.x,
00064                                 transformLocal.transform.rotation.y,
00065                                 transformLocal.transform.rotation.z);*/
00066                 Eigen::Vector3d offset(transformGPS.transform.translation.x,
00067                                 transformGPS.transform.translation.y,
00068                                 transformGPS.transform.translation.z);
00069                 Eigen::Vector3d pos_corr = rot.matrix()*offset;
00070 
00071                 posxy.first -= pos_corr(0);
00072                 posxy.second -= pos_corr(1);
00073                 
00074                 //ROS_ERROR("Corrected position: %f %f", pos_corr(0), pos_corr(1));
00075                 
00076                 originLL.first = transformDeg.transform.translation.y;
00077                 originLL.second = transformDeg.transform.translation.x;
00078 
00079                 std::pair<double, double> posxy_corr = labust::tools::meter2deg(posxy.first, posxy.second, transformDeg.transform.translation.y);
00080                 posLL.first = originLL.first + posxy_corr.first;
00081                 posLL.second = originLL.second + posxy_corr.second;
00082 
00083                 isNew = true;
00084         }
00085         catch(tf2::TransformException& ex)
00086         {
00087                 ROS_WARN("Unable to decode GPS measurement. Missing frame : %s",ex.what());
00088         }
00089 };
00090 
00091 void ImuHandler::configure(ros::NodeHandle& nh)
00092 {
00093         imu = nh.subscribe<sensor_msgs::Imu>("imu", 1,
00094                         &ImuHandler::onImu, this);
00095 }
00096 
00097 void ImuHandler::onImu(const sensor_msgs::Imu::ConstPtr& data)
00098 {
00099         geometry_msgs::TransformStamped transform;
00100         try
00101         {
00102                 transform = buffer.lookupTransform("base_link", "imu_frame", ros::Time(0));
00103                 Eigen::Quaternion<double> meas(data->orientation.w, data->orientation.x,
00104                                 data->orientation.y, data->orientation.z);
00105                 Eigen::Quaternion<double> rot(transform.transform.rotation.w,
00106                                 transform.transform.rotation.x,
00107                                 transform.transform.rotation.y,
00108                                 transform.transform.rotation.z);
00109                 Eigen::Quaternion<double> result = meas*rot;
00110                 if (gps != 0) gps->setRotation(result);
00111                 //KDL::Rotation::Quaternion(result.x(),result.y(),result.z(),result.w()).GetEulerZYX
00112                 //              (rpy[yaw],rpy[pitch],rpy[roll]);
00113                 labust::tools::eulerZYXFromQuaternion(result, rpy[roll], rpy[pitch], rpy[yaw]);
00114                 rpy[yaw] = unwrap(rpy[yaw]);
00115 
00116                 //Transform angular velocities
00117                 Eigen::Vector3d angvel;
00118                 angvel<<data->angular_velocity.x,
00119                                 data->angular_velocity.y,
00120                                 data->angular_velocity.z;
00121                 angvel = meas*angvel;
00122 
00123                 pqr[p] = angvel(0);
00124                 pqr[q] = angvel(1);
00125                 pqr[r] = angvel(2);
00126 
00127                 //Transform the accelerations
00128                 angvel<<data->linear_acceleration.x,
00129                                 data->linear_acceleration.y,
00130                                 data->linear_acceleration.z;
00131                 angvel = meas*angvel;
00132 
00133                 axyz[ax] = angvel(0);
00134                 axyz[ay] = angvel(1);
00135                 axyz[az] = angvel(2);
00136 
00137                 isNew = true;
00138         }
00139         catch (tf2::TransformException& ex)
00140         {
00141                 ROS_WARN("Failed converting the IMU data: %s",ex.what());
00142         }
00143 };
00144 
00145 void DvlHandler::configure(ros::NodeHandle& nh)
00146 {
00147         nu_dvl = nh.subscribe<geometry_msgs::TwistStamped>("dvl", 1,
00148                         &DvlHandler::onDvl, this);
00149         nu_dvl = nh.subscribe<std_msgs::Bool>("dvl_bottom", 1,
00150                         &DvlHandler::onBottomLock, this);
00151 
00152         bottom_lock = false;
00153 
00154 
00155         uvw[u] = uvw[v] = uvw[w] = 0;
00156 }
00157 
00158 void DvlHandler::onBottomLock(const std_msgs::Bool::ConstPtr& data)
00159 {
00160                 this->bottom_lock = data->data;
00161 }
00162 
00163 void DvlHandler::onDvl(const geometry_msgs::TwistStamped::ConstPtr& data)
00164 {
00165         //Ignore water lock data (?)
00166         if (!bottom_lock) return;
00167 
00168         if (data->header.frame_id == "dvl_frame")
00169         {
00170                 try
00171                 {
00172                         geometry_msgs::TransformStamped transform;
00173                         transform = buffer.lookupTransform("base_link", "dvl_frame", ros::Time(0));
00174 
00175                         Eigen::Vector3d speed(data->twist.linear.x, data->twist.linear.y, data->twist.linear.z);
00176                         Eigen::Quaternion<double> rot(transform.transform.rotation.w,
00177                                         transform.transform.rotation.x,
00178                                         transform.transform.rotation.y,
00179                                         transform.transform.rotation.z);
00180                         Eigen::Vector3d body_speed = rot.matrix()*speed;
00181 
00182                         //Add compensation for excentralized DVL
00183                         Eigen::Vector3d origin(transform.transform.translation.x,
00184                                         transform.transform.translation.y,
00185                                         transform.transform.translation.z);
00186                         if (origin.x() != 0 || origin.y() != 0)
00187                         {
00188 
00189                                 body_speed -= Eigen::Vector3d(-r*origin.y(),r*origin.x(),0);
00190                         }
00191 
00192                         uvw[u] = body_speed.x();
00193                         uvw[v] = body_speed.y();
00194                         uvw[w] = body_speed.z();
00195                 }
00196                 catch (std::exception& ex)
00197                 {
00198                         ROS_WARN("DVL measurement failure:%s",ex.what());
00199                         isNew = false;
00200                         return;
00201                 }
00202         }
00203         else if (data->header.frame_id == "base_link")
00204         {
00205                 uvw[u] = data->twist.linear.x;
00206                 uvw[v] = data->twist.linear.y;
00207                 uvw[w] = data->twist.linear.z;
00208         }
00209         else if (data->header.frame_id == "local")
00210         {
00211                 geometry_msgs::TransformStamped transform;
00212                 Eigen::Vector3d meas(data->twist.linear.x,
00213                                 data->twist.linear.y,
00214                                 data->twist.linear.z);
00215                 Eigen::Quaternion<double> rot(transform.transform.rotation.w,
00216                                 transform.transform.rotation.x,
00217                                 transform.transform.rotation.y,
00218                                 transform.transform.rotation.z);
00219                 transform = buffer.lookupTransform("local", "base_link", ros::Time(0));
00220                 Eigen::Vector3d result = rot.matrix()*meas;
00221                 uvw[u] = result.x();
00222                 uvw[v] = result.y();
00223                 uvw[w] = result.z();
00224         }
00225         else if (data->header.frame_id == "gps_frame")
00226         {
00227                 try
00228                 {
00229                         geometry_msgs::TransformStamped transform;
00230                         transform = buffer.lookupTransform("base_link", "gps_frame", ros::Time(0));
00231 
00232                         Eigen::Vector3d speed(data->twist.linear.x, data->twist.linear.y, data->twist.linear.z);
00233                         Eigen::Quaternion<double> rot(transform.transform.rotation.w,
00234                                         transform.transform.rotation.x,
00235                                         transform.transform.rotation.y,
00236                                         transform.transform.rotation.z);
00237                         Eigen::Vector3d body_speed = rot.matrix()*speed;
00238 
00239                         //Add compensation for excentralized GPS
00240                         Eigen::Vector3d origin(transform.transform.translation.x,
00241                                         transform.transform.translation.y,
00242                                         transform.transform.translation.z);
00243                         if (origin.x() != 0 || origin.y() != 0)
00244                         {
00245 
00246                                 body_speed -= Eigen::Vector3d(-r*origin.y(),r*origin.x(),0);
00247                         }
00248 
00249                         uvw[u] = body_speed.x();
00250                         uvw[v] = body_speed.y();
00251                         uvw[w] = body_speed.z();
00252                 }
00253                 catch (std::exception& ex)
00254                 {
00255                         ROS_WARN("DVL measurement failure:%s",ex.what());
00256                         isNew = false;
00257                         return;
00258                 }
00259         }
00260         else
00261         {
00262                 isNew = false;
00263                 return;
00264         }
00265 
00266         isNew = true;
00267 }


labust_navigation
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:23:33