Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify and generalize testing procedure (over cmake, catkin_make, catkin build) #25

Merged
merged 4 commits into from
Jul 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ project(ifopt VERSION 2.0.2)
###########
include(GNUInstallDirs) # for correct library locations across platforms
set(config_package_location "share/${PROJECT_NAME}/cmake") # for .cmake find-scripts installs
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # so installed solver libraries link to IFOPT/SNOPT
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) # so installed solver libraries link to libifopt_core.so
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # so installed solver libraries link to IFOPT/SNOPT
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) # so installed solver libraries link to libifopt_core.so
set(IFOPT_INSTALL_BINDIR ${CMAKE_INSTALL_LIBDIR}/ifopt) # replicate default for catkin installs

IF(NOT CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "CMAKE_BUILD_TYPE not set to Release -> impacts performance")
Expand Down
69 changes: 34 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

*A modern, light-weight, [Eigen]-based C++ interface to Nonlinear Programming solvers, such as [Ipopt] and [Snopt].*

The optimization problem to solve is e.g. defined as:
An example nonlinear optimization problem to solve is defined as:

<img align="center" height="100" src="https://i.imgur.com/YGi4LrR.png"/>

Expand All @@ -23,7 +23,7 @@ Related variables and constraints are implemented (grouped) in *independent sets

More Features:
:heavy_check_mark: [Eigen] allows inuitive formulation and fast performance due to sparse matrix exploitation.
:heavy_check_mark: exports cmake scripts to easily <find_package(ifopt)> in your project.
:heavy_check_mark: exports cmake scripts to easily `find_package(ifopt)` in your project.
:heavy_check_mark: [catkin] integration (optional).
:heavy_check_mark: light-weight (~[2k lines of code](https://i.imgur.com/NCPJsSw.png)) makes it easy to use and extend.

Expand All @@ -32,14 +32,14 @@ More Features:
## Dependencies
Name | Min. Ver. | Description | Install
--- | --- | --- | --- |
[CMake] | v3.1.0 | C++ build tool | ```sudo apt-get install cmake```
[CMake] | v3.1.0 | C++ build tool | ```sudo apt-get install cmake``` [(upgrade)](https://askubuntu.com/questions/829310/how-to-upgrade-cmake-in-ubuntu#answer-908211)
[Eigen] | v3.2.0 | Library for linear algebra | ```sudo apt-get install libeigen3-dev```
[Ipopt] | v3.11.9 | NLP solver (Interior-Point) |```sudo apt-get install coinor-libipopt-dev```
([Snopt]) | 7.4 | NLP solver (SQP) | non-free

* Quick Install:
Quick Install:

``` sudo apt-get install cmake libeigen3-dev coinor-libipopt-dev```
``` sudo apt-get install cmake libeigen3-dev coinor-libipopt-dev```

If you want to link to a local installation of Ipopt or to Snopt, see the [doxygen documentation](http://docs.ros.org/kinetic/api/ifopt/html/).

Expand All @@ -55,14 +55,6 @@ If you want to link to a local installation of Ipopt or to Snopt, see the [doxyg
# sudo xargs rm < install_manifest.txt # in case you want to uninstall the above
```

* Test: Make sure everything installed correctly by running
```bash
make test
```
You should see `#1 ifopt_core-test....Passed` as well as one test for each installed solver.
In case you want to see the actual iterations of the solver, run ``ctest -V``.


* Use: To use in your cmake project, see this minimal *CMakeLists.txt*:
```cmake
find_package(ifopt)
Expand All @@ -75,20 +67,13 @@ If you want to link to a local installation of Ipopt or to Snopt, see the [doxyg
## Building with catkin
* Install: Download [catkin] or [catkin command line tools], then:
```bash
cd catkin_workspace/src
cd catkin_ws/src
git clone https://github.com/ethz-adrl/ifopt.git
cd ..
catkin_make_isolated # `catkin build` if you are using catkin command-line tools
source ./devel/setup.bash
```

* Test: To run the code, navigate to your `catkin_ws/build` folder and execute
the binaries
```bash
./ifopt/ifopt_core/ifopt_core-test
./ifopt/ifopt_ipopt/ifopt_ipopt-example
```


* Use: Include in your catkin project by adding to your *CMakeLists.txt*
```cmake
find_package(catkin COMPONENTS ifopt)
Expand All @@ -101,28 +86,42 @@ If you want to link to a local installation of Ipopt or to Snopt, see the [doxyg
<depend>ifopt</depend>
</package>
```

## Test
Navigate to your build folder in which the `Makefile` resides, which depends
on how you built the code:
```bash
cd ifopt/build # plain cmake
cd catkin_ws/build_isolated/ifopt/devel # catkin_make_isolated
cd catkin_ws/build/ifopt # catkin build
```
Make sure everything installed correctly by running the `test` target
```bash
make test
```
You should see `ifopt_ipopt-example....Passed` (or snopt if installed) as well as `ifopt_core-test` if
[gtest] is installed.

If you have IPOPT installed and linked correctly, you can also run the [binary example](ifopt_ipopt/test/ex_test_ipopt.cc)
directly (again, first navigate to the build folder with the `Makefile`)
```bash
make test ARGS='-R ifopt_ipopt-example -V'
```
Output:
```bash
1.0 0.0
```

## Example
Each set of variables, costs and constraints are formulated by one C++ object
purely through Eigen vectors and matrices and independent from any specific solver.
Although this [example](ifopt_core/test/ifopt/test_vars_constr_cost.h) adds just one,
Although the above [example](ifopt_core/test/ifopt/test_vars_constr_cost.h) adds just one,
multiple sets of variables or constraints can be added to the NLP and ifopt manages
the overall variable vector and jacobian, so each set can be implemented independent of
the others. A more involved problem definition with multiple sets
of variables and constraints, taken from [towr] can be seen in the following:

<img align="center" height="500" src="https://i.imgur.com/4yhohZF.png"/>

If you have IPOPT installed and linked correctly, you can run this binary [example](ifopt_ipopt/test/ex_test_ipopt.cc) through
```bash
./build/ifopt_ipopt/ifopt_ipopt-example # or `rosrun ifopt ifopt_ipopt-example `
```
Output:
```bash
1.0 0.0
```

## Authors
[Alexander W. Winkler](https://awinkler.github.io/) - Initial Work/Maintainer

Expand Down Expand Up @@ -166,12 +165,12 @@ To report bugs, request features or ask questions, please have a look at [CONTRI
[Eigen]: http://eigen.tuxfamily.org
[Ipopt]: https://projects.coin-or.org/Ipopt
[Snopt]: http://ampl.com/products/solvers/solvers-we-sell/snopt/
[catkin]: http://wiki.ros.org/catkin
[catkin]: http://wiki.ros.org/catkin/Tutorials/create_a_workspace
[catkin command line tools]: http://catkin-tools.readthedocs.io/en/latest/installing.html
[towr]: https://github.com/ethz-adrl/towr
[catkin tools]: http://catkin-tools.readthedocs.org/
[ROS]: http://www.ros.org
[rviz]: http://wiki.ros.org/rviz
[Fa2png]: http://fa2png.io/r/font-awesome/link/
[gtest]: https://github.com/google/googletest


13 changes: 10 additions & 3 deletions ifopt_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ target_compile_features(${LIB_CORE}
## Install ##
#############
# store in export-set for find-script generation
install(TARGETS ${LIB_CORE} EXPORT ${LIB_CORE}-targets
install(
TARGETS ${LIB_CORE}
EXPORT ${LIB_CORE}-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# Copy header files to usr/local/include/ifopt/*
install(
Expand All @@ -43,7 +44,8 @@ install(
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ifopt
)
# Generate the find scripts
install(EXPORT ${LIB_CORE}-targets
install(
EXPORT ${LIB_CORE}-targets
FILE ${LIB_CORE}-targets.cmake
NAMESPACE ifopt::
DESTINATION ${config_package_location}
Expand All @@ -65,4 +67,9 @@ if (TARGET GTest::GTest) # only build when modern target exists
GTest::GTest GTest::Main
)
add_test(${LIB_CORE}-test ${LIB_CORE}-test)

install(
TARGETS ${LIB_CORE}-test
RUNTIME DESTINATION ${IFOPT_INSTALL_BINDIR}
)
endif()
7 changes: 5 additions & 2 deletions ifopt_ipopt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
find_package(IPOPT 3.11.9 REQUIRED)
# previous IPOPT versions have a bug which causes mumps segfault:
# https://bugs.launchpad.net/ubuntu/+source/coinor-ipopt/+bug/1167585


###########
## Build ##
Expand Down Expand Up @@ -47,10 +50,10 @@ add_test(${LIB_IPOPT}-example ${LIB_IPOPT}-example)
# Copy library files to usr/local/lib/libifopt_ipopt.so
install(
TARGETS ${LIB_IPOPT} ${LIB_IPOPT}-example
EXPORT ${LIB_IPOPT}-targets
EXPORT ${LIB_IPOPT}-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
RUNTIME DESTINATION ${IFOPT_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# Copy header files to usr/local/include/ifopt/*
Expand Down
87 changes: 41 additions & 46 deletions ifopt_ipopt/cmake/FindIPOPT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,52 +40,11 @@
# (To distribute this file outside of YCM, substitute the full
# License text for the above reference.)


if(NOT WIN32)
# On non Windows systems we use PkgConfig to find IPOPT
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)

if(IPOPT_FIND_VERSION)
if(IPOPT_FIND_VERSION_EXACT)
pkg_check_modules(_PC_IPOPT QUIET ipopt=${IPOPT_FIND_VERSION})
else()
pkg_check_modules(_PC_IPOPT QUIET ipopt>=${IPOPT_FIND_VERSION})
endif()
else()
pkg_check_modules(_PC_IPOPT QUIET ipopt)
endif()


if(_PC_IPOPT_FOUND)
set(IPOPT_INCLUDE_DIRS ${_PC_IPOPT_INCLUDE_DIRS} CACHE PATH "IPOPT include directory")
set(IPOPT_DEFINITIONS ${_PC_IPOPT_CFLAGS_OTHER} CACHE STRING "Additional compiler flags for IPOPT")
set(IPOPT_LIBRARIES "" CACHE STRING "IPOPT libraries" FORCE)
foreach(_LIBRARY IN ITEMS ${_PC_IPOPT_LIBRARIES})
find_library(${_LIBRARY}_PATH
NAMES ${_LIBRARY}
PATHS ${_PC_IPOPT_LIBRARY_DIRS})
# Workaround for https://github.com/robotology/icub-main/issues/418
if(${_LIBRARY}_PATH)
list(APPEND IPOPT_LIBRARIES ${${_LIBRARY}_PATH})
endif()
endforeach()
else()
set(IPOPT_DEFINITIONS "")
endif()

endif()

set(IPOPT_LINK_FLAGS "")

# If pkg-config fails, try to find the package using IPOPT_DIR
if(NOT _PC_IPOPT_FOUND)
set(IPOPT_DIR_TEST $ENV{IPOPT_DIR})
if(IPOPT_DIR_TEST)
set(IPOPT_DIR $ENV{IPOPT_DIR} CACHE PATH "Path to IPOPT build directory")
else()
set(IPOPT_DIR /usr CACHE PATH "Path to IPOPT build directory")
endif()
# First priority is finding the package using IPOPT_DIR if set
if(DEFINED ENV{IPOPT_DIR})
set(IPOPT_DIR $ENV{IPOPT_DIR} CACHE PATH "Path to IPOPT build directory")

set(IPOPT_INCLUDE_DIRS ${IPOPT_DIR}/include/coin)
find_library(IPOPT_LIBRARIES ipopt ${IPOPT_DIR}/lib
Expand All @@ -104,7 +63,7 @@ if(NOT WIN32)
string(REGEX REPLACE "-[^l][^ ]* " "" IPOPT_DEP ${IPOPT_DEP})
string(REPLACE "-l" "" IPOPT_DEP ${IPOPT_DEP})
string(REPLACE "\n" "" IPOPT_DEP ${IPOPT_DEP})
string(REPLACE "ipopt" "" IPOPT_DEP ${IPOPT_DEP}) # remove any possible auto-dependency
string(REPLACE "ipopt" "" IPOPT_DEP ${IPOPT_DEP}) # remove any possible auto-dependency
separate_arguments(IPOPT_DEP)

# use the find_library command in order to prepare rpath correctly
Expand All @@ -126,8 +85,44 @@ if(NOT WIN32)
endif()

set(IPOPT_DEFINITIONS "")
set(IPOPT_LINK_FLAGS "")


# if IPOPT_DIR not set, try finding IPOPT through package manager
else()
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)

if(IPOPT_FIND_VERSION)
if(IPOPT_FIND_VERSION_EXACT)
pkg_check_modules(_PC_IPOPT REQUIRED ipopt=${IPOPT_FIND_VERSION})
else()
pkg_check_modules(_PC_IPOPT REQUIRED ipopt>=${IPOPT_FIND_VERSION})
endif()
else()
pkg_check_modules(_PC_IPOPT REQUIRED ipopt)
endif()


if(_PC_IPOPT_FOUND)
set(IPOPT_INCLUDE_DIRS ${_PC_IPOPT_INCLUDE_DIRS} CACHE PATH "IPOPT include directory")
set(IPOPT_DEFINITIONS ${_PC_IPOPT_CFLAGS_OTHER} CACHE STRING "Additional compiler flags for IPOPT")
set(IPOPT_LIBRARIES "" CACHE STRING "IPOPT libraries" FORCE)
foreach(_LIBRARY IN ITEMS ${_PC_IPOPT_LIBRARIES})
find_library(${_LIBRARY}_PATH
NAMES ${_LIBRARY}
PATHS ${_PC_IPOPT_LIBRARY_DIRS})
# Workaround for https://github.com/robotology/icub-main/issues/418
if(${_LIBRARY}_PATH)
list(APPEND IPOPT_LIBRARIES ${${_LIBRARY}_PATH})
endif()
endforeach()
else()
set(IPOPT_DEFINITIONS "")
endif()
endif()
endif()

set(IPOPT_LINK_FLAGS "")

# Windows platforms
else()
Expand Down
8 changes: 4 additions & 4 deletions ifopt_snopt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ if(${SNOPT_v76})
endif()




#############
## Install ##
#############
# Copy library files to usr/local/lib/libifopt_snopt.so
install(TARGETS ${LIB_SNOPT} EXPORT ${LIB_SNOPT}-targets
install(
TARGETS ${LIB_SNOPT} ${LIB_SNOPT}-example
EXPORT ${LIB_SNOPT}-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
RUNTIME DESTINATION ${IFOPT_INSTALL_BINDIR}
)
# Copy header files to usr/local/include/ifopt/*
install(DIRECTORY include/ifopt/
Expand Down