forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolver_options.h
190 lines (165 loc) · 7.18 KB
/
solver_options.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#pragma once
#include <ostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include "drake/common/drake_assert.h"
#include "drake/common/drake_copyable.h"
#include "drake/solvers/common_solver_option.h"
#include "drake/solvers/solver_id.h"
namespace drake {
namespace solvers {
/**
* Stores options for multiple solvers. This interface does not
* do any verification of solver parameters. It does not even verify that
* the specified solver exists. Use this only when you have
* particular knowledge of what solver is being invoked, and exactly
* what tuning is required.
*
* Supported solver names/options:
*
* "SNOPT" -- Parameter names and values as specified in SNOPT
* User's Guide section 7.7 "Description of the optional parameters",
* used as described in section 7.5 for snSet().
* The SNOPT user guide can be obtained from
* https://web.stanford.edu/group/SOL/guides/sndoc7.pdf
*
* "IPOPT" -- Parameter names and values as specified in IPOPT users
* guide section "Options Reference"
* http://www.coin-or.org/Ipopt/documentation/node40.html
*
* "GUROBI" -- Parameter name and values as specified in Gurobi Reference
* Manual, section 10.2 "Parameter Descriptions"
* https://www.gurobi.com/documentation/9.5/refman/parameters.html
*
* "SCS" -- Parameter name and values as specified in the struct SCS_SETTINGS in
* SCS header file https://github.com/cvxgrp/scs/blob/master/include/scs.h
* Note that the SCS code on github master might be more up-to-date than the
* version used in Drake.
*
* "MOSEK™" -- Parameter name and values as specified in Mosek Reference
* https://docs.mosek.com/9.3/capi/parameters.html
*
* "OSQP" -- Parameter name and values as specified in OSQP Reference
* https://osqp.org/docs/interfaces/solver_settings.html#solver-settings
*
* "dReal" -- Parameter name and values as specified in dReal Reference
* https://github.com/dreal/dreal4/blob/master/README.md#command-line-options.
* Note that Drake only supports a subset of the options listed in the
* reference. @see DrealSolver for the subset of these options supported by the
* solver interface.
*
* "IBEX" -- Parameter name and values as specified in IBEX Reference
* http://www.ibex-lib.org/doc/optim.html?highlight=eps#options.
* Note that Drake only supports a subset of the options listed in the
* reference. @see IbexSolver for the subset of these options supported by the
* solver interface.
*/
class SolverOptions {
public:
SolverOptions() = default;
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(SolverOptions)
/** The values stored in SolverOptions can be double, int, or string.
* In the future, we might re-order or add more allowed types without any
* deprecation period, so be sure to use std::visit or std::get<T> to
* retrieve the variant's value in a future-proof way. */
using OptionValue = std::variant<double, int, std::string>;
/** Sets a double-valued solver option for a specific solver.
* @pydrake_mkdoc_identifier{double_option}
*/
void SetOption(const SolverId& solver_id, const std::string& solver_option,
double option_value);
/** Sets an integer-valued solver option for a specific solver.
* @pydrake_mkdoc_identifier{int_option}
*/
void SetOption(const SolverId& solver_id, const std::string& solver_option,
int option_value);
/** Sets a string-valued solver option for a specific solver.
* @pydrake_mkdoc_identifier{str_option}
*/
void SetOption(const SolverId& solver_id, const std::string& solver_option,
const std::string& option_value);
/** Sets a common option for all solvers supporting that option (for example,
* printing the progress in each iteration). If the solver doesn't support
* the option, the option is ignored.
* @pydrake_mkdoc_identifier{common_option} */
void SetOption(CommonSolverOption key, OptionValue value);
const std::unordered_map<std::string, double>& GetOptionsDouble(
const SolverId& solver_id) const;
const std::unordered_map<std::string, int>& GetOptionsInt(
const SolverId& solver_id) const;
const std::unordered_map<std::string, std::string>& GetOptionsStr(
const SolverId& solver_id) const;
/**
* Gets the common options for all solvers. Refer to CommonSolverOption for
* more details.
*/
const std::unordered_map<CommonSolverOption, OptionValue>&
common_solver_options() const {
return common_solver_options_;
}
/** Returns the kPrintFileName set via CommonSolverOption, or else an empty
* string if the option has not been set. */
std::string get_print_file_name() const;
/** Returns the kPrintToConsole set via CommonSolverOption, or else false if
* the option has not been set. */
bool get_print_to_console() const;
template <typename T>
const std::unordered_map<std::string, T>& GetOptions(
const SolverId& solver_id) const {
if constexpr (std::is_same_v<T, double>) {
return GetOptionsDouble(solver_id);
} else if constexpr (std::is_same_v<T, int>) {
return GetOptionsInt(solver_id);
} else if constexpr (std::is_same_v<T, std::string>) {
return GetOptionsStr(solver_id);
}
DRAKE_UNREACHABLE();
}
/** Returns the IDs that have any option set. */
std::unordered_set<SolverId> GetSolverIds() const;
/**
* Merges the other solver options into this. If `other` and `this` option
* both define the same option for the same solver, we ignore then one from
* `other` and keep the one from `this`.
*/
void Merge(const SolverOptions& other);
/**
* Returns true if `this` and `other` have exactly the same solvers, with
* exactly the same keys and values for the options for each solver.
*/
bool operator==(const SolverOptions& other) const;
/**
* Negate operator==.
*/
bool operator!=(const SolverOptions& other) const;
/**
* Check if for a given solver_id, the option keys are included in
* double_keys, int_keys and str_keys.
* @param solver_id If this SolverOptions has set options for this solver_id,
* then we check if the option keys are a subset of `double_keys`, `int_keys`
* and `str_keys`.
* @param double_keys The set of allowable keys for double options.
* @param int_keys The set of allowable keys for int options.
* @param str_keys The set of allowable keys for string options.
* @throws std::exception if the solver contains un-allowed options.
*/
void CheckOptionKeysForSolver(
const SolverId& solver_id,
const std::unordered_set<std::string>& allowable_double_keys,
const std::unordered_set<std::string>& allowable_int_keys,
const std::unordered_set<std::string>& allowable_str_keys) const;
private:
std::unordered_map<SolverId, std::unordered_map<std::string, double>>
solver_options_double_{};
std::unordered_map<SolverId, std::unordered_map<std::string, int>>
solver_options_int_{};
std::unordered_map<SolverId, std::unordered_map<std::string, std::string>>
solver_options_str_{};
std::unordered_map<CommonSolverOption, OptionValue> common_solver_options_{};
};
std::string to_string(const SolverOptions&);
std::ostream& operator<<(std::ostream&, const SolverOptions&);
} // namespace solvers
} // namespace drake