abb2400_ikfast_tests.cpp
Go to the documentation of this file.
2 OPW_IGNORE_WARNINGS_PUSH
3 #include <gtest/gtest.h>
4 #include <array>
5 #include "ikfast.h"
6 OPW_IGNORE_WARNINGS_POP
7 
10 
12 
14 {
16  {
17  index = 0;
18  }
19 
21  {
22  const static int width = 100;
23  int y = index % width;
24  int z = index / width;
25 
26  Transform p = Transform::Identity();
27  p.translation() = Eigen::Vector3d(0.75, y * 0.01 - 0.5, 0.5 + z * 0.01);
28 
29  index++;
30 
31  return p;
32  }
33 
34  int index;
35 };
36 
38 {
39  double eetrans[3];
40  double eerot[9];
41  double* pfree = nullptr;
42 
43  eetrans[0] = p.translation().x();
44  eetrans[1] = p.translation().y();
45  eetrans[2] = p.translation().z();
46 
47  for (int i = 0; i < 3; ++i)
48  {
49  for (int j = 0; j < 3; ++j)
50  {
51  eerot[i * 3 + j] = p.matrix()(i,j);
52  }
53  }
54 
55  ComputeIk(eetrans, eerot, pfree, sols);
56 }
57 
59  std::array<double, 6 * 8>& sols)
60 {
61  opw_kinematics::inverse(param, p, sols.data());
62 }
63 
64 size_t countValidSolutions(const std::array<double, 6 * 8>& opw)
65 {
66  std::size_t count = 0;
67  for (int i = 0; i < 8; ++i)
68  {
69  bool is_valid = true;
70  for (int j = 0; j < 6; ++j)
71  {
72  if (std::isnan(opw[i * 6 + j]))
73  {
74  is_valid = false;
75  break;
76  }
77  }
78  if (is_valid) count++;
79  }
80  return count;
81 }
82 
83 
90 static inline double normalize_angle_positive(double angle)
91 {
92  return fmod(fmod(angle, 2.0*M_PI) + 2.0*M_PI, 2.0*M_PI);
93 }
94 
95 
103 static inline double normalize_angle(double angle)
104 {
105  double a = normalize_angle_positive(angle);
106  if (a > M_PI)
107  a -= 2.0 *M_PI;
108  return a;
109 }
110 
111 
124 static inline double shortest_angular_distance(double from, double to)
125 {
126  return normalize_angle(to-from);
127 }
128 
129 
130 bool findSolInSet(const std::vector<double>& s, const std::array<double, 6 * 8>& opw)
131 {
132  for (int i = 0; i < 8; ++i)
133  {
134  bool is_same = true;
135  for (int j = 0; j < 6; ++j)
136  {
137  double value = opw[i*6 + j];
138 // if (value > M_PI) value -= 2*M_PI;
139 // if (value < -M_PI) value += 2*M_PI;
140  double diff = std::abs(shortest_angular_distance(s[j], value));
141  if (diff > 1e-6)
142  {
143  is_same = false;
144  break;
145  }
146  }
147  if (is_same) return true;
148  }
149  return false;
150 }
151 
152 void printResults(const std::array<double, 6 * 8>& sols)
153 {
154  std::cout << std::setprecision(5) << std::fixed;
155  for (int i = 0; i < 8; ++i)
156  {
157  for (int j = 0; j < 6; ++j)
158  std::cout << sols[i * 6 + j] << " ";
159  std::cout << "\n";
160  }
161 }
162 
163 void compare(ikfast::IkSolutionList<double>& ikf, std::array<double, 6 * 8>& opw)
164 {
165  auto num_ikf_sols = ikf.GetNumSolutions();
166  auto num_opw_sols = countValidSolutions(opw);
167 
168  bool equal_num = num_ikf_sols == num_opw_sols;
169  EXPECT_TRUE(equal_num);
170 
171  if (!equal_num) return;
172 
173  // lets compare solutions
174  std::vector<double> v (6);
175  for (decltype(num_ikf_sols) i = 0; i < num_ikf_sols; ++i)
176  {
177  ikf.GetSolution(i).GetSolution(v.data(), nullptr);
178  const bool found_sol_in_opw = findSolInSet(v, opw);
179  EXPECT_TRUE(found_sol_in_opw);
180  if (!found_sol_in_opw)
181  {
182  std::cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << " "
183  << v[5] << "\n";
184 
185  printResults(opw);
186  }
187  }
188 
189 }
190 
191 TEST(ikfast_to_opw, similar_solutions)
192 {
193  // IK-Fast is implicitly instantiated
194 
195  // Make OPW model
196  const auto abb2400 = opw_kinematics::makeIrb2400_10<double>();
197 
198  // Create a pose generator
199  PoseGenerator gen;
200 
201  for (int i = 0; i < 40000; ++i)
202  {
203  Transform p = gen();
204 
205  // Solve with IKFast
207  solveIKFast(p, ikf_sols);
208 
209  // Solve with OPW
210  std::array<double, 6 * 8> opw_sols;
211  solveOPW(abb2400, p, opw_sols);
212 
213  // Compare
214  compare(ikf_sols, opw_sols);
215  }
216 }
217 
218 
219 int main(int argc, char **argv)
220 {
221  testing::InitGoogleTest(&argc, argv);
222  return RUN_ALL_TESTS();
223 }
virtual const IkSolutionBase< T > & GetSolution(size_t index) const
returns the solution pointer
Definition: ikfast.h:239
void solveOPW(const opw_kinematics::Parameters< double > &param, const Transform &p, std::array< double, 6 *8 > &sols)
void compare(ikfast::IkSolutionList< double > &ikf, std::array< double, 6 *8 > &opw)
virtual size_t GetNumSolutions() const
returns the number of solutions stored
Definition: ikfast.h:249
void solveIKFast(const Transform &p, ikfast::IkSolutionList< double > &sols)
static double normalize_angle_positive(double angle)
normalize_angle_positive
size_t countValidSolutions(const std::array< double, 6 *8 > &opw)
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
TEST(ikfast_to_opw, similar_solutions)
#define M_PI
void printResults(const std::array< double, 6 *8 > &sols)
double y
IKFAST_API bool ComputeIk(const IkReal *eetrans, const IkReal *eerot, const IkReal *pfree, IkSolutionListBase< IkReal > &solutions)
int main(int argc, char **argv)
double z
static double shortest_angular_distance(double from, double to)
shortest_angular_distance
bool findSolInSet(const std::vector< double > &s, const std::array< double, 6 *8 > &opw)
Eigen::Transform< T, 3, Eigen::Isometry > Transform
Default implementation of IkSolutionListBase.
Definition: ikfast.h:229
static double normalize_angle(double angle)
normalize
void inverse(const Parameters< T > &params, const Transform< T > &pose, T *out) noexcept
Computes up to 8 kinematically unique joint solutions that put the tool flange of the robot described...
#define EXPECT_TRUE(args)
opw_kinematics::Transform< double > Transform


moveit_opw_kinematics_plugin
Author(s): Jeroen De Maeyer, Simon Schmeisser (isys vision)
autogenerated on Wed Jun 3 2020 03:17:14