DesignerTrajectoryCalculator.cpp
Go to the documentation of this file.
2
3#include <VirtualRobot/TimeOptimalTrajectory/Path.h>
4
6
7#include "PathFactory.h"
9
10#define TRAJECTORYCALCULATION_TIMESTEP 0.001
11
16
19 std::vector<std::vector<double>>& trajectory,
20 std::vector<std::vector<double>>& userPoints,
21 VirtualRobot::RobotNodeSetPtr rns,
22 double maxDeviation,
23 double accuracyFactor)
24{
25 //ARMARX_INFO << "Entering calculation";
26 //ARMARX_INFO << trajectory.size() << " jointangles in trajectory";
27 //Check if the Robot has the used RobotNodeSet
28 if (!environment->getRobot()->hasRobotNodeSet(rns))
29 {
30 throw InvalidArgumentException("Robot does not have the supplied robotnodeset!");
31 }
32 //Create a Simox VirtualRobot Path. This is later used to calculate the TimeOptimalTrajectory
33 VirtualRobot::Path path = armarx::PathFactory::createPath(trajectory, maxDeviation);
34 //If all points are equal, create a trajectory with minimal duration and the respective start and end points
35 //ARMARX_INFO << "Path length is " << path.getLength();
36 if (path.getLength() == 0)
37 {
38 //If the path length is 0, create a pseudo trajectory containing the start position once for every userPoint
39 std::vector<double> timestamps;
40 //ARMARX_INFO << "Filling timestamps";
41 for (unsigned int i = 0; i < userPoints.size(); i++)
42 {
43 timestamps.push_back(0.01 * i);
44 }
45
46 //add first point
47 std::vector<std::vector<double>> nodeData;
48 for (unsigned int i = 0; i < userPoints[0].size(); i++)
49 {
50 nodeData.push_back({userPoints[0][i]});
51 }
52 for (unsigned int i = 1; i < userPoints.size(); i++)
53 {
54 for (unsigned int j = 0; j < userPoints[0].size(); j++)
55 {
56 nodeData[j].push_back(userPoints[i][j]);
57 }
58 }
59
60 Ice::StringSeq dimensionNames = rns->getNodeNames();
61 TrajectoryPtr traj = new Trajectory(nodeData, timestamps, dimensionNames);
62 return TimedTrajectory(traj, timestamps);
63 }
64 //Get the maxVelocity and maxAcceleration for every joint
65 //If the path length is 0, create a pseudo trajectory containing the start position once for every userPoint
66
67
68 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
69 /// CREATE TRAJECTORY TO UNFOLD
70 ///
71 ///
72 std::vector<double> timestamps = std::vector<double>();
73 for (unsigned int j = 0; j < trajectory.size(); j++)
74 {
75 timestamps.push_back(j * 0.01);
76 }
77 std::vector<std::vector<double>> nodeData = std::vector<std::vector<double>>();
78 for (unsigned int i = 0; i < rns->getAllRobotNodes().size(); i++)
79 {
80 std::vector<double> node = std::vector<double>();
81 for (unsigned int j = 0; j < trajectory.size(); j++)
82 {
83 node.push_back(trajectory[j][i]);
84 }
85 nodeData.push_back(node);
86 }
87 //ARMARX_INFO << trajectory;
88 Ice::StringSeq dimensionNames = rns->getNodeNames();
89 TrajectoryPtr traj = new Trajectory(nodeData, timestamps, dimensionNames);
90 //ARMARX_INFO << traj;
91 //ARMARX_INFO << std::to_string(traj->getLength());
92 LimitlessStateSeq state;
93 for (VirtualRobot::RobotNodePtr node : rns->getAllRobotNodes())
94 {
95 LimitlessState current;
96 current.enabled = node->isLimitless();
97 current.limitLo = node->getJointLimitLow();
98 current.limitHi = node->getJointLimitHigh();
99 state.push_back(current);
100 }
101 traj->setLimitless(state);
103 //ARMARX_INFO << "UNFOLDED";
104 //TURN TRAJECTORY BACK TO VECTOR
105 std::vector<std::vector<double>> newPathVector = std::vector<std::vector<double>>();
106 //ARMARX_INFO << std::to_string(traj->getLength());
107 //ARMARX_ERROR << traj->toEigen();
108 Eigen::MatrixXd trajMatrix = traj->toEigen();
109 for (int i = 0; i < trajMatrix.rows(); i++)
110 {
111 //ARMARX_INFO << "Trying to get state at " + std::to_string(i * 0.01);
112 std::vector<double> jA = std::vector<double>();
113 for (int j = 0; j < trajMatrix.cols(); j++)
114 {
115 jA.push_back(trajMatrix(i, j));
116 }
117 //ARMARX_INFO << jA;
118 newPathVector.push_back(jA);
119 }
120 //ARMARX_INFO << newPathVector;
121 VirtualRobot::Path unfoldedPath = armarx::PathFactory::createPath(newPathVector, maxDeviation);
122 //ARMARX_INFO << "FINISHED";
123 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
124 std::vector<double> mVelocity;
125 std::vector<double> mAcceleration;
126 for (VirtualRobot::RobotNodePtr rn : rns->getAllRobotNodes())
127 {
128 if (rn->getMaxVelocity() == -1.0)
129 {
130 mVelocity.push_back(10);
131 }
132 else
133 {
134 mVelocity.push_back(rn->getMaxVelocity());
135 }
136 if (rn->getMaxAcceleration() == -1.0)
137 {
138 mAcceleration.push_back(10);
139 }
140 else
141 {
142 mAcceleration.push_back(rn->getMaxAcceleration());
143 }
144 }
145 const Eigen::VectorXd maxVelocity = Eigen::VectorXd::Map(&mVelocity[0], mVelocity.size());
146 const Eigen::VectorXd maxAcceleration =
147 Eigen::VectorXd::Map(&mAcceleration[0], mAcceleration.size());
148 //Set the timestep to the trajectorycalculation timestep constant for now
149 double timeStep = TRAJECTORYCALCULATION_TIMESTEP;
150
151 //Calculate the TimeOptimalTrajectory using Simox, and bring the accuracyFactor into account
152 //ARMARX_INFO << "Calling Simox TimeOptimalTrajectory";
153 VirtualRobot::TimeOptimalTrajectory timeOptimalTrajectory = VirtualRobot::TimeOptimalTrajectory(
154 unfoldedPath, maxVelocity, maxAcceleration, timeStep / accuracyFactor);
155 //If simox failed finding a trajectory, signal this
156 if (timeOptimalTrajectory.isValid() == 0)
157 {
158 //ARMARX_INFO << "Invalid trajectory";
159 throw InvalidArgumentException("Input trajectory can not generate a continuous path");
160 }
161 //As simox sometimes returns valid on trajectories with nonreal or negative duration, check this too
162 if (timeOptimalTrajectory.getDuration() <= 0 ||
163 std::isnan(timeOptimalTrajectory.getDuration()) ||
164 timeOptimalTrajectory.getDuration() >= HUGE_VAL)
165 {
166 //ARMARX_INFO << "Invalid trajectory duration";
167 throw InvalidArgumentException(
168 "Input trajectory can not generate a continuous path with positive real duration");
169 }
170 //ARMARX_INFO << "TimeOptimalTrajectory has duration of " << timeOptimalTrajectory.getDuration();
171 //Return the result
173 timeOptimalTrajectory, userPoints, rns, maxDeviation);
174}
#define TRAJECTORYCALCULATION_TIMESTEP
TimedTrajectory calculateTimeOptimalTrajectory(std::vector< std::vector< double > > &trajectory, std::vector< std::vector< double > > &userPoints, VirtualRobot::RobotNodeSetPtr rns, double maxDeviation, double accuracyFactor=1.0)
Calculates a TimedTrajectory from the supplied trajectory and points set by user.
static VirtualRobot::Path createPath(std::vector< std::vector< double > > &nodes, double maxDeviation)
Creates a Path out of the nodes with a maximum deviation.
static TimedTrajectory createTimedTrajectory(VirtualRobot::TimeOptimalTrajectory &trajectory, std::vector< std::vector< double > > &userPoints, VirtualRobot::RobotNodeSetPtr rns, double maxDeviation)
Creates a TimedTrajectory out of the TimeOptimalTrajectory and maps the parameter userPoints to it.
A container for a Trajectory and a set of timestamps, representing the arrival of the Trajectory at u...
static void UnfoldLimitlessJointPositions(TrajectoryPtr traj)
The Trajectory class represents n-dimensional sampled trajectories.
Definition Trajectory.h:77
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
std::shared_ptr< Environment > EnvironmentPtr
Definition Environment.h:29