JeVois  1.5
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Manager.H
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 // This code is inspired by the Neuromorphic Robotics Toolkit (http://nrtkit.org)
19 
20 #pragma once
21 
23 #include <jevois/Types/Enum.H>
24 
25 #include <vector>
26 
27 // BEGIN_JEVOIS_CODE_SNIPPET manager1.C
28 namespace jevois
29 {
30  namespace manager
31  {
32  //! Parameter category \relates jevois::Manager
33  static ParameterCategory const ParamCateg("General Options");
34 
35  //! Parameter \relates jevois::Manager
36  JEVOIS_DECLARE_PARAMETER(help, bool, "Print this help message", false, ParamCateg);
37 
38 #ifdef JEVOIS_LDEBUG_ENABLE
39  //! Enum for Parameter \relates jevois::Manager
40  JEVOIS_DEFINE_ENUM_CLASS(LogLevel, (fatal) (error) (info) (debug));
41 #else
42  //! Enum for Parameter \relates jevois::Manager
43  JEVOIS_DEFINE_ENUM_CLASS(LogLevel, (fatal) (error) (info));
44 #endif
45 
46  //! Parameter \relates jevois::Manager
47  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(loglevel, LogLevel, "Set the minimum log level to display",
48  LogLevel::info, LogLevel_Values, ParamCateg);
49 
50  //! Parameter \relates jevois::Manager
51  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(tracelevel, unsigned int, "Set the minimum trace level to display",
52  0, ParamCateg);
53 
54  //! Parameter \relates jevois::Manager
55  JEVOIS_DECLARE_PARAMETER(nickname, std::string, "Nickname associated with this camera, useful when multiple "
56  "JeVois cameras are connected to a same USB bus", "jevois", ParamCateg);
57  }
58 
59  // ######################################################################
60  //! Manager of a hierarchy of Component objects
61  /*! A Manager should be the top-level Component of any hierarchy of Components. It is primarily responsible for
62  handling the setting of Parameter values via the command-line or otherwise.
63 
64  Users should only need to construct a Manager (including Engine, which derives from Manager), add any Component to
65  it, and then call init() on the Manager, which will parse all command line options, bind them to the relevant
66  Parameters, and call init() on all subComponents (which in turn calls init() on all of their subComponents,
67  etc.). See the documentation of Component for more information about the init() flow.
68 
69  The parameter \p nickname is not internally used by the Manager. It can be set, for example, in \b initscript.cfg
70  to a different value for each camera, in systems that use multiple JeVois cameras connected to a single USB bus.
71 
72  \ingroup component */
73  class Manager : public Component,
74  public Parameter<manager::help, manager::loglevel, manager::tracelevel, manager::nickname>
75  {
76  public:
77  // END_JEVOIS_CODE_SNIPPET
78 
79  //! @name Manager construction, destruction, parsing command-line arguments
80  //! @{
81 
82  //! Constructor without command-line args
83  /*! The command-line args should be passed later using setArgs(), before you init(), otherwise the manager will
84  issue a non-fatal warning. */
85  Manager(std::string const & instance = "TheManager");
86 
87  //! Constructor
88  /*! Creates the Manager, and optionally takes in the command line arguments. */
89  Manager(int argc, char const* argv[], std::string const & instance = "TheManager");
90 
91  //! Set the command-line arguments, call this before start() if args were not passed at construction
92  void setCommandLineArgs(int argc, char const* argv[]);
93 
94  //! Destructor
95  virtual ~Manager();
96 
97  //! @}
98 
99  //! @name Component hierarchies unser the Manager
100  //! @{
101 
102  //! Pseudo-constructor: construct a top-level Component
103  /*! A component of type Comp (which must derive from jevois::Component) will be created and added as a
104  sub-component of the manager (making it a so-called top-level component). The child logically "belongs" to the
105  Manager, and will automatically be deleted when the Manager is deleted. In addition to construction, the
106  component will be brought to the same initialized state as the Manager. */
107  template <class Comp, typename... Args>
108  std::shared_ptr<Comp> addComponent(std::string const & instanceName, Args && ...args);
109 
110  //! Use addComponent() on the Manager as opposed to jevois::Component::addSubComponent()
111  template <class Comp, typename... Args>
112  std::shared_ptr<Comp> addSubComponent(std::string const & instanceName, Args && ...args) = delete;
113 
114  //! Remove a top-level Component from the Manager, by shared_ptr
115  /*! \note Beware that the passed shared_ptr is invalidated in the process. A warning is issued if the use_count is
116  not down to zero after that (i.e., there are additional shared_ptr pointers to this Component floating around,
117  which prevent it from actually being deleted. */
118  template <class Comp>
119  void removeComponent(std::shared_ptr<Comp> & component);
120 
121  //! Use removeComponent() on the Manager as opposed to jevois::Component::removeSubComponent()
122  template <class Comp>
123  void removeSubComponent(std::shared_ptr<Comp> & component) = delete;
124 
125  //! Remove a top-level Component from the Manager, by instance name
126  void removeComponent(std::string const & instanceName, bool warnIfNotFound = true);
127 
128  //! Use removeComponent() on the Manager as opposed to jevois::Component::removeSubComponent()
129  void removeSubComponent(std::string const & instanceName, bool warnIfNotFound) = delete;
130 
131  //! Get a top-level component by instance name
132  /*! This method does a dynamic_pointer_cast to Comp if it is not the default (jevois::Component). Throws if
133  component is not found by instance name, or it is found but not of type Comp (if Comp is specified). Note that
134  once you hold a shared_ptr to a Component, it is guaranteed that the component will not be destroyed until
135  that shared_ptr is released. If the JeVois system tries to destroy the component, e.g., someone calls
136  removeComponent(), the component will be un-initialized and its parent will be unset, so it will not be
137  fully operational, and will be actually deleted when the last shared_ptr to it runs out of scope. */
138  template <class Comp = jevois::Component>
139  std::shared_ptr<Comp> getComponent(std::string const & instanceName) const;
140 
141  //! Use getComponent() on the Manager as opposed to jevois::Component::getSubComponent()
142  template <class Comp>
143  std::shared_ptr<Comp> getSubComponent(std::string const & instanceName) const = delete;
144 
145  //! @}
146 
147  //! @name Manager runtime
148  //! @{
149 
150  //! Users can call init() on the Manager to initialize the whole Component tree
151  /*! This will, in particular, trigger parsing of command-line arguments. */
152  using Component::init;
153 
154  //! Users can call uninit() on the Manager to un-initialize the whole Component tree
155  /*! If started(), this will first call stop() */
156  using Component::uninit;
157 
158  //! Get the remaining arguments that were not parsed by the command line
159  /*! Any command line arguments after a lone '--' will be available in remainingArgs() */
160  std::vector<std::string> const & remainingArgs() const;
161 
162  //! @}
163 
164  protected:
165  // BEGIN_JEVOIS_CODE_SNIPPET manager2.C
166 
167  //! Parameter callback
168  void onParamChange(manager::loglevel const & param, manager::LogLevel const & newval);
169 
170  //! Parameter callback
171  void onParamChange(manager::tracelevel const & param, unsigned int const & newval);
172  // END_JEVOIS_CODE_SNIPPET
173 
174  //! Calls parseCommandLine()
175  void preInit() override;
176 
177  //! Checks for the --help flag
178  void postInit() override;
179 
180  //! Constructs a help message from all parameters in the model, and outputs it to 'out'
181  void constructHelpMessage(std::ostream & out) const;
182 
183  //! Constructs a help message and tries to send it to /usr/bin/less
184  void printHelpMessage() const;
185 
186  private:
187  //! Parse the command line and internally store the resulting remaining args
188  void doParseCommandLine();
189 
190  //! Parses the command line, and applies settings to all Parameters
191  /*! See the definition of Parameter for details on how to specify them from the command line. */
192  std::vector<std::string> const parseCommandLine(std::vector<std::string> const & commandLineArgs);
193 
194  //! The original command line arguments
195  std::vector<std::string> itsCommandLineArgs;
196 
197  //! Did we get command-line args (even though there may be none, just to detect if forgot)
198  bool itsGotArgs;
199 
200  //! Any command line arguments not used by the model
201  std::vector<std::string> itsRemainingArgs;
202  };
203 } // namespace jevois
204 
205 // Include implementation details
Generic variadic template class template definition for Component Parameters.
Manager of a hierarchy of Component objects.
Definition: Manager.H:73
A category to which multiple ParameterDef definitions can belong.
Definition: ParameterDef.H:33
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(l2grad, bool, "Use more accurate L2 gradient norm if true, L1 if false", false, ParamCateg)
JEVOIS_DECLARE_PARAMETER(thresh1, double, "First threshold for hysteresis", 50.0, ParamCateg)
A component of a model hierarchy.
Definition: Component.H:176
void onParamChange(manager::loglevel const &param, manager::LogLevel const &newval)
Parameter callback.