TimedTrajectoryFactory.cpp
Go to the documentation of this file.
2
4
5#define TIMEDTRAJECTORY_PROBEFACTOR 100
6
7#define TIMEDTRAJECTORY_FPS 100
8
11 VirtualRobot::TimeOptimalTrajectory& trajectory,
12 std::vector<std::vector<double>>& userPoints,
13 VirtualRobot::RobotNodeSetPtr rns,
14 double maxDeviation)
15
16{
17 //ARMARX_INFO << "Creating timedTrajectory";
18 //Check if the RobotNodeSet exists
19 if (rns == NULL)
20 {
21 //ARMARX_INFO << "Rns is null";
22 throw InvalidArgumentException("Rns is null");
23 }
24 //Check if the RobotNodeSet has nodes
25 if (rns->getAllRobotNodes().size() == 0)
26 {
27 //ARMARX_INFO << "Nodeset has no nodes";
28 throw InvalidArgumentException("Rns is empty");
29 }
30
31 //Tune the timing parameter here
32 double timestep = 1 / ((double)(TIMEDTRAJECTORY_FPS));
33 //timestep may not be 0!
34 timestep = (timestep > 0) ? timestep : 0.01;
35 //If the trajectory is shorter than a second, generate as many frames as you would in a second
36 //(this guarantees that the probing is within the trajectory interval (timestep could otherwise be bigger)
37 if (trajectory.getDuration() < 1)
38 {
39 timestep = trajectory.getDuration() / TIMEDTRAJECTORY_FPS;
40 }
41
42 std::vector<double> timestamps;
43 //std::vector<double> timestamps2;
44 //Nodedata is a vector containing the vectors of ALL positions at the respective timestamps for each joint.
45 //(Outer dimension : joints, Inner dimension: timestamp index)
46 std::vector<std::vector<double>> nodeData;
47 std::vector<std::vector<double>> nodeData2;
48
49 //Initialize the vectors for the respective joints, fill in the first timestamp (0)
50 timestamps.push_back(0);
51 //timestamps2.push_back(0);
52 for (unsigned int i = 0; i < rns->getSize(); i++)
53 {
54 nodeData.push_back({trajectory.getPosition(0)[i]});
55 //nodeData2.push_back({trajectory.getPosition(0)[i]});
56 }
57 //Fill in the data for all other timestamps into the now existing joint values
58 for (double t = timestep; t < trajectory.getDuration(); t += timestep)
59 {
60 Eigen::VectorXd positions = trajectory.getPosition(t);
61 //Eigen::VectorXd positions2 = trajectory.getPosition(t);
62 for (unsigned int i = 0; i < positions.size(); i++)
63 {
64 nodeData[i].push_back(positions[i]);
65 //nodeData2[i].push_back(positions2[i]);
66 }
67 //ARMARX_INFO << "Time : " << t;
68 timestamps.push_back(t);
69 //timestamps2.push_back(t);
70 }
71 LimitlessStateSeq state;
72 for (VirtualRobot::RobotNodePtr node : rns->getAllRobotNodes())
73 {
74 LimitlessState current;
75 current.enabled = node->isLimitless();
76 current.limitLo = node->getJointLimitLow();
77 current.limitHi = node->getJointLimitHigh();
78 state.push_back(current);
79 }
80 //Get the correct names for the dimensions
81 Ice::StringSeq dimensionNames = rns->getNodeNames();
82 //Ice::StringSeq dimensionNames2 = rns->getNodeNames();
83 //ARMARX_WARNING << "HELLO";
84 //Construct the armarx Trajectory from the given data
85
86 TrajectoryPtr traj = new Trajectory(nodeData, timestamps, dimensionNames);
87 traj->setLimitless(state);
88 //TrajectoryPtr original = new Trajectory(nodeData2, timestamps2, dimensionNames2);
90 /*int markedJoint = -1;
91 bool positive = false;
92 double start = 0;
93 for (double d : traj->getTimestamps())
94 {
95 Ice::DoubleSeq newStates = traj->getStates(d, 0);
96 Ice::DoubleSeq oldStates = original->getStates(d, 0);
97 int c = 0;
98 for (double f : newStates)
99 {
100 if ((f > 3.1 || f < -3.1) && rns->getAllRobotNodes()[c]->isLimitless())
101 {
102 ARMARX_ERROR << "Difference spotted " + std::to_string(f);
103
104 markedJoint = c;
105 start = d;
106 if (f > 0)
107 {
108 positive = true;
109 }
110 }
111 if (c == markedJoint)
112 {
113 if (positive && f < -3.1 || !positive && f > 3.1)
114 {
115 traj = cutTrajectory(traj, start, d);
116 }
117 }
118 c++;
119 }
120 }*/
121 //ARMARX_ERROR << traj->toEigen();
122 int pass = 1;
123 //Arbitrary interrupt condition
124 for (pass = 1; pass < 10; pass++)
125 {
126
127 std::vector<double> times;
128 unsigned int i = 0;
129 //Map the user Points to the respective timestamps that their position is approximately reached within
130 for (double t = 0; t < trajectory.getDuration();
131 t += timestep / TIMEDTRAJECTORY_PROBEFACTOR)
132 {
133 Eigen::VectorXd jointAngles =
134 Eigen::VectorXd::Map(&userPoints[i][0], userPoints[i].size());
135 /*for (int i = 0; i < jointAngles.rows(); i++)
136 {
137 ARMARX_INFO << "Point" << i << "jointAngles [" << i << "] : " << jointAngles[i];
138 }*/
139 Eigen::VectorXd pointJointAngles = trajectory.getPosition(t);
140 /*
141 for (int i = 0; i < pointJointAngles.rows(); i++)
142
143 {
144 ARMARX_INFO << "Point" << i << "pointJointAngles [" << i << "] : " << pointJointAngles[i];
145 }*/
146 const double distance = (jointAngles - pointJointAngles).norm();
147 //ARMARX_INFO << "Distance " << distance;
148 //ARMARX_INFO << "MaxDeviation " << deviation;
149 //If the deviation between the userPoint and the data at the respective point is smaller than the maxDeviation, map it
150 if (distance <= maxDeviation)
151 {
152 times.push_back(t);
153 //ARMARX_INFO << std::to_string(t);
154 i++;
155 //ARMARX_INFO << "MAPPING USER POINT" << i;
156 if (i >= userPoints.size())
157 {
158 //ARMARX_INFO << "mapping last user point";
159 //For the last point, just add the final time of the trajectory as the respective timestamp
160 //this can help mitigate the resulting forward drift of timestamps caused by the inaccuracy (maxDeviation)
161 times.pop_back();
162 times.push_back(trajectory.getDuration());
163 break;
164 }
165 }
166 }
167 //ARMARX_INFO << "Userpoint mapping complete";
168 //ARMARX_INFO << "TimedTrajectory complete";
169 //If not all points were mapped, an output is created and an empty map is returned for the userPoints
170 if (times.size() < userPoints.size())
171 {
172 //Try to solve with recursively decreasing accuracy
173 //ARMARX_INFO << "Only " << times.size() << "of " << userPoints.size() << " points found";
174 //ARMARX_INFO << "Pass " << pass << " failed to find all points.";
175 maxDeviation *= 10;
176 //timestep /= 2;
177 continue;
178 }
179 //Return the result and the number of passes that were needed for the calculation
180 pass == 1 ? ARMARX_INFO << pass << " pass needed to find mapping"
181 : ARMARX_INFO << pass << " passes needed to find mapping";
182 return TimedTrajectory(traj, times);
183 }
184 ARMARX_INFO << "More than" << pass << "passes needed for calculation";
185 //ARMARX_INFO << "Canceled calculation with maxDeviation of " << maxDeviation;
186 throw InvalidArgumentException("No TimedTrajectory could be created");
187}
#define TIMEDTRAJECTORY_PROBEFACTOR
#define TIMEDTRAJECTORY_FPS
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 FoldLimitlessJointPositions(TrajectoryPtr traj)
The Trajectory class represents n-dimensional sampled trajectories.
Definition Trajectory.h:77
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
double norm(const Point &a)
Definition point.hpp:102
double distance(const Point &a, const Point &b)
Definition point.hpp:95