Corentin Chauvin-Hameau – 2019-2020
Coverage Path Planning for an underwater robot surveying a marine farm
spline.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  *
4  * \brief Definition of a class for 3D spline interpolation
5  * \author Corentin Chauvin-Hameau
6  * \date 2020
7  */
8 
9 #include "spline.hpp"
10 #include <eigen3/Eigen/Dense>
11 #include <boost/numeric/odeint.hpp>
12 #include <vector>
13 #include <iostream>
14 
15 using namespace std;
16 using Eigen::Vector3f;
17 namespace pl = std::placeholders;
18 
19 
20 namespace mfcpp {
21 
22 Spline::Spline():
23  prepared_(false)
24 {
25 
26 }
27 
28 
30  const std::vector<Eigen::Vector3f> &positions,
31  const std::vector<Eigen::Vector3f> &orientations,
32  float speed)
33 {
34  set_poses(positions, orientations);
35  set_speed(speed);
36  prepare();
37 }
38 
39 
41  const std::vector<Eigen::Vector3f> &positions,
42  const std::vector<Eigen::Vector3f> &orientations)
43 {
44  if (positions.size() != orientations.size())
45  cout << "[Spline] Not the same number of specified positions and orientations" << endl;
46  if (positions.size() == 0)
47  cout << "[Spline] No specified position" << endl;
48 
49  p_ = positions;
50  o_ = orientations;
51  n_ = positions.size() - 1;
52  prepared_ = false;
53 }
54 
55 
57 {
58  speed_ = speed;
59  prepared_ = false;
60 }
61 
62 
64  float t,
65  Eigen::Vector3f &position,
66  Eigen::Vector3f &orientation,
67  bool &last_reached)
68 {
69  if (!prepared_)
70  prepare();
71 
72  if (t < 0) {
73  cout << "[Spline] Evaluating at t<0 (t=" << t << ")" << endl;
74  return;
75  }
76 
77  float s = compute_abscissa(t);
78 
79  if (s >= n_) {
80  last_reached = true;
81  s = n_;
82  } else
83  last_reached = false;
84 
85  position = evaluate_position(s);
86  orientation = compute_orientation(s);
87 }
88 
89 
91 {
93 
94  last_s_ = 0;
95  last_t_ = 0;
96 
97  prepared_ = true;
98 }
99 
100 
102 {
103  a_.resize(n_, vector<Vector3f>(4));
104 
105  for (int k = 0; k < n_; k++) {
106  a_[k][0] = p_[k];
107  a_[k][1] = o_[k];
108  a_[k][2] = 3*(p_[k+1] - p_[k]) - 2*o_[k] - o_[k+1];
109  a_[k][3] = 2*(p_[k] - p_[k+1]) + o_[k] + o_[k+1];
110  }
111 }
112 
113 
114 Eigen::Vector3f Spline::evaluate_position(float s)
115 {
116  if (s < 0)
117  return p_[0];
118  if (s >= n_)
119  return p_[n_];
120 
121  int k = (int) s;
122 
123  return a_[k][0] + (s-k)*a_[k][1] + pow(s-k, 2)*a_[k][2] + pow(s-k, 3)*a_[k][3];
124 }
125 
126 
127 Eigen::Vector3f Spline::compute_orientation(float s)
128 {
129  if (s < 0)
130  return o_[0];
131  if (s >= n_)
132  return o_[n_];
133 
134  int k = (int) s;
135 
136  Vector3f orientation = a_[k][1] + 2*(s-k)*a_[k][2] + 3*pow(s-k, 2)*a_[k][3];
137  return orientation;
138 }
139 
140 
142  const std::vector<double> &s,
143  std::vector<double> &dsdt,
144  const double t)
145 {
146  dsdt[0] = speed_ / compute_orientation(s[0]).norm();
147 }
148 
149 
151 {
152  float s0 = last_s_;
153  float t0 = last_t_;
154  vector<double> state(1, s0);
155 
156  if (t0 != t) {
157  size_t steps = boost::numeric::odeint::integrate(
158  std::bind(&Spline::deriv_abscissa, this, pl::_1, pl::_2, pl::_3),
159  state, t0, t, float(t-t0)/2
160  );
161  }
162 
163  last_s_ = state[0];
164  last_t_ = t;
165 
166  return state[0];
167 }
168 
169 
170 } // namespace mfcpp
Definition: common.hpp:23
float last_t_
Time instant of the last evaluated point.
Definition: spline.hpp:89
float compute_abscissa(float t)
Computes the curvilinear abscissa corresponding to a time instant.
Definition: spline.cpp:150
void compute_parameters()
Computes the spline parameters.
Definition: spline.cpp:101
float speed_
Constant speed to adopt on the path.
Definition: spline.hpp:83
std::vector< Eigen::Vector3f > o_
Corresponding orientations.
Definition: spline.hpp:85
void evaluate(float t, Eigen::Vector3f &position, Eigen::Vector3f &orientation, bool &last_reached)
Evaluates the spline at a specific time instant (assuming constant speed)
Definition: spline.cpp:63
std::vector< Eigen::Vector3f > p_
Positions to interpolate.
Definition: spline.hpp:84
Eigen::Vector3f compute_orientation(float s)
Computes the orientation at a specific curvilinear abscissa.
Definition: spline.cpp:127
void set_poses(const std::vector< Eigen::Vector3f > &positions, const std::vector< Eigen::Vector3f > &orientations)
Sets the poses to interpolate.
Definition: spline.cpp:40
int n_
Number of poses to interpolate.
Definition: spline.hpp:82
std::vector< std::vector< Eigen::Vector3f > > a_
Spline parameters for each segment (ie between each pose)
Definition: spline.hpp:86
Declaration of a class for 3D spline interpolation.
float last_s_
Curvilinear abscissa of the last evaluated point.
Definition: spline.hpp:88
void deriv_abscissa(const std::vector< double > &s, std::vector< double > &dsdt, const double t)
Computes the derivative of the curvilinear abscissa wrt time.
Definition: spline.cpp:141
void set_speed(float speed)
Set the desired speed on the path.
Definition: spline.cpp:56
bool prepared_
Whether the class is ready for interpolation.
Definition: spline.hpp:87
Eigen::Vector3f evaluate_position(float s)
Evaluates the spline at a specific curvilinear abscissa.
Definition: spline.cpp:114
Spline()
Default constructor.
Definition: spline.cpp:22
void prepare()
Prepares the class for interpolation.
Definition: spline.cpp:90