GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/dynamic-graph/eigen-io.h Lines: 49 49 100.0 %
Date: 2023-03-15 12:04:10 Branches: 162 250 64.8 %

Line Branch Exec Source
1
//
2
// Copyright 2016 CNRS
3
//
4
// Author: Rohan Budhiraja
5
//
6
7
#ifndef DYNAMIC_GRAPH_EIGEN_IO_H
8
#define DYNAMIC_GRAPH_EIGEN_IO_H
9
10
#include <dynamic-graph/exception-signal.h>
11
#include <dynamic-graph/linear-algebra.h>
12
13
#include <Eigen/Geometry>
14
#include <boost/format.hpp>
15
#include <boost/numeric/conversion/cast.hpp>
16
17
using dynamicgraph::ExceptionSignal;
18
19
// TODO: Eigen 3.3 onwards has a global Eigen::Index definition.
20
// If Eigen version is updated, use Eigen::Index instead of this macro.
21
22
/* \brief Eigen Vector input from istream
23
 *
24
 * Input Vector format: [N](val1,val2,val3,...,valN)
25
 * e.g. [5](1,23,32.2,12.12,32)
26
 */
27
namespace Eigen {
28
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE eigen_index;
29
30
11
inline std::istringstream &operator>>(std::istringstream &iss,
31
                                      dynamicgraph::Vector &inst) {
32
  unsigned int _size;
33
  double _dbl_val;
34
  char _ch;
35
  boost::format fmt(
36
      "Failed to enter %s as vector."
37
✓✗
16
      " Reenter as [N](val1,val2,val3,...,valN)");
38
✓✗✓✗
11
  fmt % iss.str();
39
✓✗✓✗
✓✗✓✓
✓✓
11
  if (iss >> _ch && _ch != '[') {
40
✓✗✓✗
1
    throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
41
  } else {
42
✓✗✓✗
✓✓✓✗
✓✗✓✓
10
    if (iss >> _size && !iss.fail()) {
43
✓✗
9
      inst.resize(_size);
44
    } else
45
✓✗✓✗
1
      throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
46
✓✗✓✗
✓✗✓✓
✓✓
9
    if (iss >> _ch && _ch != ']')
47
✓✗✓✗
1
      throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
48
    else {
49
✓✗✓✗
✓✗✓✓
✓✓
8
      if (iss >> _ch && _ch != '(')
50
✓✗✓✗
1
        throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
51
      else {
52
✓✓
42
        for (unsigned int i = 0; i < _size; i++) {
53
✓✗
35
          iss >> _dbl_val;
54
✓✗✓✓
✓✗✗✓
✓✓✓✗
35
          if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
55
✓✗
35
          inst(i) = _dbl_val;
56
        }
57
✓✗✓✗
✓✓✓✓
✓✓
7
        if (iss >> _ch && _ch != ')')
58
✓✗✓✗
1
          throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
59
      }
60
    }
61
  }
62
12
  return iss;
63
}
64
65
/* \brief Eigen Matrix input from istream
66
 *
67
 * Matrix format: [M,N]((val11,val12,val13,...,val1N),...,
68
 * (valM1,valM2,...,valMN))
69
 * e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2))
70
 */
71
72
template <typename Derived>
73
12
inline std::istringstream &operator>>(std::istringstream &iss,
74
                                      DenseBase<Derived> &inst) {
75
  unsigned int _colsize;
76
  unsigned int _rowsize;
77
  double _dbl_val;
78
  char _ch;
79
✓✗
24
  boost::format fmt(
80
      "Failed to enter %s as matrix. Reenter as "
81
      "((val11,val12,val13,...,val1N),"
82
      "...,(valM1,valM2,...,valMN))");
83
✓✗
23
  MatrixXd _tmp_matrix;
84
✓✗✓✗
12
  fmt % iss.str();
85
✓✗✓✗
✓✗✓✓
✓✓
12
  if (iss >> _ch && _ch != '[') {
86
✓✗✓✗
1
    throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
87
  } else {
88
✓✗
11
    iss >> _rowsize;
89
✓✗✓✓
✓✗✗✓
✓✓✓✗
11
    if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
90
✓✗
11
    iss >> _colsize;
91
✓✗✓✓
11
    if (iss.fail())
92
✓✗✓✗
3
      throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
93
    else {
94
✓✗
8
      _tmp_matrix.resize(_rowsize, _colsize);
95
✓✗✓✗
✓✗✓✓
✓✓
8
      if (iss >> _ch && _ch != ']')
96
✓✗✓✗
1
        throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
97
      else {
98
✓✗✓✗
✓✗✓✓
✓✓
7
        if (iss >> _ch && _ch != '(')
99
✓✗✓✗
1
          throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
100
        else {
101
✓✓
19
          for (unsigned int j = 0; j < _rowsize; j++) {
102
✓✗✓✗
✓✓✓✓
✓✓
17
            if (iss >> _ch && _ch != '(')
103
✓✗✓✗
2
              throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
104
✓✓
42
            for (unsigned int i = 0; i < _colsize; i++) {
105
✓✗
27
              iss >> _dbl_val;
106
✓✗✓✓
✓✗✗✓
✓✓✓✗
27
              if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
107
✓✗
27
              _tmp_matrix(j, i) = _dbl_val;
108
            }
109
✓✗✓✗
✓✓✓✓
✓✓
15
            if (iss >> _ch && _ch != ')')
110
✓✗✓✗
2
              throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
111
✓✗✓✓
✓✗✗✓
✓✓✓✗
13
            if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
112
          }
113
✓✗✓✗
✓✓✓✗
✓✓
2
          if (iss >> _ch && _ch != ')')
114
✓✗✓✗
1
            throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
115
        }
116
      }
117
    }
118
  }
119
✓✗
1
  inst = _tmp_matrix;
120
2
  return iss;
121
}
122
123
inline std::istringstream &operator>>(std::istringstream &iss,
124
                                      Transform<double, 3, Affine> &inst) {
125
  MatrixXd M;
126
  iss >> M;
127
  inst.matrix() = M;
128
  return iss;
129
}
130
131
/* \brief Eigen Homogeneous Matrix output
132
 *
133
 * Matrix format: [M,N]((val11,val12,val13,...,val1N),...,
134
 * (valM1,valM2,...,valMN))
135
 * e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2))
136
 */
137
138
inline std::ostream &operator<<(std::ostream &os,
139
                                Transform<double, 3, Affine> MH) {
140
  IOFormat boostFmt(StreamPrecision, DontAlignCols, ",", ",", "(", ")", "(",
141
                    ")");
142
143
  os << "[4,4]" << MH.matrix().format(boostFmt);
144
  return os;
145
}
146
147
inline std::ostream &operator<<(std::ostream &os, AngleAxisd quat) {
148
  VectorXd v(4);
149
  v(0) = quat.angle();
150
  v.tail<3>() = quat.axis();
151
  os << v;
152
  return os;
153
}
154
155
inline std::istringstream &operator>>(std::istringstream &iss,
156
                                      AngleAxisd &inst) {
157
  VectorXd v(4);
158
  iss >> v;
159
  inst.angle() = v(0);
160
  inst.axis() = v.tail<3>();
161
  return iss;
162
}
163
164
}  // namespace Eigen
165
166
#endif  // DYNAMIC_GRAPH_EIGEN_IO_H