Go to the documentation of this file.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 
00035 
00036 
00037 #include <labust/tools/conversions.hpp>
00038 
00039 #include <nav_msgs/Odometry.h>
00040 #include <geometry_msgs/TwistStamped.h>
00041 #include <std_msgs/Float32.h>
00042 #include <ros/ros.h>
00043 
00044 #include <Eigen/Dense>
00045 
00046 struct DvlSim
00047 {
00048         DvlSim():
00049                 maxBottomLock(100),
00050                 maxDepth(100),
00051                 dvl_pub(1)
00052         {
00053                 ros::NodeHandle nh,ph("~");
00054 
00055                 ph.param("MaxBottomLock",maxBottomLock, maxBottomLock);
00056                 ph.param("MaxDepth", maxDepth, maxDepth);
00057                 ph.param("DvlPub", dvl_pub, dvl_pub);
00058 
00059                 odom = nh.subscribe<nav_msgs::Odometry>("meas_odom",1,&DvlSim::onOdom, this);
00060                 dvl_nu = nh.advertise<geometry_msgs::TwistStamped>("dvl",1);
00061                 dvl_ned = nh.advertise<geometry_msgs::TwistStamped>("dvl_ned",1);
00062                 altitude_pub = nh.advertise<std_msgs::Float32>("altitude",1);
00063 
00064                 last_pos[0] = last_pos[1] = last_pos[2] = 0;
00065         }
00066 
00067         void onOdom(const typename nav_msgs::Odometry::ConstPtr& msg)
00068         {
00069                 static int i=0;
00070                 i=++i%dvl_pub;
00071 
00072                 if (i == 0)
00073                 {
00074                         double dT = (ros::Time::now() - lastTime).toSec();
00075                         lastTime = ros::Time::now();
00076                         geometry_msgs::TwistStamped::Ptr dvl(new geometry_msgs::TwistStamped());
00077                         dvl->header.stamp = ros::Time::now();
00078                         dvl->header.frame_id = msg->header.frame_id;
00079                         double pos[3],v[3];
00080                         labust::tools::pointToVector(msg->pose.pose.position, pos);
00081                         for (int i=0; i<3; ++i)
00082                         {
00083                                 v[i] = (pos[i] - last_pos[i])/dT;
00084                                 last_pos[i] = pos[i];
00085                         }
00086                         labust::tools::vectorToPoint(v, dvl->twist.linear);
00087                         dvl_ned.publish(dvl);
00088 
00089                         dvl.reset(new geometry_msgs::TwistStamped());
00090                         dvl->header.stamp = ros::Time::now();
00091                         dvl->header.frame_id = msg->child_frame_id;
00092                         
00093                         Eigen::Quaternion<double> q(msg->pose.pose.orientation.w,
00094                                         msg->pose.pose.orientation.x,
00095                                         msg->pose.pose.orientation.y,
00096                                         msg->pose.pose.orientation.z);
00097                         Eigen::Vector3d nu = q.matrix().transpose() * Eigen::Vector3d(v[0],v[1],v[2]);
00098                         dvl->twist.linear.x = nu(0);
00099                         dvl->twist.linear.y = nu(1);
00100                         dvl->twist.linear.z = nu(2);
00101                         dvl_nu.publish(dvl);
00102 
00103                         if ((maxDepth - msg->pose.pose.position.z) < maxBottomLock)
00104                         {
00105                                 std_msgs::Float32::Ptr altitude(new std_msgs::Float32());
00106                                 altitude->data = maxDepth - msg->pose.pose.position.z;
00107                                 altitude_pub.publish(altitude);
00108                         }
00109                 }
00110         }
00111 
00112 private:
00113         ros::Subscriber odom;
00114         ros::Publisher dvl_nu, altitude_pub, dvl_ned;
00115         ros::Time lastTime;
00116         double last_pos[3];
00117         int dvl_pub;
00118         double maxBottomLock, maxDepth;
00119 };
00120 
00121 int main(int argc, char* argv[])
00122 {
00123         ros::init(argc,argv,"dvl_sim");
00124         ros::NodeHandle nh;
00125         DvlSim dvl;
00126         ros::spin();
00127         return 0;
00128 }
00129 
00130