annotation_collection.hpp
Go to the documentation of this file.
00001 /*
00002  * annotation_collection.hpp
00003  *
00004  *  Created on: May 7, 2014
00005  *      Author: jorge
00006  */
00007 
00008 #ifndef ANNOTATION_COLLECTION_HPP_
00009 #define ANNOTATION_COLLECTION_HPP_
00010 
00011 #include <unique_id/unique_id.h>
00012 
00013 #include <ros/serialization.h>
00014 #include <ros/serialized_message.h>
00015 
00016 #include <visualization_msgs/Marker.h>
00017 
00018 #include <world_canvas_msgs/Annotation.h>
00019 #include <world_canvas_msgs/AnnotationData.h>
00020 
00021 #include "world_canvas_client_cpp/filter_criteria.hpp"
00022 #include "world_canvas_client_cpp/world_canvas_client.hpp"
00023 
00024 namespace wcf
00025 {
00026 
00034 class AnnotationCollection : public WorldCanvasClient
00035 {
00036 protected:
00037   ros::NodeHandle nh;
00038   ros::Publisher marker_pub;
00039   ros::Publisher markers_pub;
00040 
00041   FilterCriteria filter;
00042 
00043   std::vector<world_canvas_msgs::Annotation>     annotations;
00044   std::vector<world_canvas_msgs::AnnotationData> annots_data;
00045 
00046   std::vector<world_canvas_msgs::Annotation> annots_to_delete;
00047   bool saved;
00048 
00049   bool saveDeletes();
00050 
00058   std::vector<UniqueIDmsg> getAnnotsDataIDs();
00059 
00060   inline bool endsWith(const std::string& a, const std::string& b)
00061   {
00062     if (a.size() < b.size())
00063       return false;
00064     return (a.substr(a.size() - b.size()) == b);
00065   }
00066 
00067 public:
00074   AnnotationCollection(const std::string& world, const std::string& srv_namespace = "");
00075 
00083   AnnotationCollection(const FilterCriteria& criteria, const std::string& srv_namespace = "");
00084 
00085   virtual ~AnnotationCollection();
00086 
00093   bool filterBy(const FilterCriteria& criteria);
00094 
00100   bool load();
00101 
00107   bool loadData();
00108 
00114   bool save();
00115 
00119   bool isSaved() { return saved; }
00120 
00128   bool add(const world_canvas_msgs::Annotation& annotation,
00129            const world_canvas_msgs::AnnotationData& annot_data);
00130 
00138   bool update(const world_canvas_msgs::Annotation& annotation,
00139               const world_canvas_msgs::AnnotationData& annot_data);
00140 
00147   bool remove(const uuid_msgs::UniqueID& id);
00148 
00155   bool clearMarkers(const std::string& topic);
00156 
00164   bool publishMarkers(const std::string& topic, bool clear_existing = true);
00165 
00175   bool publishMarker(const std::string& topic, int marker_id,
00176                      const world_canvas_msgs::Annotation& ann, bool clear_existing = true);
00177 
00185   visualization_msgs::Marker makeMarker(int id, const world_canvas_msgs::Annotation& ann);
00186 
00193   visualization_msgs::Marker makeLabel(const visualization_msgs::Marker& marker);
00194 
00209   bool publish(const std::string& topic_name, const std::string& topic_type = "",
00210                bool by_server = false, bool as_list = false);
00211 
00218   bool hasAnnotation(const UniqueIDmsg& id);
00219 
00226   const world_canvas_msgs::Annotation& getAnnotation(const UniqueIDmsg& id);
00227 
00235   std::vector<world_canvas_msgs::Annotation> getAnnotations(const std::string& name);
00236 
00242   std::vector<UniqueIDmsg> getAnnotationIDs();
00243 
00249   const std::vector<world_canvas_msgs::Annotation>& getAnnotations() { return annotations; }
00250 
00257   const world_canvas_msgs::AnnotationData& getData(const world_canvas_msgs::Annotation& ann);
00258 
00265   template <typename T>
00266   unsigned int getData(std::vector<T>& data)
00267   {
00268     unsigned int count = 0;
00269     std::string type = ros::message_traits::DataType<T>::value();
00270 
00271     for (unsigned int i = 0; i < annots_data.size(); ++i)
00272     {
00273       // Check id this data corresponds to an annotation of the requested type. TODO: but we should
00274       // a list of tuples containing anns + data, so we don't need to relay on data.type
00275       if (annots_data[i].type != type)
00276         continue;
00277 
00278       // Deserialize the ROS message contained on data field; we must clone the serialized data
00279       // because SerializedMessage requires a boost::shared_array as input that will try to destroy
00280       // the underlying array once out of scope. Also we must skip 4 bytes on message_start pointer
00281       // because the first 4 bytes on the buffer contains the (already known) serialized data size.
00282       T object;
00283       uint32_t serial_size = annots_data[i].data.size();
00284       boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
00285       memcpy(buffer.get(), &annots_data[i].data[0], serial_size);
00286       ros::SerializedMessage sm(buffer, serial_size);
00287       sm.type_info = &typeid(object);
00288       sm.message_start += 4;
00289       try
00290       {
00291         ROS_DEBUG("Deserializing object '%s' of type '%s'",
00292                   unique_id::toHexString(annots_data[i].id).c_str(), type.c_str());
00293         ros::serialization::deserializeMessage(sm, object);
00294         data.push_back(object);
00295         count++;
00296       }
00297       catch (ros::serialization::StreamOverrunException& e)
00298       {
00299         ROS_ERROR("Deserialization failed on object %d: %s", i, e.what());
00300       }
00301     }
00302     return count;
00303   }
00304 
00305 };
00306 
00307 } // namespace wcf
00308 
00309 #endif /* ANNOTATION_COLLECTION_HPP_ */


world_canvas_client_cpp
Author(s): Jorge Santos
autogenerated on Thu Jun 6 2019 18:32:38