launch_config.h
Go to the documentation of this file.
1 // Aggregates all information needed to start and monitor nodes
2 // Author: Max Schwarz <max.schwarz@uni-bonn.de>
3 
4 #ifndef ROSMON_LAUNCH_LAUNCH_CONFIG_H
5 #define ROSMON_LAUNCH_LAUNCH_CONFIG_H
6 
7 #include "node.h"
8 
9 #include <map>
10 #include <vector>
11 #include <stdexcept>
12 #include <future>
13 #include <random>
14 
15 #include <XmlRpc.h>
16 #include <tinyxml.h>
17 #include <yaml-cpp/yaml.h>
18 
19 #include <fmt/format.h>
20 
21 namespace rosmon
22 {
23 namespace launch
24 {
25 
26 class LaunchConfig;
27 
28 constexpr double DEFAULT_CPU_LIMIT = 0.9f;
29 constexpr uint64_t DEFAULT_MEMORY_LIMIT = 500*1024*1024;
30 constexpr double DEFAULT_STOP_TIMEOUT = 5.0f;
31 
32 class ParseException : public std::exception
33 {
34 public:
35  explicit ParseException(const std::string& msg)
36  : m_msg(msg)
37  {}
38 
39  virtual ~ParseException() throw()
40  {}
41 
42  virtual const char* what() const noexcept
43  { return m_msg.c_str(); }
44 
45  template<typename... Args>
46  ParseException format(const char* format, const Args& ... args)
47  {
48  return ParseException(fmt::format(format, args...));
49  }
50 private:
51  std::string m_msg;
52 };
53 
54 extern const char* UNSET_MARKER;
55 
57 {
58 public:
60  : m_config(config)
61  , m_prefix("/")
62  {}
63 
64  const std::string& prefix() const
65  { return m_prefix; }
66 
67  const std::string& filename() const
68  { return m_filename; }
69 
70  void setFilename(const std::string& filename)
71  { m_filename = filename; }
72 
73  void setCurrentElement(TiXmlElement* e)
74  {
75  // NOTE: We should not keep a reference to the TiXmlElement here,
76  // since the ParseContext might be around longer than the DOM tree.
77  // See evaluateParameters().
78  if(e)
79  m_currentLine = e->Row();
80  else
81  m_currentLine = -1;
82  }
83 
84  ParseContext enterScope(const std::string& prefix);
85  void parseScopeAttributes(TiXmlElement* e, ParseContext& attr_ctx);
86 
87  std::string evaluate(const std::string& tpl, bool simplifyWhitespace = true);
88 
89  bool parseBool(const std::string& value, int line);
90 
92  {
93  m_args.clear();
94  }
95 
96  inline const std::map<std::string, std::string>& arguments() const
97  { return m_args; }
98 
99  void setArg(const std::string& name, const std::string& value, bool override);
100 
101  void setEnvironment(const std::string& name, const std::string& value);
102 
103  inline const std::map<std::string, std::string> environment() const
104  { return m_environment; }
105 
106  bool shouldSkip(TiXmlElement* e);
107 
109  { return m_config; }
110 
111  void setRemap(const std::string& from, const std::string& to);
112  const std::map<std::string, std::string>& remappings()
113  { return m_remappings; }
114 
115  std::string anonName(const std::string& base);
116 
117  template<typename... Args>
118  ParseException error(const char* fmt, const Args& ... args) const
119  {
120  std::string msg = fmt::format(fmt, args...);
121 
122  if(m_currentLine >= 0)
123  {
124  return ParseException(fmt::format("{}:{}: {}",
125  m_filename, m_currentLine, msg
126  ));
127  }
128  else
129  {
130  return ParseException(fmt::format("{}: {}", m_filename, msg));
131  }
132  }
133 
134  template<typename... Args>
135  void warning(const char* fmt, const Args& ... args) const;
136 
137 
138  double cpuLimit() const
139  { return m_cpuLimit; }
140  void setCPULimit(double limit)
141  { m_cpuLimit = limit; }
142 
143  uint64_t memoryLimit() const
144  { return m_memoryLimit; }
145  void setMemoryLimit(uint64_t limit)
146  { m_memoryLimit = limit; }
147 
148  double stopTimeout() const
149  { return m_stopTimeout; }
150  void setStopTimeout(double timeout)
151  { m_stopTimeout = timeout; }
152 
153  bool coredumpsEnabled() const
154  { return m_coredumpsEnabled; }
155  void setCoredumpsEnabled(bool enabled)
156  { m_coredumpsEnabled = enabled; }
157 
158 private:
160 
161  std::string m_prefix;
162  std::string m_filename;
163  int m_currentLine = -1;
164  std::map<std::string, std::string> m_args;
165  std::map<std::string, std::string> m_environment;
166  std::map<std::string, std::string> m_remappings;
167  std::map<std::string, std::string> m_anonNames;
168 
169  double m_cpuLimit = DEFAULT_CPU_LIMIT;
170  uint64_t m_memoryLimit = DEFAULT_MEMORY_LIMIT;
171  double m_stopTimeout = DEFAULT_STOP_TIMEOUT;
172  bool m_coredumpsEnabled = true;
173 };
174 
176 {
177 public:
178  typedef std::shared_ptr<LaunchConfig> Ptr;
179  typedef std::shared_ptr<const LaunchConfig> ConstPtr;
180 
181  LaunchConfig();
182 
183  enum class OutputAttr
184  {
185  Obey,
186  Ignore
187  };
188 
189  void setWarningOutput(std::ostream* warningStream);
190  std::ostream& warningOutput()
191  { return *m_warningOutput; }
192 
193  void setArgument(const std::string& name, const std::string& value);
194 
195  void setDefaultStopTimeout(double timeout);
196  void setDefaultCPULimit(double CPULimit);
197  void setDefaultMemoryLimit(uint64_t memoryLimit);
198 
199  void setOutputAttrMode(OutputAttr mode);
200 
201  void setNodeLogDir(const std::string& logDir);
202  std::string nodeLogDir() const
203  { return m_nodeLogDir; }
204 
205  void parse(const std::string& filename, bool onlyArguments = false);
206  void parseString(const std::string& input, bool onlyArguments = false);
207 
208  void applyAutoIncrementSpawnDelayToAll(const ros::WallDuration& autoIncrementSpawnDelay);
209 
210  void evaluateParameters();
211 
212  inline const std::map<std::string, XmlRpc::XmlRpcValue>& parameters() const
213  { return m_params; }
214 
215  inline const std::vector<Node::Ptr>& nodes() const
216  { return m_nodes; }
217 
218  inline const std::map<std::string, std::string>& arguments() const
219  { return m_rootContext.arguments(); }
220 
221  std::string anonName(const std::string& base);
222 
223  std::string rosmonNodeName() const
224  { return m_rosmonNodeName; }
225 
226  std::string windowTitle() const
227  { return m_windowTitle; }
228 
229  std::string generateAnonHash();
230 
231  bool disableUI() const
232  { return m_disableUI; }
233 private:
235  {
238  };
239 
240  void parseTopLevelAttributes(TiXmlElement* element);
241 
242  void parse(TiXmlElement* element, ParseContext* ctx, bool onlyArguments = false);
243  void parseNode(TiXmlElement* element, ParseContext& ctx);
244  void parseParam(TiXmlElement* element, ParseContext& ctx, ParamContext paramContext = PARAM_GENERAL);
245  void parseROSParam(TiXmlElement* element, ParseContext& ctx);
246  void parseInclude(TiXmlElement* element, ParseContext& ctx);
247  void parseArgument(TiXmlElement* element, ParseContext& ctx);
248  void parseEnv(TiXmlElement* element, ParseContext& ctx);
249  void parseRemap(TiXmlElement* element, ParseContext& ctx);
250 
251  void loadYAMLParams(const ParseContext& ctx, const YAML::Node& n, const std::string& prefix);
252 
253  XmlRpc::XmlRpcValue paramToXmlRpc(const ParseContext& ctx, const std::string& value, const std::string& type = "");
254 
256 
257  std::vector<Node::Ptr> m_nodes;
258 
259  using ParameterList = std::map<std::string, XmlRpc::XmlRpcValue>;
260  using ParameterFuture = std::future<XmlRpc::XmlRpcValue>;
261 
262  struct YAMLResult
263  {
264  std::string name;
265  YAML::Node yaml;
266  };
267 
269  std::map<std::string, ParameterFuture> m_paramJobs;
270  std::vector<std::future<YAMLResult>> m_yamlParamJobs;
271 
272  std::mt19937_64 m_anonGen;
273 
274  std::string m_rosmonNodeName;
275 
276  std::string m_windowTitle;
277 
278  OutputAttr m_outputAttrMode{OutputAttr::Ignore};
279 
280  bool m_disableUI = false;
281 
282  std::ostream* m_warningOutput = &std::cerr;
283 
284  std::string m_nodeLogDir;
285 };
286 
287 template<typename... Args>
288 void ParseContext::warning(const char* fmt, const Args& ... args) const
289 {
290  std::string msg = fmt::format(fmt, args...);
291 
292  if(m_currentLine >= 0)
293  {
294  m_config->warningOutput() << fmt::format(
295  "{}:{}: Warning: {}\n", m_filename, m_currentLine, msg
296  );
297  }
298  else
299  {
300  m_config->warningOutput() << fmt::format(
301  "{}: Warning: {}\n", m_filename, msg
302  );
303  }
304 }
305 
306 }
307 }
308 
309 #endif
310 
config evaluateParameters()
virtual const char * what() const noexcept
Definition: launch_config.h:42
std::map< std::string, std::string > m_anonNames
void setCoredumpsEnabled(bool enabled)
std::string windowTitle() const
std::string simplifyWhitespace(const std::string &input)
Compress any sequence of whitespace to single spaces.
std::future< XmlRpc::XmlRpcValue > ParameterFuture
void setFilename(const std::string &filename)
Definition: launch_config.h:70
ParseException(const std::string &msg)
Definition: launch_config.h:35
uint64_t memoryLimit() const
const std::string & filename() const
Definition: launch_config.h:67
ParseContext(LaunchConfig *config)
Definition: launch_config.h:59
ParseException error(const char *fmt, const Args &... args) const
std::map< std::string, ParameterFuture > m_paramJobs
std::shared_ptr< LaunchConfig > Ptr
const std::map< std::string, std::string > & arguments() const
Definition: launch_config.h:96
std::vector< std::future< YAMLResult > > m_yamlParamJobs
std::ostream & warningOutput()
const char * UNSET_MARKER
std::string rosmonNodeName() const
constexpr double DEFAULT_STOP_TIMEOUT
Definition: launch_config.h:30
std::map< std::string, std::string > m_args
const std::string & prefix() const
Definition: launch_config.h:64
ParseException format(const char *format, const Args &... args)
Definition: launch_config.h:46
std::map< std::string, std::string > m_environment
void setCPULimit(double limit)
constexpr uint64_t DEFAULT_MEMORY_LIMIT
Definition: launch_config.h:29
config parseString(R"EOF( <launch> <group ns="/"> <param name="param1" value="hello" /> </group> <node name="test_node" pkg="rosmon_core" type="abort" ns="/racecar"> <param name="private_param" value="hello again" /> </node> </launch> )EOF")
void setCurrentElement(TiXmlElement *e)
Definition: launch_config.h:73
std::shared_ptr< const LaunchConfig > ConstPtr
const std::vector< Node::Ptr > & nodes() const
const std::map< std::string, XmlRpc::XmlRpcValue > & parameters() const
const std::map< std::string, std::string > & arguments() const
void warning(const char *fmt, const Args &... args) const
std::vector< Node::Ptr > m_nodes
constexpr double DEFAULT_CPU_LIMIT
Definition: launch_config.h:28
const std::map< std::string, std::string > environment() const
void setMemoryLimit(uint64_t limit)
void setStopTimeout(double timeout)
std::map< std::string, std::string > m_remappings
std::string nodeLogDir() const
const std::map< std::string, std::string > & remappings()
std::map< std::string, XmlRpc::XmlRpcValue > ParameterList


rosmon_core
Author(s): Max Schwarz
autogenerated on Fri Jun 16 2023 02:15:06