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/pose_estimation.h>
00030 #include <hector_pose_estimation/filter/ekf.h>
00031 #include <hector_pose_estimation/global_reference.h>
00032
00033 #include <hector_pose_estimation/system/imu_input.h>
00034 #include <hector_pose_estimation/system/imu_model.h>
00035
00036 #include <boost/weak_ptr.hpp>
00037
00038 namespace hector_pose_estimation {
00039
00040 namespace {
00041 static PoseEstimation *the_instance = 0;
00042 }
00043
00044 PoseEstimation::PoseEstimation(const SystemPtr& system)
00045 : rate_update_(new Rate("rate"))
00046 , gravity_update_(new Gravity ("gravity"))
00047 , zerorate_update_(new ZeroRate("zerorate"))
00048 {
00049 if (!the_instance) the_instance = this;
00050 if (system) addSystem(system);
00051
00052 world_frame_ = "/world";
00053 nav_frame_ = "nav";
00054 base_frame_ = "base_link";
00055 stabilized_frame_ = "base_stabilized";
00056 footprint_frame_ = "base_footprint";
00057
00058 alignment_time_ = 0.0;
00059 gravity_ = -9.8065;
00060
00061 parameters().add("world_frame", world_frame_);
00062 parameters().add("nav_frame", nav_frame_);
00063 parameters().add("base_frame", base_frame_);
00064 parameters().add("stabilized_frame", stabilized_frame_);
00065 parameters().add("footprint_frame", footprint_frame_);
00066 parameters().add("position_frame", position_frame_);
00067 parameters().add(globalReference()->parameters());
00068 parameters().add("alignment_time", alignment_time_);
00069 parameters().add("gravity_magnitude", gravity_);
00070
00071
00072 addMeasurement(rate_update_);
00073 addMeasurement(gravity_update_);
00074 addMeasurement(zerorate_update_);
00075 }
00076
00077 PoseEstimation::~PoseEstimation()
00078 {
00079 cleanup();
00080 }
00081
00082 PoseEstimation *PoseEstimation::Instance() {
00083 if (!the_instance) the_instance = new PoseEstimation();
00084 return the_instance;
00085 }
00086
00087 bool PoseEstimation::init()
00088 {
00089
00090 globalReference()->updated();
00091
00092
00093 if (systems_.empty()) return false;
00094
00095
00096 filter_.reset(new filter::EKF);
00097
00098
00099 for(Measurements::iterator it = measurements_.begin(); it != measurements_.end(); ++it)
00100 if (!(*it)->init(*this, state())) return false;
00101
00102
00103 for(Systems::iterator it = systems_.begin(); it != systems_.end(); ++it)
00104 if (!(*it)->init(*this, state())) return false;
00105
00106
00107 filter_->init(*this);
00108
00109
00110 for(Systems::iterator it = systems_.begin(); it != systems_.end(); ++it)
00111 (*it)->setFilter(filter_.get());
00112 for(Measurements::iterator it = measurements_.begin(); it != measurements_.end(); ++it)
00113 (*it)->setFilter(filter_.get());
00114
00115
00116 reset();
00117
00118 return true;
00119 }
00120
00121 void PoseEstimation::cleanup()
00122 {
00123
00124 for(Systems::iterator it = systems_.begin(); it != systems_.end(); ++it) (*it)->cleanup();
00125
00126
00127 for(Measurements::iterator it = measurements_.begin(); it != measurements_.end(); ++it) (*it)->cleanup();
00128
00129
00130 if (filter_) filter_.reset();
00131 }
00132
00133 void PoseEstimation::reset()
00134 {
00135
00136 if (systems_.empty()) return;
00137
00138
00139 if (filter_) filter_->reset();
00140
00141
00142 alignment_start_ = ros::Time();
00143 if (alignment_time_ > 0) {
00144 state().setSystemStatus(STATUS_ALIGNMENT);
00145 }
00146
00147
00148 for(Systems::iterator it = systems_.begin(); it != systems_.end(); ++it) {
00149 (*it)->reset(state());
00150 (*it)->getPrior(state());
00151 }
00152
00153 for(Measurements::iterator it = measurements_.begin(); it != measurements_.end(); ++it) {
00154 (*it)->reset(state());
00155 }
00156
00157 updated();
00158 }
00159
00160 void PoseEstimation::update(ros::Time new_timestamp)
00161 {
00162
00163 if (systems_.empty()) return;
00164
00165 ros::Duration dt;
00166 if (!getTimestamp().isZero()) dt = new_timestamp - getTimestamp();
00167 setTimestamp(new_timestamp);
00168
00169
00170 update(dt.toSec());
00171 }
00172
00173 void PoseEstimation::update(double dt)
00174 {
00175
00176 if (dt < -1.0)
00177 reset();
00178 else if (dt < 0.0)
00179 return;
00180 else if (dt > 1.0)
00181 dt = 1.0;
00182
00183
00184 if (systems_.empty() || !filter_) return;
00185
00186
00187 boost::shared_ptr<ImuInput> imu = boost::shared_dynamic_cast<ImuInput>(getInput("imu"));
00188 state().setRate(imu->getRate());
00189 state().setAcceleration(imu->getAcceleration());
00190
00191 #ifdef USE_RATE_SYSTEM_MODEL
00192 if (imu && rate_update_) {
00193 rate_update_->update(Rate::Update(imu->getRate()));
00194 }
00195 #endif // USE_RATE_SYSTEM_MODEL
00196
00197
00198 filter_->predict(systems_, dt);
00199
00200
00201 gravity_update_->update(Gravity::Update(imu->getAcceleration()));
00202 zerorate_update_->update(ZeroRate::Update());
00203
00204
00205 filter_->correct(measurements_);
00206
00207
00208 for(Measurements::iterator it = measurements_.begin(); it != measurements_.end(); it++) {
00209 const MeasurementPtr& measurement = *it;
00210 measurement->increase_timer(dt);
00211 }
00212
00213
00214 if (!state().valid()) {
00215 ROS_FATAL("Invalid state, resetting...");
00216 reset();
00217 return;
00218 }
00219
00220
00221 updated();
00222
00223
00224 if (inSystemStatus(STATUS_ALIGNMENT)) {
00225 if (alignment_start_.isZero()) alignment_start_ = getTimestamp();
00226 if ((getTimestamp() - alignment_start_).toSec() >= alignment_time_) {
00227 updateSystemStatus(STATUS_DEGRADED, STATUS_ALIGNMENT);
00228 }
00229 } else if (inSystemStatus(STATE_ROLLPITCH | STATE_YAW | STATE_POSITION_XY | STATE_POSITION_Z)) {
00230 updateSystemStatus(STATUS_READY, STATUS_DEGRADED);
00231 } else {
00232 updateSystemStatus(STATUS_DEGRADED, STATUS_READY);
00233 }
00234 }
00235
00236 void PoseEstimation::updated() {
00237 for(Systems::iterator it = systems_.begin(); it != systems_.end(); ++it) {
00238 (*it)->limitState(state());
00239 }
00240 }
00241
00242 const SystemPtr& PoseEstimation::addSystem(const SystemPtr& system, const std::string& name) {
00243 if (!name.empty() && system->getName().empty()) system->setName(name);
00244 parameters().add(system->getName(), system->parameters());
00245 return systems_.add(system, system->getName());
00246 }
00247
00248 InputPtr PoseEstimation::addInput(const InputPtr& input, const std::string& name)
00249 {
00250 if (!name.empty()) input->setName(name);
00251 return inputs_.add(input, input->getName());
00252 }
00253
00254 InputPtr PoseEstimation::setInput(const Input& value, std::string name)
00255 {
00256 if (name.empty()) name = value.getName();
00257 InputPtr input = inputs_.get(name);
00258 if (!input) {
00259 ROS_WARN("Set input \"%s\", but this input is not registered by any system model.", name.c_str());
00260 return InputPtr();
00261 }
00262
00263 *input = value;
00264 return input;
00265 }
00266
00267 const MeasurementPtr& PoseEstimation::addMeasurement(const MeasurementPtr& measurement, const std::string& name) {
00268 if (!name.empty()) measurement->setName(name);
00269 parameters().add(measurement->getName(), measurement->parameters());
00270 return measurements_.add(measurement, measurement->getName());
00271 }
00272
00273 const State::Vector& PoseEstimation::getStateVector() {
00274
00275
00276
00277
00278 return state().getVector();
00279 }
00280
00281 const State::Covariance& PoseEstimation::getCovariance() {
00282
00283
00284
00285
00286 return state().getCovariance();
00287 }
00288
00289 SystemStatus PoseEstimation::getSystemStatus() const {
00290 return state().getSystemStatus();
00291 }
00292
00293 SystemStatus PoseEstimation::getMeasurementStatus() const {
00294 return state().getMeasurementStatus();
00295 }
00296
00297 bool PoseEstimation::inSystemStatus(SystemStatus test_status) const {
00298 return state().inSystemStatus(test_status);
00299 }
00300
00301 bool PoseEstimation::setSystemStatus(SystemStatus new_status) {
00302 return state().setSystemStatus(new_status);
00303 }
00304
00305 bool PoseEstimation::setMeasurementStatus(SystemStatus new_measurement_status) {
00306 return state().setMeasurementStatus(new_measurement_status);
00307 }
00308
00309 bool PoseEstimation::updateSystemStatus(SystemStatus set, SystemStatus clear) {
00310 return state().updateSystemStatus(set, clear);
00311 }
00312
00313 bool PoseEstimation::updateMeasurementStatus(SystemStatus set, SystemStatus clear) {
00314 return state().updateMeasurementStatus(set, clear);
00315 }
00316
00317 const ros::Time& PoseEstimation::getTimestamp() const {
00318 return state().getTimestamp();
00319 }
00320
00321 void PoseEstimation::setTimestamp(const ros::Time& timestamp) {
00322 state().setTimestamp(timestamp);
00323 }
00324
00325 void PoseEstimation::getHeader(std_msgs::Header& header) {
00326 header.stamp = getTimestamp();
00327 header.frame_id = nav_frame_;
00328 }
00329
00330 void PoseEstimation::getState(nav_msgs::Odometry& msg, bool with_covariances) {
00331 getHeader(msg.header);
00332 getPose(msg.pose.pose);
00333 getVelocity(msg.twist.twist.linear);
00334 getRate(msg.twist.twist.angular);
00335 msg.child_frame_id = base_frame_;
00336
00337 if (with_covariances) {
00338 State::ConstOrientationType q(state().getOrientation());
00339
00340
00341 Eigen::Matrix<ScalarType,3,4> quat_to_angular_rate;
00342 quat_to_angular_rate << -q.x(), q.w(), -q.z(), q.y(),
00343 -q.y(), q.z(), q.w(), -q.x(),
00344 -q.z(), -q.y(), q.x(), q.w();
00345 quat_to_angular_rate *= 2.0;
00346
00347 State::Covariance covariance(state().getCovariance());
00348 Eigen::Map< Eigen::Matrix<geometry_msgs::PoseWithCovariance::_covariance_type::value_type,6,6> > pose_covariance_msg(msg.pose.covariance.data());
00349 Eigen::Map< Eigen::Matrix<geometry_msgs::TwistWithCovariance::_covariance_type::value_type,6,6> > twist_covariance_msg(msg.twist.covariance.data());
00350
00351
00352 if (state().getPositionIndex() >= 0) {
00353 pose_covariance_msg.block<3,3>(0,0) = covariance.block<3,3>(state().getPositionIndex(), state().getPositionIndex());
00354 }
00355
00356
00357 if (state().getOrientationIndex() >= 0) {
00358 pose_covariance_msg.block<3,3>(3,3) = quat_to_angular_rate * covariance.block<4,4>(state().getOrientationIndex(), state().getOrientationIndex()) * quat_to_angular_rate.transpose();
00359 }
00360
00361
00362 if (state().getPositionIndex() >= 0 && state().getOrientationIndex() >= 0) {
00363 pose_covariance_msg.block<3,3>(0,3) = covariance.block<3,4>(state().getPositionIndex(), state().getOrientationIndex()) * quat_to_angular_rate.transpose();
00364 pose_covariance_msg.block<3,3>(3,0) = pose_covariance_msg.block<3,3>(0,3).transpose();
00365 }
00366
00367
00368 if (state().getVelocityIndex() >= 0) {
00369 twist_covariance_msg.block<3,3>(0,0) = covariance.block<3,3>(state().getVelocityIndex(), state().getVelocityIndex());
00370 }
00371
00372
00373 if (state().getRateIndex() >= 0) {
00374 twist_covariance_msg.block<3,3>(3,3) = covariance.block<3,3>(state().getRateIndex(), state().getRateIndex());
00375 }
00376
00377
00378 if (state().getVelocityIndex() >= 0 && state().getRateIndex() >= 0) {
00379 pose_covariance_msg.block<3,3>(0,3) = covariance.block<3,3>(state().getVelocityIndex(), state().getRateIndex());
00380 pose_covariance_msg.block<3,3>(3,0) = pose_covariance_msg.block<3,3>(0,3).transpose();
00381 }
00382 }
00383 }
00384
00385 void PoseEstimation::getPose(tf::Pose& pose) {
00386 tf::Quaternion quaternion;
00387 getPosition(pose.getOrigin());
00388 getOrientation(quaternion);
00389 pose.setRotation(quaternion);
00390 }
00391
00392 void PoseEstimation::getPose(tf::Stamped<tf::Pose>& pose) {
00393 getPose(static_cast<tf::Pose &>(pose));
00394 pose.stamp_ = getTimestamp();
00395 pose.frame_id_ = nav_frame_;
00396 }
00397
00398 void PoseEstimation::getPose(geometry_msgs::Pose& pose) {
00399 getPosition(pose.position);
00400 getOrientation(pose.orientation);
00401 }
00402
00403 void PoseEstimation::getPose(geometry_msgs::PoseStamped& pose) {
00404 getHeader(pose.header);
00405 getPose(pose.pose);
00406 }
00407
00408 void PoseEstimation::getPosition(tf::Point& point) {
00409 State::ConstPositionType position(state().getPosition());
00410 point = tf::Point(position.x(), position.y(), position.z());
00411 }
00412
00413 void PoseEstimation::getPosition(tf::Stamped<tf::Point>& point) {
00414 getPosition(static_cast<tf::Point &>(point));
00415 point.stamp_ = getTimestamp();
00416 point.frame_id_ = nav_frame_;
00417 }
00418
00419 void PoseEstimation::getPosition(geometry_msgs::Point& point) {
00420 State::ConstPositionType position(state().getPosition());
00421 point.x = position.x();
00422 point.y = position.y();
00423 point.z = position.z();
00424 }
00425
00426 void PoseEstimation::getPosition(geometry_msgs::PointStamped& point) {
00427 getHeader(point.header);
00428 getPosition(point.point);
00429 }
00430
00431 void PoseEstimation::getGlobalPosition(double &latitude, double &longitude, double &altitude) {
00432 State::ConstPositionType position(state().getPosition());
00433 double north = position.x() * globalReference()->heading().cos - position.y() * globalReference()->heading().sin;
00434 double east = -position.x() * globalReference()->heading().sin - position.y() * globalReference()->heading().cos;
00435 latitude = globalReference()->position().latitude + north / globalReference()->radius().north;
00436 longitude = globalReference()->position().longitude + east / globalReference()->radius().east;
00437 altitude = globalReference()->position().altitude + position.z();
00438 }
00439
00440 void PoseEstimation::getGlobalPosition(sensor_msgs::NavSatFix& global)
00441 {
00442 getHeader(global.header);
00443 global.header.frame_id = world_frame_;
00444
00445 if ((getSystemStatus() & STATE_POSITION_XY) && globalReference()->hasPosition()) {
00446 global.status.status = sensor_msgs::NavSatStatus::STATUS_FIX;
00447 } else {
00448 global.status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
00449 }
00450
00451 getGlobalPosition(global.latitude, global.longitude, global.altitude);
00452 global.latitude *= 180.0/M_PI;
00453 global.longitude *= 180.0/M_PI;
00454
00455 if (getSystemStatus() & STATE_POSITION_XY) {
00456 global.status.status = sensor_msgs::NavSatStatus::STATUS_FIX;
00457 } else {
00458 global.status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
00459 }
00460 }
00461
00462 void PoseEstimation::getOrientation(tf::Quaternion& quaternion) {
00463 Quaternion orientation(state().getOrientation());
00464 quaternion = tf::Quaternion(orientation.x(), orientation.y(), orientation.z(), orientation.w());
00465 }
00466
00467 void PoseEstimation::getOrientation(tf::Stamped<tf::Quaternion>& quaternion) {
00468 getOrientation(static_cast<tf::Quaternion &>(quaternion));
00469 quaternion.stamp_ = getTimestamp();
00470 quaternion.frame_id_ = nav_frame_;
00471 }
00472
00473 void PoseEstimation::getOrientation(geometry_msgs::Quaternion& quaternion) {
00474 Quaternion orientation(state().getOrientation());
00475 quaternion.w = orientation.w();
00476 quaternion.x = orientation.x();
00477 quaternion.y = orientation.y();
00478 quaternion.z = orientation.z();
00479 }
00480
00481 void PoseEstimation::getOrientation(geometry_msgs::QuaternionStamped& quaternion) {
00482 getHeader(quaternion.header);
00483 getOrientation(quaternion.quaternion);
00484 }
00485
00486 void PoseEstimation::getOrientation(double &yaw, double &pitch, double &roll) {
00487 tf::Quaternion quaternion;
00488 getOrientation(quaternion);
00489 #ifdef TF_MATRIX3x3_H
00490 tf::Matrix3x3(quaternion).getRPY(roll, pitch, yaw);
00491 #else
00492 btMatrix3x3(quaternion).getRPY(roll, pitch, yaw);
00493 #endif
00494 }
00495
00496 void PoseEstimation::getImuWithBiases(geometry_msgs::Vector3& linear_acceleration, geometry_msgs::Vector3& angular_velocity) {
00497 boost::shared_ptr<const ImuInput> input = boost::shared_dynamic_cast<const ImuInput>(getInput("imu"));
00498 boost::shared_ptr<const Accelerometer> accel = boost::shared_dynamic_cast<const Accelerometer>(getSystem("accelerometer"));
00499
00500 if (input) {
00501 linear_acceleration.x = input->getAcceleration().x();
00502 linear_acceleration.y = input->getAcceleration().y();
00503 linear_acceleration.z = input->getAcceleration().z();
00504 } else {
00505 linear_acceleration.x = 0.0;
00506 linear_acceleration.y = 0.0;
00507 linear_acceleration.z = 0.0;
00508 }
00509
00510 if (accel) {
00511 linear_acceleration.x += accel->getModel()->getBias().x();
00512 linear_acceleration.y += accel->getModel()->getBias().y();
00513 linear_acceleration.z += accel->getModel()->getBias().z();
00514 }
00515
00516 getRate(angular_velocity);
00517 }
00518
00519 void PoseEstimation::getVelocity(tf::Vector3& vector) {
00520 State::ConstVelocityType velocity(state().getVelocity());
00521 vector = tf::Vector3(velocity.x(), velocity.y(), velocity.z());
00522 }
00523
00524 void PoseEstimation::getVelocity(tf::Stamped<tf::Vector3>& vector) {
00525 getVelocity(static_cast<tf::Vector3 &>(vector));
00526 vector.stamp_ = getTimestamp();
00527 #ifdef VELOCITY_IN_BODY_FRAME
00528 vector.frame_id_ = base_frame_;
00529 #else
00530 vector.frame_id_ = nav_frame_;
00531 #endif
00532 }
00533
00534 void PoseEstimation::getVelocity(geometry_msgs::Vector3& vector) {
00535 State::ConstVelocityType velocity(state().getVelocity());
00536 vector.x = velocity.x();
00537 vector.y = velocity.y();
00538 vector.z = velocity.z();
00539 }
00540
00541 void PoseEstimation::getVelocity(geometry_msgs::Vector3Stamped& vector) {
00542 getHeader(vector.header);
00543 #ifdef VELOCITY_IN_BODY_FRAME
00544 vector.header.frame_id = base_frame_;
00545 #endif
00546 getVelocity(vector.vector);
00547 }
00548
00549 void PoseEstimation::getRate(tf::Vector3& vector) {
00550 geometry_msgs::Vector3 rate;
00551 getRate(rate);
00552 vector = tf::Vector3(rate.x, rate.y, rate.z);
00553 }
00554
00555 void PoseEstimation::getRate(tf::Stamped<tf::Vector3>& vector) {
00556 getRate(static_cast<tf::Vector3 &>(vector));
00557 vector.stamp_ = getTimestamp();
00558 #ifdef VELOCITY_IN_BODY_FRAME
00559 vector.frame_id_ = base_frame_;
00560 #else
00561 vector.frame_id_ = nav_frame_;
00562 #endif
00563 }
00564
00565 void PoseEstimation::getRate(geometry_msgs::Vector3& vector) {
00566 if (state().getRateIndex() >= 0) {
00567 State::ConstRateType rate(state().getRate());
00568 vector.x = rate.x();
00569 vector.y = rate.y();
00570 vector.z = rate.z();
00571
00572 } else {
00573 boost::shared_ptr<const ImuInput> input = boost::shared_dynamic_cast<const ImuInput>(getInput("imu"));
00574 boost::shared_ptr<const Gyro> gyro = boost::shared_dynamic_cast<const Gyro>(getSystem("gyro"));
00575
00576 if (input) {
00577 vector.x = input->getRate().x();
00578 vector.y = input->getRate().y();
00579 vector.z = input->getRate().z();
00580 } else {
00581 vector.x = 0.0;
00582 vector.y = 0.0;
00583 vector.z = 0.0;
00584 }
00585
00586 if (gyro) {
00587 vector.x += gyro->getModel()->getBias().x();
00588 vector.y += gyro->getModel()->getBias().y();
00589 vector.z += gyro->getModel()->getBias().z();
00590 }
00591 }
00592 }
00593
00594 void PoseEstimation::getRate(geometry_msgs::Vector3Stamped& vector) {
00595 getHeader(vector.header);
00596 getRate(vector.vector);
00597
00598 if (state().getRateIndex() >= 0) {
00599 #ifdef VELOCITY_IN_BODY_FRAME
00600 vector.header.frame_id = base_frame_;
00601 #else
00602 vector.header.frame_id = nav_frame_;
00603 #endif
00604 } else {
00605 vector.header.frame_id = base_frame_;
00606 }
00607 }
00608
00609 void PoseEstimation::getBias(geometry_msgs::Vector3& angular_velocity, geometry_msgs::Vector3& linear_acceleration) {
00610 boost::shared_ptr<const ImuInput> input = boost::shared_dynamic_cast<const ImuInput>(getInput("imu"));
00611 boost::shared_ptr<const Accelerometer> accel = boost::shared_dynamic_cast<const Accelerometer>(getSystem("accelerometer"));
00612 boost::shared_ptr<const Gyro> gyro = boost::shared_dynamic_cast<const Gyro>(getSystem("gyro"));
00613
00614 if (gyro) {
00615 angular_velocity.x = gyro->getModel()->getBias().x();
00616 angular_velocity.y = gyro->getModel()->getBias().y();
00617 angular_velocity.z = gyro->getModel()->getBias().z();
00618 } else {
00619 angular_velocity.x = 0.0;
00620 angular_velocity.y = 0.0;
00621 angular_velocity.z = 0.0;
00622 }
00623
00624 if (accel) {
00625 linear_acceleration.x = accel->getModel()->getBias().x();
00626 linear_acceleration.y = accel->getModel()->getBias().y();
00627 linear_acceleration.z = accel->getModel()->getBias().z();
00628 } else {
00629 linear_acceleration.x = 0.0;
00630 linear_acceleration.y = 0.0;
00631 linear_acceleration.z = 0.0;
00632 }
00633 }
00634
00635 void PoseEstimation::getBias(geometry_msgs::Vector3Stamped& angular_velocity, geometry_msgs::Vector3Stamped& linear_acceleration) {
00636 getBias(angular_velocity.vector, linear_acceleration.vector);
00637 angular_velocity.header.stamp = getTimestamp();
00638 angular_velocity.header.frame_id = base_frame_;
00639 linear_acceleration.header.stamp = getTimestamp();
00640 linear_acceleration.header.frame_id = base_frame_;
00641 }
00642
00643 void PoseEstimation::getTransforms(std::vector<tf::StampedTransform>& transforms) {
00644 tf::Quaternion orientation;
00645 tf::Point position;
00646 getOrientation(orientation);
00647 getPosition(position);
00648
00649 tf::Transform transform(orientation, position);
00650 double y,p,r;
00651 transform.getBasis().getEulerYPR(y,p,r);
00652
00653 std::string parent_frame = nav_frame_;
00654
00655 if(!position_frame_.empty()) {
00656 tf::Transform position_transform;
00657 position_transform.getBasis().setIdentity();
00658 position_transform.setOrigin(tf::Point(position.x(), position.y(), position.z()));
00659 transforms.push_back(tf::StampedTransform(position_transform, getTimestamp(), parent_frame, position_frame_ ));
00660 }
00661
00662 if (!footprint_frame_.empty()) {
00663 tf::Transform footprint_transform;
00664 footprint_transform.getBasis().setEulerYPR(y, 0.0, 0.0);
00665 footprint_transform.setOrigin(tf::Point(position.x(), position.y(), 0.0));
00666 transforms.push_back(tf::StampedTransform(footprint_transform, getTimestamp(), parent_frame, footprint_frame_));
00667
00668 parent_frame = footprint_frame_;
00669 transform = footprint_transform.inverseTimes(transform);
00670 }
00671
00672 if (!stabilized_frame_.empty()) {
00673 tf::Transform stabilized_transform(transform);
00674 #ifdef TF_MATRIX3x3_H
00675 tf::Matrix3x3 rollpitch_rotation; rollpitch_rotation.setEulerYPR(0.0, p, r);
00676 #else
00677 btMatrix3x3 rollpitch_rotation; rollpitch_rotation.setEulerYPR(0.0, p, r);
00678 #endif
00679 stabilized_transform = stabilized_transform * tf::Transform(rollpitch_rotation.inverse());
00680 transforms.push_back(tf::StampedTransform(stabilized_transform, getTimestamp(), parent_frame, stabilized_frame_));
00681
00682 parent_frame = stabilized_frame_;
00683 transform = stabilized_transform.inverseTimes(transform);
00684 }
00685
00686 transforms.push_back(tf::StampedTransform(transform, getTimestamp(), parent_frame, base_frame_));
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 }
00710
00711 void PoseEstimation::updateWorldToOtherTransform(tf::StampedTransform& world_to_other_transform) {
00712 world_to_other_transform.frame_id_ = world_frame_;
00713
00714 double y,p,r;
00715 world_to_other_transform.getBasis().getEulerYPR(y,p,r);
00716 if (!(getSystemStatus() & (STATE_ROLLPITCH | STATE_PSEUDO_ROLLPITCH))) { r = p = 0.0; }
00717 if (!(getSystemStatus() & (STATE_YAW | STATE_PSEUDO_YAW))) { y = 0.0; }
00718 if (!(getSystemStatus() & (STATE_POSITION_XY | STATE_PSEUDO_POSITION_XY))) { world_to_other_transform.getOrigin().setX(0.0); world_to_other_transform.getOrigin().setY(0.0); }
00719 if (!(getSystemStatus() & (STATE_POSITION_Z | STATE_PSEUDO_POSITION_Z))) { world_to_other_transform.getOrigin().setZ(0.0); }
00720 world_to_other_transform.getBasis().setEulerYPR(y, p, r);
00721 }
00722
00723 const GlobalReferencePtr &PoseEstimation::globalReference() {
00724 return GlobalReference::Instance();
00725 }
00726
00727 }