gps.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2011, Johannes Meyer, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Flight Systems and Automatic Control group,
00013 //       TU Darmstadt, nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #include <hector_pose_estimation/measurements/gps.h>
00030 #include <hector_pose_estimation/global_reference.h>
00031 #include <hector_pose_estimation/filter/set_filter.h>
00032 
00033 namespace hector_pose_estimation {
00034 
00035 template class Measurement_<GPSModel>;
00036 
00037 GPSModel::GPSModel()
00038 {
00039   position_stddev_ = 10.0;
00040   velocity_stddev_ = 1.0;
00041   parameters().add("position_stddev", position_stddev_);
00042   parameters().add("velocity_stddev", velocity_stddev_);
00043 }
00044 
00045 GPSModel::~GPSModel() {}
00046 
00047 void GPSModel::getMeasurementNoise(NoiseVariance& R, const State&, bool init)
00048 {
00049   if (init) {
00050     R(0,0) = R(1,1) = pow(position_stddev_, 2);
00051     R(2,2) = R(3,3) = pow(velocity_stddev_, 2);
00052   }
00053 }
00054 
00055 bool GPSModel::prepareUpdate(State &state, const MeasurementUpdate &update)
00056 {
00057   state.getRotationMatrix(R);
00058   return true;
00059 }
00060 
00061 void GPSModel::getExpectedValue(MeasurementVector& y_pred, const State& state)
00062 {
00063   y_pred(0) = state.getPosition().x();
00064   y_pred(1) = state.getPosition().y();
00065 #ifdef VELOCITY_IN_BODY_FRAME
00066   y_pred(2) = R.row(0) * state.getVelocity();
00067   y_pred(3) = R.row(1) * state.getVelocity();
00068 #else
00069   y_pred(2) = state.getVelocity().x();
00070   y_pred(3) = state.getVelocity().y();
00071 #endif
00072 }
00073 
00074 void GPSModel::getStateJacobian(MeasurementMatrix& C, const State& state, bool init)
00075 {
00076   if (state.getPositionIndex() >= 0) {
00077     C(0,State::POSITION_X) = 1.0;
00078     C(1,State::POSITION_Y) = 1.0;
00079   }
00080 
00081 #ifdef VELOCITY_IN_BODY_FRAME
00082   State::ConstOrientationType q(state.getOrientation());
00083   State::ConstVelocityType v(state.getVelocity());
00084 
00085   if (state.getOrientationIndex() >= 0) {
00086     C(2,State::QUATERNION_W) = -2.0*q.z()*v.y()+2.0*q.y()*v.z()+2.0*q.w()*v.x();
00087     C(2,State::QUATERNION_X) =  2.0*q.y()*v.y()+2.0*q.z()*v.z()+2.0*q.x()*v.x();
00088     C(2,State::QUATERNION_Y) = -2.0*q.y()*v.x()+2.0*q.x()*v.y()+2.0*q.w()*v.z();
00089     C(2,State::QUATERNION_Z) = -2.0*q.z()*v.x()-2.0*q.w()*v.y()+2.0*q.x()*v.z();
00090 
00091     C(3,State::QUATERNION_W) =  2.0*q.z()*v.x()-2.0*q.x()*v.z()+2.0*q.w()*v.y();
00092     C(3,State::QUATERNION_X) =  2.0*q.y()*v.x()-2.0*q.x()*v.y()-2.0*q.w()*v.z();
00093     C(3,State::QUATERNION_Y) =  2.0*q.x()*v.x()+2.0*q.z()*v.z()+2.0*q.y()*v.y();
00094     C(3,State::QUATERNION_Z) =  2.0*q.w()*v.x()-2.0*q.z()*v.y()+2.0*q.y()*v.z();
00095   }
00096 
00097   if (state.getVelocityIndex() >= 0) {
00098     C(2,State::VELOCITY_X)   =  R(0,0);
00099     C(2,State::VELOCITY_Y)   =  R(0,1);
00100     C(2,State::VELOCITY_Z)   =  R(0,2);
00101 
00102     C(3,State::VELOCITY_X)   =  R(1,0);
00103     C(3,State::VELOCITY_Y)   =  R(1,1);
00104     C(3,State::VELOCITY_Z)   =  R(1,2);
00105   }
00106 
00107 #else
00108   if (!init) return; // C is time-constant
00109 
00110   if (state.getVelocityIndex() >= 0) {
00111     C(2,State::VELOCITY_X) = 1.0;
00112     C(3,State::VELOCITY_Y) = 1.0;
00113   }
00114 #endif
00115 }
00116 
00117 GPS::GPS(const std::string &name)
00118   : Measurement_<GPSModel>(name)
00119   , y_(4)
00120 {
00121 }
00122 
00123 GPS::~GPS()
00124 {}
00125 
00126 void GPS::onReset() {
00127   reference_.reset();
00128 }
00129 
00130 GPSModel::MeasurementVector const& GPS::getVector(const GPSUpdate &update, const State&) {
00131   if (!reference_) {
00132     y_ = 0.0/0.0;
00133     return y_;
00134   }
00135 
00136   reference_->fromWGS84(update.latitude, update.longitude, y_(0), y_(1));
00137   reference_->fromNorthEast(update.velocity_north, update.velocity_east, y_(2), y_(3));
00138 
00139   last_ = update;
00140   return y_;
00141 }
00142 
00143 bool GPS::prepareUpdate(State &state, const Update &update) {
00144   // reset reference position if GPS has not been updated for a while
00145   if (timedout()) reference_.reset();
00146 
00147   // find new reference position
00148   if (reference_ != GlobalReference::Instance()) {
00149     reference_ = GlobalReference::Instance();
00150     reference_->setCurrentPosition(state, update.latitude, update.longitude);
00151   }
00152 
00153   return true;
00154 }
00155 
00156 } // namespace hector_pose_estimation


hector_pose_estimation_core
Author(s): Johannes Meyer
autogenerated on Mon Oct 6 2014 00:24:16