hermite  0.0.1
hermite.hpp
Go to the documentation of this file.
1 
7 #pragma once
8 
9 #include <algorithm>
10 #include <cstddef>
11 #include <cstdint>
12 #include <map>
13 #include <vector>
14 
15 #include "hermite/base_spline.hpp"
17 #include "hermite/pose.hpp"
19 
20 namespace hermite {
21 using svector::magn;
22 
49 template <std::size_t D> class Hermite : public BaseSpline<D> {
50 public:
58  Hermite() : m_multiplier{10LL} {}
59 
66  Hermite(const double multiplier) : m_multiplier{multiplier} {}
67 
71  Hermite(const Hermite<D> &other)
72  : m_multiplier{other.m_multiplier}, m_waypoints{other.m_waypoints} {}
73 
79  Hermite<D> &operator=(const Hermite<D> &other) {
80  // check if assigning to self
81  if (this == &other) {
82  return *this;
83  }
84 
85  m_multiplier = other.m_multiplier;
86  m_waypoints = other.m_waypoints;
87 
88  return *this;
89  }
90 
94  ~Hermite() override = default;
95 
104  void insert(const Pose<D> &waypoint) {
105  if (exists(waypoint)) {
106  return;
107  }
108 
109  auto tRounded = roundTime(waypoint.getTime());
110  m_waypoints[tRounded] = waypoint;
111  }
112 
122  void replace(const Pose<D> &waypoint) {
123  if (!exists(waypoint)) {
124  return;
125  }
126 
127  auto tRounded = roundTime(waypoint.getTime());
128  m_waypoints[tRounded] = waypoint;
129  }
130 
137  void insertOrReplace(const Pose<D> &waypoint) {
138  auto tRounded = roundTime(waypoint.getTime());
139  m_waypoints[tRounded] = waypoint;
140  }
141 
151  bool exists(const Pose<D> &waypoint) const {
152  return exists(waypoint.getTime());
153  }
154 
162  bool exists(const double time) const {
163  const auto tRounded = roundTime(time);
164  return m_waypoints.find(tRounded) != m_waypoints.end();
165  }
166 
177  void erase(const Pose<D> &waypoint) { erase(waypoint.getTime()); }
178 
188  void erase(const double time) {
189  const auto tRounded = roundTime(time);
190 
191  // check if exists
192  auto it = m_waypoints.find(tRounded);
193  if (it == m_waypoints.end()) {
194  return;
195  }
196 
197  m_waypoints.erase(it);
198  }
199 
205  std::vector<Pose<D>> getAllWaypoints() const {
206  std::vector<Pose<D>> res;
207  for (const auto &it : m_waypoints) {
208  res.push_back(it.second);
209  }
210 
211  return res;
212  }
213 
222  double getLowestTime() const override {
223  if (m_waypoints.size() == 0) {
224  return 0;
225  }
226 
227  auto firstIt = m_waypoints.begin();
228  return firstIt->second.getTime();
229  }
230 
239  double getHighestTime() const override {
240  if (m_waypoints.size() == 0) {
241  return 0;
242  }
243 
244  auto lastIt = m_waypoints.rbegin();
245  return lastIt->second.getTime();
246  }
247 
262  Vector<D> getPos(const double t) const override {
263  Vector<D> res;
264  if (m_waypoints.size() < 2) {
265  return res;
266  }
267 
268  auto func = getSub(t);
269  return func.getPos(t);
270  }
271 
284  Vector<D> getVel(const double t) const override {
285  Vector<D> res;
286  if (m_waypoints.size() < 2) {
287  return res;
288  }
289 
290  auto func = getSub(t);
291  return func.getVel(t);
292  }
293 
308  Vector<D> getAcc(const double t) const override {
309  Vector<D> res;
310  if (m_waypoints.size() < 2) {
311  return res;
312  }
313 
314  auto func = getSub(t);
315  return func.getAcc(t);
316  }
317 
330  double getLength(const double timeStep) const override {
331  double res = 0.0;
332 
333  if (m_waypoints.size() < 2) {
334  return res;
335  }
336 
337  double time = getLowestTime() + timeStep;
338  const double timeEnd = getHighestTime();
339  while (time <= timeEnd) {
340  auto vel = getVel(time);
341  auto speed = magn(vel);
342  res += speed * timeStep;
343 
344  time += timeStep;
345  }
346 
347  return res;
348  }
349 
350 private:
351  double m_multiplier;
352  std::map<std::int64_t, Pose<D>> m_waypoints;
353 
361  std::int64_t roundTime(double t) const {
362  t *= m_multiplier;
363  return static_cast<std::int64_t>(t);
364  }
365 
374  HermiteSub<D> getSub(const double t) const {
375  const auto tRound = roundTime(t);
376  auto itLower = m_waypoints.upper_bound(tRound);
377 
378  if (itLower == m_waypoints.begin()) {
379  itLower++;
380  }
381 
382  if (itLower == m_waypoints.end()) {
383  itLower--;
384  }
385 
386  auto itUpper = itLower;
387  itLower--;
388 
389  const auto objUpper = itUpper->second;
390  const auto objLower = itLower->second;
391 
392  const auto p0 = objLower.getPos();
393  const auto pf = objUpper.getPos();
394  const auto v0 = objLower.getVel();
395  const auto vf = objUpper.getVel();
396  const auto lowerT = objLower.getTime();
397  const auto upperT = objUpper.getTime();
398 
399  HermiteSub<D> res{p0, pf, v0, vf, lowerT, upperT};
400  return res;
401  }
402 };
403 } // namespace hermite
T magn(const Vector< D, T > &v)
Gets the magnitude of the vector.
Definition: simplevectors.hpp:1281
Abstract base class for interpolating splines.
Definition: base_spline.hpp:20
Hermite spline class.
Definition: hermite.hpp:49
double getHighestTime() const override
Gets the upper bound of the domain of the piecewise spline function, which is the last time (highest ...
Definition: hermite.hpp:239
Vector< D > getPos(const double t) const override
Gets position at a certain time.
Definition: hermite.hpp:262
void insertOrReplace(const Pose< D > &waypoint)
Inserts a waypoint if it doesn't exist, otherwise replaces the waypoint.
Definition: hermite.hpp:137
bool exists(const Pose< D > &waypoint) const
Checks if a waypoint exists.
Definition: hermite.hpp:151
Hermite()
Default constructor.
Definition: hermite.hpp:58
double getLength(const double timeStep) const override
Gets arc length.
Definition: hermite.hpp:330
bool exists(const double time) const
Checks if a waypoint at a certain time exists.
Definition: hermite.hpp:162
Vector< D > getVel(const double t) const override
Gets velocity at a certain time.
Definition: hermite.hpp:284
std::vector< Pose< D > > getAllWaypoints() const
Gets a list of all waypoints.
Definition: hermite.hpp:205
void replace(const Pose< D > &waypoint)
Replaces a waypoint.
Definition: hermite.hpp:122
void erase(const Pose< D > &waypoint)
Removes a waypoint.
Definition: hermite.hpp:177
void insert(const Pose< D > &waypoint)
Inserts a waypoint.
Definition: hermite.hpp:104
Hermite(const Hermite< D > &other)
Copy constructor.
Definition: hermite.hpp:71
double getLowestTime() const override
Gets the lower bound of the domain of the piecewise spline function, which is the first time (lowest ...
Definition: hermite.hpp:222
Hermite< D > & operator=(const Hermite< D > &other)
Assignment operator.
Definition: hermite.hpp:79
Hermite(const double multiplier)
Constructor.
Definition: hermite.hpp:66
~Hermite() override=default
Destructor.
Vector< D > getAcc(const double t) const override
Gets acceleration of the function at a certain time.
Definition: hermite.hpp:308
void erase(const double time)
Removes a waypoint.
Definition: hermite.hpp:188
A pose object.
Definition: pose.hpp:23
double getTime() const
Gets time.
Definition: pose.hpp:88
A base vector representation.
Definition: simplevectors.hpp:63