12 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
16 : Base(optConProblem, settings)
21 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
24 const std::string& settingsFile,
26 const std::string& ns)
27 :
Base(optConProblem, settingsFile, verbose, ns)
33 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
39 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
42 launchWorkerThreads();
46 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
49 workersActive_ =
false;
50 workerTask_ = SHUTDOWN;
51 workerWakeUpCondition_.notify_all();
54 std::cout <<
"Shutting down workers" << std::endl;
55 #endif // DEBUG_PRINT_MP 57 for (
size_t i = 0;
i < workerThreads_.size();
i++)
59 workerThreads_[
i].join();
63 std::cout <<
"All workers shut down" << std::endl;
64 #endif // DEBUG_PRINT_MP 68 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
72 printString(
"[Thread " + std::to_string(threadId) +
"]: launched");
73 #endif // DEBUG_PRINT_MP 77 int workerTask_local = IDLE;
78 size_t uniqueProcessID = 0;
83 while (workersActive_)
85 workerTask_local = workerTask_.load();
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)));
101 if (workerTask_local == IDLE ||
102 uniqueProcessID == generateUniqueProcessID(iteration_local, (
int)workerTask_local, lqpCounter_local))
104 #ifdef DEBUG_PRINT_MP 105 printString(
"[Thread " + std::to_string(threadId) +
"]: going to sleep !");
109 std::unique_lock<std::mutex> waitLock(workerWakeUpMutex_);
110 while (workerTask_ == IDLE || (uniqueProcessID == generateUniqueProcessID(this->
iteration_,
113 workerWakeUpCondition_.wait(waitLock);
117 workerTask_local = workerTask_.load();
121 #ifdef DEBUG_PRINT_MP 122 printString(
"[Thread " + std::to_string(threadId) +
"]: woke up !");
123 #endif // DEBUG_PRINT_MP 128 #ifdef DEBUG_PRINT_MP 129 printString(
"Breaking - workers are not active !");
130 #endif // DEBUG_PRINT_MP 135 switch (workerTask_local)
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);
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);
155 case COMPUTE_LQ_PROBLEM:
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);
166 #ifdef DEBUG_PRINT_MP 167 printString(
"[Thread " + std::to_string(threadId) +
"]: now shutting down !");
168 #endif // DEBUG_PRINT_MP 174 #ifdef DEBUG_PRINT_MP 175 printString(
"[Thread " + std::to_string(threadId) +
"]: is idle. Now going to sleep.");
176 #endif // DEBUG_PRINT_MP 181 printString(
"[Thread " + std::to_string(threadId) +
"]: WARNING: Worker has unknown task !");
187 #ifdef DEBUG_PRINT_MP 188 printString(
"[Thread " + std::to_string(threadId) +
"]: shut down.");
189 #endif // DEBUG_PRINT_MP 193 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
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 201 workersActive_ =
true;
206 workerThreads_.push_back(std::thread(&NLOCBackendMP::threadWork,
this,
i));
211 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
216 if (lastIndex == (static_cast<size_t>(this->
K_) - 1))
223 if (lastIndex == firstIndex)
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 238 Eigen::setNbThreads(1);
239 #ifdef DEBUG_PRINT_MP 240 printString(
"[MP]: Restricting Eigen to " + std::to_string(Eigen::nbThreads()) +
" threads.");
241 #endif //DEBUG_PRINT_MP 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();
254 #ifdef DEBUG_PRINT_MP 255 printString(
"[MP]: Will sleep now until done with LQ approximation.");
256 #endif //DEBUG_PRINT_MP 258 std::unique_lock<std::mutex> waitLock(kCompletedMutex_);
259 kCompletedCondition_.wait(waitLock, [
this] {
return kCompleted_.load() > KMax_ - KMin_; });
262 #ifdef DEBUG_PRINT_MP 263 printString(
"[MP]: Woke up again, should have computed LQ approximation now.");
264 #endif //DEBUG_PRINT_MP 268 #ifdef DEBUG_PRINT_MP 269 printString(
"[MP]: Restoring " + std::to_string(Eigen::nbThreads()) +
" Eigen threads.");
270 #endif //DEBUG_PRINT_MP 274 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
279 const size_t k = kTaken_++;
281 if (k > KMax_ - KMin_)
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_));
290 if (kCompleted_.load() > KMax_ - KMin_)
291 kCompletedCondition_.notify_all();
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));
311 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
319 if (lastIndex == firstIndex)
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 327 this->xShot_, *this->substepsX_, *this->substepsU_);
336 Eigen::setNbThreads(1);
337 #ifdef DEBUG_PRINT_MP 338 printString(
"[MP]: Restricting Eigen to " + std::to_string(Eigen::nbThreads()) +
" threads.");
339 #endif //DEBUG_PRINT_MP 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();
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 358 std::unique_lock<std::mutex> waitLock(kCompletedMutex_);
359 kCompletedCondition_.wait(waitLock, [
this] {
return kCompleted_.load() > KMax_ - KMin_; });
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 367 #ifdef DEBUG_PRINT_MP 368 printString(
"[MP]: Restoring " + std::to_string(Eigen::nbThreads()) +
" Eigen threads.");
369 #endif //DEBUG_PRINT_MP 373 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
378 size_t k = kTaken_++;
380 if (k > KMax_ - KMin_)
382 if (kCompleted_.load() > KMax_ - KMin_)
383 kCompletedCondition_.notify_all();
387 size_t kShot = (KMax_ - k);
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));
408 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
411 Eigen::setNbThreads(1);
413 alphaProcessed_.clear();
415 alphaBestFound_ =
false;
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();
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(); });
434 #ifdef DEBUG_PRINT_MP 435 std::cout <<
"[MP]: Woke up again, should have results now." << std::endl;
436 #endif //DEBUG_PRINT_MP 438 double alphaBest = 0.0;
439 if (alphaExpBest_ != alphaExpMax_)
446 #ifdef DEBUG_PRINT_MP 447 printString(
"[MP]: Restoring " + std::to_string(Eigen::nbThreads()) +
" Eigen threads.");
448 #endif //DEBUG_PRINT_MP 451 this->
lu_norm_ = this->
template computeDiscreteArrayNorm<ct::core::ControlVectorArray<CONTROL_DIM, SCALAR>, 2>(
453 this->
lx_norm_ = this->
template computeDiscreteArrayNorm<ct::core::StateVectorArray<STATE_DIM, SCALAR>, 2>(
464 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
469 size_t alphaExp = alphaTaken_++;
471 #ifdef DEBUG_PRINT_MP 472 printString(
"[Thread " + std::to_string(threadId) +
"]: Taking alpha index " + std::to_string(alphaExp));
475 if (alphaExp >= alphaExpMax_ || alphaBestFound_)
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();
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));
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_);
504 lineSearchResultMutex_.lock();
508 this->
acceptStep(alpha, intermediateCost, finalCost, defectNorm, e_box_norm, e_gen_norm, lowestCostPrevious_, cost);
515 lineSearchResultMutex_.unlock();
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));
530 alphaExpBest_ = alphaExp;
540 this->
d_.
swap(defects_recorded);
548 if (!alphaBestFound_)
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));
559 printString(
"[LineSearch, Thread " + std::to_string(threadId) +
560 "]: getting terminated. Best stepsize found by another thread.");
564 alphaProcessed_[alphaExp] = 1;
568 bool allPreviousAlphasProcessed =
true;
569 for (
size_t i = 0;
i < alphaExpBest_;
i++)
571 if (alphaProcessed_[
i] != 1)
573 allPreviousAlphasProcessed =
false;
577 if (allPreviousAlphasProcessed)
579 alphaBestFound_ =
true;
580 alphaBestFoundCondition_.notify_all();
583 lineSearchResultMutex_.unlock();
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)
593 return (10e12 * (resetCount + 1) + 10e6 * (workerState + 1) + iterateNo + 1);
596 template <
size_t STATE_DIM,
size_t CONTROL_DIM,
size_t P_DIM,
size_t V_DIM,
typename SCALAR,
bool CONTINUOUS>
599 std::cout << text << std::endl;
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