Coder Social home page Coder Social logo

giaf / hpipm Goto Github PK

View Code? Open in Web Editor NEW
504.0 19.0 124.0 7.68 MB

High-performance interior-point-method QP and QCQP solvers

License: Other

Makefile 1.59% C 90.29% CMake 0.42% MATLAB 4.44% Shell 0.10% TeX 0.14% Python 2.88% Julia 0.14%
high-performance interior-point-method optimal-control

hpipm's Introduction

This is HPIPM, a high-performance interior-point method solver for dense, optimal control- and tree-structured convex quadratic programs (QP) and quadratically-constrained quadratic programs (QCQP). It provides efficient implementations of dense and structure-exploiting algorithms to solve small to medium scale problems arising in model predictive control and embedded optimization in general and it relies on the high-performance linear algebra package BLASFEO.

HPIPM (and BLASFEO, which is a dependency), comes with both make and cmake build systems. The preferred one is make, which can be used to compile and run any library, interface and example in any language. make is also used in the continuous integration travis scripts. cmake can only be used to compile the libraries, while the interested user should compile interfaces and run examples by him/herself by taking inspiration form the commands in the various Makefiles.


Getting Started:

The best way to get started with HPIPM is to check out the examples in /hpipm/examples/. HPIPM can be directly used from C, but there are also interfaces to Python and Matlab. Depending on which level you want to use HPIPM, check out the following section below. The QP notation used in HPIPM can be found in the doc folder.

C

In order to run the C examples in /hpipm/examples/C/ follow the steps below:

  1. Clone BLASFEO on your machine: git clone https://github.com/giaf/blasfeo.git
  2. From the BLASFEO root folder, run make static_library -j 4 && sudo make install_static (default installation folder: /opt/blasfeo; if a different one is chosen, BLASFEO_PATH in HPIPM's Makefile.rule should be updated accordingly)
  3. From the HPIPM root folder, run make static_library -j 4 && make examples
  4. In a terminal, navigate to /hpipm/examples/c/ and run getting_started.out to solve a simple OCP-structured QP.

MATLAB and Octave

Linux

The interface for Matlab and Octave is based on mex files.

  1. Clone BLASFEO on your machine: git clone https://github.com/giaf/blasfeo.git
  2. From the BLASFEO root folder, run make shared_library -j 4 && sudo make install_shared
  3. From the HPIPM root folder, run make shared_library -j 4 && sudo make install_shared
  4. In a terminal, navigate to the folder hpipm/interfaces/matlab_octave. Set the needed environment flags by running source env.sh (you may need to change the BLASFEO_MAIN_FOLDER, or to make it equal to the BLASFEO_PATH) in that folder. Compile the interface by running make all -j 4 (for Octave), or make compile_mex_with_matlab (for Matlab).
  5. In a terminal, navigate to the folder hpipm/examples/matlab_octave. Set the needed environment flags by running source env.sh (you may need to change the BLASFEO_MAIN_FOLDER, or to make it equal to the BLASFEO_PATH) in that folder. Run an instance of Matlab or Octave from the same terminal. Get started by running the examples in that folder.

MATLAB on Windows

The interface for Matlab and Octave is based on mex files.

  1. Clone BLASFEO on your machine: git clone https://github.com/giaf/blasfeo.git
  2. Install Microsoft Visual C++
  3. From the BLASFEO root folder, run
mkdir build
cd build
cmake ..
cmake --build .

Copy blasfeo.lib from build/Debug/ to lib/.

  1. From the HPIPM root folder, run
mkdir build
cd build
cmake ..
cmake --build .

(you may need to change the BLASFEO_PATH to the actual value matching your BLASFEO installation, e.g. by replacing the second last line above with cmake -DBLASFEO_PATH=/path/to/your/blasfeo/installation/folder ..). Copy hpipm.lib from build/Debug/ to lib/.

  1. Open Matlab and navigate to the folder hpipm/interfaces/matlab_octave. Set the needed environment flags by running env.m (you may need to change the BLASFEO_MAIN_FOLDER, or to make it equal to the BLASFEO_PATH) in that folder. Compile the interface by running compile_mex_all.m.

(Make sure that Matlab is configured to compile mex files with the same compiler as used in point 2), as sometimes by default it makes use of MinGW64 instead. If the HPIPM and BLASFEO libraries and the mex files are not all compiled with visual studio, or all compiled with MinGW64, errors about missing dependencies from the runtime library happen.)

  1. In Matlab, navigate to the folder hpipm/examples/matlab_octave. Get started by running the examples in that folder. You may need to add folder hpipm/interfaces/matlab_octave to the Matlab path.

Simulink

The QP model is read from the file qp_data.c, which can be generated using the C, matlab/octave or python interfaces.

  1. Follow the steps 1)-4) for the MATLAB interface.
  2. In a terminal, navigate to the folder hpipm/examples/simulink. Run make_sfun.m to compile the S-function, and load_paramaters.m to load some parameters used in the simulink model (e.g. horizon length, number of inputs and states) form qp_data.c.
  3. Open the simulink model hpipm_simulink_getting_started.slx and start the simulation.

Python

If you would like to try out the Python interface, check out the examples in /hpipm/examples/python/ after going through the following steps:

  1. Clone BLASFEO on your machine: git clone https://github.com/giaf/blasfeo.git
  2. From the BLASFEO root folder, run make shared_library -j 4 && sudo make install_shared
  3. From the HPIPM root folder, run make shared_library -j 4 && sudo make install_shared
  4. In a terminal, navigate to /hpipm/interfaces/python/hpipm_python and run pip install . or pip3 install . (depending on your python version).
  5. In a terminal, navigate to /hpipm/examples/python. Set the needed environment flags by running source env.sh (you may need to change the BLASFEO_MAIN_FOLDER, or to make it equal to the BLASFEO_PATH) in that folder. Alternatively you can make sure yourself that the location of the installed shared libraries is known to the system e.g. by running export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/blasfeo/lib:/opt/hpipm/lib (possibly after updating it to the chosen installation directories). Finally, run python example_qp_getting_started.py or python3 example_qp_getting_started.py (depending on your python version) to solve a simple OCP-structured QP.

Common mistakes:

Matrix format

For performance reasons, HPIPM uses an internal matrix (and vector) format based on BLASFEO own matrix (and vector) structs. The exact layout of the matrix elements in memory is implementation- and architecture-dependent, so it can't be just inspected directly.

However, in the C interface there are setter and getter routines to correctly populate these internal matrix (and vector) representations. By default these setter and getter routines expect matrices to be passed in column-major order, that is the default order in e.g. Matlab and optimized linear algebra libraries such as BLAS and LAPACK. There is also a versions of a few setter and getter routines that expect matrices to be passed in row-major order, and these routines are clearly marked using the wording _rowmaj at the end of the routine name. These routines are basically identical to the default (aka column-major) ones with the only difference that the input matrix is transposed while being packed in / unpacked from the internal format.

Notice that the memory layout of the elements in the column-major matrix order corresponds to the layout of the transposed of the same matrix in the row-major matrix order, and the other way around.

Also notice that in C a matrix represented as an array of arrays is stored in row-major order. Similarly, in Python a matrix represented using numpy as an array of arrays is also stored in row-major order. On the other hand, in Matlab a dense matrix is stored in column-major order. This can be source of confusion.


References:

  • G. Frison, M. Diehl. HPIPM: a high-performance quadratic programming framework for model predictive control. (2020) (arXiv preprint https://arxiv.org/abs/2003.02547)

  • G. Frison, J. Frey, F. Messerer, A. Zanelli, M. Diehl. Introducing the quadratically-constrained quadratic programming framework in HPIPM. (2022) (arXiv preprint https://arxiv.org/abs/2112.11872)

  • G. Frison, H.H. B. Sørensen, B. Dammann, and J.B. Jørgensen. High-performance small-scale solvers for linear model predictive control. In IEEE European Control Conference, pages 128–133. IEEE, 2014 - https://ieeexplore.ieee.org/document/6981589/

  • G. Frison, D. Kouzoupis, T. Sartor, A. Zanelli, M. Diehl. BLASFEO: Basic Linear Algebra Subroutines For Embedded Optimization. ACM Transactions on Mathematical Software (TOMS) (2018) (arXiv preprint https://arxiv.org/abs/1704.02457)

  • https://github.com/giaf/blasfeo


Notes:

  • HPIPM relies on the high-performance linear algebra library BLASFEO. BLASFEO provides several implementations optimized for different computer architectures, and it makes heavy use of assembly code. If you get the error Illegal instruction at run time, you are probably using a BLASFEO version (TARGET) unsupported by your CPU.

hpipm's People

Contributors

adamheins avatar aghezz1 avatar bnovoselnik avatar dkouzoup avatar dlcfort avatar freyjo avatar giaf avatar imciner2 avatar jiangyntech avatar lenvm avatar mishrasamiksha avatar nielsvd avatar nitesh4146 avatar reichardtj avatar roversch avatar sandmaennchen avatar tmmsartor avatar zanellia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hpipm's Issues

Possible Bug in Setting Contraints

First off, I'd like to say thanks to Gianluca and all contributors for supplying this really amazing piece of software. Great effort!

In playing with the python interface, I noticed that hpipm.d_ocp_qp_set("idxbx", np.arange(number_of_states), 0) gives me an error while hpipm.d_ocp_qp_set("Jbx", np.eye(number_of_states), 0) does not and my trials work.

Digging deeper, I found the following lines that all feature an odd:

if (nbx[ii>0])

if(nbx[ii>0])

if(nb[ii>0])

if(nbx[ii>0])

if(nb[ii>0])

I admit that I am not fully clear on the logic of the code and the memory layout, but I suspect it should read

if (nbx[ii] > 0)

Thanks for considering this issue.
Best
Jörg

TARGET discrepancy between BLASFEO and HPIPM

Deploying HPIPM on embedded hardware that does not support AVX seems to be a bit puzzling for non-developers: setting the BLASFEO target to GENERIC is expected to solve the issue, but it actually does not as the HPIPM target needs to be set to GENERIC too.

  1. Could there be a better way to handle targets in a more consistent way?
  2. Is the HPIPM's AVX target actually useful in terms of performance?

Optimization reaches minimal step length

Hello!
I have a question regarding solving an OCP. I have setup the problem, however the solver returns code 2 which indicates reaching the minimal step length. What exactly does this mean and does this indicate that my problem does not have a solution? Do you have suggestion on a workflow to debug such an issue?

Regards

API improvement proposal: OCP QP size as an array of structs

Numerous hpipm functions take the arguments that define a size of an OCP QP, for example:

int d_memsize_ocp_qp(int N, int *nx, int *nu, int *nb, int *ng, int *ns);

This creates several inconveniences:

  • At least 5 arrays must be declared and their memory properly (de-)allocated;
  • The functions have 5 arguments of the same type, which must be matched by their order. It is easy to make a mistake by mixing the order of arguments.
  • Every function that needs OCP QP sizes has 5 additional arguments.
  • If the way the size is defined changes (for example, ns is added), it changes the prototype of all functions which take size as an argument.

This can be simplified by putting the sizes corresponding to a single OCP QP stage in a struct:

struct ocp_qp_size
{
    int nx;
    int nu;
    int nb;
    int ng;
    int ns;
};

Then, the prototype of the function above and similar functions will change to

int d_memsize_ocp_qp(int N, ocp_qp_size const * size);

which is much shorter. Furthermore, the chance of confusing different components of the size decreases because of the explicit names in the assignments:

ocp_qp_size size[N];

for (int i = 0; i < N; ++i)
{
    size[i].nx = NX;
    size[i].nu = NU;
    size[i].nb = 1;
    size[i].ng = 0;
    size[i].ns = 0;
}

d_memsize_ocp_qp(N, size);

Extracting feedback-gain matrices from d_ocp_qp_ipm_ws

Dear @giaf ,

in closed-loop single shooting SQP algorithms, like iLQR, we usually use the time-varying LQR feedback from the riccati recursion to forward simulate the system dynamics (generate a roll-out) in the next SQP iteration.

Here is an example how I reconstructed the LQR-feedback gains from the ocp_qp_ipm workspace after successful OCP solution (code), based on the ct-v2 tag of hpipm:

For all stages except for the first one, i.e. i=2,...,N

    Eigen::Matrix<double, control_dim, control_dim> Lr;    
    Eigen::Matrix<double, state_dim, control_dim> Ls;
    for (int i = 1; i < N; i++)
    {
        ::d_cvt_strmat2mat(Lr.rows(), Lr.cols(), &workspace_.L[i], 0, 0, Lr.data(), Lr.rows());
        ::d_cvt_strmat2mat(Ls.rows(), Ls.cols(), &workspace_.L[i], Lr.rows(), 0, Ls.data(), Ls.rows());
        TVLQR_K_ [i] = (-Ls * Lr.partialPivLu().inverse()).transpose();
    }

For the first time-step, i=0, it was not so straightforward, in fact we had to reconstruct the feedback gain for the first stage methodically:

    // step 1: reconstruct Hessian for first time step H
    Eigen::Matrix<double, control_dim, control_dim> Lr;
    ::blasfeo_unpack_dmat(Lr.rows(), Lr.cols(), &workspace_.L[0], 0, 0, Lr.data(), Lr.rows());
    Eigen::Matrix<double, control_dim, control_dim> H;
    H = Lr.template triangularView<Eigen::Lower>() * Lr.transpose();  // Lr is cholesky of H

    // step2: reconstruct riccati matrix S[1] for second time-step
    Eigen::Matrix<double, state_dim, state_dim> Lq;
    ::blasfeo_unpack_dmat(Lq.rows(), Lq.cols(), &workspace_.L[1], control_dim, control_dim, Lq.data(), Lq.rows());
    Eigen::Matrix<double, state_dim, state_dim> S;
    S = Lq.template triangularView<Eigen::Lower>() * Lq.transpose();  // Lq is cholesky of S

    // step3 : compute tvlqr-feedback for first stage
    TVLQR_K_ [0] = (-H.inverse() *  (P_[0] + B_[0].transpose() * S * A_[0])); 

In above code, A_ and B_ refer to LTV-system matrices at respective stages, and P_ is obviously the second-order cost cross-term from an LQ OCP problem. TVLQR_K_ is the desired feedback matrix, and the ocp workspace is denoted "workspace_".

Now to the question: the issue is, that with the newest HPIPM release, I can still successfully reconstruct the TVLQR-feedback for stages 2...N, but it seems that the content of workspace_.L[0] has changed ? I fail in reconstructing appropriate TVLQR-feedback for the first time step.

Sorry for the lengthy introduction -- but would you mind commenting on as to what extent the meaning of the first entry of L, i.e. L[0], has changed in the workspace?

Thanks a lot in advance and all the best!

One slack variable for softening multiple constraints

I believe that it is currently not possible to have one slack variable assigned to soften multiple constraints. I.e., having a recurring index in idxs_rev. If I have this in e.g. a chain of masses problem, HPIPM does not seem to converge. If every soft constraint has its own pair of slacks all is fine.

Is this observation correct? If so, would it be a big effort to support this feature?

After browsing the code a bit, I came across possible show stoppers in the logic in (not sure if that's all though):

Make BLASFEO_INCLUDE_DIR user definable

Here the BLASFEO_INCLUDE_DIR is forced to be ${BLASFEO_PATH}/include. In blasfeo, the option BLASFEO_HEADERS_INSTALLATION_DIRECTORY is however configurable. It would therefore be more appropriate if BLASFEO_INCLUDE_DIR could be provided as an option. Either by making it an option() explicitly or by writing

set(BLASFEO_INCLUDE_DIR "${BLASFEO_PATH}/include" CACHE STRING "Path to BLASFEO header files.")

instead of

set(BLASFEO_INCLUDE_DIR "${BLASFEO_PATH}/include")

Fails with BUILD_SHARED_LIBS=ON

Fails to build the shared library:

ninja: error: '/opt/blasfeo/lib/libblasfeo.a', needed by 'libhpipm.so', missing and no known rule to make it

failure to link against blasfeo_dtrsm after upgrade to Ubuntu 18.04.

Dear @giaf
I recently upgraded one of my computers from Ubuntu 16.04 to Ubuntu 18.04, after which got an unexpected linking error against blasfeo (from hpipm).

/usr/local/lib/libhpipm.a(d_ocp_qp_ipm.c.o): In function `d_ocp_qp_ipm_get_ric_K':
d_ocp_qp_ipm.c:(.text+0x25d2): undefined reference to `blasfeo_dtrsm'
collect2: error: ld returned 1 exit status

It seems related to the feedback matrix getters that you implemented recently. I went back to an ubuntu 16.04 machine with exactly the same code, and can confirm that it still works there.
Would you have any pointers for me where to start debugging this?

MATLAB

Hi @giaf ,

I wanted to know if I could use this solver within a MATLAB/Simulink environment. Is it possible? If it is possible, how should I proceed with it? Maybe some starting points will help a lot. Looking forward to hear from you.

Kind regards
Pranjal Biswas

Dense QP solve always reaches maximum number of iterations only on embedded hardware

Hello again! :)

I prototyped an algorithm using hpipm's d_dense_qp functionalities in MATLAB/ Simulink, where everything goes according to plan: hpipm requires 2 iterations and outputs 0 as the solver status. When applying the algorithm to an embedded hardware, however, hpipm always reaches the maximum number of iterations (I increased the number until 100) and outputs 1 accordingly as the solver status.

Since I am not yet familiar with the solver options, I could use some help narrowing down where to start debugging. Which options/ tolerances have to be manipulated/ relaxed to check whether hpipm would ever find a solution? Are there typical procedures for debugging? Are there some output metrics that I should evaluate?

"library not loaded" for python interface

Hi,
First thank you for publishing this solver!

When I'm trying to install hpipm including the python interface I experienced the following issue when running getting_started.py:

OSError: dlopen(libhpipm.so, 6): Library not loaded: libblasfeo.so
Referenced from: /opt/hpipm/lib/libhpipm.so`
Reason: image not found

I'm pretty sure I strictly followed the steps and there's no other problem. Besides everything works well when using the C interface. I googled for the reported error but nothing seems helpful or similar to this one.

Below are more details regarding this issue:
(1) I got Successfully installed hpipm-python-0.1 at the end of step 5
(2) I do add the two libraries to path:

$ echo $LD_LIBRARY_PATH
:/opt/blasfeo/lib:/opt/hpipm/lib

(3) The library does exist in the directory:

$ cd /opt/hpipm/lib
$ ls -l
total 992
-rwxr-xr-x  1 root  wheel  505132 May 25 01:51 libhpipm.so

(4) My operating system is Mac OS X.

Thanks,
Francis

Clarify licenses

Thank you so much for providing this awesome library!

I noticed some inconsistencies in the licenses of some files. Most of them are 2-Clause BSD, but in the following files you include the GPL license:

  • CMakeLists.txt
  • Files in archive/
  • Files in examples/c/
  • Files in test_problems/
  • Files in interfaces/archive/octave/

Could you consider unifying the license terms of those files, so that it will be easier for others to use your library in non-GPL code?

One last thing: the file experimental/andrea/notes/syscop.bib is an external symbolic link that cannot be resolved.

Is it possible to make shared_library in win10 powershell?

Hey~, I want to use tihs code in matlab 2016b on win10, but it has a problem:

E:\EnZone\Desktop\MPCC\Matlab\hpipm\blasfeo> make shared_library -j4
Parsing Makefile.rule
process_begin: CreateProcess(NULL, uname -s, ...) failed.
make: Makefile.rule:119: pipe: No error
process_begin: CreateProcess(NULL, ulimit -s, ...) failed.
make: Makefile.rule:321: pipe: No such file or directory
'bc' is not an internal or external command, nor is it a runnable program or batch file.
touch ./include/blasfeo_target.h
process_begin: CreateProcess(NULL, touch ./include/blasfeo_target.h, ...) failed.
make (e=2): The specified file could not be found by the system。
make: *** [Makefile:865: target] Error 2

so I want to know Whether it need to be based on the linux system to run perfectly ??
And I'm a novice , I only want to I just want to see the results of the experiment https://github.com/alexliniger/MPCC.

mexa64 file for dense qp in MATLAB

Hello @giaf

I would like to use the dense QP solver in the MATLAB environment. I could find the mexa64 files for the OCP QP, but not for the dense QP.
As I have no experience in C, I was wondering if the generation of these mexa files is easy, and in case it is, I would like to ask if you planned to provide it?

Looking forward for an answer and best regards.

Using Slack Variables leads to asymmetric result in symmetric double integrator - User Error or Bug?

Dear Gianluca, thanks for maintaining this project!

I've been playing around with the ability to soften box constraints on the controls through the introduction of slack variables. However, in a simple 2-D double integrator problem with only quadratic costs, this resulted in a solution in which the x- and y-components of the the solution are not equal. This, however, cannot be due to symmetry in the set-up of the problem - the cost function is invariant under exchange of x and y and so are the initial condition and the terminal state. Both Blasfeo and HPIPM are on the latest version of master compiled using mingw64 on a windows machine with haswell architecture. Interface is Python.

I'm attaching the code to reproduce it and would be more than happy if this could be resolved. I'm a bit uncertain about the indexing of the slack variables, so maybe there is an easy solution - user error. I'm assuming the first $n^b_u$ slack variables correspond to the $n^b_u$ bounds on the controls, the following $n^b_x$ slack variables correspond to the box constraints on $x$ and the remaining $n_g$ slack variables correspond to the polytope constraints.

Thanks a lot for any help!

Best regards
Joerg

Here are the images produces the the code below:

without slacks all works as expected:
without_Slacks

with slacks things look different:
with_slacks

import os
os.environ['PATH'] = os.environ['PATH'] + ';D:\\github_repos\\hpipm\\lib'

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

import hpipm_python as hpipm


def draw_solution(qp_sol):
    u = np.row_stack([qp_sol.get('u', i).T for i in range(T)])
    x = np.row_stack([qp_sol.get('x', i).T for i in range(T+1)])

    fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(16, 4))
    ax1.plot(x, '.-', alpha=0.5)
    ax2.plot(u, '.-', alpha=0.5)
    ax3.plot(*x[:, :2].T,  '.-', alpha=0.5)

    ax1.set_title('State variables')
    ax2.set_title('Control Variables')
    ax3.set_title('Object Path')

    ax1.grid()
    ax2.grid()
    ax3.grid()

# A standard double Integrator, Delta t = 0.1, 
# with state x, y, vx, vy, ax, ay
A = np.array([
    [1.   , 0.   , 0.1  , 0.   , 0.005, 0.   ],
    [0.   , 1.   , 0.   , 0.1  , 0.   , 0.005],
    [0.   , 0.   , 1.   , 0.   , 0.1  , 0.   ],
    [0.   , 0.   , 0.   , 1.   , 0.   , 0.1  ],
    [0.   , 0.   , 0.   , 0.   , 1.   , 0.   ],
    [0.   , 0.   , 0.   , 0.   , 0.   , 1.   ]
])

# Control variables are dax, day
B = np.array([
    [0, 0],
    [0, 0],
    [0, 0],
    [0, 0],
    [1, 0],
    [0, 1]
])

nx, nu = A.shape[1], B.shape[1]

# Cost Matrices for State and Control 
Q = np.eye(nx)
R = np.eye(nu)

# Initial condition, we start from rest at 2, 2
x0 = np.array([2, 2, 0, 0, 0, 0])

# Bounds on Controls
u_lower = np.ones(nu) * -0.1
u_upper = np.ones(nu) *  0.1

# We only place slacks on controls
ns = nu

# Cost Matrices for Slacks - only L2 penalty
Zl = np.eye(ns) * 10
Zu = np.eye(ns) * 10
zl = np.ones(ns) * 0
zu = np.ones(ns) * 0

# Bounds on the slacks
sl = np.ones(ns) * 0.1
su = np.ones(ns) * 0.1

T = 50
mode = 'robust' # 'speed'

## First without slacks

dim = hpipm.hpipm_ocp_qp_dim(T)

dim.set('nx', nx, 0, T)     # number of states
dim.set('nu', nu, 0, T - 1) # number of inputs

dim.set('nbx', nx, 0)       # initial condition
dim.set('nbx', 0, 1, T)     # no bounds otherwise

dim.set('nbu', nu, 0, T - 1) # input limits

arg = hpipm.hpipm_ocp_qp_solver_arg(dim, mode)


qp = hpipm.hpipm_ocp_qp(dim)

# initial condition
qp.set('idxbx', np.arange(0, nx), 0)
qp.set('lbx', x0, 0)
qp.set('ubx', x0, 0)

for i in range(T):
    qp.set('A', A, i)
    qp.set('B', B, i)
    qp.set('Q', Q, i)
    qp.set('R', R, i)
    
    qp.set('idxbu', np.arange(0, nu), i)
    qp.set('lbu', u_lower, i)
    qp.set('ubu', u_upper, i)
    
# Terminal Cost
qp.set('Q', Q, T)

solver = hpipm.hpipm_ocp_qp_solver(dim, arg)
qp_sol = hpipm.hpipm_ocp_qp_sol(dim)
solver.solve(qp, qp_sol)

draw_solution(qp_sol)

### Now with Slacks

dim = hpipm.hpipm_ocp_qp_dim(T)

# Slacks only on the controls
dim.set('nsbu', ns, 0, T - 1)

dim.set('nx', nx, 0, T)     # number of states
dim.set('nu', nu, 0, T - 1) # number of inputs

dim.set('nbx', nx, 0)       # initial condition
dim.set('nbx', 0, 1, T)     # no bounds otherwise

dim.set('nbu', nu, 0, T - 1) # input limits

arg = hpipm.hpipm_ocp_qp_solver_arg(dim, mode)

qp = hpipm.hpipm_ocp_qp(dim)

# initial condition
qp.set('idxbx', np.arange(0, nx), 0)
qp.set('lbx', x0, 0)
qp.set('ubx', x0, 0)

for i in range(T):
    qp.set('A', A, i)
    qp.set('B', B, i)
    qp.set('Q', Q, i)
    qp.set('R', R, i)
    
    qp.set('idxbu', np.arange(0, nu), i)
    qp.set('lbu', u_lower, i)
    qp.set('ubu', u_upper, i)
    
    qp.set('idxs', np.arange(0, nu), i) # is this the right indexing?!
    qp.set('Zl', Zl, i)
    qp.set('Zu', Zu, i)
    qp.set('zl', zl, i)
    qp.set('zu', zu, i)
    
    qp.set('lls', sl, i)
    qp.set('lus', su, i)
    
# Terminal Cost
qp.set('Q', Q, T)

solver = hpipm.hpipm_ocp_qp_solver(dim, arg)
qp_sol = hpipm.hpipm_ocp_qp_sol(dim)
solver.solve(qp, qp_sol)

draw_solution(qp_sol)

API improvement proposal: OCP QP matrices as an array of structs

Similarly to #3, elements of an OCP QP create the same difficulties, to even bigger extent. They can also be conveniently united in a struct:

struct ocp_qp_stage
{
    double *A;
    double *B;
    double *b;
    double *Q;
    double *S; 
    double *R;
    double *q;
    double *r;
    int *idxb;
    double *lb;
    double *ub;
    double *C;
    double *D;
    double *lg;
    double *ug;
    double *Zl;
    double *Zu;
    double *zl;
    double *zu;
    int *idxs;
};

It is then enough to pass 1 argument to a function instead of 20. Compare

void d_cvt_colmaj_to_ocp_qp(double **A, double **B, double **b, double **Q, double **S, double **R, 
double **q, double **r, int **idxb, double **lb, double **ub, double **C, double **D, double **lg, 
double **ug, double **Zl, double **Zu, double **zl, double **zu, int **idxs, struct d_ocp_qp *qp);

to

void d_cvt_colmaj_to_ocp_qp(ocp_qp_stage const * stages, struct d_ocp_qp *qp);

Also in this way we can add new fields to ocp_qp_stage without changing function prototypes.

Build issue on Mac OSX

Hi there,

I'm having an issue building for MATLAB on a Mac running Catalina (10.15.7).

From the ~/blasfeo I run make shared_library -j4 && sudo make install_shared and get a very long list of errors:

Parsing Makefile.rule
touch ./include/blasfeo_target.h
echo "#ifndef TARGET_X64_INTEL_HASWELL" >  ./include/blasfeo_target.h
echo "#define TARGET_X64_INTEL_HASWELL" >> ./include/blasfeo_target.h
echo "#endif"                           >> ./include/blasfeo_target.h
echo "#ifndef TARGET_NEED_FEATURE_AVX2" >> ./include/blasfeo_target.h
echo "#define TARGET_NEED_FEATURE_AVX2" >> ./include/blasfeo_target.h
echo "#endif"                           >> ./include/blasfeo_target.h
echo "#ifndef TARGET_NEED_FEATURE_FMA"  >> ./include/blasfeo_target.h
echo "#define TARGET_NEED_FEATURE_FMA"  >> ./include/blasfeo_target.h
echo "#endif"                           >> ./include/blasfeo_target.h
echo "#ifndef LA_HIGH_PERFORMANCE" >> ./include/blasfeo_target.h
echo "#define LA_HIGH_PERFORMANCE" >> ./include/blasfeo_target.h
echo "#endif" >> ./include/blasfeo_target.h
echo "#ifndef MF_PANELMAJ" >> ./include/blasfeo_target.h
echo "#define MF_PANELMAJ" >> ./include/blasfeo_target.h
echo "#endif" >> ./include/blasfeo_target.h
echo "#ifndef EXT_DEP" >> ./include/blasfeo_target.h
echo "#define EXT_DEP" >> ./include/blasfeo_target.h
echo "#endif" >> ./include/blasfeo_target.h
echo "#ifndef BLAS_API" >> ./include/blasfeo_target.h
echo "#define BLAS_API" >> ./include/blasfeo_target.h
echo "#endif" >> ./include/blasfeo_target.h
( cd auxiliary; /Applications/Xcode.app/Contents/Developer/usr/bin/make obj)
Parsing Makefile.rule
make[1]: Nothing to be done for `obj'.
( cd kernel; /Applications/Xcode.app/Contents/Developer/usr/bin/make obj)
Parsing Makefile.rule
( cd avx2; /Applications/Xcode.app/Contents/Developer/usr/bin/make obj)
Parsing Makefile.rule
cc   -DLA_HIGH_PERFORMANCE -DMF_PANELMAJ -DBLAS_API -DMACRO_LEVEL=1 -DOS_MAC   -c -o kernel_dgemm_12x4_lib4.o kernel_dgemm_12x4_lib4.S
cc   -DLA_HIGH_PERFORMANCE -DMF_PANELMAJ -DBLAS_API -DMACRO_LEVEL=1 -DOS_MAC   -c -o kernel_dgemm_8x8_lib4.o kernel_dgemm_8x8_lib4.S
cc   -DLA_HIGH_PERFORMANCE -DMF_PANELMAJ -DBLAS_API -DMACRO_LEVEL=1 -DOS_MAC   -c -o kernel_dgemm_8x4_lib4.o kernel_dgemm_8x4_lib4.S
cc   -DLA_HIGH_PERFORMANCE -DMF_PANELMAJ -DBLAS_API -DMACRO_LEVEL=1 -DOS_MAC   -c -o kernel_dgemm_4x4_lib4.o kernel_dgemm_4x4_lib4.S
<instantiation>:12:13: error: invalid operand for instruction
 vperm2f128 x20, %ymm14, %ymm12, %ymm0
            ^~~
kernel_dgemm_8x8_lib4.S:4312:2: note: while in macro instantiation
 INNER_TRAN_SCALE_AB_8X8_LIB4
 ^
<instantiation>:13:13: error: invalid operand for instruction
 vperm2f128 x31, %ymm14, %ymm12, %ymm2
            ^~~
kernel_dgemm_8x8_lib4.S:4312:2: note: while in macro instantiation
 INNER_TRAN_SCALE_AB_8X8_LIB4
 ^
<instantiation>:14:13: error: invalid operand for instruction
 vperm2f128 x20, %ymm15, %ymm13, %ymm1
            ^~~
kernel_dgemm_8x8_lib4.S:4312:2: note: while in macro instantiation
 INNER_TRAN_SCALE_AB_8X8_LIB4
 ^
<instantiation>:15:13: error: invalid operand for instruction
 vperm2f128 x31, %ymm15, %ymm13, %ymm3
            ^~~
kernel_dgemm_8x8_lib4.S:4312:2: note: while in macro instantiation
 INNER_TRAN_SCALE_AB_8X8_LIB4
...

Not sure if it's helpful to include more of the output. Are there dependencies from XCode or the like?

Thank you.

With BUILD_SHARED_LIBS=ON it fails: can't find /usr/local/lib/libblasfeo.a

blasfeo is a separate port built with BUILD_SHARED_LIBS=ON.

When hpipm is also built with BUILD_SHARED_LIBS=ON it fails:

===>  Building for hpipm-0.1.0.80
ninja: error: '/usr/local/lib/libblasfeo.a', needed by 'libhpipm.so', missing and no known rule to make it

'/usr/local/lib/libblasfeo.a' isn't there, there is a shared llibrary instead: '/usr/local/lib/libblasfeo.so'

You should use cmake scripts to detect dependencies instead of hard-coding them.

example_mass_spring_qp.m only works with slack bounds equal to -1

I have tried to use a slack variable in example example_mass_spring_qp.m

Please find my code here.

Only when I set the lower slack bounds associated to the lower and upper constrains to a value between -1.000000001 and -0.999999999 in line 175, I manage to get the solver to finish with status 0. Any other value I tried results in a failed solution.

I would like to be able to use 0 as a slack bound.

Could you please have a look what causes the solver to not find a solution with lower slack bounds equal to 0?

Issue on cmake inferface for MATLAB on windows

Hi guys,
I was just trying to do step 4 from your instruction to get HPIPM for MATLAB on Windows.
Step 3 worked just fine, but the next one gave me a multiple fatal errors (C1083), when I was calling "cmake --build ."
It seems like "blasfeo_target.h" cannot be found, but I dont know why ...
Do you have any idea to fix this?

Potential improvements to cross-language interface paradigm

  1. Inherit methods from Python class in all languages
  2. Generate setters/getters automatically from attribute list
  3. Overload getattr and setattr for cleaner syntax
  4. Use dynamic properties of classes in Matlab meta-interface
  5. Remove code duplication in setters and getters (could be solved as well by overloading of getattr and setattr?)
  6. Hide args, dims and sol?

example build fails on tag 0.1.2

Dear @giaf,
a control-toolbox user just reported to me the following bug on hpipm tag 0.1.2: building the examples fails with

Parsing Makefile.rule
cp libhpipm.a ./examples/c/libhpipm.a
( cd examples/c; make obj )
make[1]: Entering directory '/tmp/hpipm/examples/c'
Parsing Makefile.rule
make[1]: *** No rule to make target '../matlab_octave/ocp_qp_data.o', needed by 'obj'.  Stop.
make[1]: Leaving directory '/tmp/hpipm/examples/c'
Makefile:239: recipe for target 'examples' failed
make: *** [examples] Error 2

Redeclaration of enums

There are three enums with the same fields in hpipm_x_ocp_qp_ipm.h, hpipm_x_dense_qp_ipm.h and hpipm_x_tree_ocp_qp_ipm.h:

enum ocp_qp_ipm_mode
	{
	SPEED_ABS, // focus on speed, absolute IPM formulation
	SPEED, // focus on speed, relative IPM formulation
	BALANCE, // balanced mode, relative IPM formulation
	ROBUST, // focus on robustness, relative IPM formulation
	};

enum dense_qp_ipm_mode
	{
	SPEED_ABS, // focus on speed, absolute IPM formulation
	SPEED, // focus on speed, relative IPM formulation
	BALANCE, // balanced mode, relative IPM formulation
	ROBUST, // focus on robustness, relative IPM formulation
	};

enum tree_ocp_qp_ipm_mode
	{
	SPEED_ABS, // focus on speed, absolute IPM formulation
	SPEED, // focus on speed, relative IPM formulation
	BALANCE, // balanced mode, relative IPM formulation
	ROBUST, // focus on robustness, relative IPM formulation
	};

This will create problems whenever both of these headers are included somewhere else (e.g. in ACADOS OCP QP C interface) - compiler will complain about redeclaration of enumerators.

Therefore, these enum fields should be given different names (e.g. OCP_SPEED_ABS, DENSE_SPEED_ABS, TREE_OCP_SPEED, etc.) or just use one enum for everything if the modes are the same in all modules.

Linker errors when building an executable for Intel Core target with hpipm + blasfeo

I have an exectuable which links to hpipm and blasfeo.

  • I built and installed blasfeo with TARGET = X64_INTEL_CORE.
  • Then I build and install hpipm with TARGET = SSE3 and BLASFEO_PATH set to where my blasfeo is installed.
  • Then I build an executable which links to both blasfeo and hpipm, and I get the following linker errors:
[build] [ 96%] Linking CXX executable ../../bin/soft_constraints
[build] /opt/hpipm/lib/libhpipm.a(d_ocp_qp_ipm.o): In function `d_solve_ocp_qp_ipm':
[build] d_ocp_qp_ipm.c:(.text+0x1764): undefined reference to `d_backup_res_m'
[build] d_ocp_qp_ipm.c:(.text+0x1e16): undefined reference to `d_compute_alpha_qp'
[build] d_ocp_qp_ipm.c:(.text+0x1e58): undefined reference to `d_update_var_qp'
[build] d_ocp_qp_ipm.c:(.text+0x1e77): undefined reference to `d_backup_res_m'
[build] d_ocp_qp_ipm.c:(.text+0x2014): undefined reference to `d_update_var_qp'
...

If I build blasfeo with TARGET = AVX, the executable links fine, but I get SIGILL when running it because apparently hpipm tries to execute an instruction not supported by my CPU, and this is not what I want.

MATLAB interface on Windows not compiling

I am trying to use HPIPM as a solver for a problem defined in MATLAB. README.md describes the steps for compiling the interface for Linux, however not for Windows.
I compiled BLASFEO and HPIPM using CMake. I have set the path environment variables manually in MATLAB, however running the file compile_mex_all.m runs into multiple errors on line 158.
Could you add some instructions how to compile the MATLAB interface on Windows?

Building on Arm Cortex-A57: Unrecognized command line option -mavx

Hello, I am trying to build this on a Jetson TX2 (Arm Cortex-A57), so I have defined the TARGET accordingly in the Makefile.rule file in the blasefeo root folder. When following your instructions (specifically running make static_library from the hpipm root folder), an error is returned indicating "the command line option -mavx is not found".
Do you know what could be the issue?

Linker errors when linking to libhpipm

My code uses d_solve_ipm_hard_ocp_qp and I get the following errors from linker after pulling the latest code from master:

/opt/hpipm/lib/libhpipm.a(d_ocp_qp_ipm_hard.o): In function `d_solve_ipm_hard_ocp_qp':
d_ocp_qp_ipm_hard.c:(.text+0xe37): undefined reference to `d_init_var_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0xe45): undefined reference to `d_compute_res_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0xe94): undefined reference to `d_fact_solve_kkt_step_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0xec6): undefined reference to `d_compute_res_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0xf2f): undefined reference to `d_compute_res_hard_ocp_qp'
/opt/hpipm/lib/libhpipm.a(d_ocp_qp_ipm_hard.o): In function `d_solve_ipm2_hard_ocp_qp':
d_ocp_qp_ipm_hard.c:(.text+0xfc7): undefined reference to `d_init_var_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0xfd5): undefined reference to `d_compute_res_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0x1028): undefined reference to `d_fact_solve_kkt_step_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0x109e): undefined reference to `d_solve_kkt_step_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0x10d1): undefined reference to `d_compute_res_hard_ocp_qp'
d_ocp_qp_ipm_hard.c:(.text+0x1137): undefined reference to `d_compute_res_hard_ocp_qp'
/opt/hpipm/lib/libhpipm.a(d_ocp_qp_kkt.o): In function `d_compute_res_ocp_qp':
d_ocp_qp_kkt.c:(.text+0x1125): undefined reference to `dgemv_diag_libstr'

I didn't find a definition of d_init_var_hard_ocp_qp, d_compute_res_hard_ocp_qp in the hpipm code. Is the hard OCP solver deprecated?

[ct-v2] fail to compile

Hi all,

When I tried to compile the tag ct-v2 on my Ubuntu 16.04 64-bits pc, it fails as the following file.

hpipm-ct-v2-error.txt

Could anyone give me any hint?
Thank you in advance!

Best,
Kahn

Matlab-Python interface

The Matlab interface reads the A and B matrices incorrectly, and transposing the matrices solves the issue.

I also have an improved getting_started.m script if you are interested.

Some small issues

I am compiling hpipm in one big .c file for embedded use, and I came across some minor issues:

It seems that include/hpipm_d_core_qp_ipm.h and include/hpipm_s_core_qp_ipm.h have no header guard.

in the d_<problem_class>_kkt.c files, the following function placeholders are not declared:
COND_SLACKS_FACT_SOLVE
COND_SLACKS_SOLVE
EXPAND_SLACKS

Proper formulation of unboudedness of constraints?

Hi @giaf
What is the recommended way of indicating that a constraints ins unbounded in a certain direction?
So far, I was simply relying into setting the upper/lower bound to a "reasonnably" low/high value. However, I noticed that some users managed to create numerical issues when setting very large or low bounds, which would cause hpipm to return with error code 2. So, what is the recommended way of indicating unboundedness in hpipm?

OCP_QP_SET_ALL required after updating ocp problem data?

Dear @giaf, I checked out the recent release 0.1.1 and ran into the following issue:

  • With previous versions, i.e. the ct-v2 tag, I had to set the pointers to the problem data once (e.g. set pointers to the linearized system matrices A,B) afterwards I could arbitrarily mutate the problem matrices and hpipm would of course use the updated problem matrices without requiring further calls.
  • In 0.1.1, simply updating problem matrices after initialization won't result in the solver "seeing" the new values. Everytime I change entries in the problem matrices, I have to call
  • "OCP_QP_SET_ALL(...)" on the problem data, before executing a solve.

Is this a known behaviour? If the expected behaviour is different, I will try to devise a minimal example upon request!

Thanks, and keep up the great work!

stable branch: Make test_problems

Hello,
First, thank you very much for the library. I had the following issue in stable branch:

make static_library worked, but make test_problem results in the following error for me

gcc -o test.out d_tools.o test_d_ocp.o -L. libhpipm.a /opt/blasfeo/lib/libblasfeo.a -lm #-pg libhpipm.a(d_ocp_qp_ipm.o): In function d_solve_ocp_qp_ipm':
d_ocp_qp_ipm.c:(.text+0x11da): undefined reference to dvecnrm_inf_libstr' d_ocp_qp_ipm.c:(.text+0x1205): undefined reference to dvecnrm_inf_libstr'
d_ocp_qp_ipm.c:(.text+0x1233): undefined reference to dvecnrm_inf_libstr' d_ocp_qp_ipm.c:(.text+0x1261): undefined reference to dvecnrm_inf_libstr'
d_ocp_qp_ipm.c:(.text+0x133b): undefined reference to dvecnrm_inf_libstr' libhpipm.a(d_ocp_qp_ipm.o):d_ocp_qp_ipm.c:(.text+0x1354): more undefined references to dvecnrm_inf_libstr' follow
libhpipm.a(d_ocp_qp_kkt.o): In function d_compute_res_ocp_qp': d_ocp_qp_kkt.c:(.text+0x126a): undefined reference to dgemv_diag_libstr'
collect2: error: ld returned 1 exit status
Makefile:74: recipe for target 'obj' failed
`
I don't have the same problem for ct-v2 branch, but I would like to try the tree-structured quadratic program solver. What would you recommend for me?
Best regards

Python example fails due to recent contribution (new exception)

getting_started.py fails at line 66
qp.set('A', [A, A, A, A, A])
Due to a recent modification to the ...wrapper/hpipm_ocp_qp.py at line 176:
raise Exception("Trying to assign value which is not a vector nor a scalar. Exiting.")

Is it enough to do?
qp.set('A', np.array([A, A, A, A, A]))

Not able to obtain lambda values

Hello,
I want to use the HPIPM as QP solver for a SQP-Algorithm. Therefore, I need to obtain the lambda (and possibly pi) values which result from the solution of the QP. How can I obtain these values? I'm using MATLAB and tried the straightforward approach sol.get('lambda'); but that didn't work.

API improvement proposal: OCP QP solution vectors as an array of structs

Similarly to #4 and #3 , I propose

struct ocp_qp_stage_sol
{
    double *u;
    double *x;
    double *ls;
    double *us;
    double *pi;
    double *lam_lb;
    double *lam_ub;
    double *lam_lg;
    double *lam_ug;
    double *lam_ls;
    double *lam_us;
};

which would change this

void d_cvt_ocp_qp_sol_to_colmaj(struct d_ocp_qp *qp, struct d_ocp_qp_sol *qp_sol, double **u, 
double **x, double **ls, double **us, double **pi, double **lam_lb, double **lam_ub, double **lam_lg, 
double **lam_ug, double **lam_ls, double **lam_us);

to

void d_cvt_ocp_qp_sol_to_colmaj(struct d_ocp_qp *qp, struct d_ocp_qp_sol *qp_sol, ocp_qp_stage_sol * sol);

d_cond.c: Condensed hessian seems to be lower triangular + is there an option to condense x0? + what is the purpose of not condensing the last stage?

I tried out hpipm's condensing routines and it seems as if the output only contains the lower triangular and diagonal elements of the overall hessian. So I had to manually copy the elements below the diagonal to the upper part. Is this intended?

I did not want to create too many issues concerning the same function, so I just post my additional questions here, too.

The vector of optimization variables of the resulting dense QP apparently has the form [uN-1, ... u0, x0]. Since I have a large state space, eliminating x0 should give a significant speed up in the following dense QP solve. Would it make sense to create an option for this? Is there one already?

And could anyone give a hint as to what the benefits are of not condensing the last stage?

hpipm_dense_qp_solver fails with only equality constraints

Hello,
I intend to use HPIPM for solving a quadratic static constrained optimization problem. I use the MATLAB API, more accurate, the hpipm_dense_qp_solver function. My problem looks as follows

min_x 1/2x'Hx
s.t. A
x=b

According to the publication https://arxiv.org/abs/2003.02547 I set the following arguments

dim = hpipm_dense_qp_dim();
dim.set('nv', nv); % nv is the number of optimization variables, in my case 94
dim.set('ne', ne); % ne is the number of equality constraints, in my case 89
qp = hpipm_dense_qp(dim);
qp.set('H', H);
qp.set('A', Aeq);
qp.set('b', beq);
sol = hpipm_dense_qp_sol(dim);
mode = 'speed';
arg = hpipm_dense_qp_solver_arg(dim, mode);
    
solver = hpipm_dense_qp_solver(dim, arg);

solver.solve(qp, sol);
x = sol.get('v');

The solver exits with status 0 but the values of the solution are all NaN. If I try to solve the same problem with quadprog from MATLAB, I get a valid solution, hence, the problem is solvable. Where could the problem be?

Some files licensed under GPL3 + classpath exception

Some files in this repository are licensed under GPL3 + classpath exception, more specifically:

  • test_problems/test_d_sim.c
  • sim_core/x_sim_rk.c
  • sim_core/s_sim_rk.c
  • sim_core/d_sim_rk.c
  • interfaces/archive/octave/HPIPM_d_solve_ipm2_hard_ocp_qp.c
  • archive/test_van_der_pol_sqp.c
  • archive/test_van_der_pol_ipm.c
  • archive/test_van_der_pol_hyb.c
  • archive/test_d_pendulum_sqp.c
  • archive/test_d_pendulum_ipm.c
  • archive/test_d_pendulum_hyb.c
  • archive/test_d_nlp_sqp.c
  • archive/test_d_nlp_ipm.c
  • archive/sqp/d_gn_sqp.c
  • archive/sim_core/d_irk_int.c
  • archive/pendulum/vde_hess_model.c
  • archive/pendulum/vde_forw_model.c
  • archive/pendulum/vde_adj_model.c
  • archive/pendulum/ode_model.c
  • archive/pendulum/jac_model.c
  • archive/ocp_nlp/x_ocp_nlp_sol.c
  • archive/ocp_nlp/s_ocp_nlp_sol.c
  • archive/ocp_nlp/d_ocp_nlp_sqp.c
  • archive/ocp_nlp/d_ocp_nlp_sol.c
  • archive/ocp_nlp/d_ocp_nlp_ipm.c
  • archive/ocp_nlp/d_ocp_nlp_hyb.c
  • archive/ocp_nlp/d_ocp_nlp_aux.c
  • archive/ocp_nlp/d_ocp_nlp.c
  • archive/include/hpipm_s_ocp_nlp_sol.h
  • archive/include/hpipm_d_ocp_nlp_sqp.h
  • archive/include/hpipm_d_ocp_nlp_sol.h
  • archive/include/hpipm_d_ocp_nlp_ipm.h
  • archive/include/hpipm_d_ocp_nlp_hyb.h
  • archive/include/hpipm_d_ocp_nlp_aux.h
  • archive/include/hpipm_d_ocp_nlp.h
  • archive/include/hpipm_d_irk_int.h

It's usually tricky to combine GPL with other licenses in one project. In some cases, GPL might actually be governing the entire project's source distribution terms indirectly.

Is this intentional? If yes, I think it would make sense to prominently note this in the README.

Compillation warnings

clang8 prints these warnings:

In file included from /usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/d_tree_ocp_qp_ipm.c:117:
/usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/x_tree_ocp_qp_ipm.c:1016:118: warning: | has lower precedence than >; > will be evaluated first [-Wparentheses]
                                ( itref_qp_norm[0]==0.0 & BLASFEO_DVECEL(ws->res_itref->res_g+0, 0)!=BLASFEO_DVECEL(ws->res_itref->res_g+0, 0) ) |
                                                                                                                                                 ^
/usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/x_tree_ocp_qp_ipm.c:1016:118: note: place parentheses around the '>' expression to silence this warning
                                ( itref_qp_norm[0]==0.0 & BLASFEO_DVECEL(ws->res_itref->res_g+0, 0)!=BLASFEO_DVECEL(ws->res_itref->res_g+0, 0) ) |
                                                                                                                                                 ^
/usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/x_tree_ocp_qp_ipm.c:1016:118: note: place parentheses around the | expression to evaluate it first
                                ( itref_qp_norm[0]==0.0 & BLASFEO_DVECEL(ws->res_itref->res_g+0, 0)!=BLASFEO_DVECEL(ws->res_itref->res_g+0, 0) ) |
                                                                                                                                                 ^
                                (
1 warning generated.
In file included from /usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/d_tree_ocp_qp_kkt.c:112:
/usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/x_tree_ocp_qp_kkt.c:1020:26: warning: equality comparison result unused [-Wunused-comparison]
                        ws->use_hess_fact[idx]==1;
                        ~~~~~~~~~~~~~~~~~~~~~~^~~
/usr/ports/math/hpipm/work/hpipm-0.1.0/tree_ocp_qp/x_tree_ocp_qp_kkt.c:1020:26: note: use '=' to turn this equality comparison into an assignment
                        ws->use_hess_fact[idx]==1;
                                              ^~
                                              =
1 warning generated.
In file included from /usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/s_ocp_qp_kkt.c:126:
/usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/x_ocp_qp_kkt.c:1417:24: warning: equality comparison result unused [-Wunused-comparison]
                ws->use_hess_fact[ss]==1;
                ~~~~~~~~~~~~~~~~~~~~~^~~
/usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/x_ocp_qp_kkt.c:1417:24: note: use '=' to turn this equality comparison into an assignment
                ws->use_hess_fact[ss]==1;
                                     ^~
                                     =
/usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/x_ocp_qp_kkt.c:1488:25: warning: equality comparison result unused [-Wunused-comparison]
                        ws->use_hess_fact[ss]==1;
                        ~~~~~~~~~~~~~~~~~~~~~^~~
/usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/x_ocp_qp_kkt.c:1488:25: note: use '=' to turn this equality comparison into an assignment
                        ws->use_hess_fact[ss]==1;
                                             ^~
                                             =
/usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/x_ocp_qp_kkt.c:1559:24: warning: equality comparison result unused [-Wunused-comparison]
                ws->use_hess_fact[ss]==1;
                ~~~~~~~~~~~~~~~~~~~~~^~~
/usr/ports/math/hpipm/work/hpipm-0.1.0/ocp_qp/x_ocp_qp_kkt.c:1559:24: note: use '=' to turn this equality comparison into an assignment
                ws->use_hess_fact[ss]==1;
                                     ^~
                                     =
3 warnings generated.

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.