MRSL Motion Primitive Library  1.2
A motion primitive library for generating trajectory for mobile robots
trajectory.h
Go to the documentation of this file.
1 
6 #ifndef MPL_TRAJECTORY_H
7 #define MPL_TRAJECTORY_H
8 
9 #include <mpl_basis/lambda.h>
10 #include <mpl_basis/primitive.h>
11 
19 template <int Dim>
20 struct Command {
27  decimal_t t;
28 };
29 
32 
35 
42 template <int Dim>
43 class Trajectory {
44  public:
48  Trajectory() : total_t_(0) {}
52  Trajectory(const vec_E<Primitive<Dim>> &prs) : segs(prs) {
53  taus.push_back(0);
54  for (const auto &pr : prs) taus.push_back(pr.t() + taus.back());
55  Ts = taus;
56  total_t_ = taus.back();
57  }
58 
68  decimal_t tau = lambda_.getTau(time);
69  if (tau < 0) tau = 0;
70  if (tau > total_t_) tau = total_t_;
71 
72  for (size_t id = 0; id < segs.size(); id++) {
73  if ((tau >= taus[id] && tau < taus[id + 1]) || id == segs.size() - 1) {
74  tau -= taus[id];
75  Waypoint<Dim> p(segs[id].control());
76  for (int j = 0; j < Dim; j++) {
77  const auto pr = segs[id].pr(j);
78  p.pos(j) = pr.p(tau);
79  p.vel(j) = pr.v(tau);
80  p.acc(j) = pr.a(tau);
81  p.jrk(j) = pr.j(tau);
82  p.yaw = normalize_angle(segs[id].pr_yaw().p(tau));
83  }
84  return p;
85  }
86  }
87 
88  printf("cannot find tau according to time: %f\n", time);
89  return Waypoint<Dim>();
90  }
91 
99  bool evaluate(decimal_t time, Command<Dim> &p) const {
100  decimal_t tau = lambda_.getTau(time);
101  if (tau < 0) tau = 0;
102  if (tau > total_t_) tau = total_t_;
103 
104  decimal_t lambda = 1;
105  decimal_t lambda_dot = 0;
106 
107  if (lambda_.exist()) {
108  VirtualPoint vt = lambda_.evaluate(tau);
109  lambda = vt.p;
110  lambda_dot = vt.v;
111  }
112 
113  for (size_t id = 0; id < segs.size(); id++) {
114  if (tau >= taus[id] && tau <= taus[id + 1]) {
115  tau -= taus[id];
116  for (int j = 0; j < Dim; j++) {
117  const auto pr = segs[id].pr(j);
118  p.pos(j) = pr.p(tau);
119  p.vel(j) = pr.v(tau) / lambda;
120  p.acc(j) = pr.a(tau) / lambda / lambda -
121  p.vel(j) * lambda_dot / lambda / lambda / lambda;
122  p.jrk(j) = pr.j(tau) / lambda / lambda -
123  3 / power(lambda, 3) * p.acc(j) * p.acc(j) * lambda_dot +
124  3 / power(lambda, 4) * p.vel(j) * lambda_dot * lambda_dot;
125  p.yaw = normalize_angle(segs[id].pr_yaw().p(tau));
126  p.yaw_dot = normalize_angle(segs[id].pr_yaw().v(tau));
127  p.t = time;
128  }
129  return true;
130  }
131  }
132 
133  printf("cannot find tau according to time: %f\n", time);
134  return false;
135  }
136 
140  bool scale(decimal_t ri, decimal_t rf) {
141  std::vector<VirtualPoint> vs;
142  VirtualPoint vi, vf;
143  vi.p = 1.0 / ri;
144  vi.v = 0;
145  vi.t = 0;
146 
147  vf.p = 1.0 / rf;
148  vf.v = 0;
149  vf.t = taus.back();
150 
151  vs.push_back(vi);
152  vs.push_back(vf);
153  Lambda ls(vs);
154  lambda_ = ls;
155  std::vector<decimal_t> ts;
156  for (const auto &tau : taus) ts.push_back(lambda_.getT(tau));
157  Ts = ts;
158  total_t_ = Ts.back();
159  return true;
160  }
161 
166  std::vector<VirtualPoint> vs;
167  VirtualPoint vi, vf;
168  vi.p = ri;
169  vi.v = 0;
170  vi.t = 0;
171 
172  vf.p = rf;
173  vf.v = 0;
174  vf.t = taus.back();
175 
176  vs.push_back(vi);
177  for (int id = 0; id < (int)segs.size(); id++) {
178  for (int i = 0; i < 3; i++) {
179  if (segs[id].max_vel(i) > mv) {
180  std::vector<decimal_t> ts = segs[id].pr(i).extrema_vel(segs[id].t());
181  if (id != 0) ts.push_back(0);
182  ts.push_back(segs[id].t());
183  for (const auto &tv : ts) {
184  Vec4f p = segs[id].pr(i).evaluate(tv);
185  decimal_t v = p(1);
186  decimal_t lambda_v = fabs(v) / mv;
187  if (lambda_v <= 1) continue;
188 
189  VirtualPoint vt;
190  vt.p = lambda_v;
191  vt.v = 0;
192  vt.t = tv + taus[id];
193  vs.push_back(vt);
194  }
195  }
196  }
197  }
198 
199  vs.push_back(vf);
200 
201  std::sort(
202  vs.begin(), vs.end(),
203  [](const VirtualPoint &i, const VirtualPoint &j) { return i.t < j.t; });
204  decimal_t max_l = 1;
205  for (const auto &v : vs) {
206  if (v.p > max_l) max_l = v.p;
207  }
208 
209  if (max_l <= 1) return false;
210 
211  // printf("max_l: %f\n", max_l);
212  for (int i = 1; i < (int)vs.size() - 1; i++) vs[i].p = max_l;
213  std::vector<VirtualPoint> vs_s;
214  vs_s.push_back(vs.front());
215  for (const auto &v : vs)
216  if (v.t > vs_s.back().t) vs_s.push_back(v);
217 
218  lambda_ = Lambda(vs_s);
219 
220  std::vector<decimal_t> ts;
221  for (const auto &tau : taus) ts.push_back(lambda_.getT(tau));
222  Ts = ts;
223  total_t_ = Ts.back();
224  return true;
225  }
226 
230  vec_E<Command<Dim>> sample(int N) const {
231  vec_E<Command<Dim>> ps(N + 1);
232 
233  decimal_t dt = total_t_ / N;
234  for (int i = 0; i <= N; i++) evaluate(i * dt, ps[i]);
235 
236  return ps;
237  }
238 
250  decimal_t J(const Control::Control &control) const {
251  decimal_t j = 0;
252  for (const auto &seg : segs) j += seg.J(control);
253  return j;
254  }
255 
262  decimal_t Jyaw() const {
263  decimal_t j = 0;
264  for (const auto &seg : segs) j += seg.Jyaw();
265  return j;
266  }
267 
269  std::vector<decimal_t> getSegmentTimes() const {
270  std::vector<decimal_t> dts;
271  for (int i = 0; i < (int)Ts.size() - 1; i++)
272  dts.push_back(Ts[i + 1] - Ts[i]);
273  return dts;
274  }
275 
279  if (segs.empty()) return ws;
280  decimal_t t = 0;
281  for (const auto &seg : segs) {
282  ws.push_back(seg.evaluate(0));
283  ws.back().t = t;
284  t += seg.t();
285  }
286  ws.push_back(segs.back().evaluate(segs.back().t()));
287  ws.back().t = t;
288  return ws;
289  }
290 
292  vec_E<Primitive<Dim>> getPrimitives() const { return segs; }
293 
297  Lambda lambda() const { return lambda_; }
298 
300  decimal_t getTotalTime() const { return total_t_; }
301 
305  std::vector<decimal_t> taus;
307  std::vector<decimal_t> Ts;
312 };
313 
316 
319 
320 #endif
Waypoint< Dim > evaluate(decimal_t time) const
Evaluate Waypoint at time .
Definition: trajectory.h:67
piecewise polynomial for scaling trajectory
Definition: lambda.h:73
Lambda lambda_
Scaling object.
Definition: trajectory.h:311
Primitive classes.
decimal_t yaw
yaw
Definition: trajectory.h:25
Vecf< Dim > acc
acceleration in
Definition: trajectory.h:23
decimal_t J(const Control::Control &control) const
Return total efforts of Primitive for the given duration: .
Definition: trajectory.h:250
vec_E< Primitive< Dim > > getPrimitives() const
Get Primitive array.
Definition: trajectory.h:292
Vecf< Dim > jrk
jerk in
Definition: waypoint.h:35
decimal_t yaw
yaw
Definition: waypoint.h:36
vec_E< Primitive< Dim > > segs
Segments of primitives.
Definition: trajectory.h:303
std::vector< decimal_t > taus
Time in virtual domain.
Definition: trajectory.h:305
std::vector< decimal_t > Ts
Time in actual domain.
Definition: trajectory.h:307
bool scale(decimal_t ri, decimal_t rf)
Scale according to ratio at start and end (velocity only)
Definition: trajectory.h:140
Waypoint base class.
Definition: waypoint.h:23
Command class.
Definition: trajectory.h:20
decimal_t getTotalTime() const
Get the total duration of Trajectory.
Definition: trajectory.h:300
std::vector< decimal_t > getSegmentTimes() const
Get time of each segment.
Definition: trajectory.h:269
Trajectory< 3 > Trajectory3D
Trajectory in 3D.
Definition: trajectory.h:318
Command< 2 > Command2D
Command 2D.
Definition: trajectory.h:31
Trajectory class.
Definition: trajectory.h:43
decimal_t total_t_
Total time of the trajectory.
Definition: trajectory.h:309
bool scale_down(decimal_t mv, decimal_t ri, decimal_t rf)
Scale down the whole trajectory according to mv.
Definition: trajectory.h:165
decimal_t power(decimal_t t, int n)
Return .
Definition: math.h:197
Control
Enum for control input.
Definition: control.h:10
vec_E< Waypoint< Dim > > getWaypoints() const
Get intermediate Waypoint on the trajectory.
Definition: trajectory.h:277
Vecf< Dim > acc
acceleration in
Definition: waypoint.h:34
std::vector< T, Eigen::aligned_allocator< T > > vec_E
Pre-allocated std::vector for Eigen using vec_E.
Definition: data_type.h:53
Lambda class.
Vecf< Dim > vel
velocity in
Definition: waypoint.h:33
Lambda lambda() const
Get the scaling factor Lambda.
Definition: trajectory.h:297
decimal_t yaw_dot
yaw velocity
Definition: trajectory.h:26
double decimal_t
Rename the float type used in lib.
Definition: data_type.h:49
Vecf< Dim > pos
position in
Definition: trajectory.h:21
Trajectory< 2 > Trajectory2D
Trajectory in 2D.
Definition: trajectory.h:315
Trajectory()
Empty constructor.
Definition: trajectory.h:48
vec_E< Command< Dim > > sample(int N) const
Sample N+1 Command along trajectory using uniformed time.
Definition: trajectory.h:230
Trajectory(const vec_E< Primitive< Dim >> &prs)
Construct from multiple primitives.
Definition: trajectory.h:52
Vecf< Dim > jrk
jerk in
Definition: trajectory.h:24
Used for scaling, ignored for most case.
Definition: lambda.h:16
Eigen::Matrix< decimal_t, N, 1 > Vecf
Eigen 1D float vector of size N.
Definition: data_type.h:56
Vecf< 4 > Vec4f
Eigen 1D float vector of size 4.
Definition: data_type.h:84
Primitive class.
Definition: primitive.h:206
Command< 3 > Command3D
Command 3D.
Definition: trajectory.h:34
Vecf< Dim > pos
position in
Definition: waypoint.h:32
Vecf< Dim > vel
velocity in
Definition: trajectory.h:22
bool evaluate(decimal_t time, Command< Dim > &p) const
Evaluate Command at , return false if fails to evaluate.
Definition: trajectory.h:99
decimal_t Jyaw() const
Return total yaw efforts for the given duration: .
Definition: trajectory.h:262