iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test-Derived-Module.C
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 // Test for proper access via chained SFINAE in derived components and derived modules
36 
38 #include <nrt/Core/Model/Manager.H>
39 #include <nrt/Core/Typing/Macros.H> // for NRT_MACRO_WHERE
40 #include <nrt/Core/Geometry/Dims.H>
41 #include <iostream>
42 
43 class MessageA : public nrt::MessageBase
44 {
45  public:
46  int value;
47  template<class Archive> inline void serialize(Archive& ar) { ar(value); }
48 };
49 
50 class MessageB : public nrt::MessageBase
51 {
52  public:
53  bool flag;
54  template<class Archive> inline void serialize(Archive& ar) { ar(flag); }
55 };
56 
57 NRT_DECLARE_MESSAGEPOSTER_PORT(OutputA, MessageA, void, "MessageA Output");
58 NRT_DECLARE_MESSAGEPOSTER_PORT(OutputAB, MessageA, MessageB, "MessageA Output with MessageB return");
59 NRT_DECLARE_MESSAGECHECKER_PORT(AsyncInputA, MessageA, "MessageA Async Input");
60 NRT_DECLARE_MESSAGECHECKER_PORT(AsyncInputAder, MessageA, "MessageA Async Input for Derived checker");
61 NRT_DECLARE_MESSAGESUBSCRIBER_PORT(InputA, MessageA, void, "MessageA Input");
62 NRT_DECLARE_MESSAGESUBSCRIBER_PORT(InputAB, MessageA, MessageB, "MessageA Input with MessageB return");
63 
64 NRT_DECLARE_PARAMETER(number, int, "Integer number", 0);
65 NRT_DECLARE_PARAMETER(dims, nrt::Dims<int>, "Dimensions to use", nrt::Dims<int>());
66 
67 // ######################################################################
68 // Base class module, source
69 class BaseSource : public nrt::Module,
70  public nrt::MessagePoster<OutputA>,
71  public nrt::Parameter<dims>
72 {
73  public:
74  using nrt::Module::Module;
75  virtual ~BaseSource() { }
76 
77  void postit()
78  {
79  std::unique_ptr<MessageA> m(new MessageA);
80  m->value = 42;
81  NRT_INFO("Posting MessageA(" << m->value << ") to OutputA");
82  OutputA::post(m); // this blocks until all callbacks are complete
83  }
84 };
85 
86 // ######################################################################
87 // Base class module, checker
88 class BaseCheck : public nrt::Module,
89  public nrt::MessageChecker<AsyncInputA>,
90  public nrt::Parameter<dims>
91 {
92  public:
93  using nrt::Module::Module;
94  virtual ~BaseCheck() { }
95 
96  void checkit(nrt::MessageCheckerPolicy const mcp)
97  {
98  NRT_INFO("Testing check() functionality");
99 
100  if (auto res = AsyncInputA::check(mcp))
101  while(res.exhausted() == false)
102  try
103  {
104  auto msg = res.get();
105  if (msg) NRT_INFO("Got a result from check()! value is:" << msg->value);
106  }
107  catch (...) { nrt::warnAndRethrowException(); }
108  else NRT_INFO("No MessageA on the Blackboard");
109  }
110 };
111 
112 // ######################################################################
113 // Base class module, subscriber:
114 class BaseSink : public nrt::Module,
115  public nrt::MessageSubscriber<InputA>,
116  public nrt::Parameter<dims>
117 {
118  public:
119  using nrt::Module::Module;
120  virtual ~BaseSink() { }
121 
122  virtual void onMessage(InputA::InPtr msg)
123  { NRT_INFO("BaseSink received MessageA(" << msg->value << ") on InputA"); }
124 };
125 
126 // ######################################################################
127 // Derived source
128 class DerSource : public BaseSource,
129  public nrt::MessagePoster<OutputAB>,
130  public nrt::Parameter<number>
131 {
132  public:
133  using BaseSource::BaseSource;
134  virtual ~DerSource() { }
135 
136  void postit()
137  {
138  // try to access derived class parameter:
139  NRT_INFO("number = " << number::get());
140 
141  // try to access base class parameter:
142  NRT_INFO("dims = " << dims::get());
143 
144  // post on base port:
145  std::unique_ptr<MessageA> mb(new MessageA);
146  mb->value = 47;
147  NRT_INFO("Posting MessageA(" << mb->value << ") to base OutputA");
148  OutputA::post(mb); // this blocks until all callbacks are complete
149 
150  // post on derived poster port:
151  std::unique_ptr<MessageA> md(new MessageA);
152  md->value = 28;
153  NRT_INFO("Posting MessageA(" << md->value << ") to derived OutputAB");
154  if (auto result = OutputAB::post(md))
155  while (result.empty() == false)
156  NRT_INFO("Got result: " << result.get()->flag << " from post on outputAB");
157  }
158 };
159 
160 // ######################################################################
161 // Derived class module, checker
162 class DerCheck : public BaseCheck,
163  public nrt::MessageChecker<AsyncInputAder>,
164  public nrt::Parameter<number>
165 {
166  public:
167  using BaseCheck::BaseCheck;
168  virtual ~DerCheck() { }
169 
170  void checkit(nrt::MessageCheckerPolicy const mcp)
171  {
172  NRT_INFO("Testing derived class check() functionality on base checker");
173 
174  if (auto res = AsyncInputA::check(mcp))
175  while(res.exhausted() == false)
176  try
177  {
178  auto msg = res.get();
179  if (msg) NRT_INFO("Got a result from check()! value is:" << msg->value);
180  }
181  catch (...) { nrt::warnAndRethrowException(); }
182  else NRT_INFO("No MessageA on the Blackboard");
183 
184  NRT_INFO("Testing derived class check() functionality on derived checker");
185 
186  if (auto res = AsyncInputAder::check(mcp))
187  while(res.exhausted() == false)
188  try
189  {
190  auto msg = res.get();
191  if (msg) NRT_INFO("Got a result from check()! value is:" << msg->value);
192  }
193  catch (...) { nrt::warnAndRethrowException(); }
194  else NRT_INFO("No MessageA on the Blackboard");
195  }
196 };
197 
198 // ######################################################################
199 // Derived lass module, subscriber:
200 class DerSink : public BaseSink,
201  public nrt::MessageSubscriber<InputAB>,
202  public nrt::Parameter<number>
203 {
204  public:
205  using BaseSink::BaseSink;
206  virtual ~DerSink() { }
207 
208  virtual void onMessage(InputA::InPtr msg)
209  { NRT_INFO("DerSink received MessageA(" << msg->value << ") on InputA"); }
210 
211  virtual InputAB::OutPtr onMessage(InputAB::InPtr msg)
212  {
213  NRT_INFO("DerSink received MessageA(" << msg->value << ") on InputAB");
214  std::unique_ptr<MessageB> ret(new MessageB);
215  ret->flag = true;
216  return ret;
217  }
218 };
219 
220 // ######################################################################
221 // ######################################################################
222 // ######################################################################
223 //! Test main function demonstrating use of Blackboard
224 int main(int argc, char const* argv[])
225 {
226  try
227  {
228  // Get a handle onto our Blackboard:
230 
231  // Set some default args, in particular, we are master by default:
232  bb.setParamVal("master", true);
233 
234  // Get command-line args:
235  bb.setCommandLineArgs(argc, argv);
236 
237  // instantiate modules:
238  auto bp = bb.addModule<BaseSource>("bp");
239  auto bc = bb.addModule<BaseCheck>("bc");
240  auto bs = bb.addModule<BaseSink>("bs");
241 
242  auto dp = bb.addModule<DerSource>("dp");
243  auto dc = bb.addModule<DerCheck>("dc");
244  auto ds = bb.addModule<DerSink>("ds");
245 
246  // set topics:
247  bp->OutputA::setTopic("cool");
248  bc->AsyncInputA::setTopicFilter("cool");
249  bs->InputA::setTopicFilter("cool");
250 
251  dp->OutputA::setTopic("dcool");
252  dp->OutputAB::setTopic("dcoolx");
253  dc->AsyncInputA::setTopicFilter("dcool");
254  dc->AsyncInputAder::setTopicFilter("dcoolx");
255  ds->InputA::setTopicFilter("dcool");
256  ds->InputAB::setTopicFilter("dcool");
257 
258  // get started:
259  bb.launch();
260 
261  nrt::Blackboard::instance().printInfo(std::cout);
262 
263  // post a Message:
264  bp->postit();
265 
266  // make sure all callbacks are completed to avoid clashing in printing messages
267  usleep(300000);
268 
269  // Blackboard should have this Message:
270  nrt::Blackboard::instance().printMessages(std::cout);
271 
272  // check for it, first Any (should find it), then Unseen (should not):
275 
276  // Final blackboard state:
277  nrt::Blackboard::instance().printMessages(std::cout);
278 
279  // more checks using the derived classes:
280  dp->postit();
283 
284  // done
285  bb.stop();
286 
287  NRT_INFO("Execution successful.");
288  }
289  catch (...) { nrt::warnAndRethrowException(); }
290 
291  return 0;
292 }