# 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 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.; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  os 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  casadi  import  * 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  . utils  import  ALLOWED_CASADI_VERSIONS ,  is_empty ,  casadi_length ,  casadi_version_warning 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  generate_c_code_constraint (  model ,  con_name ,  is_terminal ,  opts  ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    casadi_version  =  CasadiMeta . version ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    casadi_opts  =  dict ( mex = False ,  casadi_int = ' int ' ,  casadi_real = ' double ' ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  casadi_version  not  in  ( ALLOWED_CASADI_VERSIONS ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        casadi_version_warning ( casadi_version ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # load constraint variables and expression 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    x  =  model . x 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    p  =  model . p 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  isinstance ( x ,  casadi . MX ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        symbol  =  MX . sym 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        symbol  =  SX . sym 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  is_terminal : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        con_h_expr  =  model . con_h_expr_e 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        con_phi_expr  =  model . con_phi_expr_e 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # create dummy u, z 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        u  =  symbol ( ' u ' ,  0 ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        z  =  symbol ( ' z ' ,  0 ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        con_h_expr  =  model . con_h_expr 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        con_phi_expr  =  model . con_phi_expr 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        u  =  model . u 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        z  =  model . z 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( not  is_empty ( con_h_expr ) )  and  ( not  is_empty ( con_phi_expr ) ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        raise  Exception ( " acados: you can either have constraint_h, or constraint_phi, not both. " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  ( is_empty ( con_h_expr )  and  is_empty ( con_phi_expr ) ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  is_empty ( con_h_expr ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constr_type  =  ' BGP ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constr_type  =  ' BGH ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  is_empty ( p ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p  =  symbol ( ' p ' ,  0 ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  is_empty ( z ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            z  =  symbol ( ' z ' ,  0 ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  ( is_empty ( con_h_expr ) )  and  opts [ ' generate_hess ' ] : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # multipliers for hessian 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            nh  =  casadi_length ( con_h_expr ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            lam_h  =  symbol ( ' lam_h ' ,  nh ,  1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # set up & change directory 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        code_export_dir  =  opts [ " code_export_directory " ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  os . path . exists ( code_export_dir ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            os . makedirs ( code_export_dir ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cwd  =  os . getcwd ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        os . chdir ( code_export_dir ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gen_dir  =  con_name  +  ' _constraints ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  os . path . exists ( gen_dir ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            os . mkdir ( gen_dir ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        gen_dir_location  =  os . path . join ( ' . ' ,  gen_dir ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        os . chdir ( gen_dir_location ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # export casadi functions 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  constr_type  ==  ' BGH ' : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  is_terminal : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fun_name  =  con_name  +  ' _constr_h_e_fun_jac_uxt_zt ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fun_name  =  con_name  +  ' _constr_h_fun_jac_uxt_zt ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            jac_ux_t  =  transpose ( jacobian ( con_h_expr ,  vertcat ( u , x ) ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            jac_z_t  =  jacobian ( con_h_expr ,  z ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constraint_fun_jac_tran  =  Function ( fun_name ,  [ x ,  u ,  z ,  p ] ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    [ con_h_expr ,  jac_ux_t ,  jac_z_t ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constraint_fun_jac_tran . generate ( fun_name ,  casadi_opts ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  opts [ ' generate_hess ' ] : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  is_terminal : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    fun_name  =  con_name  +  ' _constr_h_e_fun_jac_uxt_zt_hess ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    fun_name  =  con_name  +  ' _constr_h_fun_jac_uxt_zt_hess ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # adjoint 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                adj_ux  =  jtimes ( con_h_expr ,  vertcat ( u ,  x ) ,  lam_h ,  True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # hessian 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                hess_ux  =  jacobian ( adj_ux ,  vertcat ( u ,  x ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                adj_z  =  jtimes ( con_h_expr ,  z ,  lam_h ,  True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                hess_z  =  jacobian ( adj_z ,  z ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # set up functions 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                constraint_fun_jac_tran_hess  =  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Function ( fun_name ,  [ x ,  u ,  lam_h ,  z ,  p ] ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      [ con_h_expr ,  jac_ux_t ,  hess_ux ,  jac_z_t ,  hess_z ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # generate C code 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                constraint_fun_jac_tran_hess . generate ( fun_name ,  casadi_opts ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  is_terminal : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fun_name  =  con_name  +  ' _constr_h_e_fun ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fun_name  =  con_name  +  ' _constr_h_fun ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            h_fun  =  Function ( fun_name ,  [ x ,  u ,  z ,  p ] ,  [ con_h_expr ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            h_fun . generate ( fun_name ,  casadi_opts ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else :  # BGP constraint 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  is_terminal : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fun_name  =  con_name  +  ' _phi_e_constraint ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                r  =  model . con_r_in_phi_e 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                con_r_expr  =  model . con_r_expr_e 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fun_name  =  con_name  +  ' _phi_constraint ' 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                r  =  model . con_r_in_phi 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                con_r_expr  =  model . con_r_expr 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            nphi  =  casadi_length ( con_phi_expr ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            con_phi_expr_x_u_z  =  substitute ( con_phi_expr ,  r ,  con_r_expr ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phi_jac_u  =  jacobian ( con_phi_expr_x_u_z ,  u ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phi_jac_x  =  jacobian ( con_phi_expr_x_u_z ,  x ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phi_jac_z  =  jacobian ( con_phi_expr_x_u_z ,  z ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            hess  =  hessian ( con_phi_expr [ 0 ] ,  r ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  i  in  range ( 1 ,  nphi ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                hess  =  vertcat ( hess ,  hessian ( con_phi_expr [ i ] ,  r ) [ 0 ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            r_jac_u  =  jacobian ( con_r_expr ,  u ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            r_jac_x  =  jacobian ( con_r_expr ,  x ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constraint_phi  =  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Function ( fun_name ,  [ x ,  u ,  z ,  p ] ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    [ con_phi_expr_x_u_z ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    vertcat ( transpose ( phi_jac_u ) ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    transpose ( phi_jac_x ) ) ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    transpose ( phi_jac_z ) ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    hess ,  vertcat ( transpose ( r_jac_u ) ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    transpose ( r_jac_x ) ) ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constraint_phi . generate ( fun_name ,  casadi_opts ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # change directory back 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        os . chdir ( cwd ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return