ed
plugin_container.cpp
Go to the documentation of this file.
1 #include "ed/plugin_container.h"
2 
3 #include <ed/error_context.h>
4 #include "ed/init_data.h"
5 #include "ed/plugin.h"
6 
7 #include <pluginlib/class_loader.h>
8 
9 #include <ros/rate.h>
10 
11 namespace ed
12 {
13 
14 // --------------------------------------------------------------------------------
15 
17  : class_loader_(nullptr), request_stop_(false), is_running_(false), cycle_duration_(0.1), loop_frequency_(10),
18  loop_frequency_max_(11), loop_frequency_min_(9), step_finished_(true), t_last_update_(0), tf_buffer_(tf_buffer),
19  loop_usage_status_(nullptr)
20 {
21 }
22 
23 // --------------------------------------------------------------------------------
24 
26 {
27  requestStop();
28 
29  if (thread_)
30  thread_->join();
31 
32  plugin_.reset();
33  if (class_loader_)
34  delete class_loader_;
35 }
36 
37 // --------------------------------------------------------------------------------
38 
39 PluginPtr PluginContainer::loadPlugin(const std::string& plugin_name, const std::string& plugin_type, InitData& init)
40 {
41  // Load the library
42  if (class_loader_)
43  delete class_loader_;
44  class_loader_ = new pluginlib::ClassLoader<ed::Plugin>("ed", "ed::Plugin");
45 
46  // Create plugin
47  if (!class_loader_->isClassAvailable(plugin_type))
48  init.config.addError("Could not find plugin with the type '" + plugin_type + "'.");
49  else
50  {
51  plugin_ = class_loader_->createInstance(plugin_type);
52  if (plugin_)
53  {
54  name_ = plugin_name;
55  plugin_->name_ = plugin_name;
56  plugin_->tf_buffer_ = tf_buffer_;
57 
58  configure(init, false);
59 
60  // If there was an error during configuration, do not start plugin
61  if (init.config.hasError())
62  return nullptr;
63 
64  // Initialize the plugin
65  plugin_->initialize();
66 
67  return plugin_;
68  }
69  }
70 
71  return nullptr;
72 }
73 
74 // --------------------------------------------------------------------------------
75 
76 void PluginContainer::configure(InitData& init, bool reconfigure)
77 {
78  // Read optional frequency
79  double freq = 10; // default
80  init.config.value("frequency", freq, tue::config::OPTIONAL);
81 
82  // Set plugin loop frequency
83  setLoopFrequency(freq);
84 
85  // Setup LoopUsageStatus
86  diagnostic_updater::FrequencyStatusParam params(&loop_frequency_min_, &loop_frequency_max_);
87  params.window_size_ = 20; // Stats are published at 2 Hz, so this window is 10 seconds
88  loop_usage_status_ = std::make_unique<ed::LoopUsageStatus>(params, plugin_->name());
89 
90  if (init.config.readGroup("parameters"))
91  {
92  tue::Configuration scoped_config = init.config.limitScope();
93  InitData scoped_init(init.properties, scoped_config);
94 
95  plugin_->configure(scoped_config); // This call will become obsolete (TODO)
96  plugin_->initialize(scoped_init);
97 
98  // Read optional frequency (inside parameters is obsolete)
99  double freq_temp;
100  if (init.config.value("frequency", freq_temp, tue::config::OPTIONAL))
101  init.config.addError("Specify parameter 'frequency' outside 'parameters'.");
102 
103  init.config.endGroup();
104  }
105  else if (!reconfigure)
106  {
107  // No parameter available
108  tue::Configuration scoped_config;
109  InitData scoped_init(init.properties, scoped_config);
110 
111  plugin_->configure(scoped_config); // This call will become obsolete (TODO)
112  plugin_->initialize(scoped_init);
113 
114  if (scoped_config.hasError())
115  init.config.addError(scoped_config.error());
116  }
117 }
118 
119 // --------------------------------------------------------------------------------
120 
122 {
123  thread_ = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&PluginContainer::run, this)));
124  pthread_setname_np(thread_->native_handle(), name_.c_str());
125 }
126 
127 // --------------------------------------------------------------------------------
128 
130 {
131  is_running_ = true;
132  request_stop_ = false;
133 
134  double innerloop_frequency = 1000; // TODO: magic number!
135 
136  ros::Rate r(loop_frequency_);
137  ros::Rate ir(innerloop_frequency);
138  while(!request_stop_)
139  {
140  if (!step())
141  // If not stepped, sleep short
142  ir.sleep();
143  else
144  // stepped, sleep normal
145  r.sleep();
146  }
147 
148  is_running_ = false;
149 }
150 
151 // --------------------------------------------------------------------------------
152 
154 {
155  // If we still have an update_request, it means the request is not yet handled,
156  // so we have to skip this cycle (and wait until the world model has handled it)
157  {
158  boost::lock_guard<boost::mutex> lg(mutex_update_request_);
159  if (update_request_)
160  return false;
161  }
162 
164 
165  // Check if there is a new world. If so replace the current one with the new one
166  {
167  boost::lock_guard<boost::mutex> lg(mutex_world_);
168  if (world_new_)
169  {
171  world_deltas = world_deltas_;
172 
174  world_new_.reset();
175  }
176  }
177 
178  if (world_current_)
179  {
180  PluginInput data(*world_current_, world_deltas);
181 
182  UpdateRequestPtr update_request(new UpdateRequest);
183 
184  loop_usage_status_->start();
185  {
186  ed::ErrorContext errc("Plugin:", name().c_str());
187 
188  // Old
189  plugin_->process(*world_current_, *update_request);
190 
191  // New
192  plugin_->process(data, *update_request);
193  }
194  loop_usage_status_->stop();
195 
196  // If the received update_request was not empty, set it
197  if (!update_request->empty())
198  update_request_ = update_request;
199  }
200  return true;
201 }
202 
203 // --------------------------------------------------------------------------------
204 
206 {
207  request_stop_ = true;
208 }
209 
210 // --------------------------------------------------------------------------------
211 
212 }
213 
214 
ed::PluginContainer::requestStop
void requestStop()
Definition: plugin_container.cpp:205
ed::UpdateRequest
Definition: update_request.h:24
std::string
ed::TFBufferConstPtr
shared_ptr< const tf2_ros::Buffer > TFBufferConstPtr
Definition: types.h:84
ed::PluginContainer::loop_usage_status_
std::unique_ptr< ed::LoopUsageStatus > loop_usage_status_
Definition: plugin_container.h:116
ed::PluginContainer::name_
std::string name_
Definition: plugin_container.h:84
ed::PluginContainer::name
const std::string & name() const
Definition: plugin_container.h:44
std::vector< UpdateRequestConstPtr >
ed::PluginContainer::mutex_update_request_
boost::mutex mutex_update_request_
Definition: plugin_container.h:98
plugin.h
ed::PluginContainer::world_new_
WorldModelConstPtr world_new_
Definition: plugin_container.h:110
ed::InitData
Definition: init_data.h:12
ed::PluginContainer::step
bool step()
Definition: plugin_container.cpp:153
ed::InitData::config
tue::Configuration & config
Definition: init_data.h:18
ed::ErrorContext
Definition: error_context.h:14
std::vector::clear
T clear(T... args)
ed::PluginContainer::configure
void configure(InitData &init, bool reconfigure)
Definition: plugin_container.cpp:76
ed::PluginContainer::loop_frequency_max_
double loop_frequency_max_
Definition: plugin_container.h:95
ed::PluginContainer::loadPlugin
PluginPtr loadPlugin(const std::string &plugin_name, const std::string &plugin_type, InitData &init)
Definition: plugin_container.cpp:39
ed::PluginContainer::tf_buffer_
TFBufferConstPtr tf_buffer_
Definition: plugin_container.h:114
tue::config::ReaderWriter
tue::config::ReaderWriter::error
const std::string & error() const
ed::PluginContainer::request_stop_
bool request_stop_
Definition: plugin_container.h:86
std::string::c_str
T c_str(T... args)
tue::config::ReaderWriter::endGroup
bool endGroup()
ed::PluginContainer::loop_frequency_min_
double loop_frequency_min_
Definition: plugin_container.h:96
ed::PluginInput
Definition: plugin.h:19
tue::config::OPTIONAL
OPTIONAL
init_data.h
pluginlib::ClassLoader< ed::Plugin >
ed::PluginContainer::plugin_
PluginPtr plugin_
Definition: plugin_container.h:82
ed::PluginContainer::class_loader_
pluginlib::ClassLoader< ed::Plugin > * class_loader_
Definition: plugin_container.h:80
ed::UpdateRequestPtr
shared_ptr< UpdateRequest > UpdateRequestPtr
Definition: types.h:47
ed::PluginContainer::world_current_
WorldModelConstPtr world_current_
Definition: plugin_container.h:112
ed::PluginContainer::loop_frequency_
double loop_frequency_
Definition: plugin_container.h:93
tue::config::ReaderWriter::addError
void addError(const std::string &msg)
tue::config::ReaderWriter::value
bool value(const std::string &name, T &value, RequiredOrOptional opt=REQUIRED)
plugin_container.h
ed::PluginContainer::thread_
ed::shared_ptr< boost::thread > thread_
Definition: plugin_container.h:102
ed::PluginContainer::~PluginContainer
virtual ~PluginContainer()
Definition: plugin_container.cpp:25
tue::config::ReaderWriter::limitScope
ReaderWriter limitScope() const
ed::PluginContainer::mutex_world_
boost::mutex mutex_world_
Definition: plugin_container.h:108
ed::PluginContainer::PluginContainer
PluginContainer(const ed::TFBufferConstPtr &tf_buffer_)
Definition: plugin_container.cpp:16
ed::PluginContainer::is_running_
bool is_running_
Definition: plugin_container.h:88
error_context.h
tue::config::ReaderWriter::readGroup
bool readGroup(const std::string &name, const RequiredOrOptional opt=OPTIONAL)
ed
Definition: convex_hull.h:8
ed::PluginContainer::setLoopFrequency
void setLoopFrequency(double freq)
Definition: plugin_container.h:64
ed::PluginContainer::update_request_
UpdateRequestPtr update_request_
Definition: plugin_container.h:100
ed::PluginContainer::runThreaded
void runThreaded()
Definition: plugin_container.cpp:121
ed::InitData::properties
ed::PropertyKeyDB & properties
Definition: init_data.h:17
ed::PluginPtr
shared_ptr< Plugin > PluginPtr
Definition: types.h:39
ed::PluginContainer::world_deltas_
std::vector< UpdateRequestConstPtr > world_deltas_
Definition: plugin_container.h:124
ed::PluginContainer::run
void run()
Definition: plugin_container.cpp:129
tue::config::ReaderWriter::hasError
bool hasError() const