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/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
00087 system_status_ = 0;
00088 measurement_status_ = 0;
00089
00090
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
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
00127
00128
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
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
00175 if (orientation_index > 0) {
00176 int length = orientation_index;
00177 x().head(length) += vector_update.head(length);
00178 }
00179
00180
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
00187 updateOrientation(vector_update.segment<3>(orientation_index));
00188
00189 } else {
00190
00191 x() += vector_update;
00192 }
00193 }
00194
00195 void State::updateOrientation(const ColumnVector3 &rotation_vector)
00196 {
00197 if (!orientation()) return;
00198
00199
00200
00201
00202
00203
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
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
00251
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 }