37 #include <boost/thread/barrier.hpp> 45 std::function<void(size_t)> fun;
46 std::vector<std::thread> threads;
47 boost::barrier barrier;
55 , threads(thread_count)
57 , barrier(thread_count)
59 for(
size_t i = 1; i < thread_count; i++)
61 std::thread t([
this, i]() {
71 std::swap(t, threads[i]);
78 for(
auto& t : threads)
79 if(t.joinable()) t.join();
93 std::vector<std::unique_ptr<IKSolver>> solvers;
94 std::vector<std::vector<double>> solver_solutions;
95 std::vector<std::vector<double>> solver_temps;
96 std::vector<int> solver_success;
97 std::vector<double> solver_fitness;
102 std::atomic<int> finished;
103 std::atomic<uint32_t> iteration_count;
104 std::vector<double> result;
105 std::unique_ptr<ParallelExecutor> par;
114 std::string name = params.solver_class_name;
116 enable_counter = params.enable_counter;
119 solvers.emplace_back(IKFactory::create(name, params));
120 thread_count = solvers.front()->concurrency();
121 if(params.thread_count) {
122 thread_count = params.thread_count;
124 while(solvers.size() < thread_count)
125 solvers.emplace_back(IKFactory::clone(solvers.front().get()));
126 for(
size_t i = 0; i < thread_count; i++)
127 solvers[i]->thread_index = i;
132 solver_solutions.resize(thread_count);
133 solver_temps.resize(thread_count);
134 solver_success.resize(thread_count);
135 solver_fitness.resize(thread_count);
138 par.reset(
new ParallelExecutor(thread_count, [
this](
size_t i) { solverthread(i); }));
141 void initialize(
const Problem& problem)
143 this->problem = problem;
148 void solverthread(
size_t i)
150 THREADPROFILER(
"thread", i);
151 COUNTERPROFILER(
"solver threads");
155 BLOCKPROFILER(
"ik solver init");
156 solvers[i]->initialize(problem);
160 for(
size_t iteration = 0; (ros::WallTime::now().toSec() < timeout && finished == 0) || (iteration == 0 && i == 0); iteration++)
167 for(
int it2 = 1; it2 < 4; it2++)
168 if(ros::WallTime::now().toSec() < timeout && finished == 0) solvers[i]->step();
173 auto& result = solver_temps[i];
174 result = solvers[i]->getSolution();
175 auto& fk = solvers[i]->model;
176 fk.applyConfiguration(result);
177 bool success = solvers[i]->checkSolution(result, fk.getTipFrames());
178 if(success) finished = 1;
179 solver_success[i] = success;
180 solver_solutions[i] = result;
181 solver_fitness[i] = solvers[i]->computeFitness(result, fk.getTipFrames());
188 for(
auto& s : solvers)
195 BLOCKPROFILER(
"solve mt");
199 result = problem.initial_guess;
200 timeout = problem.timeout;
203 for(
auto& s : solver_solutions)
204 s = problem.initial_guess;
205 for(
auto& s : solver_temps)
206 s = problem.initial_guess;
207 for(
auto& s : solver_success)
209 for(
auto& f : solver_fitness)
211 for(
auto& s : solvers)
216 BLOCKPROFILER(
"solve mt 2");
220 size_t best_index = 0;
221 best_fitness = DBL_MAX;
224 for(
size_t i = 0; i < thread_count; i++)
226 if(solver_success[i])
229 if(solvers[0]->problem.secondary_goals.empty())
233 fitness = solver_fitness[i];
239 fitness = solver_fitness[i] + solvers[0]->computeSecondaryFitnessAllVariables(solver_solutions[i]);
241 if(fitness < best_fitness)
243 best_fitness = fitness;
251 if(best_fitness == DBL_MAX)
253 for(
size_t i = 0; i < thread_count; i++)
255 if(solver_fitness[i] < best_fitness)
257 best_fitness = solver_fitness[i];
265 LOG(
"iterations", iteration_count);
268 result = solver_solutions[best_index];
269 success = solver_success[best_index];
272 double getSolutionFitness()
const {
return best_fitness; }
274 bool getSuccess()
const {
return success; }
276 const std::vector<double>& getSolution()
const {
return result; }