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 }