ObjectTFBroadcaster.cpp
Go to the documentation of this file.
00001 #include <object_msgs_tools/ObjectTFBroadcaster.h>
00002 #include <object_msgs_tools/ObjectFunctions.h>
00003 #include <object_msgs/ObjectInfo.h>
00004 
00005 using object_msgs_tools::ObjectTFBroadcaster;
00006 
00007 ObjectTFBroadcaster::ObjectTFBroadcaster(
00008     ros::NodeHandle& n,
00009     const std::string& register_object_service,
00010     unsigned int publish_tf_rate,
00011     unsigned int query_object_info_rate,
00012     const std::string& object_topic,
00013     const std::string& object_service): 
00014     node(n)
00015 {
00016     if (object_service.empty() && object_topic.empty())
00017     {
00018         ROS_ERROR("Can't use ObjetTFBroadcaster if neither service nor object info topic is set");
00019         throw std::runtime_error("Can't use ObjetTFBroadcaster if neither service nor object info topic is set");
00020     }
00021     
00022     ros::Rate rate(publish_tf_rate);
00023     publish_tf_timer = node.createTimer(rate, &ObjectTFBroadcaster::publishTFEvent, this);
00024     if (!register_object_service.empty())
00025     {
00026         ROS_INFO_STREAM("Advertising service "<<register_object_service);
00027         register_object_srv = node.advertiseService(register_object_service, &ObjectTFBroadcaster::registerObjectService,this);
00028     }
00029     
00030     if (!object_service.empty())
00031     {
00032         ros::Rate qRate(query_object_info_rate);
00033         query_object_info_timer=node.createTimer(qRate,&ObjectTFBroadcaster::queryObjectPoseEvent, this);
00034         query_object_info_timer.start();
00035         object_info_srv = node.serviceClient<object_msgs::ObjectInfo>(object_service);
00036     }
00037     if (!object_topic.empty())
00038         object_info_sub = node.subscribe(object_topic,1000,&ObjectTFBroadcaster::objectCallback, this);
00039 }
00040 
00041 bool ObjectTFBroadcaster::isRegistered(const std::string& name) const
00042 {
00043     obj_poses_mutex.lock();
00044     bool exists= obj_poses.find(name) != obj_poses.end();
00045     obj_poses_mutex.unlock();
00046     return exists;
00047 }
00048 
00049 bool ObjectTFBroadcaster::registerObjectService(object_msgs::RegisterObject::Request &req,
00050                                                 object_msgs::RegisterObject::Response &res)
00051 {
00052     ROS_INFO_STREAM("Calling ObjectTFBroadcaster service with "<<req.name);
00053     res.success = registerObject(req.name, true);
00054     // always return success because none of the errors
00055     // are fatal, the object will probably still be updated
00056     // even if the information was not available at the time.
00057     // It was still added (or already exists).
00058     return true;
00059 }
00060 
00061 
00062 int ObjectTFBroadcaster::registerObject(const std::string& name, bool printMsgs)
00063 {
00064     object_msgs::Object obj;
00065     // Get initial information of the object.
00066     // If this fails it doesn't matter, the first pose inserted will be invalid
00067     queryObjectPose(name,obj, false);
00068     geometry_msgs::PoseStamped pose;
00069     if (!ObjectFunctions::getObjectPose(obj, pose)){
00070         if (printMsgs) ROS_WARN_STREAM("ObjectTFBroadcaster: Could not get pose for object '"<<name<<"'");
00071         return object_msgs::RegisterObject::Response::ERROR_INFO;
00072     }
00073 
00074     obj_poses_mutex.lock();
00075     bool success = obj_poses.insert(std::make_pair(name,pose)).second;
00076     obj_poses_mutex.unlock();
00077     if (!success)
00078     {
00079         if (printMsgs)
00080             ROS_WARN_STREAM("Object " << name << 
00081                 " could not be added in ObjectTFBroadcaster because it was already registered.");
00082         return object_msgs::RegisterObject::Response::EXISTS;
00083     }
00084     return object_msgs::RegisterObject::Response::SUCCESS;
00085 }
00086 
00087  
00088 bool ObjectTFBroadcaster::queryObjectPose(const std::string& name, object_msgs::Object& obj, bool printErrors)
00089 {
00090     if (object_info_srv.getService().empty())
00091     {
00092         if (printErrors) ROS_ERROR("ObjectTFBroadcaster: Service to request object_msgs/Object is not running.");
00093         return false;
00094     }
00095     object_msgs::ObjectInfo srv;
00096     srv.request.name = name;
00097     srv.request.get_geometry = false;
00098     if (object_info_srv.call(srv)){
00099         //ROS_INFO("Result:");
00100         //std::cout<<srv.response<<std::endl;
00101     }else{
00102         if (printErrors) ROS_ERROR("ObjectTFBroadcaster: Failed to call service to obtain object info");
00103         return false;
00104     }
00105     obj=srv.response.object;
00106     return true;
00107 }
00108 
00109 void ObjectTFBroadcaster::sendTF(const geometry_msgs::PoseStamped& pose, const std::string& frame_name){
00110     tf::Transform transform;
00111     transform.setOrigin( tf::Vector3(pose.pose.position.x, pose.pose.position.y, pose.pose.position.z) );
00112     tf::Quaternion q(pose.pose.orientation.x,pose.pose.orientation.y,pose.pose.orientation.z,pose.pose.orientation.w);
00113     transform.setRotation(q);
00114     // ROS_INFO_STREAM("Send tf in "<<frame_name<<". "); //<<std::endl<<pose);
00115     tf_broadcaster.sendTransform(tf::StampedTransform(transform, pose.header.stamp, pose.header.frame_id, frame_name));
00116     // ROS_INFO("TF sent.");
00117 }
00118 
00119 
00120 bool ObjectTFBroadcaster::updateObject(const object_msgs::Object& obj)
00121 {
00122     // ROS_INFO_STREAM("ObjectTFBroadcaster: Got object "<<obj);
00123     geometry_msgs::PoseStamped pose;
00124     if (!ObjectFunctions::getObjectPose(obj, pose)){
00125         ROS_ERROR("ObjectTFBroadcaster: Could not get pose");
00126         return false;
00127     }
00128     std::map<std::string, geometry_msgs::PoseStamped>::iterator it;
00129     obj_poses_mutex.lock();
00130     it = obj_poses.find(obj.name);
00131     bool success = (it != obj_poses.end());
00132     if (success) it->second=pose;
00133     obj_poses_mutex.unlock();
00134     if (!success)
00135     {
00136         ROS_ERROR_STREAM("ObjectTFBroadcaster: Could not update object "
00137             <<obj.name<<" because it was not registered. Call registerObject() to add it.");
00138     }
00139     return success;
00140 }
00141 
00142 void ObjectTFBroadcaster::objectCallback(const object_msgs::Object& obj){
00143     updateObject(obj);
00144 }
00145 
00146 void ObjectTFBroadcaster::publishTFEvent(const ros::TimerEvent& e){
00147     // ROS_INFO("TF");
00148     obj_poses_mutex.lock();
00149     std::map<std::string, geometry_msgs::PoseStamped>::iterator it;
00150     for (it = obj_poses.begin(); it!=obj_poses.end(); ++it)
00151     {
00152         it->second.header.stamp=ros::Time::now();
00153         // ROS_INFO_STREAM("Sending TF for "<<it->first);//<<": "<<it->second);
00154         sendTF(it->second,it->first);    
00155     }
00156     obj_poses_mutex.unlock();
00157 }
00158 
00159 void ObjectTFBroadcaster::queryObjectPoseEvent(const ros::TimerEvent& e)
00160 {
00161     // ROS_INFO("Query");
00162     obj_poses_mutex.lock();
00163     std::map<std::string, geometry_msgs::PoseStamped>::iterator it;
00164     for (it = obj_poses.begin(); it!=obj_poses.end(); ++it)
00165     {
00166         object_msgs::Object obj;
00167         if (!queryObjectPose(it->first,obj,true)) continue;
00168         updateObject(obj);
00169     }
00170     obj_poses_mutex.unlock();
00171 }


object_msgs_tools
Author(s): Jennifer Buehler
autogenerated on Mon Feb 25 2019 03:45:29