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 #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;
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
00145 if (timedout()) reference_.reset();
00146
00147
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 }