Collects the largest equality and inequality constraint violations from acados.
115 {
116
117
118 for (int stage = 0; stage <= dims->N; ++stage) {
119 std::vector<double> residuals(2 * dims->ni[stage]);
120 ocp_nlp_get_at_stage(solver, stage, "ineq_fun", residuals.data());
121 for (size_t index = 0; index < residuals.size(); ++index) {
122 if (residuals[index] > metrics.max_ineq_violation) {
123 metrics.max_ineq_violation = residuals[index];
124 metrics.max_ineq_stage = stage;
125 metrics.max_ineq_index = static_cast<int>(index);
126 }
127 }
128 }
129
130 for (int stage = 0; stage < dims->N; ++stage) {
131 std::vector<double> residuals(dims->nx[stage + 1]);
132 ocp_nlp_get_at_stage(solver, stage, "res_eq", residuals.data());
133 for (size_t state = 0; state < residuals.size(); ++state) {
134 if (std::abs(residuals[state]) > metrics.max_eq_violation) {
135 metrics.max_eq_violation = std::abs(residuals[state]);
136 metrics.max_eq_stage = stage;
137 metrics.max_eq_state = static_cast<int>(state);
138 }
139 }
140 }
141
142 if (metrics.max_ineq_stage < 0) return;
143
144 const int ni = dims->ni[metrics.max_ineq_stage];
145 const int nb = dims->nb[metrics.max_ineq_stage];
146 const int ng = dims->ng[metrics.max_ineq_stage];
147 const int nh = ni - nb - ng - dims->ns[metrics.max_ineq_stage];
148 const int index = metrics.max_ineq_index % ni;
149 metrics.max_ineq_side = metrics.max_ineq_index < ni ? "lower" : "upper";
150 metrics.max_ineq_index = index;
151 if (index < nb) {
152 std::vector<int> bound_indices(nb);
153 ocp_nlp_get_at_stage(solver, metrics.max_ineq_stage, "idxb", bound_indices.data());
154 const int variable_index = bound_indices[index];
155 if (variable_index < dims->nu[metrics.max_ineq_stage]) {
156 metrics.max_ineq_type = "control";
157 metrics.max_ineq_index = variable_index;
158 } else {
159 metrics.max_ineq_type = "state";
160 metrics.max_ineq_index = variable_index - dims->nu[metrics.max_ineq_stage];
161 }
162 } else if (index < nb + ng) {
163 metrics.max_ineq_type = "linear";
164 } else if (index < nb + ng + nh) {
165 const int h_index = index - nb - ng;
166 const int ego_circles = nh / (obstacle_circles + 2);
167 if (h_index < 2 * ego_circles) {
168 metrics.max_ineq_type = h_index % 2 == 0 ? "boundary_left" : "boundary_right";
169 metrics.max_ineq_index = h_index / 2;
170 } else if (h_index < (obstacle_circles + 2) * ego_circles) {
171 const int obstacle_index = h_index - 2 * ego_circles;
172 metrics.max_ineq_type = "obstacle_" + std::to_string(obstacle_index / ego_circles);
173 metrics.max_ineq_index = obstacle_index % ego_circles;
174 } else {
175 metrics.max_ineq_type = "vehicle";
176 metrics.max_ineq_index = h_index - (obstacle_circles + 2) * ego_circles;
177 }
178 } else {
179 metrics.max_ineq_type = "slack";
180 metrics.max_ineq_index = index - nb - ng - nh;
181 }
182
183}