How to use User-defined function to Nonlinear programming in C++?

443 views
Skip to first unread message

li guo

unread,
May 3, 2022, 4:55:42 AM5/3/22
to CasADi
Dear 
  I use the casadi/ipopt to trajectory optimization, the objective function contain trajectory  safe part(is calculated by ESDF map), the question is similar the one to https://groups.google.com/g/casadi-users/c/e0SUhcvH-aI. So I begen to learn how to  use User-defined function to  Nonlinear programming. 

For example, the nonlinear programming question is   the one form https://groups.google.com/g/casadi-users/c/zvy3FjcB8Lo/m/gOUZrcWlAQAJ
 min  sin(x[0]+p)    ,
MX x= MX::sym("x",2,1)    is the decision variable.
MX p= MX::sym("p",1,1)     is a known parameter vector.

Just like https://groups.google.com/g/casadi-users/c/4mAvpRqCs8o and the code  is in the attachment
I get error information is 

CasADi - 2022-05-03 16:47:15 WARNING("nlp_solver_:nlp_grad_f failed:Error in Function::operator() for 'nlp_grad_f' [MXFunction] at .../casadi/core/function.cpp:1368:
Error in Function::operator() for 'jac_my_sin' [CallbackInternal] at .../casadi/core/function.cpp:1368:
.../casadi/core/function_internal.cpp:3366: Failed to evaluate 'eval_dm' for jac_my_sin:
.../casadi/core/callback_internal.cpp:122: Error calling "eval" for object jac_my_sin:
.../casadi/core/callback_internal.cpp:122: Assertion "(self_)!=0" failed:
Callback object has been deleted") [.../casadi/core/oracle_function.cpp:223]
CasADi - 2022-05-03 16:47:15 WARNING("nlp_solver_:nlp_grad_f failed:Error in Function::operator() for 'nlp_grad_f' [MXFunction] at .../casadi/core/function.cpp:1368:
Error in Function::operator() for 'jac_my_sin' [CallbackInternal] at .../casadi/core/function.cpp:1368:
.../casadi/core/function_internal.cpp:3366: Failed to evaluate 'eval_dm' for jac_my_sin:
.../casadi/core/callback_internal.cpp:122: Error calling "eval" for object jac_my_sin:
.../casadi/core/callback_internal.cpp:122: Assertion "(self_)!=0" failed:
Callback object has been deleted") [.../casadi/core/oracle_function.cpp:223]
CasADi - 2022-05-03 16:47:15 WARNING("nlp_solver_:nlp_grad failed:Error in Function::operator() for 'nlp_grad' [MXFunction] at .../casadi/core/function.cpp:1368:
Error in Function::operator() for 'jac_my_sin' [CallbackInternal] at .../casadi/core/function.cpp:1368:
.../casadi/core/function_internal.cpp:3366: Failed to evaluate 'eval_dm' for jac_my_sin:
.../casadi/core/callback_internal.cpp:122: Error calling "eval" for object jac_my_sin:
.../casadi/core/callback_internal.cpp:122: Assertion "(self_)!=0" failed:
Callback object has been deleted") [.../casadi/core/oracle_function.cpp:223]
CasADi - 2022-05-03 16:47:15 WARNING("Failed to calculate multipliers") [.../casadi/core/nlpsol.cpp:621]

So, my question is how to solve the error and how to use user-defined function to nonlinear optimization? Can someone give me some examples in c++ to learn? 

Thank you very much!!
main.cpp

li guo

unread,
May 4, 2022, 9:54:04 PM5/4/22
to CasADi
I have solved the problem, refer to https://github.com/casadi/casadi/issues/2490.

The code:

#include <iostream>
#include <casadi/casadi.hpp>

using namespace casadi;
using namespace std;

class MyCallback : public casadi::Callback {
public:
MyCallback(const std::string& name,const casadi::Dict& opts = casadi::Dict())
{
construct(name, opts);
}
~MyCallback() override {}

// Number of inputs.
casadi_int get_n_in() override { return 2;}

// Number of outputs.
casadi_int get_n_out() override { return 1;}

// Set sparsity of input.
casadi::Sparsity get_sparsity_in(casadi_int i) override {
if(i==0) return casadi::Sparsity::dense(2, 1);
else if (i==1) return casadi::Sparsity::dense(1, 1);
}
// Set sparsity of output.
casadi::Sparsity get_sparsity_out(casadi_int i) override {
return casadi::Sparsity::dense(1, 1);
}

void init() override {
std::cout << "initializing_object! " << std::endl;
}

// Evaluate numerically.
std::vector<casadi::DM> eval(const std::vector<casadi::DM>& arg) const override {
// std::cout << "thie is my evaluating jacobian callback" << std::endl;
DM x= arg[0];
DM p= arg[1];
DM f= sin(x(0)+p);
return {f};
}
bool has_jacobian() const override {return true; }

casadi::Function get_jacobian(const std::string&name, const std::vector<std::string>& inames, const std::vector<std::string> &onames,
const casadi::Dict &opts) const override {
MX x = MX::sym("x",2,1);
MX p = MX::sym("p",1,1);
MX f = MX::sym("f",1,1);
MX res=MX::horzcat({cos(x(0)+p),0,0});
Function f_jac =Function(name,{x,p,f},{res});
return f_jac;
}

};

int main()
{
auto test =MyCallback("my_sin");
std::cout<<test;
MXDict arg,res;
MX x= MX::sym("x",2,1);
MX p= MX::sym("p",1,1);
arg["i0"]=x;
arg["i1"]=p;
MXDict nlp = {{"x", x},{"p",p},{"f",test(arg).at("o0")},{"g",x(1)}};
std::cout<<nlp;
Dict nlp_config_ = {{"ipopt", Dict({{"linear_solver", "ma27"},
{"hessian_approximation","limited-memory"}})}};
Function nlp_solver_=nlpsol("nlp_solver_", "ipopt", nlp,nlp_config_);
std::cout<<nlp_solver_;

DMDict arguments,result;
arguments["x0"]=1.57;
arguments["lbx"]=0;
arguments["ubx"]=3.14;
arguments["p"]=0;
arguments["lbg"]=1;
arguments["ubg"]=1;

result=nlp_solver_(arguments);
std::cout<<result;

}

Tong Zhao

unread,
Jan 22, 2023, 7:51:26 PM1/22/23
to CasADi
Hi,

Thank you for posting your solutions. May I ask a very simple question: what is your operating system, and what steps did you perform to make your C++ program compile successfully with the CasADi binary package you downloaded?

I use Visual Studio, but I cannot find out how to resolve linking problems as they appear. Do you use Visual Studio, or do you just use terminal to link and compile your C++ program with CasADi? A sample terminal command example would be appreciated if possible.

In addition, did you have to set up environment variables like PATH in your OS? I am using Windows 10. I am unable to get the simplest CasADi C++ program running yet.

Thank you.

Reply all
Reply to author
Forward
0 new messages