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/navigation/EKF_RTT.hpp>
00038 #include <labust/navigation/RelativeTrackingModel.hpp>
00039 
00040 #include <labust/tools/GeoUtilities.hpp>
00041 #include <labust/tools/MatrixLoader.hpp>
00042 #include <labust/tools/conversions.hpp>
00043 #include <labust/tools/DynamicsLoader.hpp>
00044 #include <labust/math/NumberManipulation.hpp>
00045 #include <labust/simulation/DynamicsParams.hpp>
00046 #include <labust/navigation/KFModelLoader.hpp>
00047 
00048 
00049 #include <auv_msgs/NavSts.h>
00050 #include <auv_msgs/BodyForceReq.h>
00051 #include <geometry_msgs/TwistStamped.h>
00052 #include <geometry_msgs/TransformStamped.h>
00053 #include <std_msgs/Float32.h>
00054 #include <std_msgs/Bool.h>
00055 #include <underwater_msgs/USBLFix.h>
00056 
00057 #include <ros/ros.h>
00058 
00059 #include <boost/bind.hpp>
00060 
00061 using namespace labust::navigation;
00062 
00063 Estimator3D::Estimator3D():
00064                 inputVec(KFNav::vector::Zero(KFNav::inputSize)),
00065                 measurements(KFNav::vector::Zero(KFNav::stateNum)),
00066                 newMeas(KFNav::vector::Zero(KFNav::measSize)),
00067                 alt(0),
00068                 xc(0),
00069                 yc(0){this->onInit();};
00070 
00071 void Estimator3D::onInit()
00072 {
00073         ros::NodeHandle nh, ph("~");
00074         
00075         configureNav(nav,nh);
00076 
00077         
00078         pubStateHat = nh.advertise<auv_msgs::NavSts>("stateHatRelative",1);
00079         pubStateMeas = nh.advertise<auv_msgs::NavSts>("measRelative",1);
00080 
00081         
00082         subStateHat = nh.subscribe<auv_msgs::NavSts>("stateHat", 1, &Estimator3D::onStateHat, this);
00083         subCurrentsHat = nh.subscribe<geometry_msgs::TwistStamped>("currentsHat", 1, &Estimator3D::onCurrentsHat, this);
00084         subTargetTau = nh.subscribe<auv_msgs::BodyForceReq>("bla", 1, &Estimator3D::onTargetTau, this);
00085         subTargetDepth = nh.subscribe<std_msgs::Float32>("depth", 1,    &Estimator3D::onTargetDepth, this);
00086         subTargetHeading = nh.subscribe<std_msgs::Float32>("heading", 1, &Estimator3D::onTargetHeading, this);
00087         subUSBLfix = nh.subscribe<underwater_msgs::USBLFix>("usbl_fix", 1, &Estimator3D::onUSBLfix, this);
00088         modelUpdate = nh.subscribe<navcon_msgs::ModelParamsUpdate>("model_update", 1, &Estimator3D::onModelUpdate,this);
00089 }
00090 
00091 void Estimator3D::configureNav(KFNav& nav, ros::NodeHandle& nh){
00092 
00093         ROS_INFO("Configure navigation.");
00094 
00095         labust::simulation::DynamicsParams params;
00096         labust::tools::loadDynamicsParams(nh, params);
00097 
00098         ROS_INFO("Loaded dynamics params.");
00099 
00100         this->params[X].alpha = params.m + params.Ma(0,0);
00101         this->params[X].beta = params.Dlin(0,0);
00102         this->params[X].betaa = params.Dquad(0,0);
00103 
00104         this->params[Y].alpha = params.m + params.Ma(1,1);
00105         this->params[Y].beta = params.Dlin(1,1);
00106         this->params[Y].betaa = params.Dquad(1,1);
00107 
00108         this->params[Z].alpha = params.m + params.Ma(2,2);
00109         this->params[Z].beta = params.Dlin(2,2);
00110         this->params[Z].betaa = params.Dquad(2,2);
00111 
00112         this->params[K].alpha = params.Io(0,0) + params.Ma(3,3);
00113         this->params[K].beta = params.Dlin(3,3);
00114         this->params[K].betaa = params.Dquad(3,3);
00115 
00116         this->params[M].alpha = params.Io(1,1) + params.Ma(4,4);
00117         this->params[M].beta = params.Dlin(4,4);
00118         this->params[M].betaa = params.Dquad(4,4);
00119 
00120         this->params[N].alpha = params.Io(2,2) + params.Ma(5,5);
00121         this->params[N].beta = params.Dlin(5,5);
00122         this->params[N].betaa = params.Dquad(5,5);
00123 
00124         nav.setParameters(this->params[X], this->params[Y],
00125                         this->params[Z], this->params[K],
00126                         this->params[M], this->params[N]);
00127 
00128         nav.initModel();
00129         labust::navigation::kfModelLoader(nav, nh, "ekfnav_rtt");
00130 }
00131 
00132 void Estimator3D::onModelUpdate(const navcon_msgs::ModelParamsUpdate::ConstPtr& update)
00133 {
00134         ROS_INFO("Updating the model parameters for %d DoF.",update->dof);
00135         params[update->dof].alpha = update->alpha;
00136         if (update->use_linear)
00137         {
00138                 params[update->dof].beta = update->beta;
00139                 params[update->dof].betaa = 0;
00140         }
00141         else
00142         {
00143                 params[update->dof].beta = 0;
00144                 params[update->dof].betaa = update->betaa;
00145         }
00146         nav.setParameters(this->params[X],this->params[Y],
00147                         this->params[Z], this->params[K],
00148                         this->params[M],this->params[N]);
00149 }
00150 
00151 void Estimator3D::onStateHat(const auv_msgs::NavSts::ConstPtr& data){
00152 
00153         u = data->body_velocity.x;
00154         v = data->body_velocity.y;
00155 
00156         inputVec(KFNav::psi) = data->orientation.yaw;
00157 }
00158 
00159 void Estimator3D::onCurrentsHat(const  geometry_msgs::TwistStamped::ConstPtr& data){
00160 
00161         xc = data->twist.linear.x;
00162         yc = data->twist.linear.y;
00163 }
00164 
00165 void Estimator3D::onTargetTau(const auv_msgs::BodyForceReq::ConstPtr& tau)
00166 {
00167         inputVec(KFNav::X) = tau->wrench.force.x;
00168         inputVec(KFNav::Z) = tau->wrench.force.z;
00169         inputVec(KFNav::N) = tau->wrench.torque.z;
00170 }
00171 
00172 void Estimator3D::onTargetDepth(const std_msgs::Float32::ConstPtr& data)
00173 {
00174         measurements(KFNav::depth) = data->data;
00175         newMeas(KFNav::depth) = 1;
00176 }
00177 
00178 void Estimator3D::onTargetHeading(const std_msgs::Float32::ConstPtr& data){
00179 
00180         measurements(KFNav::psi_t) = data->data;
00181         newMeas(KFNav::psi_t) = 1;
00182 }
00183 
00184 void Estimator3D::onUSBLfix(const underwater_msgs::USBLFix::ConstPtr& data){
00185 
00186 
00187 
00188         measurements(KFNav::d) = data->range;
00189         newMeas(KFNav::d) = 1;
00190 
00191         measurements(KFNav::theta) = data->bearing;
00192         newMeas(KFNav::theta) = 1;
00193 
00194         measurements(KFNav::delta_xm) = data->relative_position.x;
00195         newMeas(KFNav::delta_xm) = 1;
00196 
00197         measurements(KFNav::delta_ym) = data->relative_position.y;
00198         newMeas(KFNav::delta_ym) = 1;
00199 
00200         measurements(KFNav::delta_zm) = data->relative_position.z;
00201         newMeas(KFNav::delta_zm) = 1;
00202 }
00203 
00204 
00205 void Estimator3D::processMeasurements()
00206 {
00207 
00208         
00209         
00210         
00211         
00212         
00213 
00214         
00215         
00216         
00217         
00218 
00219         
00220         
00221         
00222         
00223 
00224         
00225         
00226         
00227         
00228 
00229         
00230         
00231         
00232 }
00233 
00234 void Estimator3D::publishState(){
00235 
00236         auv_msgs::NavSts::Ptr state(new auv_msgs::NavSts());
00237         const KFNav::vector& estimate = nav.getState();
00238 
00239         state->body_velocity.x = estimate(KFNav::u_t);
00240         state->body_velocity.z = estimate(KFNav::w_t);
00241 
00242         state->orientation_rate.yaw = estimate(KFNav::r_t);
00243 
00244         state->position.north = estimate(KFNav::delta_x);
00245         state->position.east = estimate(KFNav::delta_y);
00246         state->position.depth = estimate(KFNav::delta_z);
00247 
00248         state->orientation.yaw = labust::math::wrapRad(estimate(KFNav::psi_t));
00249 
00250         const KFNav::matrix& covariance = nav.getStateCovariance();
00251         state->position_variance.north = covariance(KFNav::delta_x, KFNav::delta_x);
00252         state->position_variance.east = covariance(KFNav::delta_y, KFNav::delta_y);
00253         state->position_variance.depth = covariance(KFNav::delta_z, KFNav::delta_z);
00254 
00255         state->orientation_variance.yaw =  covariance(KFNav::psi_t, KFNav::psi_t);
00256 
00257         state->header.stamp = ros::Time::now();
00258         state->header.frame_id = "local";
00259         pubStateHat.publish(state);
00260 }
00261 
00262 void Estimator3D::start(){
00263 
00264         ros::NodeHandle ph("~");
00265         double Ts(0.1);
00266         ph.param("Ts",Ts,Ts);
00267         ros::Rate rate(1/Ts);
00268         nav.setTs(Ts);
00269 
00270         while (ros::ok()){
00271 
00272                 inputVec(KFNav::x_dot) = xc + u*cos(inputVec(KFNav::psi)) - v*sin(inputVec(KFNav::psi));
00273                 inputVec(KFNav::y_dot) = yc + u*sin(inputVec(KFNav::psi)) + v*cos(inputVec(KFNav::psi));
00274 
00275                 nav.predict(inputVec);
00276                 processMeasurements();
00277                 bool newArrived(false);
00278                 for(size_t i=0; i<newMeas.size(); ++i)  if ((newArrived = newMeas(i))) break;
00279                 if (newArrived) nav.correct(nav.update(measurements, newMeas));
00280 
00281                 publishState();
00282 
00283                 
00284                 geometry_msgs::TransformStamped transform;
00285                 transform.transform.translation.x = nav.getState()(KFNav::delta_x);
00286                 transform.transform.translation.y = nav.getState()(KFNav::delta_y);
00287                 transform.transform.translation.z = nav.getState()(KFNav::delta_z);
00288 
00289                 labust::tools::quaternionFromEulerZYX(0.0,
00290                                                 0.0,
00291                                                 nav.getState()(KFNav::psi),
00292                                                 transform.transform.rotation);
00293 
00294                 transform.child_frame_id = "base_link_relative";
00295                 transform.header.frame_id = "local";
00296                 transform.header.stamp = ros::Time::now();
00297                 broadcaster.sendTransform(transform);
00298 
00299                 rate.sleep();
00300                 ros::spinOnce();
00301         }
00302 }
00303 
00304 int main(int argc, char* argv[]){
00305 
00306         ros::init(argc,argv,"nav_sb");
00307         Estimator3D nav;
00308         nav.start();
00309         return 0;
00310 }
00311 
00312