HEBI C++ API  3.15.0
goal.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <Eigen/Dense>
4 #include "trajectory.hpp"
5 
6 namespace hebi {
7 namespace arm {
8 
9 // A class that specifies a goal position of one or more waypoint and/or
10 // auxilary states.
11 // Static create methods are provided for various cases; in the case that
12 // velocities or accelerations are omitted, the default behavior is to leave
13 // these unconstrained except for a final "0" state. For aux states, this is
14 // left as unchanged. For times, this is left to the Arm object to fill in a
15 // heuristic.
16 class Goal {
17 
18 public:
20  // Single waypoint static create functions
22 
23  // Single waypoint, default vel/accel, no time
24  static Goal createFromPosition(const Eigen::VectorXd& positions) {
25  return Goal(Eigen::VectorXd(0),
26  toMatrix(positions),
27  nanWithZeroRight(positions.size(), 1),
28  nanWithZeroRight(positions.size(), 1),
29  Eigen::MatrixXd(0, 0));
30  }
31 
32  // Single waypoint, default vel/accel
33  static Goal createFromPosition(double time, const Eigen::VectorXd& positions) {
34  return Goal(toVector(time),
35  toMatrix(positions),
36  nanWithZeroRight(positions.size(), 1),
37  nanWithZeroRight(positions.size(), 1),
38  Eigen::MatrixXd(0, 0));
39  }
40 
41  // Single waypoint, no time
42  static Goal createFromWaypoint(const Eigen::VectorXd& positions,
43  const Eigen::VectorXd& velocities,
44  const Eigen::VectorXd& accelerations) {
45  return Goal(Eigen::VectorXd(0),
46  toMatrix(positions),
47  toMatrix(velocities),
48  toMatrix(accelerations),
49  Eigen::MatrixXd(0, 0));
50  }
51 
52  // Single waypoint
53  static Goal createFromWaypoint(double time,
54  const Eigen::VectorXd& positions,
55  const Eigen::VectorXd& velocities,
56  const Eigen::VectorXd& accelerations) {
57  return Goal(toVector(time),
58  toMatrix(positions),
59  toMatrix(velocities),
60  toMatrix(accelerations),
61  Eigen::MatrixXd(0, 0));
62  }
63 
64  // Single waypoints + aux state, no time
65  static Goal createFromWaypointWithAux(const Eigen::VectorXd& positions,
66  const Eigen::VectorXd& velocities,
67  const Eigen::VectorXd& accelerations,
68  const Eigen::VectorXd& aux) {
69  return Goal(Eigen::VectorXd(0),
70  toMatrix(positions),
71  toMatrix(velocities),
72  toMatrix(accelerations),
73  toMatrix(aux));
74  }
75 
76  // Single waypoints + aux state
77  static Goal createFromWaypointWithAux(double time,
78  const Eigen::VectorXd& positions,
79  const Eigen::VectorXd& velocities,
80  const Eigen::VectorXd& accelerations,
81  const Eigen::VectorXd& aux) {
82  return Goal(toVector(time),
83  toMatrix(positions),
84  toMatrix(velocities),
85  toMatrix(accelerations),
86  toMatrix(aux));
87  }
88 
90  // Multiple waypoint static create functions
92 
93  // Multiple waypoints, default vel/accel, no time
94  static Goal createFromPositions(const Eigen::MatrixXd& positions) {
95  return Goal(Eigen::VectorXd(0),
96  positions,
97  nanWithZeroRight(positions.rows(), positions.cols()),
98  nanWithZeroRight(positions.rows(), positions.cols()),
99  Eigen::MatrixXd(0, 0));
100  }
101 
102  // Multiple waypoints, default vel/accel
103  static Goal createFromPositions(const Eigen::VectorXd& times,
104  const Eigen::MatrixXd& positions) {
105  return Goal(times,
106  positions,
107  nanWithZeroRight(positions.rows(), positions.cols()),
108  nanWithZeroRight(positions.rows(), positions.cols()),
109  Eigen::MatrixXd(0, 0));
110  }
111 
112  // Multiple waypoints, no time
113  static Goal createFromWaypoints(const Eigen::MatrixXd& positions,
114  const Eigen::MatrixXd& velocities,
115  const Eigen::MatrixXd& accelerations) {
116  return Goal(Eigen::VectorXd(0),
117  positions,
118  velocities,
120  Eigen::MatrixXd(0, 0));
121  }
122 
123  // Multiple waypoints
124  static Goal createFromWaypoints(const Eigen::VectorXd& times,
125  const Eigen::MatrixXd& positions,
126  const Eigen::MatrixXd& velocities,
127  const Eigen::MatrixXd& accelerations) {
128  return Goal(times,
129  positions,
130  velocities,
132  Eigen::MatrixXd(0, 0));
133  }
134 
135  // Multiple waypoints + aux state, no time
136  static Goal createFromWaypointsWithAux(const Eigen::MatrixXd& positions,
137  const Eigen::MatrixXd& velocities,
138  const Eigen::MatrixXd& accelerations,
139  const Eigen::MatrixXd& aux) {
140  return Goal(Eigen::VectorXd(0),
141  positions,
142  velocities,
144  aux);
145  }
146 
147  // Multiple waypoints + aux state
148  static Goal createFromWaypointsWithAux(const Eigen::VectorXd& times,
149  const Eigen::MatrixXd& positions,
150  const Eigen::MatrixXd& velocities,
151  const Eigen::MatrixXd& accelerations,
152  const Eigen::MatrixXd& aux) {
153  return Goal(times,
154  positions,
155  velocities,
157  aux);
158  }
159 
160  const Eigen::VectorXd& times() const { return times_; }
161  const Eigen::MatrixXd& positions() const { return positions_; }
162  const Eigen::MatrixXd& velocities() const { return velocities_; }
163  const Eigen::MatrixXd& accelerations() const { return accelerations_; }
164  const Eigen::MatrixXd& aux() const { return aux_; }
165 
166  // Build a trajectory that is continuous from the current arm state
167  // If "start_vel" is null, assumed to be zero
168  // If "start_acc" is null, assumed to be zero
169  std::tuple<std::shared_ptr<hebi::trajectory::Trajectory>, Eigen::MatrixXd, Eigen::VectorXd> buildTrajectoryFrom(const Eigen::VectorXd& start_pos, const Eigen::VectorXd* start_vel, const Eigen::VectorXd* start_accel) const {
170 
171  // Note -- in future, we can call heuristics from API here
172  auto getWaypointTimes = [](const Eigen::MatrixXd& positions, const Eigen::MatrixXd& /*velocities*/,
173  const Eigen::MatrixXd& /*accelerations*/) {
174  double rampTime = 1.2;
175 
176  size_t num_waypoints = positions.cols();
177 
178  Eigen::VectorXd times(num_waypoints);
179  for (size_t i = 0; i < num_waypoints; ++i)
180  times[i] = rampTime * (double)i;
181 
182  return times;
183  };
184 
185  const auto num_joints = positions_.rows();
186  auto num_waypoints = positions_.cols() + 1;
187  if (start_pos.size() != num_joints) {
188  throw std::invalid_argument("start positions size must match number of joints in Goal object");
189  } else if (start_vel != nullptr && start_vel->size() != num_joints) {
190  throw std::invalid_argument("start velocities size must match number of joints in Goal object");
191  } else if (start_accel != nullptr && start_accel->size() != num_joints) {
192  throw std::invalid_argument("start accelerations size must match number of joints in Goal object");
193  }
194 
195  // Start with provided velocity and acceleration, or default to zero
196  Eigen::VectorXd curr_vel = Eigen::VectorXd::Zero(num_joints);
197  Eigen::VectorXd curr_accel = Eigen::VectorXd::Zero(num_joints);
198  if (start_vel)
199  curr_vel = *start_vel;
200  if (start_accel)
201  curr_accel = *start_accel;
202 
203  Eigen::MatrixXd positions(num_joints, num_waypoints);
204  Eigen::MatrixXd velocities(num_joints, num_waypoints);
205  Eigen::MatrixXd accelerations(num_joints, num_waypoints);
206 
207  // Initial state
208  positions.col(0) = start_pos;
209  velocities.col(0) = curr_vel;
210  accelerations.col(0) = curr_accel;
211 
212  // Copy new waypoints
213  positions.rightCols(num_waypoints - 1) = positions_;
214  velocities.rightCols(num_waypoints - 1) = velocities_;
215  accelerations.rightCols(num_waypoints - 1) = accelerations_;
216 
217  // Get waypoint times
218  Eigen::VectorXd waypoint_times(num_waypoints);
219  // If time vector is empty, automatically determine times
220  if (times_.size() == 0) {
221  waypoint_times = getWaypointTimes(positions, velocities, accelerations); // TODO: reference??!?
222  } else {
223  waypoint_times(0) = 0;
224  waypoint_times.tail(num_waypoints - 1) = times_;
225  }
226 
227  // Create new trajectory
228  auto trajectory =
230 
231  Eigen::MatrixXd aux(0,0);
232  Eigen::VectorXd aux_times(0);
233 
234  // Update aux state:
235  if (aux_.rows() > 0 && (aux_.cols() + 1) == num_waypoints) {
236  aux.resize(aux_.rows(), aux_.cols() + 1);
237  aux.col(0).setConstant(std::numeric_limits<double>::quiet_NaN());
238  aux.rightCols(num_waypoints - 1) = aux_;
239  aux_times = waypoint_times;
240  }
241 
242  return {trajectory, aux, aux_times};
243  }
244 
245 private:
246 
247  Goal(const Eigen::VectorXd& times,
248  const Eigen::MatrixXd& positions,
249  const Eigen::MatrixXd& velocities,
250  const Eigen::MatrixXd& accelerations,
251  const Eigen::MatrixXd& aux)
252  : times_(times),
253  positions_(positions),
254  velocities_(velocities),
255  accelerations_(accelerations),
256  aux_(aux) {
257  if (positions_.rows() != velocities_.rows() || positions_.rows() != accelerations_.rows() ||
258  positions_.cols() != velocities_.cols() || positions_.cols() != accelerations_.cols())
259  throw std::invalid_argument("Goal must have consistent position/velocity/acceleration sizes");
260  if (aux_.cols() != 0 && positions_.cols() != aux_.cols())
261  throw std::invalid_argument("Goal must have empty aux or aux consistent with number of waypoints");
262  }
263 
264  // Helper function to create unconstrained points along a motion, with nan at the right side.
265  static Eigen::MatrixXd nanWithZeroRight(size_t num_joints, size_t num_waypoints) {
266  double nan = std::numeric_limits<double>::quiet_NaN();
267  Eigen::MatrixXd matrix(num_joints, num_waypoints);
268  matrix.setConstant(nan);
269  matrix.rightCols<1>().setZero();
270  return matrix;
271  }
272 
273  static Eigen::VectorXd toVector(double scalar) {
274  Eigen::VectorXd vector(1);
275  vector[0] = scalar;
276  return vector;
277  }
278 
279  static Eigen::MatrixXd toMatrix(const Eigen::VectorXd& vector) {
280  Eigen::MatrixXd matrix(vector.size(), 1);
281  matrix.col(0) = vector;
282  return matrix;
283  }
284 
285  const Eigen::VectorXd times_{0};
286  const Eigen::MatrixXd positions_{0, 0};
287  const Eigen::MatrixXd velocities_{0, 0};
288  const Eigen::MatrixXd accelerations_{0, 0};
289  const Eigen::MatrixXd aux_{0, 0};
290 };
291 
292 } // namespace arm
293 } // namespace hebi
static Goal createFromPositions(const Eigen::VectorXd &times, const Eigen::MatrixXd &positions)
Definition: goal.hpp:103
static Goal createFromWaypoint(const Eigen::VectorXd &positions, const Eigen::VectorXd &velocities, const Eigen::VectorXd &accelerations)
Definition: goal.hpp:42
static Goal createFromWaypoint(double time, const Eigen::VectorXd &positions, const Eigen::VectorXd &velocities, const Eigen::VectorXd &accelerations)
Definition: goal.hpp:53
Definition: arm.cpp:10
const Eigen::MatrixXd & positions() const
Definition: goal.hpp:161
static Goal createFromWaypointWithAux(double time, const Eigen::VectorXd &positions, const Eigen::VectorXd &velocities, const Eigen::VectorXd &accelerations, const Eigen::VectorXd &aux)
Definition: goal.hpp:77
static Goal createFromPosition(const Eigen::VectorXd &positions)
Definition: goal.hpp:24
static Goal createFromWaypointsWithAux(const Eigen::VectorXd &times, const Eigen::MatrixXd &positions, const Eigen::MatrixXd &velocities, const Eigen::MatrixXd &accelerations, const Eigen::MatrixXd &aux)
Definition: goal.hpp:148
Definition: arm.cpp:11
static Goal createFromWaypointsWithAux(const Eigen::MatrixXd &positions, const Eigen::MatrixXd &velocities, const Eigen::MatrixXd &accelerations, const Eigen::MatrixXd &aux)
Definition: goal.hpp:136
static Goal createFromWaypoints(const Eigen::VectorXd &times, const Eigen::MatrixXd &positions, const Eigen::MatrixXd &velocities, const Eigen::MatrixXd &accelerations)
Definition: goal.hpp:124
std::tuple< std::shared_ptr< hebi::trajectory::Trajectory >, Eigen::MatrixXd, Eigen::VectorXd > buildTrajectoryFrom(const Eigen::VectorXd &start_pos, const Eigen::VectorXd *start_vel, const Eigen::VectorXd *start_accel) const
Definition: goal.hpp:169
const Eigen::VectorXd & times() const
Definition: goal.hpp:160
const Eigen::MatrixXd & accelerations() const
Definition: goal.hpp:163
const Eigen::MatrixXd & aux() const
Definition: goal.hpp:164
static Goal createFromPositions(const Eigen::MatrixXd &positions)
Definition: goal.hpp:94
static Goal createFromWaypoints(const Eigen::MatrixXd &positions, const Eigen::MatrixXd &velocities, const Eigen::MatrixXd &accelerations)
Definition: goal.hpp:113
static Goal createFromPosition(double time, const Eigen::VectorXd &positions)
Definition: goal.hpp:33
static std::shared_ptr< Trajectory > createUnconstrainedQp(const Eigen::VectorXd &time_vector, const Eigen::MatrixXd &positions, const Eigen::MatrixXd *velocities=nullptr, const Eigen::MatrixXd *accelerations=nullptr)
Creates a smooth trajectory through a set of waypoints (position velocity and accelerations defined a...
Definition: trajectory.cpp:17
Definition: goal.hpp:16
const Eigen::MatrixXd & velocities() const
Definition: goal.hpp:162
static Goal createFromWaypointWithAux(const Eigen::VectorXd &positions, const Eigen::VectorXd &velocities, const Eigen::VectorXd &accelerations, const Eigen::VectorXd &aux)
Definition: goal.hpp:65