state.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2013, 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/state.h>
00030 #include <hector_pose_estimation/substate.h>
00031 
00032 #include <ros/console.h>
00033 
00034 namespace hector_pose_estimation {
00035 
00036 FullState::FullState()
00037 {
00038   orientation_ = addSubState<OrientationStateType::VectorDimension,OrientationStateType::CovarianceDimension>("orientation");
00039   rate_ = addSubState<RateStateType::VectorDimension,RateStateType::CovarianceDimension>("rate");
00040   position_ = addSubState<PositionStateType::VectorDimension,PositionStateType::CovarianceDimension>("position");
00041   velocity_ = addSubState<VelocityStateType::VectorDimension,VelocityStateType::CovarianceDimension>("velocity");
00042   construct();
00043 }
00044 
00045 FullState::~FullState() {}
00046 
00047 OrientationPositionVelocityState::OrientationPositionVelocityState()
00048 {
00049   orientation_ = addSubState<OrientationStateType::VectorDimension,OrientationStateType::CovarianceDimension>("orientation");
00050   position_ = addSubState<PositionStateType::VectorDimension,PositionStateType::CovarianceDimension>("position");
00051   velocity_ = addSubState<VelocityStateType::VectorDimension,VelocityStateType::CovarianceDimension>("velocity");
00052   construct();
00053 }
00054 
00055 OrientationPositionVelocityState::~OrientationPositionVelocityState() {}
00056 
00057 OrientationOnlyState::OrientationOnlyState()
00058 {
00059   orientation_ = addSubState<OrientationStateType::VectorDimension,OrientationStateType::CovarianceDimension>("orientation");
00060   construct();
00061 }
00062 
00063 OrientationOnlyState::~OrientationOnlyState() {}
00064 
00065 PositionVelocityState::PositionVelocityState()
00066 {
00067   position_ = addSubState<PositionStateType::VectorDimension,PositionStateType::CovarianceDimension>("position");
00068   velocity_ = addSubState<VelocityStateType::VectorDimension,VelocityStateType::CovarianceDimension>("velocity");
00069   construct();
00070 }
00071 
00072 PositionVelocityState::~PositionVelocityState() {}
00073 
00074 State::State() {}
00075 
00076 State::~State() {}
00077 
00078 void State::construct()
00079 {
00080   base_.reset(new BaseState(*this, getVectorDimension(), getCovarianceDimension()));
00081   reset();
00082 }
00083 
00084 void State::reset()
00085 {
00086   // reset status flags
00087   system_status_ = 0;
00088   measurement_status_ = 0;
00089 
00090   // reset pseudo-states
00091   fake_rate_ = Vector::Zero(3,1);
00092   fake_orientation_ = Vector::Zero(4,1);
00093   fake_position_ = Vector::Zero(3,1);
00094   fake_velocity_ = Vector::Zero(3,1);
00095   fake_acceleration_ = Vector::Zero(3,1);
00096 
00097   // reset state
00098   vector_.setZero();
00099   covariance_.setZero();
00100   fake_orientation_.w() = 1.0;
00101   if (orientation()) orientation()->vector().w() = 1.0;
00102 
00103   R_valid_ = false;
00104 }
00105 
00106 bool State::valid() const {
00107   return (vector_ == vector_);
00108 }
00109 
00110 void State::updated()
00111 {
00112   normalize();
00113   R_valid_ = false;
00114 }
00115 
00116 State::ConstOrientationType State::getOrientation() const   { return (orientation()  ? orientation()->getVector()  : ConstOrientationType(fake_orientation_, 0)); }
00117 State::ConstRateType State::getRate() const                 { return (rate()         ? rate()->getVector()         : ConstRateType(fake_rate_, 0)); }
00118 State::ConstPositionType State::getPosition() const         { return (position()     ? position()->getVector()     : ConstPositionType(fake_position_, 0)); }
00119 State::ConstVelocityType State::getVelocity() const         { return (velocity()     ? velocity()->getVector()     : ConstVelocityType(fake_velocity_, 0)); }
00120 State::ConstAccelerationType State::getAcceleration() const { return (acceleration() ? acceleration()->getVector() : ConstAccelerationType(fake_acceleration_, 0)); }
00121 
00122 void State::getRotationMatrix(RotationMatrix &R) const
00123 {
00124   Quaternion q(getOrientation());
00125   R = q.toRotationMatrix();
00126 //  R << (q.w()*q.w()+q.x()*q.x()-q.y()*q.y()-q.z()*q.z()), (2.0*q.x()*q.y()-2.0*q.w()*q.z()),                 (2.0*q.x()*q.z()+2.0*q.w()*q.y()),
00127 //       (2.0*q.x()*q.y()+2.0*q.w()*q.z()),                 (q.w()*q.w()-q.x()*q.x()+q.y()*q.y()-q.z()*q.z()), (2.0*q.y()*q.z()-2.0*q.w()*q.x()),
00128 //       (2.0*q.x()*q.z()-2.0*q.w()*q.y()),                 (2.0*q.y()*q.z()+2.0*q.w()*q.x()),                 (q.w()*q.w()-q.x()*q.x()-q.y()*q.y()+q.z()*q.z());
00129 }
00130 
00131 const State::RotationMatrix &State::R() const {
00132   if (!R_valid_) {
00133     getRotationMatrix(R_);
00134     R_valid_ = true;
00135   }
00136   return R_;
00137 }
00138 
00139 double State::getYaw() const
00140 {
00141   ConstOrientationType q(getOrientation());
00142   return atan2(2*q.x()*q.y() + 2*q.w()*q.z(), q.x()*q.x() + q.w()*q.w() - q.z()*q.z() - q.y()*q.y());
00143 }
00144 
00145 void State::getEuler(double &roll, double &pitch, double &yaw) const
00146 {
00147   ConstOrientationType q(getOrientation());
00148   roll  = atan2(2*(q.y()*q.z() + q.w()*q.x()), q.w()*q.w() - q.x()*q.x() - q.y()*q.y() + q.z()*q.z());
00149   pitch = -asin(2*(q.x()*q.z() - q.w()*q.y()));
00150   yaw   = atan2(2*(q.x()*q.y() + q.w()*q.z()), q.w()*q.w() + q.x()*q.x() - q.y()*q.y() - q.z()*q.z());
00151 }
00152 
00153 ColumnVector3 State::getEuler() const
00154 {
00155   ColumnVector3 euler;
00156   getEuler(euler(0), euler(1), euler(2));
00157   return euler;
00158 }
00159 
00160 void State::update(const Vector &vector_update)
00161 {
00162   if (orientation()) {
00163     // if vector_update has only n - 1 elements, we have to use covariance indices
00164     int orientation_index, orientation_size;
00165     if (vector_update.size() == getVectorDimension() - 1) {
00166       orientation_index = orientation()->getCovarianceIndex();
00167       orientation_size  = orientation()->getCovarianceDimension();
00168     } else {
00169       assert(vector_update.size() == getVectorDimension());
00170       orientation_index = orientation()->getVectorIndex();
00171       orientation_size  = orientation()->getVectorDimension();
00172     }
00173 
00174     // add everything before orientation part
00175     if (orientation_index > 0) {
00176       int length = orientation_index;
00177       x().head(length) += vector_update.head(length);
00178     }
00179 
00180     // add everything after orientation part
00181     if (orientation_index + orientation_size < vector_update.size()) {
00182       int length = vector_update.size() - orientation_index - orientation_size;
00183       x().tail(length) += vector_update.tail(length);
00184     }
00185 
00186     // update orientation
00187     updateOrientation(vector_update.segment<3>(orientation_index));
00188 
00189   } else {
00190     // simply add vectors
00191     x() += vector_update;
00192   }
00193 }
00194 
00195 void State::updateOrientation(const ColumnVector3 &rotation_vector)
00196 {
00197   if (!orientation()) return;
00198 
00199 //  Eigen::Quaterniond q(orientation()->vector().data());
00200 //  q = Eigen::Quaterniond(1.0, 0.5 * rotation_vector.x(), 0.5 * rotation_vector.y(), 0.5 * rotation_vector.z()) * q;
00201 //  orientation()->vector() = q.normalized().coeffs();
00202 
00203   // Eigen::Map<Eigen::Quaterniond> q(orientation()->vector().data());
00204   Eigen::Quaterniond q(orientation()->vector().data());
00205   q = Eigen::Quaterniond().fromRotationVector(rotation_vector) * q;
00206   orientation()->vector() = q.coeffs();
00207 
00208   R_valid_ = false;
00209 }
00210 
00211 bool State::inSystemStatus(SystemStatus test_status) const {
00212   return (getSystemStatus() & test_status) == test_status;
00213 }
00214 
00215 bool State::setSystemStatus(SystemStatus new_status) {
00216   if (new_status == system_status_) return true;
00217 
00218   // iterate through StatusCallbacks
00219   for(std::vector<SystemStatusCallback>::const_iterator it = status_callbacks_.begin(); it != status_callbacks_.end(); ++it)
00220     if (!(*it)(new_status)) return false;
00221 
00222   SystemStatus set = new_status & ~system_status_;
00223   SystemStatus cleared = system_status_ & ~new_status;
00224   if (set)     ROS_INFO_STREAM("Set system status " << getSystemStatusString(new_status, set));
00225   if (cleared) ROS_INFO_STREAM("Cleared system status " << getSystemStatusString(cleared, cleared));
00226 
00227   system_status_ = new_status;
00228   return true;
00229 }
00230 
00231 bool State::setMeasurementStatus(SystemStatus new_measurement_status) {
00232   SystemStatus set = new_measurement_status & ~measurement_status_;
00233   SystemStatus cleared = measurement_status_ & ~new_measurement_status;
00234   if (set)     ROS_INFO_STREAM("Set measurement status " << getSystemStatusString(new_measurement_status, set));
00235   if (cleared) ROS_INFO_STREAM("Cleared measurement status " << getSystemStatusString(cleared, cleared));
00236 
00237   measurement_status_ = new_measurement_status;
00238   return true;
00239 }
00240 
00241 bool State::updateSystemStatus(SystemStatus set, SystemStatus clear) {
00242   return setSystemStatus((system_status_ & ~clear) | set);
00243 }
00244 
00245 bool State::updateMeasurementStatus(SystemStatus set, SystemStatus clear) {
00246   return setMeasurementStatus((measurement_status_ & ~clear) | set);
00247 }
00248 
00249 void State::addSystemStatusCallback(const SystemStatusCallback& callback) {
00250 //  for(std::vector<SystemStatusCallback>::const_iterator it = status_callbacks_.begin(); it != status_callbacks_.end(); ++it)
00251 //    if (*it == callback) return;
00252   status_callbacks_.push_back(callback);
00253 }
00254 
00255 void State::normalize() {
00256   if (orientation()) {
00257     double s = 1.0 / orientation()->vector().norm();
00258     orientation()->vector() = orientation()->vector() * s;
00259   }
00260 }
00261 
00262 void State::setOrientation(const Quaternion& orientation)
00263 {
00264   setOrientation(orientation.coeffs());
00265 }
00266 
00267 void State::setRollPitch(const Quaternion& q)
00268 {
00269   ScalarType roll, pitch;
00270   roll  = atan2(2*(q.y()*q.z() + q.w()*q.x()), q.w()*q.w() - q.x()*q.x() - q.y()*q.y() + q.z()*q.z());
00271   pitch = -asin(2*(q.x()*q.z() - q.w()*q.y()));
00272   setRollPitch(roll, pitch);
00273 }
00274 
00275 void State::setRollPitch(ScalarType roll, ScalarType pitch)
00276 {
00277   ScalarType yaw = getYaw();
00278   fake_orientation_ = Quaternion(Eigen::AngleAxis<ScalarType>(yaw, ColumnVector3::UnitZ()) * Eigen::AngleAxis<ScalarType>(pitch, ColumnVector3::UnitY()) * Eigen::AngleAxis<ScalarType>(roll, ColumnVector3::UnitX())).coeffs();
00279 }
00280 
00281 void State::setYaw(const Quaternion& orientation)
00282 {
00283   const Quaternion &q = orientation;
00284   double yaw = atan2(2*(q.x()*q.y() + q.w()*q.z()), q.w()*q.w() + q.x()*q.x() - q.y()*q.y() - q.z()*q.z());
00285   setYaw(yaw);
00286 }
00287 
00288 void State::setYaw(ScalarType yaw)
00289 {
00290   ColumnVector3 euler = getEuler();
00291   fake_orientation_ = Quaternion(Eigen::AngleAxis<ScalarType>(yaw, ColumnVector3::UnitZ()) * Eigen::AngleAxis<ScalarType>(euler(1), ColumnVector3::UnitY()) * Eigen::AngleAxis<ScalarType>(euler(2), ColumnVector3::UnitX())).coeffs();
00292 }
00293 
00294 template class SubState::initializer<Dynamic,Dynamic>;
00295 template class SubState_<Dynamic,Dynamic>;
00296 
00297 } // namespace hector_pose_estimation


hector_pose_estimation_core
Author(s): Johannes Meyer
autogenerated on Fri Aug 28 2015 10:59:55