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 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 #include <labust/navigation/EKF_3D_USBL.hpp>
00052 #include <labust/navigation/EKF_3D_USBLModel.hpp>
00053 #include <labust/tools/GeoUtilities.hpp>
00054 #include <labust/tools/MatrixLoader.hpp>
00055 #include <labust/tools/conversions.hpp>
00056 #include <labust/tools/DynamicsLoader.hpp>
00057 #include <labust/math/NumberManipulation.hpp>
00058 #include <labust/simulation/DynamicsParams.hpp>
00059 #include <labust/navigation/KFModelLoader.hpp>
00060 
00061 #include <auv_msgs/NavSts.h>
00062 #include <auv_msgs/BodyForceReq.h>
00063 #include <geometry_msgs/TwistStamped.h>
00064 #include <geometry_msgs/TransformStamped.h>
00065 #include <std_msgs/Float32.h>
00066 #include <std_msgs/Bool.h>
00067 #include <underwater_msgs/USBLFix.h>
00068 
00069 #include <ros/ros.h>
00070 
00071 #include <boost/bind.hpp>
00072 #include <math.h>
00073 
00074 using namespace labust::navigation;
00075 
00076 
00077 
00078 Estimator3D::Estimator3D():
00079 
00080                 tauIn(KFNav::vector::Zero(KFNav::inputSize)),
00081                 measurements(KFNav::vector::Zero(KFNav::measSize)),
00082                 newMeas(KFNav::vector::Zero(KFNav::measSize)),
00083                 measDelay(KFNav::vector::Zero(KFNav::measSize)),
00084                 alt(0),
00085                 useYawRate(false),
00086                 enableDelay(false),
00087                 enableRange(true),
00088                 enableBearing(true),
00089                 enableElevation(false),
00090                 delayTime(0.0),
00091                 delay_time(0.0),
00092                 dvl_model(0),
00093                 compassVariance(0.3),
00094                 gyroVariance(0.003),
00095                 OR(3,0.95),
00096                 absoluteEKF(false){this->onInit();};
00097 
00098 void Estimator3D::onInit()
00099 {
00100         ros::NodeHandle nh, ph("~");
00101 
00102         
00103         configureNav(nav,nh);
00104 
00105         
00106         stateHat = nh.advertise<auv_msgs::NavSts>("stateHat",1);
00107         stateMeas = nh.advertise<auv_msgs::NavSts>("meas",1);
00108         currentsHat = nh.advertise<geometry_msgs::TwistStamped>("currentsHat",1);
00109         buoyancyHat = nh.advertise<std_msgs::Float32>("buoyancy",1);
00110         pubRange = nh.advertise<std_msgs::Float32>("range",1);
00111         pubRangeFiltered = nh.advertise<std_msgs::Float32>("range_filtered",1);
00112         pubwk = nh.advertise<std_msgs::Float32>("w_limit",1);
00113 
00114 
00115 
00116         
00117         tauAch = nh.subscribe<auv_msgs::BodyForceReq>("tauAch", 1, &Estimator3D::onTau,this);
00118         depth = nh.subscribe<std_msgs::Float32>("depth", 1,     &Estimator3D::onDepth, this);
00119         altitude = nh.subscribe<std_msgs::Float32>("altitude", 1, &Estimator3D::onAltitude, this);
00120         modelUpdate = nh.subscribe<navcon_msgs::ModelParamsUpdate>("model_update", 1, &Estimator3D::onModelUpdate,this);
00121         resetTopic = nh.subscribe<std_msgs::Bool>("reset_nav_covariance", 1, &Estimator3D::onReset,this);
00122         useGyro = nh.subscribe<std_msgs::Bool>("use_gyro", 1, &Estimator3D::onUseGyro,this);
00123         subUSBL = nh.subscribe<underwater_msgs::USBLFix>("usbl_fix", 1, &Estimator3D::onUSBLfix,this);
00124         sub = nh.subscribe<auv_msgs::NED>("quad_delta_pos", 1, &Estimator3D::deltaPosCallback,this);
00125         subKFmode = nh.subscribe<std_msgs::Bool>("KFmode", 1, &Estimator3D::KFmodeCallback, this);
00126 
00127         KFmode = quadMeasAvailable = false;
00128 
00129         
00130         ph.param("dvl_model",dvl_model, dvl_model);
00131         nav.useDvlModel(dvl_model);
00132         ph.param("imu_with_yaw_rate",useYawRate,useYawRate);
00133         ph.param("compass_variance",compassVariance,compassVariance);
00134         ph.param("gyro_variance",gyroVariance,gyroVariance);
00135 
00136         ph.param("absoluteEKF", absoluteEKF, absoluteEKF);
00137 
00138         
00139         ph.param("delay", enableDelay, enableDelay);
00140         ph.param("delay_time", delay_time, delay_time);
00141         ph.param("range", enableRange, enableRange);
00142         ph.param("bearing", enableBearing, enableBearing);
00143         ph.param("elevation", enableElevation, enableElevation);
00144         
00145 
00146         
00147         gps.configure(nh);
00148         dvl.configure(nh);
00149         imu.configure(nh);
00150 
00151         
00152     Pstart = nav.getStateCovariance();
00153 }
00154 
00155 void Estimator3D::onReset(const std_msgs::Bool::ConstPtr& reset)
00156 {
00157    if (reset->data)
00158    {
00159       nav.setStateCovariance(10000*KFNav::matrix::Identity(KFNav::stateNum, KFNav::stateNum));
00160    }
00161 }
00162 
00163 void Estimator3D::onUseGyro(const std_msgs::Bool::ConstPtr& use_gyro)
00164 {
00165    if (use_gyro->data)
00166    {
00167       nav.R0(KFNav::psi, KFNav::psi) = gyroVariance;
00168       ROS_INFO("Switch to using gyro measurements.");
00169    }
00170    else
00171    {
00172       nav.R0(KFNav::psi, KFNav::psi) = compassVariance;
00173       ROS_INFO("Switch to using compass measurements.");
00174    }
00175 }
00176 
00177 void Estimator3D::configureNav(KFNav& nav, ros::NodeHandle& nh)
00178 {
00179         ROS_INFO("Configure navigation.");
00180 
00181         labust::simulation::DynamicsParams params;
00182         labust::tools::loadDynamicsParams(nh, params);
00183 
00184         ROS_INFO("Loaded dynamics params.");
00185 
00186         this->params[X].alpha = params.m + params.Ma(0,0);
00187         this->params[X].beta = params.Dlin(0,0);
00188         this->params[X].betaa = params.Dquad(0,0);
00189 
00190         this->params[Y].alpha = params.m + params.Ma(1,1);
00191         this->params[Y].beta = params.Dlin(1,1);
00192         this->params[Y].betaa = params.Dquad(1,1);
00193 
00194         this->params[Z].alpha = params.m + params.Ma(2,2);
00195         this->params[Z].beta = params.Dlin(2,2);
00196         this->params[Z].betaa = params.Dquad(2,2);
00197 
00198         this->params[K].alpha = params.Io(0,0) + params.Ma(3,3);
00199         this->params[K].beta = params.Dlin(3,3);
00200         this->params[K].betaa = params.Dquad(3,3);
00201 
00202         this->params[M].alpha = params.Io(1,1) + params.Ma(4,4);
00203         this->params[M].beta = params.Dlin(4,4);
00204         this->params[M].betaa = params.Dquad(4,4);
00205 
00206         this->params[N].alpha = params.Io(2,2) + params.Ma(5,5);
00207         this->params[N].beta = params.Dlin(5,5);
00208         this->params[N].betaa = params.Dquad(5,5);
00209 
00210         nav.setParameters(this->params[X], this->params[Y],
00211                         this->params[Z], this->params[K],
00212                         this->params[M], this->params[N]);
00213 
00214         nav.initModel();
00215         labust::navigation::kfModelLoader(nav, nh, "ekfnav_usbl");
00216 }
00217 
00218 void Estimator3D::onModelUpdate(const navcon_msgs::ModelParamsUpdate::ConstPtr& update)
00219 {
00220         ROS_INFO("Updating the model parameters for %d DoF.",update->dof);
00221         params[update->dof].alpha = update->alpha;
00222         if (update->use_linear)
00223         {
00224                 params[update->dof].beta = update->beta;
00225                 params[update->dof].betaa = 0;
00226         }
00227         else
00228         {
00229                 params[update->dof].beta = 0;
00230                 params[update->dof].betaa = update->betaa;
00231         }
00232         nav.setParameters(this->params[X],this->params[Y],
00233                         this->params[Z], this->params[K],
00234                         this->params[M],this->params[N]);
00235 }
00236 
00237 void Estimator3D::onTau(const auv_msgs::BodyForceReq::ConstPtr& tau)
00238 {
00239         tauIn(KFNav::X) = tau->wrench.force.x;
00240         tauIn(KFNav::Y) = tau->wrench.force.y;
00241         tauIn(KFNav::Z) = tau->wrench.force.z;
00242         tauIn(KFNav::Kroll) = tau->wrench.torque.x;
00243         tauIn(KFNav::M) = tau->wrench.torque.y;
00244         tauIn(KFNav::N) = tau->wrench.torque.z;
00245 };
00246 
00247 
00248 
00249 
00250 
00251 void Estimator3D::onDepth(const std_msgs::Float32::ConstPtr& data)
00252 {
00253         measurements(KFNav::zp) = data->data;
00254         newMeas(KFNav::zp) = 1;
00255 };
00256 
00257 void Estimator3D::onAltitude(const std_msgs::Float32::ConstPtr& data)
00258 {
00259         measurements(KFNav::altitude) = data->data;
00260         
00261         if (fabs(data->data-nav.getState()(KFNav::altitude)) < 10*nav.calculateAltInovationVariance(nav.getStateCovariance())) 
00262         {
00263                 newMeas(KFNav::altitude) = 1;
00264                 alt = data->data;
00265                 ROS_DEBUG("Accepted altitude: meas=%f, estimate=%f, variance=%f",
00266                         data->data, nav.getState()(KFNav::altitude), 10* nav.calculateAltInovationVariance(nav.getStateCovariance()));
00267         }
00268         else
00269         {
00270                 ROS_INFO("Dissmissed altitude: meas=%f, estimate=%f, variance=%f",
00271                         data->data, nav.getState()(KFNav::altitude), 10* nav.calculateAltInovationVariance(nav.getStateCovariance()));
00272         }
00273 };
00274 
00275 void Estimator3D::onUSBLfix(const underwater_msgs::USBLFix::ConstPtr& data){
00276 
00277         
00278         
00279         double delay = double(calculateDelaySteps(currentTime-delay_time, currentTime));
00280 
00281         double bear = 360 - data->bearing;
00282         double elev = 180 - data->elevation;
00283 
00284         const KFNav::vector& x = nav.getState();
00285 
00286         
00287 
00288         ROS_ERROR("RANGE: %f, BEARING: %f deg %f rad", data->range, labust::math::wrapRad(bear*M_PI/180), labust::math::wrapRad(bear*M_PI/180+x(KFNav::psi)));
00289         
00290         measurements(KFNav::range) = (data->range > 0.1)?data->range:0.1;
00291         newMeas(KFNav::range) = enableRange;
00292         measDelay(KFNav::range) = delay;
00293 
00294         
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322         
00323         measurements(KFNav::bearing) = labust::math::wrapRad(bear*M_PI/180);
00324         newMeas(KFNav::bearing) = enableBearing;
00325         measDelay(KFNav::bearing) = delay;
00326 
00327         measurements(KFNav::elevation) = elev*M_PI/180;
00328         newMeas(KFNav::elevation) = enableElevation;
00329         measDelay(KFNav::elevation) = delay;
00330 
00331         
00332         measurements(KFNav::xb) =-1.25;
00333         newMeas(KFNav::xb) = 1;
00334         measDelay(KFNav::xb) = delay;
00335 
00336         measurements(KFNav::yb) = 0.5;
00337         newMeas(KFNav::yb) = 1;
00338         measDelay(KFNav::yb) = delay;
00339 
00340         measurements(KFNav::zb) = 2.6;
00341         newMeas(KFNav::zb) = 1;
00342         measDelay(KFNav::zb) = delay;
00343 
00344         
00345         
00346         
00347         
00348 
00349 
00350         
00351 
00352         
00353         
00354 
00355         
00356         
00357 
00358         
00359         
00360 }
00361 
00362 void Estimator3D::deltaPosCallback(const auv_msgs::NED::ConstPtr& msg){
00363 
00364         quadMeasAvailable = true;
00365         deltaXpos = msg->north;
00366         deltaYpos = msg->east;
00367 }
00368 
00369 void Estimator3D::KFmodeCallback(const std_msgs::Bool::ConstPtr& msg){
00370 
00371         if(!absoluteEKF){
00372                 KFmode = msg->data;
00373 
00374                 if(KFmode && (KFmodePast xor KFmode)){
00375 
00376                         KFmodePast = KFmode;
00377                         KFNav::matrix P = nav.getStateCovariance();
00378                         P(KFNav::xp,KFNav::xp) = 10000;
00379                         P(KFNav::yp,KFNav::yp) = 10000;
00380                         nav.setStateCovariance(P);
00381 
00382                         
00383                         
00384                         
00385 
00386 
00387                 } else if(!KFmode && (KFmodePast xor KFmode)){
00388 
00389                 KFmodePast = KFmode;
00390                         KFNav::matrix P = nav.getStateCovariance();
00391                         P(KFNav::xp,KFNav::xp) = 10000;
00392                         P(KFNav::yp,KFNav::yp) = 10000;
00393                         nav.setStateCovariance(P);
00394 
00395                         
00396                         
00397                         
00398                 }
00399         }
00400 }
00401 
00402 
00403 
00404 
00405 
00406 void Estimator3D::processMeasurements()
00407 {
00408 
00410 
00411         measurements(KFNav::zp) = 0.07;
00412         newMeas(KFNav::zp) = 1;
00413 
00414 
00415         if(KFmode == true && absoluteEKF == false)
00416                 {
00417                         if ((newMeas(KFNav::xp) = newMeas(KFNav::yp) = quadMeasAvailable)){
00418 
00419                                 quadMeasAvailable = false;
00420                                 measurements(KFNav::xp) = deltaXpos;
00421                                 measurements(KFNav::yp) = deltaYpos;
00422                     }
00423                 } else {
00424 
00425                         
00426                         if ((newMeas(KFNav::xp) = newMeas(KFNav::yp) = gps.newArrived()))
00427                         {
00428                                 measurements(KFNav::xp) = gps.position().first;
00429                                 measurements(KFNav::yp) = gps.position().second;
00430                         }
00431                 }
00432 
00433                 
00434 
00435         
00436         if ((newMeas(KFNav::phi) = newMeas(KFNav::theta) = newMeas(KFNav::psi) = imu.newArrived()))
00437         {
00438 
00439                 measurements(KFNav::phi) = imu.orientation()[ImuHandler::roll];
00440                 measurements(KFNav::theta) = imu.orientation()[ImuHandler::pitch];
00441                 measurements(KFNav::psi) = imu.orientation()[ImuHandler::yaw];
00442 
00443                 ROS_DEBUG("NEW IMU: r=%f, p=%f, y=%f", imu.orientation()[ImuHandler::roll],
00444                                 imu.orientation()[ImuHandler::pitch],
00445                                 imu.orientation()[ImuHandler::yaw]);
00446 
00447 
00448                 if ((newMeas(KFNav::r) = useYawRate))
00449                 {
00450                         measurements(KFNav::r) = imu.rate()[ImuHandler::r];
00451                 }
00452         }
00453         
00454         
00455         if ((newMeas(KFNav::u) = newMeas(KFNav::v) = dvl.newArrived()))
00456         {
00457                 double vx = dvl.body_speeds()[DvlHandler::u];
00458                 double vy = dvl.body_speeds()[DvlHandler::v];
00459                 double vxe = nav.getState()(KFNav::u); 
00460                 double vye = nav.getState()(KFNav::v); 
00461 
00462                 double rvx(10),rvy(10);
00463                 
00464                 
00465                 nav.calculateUVInovationVariance(nav.getStateCovariance(), rvx, rvy);
00466 
00467                 double cpsi = cos(nav.getState()(KFNav::psi));
00468                 double spsi = sin(nav.getState()(KFNav::psi));
00469                 double xc = nav.getState()(KFNav::xc);
00470                 double yc = nav.getState()(KFNav::yc);
00471                 switch (dvl_model)
00472                 {
00473                   case 1:
00474                     vxe += xc*cpsi + yc*spsi;
00475                     vye += -xc*spsi + yc*cpsi;
00476                     break;
00477                 default: break;
00478                 }
00479 
00480                 if (fabs((vx - vxe)) > fabs(rvx))
00481                 {
00482                         ROS_INFO("Outlier rejected: meas=%f, est=%f, tolerance=%f", vx, nav.getState()(KFNav::u), fabs(rvx));
00483                         newMeas(KFNav::u) = false;
00484                 }
00485                 measurements(KFNav::u) = vx;
00486 
00487 
00488                 if (fabs((vy - vye)) > fabs(rvy))
00489                 {
00490                         ROS_INFO("Outlier rejected: meas=%f, est=%f, tolerance=%f", vy, nav.getState()(KFNav::v), fabs(rvy));
00491                         newMeas(KFNav::v) = false;
00492                 }
00493                 measurements(KFNav::v) = vy;
00494 
00495                 
00496         }
00497 
00498         
00499         auv_msgs::NavSts::Ptr meas(new auv_msgs::NavSts());
00500         meas->body_velocity.x = measurements(KFNav::u);
00501         meas->body_velocity.y = measurements(KFNav::v);
00502         meas->body_velocity.z = measurements(KFNav::w);
00503 
00504         meas->position.north = measurements(KFNav::xp);
00505         meas->position.east = measurements(KFNav::yp);
00506         meas->position.depth = measurements(KFNav::zp);
00507         meas->altitude = measurements(KFNav::altitude);
00508 
00509         meas->orientation.roll = measurements(KFNav::phi);
00510         meas->orientation.pitch = measurements(KFNav::theta);
00511         meas->orientation.yaw = labust::math::wrapRad(measurements(KFNav::psi));
00512         if (useYawRate) meas->orientation_rate.yaw = measurements(KFNav::r);
00513 
00514         meas->origin.latitude = gps.origin().first;
00515         meas->origin.longitude = gps.origin().second;
00516         meas->global_position.latitude = gps.latlon().first;
00517         meas->global_position.longitude = gps.latlon().second;
00518 
00519         meas->header.stamp = ros::Time::now();
00520         meas->header.frame_id = "local";
00521         stateMeas.publish(meas);
00522 }
00523 
00524 void Estimator3D::publishState()
00525 {
00526         auv_msgs::NavSts::Ptr state(new auv_msgs::NavSts());
00527         const KFNav::vector& estimate = nav.getState();
00528         state->body_velocity.x = estimate(KFNav::u);
00529         state->body_velocity.y = estimate(KFNav::v);
00530         state->body_velocity.z = estimate(KFNav::w);
00531 
00532         Eigen::Matrix2d R;
00533         double yaw = labust::math::wrapRad(estimate(KFNav::psi));
00534         R<<cos(yaw),-sin(yaw),sin(yaw),cos(yaw);
00535         Eigen::Vector2d in, out;
00536         in << estimate(KFNav::xc), estimate(KFNav::yc);
00537         out = R.transpose()*in;
00538 
00539         state->gbody_velocity.x = estimate(KFNav::u) + out(0);
00540         state->gbody_velocity.y = estimate(KFNav::v) + out(1);
00541         state->gbody_velocity.z = estimate(KFNav::w);
00542 
00543         state->orientation_rate.roll = estimate(KFNav::p);
00544         state->orientation_rate.pitch = estimate(KFNav::q);
00545         state->orientation_rate.yaw = estimate(KFNav::r);
00546 
00547         state->position.north = estimate(KFNav::xp);
00548         state->position.east = estimate(KFNav::yp);
00549         state->position.depth = estimate(KFNav::zp);
00550         state->altitude = estimate(KFNav::altitude);
00551 
00552         state->orientation.roll = estimate(KFNav::phi);
00553         state->orientation.pitch = estimate(KFNav::theta);
00554         state->orientation.yaw = labust::math::wrapRad(estimate(KFNav::psi));
00555 
00556         state->origin.latitude = gps.origin().first;
00557     state->origin.longitude = gps.origin().second;
00558         std::pair<double, double> diffAngle = labust::tools::meter2deg(state->position.north,
00559                         state->position.east,
00560                         
00561                         state->origin.latitude);
00562         state->global_position.latitude = state->origin.latitude + diffAngle.first;
00563         state->global_position.longitude = state->origin.longitude + diffAngle.second;
00564 
00565         const KFNav::matrix& covariance = nav.getStateCovariance();
00566         state->position_variance.north = covariance(KFNav::xp, KFNav::xp);
00567         state->position_variance.east = covariance(KFNav::yp, KFNav::yp);
00568         state->position_variance.depth = covariance(KFNav::zp,KFNav::zp);
00569         state->orientation_variance.roll =  covariance(KFNav::phi, KFNav::phi);
00570         state->orientation_variance.pitch =  covariance(KFNav::theta, KFNav::theta);
00571         state->orientation_variance.yaw =  covariance(KFNav::psi, KFNav::psi);
00572 
00573         state->header.stamp = ros::Time::now();
00574         state->header.frame_id = "local";
00575         stateHat.publish(state);
00576 
00577         geometry_msgs::TwistStamped::Ptr current(new geometry_msgs::TwistStamped());
00578         current->twist.linear.x = estimate(KFNav::xc);
00579         current->twist.linear.y = estimate(KFNav::yc);
00580         current->header.stamp = ros::Time::now();
00581         current->header.frame_id = "local";
00582         currentsHat.publish(current);
00583 
00584         std_msgs::Float32::Ptr buoyancy(new std_msgs::Float32());
00585         buoyancy->data = estimate(KFNav::buoyancy);
00586         buoyancyHat.publish(buoyancy);
00587 }
00588 
00589 
00590 int Estimator3D::calculateDelaySteps(double measTime, double arrivalTime){
00591                                 return floor((arrivalTime-measTime)/nav.Ts);
00592                         }
00593 
00594 
00595 
00596 
00597 void Estimator3D::start()
00598 {
00599         ros::NodeHandle ph("~");
00600         double Ts(0.1);
00601         ph.param("Ts",Ts,Ts);
00602         ros::Rate rate(1/Ts);
00603         nav.setTs(Ts);
00604 
00605         
00606         currentTime = ros::Time::now().toSec();
00607 
00608         while (ros::ok()){
00609 
00610                 
00611                 processMeasurements();
00612 
00613                 
00614                 FilterState state;
00615                 state.input = tauIn;
00616                 state.meas = measurements;
00617                 state.newMeas = newMeas;
00618 
00619                 
00620                 bool newDelayed(false);
00621                 for(size_t i=0; i<measDelay.size(); ++i){
00622                         if(measDelay(i)){
00623                                 state.newMeas(i) = 0;
00624                                 newDelayed = true;
00625                         }
00626                 }
00627 
00628                 
00629                 state.state = nav.getState();
00630                 state.Pcov = nav.getStateCovariance();
00631                 
00632 
00633                 
00634                 
00635                 if(pastStates.size()>1000){
00636                         pastStates.pop_front();
00637                         
00638                 }
00639                 pastStates.push_back(state);
00640 
00641                 if(newDelayed && enableDelay)
00642                 {
00643                         
00644                         int delaySteps = measDelay.maxCoeff();
00645 
00646                         
00647                         if(delaySteps >= pastStates.size())
00648                                 delaySteps = pastStates.size()-1;
00649 
00650                         
00651 
00652                         std::stack<FilterState> tmp_stack;
00653                         for(size_t i=0; i<=delaySteps; i++){
00654 
00655                                 KFNav::vector tmp_cmp;
00656                                 tmp_cmp.setConstant(KFNav::measSize, i);
00657                                 if((measDelay.array() == tmp_cmp.array()).any() && i != 0){
00658                                         FilterState tmp_state = pastStates.back();
00659                                         for(size_t j=0; j<measDelay.size(); ++j){
00660                                                 if(measDelay(j) == i){
00661                                                         tmp_state.newMeas(j) = 1;
00662                                                         tmp_state.meas(j) = measurements(j);
00663 
00667                                                         if(j == KFNav::range)
00668                                                         {
00669                                                                 const KFNav::vector& x = tmp_state.state; 
00670                                                                 double range = measurements(j);
00671 
00672                                                                 Eigen::VectorXd input(Eigen::VectorXd::Zero(3));
00673                                                                         
00674 
00675 
00676                                                                 input << x(KFNav::xp)-x(KFNav::xb), x(KFNav::yp)-x(KFNav::yb), x(KFNav::zp)-x(KFNav::zb);
00677                                                                 
00678 
00679                                                                 
00680                                                                 double y_filt, sigma, w;
00681                                                                 OR.step(input, measurements(KFNav::range), &y_filt, &sigma, &w);
00682                                                                 
00683 
00684                                                                 std_msgs::Float32 rng_msg;
00685                                                                 
00686 
00687                                                                 double w_limit =  0.3*std::sqrt(float(sigma));
00688                                                                 w_limit = (w_limit>1.0)?1.0:w_limit;
00689                                                                 if(w>w_limit)
00690                                                                 {
00691                                                                         rng_msg.data = range;
00692                                                                         pubRangeFiltered.publish(rng_msg);
00693                                                                         
00694 
00695                                                                 } else {
00696                                                                         tmp_state.newMeas(j) = 0;
00697                                                                 }
00698                                                                 
00699 
00700                                                                 rng_msg.data = w_limit;
00701                                                                 pubwk.publish(rng_msg);
00702 
00703                                                                 rng_msg.data = range;
00704                                                                 pubRange.publish(rng_msg);
00705 
00706                                                         }
00707 
00708                                                         if(j == KFNav::bearing && tmp_state.newMeas(j-1) == 0)
00709                                                         {
00710                                                                 tmp_state.newMeas(j) = 0;
00711 
00712                                                         }
00713 
00714 
00715 
00716 
00718 
00719                                                         
00720                                                 }
00721                                         }
00722                                         tmp_stack.push(tmp_state);
00723                                 } else {
00724                                         tmp_stack.push(pastStates.back());
00725                                 }
00726                                 pastStates.pop_back();
00727                         }
00728 
00729                         
00730                         FilterState state_p = tmp_stack.top();
00731                         nav.setStateCovariance(state_p.Pcov);
00732                         nav.setState(state_p.state);
00733 
00734                         
00735                         while(!tmp_stack.empty()){
00736                                 state_p = tmp_stack.top();
00737                                 tmp_stack.pop();
00738                                 pastStates.push_back(state_p);
00739 
00740                                 
00741                                 nav.predict(state_p.input);
00742                                 bool newArrived(false);
00743                                 for(size_t i=0; i<state_p.newMeas.size(); ++i)  if ((newArrived = state_p.newMeas(i))) break;
00744                                 if (newArrived) nav.correct(nav.update(state_p.meas, state_p.newMeas));
00745                         }
00746                 }else{
00747                         
00748                         nav.predict(tauIn);
00749                         bool newArrived(false);
00750                         for(size_t i=0; i<newMeas.size(); ++i)  if ((newArrived = newMeas(i))) break;
00751                         if (newArrived) nav.correct(nav.update(measurements, newMeas));
00752                 }
00753 
00754                 newMeas.setZero(); 
00755                 measDelay.setZero();
00756                 publishState();
00757 
00758                 
00759 
00760                 
00761                 geometry_msgs::TransformStamped transform;
00762                 transform.transform.translation.x = nav.getState()(KFNav::xp);
00763                 transform.transform.translation.y = nav.getState()(KFNav::yp);
00764                 transform.transform.translation.z = nav.getState()(KFNav::zp);
00765                 labust::tools::quaternionFromEulerZYX(nav.getState()(KFNav::phi),
00766                                 nav.getState()(KFNav::theta),
00767                                 nav.getState()(KFNav::psi),
00768                                 transform.transform.rotation);
00769                 if(absoluteEKF){
00770                         transform.child_frame_id = "base_link";
00771                 } else{
00772                         transform.child_frame_id = "base_link";
00773                 }
00774                 transform.header.frame_id = "local";
00775                 transform.header.stamp = ros::Time::now();
00776                 broadcaster.sendTransform(transform);
00777 
00778                 rate.sleep();
00779                 
00780                 currentTime = ros::Time::now().toSec();
00781                 ros::spinOnce();
00782         }
00783 }
00784 
00785 int main(int argc, char* argv[])
00786 {
00787         ros::init(argc,argv,"nav_3d");
00788         Estimator3D nav;
00789         nav.start();
00790         return 0;
00791 }
00792 
00793