forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
solvers: Port MosekSolver and GurobiSolver to SolverBase (RobotLocomo…
- Loading branch information
1 parent
4bb800e
commit 420bee8
Showing
10 changed files
with
98 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -657,15 +657,11 @@ std::shared_ptr<MosekSolver::License> MosekSolver::AcquireLicense() { | |
|
||
bool MosekSolver::is_available() { return true; } | ||
|
||
void MosekSolver::Solve(const MathematicalProgram& prog, | ||
const optional<Eigen::VectorXd>& initial_guess, | ||
const optional<SolverOptions>& solver_options, | ||
MathematicalProgramResult* result) const { | ||
*result = {}; | ||
result->set_decision_variable_index(prog.decision_variable_index()); | ||
SolverOptions merged_solver_options = | ||
solver_options.value_or(SolverOptions()); | ||
merged_solver_options.Merge(prog.solver_options()); | ||
void MosekSolver::DoSolve( | ||
const MathematicalProgram& prog, | ||
const Eigen::VectorXd& initial_guess, | ||
const SolverOptions& merged_options, | ||
MathematicalProgramResult* result) const { | ||
const int num_vars = prog.num_vars(); | ||
MSKtask_t task = nullptr; | ||
MSKrescodee rescode; | ||
|
@@ -744,29 +740,35 @@ void MosekSolver::Solve(const MathematicalProgram& prog, | |
|
||
if (rescode == MSK_RES_OK) { | ||
for (const auto& double_options : | ||
merged_solver_options.GetOptionsDouble(id())) { | ||
merged_options.GetOptionsDouble(id())) { | ||
if (rescode == MSK_RES_OK) { | ||
rescode = MSK_putnadouparam(task, double_options.first.c_str(), | ||
double_options.second); | ||
} | ||
} | ||
for (const auto& int_options : merged_solver_options.GetOptionsInt(id())) { | ||
for (const auto& int_options : merged_options.GetOptionsInt(id())) { | ||
if (rescode == MSK_RES_OK) { | ||
rescode = MSK_putnaintparam(task, int_options.first.c_str(), | ||
int_options.second); | ||
} | ||
} | ||
for (const auto& str_options : merged_solver_options.GetOptionsStr(id())) { | ||
for (const auto& str_options : merged_options.GetOptionsStr(id())) { | ||
if (rescode == MSK_RES_OK) { | ||
rescode = MSK_putnastrparam(task, str_options.first.c_str(), | ||
str_options.second.c_str()); | ||
} | ||
} | ||
} | ||
|
||
if (with_integer_or_binary_variable && initial_guess.has_value()) { | ||
// Mosek can accept the initial guess on its integer/binary variables, but | ||
// not on the continuous variables. So it allows some of the variables' | ||
// initial guess to be unset, while setting the others. If the initial guess | ||
// for any variable is finite, then we ask Mosek to set the initial guess. | ||
const bool has_any_finite_initial_guess = | ||
initial_guess.unaryExpr([](double g) { return std::isfinite(g); }).any(); | ||
if (with_integer_or_binary_variable && has_any_finite_initial_guess) { | ||
// Set the initial guess for the integer/binary variables. | ||
DRAKE_ASSERT(initial_guess->size() == prog.num_vars()); | ||
DRAKE_ASSERT(initial_guess.size() == prog.num_vars()); | ||
MSKint32t num_mosek_vars{0}; | ||
if (rescode == MSK_RES_OK) { | ||
// num_mosek_vars is guaranteed to be no less than prog.num_vars(), as we | ||
|
@@ -785,7 +787,7 @@ void MosekSolver::Solve(const MathematicalProgram& prog, | |
if (var_type == MathematicalProgram::VarType::INTEGER || | ||
var_type == MathematicalProgram::VarType::BINARY) { | ||
if (rescode == MSK_RES_OK) { | ||
const MSKrealt initial_guess_i = initial_guess.value()(var_count); | ||
const MSKrealt initial_guess_i = initial_guess(var_count); | ||
rescode = | ||
MSK_putxxslice(task, MSK_SOL_ITG, i, i + 1, &initial_guess_i); | ||
} | ||
|
@@ -820,7 +822,6 @@ void MosekSolver::Solve(const MathematicalProgram& prog, | |
solution_type = MSK_SOL_ITR; | ||
} | ||
|
||
result->set_solver_id(id()); | ||
// TODO([email protected]) : Add MOSEK parameters. | ||
// Mosek parameter are added by enum, not by string. | ||
MSKsolstae solution_status{MSK_SOL_STA_UNKNOWN}; | ||
|
@@ -895,13 +896,5 @@ void MosekSolver::Solve(const MathematicalProgram& prog, | |
MSK_deletetask(&task); | ||
} | ||
|
||
SolutionResult MosekSolver::Solve(MathematicalProgram& prog) const { | ||
MathematicalProgramResult result; | ||
Solve(prog, {}, {}, &result); | ||
const SolverResult solver_result = result.ConvertToSolverResult(); | ||
prog.SetSolverResult(solver_result); | ||
return result.get_solution_result(); | ||
} | ||
|
||
} // namespace solvers | ||
} // namespace drake |
Oops, something went wrong.