- 3.0.2 optimal control module.
NLOCBackendMP-impl.hpp
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4  **********************************************************************************************************************/
5 
6 
7 #pragma once
8 
9 namespace ct {
10 namespace optcon {
11 
12 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
14  const OptConProblem_t& optConProblem,
15  const NLOptConSettings& settings)
16  : Base(optConProblem, settings)
17 {
18  startupRoutine();
19 }
20 
21 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
23  const OptConProblem_t& optConProblem,
24  const std::string& settingsFile,
25  bool verbose,
26  const std::string& ns)
27  : Base(optConProblem, settingsFile, verbose, ns)
28 {
29  startupRoutine();
30 }
31 
32 
33 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
35 {
36  shutdownRoutine();
37 }
38 
39 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
41 {
42  launchWorkerThreads();
43 }
44 
45 
46 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
48 {
49  workersActive_ = false;
50  workerTask_ = SHUTDOWN;
51  workerWakeUpCondition_.notify_all();
52 
53 #ifdef DEBUG_PRINT_MP
54  std::cout << "Shutting down workers" << std::endl;
55 #endif // DEBUG_PRINT_MP
56 
57  for (size_t i = 0; i < workerThreads_.size(); i++)
58  {
59  workerThreads_[i].join();
60  }
61 
62 #ifdef DEBUG_PRINT_MP
63  std::cout << "All workers shut down" << std::endl;
64 #endif // DEBUG_PRINT_MP
65 }
66 
67 
68 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
70 {
71 #ifdef DEBUG_PRINT_MP
72  printString("[Thread " + std::to_string(threadId) + "]: launched");
73 #endif // DEBUG_PRINT_MP
74 
75 
76  // local variables
77  int workerTask_local = IDLE;
78  size_t uniqueProcessID = 0;
79  size_t iteration_local = this->iteration_;
80  size_t lqpCounter_local = this->lqpCounter_;
81 
82 
83  while (workersActive_)
84  {
85  workerTask_local = workerTask_.load();
86  iteration_local = this->iteration_;
87  lqpCounter_local = this->lqpCounter_;
88 
89 #ifdef DEBUG_PRINT_MP
90  printString("[Thread " + std::to_string(threadId) + "]: previous procId: " + std::to_string(uniqueProcessID) +
91  ", current procId: " +
92  std::to_string(generateUniqueProcessID(iteration_local, (int)workerTask_local, lqpCounter_local)));
93 #endif
94 
95 
101  if (workerTask_local == IDLE ||
102  uniqueProcessID == generateUniqueProcessID(iteration_local, (int)workerTask_local, lqpCounter_local))
103  {
104 #ifdef DEBUG_PRINT_MP
105  printString("[Thread " + std::to_string(threadId) + "]: going to sleep !");
106 #endif
107 
108  // sleep until the state is not IDLE any more and we have a different process ID than before
109  std::unique_lock<std::mutex> waitLock(workerWakeUpMutex_);
110  while (workerTask_ == IDLE || (uniqueProcessID == generateUniqueProcessID(this->iteration_,
111  (int)workerTask_.load(), this->lqpCounter_)))
112  {
113  workerWakeUpCondition_.wait(waitLock);
114  }
115  waitLock.unlock();
116 
117  workerTask_local = workerTask_.load();
118  iteration_local = this->iteration_;
119  lqpCounter_local = this->lqpCounter_;
120 
121 #ifdef DEBUG_PRINT_MP
122  printString("[Thread " + std::to_string(threadId) + "]: woke up !");
123 #endif // DEBUG_PRINT_MP
124  }
125 
126  if (!workersActive_)
127  {
128 #ifdef DEBUG_PRINT_MP
129  printString("Breaking - workers are not active !");
130 #endif // DEBUG_PRINT_MP
131  break;
132  }
133 
134 
135  switch (workerTask_local)
136  {
137  case LINE_SEARCH:
138  {
139 #ifdef DEBUG_PRINT_MP
140  printString("[Thread " + std::to_string(threadId) + "]: now busy with LINE_SEARCH !");
141 #endif // DEBUG_PRINT_MP
142  lineSearchWorker(threadId);
143  uniqueProcessID = generateUniqueProcessID(iteration_local, LINE_SEARCH, lqpCounter_local);
144  break;
145  }
146  case ROLLOUT_SHOTS:
147  {
148 #ifdef DEBUG_PRINT_MP
149  printString("[Thread " + std::to_string(threadId) + "]: now doing shot rollouts !");
150 #endif // DEBUG_PRINT_MP
151  rolloutShotWorker(threadId);
152  uniqueProcessID = generateUniqueProcessID(iteration_local, ROLLOUT_SHOTS, lqpCounter_local);
153  break;
154  }
155  case COMPUTE_LQ_PROBLEM:
156  {
157 #ifdef DEBUG_PRINT_MP
158  printString("[Thread " + std::to_string(threadId) + "]: now doing LQ approximation !");
159 #endif // DEBUG_PRINT_MP
160  computeLQProblemWorker(threadId);
161  uniqueProcessID = generateUniqueProcessID(iteration_local, COMPUTE_LQ_PROBLEM, lqpCounter_local);
162  break;
163  }
164  case SHUTDOWN:
165  {
166 #ifdef DEBUG_PRINT_MP
167  printString("[Thread " + std::to_string(threadId) + "]: now shutting down !");
168 #endif // DEBUG_PRINT_MP
169  return;
170  break;
171  }
172  case IDLE:
173  {
174 #ifdef DEBUG_PRINT_MP
175  printString("[Thread " + std::to_string(threadId) + "]: is idle. Now going to sleep.");
176 #endif // DEBUG_PRINT_MP
177  break;
178  }
179  default:
180  {
181  printString("[Thread " + std::to_string(threadId) + "]: WARNING: Worker has unknown task !");
182  break;
183  }
184  }
185  }
186 
187 #ifdef DEBUG_PRINT_MP
188  printString("[Thread " + std::to_string(threadId) + "]: shut down.");
189 #endif // DEBUG_PRINT_MP
190 }
191 
192 
193 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
195 {
196 #ifdef DEBUG_PRINT_MP
197  printString("[MP]: Going to launch worker threads!");
198  std::cout << workersActive_.load() << std::endl;
199 #endif //DEBUG_PRINT_MP
200 
201  workersActive_ = true;
202  workerTask_ = IDLE;
203 
204  for (int i = 0; i < (int)this->settings_.nThreads; i++)
205  {
206  workerThreads_.push_back(std::thread(&NLOCBackendMP::threadWork, this, i));
207  }
208 }
209 
210 
211 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
213  size_t lastIndex)
214 {
215  // fill terminal cost
216  if (lastIndex == (static_cast<size_t>(this->K_) - 1))
217  this->initializeCostToGo();
218 
219  /*
220  * In special cases, this function may be called for a single index, e.g. for the unconstrained GNMS real-time iteration scheme.
221  * Then, don't wake up workers, but do single-threaded computation for that single index, and return.
222  */
223  if (lastIndex == firstIndex)
224  {
225 #ifdef DEBUG_PRINT_MP
226  printString("[MP]: do single threaded LQ approximation for single index " + std::to_string(firstIndex) +
227  ". Not waking up workers.");
228 #endif //DEBUG_PRINT_MP
229  this->executeLQApproximation(this->settings_.nThreads, firstIndex);
230  if (this->generalConstraints_[this->settings_.nThreads] != nullptr)
231  this->computeLinearizedConstraints(this->settings_.nThreads, firstIndex);
232  return;
233  }
234 
235  /*
236  * In case of multiple points to perform LQ-approximation, start multi-threading:
237  */
238  Eigen::setNbThreads(1); // disable Eigen multi-threading
239 #ifdef DEBUG_PRINT_MP
240  printString("[MP]: Restricting Eigen to " + std::to_string(Eigen::nbThreads()) + " threads.");
241 #endif //DEBUG_PRINT_MP
242 
243  kTaken_ = 0;
244  kCompleted_ = 0;
245  KMax_ = lastIndex;
246  KMin_ = firstIndex;
247 
248 #ifdef DEBUG_PRINT_MP
249  printString("[MP]: Waking up workers to do LQ approximation.");
250 #endif //DEBUG_PRINT_MP
251  workerTask_ = COMPUTE_LQ_PROBLEM;
252  workerWakeUpCondition_.notify_all();
253 
254 #ifdef DEBUG_PRINT_MP
255  printString("[MP]: Will sleep now until done with LQ approximation.");
256 #endif //DEBUG_PRINT_MP
257 
258  std::unique_lock<std::mutex> waitLock(kCompletedMutex_);
259  kCompletedCondition_.wait(waitLock, [this] { return kCompleted_.load() > KMax_ - KMin_; });
260  waitLock.unlock();
261  workerTask_ = IDLE;
262 #ifdef DEBUG_PRINT_MP
263  printString("[MP]: Woke up again, should have computed LQ approximation now.");
264 #endif //DEBUG_PRINT_MP
265 
266 
267  Eigen::setNbThreads(this->settings_.nThreadsEigen); // restore Eigen multi-threading
268 #ifdef DEBUG_PRINT_MP
269  printString("[MP]: Restoring " + std::to_string(Eigen::nbThreads()) + " Eigen threads.");
270 #endif //DEBUG_PRINT_MP
271 }
272 
273 
274 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
276 {
277  while (true)
278  {
279  const size_t k = kTaken_++;
280 
281  if (k > KMax_ - KMin_)
282  {
283 #ifdef DEBUG_PRINT_MP
284  if ((k + 1) % 100 == 0)
285  printString("k > KMax_ - KMin_ with k = " + std::to_string(k) + " and KMax_ is " +
286  std::to_string(KMax_) + " and KMin_ is " + std::to_string(KMin_));
287 #endif
288 
289  //kCompleted_++;
290  if (kCompleted_.load() > KMax_ - KMin_)
291  kCompletedCondition_.notify_all();
292  return;
293  }
294 
295 #ifdef DEBUG_PRINT_MP
296  if ((k + 1) % 100 == 0)
297  printString("[Thread " + std::to_string(threadId) + "]: Building LQ problem for index k " +
298  std::to_string(KMax_ - k));
299 #endif
300 
301  this->executeLQApproximation(threadId, KMax_ - k);
302 
303  if (this->generalConstraints_[threadId] != nullptr)
304  this->computeLinearizedConstraints(threadId, KMax_ - k); // linearize constraints backwards
305 
306  kCompleted_++;
307  }
308 }
309 
310 
311 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
313  size_t lastIndex)
314 {
319  if (lastIndex == firstIndex)
320  {
321 #ifdef DEBUG_PRINT_MP
322  printString("[MP]: do single threaded shot rollout for single index " + std::to_string(firstIndex) +
323  ". Not waking up workers.");
324 #endif //DEBUG_PRINT_MP
325 
326  this->rolloutSingleShot(this->settings_.nThreads, firstIndex, this->u_ff_, this->x_, this->x_ref_lqr_,
327  this->xShot_, *this->substepsX_, *this->substepsU_);
328 
329  this->computeSingleDefect(firstIndex, this->x_, this->xShot_, this->d_);
330  return;
331  }
332 
336  Eigen::setNbThreads(1); // disable Eigen multi-threading
337 #ifdef DEBUG_PRINT_MP
338  printString("[MP]: Restricting Eigen to " + std::to_string(Eigen::nbThreads()) + " threads.");
339 #endif //DEBUG_PRINT_MP
340 
341 
342  kTaken_ = 0;
343  kCompleted_ = 0;
344  KMax_ = lastIndex;
345  KMin_ = firstIndex;
346 
347 
348 #ifdef DEBUG_PRINT_MP
349  std::cout << "[MP]: Waking up workers to do shot rollouts." << std::endl;
350 #endif //DEBUG_PRINT_MP
351  workerTask_ = ROLLOUT_SHOTS;
352  workerWakeUpCondition_.notify_all();
353 
354 #ifdef DEBUG_PRINT_MP
355  std::cout << "[MP]: Will sleep now until we have rolled out all shots." << std::endl;
356 #endif //DEBUG_PRINT_MP
357 
358  std::unique_lock<std::mutex> waitLock(kCompletedMutex_);
359  kCompletedCondition_.wait(waitLock, [this] { return kCompleted_.load() > KMax_ - KMin_; });
360  waitLock.unlock();
361  workerTask_ = IDLE;
362 #ifdef DEBUG_PRINT_MP
363  std::cout << "[MP]: Woke up again, should have rolled out all shots now." << std::endl;
364 #endif //DEBUG_PRINT_MP
365 
366  Eigen::setNbThreads(this->settings_.nThreadsEigen); // restore Eigen multi-threading
367 #ifdef DEBUG_PRINT_MP
368  printString("[MP]: Restoring " + std::to_string(Eigen::nbThreads()) + " Eigen threads.");
369 #endif //DEBUG_PRINT_MP
370 }
371 
372 
373 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
375 {
376  while (true)
377  {
378  size_t k = kTaken_++;
379 
380  if (k > KMax_ - KMin_)
381  {
382  if (kCompleted_.load() > KMax_ - KMin_)
383  kCompletedCondition_.notify_all();
384  return;
385  }
386 
387  size_t kShot = (KMax_ - k);
388  if (kShot % ((size_t)this->getNumStepsPerShot()) ==
389  0)
390  {
391 #ifdef DEBUG_PRINT_MP
392  if ((k + 1) % 100 == 0)
393  printString("[Thread " + std::to_string(threadId) + "]: rolling out shot with index " +
394  std::to_string(KMax_ - k));
395 #endif
396 
397  this->rolloutSingleShot(threadId, kShot, this->u_ff_, this->x_, this->x_ref_lqr_, this->xShot_,
398  *this->substepsX_, *this->substepsU_);
399 
400  this->computeSingleDefect(kShot, this->x_, this->xShot_, this->d_);
401  }
402 
403  kCompleted_++;
404  }
405 }
406 
407 
408 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
410 {
411  Eigen::setNbThreads(1); // disable Eigen multi-threading
412 
413  alphaProcessed_.clear();
414  alphaTaken_ = 0;
415  alphaBestFound_ = false;
416  alphaExpBest_ = this->settings_.lineSearchSettings.maxIterations;
417  alphaExpMax_ = this->settings_.lineSearchSettings.maxIterations;
418  alphaProcessed_.resize(this->settings_.lineSearchSettings.maxIterations, 0);
419  lowestCostPrevious_ = this->lowestCost_;
420 
421 #ifdef DEBUG_PRINT_MP
422  std::cout << "[MP]: Waking up workers." << std::endl;
423 #endif //DEBUG_PRINT_MP
424  workerTask_ = LINE_SEARCH;
425  workerWakeUpCondition_.notify_all();
426 
427 #ifdef DEBUG_PRINT_MP
428  std::cout << "[MP]: Will sleep now until done line search." << std::endl;
429 #endif //DEBUG_PRINT_MP
430  std::unique_lock<std::mutex> waitLock(alphaBestFoundMutex_);
431  alphaBestFoundCondition_.wait(waitLock, [this] { return alphaBestFound_.load(); });
432  waitLock.unlock();
433  workerTask_ = IDLE;
434 #ifdef DEBUG_PRINT_MP
435  std::cout << "[MP]: Woke up again, should have results now." << std::endl;
436 #endif //DEBUG_PRINT_MP
437 
438  double alphaBest = 0.0;
439  if (alphaExpBest_ != alphaExpMax_)
440  {
441  alphaBest = this->settings_.lineSearchSettings.alpha_0 *
442  std::pow(this->settings_.lineSearchSettings.n_alpha, alphaExpBest_);
443  }
444 
445  Eigen::setNbThreads(this->settings_.nThreadsEigen); // restore Eigen multi-threading
446 #ifdef DEBUG_PRINT_MP
447  printString("[MP]: Restoring " + std::to_string(Eigen::nbThreads()) + " Eigen threads.");
448 #endif //DEBUG_PRINT_MP
449 
450  // update norms, as they are typically different from the pure lqoc solver updates
451  this->lu_norm_ = this->template computeDiscreteArrayNorm<ct::core::ControlVectorArray<CONTROL_DIM, SCALAR>, 2>(
452  this->u_ff_, this->u_ff_prev_);
453  this->lx_norm_ = this->template computeDiscreteArrayNorm<ct::core::StateVectorArray<STATE_DIM, SCALAR>, 2>(
454  this->x_, this->x_prev_);
455 
456  this->x_prev_ = this->x_;
457  this->u_ff_prev_ = this->u_ff_;
458 
459  return alphaBest;
460 
461 } // end linesearch
462 
463 
464 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
466 {
467  while (true)
468  {
469  size_t alphaExp = alphaTaken_++;
470 
471 #ifdef DEBUG_PRINT_MP
472  printString("[Thread " + std::to_string(threadId) + "]: Taking alpha index " + std::to_string(alphaExp));
473 #endif
474 
475  if (alphaExp >= alphaExpMax_ || alphaBestFound_)
476  {
477  return;
478  }
479 
481  double alpha =
482  this->settings_.lineSearchSettings.alpha_0 * std::pow(this->settings_.lineSearchSettings.n_alpha, alphaExp);
483 
485  SCALAR cost = std::numeric_limits<SCALAR>::max();
486  SCALAR intermediateCost = std::numeric_limits<SCALAR>::max();
487  SCALAR finalCost = std::numeric_limits<SCALAR>::max();
488  SCALAR defectNorm = std::numeric_limits<SCALAR>::max();
489  SCALAR e_box_norm = std::numeric_limits<SCALAR>::max();
490  SCALAR e_gen_norm = std::numeric_limits<SCALAR>::max();
492  ct::core::StateVectorArray<STATE_DIM, SCALAR> x_shot_search(this->K_ + 1);
496  typename Base::StateSubstepsPtr substepsX =
497  typename Base::StateSubstepsPtr(new typename Base::StateSubsteps(this->K_ + 1));
498  typename Base::ControlSubstepsPtr substepsU =
499  typename Base::ControlSubstepsPtr(new typename Base::ControlSubsteps(this->K_ + 1));
500 
501  this->executeLineSearch(threadId, alpha, x_search, x_shot_search, defects_recorded, u_recorded,
502  intermediateCost, finalCost, defectNorm, e_box_norm, e_gen_norm, *substepsX, *substepsU, &alphaBestFound_);
503 
504  lineSearchResultMutex_.lock();
505 
506  // check for step acceptance and get new merit/cost
507  bool stepAccepted =
508  this->acceptStep(alpha, intermediateCost, finalCost, defectNorm, e_box_norm, e_gen_norm, lowestCostPrevious_, cost);
509 
510  if (stepAccepted)
511  {
512  // make sure we do not alter an existing result
513  if (alphaBestFound_)
514  {
515  lineSearchResultMutex_.unlock();
516  break;
517  }
518 
520  {
521  printString("[LineSearch, Thread " + std::to_string(threadId) +
522  "]: Lower cost/merit found at alpha:" + std::to_string(alpha));
523  printString("[LineSearch]: Cost:\t" + std::to_string(intermediateCost + finalCost));
524  printString("[LineSearch]: Defect:\t" + std::to_string(defectNorm));
525  printString("[LineSearch]: err box constr:\t" + std::to_string(e_box_norm));
526  printString("[LineSearch]: err gen constr:\t" + std::to_string(e_gen_norm));
527  printString("[LineSearch]: Merit:\t" + std::to_string(cost));
528  }
529 
530  alphaExpBest_ = alphaExp;
531  this->intermediateCostBest_ = intermediateCost;
532  this->finalCostBest_ = finalCost;
533  this->d_norm_ = defectNorm;
534  this->e_box_norm_ = e_box_norm;
535  this->e_gen_norm_ = e_gen_norm;
536  this->lowestCost_ = cost;
537  this->x_.swap(x_search);
538  this->xShot_.swap(x_shot_search);
539  this->u_ff_.swap(u_recorded);
540  this->d_.swap(defects_recorded);
541  this->substepsX_ = substepsX;
542  this->substepsU_ = substepsU;
543  }
544  else
545  {
547  {
548  if (!alphaBestFound_)
549  {
550  printString("[LineSearch, Thread " + std::to_string(threadId) +
551  "]: NO lower cost/merit found at alpha:" + std::to_string(alpha));
552  printString("[LineSearch]: Cost:\t" + std::to_string(intermediateCost + finalCost));
553  printString("[LineSearch]: Defect:\t" + std::to_string(defectNorm));
554  printString("[LineSearch]: err box constr:\t" + std::to_string(e_box_norm));
555  printString("[LineSearch]: err gen constr:\t" + std::to_string(e_gen_norm));
556  printString("[LineSearch]: Merit:\t" + std::to_string(cost));
557  }
558  else
559  printString("[LineSearch, Thread " + std::to_string(threadId) +
560  "]: getting terminated. Best stepsize found by another thread.");
561  }
562  }
563 
564  alphaProcessed_[alphaExp] = 1;
565 
566  // we now check if all alphas prior to the best have been processed
567  // this also covers the case that there is no better alpha
568  bool allPreviousAlphasProcessed = true;
569  for (size_t i = 0; i < alphaExpBest_; i++)
570  {
571  if (alphaProcessed_[i] != 1)
572  {
573  allPreviousAlphasProcessed = false;
574  break;
575  }
576  }
577  if (allPreviousAlphasProcessed)
578  {
579  alphaBestFound_ = true;
580  alphaBestFoundCondition_.notify_all();
581  }
582 
583  lineSearchResultMutex_.unlock();
584  }
585 }
586 
587 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
589  const size_t& iterateNo,
590  const int workerState,
591  const size_t resetCount)
592 {
593  return (10e12 * (resetCount + 1) + 10e6 * (workerState + 1) + iterateNo + 1);
594 }
595 
596 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
598 {
599  std::cout << text << std::endl;
600 }
601 
602 } // namespace optcon
603 } // namespace ct
LineSearchSettings lineSearchSettings
number of threads for eigen parallelization (applies both to MP and ST) Note. in order to activate Ei...
Definition: NLOptConSettings.hpp:275
StateVectorArray xShot_
state array variables
Definition: NLOCBackendBase.hpp:564
void computeSingleDefect(size_t k, const StateVectorArray &x_local, const StateVectorArray &xShot, StateVectorArray &d) const
computes the defect between shot and trajectory
Definition: NLOCBackendBase-impl.hpp:556
void executeLQApproximation(size_t threadId, size_t k)
Computes the linearized Dynamics and quadratic cost approximation at a specific point of the trajecto...
Definition: NLOCBackendBase-impl.hpp:685
virtual void computeLQApproximation(size_t firstIndex, size_t lastIndex) override
build LQ approximation around trajectory (linearize dynamics and general constraints, quadratize cost, etc)
Definition: NLOCBackendMP-impl.hpp:212
size_t nThreadsEigen
number of threads, for MP version
Definition: NLOptConSettings.hpp:274
int K_
Definition: NLOCBackendBase.hpp:561
StateVectorArray x_ref_lqr_
state array from previous iteration
Definition: NLOCBackendBase.hpp:567
scalar_t lowestCost_
Definition: NLOCBackendBase.hpp:588
scalar_t finalCostBest_
Definition: NLOCBackendBase.hpp:587
bool rolloutSingleShot(const size_t threadId, const size_t k, ControlVectorArray &u_ff_local, StateVectorArray &x_local, const StateVectorArray &x_ref_lqr, StateVectorArray &xShot, StateSubsteps &substepsX, ControlSubsteps &substepsU, std::atomic_bool *terminationFlag=nullptr) const
integrate the individual shots
Definition: NLOCBackendBase-impl.hpp:436
size_t iteration_
Definition: NLOCBackendBase.hpp:555
StateVectorArray d_
rolled-out state (at the end of a time step forward)
Definition: NLOCBackendBase.hpp:565
double alpha_0
Definition: NLOptConSettings.hpp:61
void computeLinearizedConstraints(size_t threadId, size_t k)
Computes the linearized general constraints at a specific point of the trajectory.
Definition: NLOCBackendBase-impl.hpp:790
bool debugPrint
Definition: NLOptConSettings.hpp:66
StateVectorArray x_
the time trajectory
Definition: NLOCBackendBase.hpp:563
SCALAR lu_norm_
sum of the norms of state update
Definition: NLOCBackendBase.hpp:584
int getNumStepsPerShot() const
Definition: NLOCBackendBase-impl.hpp:1659
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef NLOCBackendBase< STATE_DIM, CONTROL_DIM, P_DIM, V_DIM, SCALAR, CONTINUOUS > Base
Definition: NLOCBackendMP.hpp:36
StateVectorArray x_prev_
defects in between end of rollouts and subsequent state decision vars
Definition: NLOCBackendBase.hpp:566
ControlVectorArray u_ff_prev_
feed forward controls
Definition: NLOCBackendBase.hpp:570
std::vector< typename OptConProblem_t::ConstraintPtr_t > generalConstraints_
Definition: NLOCBackendBase.hpp:612
virtual ~NLOCBackendMP()
destructor
Definition: NLOCBackendMP-impl.hpp:34
Settings for the NLOptCon algorithm.
Definition: NLOptConSettings.hpp:198
std::conditional< CONTINUOUS, ContinuousOptConProblem< STATE_DIM, CONTROL_DIM, SCALAR >, DiscreteOptConProblem< STATE_DIM, CONTROL_DIM, SCALAR > >::type OptConProblem_t
Definition: NLOCBackendBase.hpp:62
CppAD::AD< CppAD::cg::CG< double > > SCALAR
size_t lqpCounter_
a counter used to identify lqp problems in derived classes, i.e. for thread management in MP ...
Definition: NLOCBackendBase.hpp:615
Settings_t settings_
Definition: NLOCBackendBase.hpp:559
void executeLineSearch(const size_t threadId, const scalar_t alpha, ct::core::StateVectorArray< STATE_DIM, SCALAR > &x_recorded, ct::core::StateVectorArray< STATE_DIM, SCALAR > &x_shot_recorded, ct::core::StateVectorArray< STATE_DIM, SCALAR > &defects_recorded, ct::core::ControlVectorArray< CONTROL_DIM, SCALAR > &u_recorded, scalar_t &intermediateCost, scalar_t &finalCost, scalar_t &defectNorm, scalar_t &e_box_norm, scalar_t &e_gen_norm, StateSubsteps &substepsX, ControlSubsteps &substepsU, std::atomic_bool *terminationFlag=nullptr) const
Check if controller with particular alpha is better.
Definition: NLOCBackendBase-impl.hpp:1107
for i
Definition: mpc_unittest_plotting.m:14
SCALAR performLineSearch() override
performLineSearch: execute the line search, possibly with different threading schemes ...
Definition: NLOCBackendMP-impl.hpp:409
ControlVectorArray u_ff_
reference for lqr
Definition: NLOCBackendBase.hpp:569
size_t maxIterations
Definition: NLOptConSettings.hpp:60
bool acceptStep(const SCALAR alpha, const SCALAR intermediateCost, const SCALAR finalCost, const SCALAR defectNorm, const SCALAR e_box_norm, const SCALAR e_gen_norm, const SCALAR lowestMeritPrevious, SCALAR &new_merit)
in case of line-search compute new merit and check if to accept step. Returns true if accept step ...
Definition: NLOCBackendBase-impl.hpp:1187
StateSubstepsPtr substepsX_
state array from previous iteration
Definition: NLOCBackendBase.hpp:577
Definition: NLOCBackendMP.hpp:31
SCALAR e_gen_norm_
sum of the norms of all box constraint violations
Definition: NLOCBackendBase.hpp:582
scalar_t intermediateCostBest_
sum of the norms of control update
Definition: NLOCBackendBase.hpp:586
SCALAR lx_norm_
sum of the norms of all general constraint violations
Definition: NLOCBackendBase.hpp:583
ControlSubstepsPtr substepsU_
state substeps recorded by integrator during rollouts
Definition: NLOCBackendBase.hpp:578
NLOCBackendMP(const OptConProblem_t &optConProblem, const NLOptConSettings &settings)
Definition: NLOCBackendMP-impl.hpp:13
void initializeCostToGo()
Initializes cost to go.
Definition: NLOCBackendBase-impl.hpp:819
const bool verbose
Definition: ConstraintComparison.h:18
int nThreads
save the smallest eigenvalue of the Hessian
Definition: NLOptConSettings.hpp:272
double n_alpha
Definition: NLOptConSettings.hpp:64
SCALAR d_norm_
control substeps recorded by integrator during rollouts
Definition: NLOCBackendBase.hpp:580
void swap(DiscreteArray &other)
SCALAR e_box_norm_
sum of the norms of all defects (internal constraint)
Definition: NLOCBackendBase.hpp:581
virtual void rolloutShots(size_t firstIndex, size_t lastIndex) override
integrates the specified shots and computes the corresponding defects
Definition: NLOCBackendMP-impl.hpp:312