Coder Social home page Coder Social logo

zeta1999 / ifopt Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jwdinius/ifopt

0.0 1.0 0.0 177 KB

Eigen-based Interface to Nonlinear Programming Solvers IPOPT and SNOPT

Home Page: http://awinkler.me

License: BSD 3-Clause "New" or "Revised" License

CMake 9.24% C++ 90.76%

ifopt's Introduction

I created this fork because I wanted to learn more about CMake; particularly exporting/importing packages with different sets of dependencies. This repo was chosen because of its small number of source files, sufficient unit tests, and file structure with submodules. The submodules can be built together or separately. As a bonus, the ifopt_ipopt and ifopt_snopt submodules have third party dependencies to be built against.

The information below has been modified from the original repo to include build instructions for the reorganized pure CMake build support that I added.

Build Status DOI

Ifopt is a unified Eigen-based interface to use Nonlinear Programming solvers, such as Ipopt and Snopt. The user defines the solver independent optimization problem by set of C++ classes resembling variables, cost and constraints. Subsequently, the problem can then be solved with either solver. This package can be dropped in your catkin workspace.

Author/Maintainer: Alexander W. Winkler

               


... also we only need 981 lines of code (why this matters) to allow the generation of (1) solver independent problem formulations, (2) automatic ordering of independent variable and constraint sets in the overall problem, (3) Eigen sparse-matrix exploitation for fast performance, (4) constraint-jacobian and cost-gradient ordering and (5) implementation of interfaces to Ipopt and Snopt.

Building

  • Install Eigen: $ sudo apt-get install libeigen3-dev

  • Depending on which solver you want to use, install either Ipopt or Snopt. Follow the instructions provided here:

  • To build ifopt_snopt or ifopt_ipopt set the location of the shared libraries and header files directly in the CMakeLists.txt of the corresponding solver.

  • Navigate to desired directory and clone the repo there

    $ git clone https://github.com/jwdinius/ifopt.git
    
  • If you wish to build unit tests (recommended), create a third_party directory and clone googletest into it

    $ cd ifopt ; mkdir third_party ; cd third_party
    $ git clone https://github.com/google/googletest.git gtest
    
  • Configure the build (remove -DBUILD_TEST=True if you don't wish to build unit tests)

    $ cd .. ; mkdir build ; cd build ;
    $ cmake .. -DBUILD_TEST=True
    
  • Build with make

    $ make
    

Unit Tests

Make sure everything installed correctly by running the unit tests through

$ make test

This should also solve the example problem with your installed solvers. If you have IPOPT installed and linked correctly, this should also execute the binary ifopt_ipopt-test.

(Un)Install

You can install the build targets of this project to the CMake install location:

$ make install

You made need special privileges to install to this directory; in that case, prepend the command above with sudo. Similarly, you can uninstall/remove with

$ make uninstall

Again, you may need to use sudo.

Usage

For an example of how to use this to efficiently generate dynamic motions for legged robots, check-out towr. See test/ex_problem.h for a minimal example with detailed comments and explanation of the below code line by line. The optimization problem to solve is defined as:

#include <ifopt/test/ex_problem.h>
#include <ifopt_ipopt/ipopt_adapter.h>

int main() 
{
  Problem nlp;

  nlp.AddVariableSet  (std::make_shared<ExVariables>());
  nlp.AddConstraintSet(std::make_shared<ExConstraint>());
  nlp.AddCostSet      (std::make_shared<ExCost>());
  
  IpoptAdapter::Solve(nlp); // or SnoptAdapter::Solve(nlp);
  std::cout << nlp.GetOptVariables()->GetValues();
}

Output:

1.0 0.0

The 3 classes representing variables, costs and constraints are defined as in the following. The variables x0 and x1 with their bound -1 <= x0 <= 1 is formulated as follows:

class ExVariables : public VariableSet {
public:
  ExVariables() : VariableSet(2, "var_set1")
  { // initial values
    x0_ = 0.5;
    x1_ = 1.5;
  }

  virtual void SetVariables(const VectorXd& x)
  {
    x0_ = x(0);
    x1_ = x(1);
  };

  virtual VectorXd GetValues() const
  {
    return Vector2d(x0_, x1_);
  };

  VecBound GetBounds() const override
  {
    VecBound bounds(GetRows());
    bounds.at(0) = Bounds(-1.0, 1.0);
    bounds.at(1) = NoBound;
    return bounds;
  }

private:
  double x0_, x1_;
};

The example constraint 0 = x0^2 + x1 - 1 is formulated as follows:

class ExConstraint : public ConstraintSet {
public:
  ExConstraint() : ConstraintSet(1, "constraint1") {}

  virtual VectorXd GetValues() const override
  {
    VectorXd g(GetRows());
    Vector2d x = GetVariables()->GetComponent("var_set1")->GetValues();
    g(0) = std::pow(x(0),2) + x(1);
    return g;
  };

  VecBound GetBounds() const override
  {
    VecBound b(GetRows());
    b.at(0) = Bounds(1.0, 1.0);
    return b;
  }

  void FillJacobianBlock (std::string var_set, Jacobian& jac) const override
  {
    if (var_set == "var_set1") {
      Vector2d x = GetVariables()->GetComponent("var_set1")->GetValues();
      
      jac.coeffRef(0, 0) = 2.0*x(0); // derivative of first constraint w.r.t x0
      jac.coeffRef(0, 1) = 1.0;      // derivative of first constraint w.r.t x1
    }
  }
};

The example cost f(x) = -(x1-2)^2 is formulated as follows:

class ExCost: public CostTerm {
public:
  ExCost() : CostTerm("cost_term1") {}

  virtual double GetCost() const override
  {
    Vector2d x = GetVariables()->GetComponent("var_set1")->GetValues();
    return -std::pow(x(1)-2,2);
  };

  void FillJacobianBlock (std::string var_set, Jacobian& jac) const override
  {
    if (var_set == "var_set1") {
      Vector2d x = GetVariables()->GetComponent("var_set1")->GetValues();

      jac.coeffRef(0, 0) = 0.0;             // derivative of cost w.r.t x0
      jac.coeffRef(0, 1) = -2.0*(x(1)-2.0); // derivative of cost w.r.t x1
    }
  }
};

Publications

If you use this work in an academic context, please consider citing the currently released version DOI as shown here.

Bugs & Feature Requests

Please report bugs and request features using the Issue Tracker.

ifopt's People

Contributors

awinkler avatar depardo avatar jwdinius avatar traversaro avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.