signal-cast-registerer.cpp 8.53 KB
Newer Older
1
2
3
4
5
6
7
// Copyright 2010 Thomas Moulard.
//

#include <string>

#include <boost/foreach.hpp>
#include <boost/format.hpp>
8

9
#include "signal-cast-register-test.h"
10
#include <dynamic-graph/debug.h>
11
#include <dynamic-graph/eigen-io.h>
12
13
#include <dynamic-graph/entity.h>
#include <dynamic-graph/factory.h>
14
#include <dynamic-graph/linear-algebra.h>
15
16
#include <dynamic-graph/pool.h>
#include <dynamic-graph/signal-cast-helper.h>
17
18
19
20
21
22
23
24
25
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal.h>

#include "signal-cast-registerer-libA.hh"
#include "signal-cast-registerer-libB.hh"

#define BOOST_TEST_MODULE signal_cast_registerer

#include <boost/test/output_test_stream.hpp>
26
#include <boost/test/unit_test.hpp>
27
#include <iostream>
28
29
30

using boost::test_tools::output_test_stream;

31
typedef Eigen::VectorXd Vector;
32
typedef Eigen::MatrixXd Matrix;
33

Bergé's avatar
Bergé committed
34
struct EigenCastRegisterer_V : public dynamicgraph::SignalCastRegisterer {
35
  typedef Vector bnuVector;
36

37
38
39
  EigenCastRegisterer_V()
      : SignalCastRegisterer(typeid(bnuVector), dispVector, castVector,
                             traceVector) {}
40

41
  static boost::any castVector(std::istringstream &iss) {
42
43
44
45
46
    bnuVector res;
    iss >> res;
    return res;
  }

47
48
  static void dispVector(const boost::any &object, std::ostream &os) {
    const bnuVector &v = boost::any_cast<bnuVector>(object);
49
    os << "[ ";
50
51
    for (int i = 0; i < v.size(); ++i)
      os << v(i) << " ";
52
53
54
    os << " ];" << std::endl;
  }

55
56
57
58
  static void traceVector(const boost::any &object, std::ostream &os) {
    const bnuVector &v = boost::any_cast<bnuVector>(object);
    for (int i = 0; i < v.size(); ++i)
      os << v(i) << " ";
59
60
61
62
    os << std::endl;
  }
};

Bergé's avatar
Bergé committed
63
64
65
template <typename Derived>
struct EigenCastRegisterer_M : public dynamicgraph::SignalCastRegisterer {
  typedef Matrix bnuMatrix;
66

67
68
69
  EigenCastRegisterer_M()
      : SignalCastRegisterer(typeid(bnuMatrix), dispMatrix, castMatrix,
                             traceMatrix) {}
70

71
  static boost::any castMatrix(std::istringstream &iss) {
Bergé's avatar
Bergé committed
72
73
74
75
    bnuMatrix res;
    iss >> res;
    return res;
  }
76

77
78
  static void dispMatrix(const boost::any &object, std::ostream &os) {
    const bnuMatrix &m = boost::any_cast<bnuMatrix>(object);
Bergé's avatar
Bergé committed
79
80
    os << m << std::endl;
  }
81

82
83
  static void traceMatrix(const boost::any &object, std::ostream &os) {
    const bnuMatrix &m = boost::any_cast<bnuMatrix>(object);
Bergé's avatar
Bergé committed
84
85
    os << m << std::endl;
  }
86
87
88
};

EigenCastRegisterer_V myVectorCast;
89
EigenCastRegisterer_M<int> myMatrixCast;
90
91
92
93
94
95

// Define a new cast with a type that supports streaming operators to
// and from it (this could be automated with macros).
dynamicgraph::DefaultCastRegisterer<bool> myBooleanCast;

// Check standard double cast registerer.
Bergé's avatar
Bergé committed
96
BOOST_AUTO_TEST_CASE(standard_double_registerer) {
97
98
99
100
101
  dynamicgraph::Signal<double, int> mySignal("out");

  typedef std::pair<std::string, std::string> test_t;
  std::vector<test_t> values;

Bergé's avatar
Bergé committed
102
103
104
  values.push_back(std::make_pair("42.0", "42\n"));
  values.push_back(std::make_pair("42.5", "42.5\n"));
  values.push_back(std::make_pair("-12.", "-12\n"));
105
106
107

  // Double special values.
  // FIXME: these tests are failing :(
Bergé's avatar
Bergé committed
108
109
110
111
  values.push_back(std::make_pair("inf", "inf\n"));
  values.push_back(std::make_pair("-inf", "-inf\n"));
  values.push_back(std::make_pair("nan", "nan\n"));

112
  BOOST_FOREACH (const test_t &test, values) {
Bergé's avatar
Bergé committed
113
114
115
    // Set
    std::istringstream value(test.first);
    mySignal.set(value);
116

Bergé's avatar
Bergé committed
117
    // Get
118
    {
Bergé's avatar
Bergé committed
119
120
121
      output_test_stream output;
      mySignal.get(output);
      BOOST_CHECK(output.is_equal(test.second));
122
123
    }

Bergé's avatar
Bergé committed
124
125
126
127
128
129
130
131
    // Trace
    {
      output_test_stream output;
      mySignal.trace(output);
      BOOST_CHECK(output.is_equal(test.second));
    }
  }

132
133
  // Check invalid values.
  // FIXME: this test is failing for now.
Bergé's avatar
Bergé committed
134
135
  std::istringstream value("This is not a valid double.");
  BOOST_CHECK_THROW(mySignal.set(value), std::exception);
136
137
138
}

// Check a custom cast registerer for Boost uBLAS vectors.
Bergé's avatar
Bergé committed
139
BOOST_AUTO_TEST_CASE(custom_vector_registerer) {
140
  dynamicgraph::Signal<dynamicgraph::Vector, int> myVectorSignal("vector");
141

142
143
144
145
146
147
148
149
150
  /// Create a second local vector registerer to generate an exception.
  bool res = false;
  try {
    EigenCastRegisterer_V myVectorCast2;
  } catch (const ExceptionSignal &aes) {
    res = (aes.getCode() == ExceptionSignal::GENERIC);
  }
  //  BOOST_CHECK(res);

151
152
153
154
  // Print the signal name.
  {
    output_test_stream output;
    output << myVectorSignal;
Bergé's avatar
Bergé committed
155
    BOOST_CHECK(output.is_equal("Sig:vector (Type Cst)"));
156
157
  }

Bergé's avatar
Bergé committed
158
159
160
161
162
  for (unsigned int i = 0; i < 5; ++i) {
    Vector v = Vector::Unit(5, i);
    std::ostringstream os;
    os << v;
    std::istringstream ss("[5](" + os.str() + ")");
163

Bergé's avatar
Bergé committed
164
165
    // Set signal value.
    myVectorSignal.set(ss);
166

Bergé's avatar
Bergé committed
167
168
169
    // Print out signal value.
    output_test_stream output;
    myVectorSignal.get(output);
170

Bergé's avatar
Bergé committed
171
172
    boost::format fmt("[ %d %d %d %d %d  ];\n");
    fmt % (i == 0) % (i == 1) % (i == 2) % (i == 3) % (i == 4);
173

Bergé's avatar
Bergé committed
174
175
    BOOST_CHECK(output.is_equal(fmt.str()));
  }
176

Bergé's avatar
Bergé committed
177
  // Catch Exception of ss (not good input)
178

Bergé's avatar
Bergé committed
179
  // ss[0] != "["
180
  try {
Bergé's avatar
Bergé committed
181
182
    std::istringstream ss("test");
    myVectorSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
183
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
184
    std::cout << "Test passed : ss[0] != \"[\"";
185
186
  }

Bergé's avatar
Bergé committed
187
188
189
190
  // ss[1] != %i
  try {
    std::istringstream ss("[test");
    myVectorSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
191
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
192
193
    std::cout << "Test passed : ss[1] != %i";
  }
194

Bergé's avatar
Bergé committed
195
196
197
198
  // ss[2] != "]"
  try {
    std::istringstream ss("[5[");
    myVectorSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
199
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
200
201
    std::cout << "Test passed : ss[2] != \"]\"";
  }
202

Bergé's avatar
Bergé committed
203
204
205
206
  // ss[3] != "("
  try {
    std::istringstream ss("[5]test");
    myVectorSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
207
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
208
209
    std::cout << "Test passed : ss[3] != \"(\"";
  }
210

Bergé's avatar
Bergé committed
211
212
213
214
  // ss[4] != ' ' || ','
  try {
    std::istringstream ss("[5](1, ");
    myVectorSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
215
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
216
217
    BOOST_ERROR("Can't happened");
  }
218

Bergé's avatar
Bergé committed
219
220
221
222
  // ss[-1] != ")"
  try {
    std::istringstream ss("[5](1,2,3,4,5]");
    myVectorSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
223
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
224
225
    std::cout << "Test passed : ss[-1] != \")\"";
  }
226
227
228
229
230
231
232

  try {
    output_test_stream output;
    myVectorSignal.trace(output);
  } catch (ExceptionSignal &e) {
    std::cout << "Test passed : ss[-1] != \")\"";
  }
233
234
}

Bergé's avatar
Bergé committed
235
236
BOOST_AUTO_TEST_CASE(custom_matrix_registerer) {
  dynamicgraph::Signal<dynamicgraph::Matrix, int> myMatrixSignal("matrix");
237

Bergé's avatar
Bergé committed
238
239
240
241
242
243
  // Print the signal name.
  {
    output_test_stream output;
    output << myMatrixSignal;
    BOOST_CHECK(output.is_equal("Sig:matrix (Type Cst)"));
  }
244

Bergé's avatar
Bergé committed
245
  // Catch Exception of ss (not good input)
246

Bergé's avatar
Bergé committed
247
248
249
250
  // ss[0] != "["
  try {
    std::istringstream ss("test");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
251
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
252
253
    std::cout << "Test passed : ss[0] != \"[\"";
  }
254

Bergé's avatar
Bergé committed
255
256
257
258
  // ss[1] != %i
  try {
    std::istringstream ss("[test");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
259
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
260
261
    std::cout << "Test passed : ss[1] != %i";
  }
262

Bergé's avatar
Bergé committed
263
264
265
266
  // ss[2] != ","
  try {
    std::istringstream ss("[5[");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
267
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
268
269
    std::cout << "Test passed : ss[2] != \",\"";
  }
270

Bergé's avatar
Bergé committed
271
272
273
274
  // ss[3] != %i
  try {
    std::istringstream ss("[5,c");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
275
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
276
277
    std::cout << "Test passed : ss[3] != %i";
  }
278

Bergé's avatar
Bergé committed
279
280
281
282
  // ss[4] != "]"
  try {
    std::istringstream ss("[5,3[");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
283
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
284
285
    std::cout << "Test passed : ss[4] != \"]\"";
  }
286

Bergé's avatar
Bergé committed
287
288
289
290
  // ss[5] != "("
  try {
    std::istringstream ss("[5,3]test");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
291
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
292
293
    std::cout << "Test passed : ss[5] != \"(\"";
  }
294

Bergé's avatar
Bergé committed
295
296
297
298
  // ss[6] != "("
  try {
    std::istringstream ss("[5,3](test");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
299
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
300
301
    std::cout << "Test passed : ss[6] != \"(\"";
  }
302

Bergé's avatar
Bergé committed
303
304
305
306
  // ss[8] != " " || ","
  try {
    std::istringstream ss("[5,3]((1,");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
307
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
308
309
    BOOST_ERROR("Can't happened");
  }
310

Bergé's avatar
Bergé committed
311
312
313
314
  // ss[6+n] != ")"
  try {
    std::istringstream ss("[5,3]((1,2,3]");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
315
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
316
317
    std::cout << ("ss[6+n] != \")\"");
  }
318

Bergé's avatar
Bergé committed
319
320
321
322
  // ss[-3] != ")"
  try {
    std::istringstream ss("[5,1]((1)(2)(3[");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
323
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
324
325
    std::cout << "Test passed : ss[5] != \")\"";
  }
326

Bergé's avatar
Bergé committed
327
328
329
330
  // ss[-3] != ")"
  try {
    std::istringstream ss("[5,1]((1)(2)(3)[");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
331
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
332
333
    std::cout << "Test passed : ss[5] != \")\"";
  }
334

Bergé's avatar
Bergé committed
335
336
337
338
  // ss[-1]!= ")"
  try {
    std::istringstream ss("[3,1]((1)(2),(3)[");
    myMatrixSignal.set(ss);
Olivier Stasse's avatar
Olivier Stasse committed
339
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
340
341
    std::cout << "Test passed : ss[5] != \")\" and ignore \",\"";
  }
342

Bergé's avatar
Bergé committed
343
  //[...]((...))
344
}