humoto
reader.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Jan Michalczyk
4  @author Alexander Sherikov
5  @copyright 2014-2017 INRIA. Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 
11 #pragma once
12 
13 namespace humoto
14 {
15  namespace config
16  {
17  namespace yaml
18  {
19  /**
20  * @brief Configuration reader class
21  */
23  {
24  private:
25  /// input file stream
26  std::ifstream config_ifs_;
27 
28  /// instance of YAML parser
29  YAML::Parser parser_;
30 
31  /// root node
32  YAML::Node root_node_;
33 
34  /// Stack of nodes.
35  std::stack<const YAML::Node *> node_stack_;
36 
37 
38  private:
39  /**
40  * @brief open configuration file
41  *
42  * @param[in] file_name
43  */
44  void openFile(const std::string& file_name)
45  {
46  config_ifs_.open(file_name.c_str());
47  if (!config_ifs_.good())
48  {
49  std::string file_name_default = std::string(HUMOTO_DEFAULT_CONFIG_PREFIX) + file_name;
50  config_ifs_.open(file_name_default.c_str());
51  }
52  if (!config_ifs_.good())
53  {
54  HUMOTO_THROW_MSG(std::string("Could not open configuration file: ") + file_name.c_str());
55  }
56 
57  parser_.Load(config_ifs_),
58  parser_.GetNextDocument(root_node_);
59  node_stack_.push(&root_node_);
60  }
61 
62 
63  /**
64  * @brief Get current node
65  *
66  * @return pointer to the current node
67  */
68  const YAML::Node * getCurrentNode()
69  {
70  return(node_stack_.top());
71  }
72 
73 
74  public:
75  /**
76  * @brief Constructor
77  *
78  * @param[in] file_name
79  */
80  explicit Reader(const std::string& file_name)
81  {
82  openFile(file_name);
83  }
84 
85 
86  /**
87  * @brief Default constructor
88  */
90  {
91  }
92 
93 
94 
95  /**
96  * @brief Descend to the entry with the given name
97  *
98  * @param[in] child_name child node name
99  *
100  * @return true if successful.
101  */
102  bool descend(const std::string & child_name)
103  {
104  const YAML::Node * child = getCurrentNode()->FindValue(child_name);
105 
106  if (child == NULL)
107  {
108  return(false);
109  }
110  else
111  {
112  node_stack_.push(child);
113  return(true);
114  }
115  }
116 
117 
118  /**
119  * @brief Ascend from the current entry to its parent.
120  */
121  void ascend()
122  {
123  node_stack_.pop();
124  }
125 
126 
127  /**
128  * @brief Read configuration entry (vector)
129  *
130  * @tparam t_Scalar Eigen template parameter
131  * @tparam t_rows Eigen template parameter
132  * @tparam t_flags Eigen template parameter
133  *
134  * @param[out] entry configuration parameter
135  * @param[in] entry_name name of the configuration parameter
136  * @param[in] crash_on_missing_entry
137  */
138  template < typename t_Scalar,
139  int t_rows,
140  int t_flags>
141  void readCompound(Eigen::Matrix<t_Scalar, t_rows, 1, t_flags> &entry,
142  const std::string & entry_name,
143  const bool crash_on_missing_entry = false)
144  {
145  if (descend(entry_name))
146  {
147  HUMOTO_ASSERT( (getCurrentNode()->Type() == YAML::NodeType::Sequence),
148  "[Config] Entry is not a sequence.");
149 
150  if (Eigen::Dynamic == t_rows)
151  {
152  entry.resize(getCurrentNode()->size());
153  }
154  else
155  {
156  HUMOTO_ASSERT( (static_cast<int>(getCurrentNode()->size()) == t_rows),
157  "[Config] Wrong entry sequence size.");
158  }
159 
160  for(humoto::EigenIndex i = 0; i < (Eigen::Dynamic == t_rows ? entry.rows() : t_rows); ++i)
161  {
162  (*getCurrentNode())[i] >> entry(i);
163  }
164 
165  ascend();
166  }
167  else
168  {
169  if (crash_on_missing_entry)
170  {
171  HUMOTO_THROW_MSG(std::string("Configuration file does not contain entry '") + entry_name + "'.");
172  }
173  }
174  }
175 
176 
177 
178  /**
179  * @brief Read a configuration entry (matrix)
180  *
181  * @tparam t_Scalar Eigen template parameter
182  * @tparam t_rows Eigen template parameter
183  * @tparam t_cols Eigen template parameter
184  * @tparam t_flags Eigen template parameter
185  *
186  * @param[out] entry data
187  * @param[in] entry_name name
188  * @param[in] crash_on_missing_entry
189  */
190  template < typename t_Scalar,
191  int t_rows,
192  int t_cols,
193  int t_flags>
194  void readCompound( Eigen::Matrix<t_Scalar, t_rows, t_cols, t_flags> &entry,
195  const std::string& entry_name,
196  const bool crash_on_missing_entry = false)
197  {
198  if (descend(entry_name))
199  {
200  humoto::EigenIndex num_rows;
201  humoto::EigenIndex num_cols;
202 
203  readScalar(num_rows, "rows", true);
204  readScalar(num_cols, "cols", true);
205 
206 
207  Eigen::VectorXd v;
208  readCompound(v, "data", true);
209 
210  HUMOTO_ASSERT( v.rows() == num_rows*num_cols,
211  std::string("Inconsistent configuration file entry: ") + entry_name);
212 
213  Eigen::Map< Eigen::Matrix< double,
214  Eigen::Dynamic,
215  Eigen::Dynamic,
216  Eigen::RowMajor> > map(v.data(),
217  num_rows,
218  num_cols);
219  entry = map;
220 
221  ascend();
222  }
223  else
224  {
225  if (crash_on_missing_entry)
226  {
227  HUMOTO_THROW_MSG(std::string("Configuration file does not contain entry '") + entry_name + "'.");
228  }
229  }
230  }
231 
232 
233  /**
234  * @brief Read configuration entry (std::vector)
235  *
236  * @tparam t_VectorEntryType type of the entry of std::vector
237  *
238  * @param[out] entry configuration parameter
239  * @param[in] entry_name name of the configuration parameter
240  * @param[in] crash_on_missing_entry
241  */
242  template <typename t_VectorEntryType>
243  void readCompound( std::vector<t_VectorEntryType> & entry,
244  const std::string & entry_name,
245  const bool crash_on_missing_entry = false)
246  {
247  if (descend(entry_name))
248  {
249  HUMOTO_ASSERT( (getCurrentNode()->Type() == YAML::NodeType::Sequence),
250  "[Config] Entry is not a sequence.");
251 
252  entry.resize(getCurrentNode()->size());
253 
254  for(std::size_t i = 0; i < getCurrentNode()->size(); ++i)
255  {
256  (*getCurrentNode())[i] >> entry[i];
257  }
258 
259  ascend();
260  }
261  else
262  {
263  if (crash_on_missing_entry)
264  {
265  HUMOTO_THROW_MSG(std::string("Configuration file does not contain entry '") + entry_name + "'.");
266  }
267  }
268  }
269 
270 
271 
272  /**
273  * @brief Read configuration entry (scalar template)
274  *
275  * @tparam t_EntryType type of the entry
276  *
277  * @param[out] entry configuration parameter
278  * @param[in] entry_name name of the configuration parameter
279  * @param[in] crash_on_missing_entry
280  */
281  template <typename t_EntryType>
282  void readScalar(t_EntryType & entry,
283  const std::string & entry_name,
284  const bool crash_on_missing_entry = false)
285  {
286  if (descend(entry_name))
287  {
288  *getCurrentNode() >> entry;
289  ascend();
290  }
291  else
292  {
293  if (crash_on_missing_entry)
294  {
295  HUMOTO_THROW_MSG(std::string("Configuration file does not contain entry '") + entry_name + "'.");
296  }
297  }
298  }
299 
300 
301  /**
302  * @brief Read configuration entry (an enum). This method
303  * is added since an explicit casting to integer is needed.
304  *
305  * @tparam t_EnumerationType enumeration type
306  *
307  * @param[out] entry configuration parameter
308  * @param[in] entry_name name of the configuration parameter
309  * @param[in] crash_on_missing_entry
310  */
311  template <typename t_EnumerationType>
312  void readEnum( t_EnumerationType & entry,
313  const std::string & entry_name,
314  const bool crash_on_missing_entry = false)
315  {
316  if (descend(entry_name))
317  {
318  int tmp_value = 0;
319  *getCurrentNode() >> tmp_value;
320 
321  entry = static_cast<t_EnumerationType> (tmp_value);
322  ascend();
323  }
324  else
325  {
326  if (crash_on_missing_entry)
327  {
328  HUMOTO_THROW_MSG(std::string("Configuration file does not contain entry '") + entry_name + "'.");
329  }
330  }
331  }
332  };
333  }
334  }
335 }
std::stack< const YAML::Node * > node_stack_
Stack of nodes.
Definition: reader.h:35
void readScalar(t_EntryType &entry, const std::string &entry_name, const bool crash_on_missing_entry=false)
Read configuration entry (scalar template)
Definition: reader.h:282
Reader()
Default constructor.
Definition: reader.h:89
void readCompound(std::vector< t_VectorEntryType > &entry, const std::string &entry_name, const bool crash_on_missing_entry=false)
Read configuration entry (std::vector)
Definition: reader.h:243
#define HUMOTO_LOCAL
Definition: export_import.h:26
void readCompound(Eigen::Matrix< t_Scalar, t_rows, t_cols, t_flags > &entry, const std::string &entry_name, const bool crash_on_missing_entry=false)
Read a configuration entry (matrix)
Definition: reader.h:194
std::ifstream config_ifs_
input file stream
Definition: reader.h:26
void ascend()
Ascend from the current entry to its parent.
Definition: reader.h:121
void readCompound(Eigen::Matrix< t_Scalar, t_rows, 1, t_flags > &entry, const std::string &entry_name, const bool crash_on_missing_entry=false)
Read configuration entry (vector)
Definition: reader.h:141
Configuration reader class.
Definition: reader.h:22
YAML::Node root_node_
root node
Definition: reader.h:32
#define HUMOTO_ASSERT(condition, message)
#define HUMOTO_THROW_MSG(s)
HUMOTO_THROW_MSG throws an error message concatenated with the name of the function (if supported)...
EIGEN_DEFAULT_DENSE_INDEX_TYPE EigenIndex
Definition: utility.h:26
bool descend(const std::string &child_name)
Descend to the entry with the given name.
Definition: reader.h:102
void openFile(const std::string &file_name)
open configuration file
Definition: reader.h:44
void readEnum(t_EnumerationType &entry, const std::string &entry_name, const bool crash_on_missing_entry=false)
Read configuration entry (an enum). This method is added since an explicit casting to integer is need...
Definition: reader.h:312
YAML::Parser parser_
instance of YAML parser
Definition: reader.h:29
The root namespace of HuMoTo.
Definition: config.h:12
Reader(const std::string &file_name)
Constructor.
Definition: reader.h:80
const YAML::Node * getCurrentNode()
Get current node.
Definition: reader.h:68