bio_ik
MoveIt kinematics_base plugin based on particle optimization & GA
ik_base.h
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2016-2017, Philipp Sebastian Ruppel
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 #pragma once
36 
37 #include <bio_ik/goal.h>
38 
39 #include "forward_kinematics.h"
40 #include "problem.h"
41 #include "utils.h"
42 #include <bio_ik/robot_info.h>
43 
44 #include <random>
45 
46 namespace bio_ik
47 {
48 
49 struct Random
50 {
51  // std::mt19937 rng;
52  std::minstd_rand rng;
53  // std::ranlux24 rng;
54  // std::knuth_b rng;
55  // std::default_random_engine rng;
56 
57  inline double random() { return std::uniform_real_distribution<double>(0, 1)(rng); }
58 
59  inline std::size_t random_index(std::size_t s) { return std::uniform_int_distribution<size_t>(0, s - 1)(rng); }
60 
61  std::normal_distribution<double> normal_distribution;
62  inline double random_gauss() { return normal_distribution(rng); }
63 
64  inline double random(double min, double max) { return random() * (max - min) + min; }
65 
66  template <class e> inline e& random_element(std::vector<e>& l) { return l[random_index(l.size())]; }
67 
68  template <class e> inline const e& random_element(const std::vector<e>& l) { return l[random_index(l.size())]; }
69 
70  XORShift64 _xorshift;
71  inline size_t fast_random_index(size_t mod) { return _xorshift() % mod; }
72  template <class T> inline const T& fast_random_element(const std::vector<T>& v) { return v[fast_random_index(v.size())]; }
73 
74  static const size_t random_buffer_size = 1024 * 1024 * 8;
75 
76  const double* make_random_buffer()
77  {
78  static std::vector<double> buf;
79  buf.resize(random_buffer_size);
80  for(auto& r : buf)
81  r = random();
82  return buf.data();
83  }
84  const double* random_buffer;
85  size_t random_buffer_index;
86  inline double fast_random()
87  {
88  double r = random_buffer[random_buffer_index & (random_buffer_size - 1)];
89  random_buffer_index++;
90  return r;
91  }
92 
93  const double* make_random_gauss_buffer()
94  {
95  // LOG("make_random_gauss_buffer");
96  static std::vector<double> buf;
97  buf.resize(random_buffer_size);
98  for(auto& r : buf)
99  r = random_gauss();
100  return buf.data();
101  }
102  const double* random_gauss_buffer;
103  size_t random_gauss_index;
104  inline double fast_random_gauss()
105  {
106  double r = random_gauss_buffer[random_gauss_index & (random_buffer_size - 1)];
107  random_gauss_index++;
108  return r;
109  }
110  inline const double* fast_random_gauss_n(size_t n)
111  {
112  size_t i = random_gauss_index;
113  random_gauss_index += n;
114  if(random_gauss_index >= random_buffer_size) i = 0, random_gauss_index = n;
115  return random_gauss_buffer + i;
116  }
117 
118  Random()
119  : rng(std::random_device()())
120  {
121  random_buffer = make_random_buffer();
122  random_buffer_index = _xorshift();
123  random_gauss_buffer = make_random_gauss_buffer();
124  random_gauss_index = _xorshift();
125  }
126 };
127 
128 struct IKBase : Random
129 {
130  IKParams params;
131  RobotFK model;
132  RobotInfo modelInfo;
133  int thread_index;
134  Problem problem;
135  std::vector<Frame> null_tip_frames;
136  volatile int canceled;
137 
138  virtual void step() = 0;
139 
140  virtual const std::vector<double>& getSolution() const = 0;
141 
142  virtual void setParams(const IKParams& p) {}
143 
144  IKBase(const IKParams& p)
145  : model(p.robot_model)
146  , modelInfo(p.robot_model)
147  , params(p)
148  {
149  setParams(p);
150  }
151  virtual ~IKBase() {}
152 
153  virtual void initialize(const Problem& problem)
154  {
155  this->problem = problem;
156  this->problem.initialize2();
157  model.initialize(problem.tip_link_indices);
158  // active_variables = problem.active_variables;
159  null_tip_frames.resize(problem.tip_link_indices.size());
160  }
161 
162  double computeSecondaryFitnessActiveVariables(const double* active_variable_positions) { return problem.computeGoalFitness(problem.secondary_goals, null_tip_frames.data(), active_variable_positions); }
163 
164  double computeSecondaryFitnessAllVariables(const std::vector<double>& variable_positions) { return computeSecondaryFitnessActiveVariables(extractActiveVariables(variable_positions)); }
165 
166  double computeFitnessActiveVariables(const std::vector<Frame>& tip_frames, const double* active_variable_positions) { return problem.computeGoalFitness(problem.goals, tip_frames.data(), active_variable_positions); }
167 
168  double computeFitnessActiveVariables(const aligned_vector<Frame>& tip_frames, const double* active_variable_positions) { return problem.computeGoalFitness(problem.goals, tip_frames.data(), active_variable_positions); }
169 
170  double computeCombinedFitnessActiveVariables(const std::vector<Frame>& tip_frames, const double* active_variable_positions)
171  {
172  double ret = 0.0;
173  ret += problem.computeGoalFitness(problem.goals, tip_frames.data(), active_variable_positions);
174  ret += problem.computeGoalFitness(problem.secondary_goals, null_tip_frames.data(), active_variable_positions);
175  return ret;
176  }
177 
178  double computeCombinedFitnessActiveVariables(const aligned_vector<Frame>& tip_frames, const double* active_variable_positions)
179  {
180  double ret = 0.0;
181  ret += problem.computeGoalFitness(problem.goals, tip_frames.data(), active_variable_positions);
182  ret += problem.computeGoalFitness(problem.secondary_goals, null_tip_frames.data(), active_variable_positions);
183  return ret;
184  }
185 
186  bool checkSolutionActiveVariables(const std::vector<Frame>& tip_frames, const double* active_variable_positions) { return problem.checkSolutionActiveVariables(tip_frames, active_variable_positions); }
187 
188  bool checkSolution(const std::vector<double>& variable_positions, const std::vector<Frame>& tips) { return checkSolutionActiveVariables(tips, extractActiveVariables(variable_positions)); }
189 
190  std::vector<double> temp_active_variable_positions;
191 
192  double* extractActiveVariables(const std::vector<double>& variable_positions)
193  {
194  temp_active_variable_positions.resize(problem.active_variables.size());
195  for(size_t i = 0; i < temp_active_variable_positions.size(); i++)
196  temp_active_variable_positions[i] = variable_positions[problem.active_variables[i]];
197  return temp_active_variable_positions.data();
198  }
199 
200  double computeFitness(const std::vector<double>& variable_positions, const std::vector<Frame>& tip_frames) { return computeFitnessActiveVariables(tip_frames, extractActiveVariables(variable_positions)); }
201 
202  double computeFitness(const std::vector<double>& variable_positions)
203  {
204  model.applyConfiguration(variable_positions);
205  return computeFitness(variable_positions, model.getTipFrames());
206  }
207 
208  virtual size_t concurrency() const { return 1; }
209 };
210 
211 typedef IKBase IKSolver;
212 
214 }