abb2400_ikfast_tests.cpp
Go to the documentation of this file.
2 OPW_IGNORE_WARNINGS_PUSH
3 #include <gtest/gtest.h> // IWYU pragma: keep
4 #include <cstdlib> // for abs, size_t
5 #include <array> // for array
6 #include <cmath> // for fmod, M_PI, isnan
7 #include <iomanip> // for operator<<, setp...
8 #include <iostream> // for operator<<, basi...
9 #include <vector> // for vector
10 #include "ikfast.h"
11 OPW_IGNORE_WARNINGS_POP
12 
13 #include "opw_kinematics/opw_kinematics.h" // IWYU pragma: keep
14 #include "opw_kinematics/opw_utilities.h" // IWYU pragma: keep
15 #include "opw_kinematics/opw_parameters_examples.h" // for makeIrb2400_10
16 
19 
21 {
22  PoseGenerator() { index = 0; }
23 
25  {
26  const static int width = 100;
27  int y = index % width;
28  int z = index / width;
29 
30  Transform p = Transform::Identity();
31  p.translation() = Eigen::Vector3d(0.75, y * 0.01 - 0.5, 0.5 + z * 0.01);
32 
33  index++;
34 
35  return p;
36  }
37 
38  int index;
39 };
40 
42 {
43  double eetrans[3];
44  double eerot[9];
45  double* pfree = nullptr;
46 
47  eetrans[0] = p.translation().x();
48  eetrans[1] = p.translation().y();
49  eetrans[2] = p.translation().z();
50 
51  for (int i = 0; i < 3; ++i)
52  {
53  for (int j = 0; j < 3; ++j)
54  {
55  eerot[i * 3 + j] = p.matrix()(i, j);
56  }
57  }
58 
59  ComputeIk(eetrans, eerot, pfree, sols);
60 }
61 
63 {
64  return opw_kinematics::inverse(param, p);
65 }
66 
67 std::size_t countValidSolutions(const Solutions& opw)
68 {
69  std::size_t count = 0;
70  for (const auto& s : opw)
71  {
73  count++;
74  }
75  return count;
76 }
77 
84 static inline double normalize_angle_positive(double angle)
85 {
86  return fmod(fmod(angle, 2.0 * M_PI) + 2.0 * M_PI, 2.0 * M_PI);
87 }
88 
96 static inline double normalize_angle(double angle)
97 {
98  double a = normalize_angle_positive(angle);
99  if (a > M_PI)
100  a -= 2.0 * M_PI;
101  return a;
102 }
103 
116 static inline double shortest_angular_distance(double from, double to) { return normalize_angle(to - from); }
117 
118 bool findSolInSet(const std::array<double, 6>& s, const Solutions& opw)
119 {
120  for (std::size_t i = 0; i < 8; ++i)
121  {
122  bool is_same = true;
123  for (std::size_t j = 0; j < 6; ++j)
124  {
125  double value = opw[i][j];
126  // if (value > M_PI) value -= 2*M_PI;
127  // if (value < -M_PI) value += 2*M_PI;
128  double diff = std::abs(shortest_angular_distance(s[j], value));
129  if (diff > 1e-6)
130  {
131  is_same = false;
132  break;
133  }
134  }
135  if (is_same)
136  return true;
137  }
138  return false;
139 }
140 
141 void printResults(const Solutions& sols)
142 {
143  std::cout << std::setprecision(5) << std::fixed;
144  for (const auto& s : sols)
145  {
146  for (std::size_t i = 0; i < 6; ++i)
147  std::cout << s[i] << " ";
148  std::cout << "\n";
149  }
150 }
151 
153 {
154  auto num_ikf_sols = ikf.GetNumSolutions();
155  auto num_opw_sols = countValidSolutions(opw);
156 
157  bool equal_num = num_ikf_sols == num_opw_sols;
158  EXPECT_TRUE(equal_num);
159 
160  if (!equal_num)
161  return;
162 
163  // lets compare solutions
164  std::array<double, 6> v;
165  for (decltype(num_ikf_sols) i = 0; i < num_ikf_sols; ++i)
166  {
167  ikf.GetSolution(i).GetSolution(v.data(), nullptr);
168  const bool found_sol_in_opw = findSolInSet(v, opw);
169  EXPECT_TRUE(found_sol_in_opw);
170  if (!found_sol_in_opw)
171  {
172  std::cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << " " << v[5] << "\n";
173 
174  printResults(opw);
175  }
176  }
177 }
178 
179 TEST(ikfast_to_opw, similar_solutions) // NOLINT
180 {
181  // IK-Fast is implicitly instantiated
182 
183  // Make OPW model
184  const auto abb2400 = opw_kinematics::makeIrb2400_10<double>();
185 
186  // Create a pose generator
187  PoseGenerator gen;
188 
189  for (int i = 0; i < 40000; ++i)
190  {
191  Transform p = gen();
192 
193  // Solve with IKFast
195  solveIKFast(p, ikf_sols);
196 
197  // Solve with OPW
198  Solutions opw_sols = solveOPW(abb2400, p);
199 
200  // Compare
201  compare(ikf_sols, opw_sols);
202  }
203 }
204 
205 int main(int argc, char** argv)
206 {
207  testing::InitGoogleTest(&argc, argv);
208  return RUN_ALL_TESTS();
209 }
PoseGenerator
Definition: abb2400_ikfast_tests.cpp:20
ikfast::IkSolutionList
Default implementation of IkSolutionListBase.
Definition: ikfast.h:261
opw_kinematics::isValid
bool isValid(const std::array< T, 6 > &qs)
Definition: opw_utilities.h:10
ComputeIk
IKFAST_API bool ComputeIk(const IkReal *eetrans, const IkReal *eerot, const IkReal *pfree, IkSolutionListBase< IkReal > &solutions)
Definition: abb_irb2400_manipulator_ikfast_solver.cpp:3205
compare
void compare(ikfast::IkSolutionList< double > &ikf, Solutions &opw)
Definition: abb2400_ikfast_tests.cpp:152
opw_kinematics::Transform
Eigen::Transform< T, 3, Eigen::Isometry > Transform
Definition: opw_kinematics.h:15
ikfast::IkSolutionList::GetNumSolutions
virtual size_t GetNumSolutions() const
returns the number of solutions stored
Definition: ikfast.h:282
opw_kinematics.h
PoseGenerator::PoseGenerator
PoseGenerator()
Definition: abb2400_ikfast_tests.cpp:22
Transform
opw_kinematics::Transform< double > Transform
Definition: abb2400_ikfast_tests.cpp:17
normalize_angle_positive
static double normalize_angle_positive(double angle)
normalize_angle_positive
Definition: abb2400_ikfast_tests.cpp:84
opw_kinematics::Solutions
std::array< std::array< T, 6 >, 8 > Solutions
Definition: opw_kinematics.h:22
Solutions
opw_kinematics::Solutions< double > Solutions
Definition: abb2400_ikfast_tests.cpp:18
opw_utilities.h
ikfast.h
countValidSolutions
std::size_t countValidSolutions(const Solutions &opw)
Definition: abb2400_ikfast_tests.cpp:67
findSolInSet
bool findSolInSet(const std::array< double, 6 > &s, const Solutions &opw)
Definition: abb2400_ikfast_tests.cpp:118
printResults
void printResults(const Solutions &sols)
Definition: abb2400_ikfast_tests.cpp:141
TEST
TEST(ikfast_to_opw, similar_solutions)
Definition: abb2400_ikfast_tests.cpp:179
ikfast::IkSolutionList::GetSolution
virtual const IkSolutionBase< T > & GetSolution(size_t index) const
returns the solution pointer
Definition: ikfast.h:271
normalize_angle
static double normalize_angle(double angle)
normalize
Definition: abb2400_ikfast_tests.cpp:96
PoseGenerator::index
int index
Definition: abb2400_ikfast_tests.cpp:38
solveOPW
Solutions solveOPW(const opw_kinematics::Parameters< double > &param, const Transform &p)
Definition: abb2400_ikfast_tests.cpp:62
main
int main(int argc, char **argv)
Definition: abb2400_ikfast_tests.cpp:205
opw_kinematics::inverse
Solutions< T > inverse(const Parameters< T > &params, const Transform< T > &pose) noexcept
Computes up to 8 kinematically unique joint solutions that put the tool flange of the robot described...
Definition: opw_kinematics_impl.h:113
opw_parameters_examples.h
opw_macros.h
solveIKFast
void solveIKFast(const Transform &p, ikfast::IkSolutionList< double > &sols)
Definition: abb2400_ikfast_tests.cpp:41
opw_kinematics::Parameters
Definition: opw_parameters.h:10
shortest_angular_distance
static double shortest_angular_distance(double from, double to)
shortest_angular_distance
Definition: abb2400_ikfast_tests.cpp:116
PoseGenerator::operator()
Transform operator()()
Definition: abb2400_ikfast_tests.cpp:24


opw_kinematics
Author(s): Jon Meyer , Jeroen De Maeyer
autogenerated on Thu Jan 16 2025 03:40:37