model_node.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  *  Author : Dula Nad
00035  *  Created: 05.03.2013.
00036  *********************************************************************/
00037 #include <labust/xml/XMLReader.hpp>
00038 #include <labust/simulation/VehicleModel6DOF.hpp>
00039 #include <labust/vehicles/ScaleAllocation.hpp>
00040 #include <labust/tools/rosutils.hpp>
00041 #include <labust/tools/GeoUtilities.hpp>
00042 
00043 #include <auv_msgs/NavSts.h>
00044 #include <auv_msgs/BodyForceReq.h>
00045 #include <nav_msgs/Odometry.h>
00046 #include <std_msgs/String.h>
00047 #include <sensor_msgs/NavSatFix.h>
00048 #include <sensor_msgs/Imu.h>
00049 #include <sensor_msgs/FluidPressure.h>
00050 #include <geometry_msgs/TwistStamped.h>
00051 #include <tf/transform_broadcaster.h>
00052 #include <tf/transform_listener.h>
00053 #include <ros/ros.h>
00054 
00055 #include <Eigen/Dense>
00056 
00057 #include <boost/bind.hpp>
00058 
00059 #include <sstream>
00060 #include <string>
00061 
00062 double modelLat(0),modelLon(0);
00063 double originLat(0), originLon(0);
00064 double thrustScale(1);
00065 
00066 nav_msgs::Odometry* mapToUWSimOdometry(const labust::simulation::vector& eta,
00067                 const labust::simulation::vector& nu,
00068                 nav_msgs::Odometry* odom,
00069                 tf::TransformListener& lisWorld)
00070 {
00071         using namespace labust::simulation;
00072         using namespace Eigen;
00073 
00074         /*odom->pose.pose.position.x = eta(VehicleModel6DOF::x);
00075         odom->pose.pose.position.y = eta(VehicleModel6DOF::y);
00076         odom->pose.pose.position.z = eta(VehicleModel6DOF::z);
00077         Matrix3f m;
00078         m = AngleAxisf(eta(VehicleModel6DOF::psi), Vector3f::UnitZ())*
00079                 AngleAxisf(eta(VehicleModel6DOF::theta), Vector3f::UnitY())*
00080                 AngleAxisf(eta(VehicleModel6DOF::phi), Vector3f::UnitX());*/
00081 
00082         tf::StampedTransform transform;
00083         try
00084         {
00085             lisWorld.lookupTransform("uwsim_frame", "base_link", ros::Time(0), transform);
00086         }
00087         catch (tf::TransformException& ex)
00088         {
00089            ROS_ERROR("%s",ex.what());
00090         }
00091 
00092         /*Quaternion<float> q(m);
00093 
00094         odom->pose.pose.orientation.x = q.x();
00095         odom->pose.pose.orientation.y = q.y();
00096         odom->pose.pose.orientation.z = q.z();
00097         odom->pose.pose.orientation.w = q.w();*/
00098 
00099   odom->twist.twist.linear.x = nu(VehicleModel6DOF::u);
00100         odom->twist.twist.linear.y = nu(VehicleModel6DOF::v);
00101         odom->twist.twist.linear.z = nu(VehicleModel6DOF::w);
00102 
00103         odom->twist.twist.angular.x = nu(VehicleModel6DOF::p);
00104         odom->twist.twist.angular.y = nu(VehicleModel6DOF::q);
00105         odom->twist.twist.angular.z = nu(VehicleModel6DOF::r);
00106         odom->child_frame_id = "base_link";
00107 
00108         //tf::Quaternion q(tf::createQuaternionFromRPY(eta(VehicleModel6DOF::phi),eta(VehicleModel6DOF::theta),eta(VehicleModel6DOF::psi)));
00109         odom->pose.pose.orientation.x = transform.getRotation().x();
00110         odom->pose.pose.orientation.y = transform.getRotation().y();
00111         odom->pose.pose.orientation.z = transform.getRotation().z();
00112         odom->pose.pose.orientation.w = transform.getRotation().w();
00113 
00114         /*Quaternion<float> q;
00115         labust::tools::quaternionFromEuler(eta(VehicleModel6DOF::phi),
00116                         eta(VehicleModel6DOF::theta),
00117                         eta(VehicleModel6DOF::psi), q);
00118 
00119         odom->pose.pose.orientation.x = q.x();
00120         odom->pose.pose.orientation.y = q.y();
00121         odom->pose.pose.orientation.z = q.z();
00122         odom->pose.pose.orientation.w = q.w();*/
00123 
00124         odom->pose.pose.position.x = transform.getOrigin().x();
00125         odom->pose.pose.position.y = transform.getOrigin().y();
00126         odom->pose.pose.position.z = transform.getOrigin().z();
00127 
00128         odom->header.stamp = ros::Time::now();
00129         odom->header.frame_id = "uwsim_frame";
00130 
00131         return odom;
00132 }
00133 
00134 geometry_msgs::TwistStamped* mapToDvl(const labust::simulation::vector& eta,
00135                 const labust::simulation::vector& nu, geometry_msgs::TwistStamped* dvl,
00136                 tf::TransformBroadcaster& dvlBroadcast)
00137 {
00138         using namespace labust::simulation;
00139         dvl->twist.linear.x = nu(VehicleModel6DOF::u);
00140         dvl->twist.linear.y = nu(VehicleModel6DOF::v);
00141         dvl->twist.linear.z = nu(VehicleModel6DOF::w);
00142 
00143         dvl->header.frame_id="base_link";
00144         dvl->header.stamp = ros::Time::now();
00145 
00146         tf::Transform transform;
00147         transform.setOrigin(tf::Vector3(0, 0, 0));
00148         transform.setRotation(tf::createQuaternionFromRPY(0,0,0));
00149         dvlBroadcast.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base_link", "imu_frame"));
00150 
00151         return dvl;
00152 }
00153 
00154 auv_msgs::NavSts* mapToNavSts(const labust::simulation::vector& eta, const labust::simulation::vector& nu, auv_msgs::NavSts* nav)
00155 {
00156         using namespace labust::simulation;
00157         using namespace Eigen;
00158         nav->global_position.latitude = modelLat;
00159         nav->global_position.longitude = modelLon;
00160 
00161         nav->position.north = eta(VehicleModel6DOF::x);
00162         nav->position.east = eta(VehicleModel6DOF::y);
00163         nav->position.depth = eta(VehicleModel6DOF::z);
00164         nav->orientation.roll = eta(VehicleModel6DOF::phi);
00165         nav->orientation.pitch = eta(VehicleModel6DOF::theta);
00166         nav->orientation.yaw = eta(VehicleModel6DOF::psi);
00167 
00168         nav->body_velocity.x = nu(VehicleModel6DOF::u);
00169         nav->body_velocity.y = nu(VehicleModel6DOF::v);
00170         nav->body_velocity.z = nu(VehicleModel6DOF::w);
00171         nav->orientation_rate.roll = nu(VehicleModel6DOF::p);
00172         nav->orientation_rate.pitch = nu(VehicleModel6DOF::q);
00173         nav->orientation_rate.yaw = nu(VehicleModel6DOF::r);
00174 
00175         nav->header.stamp = ros::Time::now();
00176 
00177         return nav;
00178 }
00179 
00180 sensor_msgs::NavSatFix* mapToNavSatFix(const labust::simulation::vector& eta, const labust::simulation::vector& nu, sensor_msgs::NavSatFix* fix,
00181                 const std::string& utmzone, tf::TransformListener& lisWorld, tf::TransformBroadcaster& gpsBroadcast)
00182 {
00183         using namespace labust::simulation;
00184         using namespace Eigen;
00185 
00186         tf::StampedTransform transformLocal, transformDeg;
00187 
00188         try
00189         {
00190                 //In case the origin changes
00191                 lisWorld.lookupTransform("/worldLatLon", "/world", ros::Time(0), transformDeg);
00192                 originLat = transformDeg.getOrigin().y();
00193                 originLon = transformDeg.getOrigin().x();
00194         }
00195         catch (tf::TransformException& ex)
00196         {
00197            ROS_ERROR("%s",ex.what());
00198         }
00199 
00200         try
00201         {
00202             lisWorld.lookupTransform("base_link", "gps_frame", ros::Time(0), transformLocal);
00203             //lisWorld.lookupTransform("worldLatLon", "local", ros::Time(0), transformDeg);
00204 
00205                 fix->altitude = eta(VehicleModel6DOF::z) - transformLocal.getOrigin().z() ;
00206                 //gps_common::UTMtoLL(transform.getOrigin().y(), transform.getOrigin().x(), utmzone, fix->latitude, fix->longitude);
00207                 std::pair<double, double> diffAngle = labust::tools::meter2deg(eta(VehicleModel6DOF::x),
00208                         eta(VehicleModel6DOF::y),
00209                         //The latitude angle
00210                         originLat);
00211 
00212                 modelLat = fix->latitude = originLat + diffAngle.first;
00213                 modelLon = fix->longitude = originLon + diffAngle.second;
00214             fix->header.stamp = ros::Time::now();
00215             fix->header.frame_id = "worldLatLon";
00216 
00217                         tf::Transform transform;
00218                         Eigen::Quaternion<float> q;
00219                         transform.setOrigin(tf::Vector3(eta(VehicleModel6DOF::x),
00220                                         eta(VehicleModel6DOF::y),
00221                                         eta(VehicleModel6DOF::z)));
00222                         labust::tools::quaternionFromEulerZYX(eta(VehicleModel6DOF::phi),
00223                                         eta(VehicleModel6DOF::theta),
00224                                         eta(VehicleModel6DOF::psi), q);
00225                         transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00226                         gpsBroadcast.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "local", "base_link_noisy"));
00227         }
00228         catch (tf::TransformException& ex)
00229         {
00230            ROS_ERROR("%s",ex.what());
00231         }
00232 
00233         return fix;
00234 }
00235 
00236 sensor_msgs::Imu* mapToImu(const labust::simulation::vector& eta,
00237                 const labust::simulation::vector& nu, const labust::simulation::vector& nuacc,
00238                 sensor_msgs::Imu* imu, tf::TransformBroadcaster& imuBroadcast)
00239 {
00240         using namespace labust::simulation;
00241         using namespace Eigen;
00242 
00243         imu->header.stamp = ros::Time::now();
00244         imu->header.frame_id = "imu_frame";
00245         imu->linear_acceleration.x = nuacc(VehicleModel6DOF::x);
00246         imu->linear_acceleration.y = nuacc(VehicleModel6DOF::y);
00247         imu->linear_acceleration.z = nuacc(VehicleModel6DOF::z);
00248         imu->angular_velocity.x = nu(VehicleModel6DOF::p);
00249         imu->angular_velocity.y = nu(VehicleModel6DOF::q);
00250         imu->angular_velocity.z = nu(VehicleModel6DOF::r);
00251 
00252         Quaternion<float> quat;
00253         labust::tools::quaternionFromEulerZYX(eta(VehicleModel6DOF::phi),
00254                         eta(VehicleModel6DOF::theta),
00255                         eta(VehicleModel6DOF::psi), quat);
00256 
00257         imu->orientation.x = quat.x();
00258         imu->orientation.y = quat.y();
00259         imu->orientation.z = quat.z();
00260         imu->orientation.w = quat.w();
00261 
00262         tf::Transform transform;
00263         transform.setOrigin(tf::Vector3(0, 0, 0));
00264         transform.setRotation(tf::createQuaternionFromRPY(0,0,0));
00265         imuBroadcast.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base_link", "imu_frame"));
00266 
00267         return imu;
00268 }
00269 
00270 void handleTau(labust::simulation::vector* tauIn, const auv_msgs::BodyForceReq::ConstPtr& tau)
00271 {
00272         using namespace labust::simulation;
00273         (*tauIn)(VehicleModel6DOF::X) = thrustScale*tau->wrench.force.x;
00274         (*tauIn)(VehicleModel6DOF::Y) = thrustScale*tau->wrench.force.y;
00275         (*tauIn)(VehicleModel6DOF::Z) = thrustScale*tau->wrench.force.z;
00276         (*tauIn)(VehicleModel6DOF::K) = thrustScale*tau->wrench.torque.x;
00277         (*tauIn)(VehicleModel6DOF::M) = thrustScale*tau->wrench.torque.y;
00278         (*tauIn)(VehicleModel6DOF::N) = thrustScale*tau->wrench.torque.z;
00279 };
00280 
00281 void handleCurrent(labust::simulation::vector* current, const std_msgs::String::ConstPtr& data)
00282 {
00283         std::istringstream out(data->data);
00284         float a;
00285         out>>(*current)(0)>>(*current)(1)>>(*current)(2);;
00286 };
00287 
00288 //Simple dynamics simulation only ROS node
00289 //\todo Add allocation algorithm
00290 //\todo Add thruster nonlinearity ?
00291 //\todo Separate GPS, Imu sim into simulation nodelets with noise
00292 int main(int argc, char* argv[])
00293 {
00294         ros::init(argc,argv,"model_node");
00295 
00296         //Initialize the simulator
00297         labust::xml::ReaderPtr reader(new labust::xml::Reader(argv[1],true));
00298         reader->useNode(reader->value<_xmlNode*>("//configurations"));
00299         labust::simulation::VehicleModel6DOF model(reader);
00300 
00301         ros::NodeHandle nh,ph("~");
00302 
00303         //Publishers
00304         ros::Publisher state = nh.advertise<auv_msgs::NavSts>("meas",1);
00305         ros::Publisher stateNoisy = nh.advertise<auv_msgs::NavSts>("noisy_meas",1);
00306         //ros::Publisher uwsim = nh.advertise<nav_msgs::Odometry>("uwsim_hook",1);
00307         ros::Publisher tauAch = nh.advertise<auv_msgs::BodyForceReq>("tauAch",1);
00308         ros::Publisher gpsFix = nh.advertise<sensor_msgs::NavSatFix>("fix",1);
00309         ros::Publisher imuMeas = nh.advertise<sensor_msgs::Imu>("imu_model",1);
00310         ros::Publisher dvlMeas = nh.advertise<geometry_msgs::TwistStamped>("dvl",1);
00311         ros::Publisher pressureMeas = nh.advertise<sensor_msgs::FluidPressure>("pressure",1);
00312         //Subscribers
00313         labust::simulation::vector tau(labust::simulation::zero_v(6)), current(labust::simulation::zero_v(3));
00314         ros::Subscriber tauSub = nh.subscribe<auv_msgs::BodyForceReq>("tauIn", 1, boost::bind(&handleTau,&tau,_1));
00315         ros::Subscriber curSub = nh.subscribe<std_msgs::String>("currents", 1, boost::bind(&handleCurrent,&current,_1));
00316         //Transform broadcasters
00317         tf::TransformBroadcaster localFrame;
00318         tf::TransformListener lisWorld;
00319         bool publishWorld, useNoisy;
00320         double gpsTime;
00321         nh.param("LocalOriginLat",originLat,originLat);
00322         nh.param("LocalOriginLon",originLon,originLon);
00323         ph.param("publish_world", publishWorld, true);
00324         ph.param("use_noise", useNoisy, false);
00325         ph.param("gps_time",gpsTime,1.0);
00326         ph.param("thrustScale",thrustScale,1.0);
00327 
00328         std::string utmzone;
00329         /*/double northing, easting;
00330         tf::Transform transform;
00331         gps_common::LLtoUTM(originLat, originLon,northing,easting,utmzone);
00332         std::cout.precision(10);
00333         std::cout<<"Northing:"<<northing<<","<<easting<<std::endl;*/
00334 
00335         auv_msgs::NavSts nav,navNoisy;
00336         nav_msgs::Odometry odom;
00337         sensor_msgs::NavSatFix fix;
00338         sensor_msgs::Imu imu;
00339         geometry_msgs::TwistStamped dvl;
00340         sensor_msgs::FluidPressure depth;
00341 
00342         double fs(10);
00343         int wrap(1);
00344         ph.param("Rate",fs,fs);
00345         ph.param("ModelWrap",wrap,wrap);
00346         ros::Rate rate(fs);
00347         model.setTs(1/(fs*wrap));
00348 
00349         //Construct the allocation matrix for the vehicle.
00350         //We can have it fixed here since this is a specific application.
00351         //\todo Use real thruster angles instead of 45 degree
00352         Eigen::Matrix<float, 3,4> B;
00353         float cp(cos(M_PI/4)),sp(sin(M_PI/4));
00354         B<<cp,cp,cp,cp,
00355            sp,-sp,-sp,sp,
00356            1,-1,1,-1;
00357 
00358         double maxThrust(100/(2*cp)),minThrust(-maxThrust);
00359         ph.param("maxThrust",maxThrust,maxThrust);
00360         ph.param("minThrust",minThrust,-maxThrust);
00361 
00362 
00363         //Scaling allocation only for XYN
00364         labust::vehicles::ScaleAllocation allocator(B,maxThrust,minThrust);
00365 
00366         ros::Time lastGps = ros::Time::now();
00367         while (ros::ok())
00368         {
00369                 using namespace labust::simulation;
00370                 Eigen::Vector3f tauXYN,tauXYNsc;
00371                 tauXYN<<tau(VehicleModel6DOF::X),tau(VehicleModel6DOF::Y),tau(VehicleModel6DOF::N);
00372                 double scale = allocator.scale(tauXYN,&tauXYNsc);
00373 
00374 //              tau(VehicleModel6DOF::X) = labust::math::coerce(tau(VehicleModel6DOF::X), minThrust, maxThrust);
00375 //              tau(VehicleModel6DOF::N) = labust::math::coerce(tau(VehicleModel6DOF::N), minThrust, maxThrust);
00376 //
00377 //              //Differential allocation
00378 //              double t1 = (tau(VehicleModel6DOF::X) + tau(VehicleModel6DOF::N))/2;
00379 //              double t2 = (tau(VehicleModel6DOF::X) - tau(VehicleModel6DOF::N))/2;
00380 //
00381 //              t1 = labust::math::coerce(t1, minThrust, maxThrust);
00382 //              t2 = labust::math::coerce(t2, minThrust, maxThrust);
00383 
00384                 auv_msgs::BodyForceReq t;
00385                 //tau(VehicleModel6DOF::X) = t.wrench.force.x = t1+t2;
00386                 tau(VehicleModel6DOF::X) = t.wrench.force.x = tauXYNsc(0);
00387                 tau(VehicleModel6DOF::Y) = t.wrench.force.y = tauXYNsc(1);
00388                 t.wrench.force.z = tau(VehicleModel6DOF::Z);
00389                 t.wrench.torque.x = tau(VehicleModel6DOF::K);
00390                 t.wrench.torque.y = tau(VehicleModel6DOF::M);
00391                 tau(VehicleModel6DOF::N) = t.wrench.torque.z = tauXYNsc(2);
00392                 //tau(VehicleModel6DOF::N) = t.wrench.torque.z = t1-t2;
00393                 t.header.stamp = ros::Time::now();
00394 
00395                 //t.disable_axis.x = tau(VehicleModel6DOF::X) != tauXYN(0);
00396                 //t.disable_axis.yaw = tau(VehicleModel6DOF::N) != tauXYN(2);
00397 
00398                 //scale = 1;
00399 
00400                 //Publish the scaled values if scaling occured
00401                 if (scale>1)
00402                 {
00403                         //Signal windup occured
00404                         t.disable_axis.x = t.disable_axis.y = t.disable_axis.yaw = 1;
00405                 }
00406 
00407                 tauAch.publish(t);
00408 
00409                 model.setCurrent(current);
00410                 //Perform simulation with smaller sampling type if wrap>1
00411                 for (size_t i=0; i<wrap;++i) model.step(tau);
00412 
00413                 //uwsim.publish(*mapToUWSimOdometry(model.Eta(),model.Nu(),&odom, lisWorld));
00414                 state.publish(*mapToNavSts(model.Eta(),model.Nu(),&nav));
00415                 stateNoisy.publish(*mapToNavSts(model.EtaNoisy(),model.NuNoisy(),&navNoisy));
00416 
00417                 const vector& Nu = (useNoisy?model.NuNoisy():model.Nu());
00418                 const vector& Eta = (useNoisy?model.EtaNoisy():model.Eta());
00419                 if ((ros::Time::now()-lastGps).sec >= gpsTime)
00420                 {
00421                         mapToNavSatFix(Eta,Nu,&fix,utmzone,lisWorld,localFrame);
00422                         if (fix.altitude >= 0)
00423                         {
00424                                 gpsFix.publish(fix);
00425                         }
00426                         lastGps = ros::Time::now();
00427                 }
00428 
00429                 imuMeas.publish(*mapToImu(Eta,Nu,model.NuAcc(),&imu,localFrame));
00430                 dvlMeas.publish(*mapToDvl(Eta,Nu,&dvl,localFrame));
00431                 depth.fluid_pressure = model.getPressure(Eta(VehicleModel6DOF::z));
00432                 depth.header.frame_id = "local";
00433                 pressureMeas.publish(depth);
00434 
00435                 tf::Transform transform;
00436                 transform.setOrigin(tf::Vector3(originLon, originLat, 0));
00437                 transform.setRotation(tf::createQuaternionFromRPY(0,0,0));
00438                 Eigen::Quaternion<float> q;
00439                 labust::tools::quaternionFromEulerZYX(M_PI,0,M_PI/2,q);
00440                 if (publishWorld)
00441                 {
00442                         localFrame.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "/worldLatLon", "/world"));
00443                         transform.setOrigin(tf::Vector3(0, 0, 0));
00444                         transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00445                         localFrame.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "/world", "local"));
00446                 }
00447 
00448                 tf::Transform transform3;
00449                 transform3.setOrigin(tf::Vector3(0, 0, 0));
00450                 q = q.conjugate();
00451                 transform3.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00452                 localFrame.sendTransform(tf::StampedTransform(transform3, ros::Time::now(), "local", "uwsim_frame"));
00453 
00454                 const vector& eta = model.Eta();
00455                 //tf::Transform transform;
00456                 transform.setOrigin(tf::Vector3(eta(VehicleModel6DOF::x),
00457                                 eta(VehicleModel6DOF::y),
00458                                 eta(VehicleModel6DOF::z)));
00459                 labust::tools::quaternionFromEulerZYX(eta(VehicleModel6DOF::phi),
00460                                 eta(VehicleModel6DOF::theta),
00461                                 eta(VehicleModel6DOF::psi), q);
00462                 transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00463                 localFrame.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "local", "base_link_sim"));
00464 
00465                 tf::Transform transform2;
00466                 transform2.setOrigin(tf::Vector3(0, 0, -0.25));
00467                 transform2.setRotation(tf::createQuaternionFromRPY(0,0,0));
00468                 localFrame.sendTransform(tf::StampedTransform(transform2, ros::Time::now(), "base_link", "gps_frame"));
00469 
00470                 rate.sleep();
00471                 ros::spinOnce();
00472         }
00473 
00474         return 0;
00475 }
00476 


ldtravocean
Author(s):
autogenerated on Fri Feb 7 2014 11:37:01