# # Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, # Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, # Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, # Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl # # This file is part of acados. # # The 2-Clause BSD License # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE.; # {%- if solver_options.qp_solver %} {%- set qp_solver = solver_options.qp_solver %} {%- else %} {%- set qp_solver = "FULL_CONDENSING_HPIPM" %} {%- endif %} {%- if solver_options.hessian_approx %} {%- set hessian_approx = solver_options.hessian_approx %} {%- elif solver_options.sens_hess %} {%- set hessian_approx = "EXACT" %} {%- else %} {%- set hessian_approx = "GAUSS_NEWTON" %} {%- endif %} {%- if constraints.constr_type %} {%- set constr_type = constraints.constr_type %} {%- else %} {%- set constr_type = "NONE" %} {%- endif %} {%- if constraints.constr_type_e %} {%- set constr_type_e = constraints.constr_type_e %} {%- else %} {%- set constr_type_e = "NONE" %} {%- endif %} {%- if cost.cost_type %} {%- set cost_type = cost.cost_type %} {%- else %} {%- set cost_type = "NONE" %} {%- endif %} {%- if cost.cost_type_e %} {%- set cost_type_e = cost.cost_type_e %} {%- else %} {%- set cost_type_e = "NONE" %} {%- endif %} {%- if cost.cost_type_0 %} {%- set cost_type_0 = cost.cost_type_0 %} {%- else %} {%- set cost_type_0 = "NONE" %} {%- endif %} {%- if dims.nh %} {%- set dims_nh = dims.nh %} {%- else %} {%- set dims_nh = 0 %} {%- endif %} {%- if dims.nphi %} {%- set dims_nphi = dims.nphi %} {%- else %} {%- set dims_nphi = 0 %} {%- endif %} {%- if dims.nh_e %} {%- set dims_nh_e = dims.nh_e %} {%- else %} {%- set dims_nh_e = 0 %} {%- endif %} {%- if dims.nphi_e %} {%- set dims_nphi_e = dims.nphi_e %} {%- else %} {%- set dims_nphi_e = 0 %} {%- endif %} {%- if solver_options.model_external_shared_lib_dir %} {%- set model_external_shared_lib_dir = solver_options.model_external_shared_lib_dir %} {%- endif %} {%- if solver_options.model_external_shared_lib_name %} {%- set model_external_shared_lib_name = solver_options.model_external_shared_lib_name %} {%- endif %} {#- control operator #} {%- if os and os == "pc" %} {%- set control = "&" %} {%- else %} {%- set control = ";" %} {%- endif %} {%- if acados_link_libs and os and os == "pc" %}{# acados linking libraries and flags #} {%- set link_libs = acados_link_libs.qpoases ~ " " ~ acados_link_libs.hpmpc ~ " " ~ acados_link_libs.osqp -%} {%- set openmp_flag = acados_link_libs.openmp %} {%- else %} {%- set openmp_flag = " " %} {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} {%- set link_libs = "-lqpOASES_e" %} {%- else %} {%- set link_libs = "" %} {%- endif %} {%- endif %} cmake_minimum_required(VERSION 3.10) project({{ model.name }}) # build options. option(BUILD_ACADOS_SOLVER_LIB "Should the solver library acados_solver_{{ model.name }} be build?" OFF) option(BUILD_ACADOS_OCP_SOLVER_LIB "Should the OCP solver library acados_ocp_solver_{{ model.name }} be build?" OFF) option(BUILD_EXAMPLE "Should the example main_{{ model.name }} be build?" OFF) {%- if solver_options.integrator_type != "DISCRETE" %} option(BUILD_SIM_EXAMPLE "Should the simulation example main_sim_{{ model.name }} be build?" OFF) option(BUILD_ACADOS_SIM_SOLVER_LIB "Should the simulation solver library acados_sim_solver_{{ model.name }} be build?" OFF) {%- endif %} # object target names set(MODEL_OBJ model_{{ model.name }}) set(OCP_OBJ ocp_{{ model.name }}) set(SIM_OBJ sim_{{ model.name }}) # model set(MODEL_SRC {%- if solver_options.integrator_type == "ERK" %} {{ model.name }}_model/{{ model.name }}_expl_ode_fun.c {{ model.name }}_model/{{ model.name }}_expl_vde_forw.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_model/{{ model.name }}_expl_ode_hess.c {%- endif %} {%- elif solver_options.integrator_type == "IRK" %} {{ model.name }}_model/{{ model.name }}_impl_dae_fun.c {{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_z.c {{ model.name }}_model/{{ model.name }}_impl_dae_jac_x_xdot_u_z.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_model/{{ model.name }}_impl_dae_hess.c {%- endif %} {%- elif solver_options.integrator_type == "LIFTED_IRK" %} {{ model.name }}_model/{{ model.name }}_impl_dae_fun.c {{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_u.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_model/{{ model.name }}_impl_dae_hess.c {%- endif %} {%- elif solver_options.integrator_type == "GNSF" %} {% if model.gnsf.purely_linear != 1 %} {{ model.name }}_model/{{ model.name }}_gnsf_phi_fun.c {{ model.name }}_model/{{ model.name }}_gnsf_phi_fun_jac_y.c {{ model.name }}_model/{{ model.name }}_gnsf_phi_jac_y_uhat.c {% if model.gnsf.nontrivial_f_LO == 1 %} {{ model.name }}_model/{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz.c {%- endif %} {%- endif %} {{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c {%- elif solver_options.integrator_type == "DISCRETE" %} {%- if model.dyn_ext_fun_type == "casadi" %} {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun.c {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac_hess.c {%- endif %} {%- else %} {{ model.name }}_model/{{ model.dyn_source_discrete }} {%- endif %} {%- endif -%} ) add_library(${MODEL_OBJ} OBJECT ${MODEL_SRC} ) # optimal control problem - mostly CasADi exports if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_ACADOS_OCP_SOLVER_LIB} OR ${BUILD_EXAMPLE}) set(OCP_SRC {%- if constr_type == "BGP" and dims_nphi > 0 %} {{ model.name }}_constraints/{{ model.name }}_phi_constraint.c {%- endif %} {%- if constr_type_e == "BGP" and dims_nphi_e > 0 %} {{ model.name }}_constraints/{{ model.name }}_phi_e_constraint.c {%- endif %} {%- if constr_type == "BGH" and dims_nh > 0 %} {{ model.name }}_constraints/{{ model.name }}_constr_h_fun_jac_uxt_zt.c {{ model.name }}_constraints/{{ model.name }}_constr_h_fun.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_constraints/{{ model.name }}_constr_h_fun_jac_uxt_zt_hess.c {%- endif %} {%- endif %} {%- if constr_type_e == "BGH" and dims_nh_e > 0 %} {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_zt.c {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_zt_hess.c {%- endif %} {%- endif %} {%- if cost_type_0 == "NONLINEAR_LS" %} {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun.c {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun_jac_ut_xt.c {{ model.name }}_cost/{{ model.name }}_cost_y_0_hess.c {%- elif cost_type_0 == "EXTERNAL" %} {%- if cost.cost_ext_fun_type_0 == "casadi" %} {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun.c {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun_jac.c {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun_jac_hess.c {%- else %} {{ model.name }}_cost/{{ cost.cost_source_ext_cost_0 }} {%- endif %} {%- endif %} {%- if cost_type == "NONLINEAR_LS" %} {{ model.name }}_cost/{{ model.name }}_cost_y_fun.c {{ model.name }}_cost/{{ model.name }}_cost_y_fun_jac_ut_xt.c {{ model.name }}_cost/{{ model.name }}_cost_y_hess.c {%- elif cost_type == "EXTERNAL" %} {%- if cost.cost_ext_fun_type == "casadi" %} {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun.c {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun_jac.c {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun_jac_hess.c {%- elif cost.cost_source_ext_cost != cost.cost_source_ext_cost_0 %} {{ model.name }}_cost/{{ cost.cost_source_ext_cost }} {%- endif %} {%- endif %} {%- if cost_type_e == "NONLINEAR_LS" %} {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun.c {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun_jac_ut_xt.c {{ model.name }}_cost/{{ model.name }}_cost_y_e_hess.c {%- elif cost_type_e == "EXTERNAL" %} {%- if cost.cost_ext_fun_type_e == "casadi" %} {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun.c {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac.c {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac_hess.c {%- elif cost.cost_source_ext_cost_e != cost.cost_source_ext_cost_0 %} {{ model.name }}_cost/{{ cost.cost_source_ext_cost_e }} {%- endif %} {%- endif %} acados_solver_{{ model.name }}.c) add_library(${OCP_OBJ} OBJECT ${OCP_SRC}) endif() {%- if solver_options.integrator_type != "DISCRETE" %} # for sim solver if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_EXAMPLE} {%- if solver_options.integrator_type != "DISCRETE" %} OR ${BUILD_SIM_EXAMPLE} OR ${BUILD_ACADOS_SIM_SOLVER_LIB} {%- endif -%} ) set(SIM_SRC acados_sim_solver_{{ model.name }}.c) add_library(${SIM_OBJ} OBJECT ${SIM_SRC}) endif() {%- endif %} # for target example set(EX_SRC main_{{ model.name }}.c) set(EX_EXE main_{{ model.name }}) {%- if model_external_shared_lib_dir and model_external_shared_lib_name %} set(EXTERNAL_DIR {{ model_external_shared_lib_dir }}) set(EXTERNAL_LIB {{ model_external_shared_lib_name }}) {%- else %} set(EXTERNAL_DIR) set(EXTERNAL_LIB) {%- endif %} # set some search paths for preprocessor and linker set(ACADOS_INCLUDE_PATH {{ acados_include_path }} CACHE PATH "Define the path which contains the include directory for acados.") set(ACADOS_LIB_PATH {{ acados_lib_path }} CACHE PATH "Define the path which contains the lib directory for acados.") # c-compiler flags for debugging set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb") set(CMAKE_C_FLAGS " {%- if qp_solver == "FULL_CONDENSING_QPOASES" -%} -DACADOS_WITH_QPOASES {%- endif -%} {%- if qp_solver == "PARTIAL_CONDENSING_OSQP" -%} -DACADOS_WITH_OSQP {%- endif -%} {%- if qp_solver == "PARTIAL_CONDENSING_QPDUNES" -%} -DACADOS_WITH_QPDUNES {%- endif -%} -fPIC -std=c99 {{ openmp_flag }}") #-fno-diagnostics-show-line-numbers -g include_directories( ${ACADOS_INCLUDE_PATH} ${ACADOS_INCLUDE_PATH}/acados ${ACADOS_INCLUDE_PATH}/blasfeo/include ${ACADOS_INCLUDE_PATH}/hpipm/include {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} ${ACADOS_INCLUDE_PATH}/qpOASES_e/ {%- endif %} ) # linker flags link_directories(${ACADOS_LIB_PATH}) # link to libraries if(UNIX) link_libraries(acados hpipm blasfeo m {{ link_libs }}) else() link_libraries(acados hpipm blasfeo {{ link_libs }}) endif() # the targets # bundled_shared_lib if(${BUILD_ACADOS_SOLVER_LIB}) set(LIB_ACADOS_SOLVER acados_solver_{{ model.name }}) add_library(${LIB_ACADOS_SOLVER} SHARED $ $ {%- if solver_options.integrator_type != "DISCRETE" %} $ {%- endif -%} ) install(TARGETS ${LIB_ACADOS_SOLVER} DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(${BUILD_ACADOS_SOLVER_LIB}) # ocp_shared_lib if(${BUILD_ACADOS_OCP_SOLVER_LIB}) set(LIB_ACADOS_OCP_SOLVER acados_ocp_solver_{{ model.name }}) add_library(${LIB_ACADOS_OCP_SOLVER} SHARED $ $) # Specify libraries or flags to use when linking a given target and/or its dependents. target_link_libraries(${LIB_ACADOS_OCP_SOLVER} PRIVATE ${EXTERNAL_LIB}) target_link_directories(${LIB_ACADOS_OCP_SOLVER} PRIVATE ${EXTERNAL_DIR}) install(TARGETS ${LIB_ACADOS_OCP_SOLVER} DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(${BUILD_ACADOS_OCP_SOLVER_LIB}) # example if(${BUILD_EXAMPLE}) add_executable(${EX_EXE} ${EX_SRC} $ $ {%- if solver_options.integrator_type != "DISCRETE" %} $ {%- endif -%} ) install(TARGETS ${EX_EXE} DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(${BUILD_EXAMPLE}) {% if solver_options.integrator_type != "DISCRETE" -%} # example_sim if(${BUILD_SIM_EXAMPLE}) set(EX_SIM_SRC main_sim_{{ model.name }}.c) set(EX_SIM_EXE main_sim_{{ model.name }}) add_executable(${EX_SIM_EXE} ${EX_SIM_SRC} $ $) install(TARGETS ${EX_SIM_EXE} DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(${BUILD_SIM_EXAMPLE}) # sim_shared_lib if(${BUILD_ACADOS_SIM_SOLVER_LIB}) set(LIB_ACADOS_SIM_SOLVER acados_sim_solver_{{ model.name }}) add_library(${LIB_ACADOS_SIM_SOLVER} SHARED $ $) install(TARGETS ${LIB_ACADOS_SIM_SOLVER} DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(${BUILD_ACADOS_SIM_SOLVER_LIB}) {%- endif %}