00001 #include "Object.h"
00002 #include "parameters.h"
00003 #include <boost/lexical_cast.hpp>
00004
00005 #include <Eigen/Geometry>
00006 #include <tf/transform_datatypes.h>
00007
00008 namespace hector_object_tracker {
00009
00010 std::map<std::string,unsigned int> Object::object_count;
00011 std::string Object::object_namespace;
00012
00013 Object::Object(const std::string class_id, const std::string object_id)
00014 {
00015 if (!class_id.empty()) {
00016 this->info.class_id = class_id;
00017 } else {
00018 this->info.class_id = "object";
00019 }
00020
00021 if (!object_id.empty()) {
00022 this->info.object_id = object_id;
00023 } else {
00024 this->info.object_id = this->info.class_id + "_" + boost::lexical_cast<std::string>(object_count[this->info.class_id]++);
00025 }
00026
00027
00028 }
00029
00030 Object::Object(const hector_worldmodel_msgs::Object& other) {
00031 *this = other;
00032 }
00033
00034 Object::~Object()
00035 {}
00036
00037 void Object::reset() {
00038 object_count.clear();
00039 }
00040
00041 void Object::getMessage(hector_worldmodel_msgs::Object& object) const {
00042 object.header = this->header;
00043 this->getPoseWithCovariance(object.pose);
00044 object.info = this->info;
00045 object.state = this->state;
00046 }
00047
00048 hector_worldmodel_msgs::Object Object::getMessage() const {
00049 hector_worldmodel_msgs::Object object;
00050 getMessage(object);
00051 return object;
00052 }
00053
00054 void Object::getPoseWithCovariance(geometry_msgs::PoseWithCovariance& pose) const {
00055 getPose(pose.pose);
00056 getCovariance(pose.covariance);
00057 }
00058
00059 void Object::setPose(const geometry_msgs::PoseWithCovariance& pose) {
00060 setPose(pose.pose);
00061 setCovariance(pose.covariance);
00062 }
00063
00064 void Object::getPose(geometry_msgs::Pose& pose) const
00065 {
00066 pose.position.x = this->position.x();
00067 pose.position.y = this->position.y();
00068 pose.position.z = this->position.z();
00069 pose.orientation.w = this->orientation.w();
00070 pose.orientation.x = this->orientation.x();
00071 pose.orientation.y = this->orientation.y();
00072 pose.orientation.z = this->orientation.z();
00073 }
00074
00075 void Object::getPose(tf::Pose& pose) const
00076 {
00077 pose.getOrigin().setValue(this->position.x(), this->position.y(), this->position.z());
00078 pose.getBasis().setRotation(tf::Quaternion(this->orientation.x(), this->orientation.y(), this->orientation.z(), this->orientation.w()));
00079 }
00080
00081 void Object::setPose(const geometry_msgs::Pose& pose)
00082 {
00083 setPosition(pose.position);
00084 setOrientation(pose.orientation);
00085 }
00086
00087 void Object::setPose(const tf::Pose &pose)
00088 {
00089 setPosition(pose.getOrigin());
00090 tf::Quaternion rot;
00091 pose.getBasis().getRotation(rot);
00092 setOrientation(rot);
00093 }
00094
00095 const Eigen::Vector3f& Object::getPosition() const {
00096 return position;
00097 }
00098
00099 void Object::setPosition(const Eigen::Vector3f& position) {
00100 this->position = position;
00101 }
00102
00103 void Object::setPosition(const geometry_msgs::Point& position) {
00104 this->position << position.x, position.y, position.z;
00105 }
00106
00107 void Object::setPosition(const tf::Point& position)
00108 {
00109 this->position << position.x(), position.y(), position.z();
00110 }
00111
00112 const Eigen::Quaternionf& Object::getOrientation() const
00113 {
00114 return this->orientation;
00115 }
00116
00117 void Object::setOrientation(const geometry_msgs::Quaternion& orientation)
00118 {
00119 this->orientation.coeffs() << orientation.x, orientation.y, orientation.z, orientation.w;
00120 }
00121
00122 void Object::setOrientation(const tf::Quaternion& orientation)
00123 {
00124 this->orientation.coeffs() << orientation.x(), orientation.y(), orientation.z(), orientation.w();
00125 }
00126
00127 const Eigen::Matrix3f& Object::getCovariance() const {
00128 return covariance;
00129 }
00130
00131 void Object::getCovariance(geometry_msgs::PoseWithCovariance::_covariance_type& covariance) const {
00132 covariance[0] = this->covariance(0,0);
00133 covariance[1] = this->covariance(0,1);
00134 covariance[2] = this->covariance(0,2);
00135 covariance[6] = this->covariance(1,0);
00136 covariance[7] = this->covariance(1,1);
00137 covariance[8] = this->covariance(1,2);
00138 covariance[12] = this->covariance(2,0);
00139 covariance[13] = this->covariance(2,1);
00140 covariance[14] = this->covariance(2,2);
00141 }
00142
00143 void Object::setCovariance(const Eigen::Matrix3f& eigen) {
00144 this->covariance = eigen;
00145 }
00146
00147 void Object::setCovariance(const tf::Matrix3x3& tf) {
00148 this->covariance << tf[0][0], tf[0][1], tf[0][2],
00149 tf[1][0], tf[1][1], tf[1][2],
00150 tf[2][0], tf[2][1], tf[2][2];
00151 }
00152
00153 void Object::setCovariance(const geometry_msgs::PoseWithCovariance::_covariance_type& covariance) {
00154 this->covariance << covariance[0], covariance[1], covariance[2],
00155 covariance[6], covariance[7], covariance[8],
00156 covariance[12], covariance[13], covariance[14];
00157 }
00158
00159 void Object::setState(const StateType& state) {
00160 if (this->state.state == state) return;
00161 ROS_INFO("Setting object state for %s to %s", getObjectId().c_str(), hector_worldmodel_msgs::getObjectStateString(state));
00162 this->state.state = state;
00163 }
00164
00165 void Object::intersect(const tf::Pose& poseB, const Eigen::Matrix3f& covarianceB, float support) {
00166 Eigen::Vector3f positionB(poseB.getOrigin().x(), poseB.getOrigin().y(), poseB.getOrigin().z());
00167 tf::Quaternion orientationB = poseB.getRotation();
00168
00169 float omega = 0.5f;
00170
00171 Eigen::Matrix3f A(covariance.inverse() * omega);
00172 Eigen::Matrix3f B(covarianceB.inverse() * (1.0f - omega));
00173 double infA = 1./covariance.trace();
00174 double infB = 1./covarianceB.trace();
00175
00176 covariance = (A + B).inverse();
00177 position = covariance * (A * position + B * positionB);
00178 updateOrientation(orientationB, infB / (infA + infB));
00179
00180 setPosition(position);
00181 setCovariance(covariance);
00182 addSupport(support);
00183 }
00184
00185 void Object::update(const tf::Pose& poseB, const Eigen::Matrix3f& covarianceB, float support) {
00186 Eigen::Vector3f positionB(poseB.getOrigin().x(), poseB.getOrigin().y(), poseB.getOrigin().z());
00187 tf::Quaternion orientationB = poseB.getRotation();
00188
00189
00190 Eigen::Matrix3f A(covariance.inverse());
00191 Eigen::Matrix3f B(covarianceB.inverse());
00192 double infA = 1./covariance.trace();
00193 double infB = 1./covarianceB.trace();
00194
00195 covariance = (A + B).inverse();
00196 position = covariance * (A * position + B * positionB);
00197 updateOrientation(orientationB, infB / (infA + infB));
00198
00199 setPosition(position);
00200 setCovariance(covariance);
00201 addSupport(support);
00202 }
00203
00204 void Object::updateOrientation(const tf::Quaternion& orientationB, double slerp_factor) {
00205
00206 if (parameter(_with_orientation, getClassId())) {
00207 tf::Quaternion q(orientation.x(), orientation.y(), orientation.z(), orientation.w());
00208 q.slerp(orientationB, slerp_factor);
00209 setOrientation(q);
00210 }
00211
00212 else {
00213 setOrientation(orientationB);
00214 }
00215 }
00216
00217 void Object::getVisualization(visualization_msgs::MarkerArray &markers) const {
00218 visualization_msgs::Marker marker;
00219 std::string postfix;
00220
00221
00222 marker.color = parameter(_marker_color, this->info.class_id);
00223
00224 switch(this->state.state) {
00225 case hector_worldmodel_msgs::ObjectState::CONFIRMED:
00226 marker.color.r = 0.0;
00227 marker.color.g = 0.8;
00228 marker.color.b = 0.0;
00229 postfix = " (CONFIRMED)";
00230 break;
00231 case hector_worldmodel_msgs::ObjectState::DISCARDED:
00232 marker.color.a = 0.5;
00233 postfix = " (DISCARDED)";
00234 break;
00235 case hector_worldmodel_msgs::ObjectState::INACTIVE:
00236 marker.color.a = 0.5;
00237 postfix = " (INACTIVE)";
00238 break;
00239 case hector_worldmodel_msgs::ObjectState::UNKNOWN:
00240 marker.color.a = 0.5;
00241 break;
00242 case hector_worldmodel_msgs::ObjectState::PENDING:
00243 marker.color.a = 0.5;
00244 postfix = " (PENDING)";
00245 break;
00246 default:
00247 break;
00248 }
00249
00250 marker.header = this->header;
00251 marker.action = visualization_msgs::Marker::ADD;
00252 getPose(marker.pose);
00253 marker.ns = this->info.class_id;
00254
00255 marker.type = visualization_msgs::Marker::ARROW;
00256 marker.scale.x = 1.0;
00257 marker.scale.y = 1.0;
00258 marker.scale.z = 1.0;
00259
00260
00261 marker.type = visualization_msgs::Marker::SPHERE;
00262 marker.scale.x = 0.1;
00263 marker.scale.y = 0.1;
00264 marker.scale.z = 0.1;
00265 markers.markers.push_back(marker);
00266
00267 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00268 marker.text = (!this->info.name.empty() ? this->info.name : this->info.object_id) + postfix;
00269 marker.scale.x = 0.0;
00270 marker.scale.y = 0.0;
00271 marker.scale.z = 0.1;
00272 marker.pose.position.z += 1.5 * marker.scale.z;
00273 markers.markers.push_back(marker);
00274 }
00275
00276 void Object::setNamespace(const std::string &ns) {
00277 object_namespace = ns;
00278 }
00279
00280 Object& Object::operator =(const hector_worldmodel_msgs::Object& other) {
00281 header = other.header;
00282 info = other.info;
00283 state = other.state;
00284 setPose(other.pose);
00285 return *this;
00286 }
00287
00288 ObjectPtr Object::transform(tf::Transformer& tf, const std::string& target_frame) const
00289 {
00290 return transform(tf, target_frame, this->header.stamp);
00291 }
00292
00293 ObjectPtr Object::transform(tf::Transformer& tf, const std::string& target_frame, const ros::Time& target_time) const
00294 {
00295 tf::StampedTransform transform;
00296 tf.lookupTransform(target_frame, this->header.frame_id, target_time, transform);
00297
00298 ObjectPtr result(new Object(*this));
00299
00300 tf::Pose pose;
00301 this->getPose(pose);
00302
00303
00304 pose = transform * pose;
00305 result->setPose(pose);
00306
00307
00308 tf::Matrix3x3 rotation(transform.getBasis());
00309 tf::Matrix3x3 cov(covariance(0,0), covariance(0,1), covariance(0,2),
00310 covariance(1,0), covariance(1,1), covariance(1,2),
00311 covariance(2,0), covariance(2,1), covariance(2,2));
00312 result->setCovariance(rotation * cov * rotation.transpose());
00313
00314
00315 result->header.frame_id = target_frame;
00316
00317 return result;
00318 }
00319
00320 double Object::getDistance(const Object &other)
00321 {
00322 return (this->getPosition() - other.getPosition()).norm();
00323 }
00324
00325 }