Cafer_core
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
manager.hpp
Go to the documentation of this file.
1 //| This file is a part of the CAFER framework developped within
2 //| the DREAM project (http://www.robotsthatdream.eu/).
3 //| Copyright 2015, ISIR / Universite Pierre et Marie Curie (UPMC)
4 //| Main contributor(s):
5 //| * Stephane Doncieux, stephane.doncieux@isir.upmc.fr
6 //| * Léni Le Goff, le_goff@isir.upmc.fr
7 //|
8 //| This experiment allows to generate neural networks for simple
9 //| navigation tasks (obstacle avoidance and maze navigation).
10 //|
11 //| This software is governed by the CeCILL license under French law
12 //| and abiding by the rules of distribution of free software. You
13 //| can use, modify and/ or redistribute the software under the terms
14 //| of the CeCILL license as circulated by CEA, CNRS and INRIA at the
15 //| following URL "http://www.cecill.info".
16 //|
17 //| As a counterpart to the access to the source code and rights to
18 //| copy, modify and redistribute granted by the license, users are
19 //| provided only with a limited warranty and the software's author,
20 //| the holder of the economic rights, and the successive licensors
21 //| have only limited liability.
22 //|
23 //| In this respect, the user's attention is drawn to the risks
24 //| associated with loading, using, modifying and/or developing or
25 //| reproducing the software by the user in light of its specific
26 //| status of free software, that may mean that it is complicated to
27 //| manipulate, and that also therefore means that it is reserved for
28 //| developers and experienced professionals having in-depth computer
29 //| knowledge. Users are therefore encouraged to load and test the
30 //| software's suitability as regards their requirements in conditions
31 //| enabling the security of their systems and/or data to be ensured
32 //| and, more generally, to use and operate it in the same conditions
33 //| as regards security.
34 //|
35 //| The fact that you are presently reading this means that you have
36 //| had knowledge of the CeCILL license and that you accept its terms.
37 
38 #ifndef _MANAGER_HPP
39 #define _MANAGER_HPP
40 
41 #include <iostream>
42 #include <ctime>
43 #include <random>
44 #include <sstream>
45 #include <mutex>
46 #include <unordered_map>
47 #include <deque>
48 
49 #include <ros/ros.h>
50 #include <std_msgs/Time.h>
51 #include <std_msgs/Header.h>
52 
53 #include "cafer_core/component.hpp"
54 
55 namespace cafer_core {
56 
60  template<typename Msg, typename DataContainer, typename DerivedClass>
61  class ManagerBase {
62  public:
63 
67  enum io {
69  };
70 
77  ManagerBase(std::string type, std::string name, std::string description = "") :
78 
79  _type(type), _name(name), _description(description)
80  {
81  //init random number generator for random access
82  std::seed_seq seed = {std::time(0)};
83  _gen.seed(seed);
84 
85 // //init services
86 // std::stringstream sstream;
87 // sstream << _name << "_start_to_publish";
88 // _start_to_publish->reset(new ros::ServiceServer(ros_nh->advertiseService(sstream.str(),start_to_publish)));
89 
90 // std::stringstream sstream2;
91 // sstream2 << _name << "_search_service";
92 // _search_service->reset(new ros::ServiceServer(ros_nh->advertiseService(sstream2.str(),search_service)));
93 
94  }
95 
97  {
98  _subcriber.reset();
99 // _publisher.reset();
100 // _server.reset();
101  }
102 
104  {
105  return true;
106  }
107 
108  void update()
109  {
110 
111  }
112 
117  void add_cb(const shared_ptr<Msg>& msg)
118  {
119  static_cast<DerivedClass *>(this)->add(*msg);
120  }
121 
126  void listen_to(const std::string& topic, io type_io = ADD)
127  {
128  if (type_io == ADD) {
129  _subcriber.reset(new ros::Subscriber(ros_nh->subscribe(topic, 10, &ManagerBase::add_cb, this)));
130  }
131  }
132 
137  size_t data_size()
138  {
139  size_t _container_size;
140  _container_mutex.lock();
141  _container_size = _data_set.size();
142  _container_mutex.unlock();
143  return _container_size;
144  }
145 
146 // void search_service()
147 // /*
148 // * @brief AskTo Call a specific service
149 // * @param md
150 // */
151 // void ask_to(const std::string& name){
152 
153 // std::stringstream sstream;
154 // sstream << name << "_search_service";
155 // ros::ServiceClient client = ros_nh->serviceClient<>(sstream.str());
156 
157 
158 // while(!client.call(srv)){std::cout << "Wait for service " << service_name << std::endl;}
159 // //DO SOMETHING !!!!
160 // }
161 
162 // void start_to_publish(cafer_core::start_to_talk::Request& req,
163 // cafer_core::start_to_talk::Response& res){
164 
165 // if(!req.want_to_listen)
166 // return;
167 
168 // std::stringstream sstream;
169 // sstream << _name << "_talker";
170 // _publisher.reset(ros_nh->advertise(sstream.str(),talk_cb));
171 // res.start_to_talk = true;
172 // //do parallisation
173 // }
174  protected:
175 
176  DataContainer _data_set;
177 
178  long int _id;
179  std::string _name;
180  std::string _description;
181  std::string _type;
182 
183  std::unique_ptr<ros::Publisher> _publisher;
184 
185 
186  std::unique_ptr<ros::Subscriber> _subcriber;
187  std::mt19937 _gen;
188 
189  std::mutex _container_mutex;
190  // shared_ptr<ros::ServiceServer> _start_to_publish;
191  // shared_ptr<ros::ServiceServer> _search_service;
192  };
193 
194  //Declaring the Manager class, inheriting from ManagerBase.
195  template<typename Msg, typename DataContainer>
196  class Manager : public ManagerBase<Msg, DataContainer, Manager<Msg, DataContainer>> {
197  };
198 
199  //Partial template specialization of the Manager class using unordered_map as container.
200 
201  template<typename Msg>
202  class Manager<Msg, std::unordered_map<u_int32_t, Msg>>
203  : public ManagerBase<Msg, std::unordered_map<u_int32_t, Msg>, Manager<Msg, std::unordered_map<u_int32_t, Msg>>> {
204  //Defining Base as an alias for the template pattern.
206  //Inheriting base class constructor
207  using Base::Base;
208  public:
209 
214  void add(const Msg& msg)
215  {
216  Base::_container_mutex.lock();
217  Base::_data_set.emplace(msg.header.seq, msg);
218  Base::_container_mutex.unlock();
219  }
220 
225  Msg get()
226  {
227  std::uniform_int_distribution<> dist(0., Base::_data_set.size() - 1);
228  Base::_container_mutex.lock();
229  auto random_it = std::next(std::begin(Base::_data_set), dist(Base::_gen));
230  Base::_container_mutex.unlock();
231  Msg res = random_it->second;
232  return res;
233  }
234 
240  size_t remove(const u_int32_t& h)
241  {
242  size_t return_val;
243  Base::_container_mutex.lock();
244  return_val = Base::_data_set.erase(h);
245  Base::_container_mutex.unlock();
246  return return_val;
247  }
248 
253  Msg search(const u_int32_t& id)
254  {
255  Msg return_msg;
256  Base::_container_mutex.lock();
257  return_msg = Base::_data_set.find(id)->second;
258  Base::_container_mutex.unlock();
259  return return_msg;
260  }
261  };
262 
263  //Partial template specialization of the Manager class using deque as container.
264  template<typename Msg>
265  class Manager<Msg, std::deque<Msg>> : public ManagerBase<Msg, std::deque<Msg>, Manager<Msg, std::deque<Msg>>> {
266  //Defining Base as an alias for the template pattern.
268  //Inheriting base class constructor
269  using Base::Base;
270 
271  public:
272 
278  void add(const Msg& msg)
279  {
280  Base::_container_mutex.lock();
281  Base::_data_set.push_back(msg);
282  Base::_container_mutex.unlock();
283  }
284 
290  Msg get()
291  {
292  Msg msg;
293 
294  Base::_container_mutex.lock();
295  msg = Base::_data_set.front();
296  Base::_data_set.pop_front();
297  Base::_container_mutex.unlock();
298 
299  return msg;
300  }
301  };
302 
303  //Namespace aliases to simplify template usage.
307  template<typename Msg>
309 
313  template<typename Msg>
315 }
316 
317 #endif //_MANAGER_HPP
size_t data_size()
Returns the number of elements in the data container.
Definition: manager.hpp:137
std::unique_ptr< ros::Publisher > _publisher
Definition: manager.hpp:183
std::unique_ptr< ros::Subscriber > _subcriber
subscriber to retrieve data
Definition: manager.hpp:186
ros::Subscriber Subscriber
Definition: aliases.hpp:23
void add_cb(const shared_ptr< Msg > &msg)
The callback function used to process messages from the listened topic.
Definition: manager.hpp:117
void add(const Msg &msg)
add a msg to the container of Manager
Definition: manager.hpp:214
shared_ptr< ros::NodeHandle > ros_nh
std::string _description
Definition: manager.hpp:180
boost::shared_ptr< T > shared_ptr
Definition: aliases.hpp:15
std::mutex _container_mutex
Mutex to protect the _data_set from concurrent access.
Definition: manager.hpp:189
io
The io enum type of traitement to do with incoming data.
Definition: manager.hpp:67
Msg search(const u_int32_t &id)
search a precise msg by is identifier
Definition: manager.hpp:253
DataContainer _data_set
the data container. All messages are stored in this container.
Definition: manager.hpp:176
void add(const Msg &msg)
add a msg to the container of Manager. Add the new message in the back of the queue.
Definition: manager.hpp:278
Base class for manager component. A manager component handle ROS messages (like images, features or policies).
Definition: manager.hpp:61
void listen_to(const std::string &topic, io type_io=ADD)
Connects to a specific topic and listen to it.
Definition: manager.hpp:126
ManagerBase(std::string type, std::string name, std::string description="")
Manager constructor.
Definition: manager.hpp:77