Source code for leap_c.diff_mpc.utils.solve

import time

import numpy as np
from acados_template.acados_ocp_batch_solver import AcadosOcpBatchSolver
from acados_template.acados_ocp_iterate import AcadosOcpFlattenedBatchIterate

from leap_c.diff_mpc.data import AcadosOcpSolverInput
from leap_c.diff_mpc.initializer import AcadosDiffMpcInitializer
from leap_c.diff_mpc.utils.prepare_solver import prepare_batch_solver


[docs] def solve_with_retry( batch_solver: AcadosOcpBatchSolver, initializer: AcadosDiffMpcInitializer, ocp_iterate: AcadosOcpFlattenedBatchIterate | None, solver_input: AcadosOcpSolverInput, ) -> tuple[np.ndarray, dict[str, float]]: """Solve a batch of problem instances, and retry in case of failure. This function prepares the batch solver by loading the iterate, setting the initial conditions, and configuring the global and stage-wise parameters. If `p_global` or `p_stagewise` is not provided, it will check if the model has default parameters and load them accordingly. Args: batch_solver: The batch solver to use. initializer: The initializer used for retries. ocp_iterate: The iterate to load into the batch solver. solver_input: Input data for the solver, which includes initial conditions and parameters. Returns: The status of each solver (`status != 0` means failure) and statistics of the solving process, i.e., `"solving_time"`, `"success_rate"`, and `"retry_rate"`. """ batch_size = solver_input.batch_size if ocp_iterate is None: ocp_iterate = initializer.batch_iterate(solver_input) with_retry = False else: with_retry = True prepare_batch_solver(batch_solver, ocp_iterate, solver_input) start = time.perf_counter() batch_solver.solve(n_batch=batch_size) time_solve = time.perf_counter() - start active_solvers = batch_solver.ocp_solvers[:batch_size] batch_status = batch_solver.status if with_retry and batch_status.any(): for idx, solver in enumerate(active_solvers): if batch_status[idx] == 0: continue single_iterate = initializer.single_iterate(solver_input.get_sample(idx)) solver.set_iterate(single_iterate) start_retry = time.perf_counter() batch_solver.solve(n_batch=batch_size) time_solve += time.perf_counter() - start_retry batch_status_retry = batch_solver.status stats = { "solving_time": time_solve, "success_rate": (batch_status_retry == 0).mean(), "retry_rate": (batch_status != 0).mean(), } return batch_status_retry, stats