DesignerTrajectory.cpp
Go to the documentation of this file.
1 #include "DesignerTrajectory.h"
2 
3 #include <iostream>
4 using namespace std;
5 
6 using namespace armarx;
7 
8 VirtualRobot::RobotNodeSetPtr
9 DesignerTrajectory::getRns()
10 {
11  return rns;
12 }
13 
14 void
15 DesignerTrajectory::setRns(const VirtualRobot::RobotNodeSetPtr& value)
16 {
17  if (value != nullptr)
18  {
19  rns = value;
20  }
21  else
22  {
23  throw InvalidArgumentException("Can not set VirtualRobot::RobotNodeSetPtr rns = nullptr");
24  }
25 }
26 
27 std::vector<TrajectoryPtr>
28 DesignerTrajectory::getInterBreakpointTrajectories()
29 {
30  return interBreakpointTrajectories;
31 }
32 
33 void
34 DesignerTrajectory::setInterBreakpointTrajectories(const std::vector<TrajectoryPtr>& value)
35 {
36  if (value.size() != 0)
37  {
38  interBreakpointTrajectories = value;
39  }
40  else
41  {
42  throw InvalidArgumentException("Can not set std::vector<TrajectoryPtr> "
43  "interBreakpointTrajectories with empty vector ");
44  }
45 }
46 
48  VirtualRobot::RobotNodeSetPtr newRns)
49 {
50  if (newRns != nullptr)
51  {
52  rns = newRns;
53  }
54  else
55  {
56  throw InvalidArgumentException("Can not construct DesignerTrajectory with "
57  "VirtualRobot::RobotNodeSetPtr rns = nullptr");
58  }
59  if (firstPoint != nullptr)
60  {
61  addFirstUserWaypoint(firstPoint);
62  }
63  else
64  {
65  throw InvalidArgumentException(
66  "Can not construct DesignerTrajectory with UserWaypointPtr firstPoint = nullptr");
67  }
68 
69  std::vector<Ice::DoubleSeq> data;
70  std::vector<double> jointAngles = firstPoint->getJointAngles();
71  if (jointAngles.size() != 0)
72  {
73  //add jointAngles to every dimension
74  for (unsigned int i = 0; i < jointAngles.size(); i++)
75  {
76  data.push_back({jointAngles[i]});
77  }
78  }
79  else
80  {
81  throw InvalidArgumentException("firstPoint of a DesignerTrajectory must have jointAngles");
82  }
83  //firstPoint has eveytime timestamp 0
84  interBreakpointTrajectories.push_back(
85  TrajectoryPtr(new Trajectory(data, {0}, rns->getNodeNames())));
86 }
87 
88 DesignerTrajectory::DesignerTrajectory(const DesignerTrajectory& source) : rns(source.rns)
89 {
90  std::vector<TrajectoryPtr> trajectoriesTmp;
91  std::vector<UserWaypointPtr> userWaypointsTmp;
92  std::vector<TransitionPtr> transitionsTmp;
93 
94  for (TrajectoryPtr t : source.interBreakpointTrajectories)
95  {
96  trajectoriesTmp.push_back(TrajectoryPtr(new Trajectory(*t)));
97  }
98 
99 
100  for (UserWaypointPtr w : source.userWaypoints)
101  {
102  userWaypointsTmp.push_back(UserWaypointPtr(new UserWaypoint(*w)));
103  }
104 
105  for (unsigned int i = 0; i < userWaypointsTmp.size() - 1; i++)
106  {
107  UserWaypointPtr start = userWaypointsTmp[i];
108  UserWaypointPtr end = userWaypointsTmp[i + 1];
109  TransitionPtr trans = source.transitions[i];
110 
111  transitionsTmp.push_back(TransitionPtr(new Transition(*trans, start, end)));
112  }
113 
114  userWaypoints = userWaypointsTmp;
115  interBreakpointTrajectories = trajectoriesTmp;
116  transitions = transitionsTmp;
117 }
118 
119 void
121 {
122  if (point != nullptr)
123  {
124  userWaypoints.insert(userWaypoints.begin(), point);
125 
126  if (userWaypoints.size() > 1)
127  {
128  transitions.insert(transitions.begin(),
129  TransitionPtr(new Transition(userWaypoints[0], userWaypoints[1])));
130  }
131  }
132  else
133  {
134  throw InvalidArgumentException("Can not add UserWaypoint with point = nullptr");
135  }
136 }
137 
138 void
140 {
141  if (point != nullptr)
142  {
143  userWaypoints.push_back(point);
144  if (userWaypoints.size() > 1)
145  {
146  transitions.push_back(TransitionPtr(new Transition(
147  userWaypoints[userWaypoints.size() - 2], userWaypoints[userWaypoints.size() - 1])));
148  }
149  }
150  else
151  {
152  throw InvalidArgumentException("Can not add UserWaypoint with point = nullptr");
153  }
154 }
155 
156 void
158 {
159  if (point != nullptr)
160  {
161  if (index != 0 && index < userWaypoints.size())
162  {
163  userWaypoints.insert(userWaypoints.begin() + index, point);
164 
165  if (userWaypoints.size() > 1)
166  {
167  transitions.insert(
168  transitions.begin() + index - 1,
169  TransitionPtr(new Transition(userWaypoints[index - 1], userWaypoints[index])));
170  transitions[index]->setStart(userWaypoints[index]);
171  }
172  }
173  else
174  {
175  if (index == 0)
176  {
177  addFirstUserWaypoint(point);
178  }
179  else
180  {
181  throw IndexOutOfBoundsException("insertUserWaypoint");
182  }
183  }
184  }
185  else
186  {
187  throw InvalidArgumentException("Can not add UserWaypoint with point = nullptr");
188  }
189 }
190 
191 void
193 {
194  if (index < userWaypoints.size())
195  {
196  userWaypoints.erase(userWaypoints.begin() + index);
197  //delete first waypoint
198  if (index == 0)
199  {
200  transitions.erase(transitions.begin());
201  }
202  //delete last Waypoint
203  else if (index == transitions.size())
204  {
205  transitions.erase(transitions.begin() + index - 1);
206  }
207  else
208  {
209  transitions.erase(transitions.begin() + index);
210  transitions.erase(transitions.begin() + index - 1);
211  transitions.insert(transitions.begin() + index - 1,
212  std::shared_ptr<Transition>(
213  new Transition(userWaypoints[index - 1], userWaypoints[index])));
214  }
215  }
216  else
217  {
218  throw IndexOutOfBoundsException("deleteUserWaypoint");
219  }
220 }
221 
222 unsigned int
224 {
225  return userWaypoints.size();
226 }
227 
230 {
231  if (index < userWaypoints.size())
232  {
233  return userWaypoints[index];
234  }
235  else
236  {
237  throw IndexOutOfBoundsException("getUserWaypoint");
238  }
239 }
240 
243 {
244  if (index < transitions.size())
245  {
246  return transitions[index];
247  }
248  else
249  {
250  throw IndexOutOfBoundsException();
251  }
252 }
253 
256 {
257  std::vector<Ice::DoubleSeq> dimensionDatas = getDimensionDatas();
258  Ice::DoubleSeq timestamps = getAllTimestamps();
260  dimensionDatas, timestamps, interBreakpointTrajectories[0]->getDimensionNames()));
261  setLimitless(tmp, rns);
262 
263  return tmp;
264 }
265 
268 {
269  if (index < interBreakpointTrajectories.size())
270  {
271  return interBreakpointTrajectories[index];
272  }
273  else
274  {
275  throw IndexOutOfBoundsException();
276  }
277 }
278 
279 std::vector<UserWaypointPtr>
281 {
282  std::vector<UserWaypointPtr> tmp;
283 
284  for (unsigned int i = 0; i < userWaypoints.size(); i++)
285  {
286  tmp.push_back(UserWaypointPtr(new UserWaypoint(*userWaypoints[i])));
287  }
288  return tmp;
289 }
290 
291 std::vector<UserWaypointPtr>
293 {
294  return userWaypoints;
295 }
296 
299 {
300  if (userWaypoints.size() > 1)
301  {
302 
303  std::vector<Ice::DoubleSeq> dimensionDatas = getDimensionDatas();
304  std::vector<double> timestamps = getAllTimestamps();
305 
306  double tmpDif = 0;
307  unsigned int count = 0;
308  for (unsigned int i = 0; i < transitions.size() - 1; i++)
309  {
310  TransitionPtr t = transitions[i];
311  double stretch = t->getUserDuration() / t->getTimeOptimalDuration();
312  unsigned int start = count;
313  //search for the index which represents the end of the transition
314  double endTime = t->getEnd()->getTimeOptimalTimestamp();
315  while (count + 1 < timestamps.size() && endTime > timestamps[count + 1])
316  {
317  count++;
318  }
319  unsigned int end = count;
320  for (unsigned int k = start; k < end; k++)
321  {
322  timestamps[k + 1] = timestamps[k + 1] + tmpDif;
323  double oldDuration = timestamps[k + 1] - timestamps[k];
324  double newDuration = oldDuration * stretch;
325  tmpDif = tmpDif + newDuration - oldDuration;
326  timestamps[k + 1] = timestamps[k] + newDuration;
327  }
328  }
329  //last transition
330  TransitionPtr t = transitions.back();
331  double stretch = t->getUserDuration() / t->getTimeOptimalDuration();
332  unsigned int start = count;
333  unsigned int end = timestamps.size() - 1;
334  for (unsigned int k = start; k < end; k++)
335  {
336  timestamps[k + 1] = timestamps[k + 1] + tmpDif;
337  double oldDuration = timestamps[k + 1] - timestamps[k];
338  double newDuration = (timestamps[k + 1] - timestamps[k]) * stretch;
339  tmpDif = tmpDif + newDuration - oldDuration;
340  timestamps[k + 1] = timestamps[k] + newDuration;
341  }
343  dimensionDatas, timestamps, interBreakpointTrajectories[0]->getDimensionNames()));
344  setLimitless(traj, rns);
345  return traj;
346  }
347  else
348  {
349  return interBreakpointTrajectories[0];
350  }
351 }
352 
353 //////////////private/////////////////////////////////////////////////////////////////////
354 std::vector<std::vector<double>>
355 DesignerTrajectory::getDimensionDatas()
356 {
357  std::vector<Ice::DoubleSeq> dimensionDatas;
358 
359  if (interBreakpointTrajectories.size() != 0)
360  {
361  //just for the first point
362  for (unsigned int i = 0; i < interBreakpointTrajectories[0]->dim(); i++)
363  {
364  //get the JointAngle of the first point at current dimension
365  dimensionDatas.push_back({interBreakpointTrajectories[0]->getDimensionData(i)[0]});
366  }
367 
368  //through all trajectories
369  for (const TrajectoryPtr& t : interBreakpointTrajectories)
370  {
371  //through all dimensions
372  unsigned int dimension = t->dim();
373  for (unsigned int i = 0; i < dimension; i++)
374  {
375  //get all jointAngles
376  std::vector<double> newDatas = t->getDimensionData(i);
377  dimensionDatas[i].insert(
378  dimensionDatas[i].end(), newDatas.begin() + 1, newDatas.end());
379  }
380  }
381  return dimensionDatas;
382  }
383  else
384  {
385  throw LogicError("No inter breakpoint trajectories");
386  }
387 }
388 
389 std::vector<double>
390 DesignerTrajectory::getAllTimestamps()
391 {
392  std::vector<double> timestamps;
393 
394  if (interBreakpointTrajectories.size() != 0)
395  {
396  //first timestamp
397  timestamps.push_back(interBreakpointTrajectories[0]->getTimestamps()[0]);
398  //through all trajectories
399  for (const TrajectoryPtr& t : interBreakpointTrajectories)
400  {
401  double d = timestamps.back();
402  std::vector<double> newTimestamps = t->getTimestamps();
403  for (unsigned int i = 1; i < newTimestamps.size(); i++)
404  {
405  timestamps.push_back(newTimestamps[i] + d);
406  }
407  }
408  return timestamps;
409  }
410  else
411  {
412  throw LogicError("No inter breakpoint trajectories");
413  }
414 }
415 
416 void
417 DesignerTrajectory::setLimitless(TrajectoryPtr traj, VirtualRobot::RobotNodeSetPtr rns)
418 {
419  //set Limitless state for smooth interpolation
420  LimitlessStateSeq states;
421  for (VirtualRobot::RobotNodePtr node : rns->getAllRobotNodes())
422  {
423  LimitlessState state;
424  state.enabled = node->isLimitless();
425  state.limitLo = node->getJointLimitLow();
426  state.limitHi = node->getJointLimitHigh();
427  states.push_back(state);
428  }
429  traj->setLimitless(states);
430 }
armarx::UserWaypointPtr
std::shared_ptr< UserWaypoint > UserWaypointPtr
Definition: UserWaypoint.h:142
armarx::DesignerTrajectory::getNrOfUserWaypoints
unsigned int getNrOfUserWaypoints() const
get the number of the userwaypoints
Definition: DesignerTrajectory.cpp:223
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::DesignerTrajectory::getAllUserWaypoints
std::vector< UserWaypointPtr > getAllUserWaypoints() const
get a copy of all userwaypoints
Definition: DesignerTrajectory.cpp:280
armarx::DesignerTrajectory::addFirstUserWaypoint
void addFirstUserWaypoint(UserWaypointPtr &point)
add a new first userWaypoint
Definition: DesignerTrajectory.cpp:120
armarx::UserWaypoint
The UserWaypoint class represents a waypoint of the trajectory.
Definition: UserWaypoint.h:47
armarx::DesignerTrajectory
Definition: DesignerTrajectory.h:36
armarx::DesignerTrajectory::getTimeOptimalTrajectory
TrajectoryPtr getTimeOptimalTrajectory()
get the time optimal trajectory.
Definition: DesignerTrajectory.cpp:255
DesignerTrajectory.h
IceInternal::Handle< Trajectory >
armarx::DesignerTrajectory::deleteUserWaypoint
void deleteUserWaypoint(unsigned int index)
delete the userwaypoint and remove all transitions including the userwaypoint.
Definition: DesignerTrajectory.cpp:192
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::DesignerTrajectory::getTransition
TransitionPtr getTransition(unsigned int index)
get the transition
Definition: DesignerTrajectory.cpp:242
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::DesignerTrajectory::DesignerTrajectory
DesignerTrajectory(UserWaypointPtr &firstPoint, VirtualRobot::RobotNodeSetPtr newRns)
Definition: DesignerTrajectory.cpp:47
armarx::TransitionPtr
std::shared_ptr< Transition > TransitionPtr
Definition: Transition.h:143
armarx::Transition
Definition: Transition.h:36
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:661
armarx::DesignerTrajectory::getFinalTrajectory
TrajectoryPtr getFinalTrajectory()
get the final trajectory with the right durations
Definition: DesignerTrajectory.cpp:298
armarx::DesignerTrajectory::getUserWaypoint
UserWaypointPtr getUserWaypoint(unsigned int index)
get the userWaypoint
Definition: DesignerTrajectory.cpp:229
armarx::TrajectoryPtr
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition: Trajectory.h:52
armarx::VariantType::Trajectory
const VariantTypeId Trajectory
Definition: Trajectory.h:44
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
armarx::DesignerTrajectory::getTrajectorySegment
TrajectoryPtr getTrajectorySegment(unsigned int index)
get one interBreakPoint trajectory
Definition: DesignerTrajectory.cpp:267
std
Definition: Application.h:66
armarx::DesignerTrajectory::addLastUserWaypoint
void addLastUserWaypoint(UserWaypointPtr &point)
add new last userWaypoint
Definition: DesignerTrajectory.cpp:139
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::DesignerTrajectory::insertUserWaypoint
void insertUserWaypoint(UserWaypointPtr &point, unsigned int index)
insert userwaypoint before index
Definition: DesignerTrajectory.cpp:157