EKF3D.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: 26.03.2013.
00036  *********************************************************************/
00037 #include <labust/navigation/EKF3D.hpp>
00038 #include <labust/navigation/LDTravModelExtended.hpp>
00039 #include <labust/tools/GeoUtilities.hpp>
00040 #include <labust/tools/MatrixLoader.hpp>
00041 #include <labust/tools/conversions.hpp>
00042 #include <labust/tools/DynamicsLoader.hpp>
00043 #include <labust/math/NumberManipulation.hpp>
00044 #include <labust/simulation/DynamicsParams.hpp>
00045 #include <labust/navigation/KFModelLoader.hpp>
00046 
00047 
00048 #include <auv_msgs/NavSts.h>
00049 #include <auv_msgs/BodyForceReq.h>
00050 #include <geometry_msgs/TwistStamped.h>
00051 #include <geometry_msgs/TransformStamped.h>
00052 #include <std_msgs/Float32.h>
00053 #include <std_msgs/Bool.h>
00054 
00055 #include <ros/ros.h>
00056 
00057 #include <boost/bind.hpp>
00058 
00059 using namespace labust::navigation;
00060 
00061 Estimator3D::Estimator3D():
00062                 tauIn(KFNav::vector::Zero(KFNav::inputSize)),
00063                 measurements(KFNav::vector::Zero(KFNav::stateNum)),
00064                 newMeas(KFNav::vector::Zero(KFNav::stateNum)),
00065                 alt(0),
00066                 useYawRate(false),
00067                 dvl_model(0),
00068                 compassVariance(0.3),
00069                 gyroVariance(0.003),
00070                 absoluteEKF(false),
00071                 max_dvl(1.5),
00072                 min_altitude(0.5),
00073                 dvl_timeout(5),
00074                 dvl_time(ros::Time::now()){this->onInit();};
00075 
00076 void Estimator3D::onInit()
00077 {
00078         ros::NodeHandle nh, ph("~");
00079         //Configure the navigation
00080         configureNav(nav,nh);
00081         //Publishers
00082         stateHat = nh.advertise<auv_msgs::NavSts>("stateHat",1);
00083         stateMeas = nh.advertise<auv_msgs::NavSts>("meas",1);
00084         currentsHat = nh.advertise<geometry_msgs::TwistStamped>("currentsHat",1);
00085         buoyancyHat = nh.advertise<std_msgs::Float32>("buoyancy",1);
00086         turns_pub = nh.advertise<std_msgs::Float32>("turns",1);
00087         unsafe_dvl = nh.advertise<std_msgs::Bool>("unsafe_dvl",1);
00088         //Subscribers
00089         tauAch = nh.subscribe<auv_msgs::BodyForceReq>("tauAch", 1, &Estimator3D::onTau,this);
00090         depth = nh.subscribe<std_msgs::Float32>("depth", 1,     &Estimator3D::onDepth, this);
00091         altitude = nh.subscribe<std_msgs::Float32>("altitude", 1, &Estimator3D::onAltitude, this);
00092         modelUpdate = nh.subscribe<navcon_msgs::ModelParamsUpdate>("model_update", 1, &Estimator3D::onModelUpdate,this);
00093         resetTopic = nh.subscribe<std_msgs::Bool>("reset_nav_covariance", 1, &Estimator3D::onReset,this);
00094         useGyro = nh.subscribe<std_msgs::Bool>("use_gyro", 1, &Estimator3D::onUseGyro,this);
00095 
00096 
00097         KFmode = quadMeasAvailable = false;
00098         sub = nh.subscribe<auv_msgs::NED>("quad_delta_pos", 1, &Estimator3D::deltaPosCallback,this);
00099         subKFmode = nh.subscribe<std_msgs::Bool>("KFmode", 1, &Estimator3D::KFmodeCallback, this);
00100 
00101         //Get DVL model
00102         ph.param("dvl_model",dvl_model, dvl_model);
00103         nav.useDvlModel(dvl_model);
00104         ph.param("imu_with_yaw_rate",useYawRate,useYawRate);
00105         ph.param("compass_variance",compassVariance,compassVariance);
00106         ph.param("gyro_variance",gyroVariance,gyroVariance);
00107         ph.param("max_dvl",max_dvl,max_dvl);
00108         ph.param("min_altitude", min_altitude, min_altitude);
00109         ph.param("dvl_timeout", dvl_timeout, dvl_timeout);
00110         double trustf(0);
00111         ph.param("dvl_rot_trust_factor", trustf, trustf);
00112         double sway_corr(0);
00113         ph.param("sway_corr", sway_corr, sway_corr);
00114         ph.param("absoluteEKF", absoluteEKF,absoluteEKF);
00115 
00116         //Configure handlers.
00117         gps.configure(nh);
00118         dvl.configure(nh);
00119         imu.configure(nh);
00120         imu.setGpsHandler(&gps);
00121 
00122   Pstart = nav.getStateCovariance();
00123   nav.setDVLRotationTrustFactor(trustf);
00124   nav.setSwayCorrection(sway_corr);
00125 //Rstart = nav.R;
00126  // ROS_ERROR("NAVIGATION");
00127 
00128 }
00129 
00130 void Estimator3D::onReset(const std_msgs::Bool::ConstPtr& reset)
00131 {
00132    if (reset->data)
00133    {
00134       nav.setStateCovariance(10000*KFNav::matrix::Identity(KFNav::stateNum, KFNav::stateNum));
00135    }
00136 }
00137 
00138 void Estimator3D::onUseGyro(const std_msgs::Bool::ConstPtr& use_gyro)
00139 {
00140    if (use_gyro->data)
00141    {
00142       nav.R0(KFNav::psi, KFNav::psi) = gyroVariance;
00143       ROS_INFO("Switch to using gyro measurements.");
00144    }
00145    else
00146    {
00147       nav.R0(KFNav::psi, KFNav::psi) = compassVariance;
00148       ROS_INFO("Switch to using compass measurements.");
00149    }
00150 }
00151 
00152 void Estimator3D::configureNav(KFNav& nav, ros::NodeHandle& nh)
00153 {
00154         ROS_INFO("Configure navigation.");
00155 
00156         labust::simulation::DynamicsParams params;
00157         labust::tools::loadDynamicsParams(nh, params);
00158 
00159         ROS_INFO("Loaded dynamics params.");
00160 
00161         this->params[X].alpha = params.m + params.Ma(0,0);
00162         this->params[X].beta = params.Dlin(0,0);
00163         this->params[X].betaa = params.Dquad(0,0);
00164 
00165         this->params[Y].alpha = params.m + params.Ma(1,1);
00166         this->params[Y].beta = params.Dlin(1,1);
00167         this->params[Y].betaa = params.Dquad(1,1);
00168 
00169         this->params[Z].alpha = params.m + params.Ma(2,2);
00170         this->params[Z].beta = params.Dlin(2,2);
00171         this->params[Z].betaa = params.Dquad(2,2);
00172 
00173         this->params[K].alpha = params.Io(0,0) + params.Ma(3,3);
00174         this->params[K].beta = params.Dlin(3,3);
00175         this->params[K].betaa = params.Dquad(3,3);
00176 
00177         this->params[M].alpha = params.Io(1,1) + params.Ma(4,4);
00178         this->params[M].beta = params.Dlin(4,4);
00179         this->params[M].betaa = params.Dquad(4,4);
00180 
00181         this->params[N].alpha = params.Io(2,2) + params.Ma(5,5);
00182         this->params[N].beta = params.Dlin(5,5);
00183         this->params[N].betaa = params.Dquad(5,5);
00184 
00185         nav.setParameters(this->params[X], this->params[Y],
00186                         this->params[Z], this->params[K],
00187                         this->params[M], this->params[N]);
00188 
00189         nav.initModel();
00190         labust::navigation::kfModelLoader(nav, nh, "ekfnav");
00191 }
00192 
00193 void Estimator3D::onModelUpdate(const navcon_msgs::ModelParamsUpdate::ConstPtr& update)
00194 {
00195         ROS_INFO("Updating the model parameters for %d DoF.",update->dof);
00196         params[update->dof].alpha = update->alpha;
00197         if (update->use_linear)
00198         {
00199                 params[update->dof].beta = update->beta;
00200                 params[update->dof].betaa = 0;
00201         }
00202         else
00203         {
00204                 params[update->dof].beta = 0;
00205                 params[update->dof].betaa = update->betaa;
00206         }
00207         nav.setParameters(this->params[X],this->params[Y],
00208                         this->params[Z], this->params[K],
00209                         this->params[M],this->params[N]);
00210 }
00211 
00212 void Estimator3D::onTau(const auv_msgs::BodyForceReq::ConstPtr& tau)
00213 {
00214         tauIn(KFNav::X) = tau->wrench.force.x;
00215         tauIn(KFNav::Y) = tau->wrench.force.y;
00216         tauIn(KFNav::Z) = tau->wrench.force.z;
00217         tauIn(KFNav::Kroll) = tau->wrench.torque.x;
00218         tauIn(KFNav::M) = tau->wrench.torque.y;
00219         tauIn(KFNav::N) = tau->wrench.torque.z;
00220 };
00221 
00222 void Estimator3D::onDepth(const std_msgs::Float32::ConstPtr& data)
00223 {
00224         boost::mutex::scoped_lock l(meas_mux);
00225         measurements(KFNav::zp) = data->data;
00226         newMeas(KFNav::zp) = 1;
00227         ROS_INFO("Depth measurement received: %f", newMeas(KFNav::zp));
00228 };
00229 
00230 void Estimator3D::onAltitude(const std_msgs::Float32::ConstPtr& data)
00231 {
00232         boost::mutex::scoped_lock l(meas_mux);
00233         measurements(KFNav::altitude) = data->data;
00234         //Skip measurement if minimum altitude is encountered
00235         if (data->data <= min_altitude) return;
00236         //Dismiss false altitude
00237         if (fabs(data->data-nav.getState()(KFNav::altitude)) < 3*nav.calculateAltInovationVariance(nav.getStateCovariance()))
00238         {
00239                 newMeas(KFNav::altitude) = 1;
00240                 alt = data->data;
00241                 ROS_DEBUG("Accepted altitude: meas=%f, estimate=%f, variance=%f",
00242                         data->data, nav.getState()(KFNav::altitude), 3*nav.calculateAltInovationVariance(nav.getStateCovariance()));
00243         }
00244         else
00245         {
00246                 ROS_INFO("Dissmissed altitude: meas=%f, estimate=%f, variance=%f",
00247                         data->data, nav.getState()(KFNav::altitude), 10* nav.calculateAltInovationVariance(nav.getStateCovariance()));
00248         }
00249 };
00250 
00251 void Estimator3D::deltaPosCallback(const auv_msgs::NED::ConstPtr& msg){
00252 
00253         quadMeasAvailable = true;
00254         deltaXpos = msg->north;
00255         deltaYpos = msg->east;
00256         //ROS_ERROR("PRimio topic");
00257 }
00258 
00259 void Estimator3D::KFmodeCallback(const std_msgs::Bool::ConstPtr& msg){
00260 
00261         if(!absoluteEKF){
00262                 KFmode = msg->data;
00263 
00264                 if(KFmode && (KFmodePast xor KFmode)){
00265 
00266                         KFmodePast = KFmode;
00267                         KFNav::matrix P = nav.getStateCovariance();
00268                         P(KFNav::xp,KFNav::xp) = 10000;
00269                         P(KFNav::yp,KFNav::yp) = 10000;
00270                         nav.setStateCovariance(P);
00271 
00272                         //nav.R0(KFNav::xp,KFNav::xp) = 1;
00273                         //nav.R0(KFNav::xp,KFNav::xp) = 1;
00274                         //nav.R(7,7) = 0.001;
00275 
00276 
00277                 } else if(!KFmode && (KFmodePast xor KFmode)){
00278 
00279                 KFmodePast = KFmode;
00280                         KFNav::matrix P = nav.getStateCovariance();
00281                         P(KFNav::xp,KFNav::xp) = 10000;
00282                         P(KFNav::yp,KFNav::yp) = 10000;
00283                         nav.setStateCovariance(P);
00284 
00285                         //nav.setStateCovariance(Pstart);
00286 
00287                         //nav.R0 = Rstart;
00288 
00289                         //Rstart(KFNav::xp,KFNav::xp)
00290                 }
00291         }
00292 }
00293 
00294 void Estimator3D::processMeasurements()
00295 {
00296         boost::mutex::scoped_lock l(meas_mux);
00297         if(KFmode == true && absoluteEKF == false)
00298                 {
00299                         if ((newMeas(KFNav::xp) = newMeas(KFNav::yp) = quadMeasAvailable)){
00300 
00301                                 quadMeasAvailable = false;
00302                                 measurements(KFNav::xp) = deltaXpos;
00303                                 measurements(KFNav::yp) = deltaYpos;
00304                     }
00305                 } else {
00306 
00307                         //GPS measurements
00308                         if ((newMeas(KFNav::xp) = newMeas(KFNav::yp) = gps.newArrived()))
00309                         {
00310                                 measurements(KFNav::xp) = gps.position().first;
00311                                 measurements(KFNav::yp) = gps.position().second;
00312                         }
00313                 }
00314 
00315                 //ROS_ERROR("xp: %4.2f, yp: %4.2f, MODE: %d",measurements(KFNav::xp),measurements(KFNav::yp),KFmode );
00316 
00317         //Imu measurements
00318         if ((newMeas(KFNav::phi) = newMeas(KFNav::theta) = newMeas(KFNav::psi) = imu.newArrived()))
00319         {
00320                 measurements(KFNav::phi) = imu.orientation()[ImuHandler::roll];
00321                 measurements(KFNav::theta) = imu.orientation()[ImuHandler::pitch];
00322                 measurements(KFNav::psi) = imu.orientation()[ImuHandler::yaw];
00323 
00324                 ROS_DEBUG("NEW IMU: r=%f, p=%f, y=%f", imu.orientation()[ImuHandler::roll],
00325                                 imu.orientation()[ImuHandler::pitch],
00326                                 imu.orientation()[ImuHandler::yaw]);
00327 
00328 
00329                 if ((newMeas(KFNav::r) = useYawRate))
00330                 {
00331                         measurements(KFNav::r) = imu.rate()[ImuHandler::r];
00332                         //Combine measurement with DVL
00333                         dvl.current_r(measurements(KFNav::r));
00334                 }
00335         }
00336         //DVL measurements
00337         //if ((newMeas(KFNav::u) = newMeas(KFNav::v) = newMeas(KFNav::w) = dvl.NewArrived()))
00338         if ((newMeas(KFNav::u) = newMeas(KFNav::v) = dvl.newArrived()))
00339         {
00340                 double vx = dvl.body_speeds()[DvlHandler::u];
00341                 double vy = dvl.body_speeds()[DvlHandler::v];
00342                 double vxe = nav.getState()(KFNav::u); 
00343                 double vye = nav.getState()(KFNav::v); 
00344 
00345                 double rvx(10),rvy(10);
00346                 //Calculate the measured value
00347                 //This depends on the DVL model actually, but lets assume
00348                 nav.calculateUVInovationVariance(nav.getStateCovariance(), rvx, rvy);
00349 
00350                 double cpsi = cos(nav.getState()(KFNav::psi));
00351                 double spsi = sin(nav.getState()(KFNav::psi));
00352                 double xc = nav.getState()(KFNav::xc);
00353                 double yc = nav.getState()(KFNav::yc);
00354                 switch (dvl_model)
00355                 {
00356                   case 1:
00357                     vxe += xc*cpsi + yc*spsi;
00358                     vye += -xc*spsi + yc*cpsi;
00359                     break;
00360                 default: break;
00361                 }
00362 
00363                 if ((fabs((vx - vxe)) > fabs(rvx)) || (fabs((vy - vye)) > fabs(rvy)))
00364                 {
00365                         ROS_INFO("Outlier rejected: meas=%f, est=%f, tolerance=%f", vx, nav.getState()(KFNav::u), fabs(rvx));
00366                         ROS_INFO("Outlier rejected: meas=%f, est=%f, tolerance=%f", vy, nav.getState()(KFNav::v), fabs(rvy));
00367                         newMeas(KFNav::u) = false;
00368                         newMeas(KFNav::v) = false;
00369                 }
00370                 measurements(KFNav::u) = vx;
00371                 measurements(KFNav::v) = vy;
00372 
00373                 //Sanity check
00374                 if ((fabs(vx) > max_dvl) || (fabs(vy) > max_dvl))
00375                 {
00376                         ROS_INFO("DVL measurement failed sanity check for maximum speed %f. Got: vx=%f, vy=%f.",max_dvl, vx, vy);
00377                         newMeas(KFNav::u) = false;
00378                         newMeas(KFNav::v) = false;
00379                 }
00380 
00381                 if (newMeas(KFNav::u) || newMeas(KFNav::v))
00382                 {
00383                         dvl_time = ros::Time::now();
00384                         std_msgs::Bool data;
00385                         data.data = false;
00386                         unsafe_dvl.publish(data);
00387                 }
00388                 //measurements(KFNav::w) = dvl.body_speeds()[DvlHandler::w];
00389         }
00390         else
00391         {
00392                 if ((ros::Time::now() - dvl_time).toSec() > dvl_timeout)
00393                 {
00394                         std_msgs::Bool data;
00395                         data.data = true;
00396                         unsafe_dvl.publish(data);
00397                 }
00398         }
00399         l.unlock();
00400 
00401         //Publish measurements
00402         auv_msgs::NavSts::Ptr meas(new auv_msgs::NavSts());
00403         meas->body_velocity.x = measurements(KFNav::u);
00404         meas->body_velocity.y = measurements(KFNav::v);
00405         meas->body_velocity.z = measurements(KFNav::w);
00406 
00407         meas->position.north = measurements(KFNav::xp);
00408         meas->position.east = measurements(KFNav::yp);
00409         meas->position.depth = measurements(KFNav::zp);
00410         meas->altitude = measurements(KFNav::altitude);
00411 
00412         meas->orientation.roll = measurements(KFNav::phi);
00413         meas->orientation.pitch = measurements(KFNav::theta);
00414         meas->orientation.yaw = labust::math::wrapRad(measurements(KFNav::psi));
00415         if (useYawRate) meas->orientation_rate.yaw = measurements(KFNav::r);
00416 
00417         meas->origin.latitude = gps.origin().first;
00418         meas->origin.longitude = gps.origin().second;
00419         meas->global_position.latitude = gps.latlon().first;
00420         meas->global_position.longitude = gps.latlon().second;
00421 
00422         meas->header.stamp = ros::Time::now();
00423         meas->header.frame_id = "local";
00424         stateMeas.publish(meas);
00425 }
00426 
00427 void Estimator3D::publishState()
00428 {
00429         auv_msgs::NavSts::Ptr state(new auv_msgs::NavSts());
00430         const KFNav::vector& estimate = nav.getState();
00431         state->body_velocity.x = estimate(KFNav::u);
00432         state->body_velocity.y = estimate(KFNav::v);
00433         state->body_velocity.z = estimate(KFNav::w);
00434 
00435         Eigen::Matrix2d R;
00436         double yaw = labust::math::wrapRad(estimate(KFNav::psi));
00437         R<<cos(yaw),-sin(yaw),sin(yaw),cos(yaw);
00438         Eigen::Vector2d in, out;
00439         in << estimate(KFNav::xc), estimate(KFNav::yc);
00440         out = R.transpose()*in;
00441 
00442         state->gbody_velocity.x = estimate(KFNav::u) + out(0);
00443         state->gbody_velocity.y = estimate(KFNav::v) + out(1);
00444         state->gbody_velocity.z = estimate(KFNav::w);
00445 
00446         state->orientation_rate.roll = estimate(KFNav::p);
00447         state->orientation_rate.pitch = estimate(KFNav::q);
00448         state->orientation_rate.yaw = estimate(KFNav::r);
00449 
00450         state->position.north = estimate(KFNav::xp);
00451         state->position.east = estimate(KFNav::yp);
00452         state->position.depth = estimate(KFNav::zp);
00453         state->altitude = estimate(KFNav::altitude);
00454 
00455         state->orientation.roll = estimate(KFNav::phi);
00456         state->orientation.pitch = estimate(KFNav::theta);
00457         state->orientation.yaw = labust::math::wrapRad(estimate(KFNav::psi));
00458 
00459         state->origin.latitude = gps.origin().first;
00460     state->origin.longitude = gps.origin().second;
00461         std::pair<double, double> diffAngle = labust::tools::meter2deg(state->position.north,
00462                         state->position.east,
00463                         //The latitude angle
00464                         state->origin.latitude);
00465         state->global_position.latitude = state->origin.latitude + diffAngle.first;
00466         state->global_position.longitude = state->origin.longitude + diffAngle.second;
00467 
00468         const KFNav::matrix& covariance = nav.getStateCovariance();
00469         state->position_variance.north = covariance(KFNav::xp, KFNav::xp);
00470         state->position_variance.east = covariance(KFNav::yp, KFNav::yp);
00471         state->position_variance.depth = covariance(KFNav::zp,KFNav::zp);
00472         state->orientation_variance.roll =  covariance(KFNav::phi, KFNav::phi);
00473         state->orientation_variance.pitch =  covariance(KFNav::theta, KFNav::theta);
00474         state->orientation_variance.yaw =  covariance(KFNav::psi, KFNav::psi);
00475 
00476         state->header.stamp = ros::Time::now();
00477         state->header.frame_id = "local";
00478         stateHat.publish(state);
00479 
00480         geometry_msgs::TwistStamped::Ptr current(new geometry_msgs::TwistStamped());
00481         current->twist.linear.x = estimate(KFNav::xc);
00482         current->twist.linear.y = estimate(KFNav::yc);
00483         current->header.stamp = ros::Time::now();
00484         current->header.frame_id = "local";
00485         currentsHat.publish(current);
00486 
00487         std_msgs::Float32::Ptr buoyancy(new std_msgs::Float32());
00488         buoyancy->data = estimate(KFNav::buoyancy);
00489         buoyancyHat.publish(buoyancy);
00490 
00491         std_msgs::Float32::Ptr turns(new std_msgs::Float32());
00492         turns->data = estimate(KFNav::psi)/(2*M_PI);
00493         turns_pub.publish(turns);
00494 }
00495 
00496 void Estimator3D::start()
00497 {
00498         ros::NodeHandle ph("~");
00499         double Ts(0.1);
00500         ph.param("Ts",Ts,Ts);
00501         ros::Rate rate(1/Ts);
00502         nav.setTs(Ts);
00503 
00504         while (ros::ok())
00505         {
00506                 nav.predict(tauIn);
00507                 processMeasurements();
00508                 bool newArrived(false);
00509                 boost::mutex::scoped_lock l(meas_mux);
00510                 for(size_t i=0; i<newMeas.size(); ++i)  if ((newArrived = newMeas(i))) break;
00511 
00512                 //Update sensor flag
00513                 bool updateDVL = !newMeas(KFNav::r);
00514 
00515                 std::ostringstream out;
00516                 out<<newMeas;
00517                 ROS_INFO("Measurements %d:%s",KFNav::psi, out.str().c_str());
00518 
00519                 if (newArrived) nav.correct(nav.update(measurements, newMeas));
00520                 KFNav::vector tcstate = nav.getState();
00521                 if (tcstate(KFNav::buoyancy) < -30) tcstate(KFNav::buoyancy) = -10;
00522                 if (tcstate(KFNav::buoyancy) > 0) tcstate(KFNav::buoyancy) = 0;
00523                 nav.setState(tcstate);
00524                 l.unlock();
00525                 publishState();
00526 
00527                 //Send the base-link transform
00528                 geometry_msgs::TransformStamped transform;
00529                 KFNav::vectorref cstate = nav.getState();
00530                 //Update DVL sensor
00531                 if (updateDVL) dvl.current_r(cstate(KFNav::r));
00532 
00533                 transform.transform.translation.x = cstate(KFNav::xp);
00534                 transform.transform.translation.y = cstate(KFNav::yp);
00535                 transform.transform.translation.z = cstate(KFNav::zp);
00536 
00537 
00538                 labust::tools::quaternionFromEulerZYX(cstate(KFNav::phi),
00539                                 cstate(KFNav::theta),
00540                                 cstate(KFNav::psi),
00541                                 transform.transform.rotation);
00542                 if(absoluteEKF){
00543                         transform.child_frame_id = "base_link_abs";
00544                 } else{
00545                         transform.child_frame_id = "base_link";
00546                 }
00547                 transform.header.frame_id = "local";
00548                 transform.header.stamp = ros::Time::now();
00549                 broadcaster.sendTransform(transform);
00550 
00551                 rate.sleep();
00552                 ros::spinOnce();
00553         }
00554 }
00555 
00556 int main(int argc, char* argv[])
00557 {
00558         ros::init(argc,argv,"nav_3d");
00559         Estimator3D nav;
00560         nav.start();
00561         return 0;
00562 }
00563 
00564 


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