This unit test applies Direct Multiple Shooting to an oscillator system. It employs all possible combinations of settings and solvers.
#include <gtest/gtest.h>
namespace optcon {
namespace example {
class OscillatorDms
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
{
settings_ = settings;
x_0_ << 0.0, 0.0;
x_final_ << 2.0, -1.0;
Q_ << 0.0, 0.0, 0.0, 10.0;
Q_final_ << 0.0, 0.0, 0.0, 0.0;
R_ << 0.001;
u_des_ << 0.0;
costFunction_ = std::shared_ptr<ct::optcon::CostFunctionQuadratic<2, 1>>(
generalConstraints_ = std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<2, 1>>(
std::shared_ptr<TerminalConstraint<2, 1>> termConstraint(new TerminalConstraint<2, 1>(x_final_));
termConstraint->setName("crazyTerminalConstraint");
generalConstraints_->addTerminalConstraint(termConstraint, true);
generalConstraints_->initialize();
ContinuousOptConProblem<2, 1> optProblem(oscillator_, costFunction_);
optProblem.setInitialState(x_0_);
optProblem.setTimeHorizon(settings_.
T_);
optProblem.setGeneralConstraints(generalConstraints_);
calcInitGuess();
dmsPlanner_ = std::shared_ptr<DmsSolver<2, 1>>(new DmsSolver<2, 1>(optProblem, settings_));
dmsPlanner_->setInitialGuess(initialPolicy_);
}
{
dmsPlanner_->solve();
}
private:
void calcInitGuess()
{
x_initguess_.resize(settings_.
N_ + 1, OscDimensions::state_vector_t::Zero());
u_initguess_.resize(settings_.
N_ + 1, OscDimensions::control_vector_t::Zero());
for (
size_t i = 0;
i < settings_.
N_ + 1; ++
i)
{
x_initguess_[
i] = x_0_ + (x_final_ - x_0_) * ((
double)
i / (double)settings_.
N_);
}
}
double w_n_;
double zeta_;
std::shared_ptr<ct::core::SecondOrderSystem> oscillator_;
DmsSettings settings_;
std::shared_ptr<DmsSolver<2, 1>> dmsPlanner_;
std::shared_ptr<ct::optcon::CostFunctionQuadratic<2, 1>> costFunction_;
std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<2, 1>> generalConstraints_;
OscDimensions::state_vector_t x_0_;
OscDimensions::state_vector_t x_final_;
OscDimensions::state_matrix_t Q_;
OscDimensions::state_matrix_t Q_final_;
OscDimensions::control_matrix_t R_;
OscDimensions::control_vector_t u_des_;
DmsPolicy<2, 1> initialPolicy_;
OscDimensions::state_vector_array_t x_initguess_;
OscDimensions::control_vector_array_t u_initguess_;
};
TEST(DmsTest, OscillatorDmsTestAllVariants)
{
for (int splineType = 0; splineType < DmsSettings::SplineType::num_types_splining; splineType++)
{
for (int costEvalT = 0; costEvalT < DmsSettings::CostEvaluationType::num_types_costevaluation; costEvalT++)
{
DmsSettings settings;
settings.N_ = 25;
settings.T_ = 5.0;
settings.nThreads_ = 1;
settings.h_min_ = 0.1;
settings.dt_sim_ = 0.01;
settings.absErrTol_ = 1e-6;
settings.relErrTol_ = 1e-6;
#ifdef BUILD_WITH_SNOPT_SUPPORT
NlpSolverSettings nlpsettings;
settings.solverSettings_ = nlpsettings;
oscDms.initialize(settings);
oscDms.getSolution();
#endif
#ifdef BUILD_WITH_IPOPT_SUPPORT
NlpSolverSettings nlpsettings_ipopt;
settings.solverSettings_ = nlpsettings_ipopt;
oscDms_ipopt.initialize(settings);
oscDms_ipopt.getSolution();
#endif
}
}
}
}
}
}
int main(
int argc,
char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}