Go to the documentation of this file.00001 #include <stdexcept>
00002 #include <string>
00003
00004 #include <boost/format.hpp>
00005 #include <boost/make_shared.hpp>
00006
00007 #include <LinearMath/btQuaternion.h>
00008
00009 #include <ros/ros.h>
00010 #include <geometry_msgs/TransformStamped.h>
00011
00012 #include <evart-client.h>
00013
00014 #include "tracker.hh"
00015
00016 namespace evart
00017 {
00018 static uint32_t
00019 getBodyIdFromName(const std::string& name)
00020 {
00021 const evas_body_list_t* bodyList = evas_body_list();
00022 if(!bodyList)
00023 throw std::runtime_error("failed to retrieve body list");
00024
00025 for(uint32_t i = 0; i < bodyList->nbodies; ++i)
00026 if(name == bodyList->bodies[i])
00027 return i;
00028
00029 boost::format fmt("failed to retrieve the body id associated to '%1%'");
00030 fmt % name;
00031 throw std::runtime_error(fmt.str());
00032 }
00033
00034 static uint32_t
00035 getSegmentIdFromName(uint32_t bodyId, const std::string& name)
00036 {
00037 const evas_body_segments_list_t* segmentList =
00038 evas_body_segments_list(bodyId);
00039 if(!segmentList)
00040 throw std::runtime_error("failed to retrieve segment list");
00041
00042 for(uint32_t i = 0; i < segmentList->nsegments; ++i)
00043 if (name == segmentList->hier[i].name)
00044 return i;
00045
00046 boost::format fmt
00047 ("failed to retrieve the segment id associated to '%1%' of body id '%2%'");
00048 fmt % name % bodyId;
00049 throw std::runtime_error(fmt.str());
00050 }
00051
00052
00053 Tracker::Tracker(ros::NodeHandle& nh,
00054 const std::string& objectName,
00055 const std::string& segmentName,
00056 const std::string& topicName,
00057 const std::string& referenceFrameName,
00058 const std::string& childFrameName,
00059 boost::optional<tf::TransformBroadcaster&>
00060 transformBroadcaster)
00061 : publisher_(),
00062 seq_(0),
00063 objectName_(objectName),
00064 segmentName_(segmentName),
00065 referenceFrameName_(referenceFrameName),
00066 childFrameName_(childFrameName),
00067 bodyId_(getBodyIdFromName(objectName)),
00068 segmentId_(getSegmentIdFromName (bodyId_, segmentName)),
00069 transformBroadcaster_ (transformBroadcaster)
00070 {
00071 publisher_ =
00072 nh.advertise<geometry_msgs::TransformStamped>(topicName, queueSize);
00073
00074 evas_body_segments(bodyId_, EVAS_ON);
00075 ROS_DEBUG_STREAM
00076 ("starting tracker for " << objectName_ << ":" << segmentName_);
00077 }
00078
00079 Tracker::~Tracker()
00080 {
00081 ROS_DEBUG_STREAM
00082 ("stopping tracker for " << objectName_ << ":" << segmentName_);
00083 evas_body_segments(bodyId_, EVAS_OFF);
00084 }
00085
00086 void
00087 Tracker::callback(const evas_body_segments_t& msg)
00088 {
00089 if (msg.segments[segmentId_].pos[0] == EVAS_EMPTY)
00090 {
00091 ROS_INFO_STREAM_THROTTLE
00092 (5, "no data for " << objectName_ << ":" << segmentName_);
00093 return;
00094 }
00095 if (msg.nsegments <= segmentId_)
00096 throw std::runtime_error("invalid segment id");
00097
00098 boost::shared_ptr<geometry_msgs::TransformStamped> t
00099 (new geometry_msgs::TransformStamped());
00100
00101 t->header.seq = seq_++;
00102 t->header.stamp.sec = msg.tv_sec;
00103 t->header.stamp.nsec = msg.tv_usec * 1000.;
00104 t->header.frame_id = referenceFrameName_;
00105
00106 t->child_frame_id = childFrameName_;
00107
00108
00109 t->transform.translation.x = msg.segments[segmentId_].pos[0] / 1000.;
00110 t->transform.translation.y = msg.segments[segmentId_].pos[1] / 1000.;
00111 t->transform.translation.z = msg.segments[segmentId_].pos[2] / 1000.;
00112
00113
00114
00115
00116
00117
00118 tf::Quaternion q;
00119 q.setRPY(msg.segments[segmentId_].rot[0] * M_PI / 180.,
00120 msg.segments[segmentId_].rot[1] * M_PI / 180.,
00121 msg.segments[segmentId_].rot[2] * M_PI / 180.);
00122 t->transform.rotation.x = q.x();
00123 t->transform.rotation.y = q.y();
00124 t->transform.rotation.z = q.z();
00125 t->transform.rotation.w = q.w();
00126
00127
00128 if (transformBroadcaster_)
00129 {
00130 tf::Transform transform;
00131 transform.setOrigin
00132 (tf::Vector3(t->transform.translation.x,
00133 t->transform.translation.y,
00134 t->transform.translation.z));
00135 transform.setRotation
00136 (tf::Quaternion
00137 (t->transform.rotation.x,
00138 t->transform.rotation.y,
00139 t->transform.rotation.z,
00140 t->transform.rotation.w));
00141 transformBroadcaster_->sendTransform
00142 (tf::StampedTransform
00143 (transform,
00144 t->header.stamp,
00145 t->header.frame_id,
00146 childFrameName_));
00147 }
00148
00149 publisher_.publish (t);
00150 }
00151
00152 }