00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
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         
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         
00063 
00064 
00065 
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                 
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                 
00112                 
00113                 labust::tools::eulerZYXFromQuaternion(result, rpy[roll], rpy[pitch], rpy[yaw]);
00114                 rpy[yaw] = unwrap(rpy[yaw]);
00115 
00116                 
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                 
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         
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                         
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                         
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 }