Developer Guide¶
This page contains additional information for people who want to extend acados
.
Contributions¶
are handled via Pull Requests (PR) on Github
Fork the project
Push your changes to your fork
Open a pull request https://github.com/acados/acados
Describe what you changed and why.
Rather make minimal changes
Rather more commits than less
Memory management in acados
¶
The following are guidelines on how memory should be assigned for an acados
structure astruct
.
There are two functions: astruct_calculate_size()
, astruct_assign()
.
astruct_calculate_size()
¶
Must return a multiple of 8 to keep the pointer aligned to 8 bytes when allocating substructures. Thus, it should end with:
make_int_multiple_of(8, &size);
astruct_assign()
¶
Should assign its members in the following order:
Align to 8 bytes, i.e.:
align_char_to(8, &c_ptr);
Assign structure itself, i.e.:
astruct *as_instance = (astruct *) c_ptr;
c_ptr += sizeof(astruct);
Assign pointers to substructures, if
astruct
contains an array ofbstruct
s, e.g.
mem->bstructs = (void **) c_ptr;
c_ptr += N*sizeof(void *);
Align to 8 bytes, since
astruct
might containint
s and the pointers were assigned.Assign “substructures”, i.e. structures that
astruct
has pointers to:
// assume astruct contains an instance of bstruct
as_instance->bstruct = bstruct_assign(c_ptr,...);
c_ptr += bstruct_calculate_size(astruct);
Note:
since calculate_size returns multiple of 8,
c_ptr
is still aligned to 8 bytes.blasfeo_dmat_structs
,blasfeo_dvec_structs
can be seen as “substructures” here.
Assign doubles (are 8 bytes anyway)
assign_and_advance_double(n_doubles, &as_instance->doubles, &c_ptr);
Assign pointers (4 bytes on 32 Bit)
assign_and_advance_double_ptrs(n_pointers, &as_instance->double_pointer, &c_ptr);
Align to 8 bytes, can be skipped if no pointers have been assigned
Assign integers
assign_and_advance_int(n_integers, &as_instance->ints, &c_ptr);
Align to 64 bytes, i.e.:
align_char_to(64, &c_ptr);
Assign
blasfeo_dmat_mem
(are multiple of 64 Bytes)
assign_and_advance_blasfeo_dmat_mem(nrow, ncol, &as_instance->blasfeo_mat, &c_ptr);
Assign
blasfeo_vec_mem
(are multiple of 32 Bytes)
assign_and_advance_blasfeo_dvec_mem(n, &as_instance->blasfeo_vec, &c_ptr);
Align c_ptr to 8 byte here for nested assigns, see “substructures”
relevant if no
blasfeo_mems
are inastruct
Dense QP solution: Populating dense_qp_out
¶
After solving a dense QP, the solution should be stored in the dense_qp_out
structure that is passed as an argument to the function dense_qp_XXX
(where XXX
is the name of the solver).
This structure has to be populated with three things:
the primal solution,
the dual solution,
constraint slacks,
which corresponds to the fields v
, lam
, and t
, respectively, in the dense_qp_out
structure.
If there are, in addition, equality constraint their dual variables should be added to the field pi
.
Primal and soft slack variables¶
The field v
should be populated with variables in the following order:
primal, lower soft slack, upper soft slack
with the corresponding dimensions nv
,ns
,ns
.
Dual variables¶
The field lam
should be populated with dual variables corresponding to bounds in the following order:
lower bounds, lower general, upper bounds, upper general, lower soft slack, upper soft slack
with the corresponding dimensions nb
,ng
,nb
,ng
,ns
,ns
.
The sign convention used is that all dual variables are nonnegative, even the ones that correspond to lower bounds.
Constraint slacks¶
If v
has been set correctly, the constraint slack t
can be computed using the auxiliary function dense_qp_compute_t()
.