From 075b056c5c3b4b735c21330e468c02a956557d7b Mon Sep 17 00:00:00 2001
From: andreadelprete <andre.delprete@gmail.com>
Date: Mon, 26 Oct 2015 13:33:35 +0100
Subject: [PATCH] First (non-working) version of the library, containing just a
 draft of the first test.

---
 .gitmodules                                   |   3 +
 CMakeLists.txt                                |  53 +++++++
 cmake                                         |   1 +
 cmake2/FindCDD.cmake                          |  25 ++++
 cmake2/FindEigen2.cmake                       |  79 ++++++++++
 cmake2/FindEigen3.cmake                       |  80 ++++++++++
 include/robust-equilibrium-lib/config.hh      | 113 ++++++++++++++
 .../solver_LP_abstract.hh                     |  34 +++++
 .../solver_LP_qpoases.hh                      |   0
 .../static_equilibrium.hh                     |  43 ++++++
 src/CMakeLists.txt                            |  31 ++++
 src/solver_LP_qpoases.cpp                     |   0
 src/static_equilibrium.cpp                    |  39 +++++
 test/CMakeLists.txt                           |  19 +++
 test/test_LP_solvers.cpp                      |   5 +
 test/test_static_equilibrium.cpp              | 140 ++++++++++++++++++
 16 files changed, 665 insertions(+)
 create mode 100644 .gitmodules
 create mode 100644 CMakeLists.txt
 create mode 160000 cmake
 create mode 100644 cmake2/FindCDD.cmake
 create mode 100644 cmake2/FindEigen2.cmake
 create mode 100644 cmake2/FindEigen3.cmake
 create mode 100644 include/robust-equilibrium-lib/config.hh
 create mode 100644 include/robust-equilibrium-lib/solver_LP_abstract.hh
 create mode 100644 include/robust-equilibrium-lib/solver_LP_qpoases.hh
 create mode 100644 include/robust-equilibrium-lib/static_equilibrium.hh
 create mode 100644 src/CMakeLists.txt
 create mode 100644 src/solver_LP_qpoases.cpp
 create mode 100644 src/static_equilibrium.cpp
 create mode 100644 test/CMakeLists.txt
 create mode 100644 test/test_LP_solvers.cpp
 create mode 100644 test/test_static_equilibrium.cpp

diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..2b7a4fe
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "cmake"]
+	path = cmake
+	url = https://github.com/jrl-umi3218/jrl-cmakemodules.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..5faf2e4
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,53 @@
+cmake_minimum_required(VERSION 2.6)
+INCLUDE(cmake/base.cmake)
+INCLUDE(cmake/cpack.cmake)
+
+
+SET(PROJECT_NAME robust-equilibrium-lib)
+SET(PROJECT_DESCRIPTION
+   "Utility classes for testing (robust) static equilibrium of a system in contact with the environment"
+ )
+SET(PROJECT_URL "")
+
+set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/;${PROJECT_SOURCE_DIR}/cmake2/")
+set(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib/")
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin/")
+
+set(SRC_DIR "${PROJECT_SOURCE_DIR}/src")
+set(INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include")
+
+set(EXTERNAL_LIBRARY_DIR "${PROJECT_SOURCE_DIR}/external/lib")
+
+if ( MSVC )  
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX")
+endif()
+
+SETUP_PROJECT()
+
+string (REPLACE "-Werror" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+MESSAGE( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )
+
+# Declare Headers
+SET(${PROJECT_NAME}_HEADERS
+    include/robust-equilibrium-lib/config.hh
+    include/robust-equilibrium-lib/solver_LP_abstract.hh
+    include/robust-equilibrium-lib/solver_LP_qpoases.hh
+    include/robust-equilibrium-lib/static_equilibrium.hh
+  )
+
+find_package(Eigen3)
+if (EIGEN3_INCLUDE_DIR)
+        message(STATUS "Found Eigen3")
+else()
+        message(STATUS "Eigen3 not found looking for Eigen2")
+        find_package(Eigen2 REQUIRED)
+endif()
+
+find_package(CDD REQUIRED)
+
+add_subdirectory (src)
+add_subdirectory (test)
+
+SETUP_PROJECT_FINALIZE()
+SETUP_PROJECT_CPACK()
+
diff --git a/cmake b/cmake
new file mode 160000
index 0000000..ad5a548
--- /dev/null
+++ b/cmake
@@ -0,0 +1 @@
+Subproject commit ad5a5486c4476e5e92cfd688b82467b54957a570
diff --git a/cmake2/FindCDD.cmake b/cmake2/FindCDD.cmake
new file mode 100644
index 0000000..54f859d
--- /dev/null
+++ b/cmake2/FindCDD.cmake
@@ -0,0 +1,25 @@
+# - Try to find libcdd
+# Once done this will define
+#  CDD_FOUND - System has CDD
+#  CDD_INCLUDE_DIRS - The CDD include directories
+#  CDD_LIBRARIES - The libraries needed to use CDD
+#  CDD_DEFINITIONS - Compiler switches required for using CDD
+
+
+find_path(CDD_INCLUDE_DIR cdd/cdd.h
+          HINTS ${CDD_INCLUDEDIR}
+          PATH_SUFFIXES CDD )
+
+find_library(CDD_LIBRARY NAMES libcdd
+             HINTS ${CDD_LIBDIR} ${CDD_LIBRARY_DIRS} )
+
+set(CDD_LIBRARIES ${CDD_LIBRARY} )
+set(CDD_INCLUDE_DIRS ${CDD_INCLUDE_DIR} )
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set CDD_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(CDD  DEFAULT_MSG
+                                  CDD_LIBRARY CDD_INCLUDE_DIR)
+
+mark_as_advanced(CDD_INCLUDE_DIR CDD_LIBRARY )
diff --git a/cmake2/FindEigen2.cmake b/cmake2/FindEigen2.cmake
new file mode 100644
index 0000000..7f0bbed
--- /dev/null
+++ b/cmake2/FindEigen2.cmake
@@ -0,0 +1,79 @@
+# - Try to find Eigen2 lib
+#
+# This module supports requiring a minimum version, e.g. you can do
+#   find_package(Eigen2 2.0.3)
+# to require version 2.0.3 to newer of Eigen2.
+#
+# Once done this will define
+#
+#  EIGEN2_FOUND - system has eigen lib with correct version
+#  EIGEN2_INCLUDE_DIR - the eigen include directory
+#  EIGEN2_VERSION - eigen version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
+# Redistribution and use is allowed according to the terms of the BSD license.
+
+if(NOT Eigen2_FIND_VERSION)
+  if(NOT Eigen2_FIND_VERSION_MAJOR)
+    set(Eigen2_FIND_VERSION_MAJOR 2)
+  endif(NOT Eigen2_FIND_VERSION_MAJOR)
+  if(NOT Eigen2_FIND_VERSION_MINOR)
+    set(Eigen2_FIND_VERSION_MINOR 0)
+  endif(NOT Eigen2_FIND_VERSION_MINOR)
+  if(NOT Eigen2_FIND_VERSION_PATCH)
+    set(Eigen2_FIND_VERSION_PATCH 0)
+  endif(NOT Eigen2_FIND_VERSION_PATCH)
+
+  set(Eigen2_FIND_VERSION "${Eigen2_FIND_VERSION_MAJOR}.${Eigen2_FIND_VERSION_MINOR}.${Eigen2_FIND_VERSION_PATCH}")
+endif(NOT Eigen2_FIND_VERSION)
+
+macro(_eigen2_check_version)
+  file(READ "${EIGEN2_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header)
+
+  string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}")
+  set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}")
+  set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}")
+  set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}")
+
+  set(EIGEN2_VERSION ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION})
+  if((${EIGEN2_WORLD_VERSION} NOTEQUAL 2) OR (${EIGEN2_MAJOR_VERSION} GREATER 10) OR (${EIGEN2_VERSION} VERSION_LESS ${Eigen2_FIND_VERSION}))
+    set(EIGEN2_VERSION_OK FALSE)
+  else()
+    set(EIGEN2_VERSION_OK TRUE)
+  endif()
+
+  if(NOT EIGEN2_VERSION_OK)
+
+    message(STATUS "Eigen2 version ${EIGEN2_VERSION} found in ${EIGEN2_INCLUDE_DIR}, "
+                   "but at least version ${Eigen2_FIND_VERSION} is required")
+  endif(NOT EIGEN2_VERSION_OK)
+endmacro(_eigen2_check_version)
+
+if (EIGEN2_INCLUDE_DIR)
+
+  # in cache already
+  _eigen2_check_version()
+  set(EIGEN2_FOUND ${EIGEN2_VERSION_OK})
+
+else (EIGEN2_INCLUDE_DIR)
+
+find_path(EIGEN2_INCLUDE_DIR NAMES Eigen/Core
+     PATHS
+     ${INCLUDE_INSTALL_DIR}
+     ${KDE4_INCLUDE_DIR}
+     PATH_SUFFIXES eigen2
+   )
+
+if(EIGEN2_INCLUDE_DIR)
+  _eigen2_check_version()
+endif(EIGEN2_INCLUDE_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Eigen2 DEFAULT_MSG EIGEN2_INCLUDE_DIR EIGEN2_VERSION_OK)
+
+mark_as_advanced(EIGEN2_INCLUDE_DIR)
+
+endif(EIGEN2_INCLUDE_DIR)
diff --git a/cmake2/FindEigen3.cmake b/cmake2/FindEigen3.cmake
new file mode 100644
index 0000000..66ffe8e
--- /dev/null
+++ b/cmake2/FindEigen3.cmake
@@ -0,0 +1,80 @@
+# - Try to find Eigen3 lib
+#
+# This module supports requiring a minimum version, e.g. you can do
+#   find_package(Eigen3 3.1.2)
+# to require version 3.1.2 or newer of Eigen3.
+#
+# Once done this will define
+#
+#  EIGEN3_FOUND - system has eigen lib with correct version
+#  EIGEN3_INCLUDE_DIR - the eigen include directory
+#  EIGEN3_VERSION - eigen version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
+# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
+
+if(NOT Eigen3_FIND_VERSION)
+  if(NOT Eigen3_FIND_VERSION_MAJOR)
+    set(Eigen3_FIND_VERSION_MAJOR 2)
+  endif(NOT Eigen3_FIND_VERSION_MAJOR)
+  if(NOT Eigen3_FIND_VERSION_MINOR)
+    set(Eigen3_FIND_VERSION_MINOR 91)
+  endif(NOT Eigen3_FIND_VERSION_MINOR)
+  if(NOT Eigen3_FIND_VERSION_PATCH)
+    set(Eigen3_FIND_VERSION_PATCH 0)
+  endif(NOT Eigen3_FIND_VERSION_PATCH)
+
+  set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
+endif(NOT Eigen3_FIND_VERSION)
+
+macro(_eigen3_check_version)
+  file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
+
+  string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
+  set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
+  set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
+  set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
+
+  set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
+  if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+    set(EIGEN3_VERSION_OK FALSE)
+  else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+    set(EIGEN3_VERSION_OK TRUE)
+  endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+
+  if(NOT EIGEN3_VERSION_OK)
+
+    message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
+                   "but at least version ${Eigen3_FIND_VERSION} is required")
+  endif(NOT EIGEN3_VERSION_OK)
+endmacro(_eigen3_check_version)
+
+if (EIGEN3_INCLUDE_DIR)
+
+  # in cache already
+  _eigen3_check_version()
+  set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
+
+else (EIGEN3_INCLUDE_DIR)
+
+  find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
+      PATHS
+      ${CMAKE_INSTALL_PREFIX}/include
+      ${KDE4_INCLUDE_DIR}
+      PATH_SUFFIXES eigen3 eigen
+    )
+
+  if(EIGEN3_INCLUDE_DIR)
+    _eigen3_check_version()
+  endif(EIGEN3_INCLUDE_DIR)
+
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
+
+  mark_as_advanced(EIGEN3_INCLUDE_DIR)
+
+endif(EIGEN3_INCLUDE_DIR)
diff --git a/include/robust-equilibrium-lib/config.hh b/include/robust-equilibrium-lib/config.hh
new file mode 100644
index 0000000..ef304c4
--- /dev/null
+++ b/include/robust-equilibrium-lib/config.hh
@@ -0,0 +1,113 @@
+#ifndef _ROBUST_EQUILIBRIUM_LIB_CONFIG_HH
+#define _ROBUST_EQUILIBRIUM_LIB_CONFIG_HH
+
+#include <Eigen/Dense>
+#include <Eigen/src/Core/util/Macros.h>
+
+// Package version (header).
+# define ROBUST_EQUILIBRIUM_VERSION "UNKNOWN"
+
+// Handle portable symbol export.
+// Defining manually which symbol should be exported is required
+// under Windows whether MinGW or MSVC is used.
+//
+// The headers then have to be able to work in two different modes:
+// - dllexport when one is building the library,
+// - dllimport for clients using the library.
+//
+// On Linux, set the visibility accordingly. If C++ symbol visibility
+// is handled by the compiler, see: http://gcc.gnu.org/wiki/Visibility
+# if defined _WIN32 || defined __CYGWIN__
+// On Microsoft Windows, use dllimport and dllexport to tag symbols.
+#  define ROBUST_EQUILIBRIUM_DLLIMPORT __declspec(dllimport)
+#  define ROBUST_EQUILIBRIUM_DLLEXPORT __declspec(dllexport)
+#  define ROBUST_EQUILIBRIUM_DLLLOCAL
+# else
+// On Linux, for GCC >= 4, tag symbols using GCC extension.
+#  if __GNUC__ >= 4
+#   define ROBUST_EQUILIBRIUM_DLLIMPORT __attribute__ ((visibility("default")))
+#   define ROBUST_EQUILIBRIUM_DLLEXPORT __attribute__ ((visibility("default")))
+#   define ROBUST_EQUILIBRIUM_DLLLOCAL  __attribute__ ((visibility("hidden")))
+#  else
+// Otherwise (GCC < 4 or another compiler is used), export everything.
+#   define ROBUST_EQUILIBRIUM_DLLIMPORT
+#   define ROBUST_EQUILIBRIUM_DLLEXPORT
+#   define ROBUST_EQUILIBRIUM_DLLLOCAL
+#  endif // __GNUC__ >= 4
+# endif // defined _WIN32 || defined __CYGWIN__
+
+# ifdef ROBUST_EQUILIBRIUM_STATIC
+// If one is using the library statically, get rid of
+// extra information.
+#  define ROBUST_EQUILIBRIUM_DLLAPI
+#  define ROBUST_EQUILIBRIUM_LOCAL
+# else
+// Depending on whether one is building or using the
+// library define DLLAPI to import or export.
+#  ifdef ROBUST_EQUILIBRIUM_EXPORTS
+#   define ROBUST_EQUILIBRIUM_DLLAPI ROBUST_EQUILIBRIUM_DLLEXPORT
+#  else
+#   define ROBUST_EQUILIBRIUM_DLLAPI ROBUST_EQUILIBRIUM_DLLIMPORT
+#  endif // ROBUST_EQUILIBRIUM_EXPORTS
+#  define ROBUST_EQUILIBRIUM_LOCAL ROBUST_EQUILIBRIUM_DLLLOCAL
+# endif // ROBUST_EQUILIBRIUM_STATIC
+
+namespace robust_equilibrium
+{
+
+//#define USE_FLOAT 1;
+#ifdef USE_FLOAT
+typedef float value_type;
+#else
+typedef double value_type;
+#endif
+
+typedef Eigen::Matrix <value_type, 2, 1>                                            Vector2;
+typedef Eigen::Matrix <value_type, 1, 2>                                            RVector2;
+typedef Eigen::Matrix <value_type, 3, 1>                                            Vector3;
+typedef Eigen::Matrix <value_type, 1, 3>                                            RVector3;
+typedef Eigen::Matrix <value_type, Eigen::Dynamic, 1>                               VectorX;
+typedef Eigen::Matrix <value_type, 1, Eigen::Dynamic>                               RVectorX;
+typedef Eigen::Matrix <value_type, 3, 3, Eigen::RowMajor>                           Rotation;
+typedef Eigen::Matrix <value_type, Eigen::Dynamic, 3, Eigen::RowMajor>              MatrixX3;
+typedef Eigen::Matrix <value_type, 4, 3, Eigen::RowMajor>                           Matrix43;
+typedef Eigen::Matrix <value_type, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatrixXX;
+
+//define Eigen ref if available
+#if EIGEN_VERSION_AT_LEAST(3,2,0)
+typedef Eigen::Ref<Vector2>     Ref_vector2;
+typedef Eigen::Ref<Vector3>     Ref_vector3;
+typedef Eigen::Ref<VectorX>     Ref_vectorX;
+typedef Eigen::Ref<Rotation>    Ref_rotation;
+typedef Eigen::Ref<MatrixX3>    Ref_matrixX3;
+typedef Eigen::Ref<Matrix43>    Ref_matrix43;
+typedef Eigen::Ref<MatrixXX>    Ref_matrixXX;
+
+typedef const Eigen::Ref<const Vector2>     & Cref_vector2;
+typedef const Eigen::Ref<const Vector3>     & Cref_vector3;
+typedef const Eigen::Ref<const VectorX>     & Cref_vectorX;
+typedef const Eigen::Ref<const Rotation>    & Cref_rotation;
+typedef const Eigen::Ref<const MatrixX3>    & Cref_matrixX3;
+typedef const Eigen::Ref<const Matrix43>    & Cref_matrix43;
+typedef const Eigen::Ref<const MatrixXX>    & Cref_matrixXX;
+#else
+typedef vector2_t   & Ref_vector2;
+typedef vector3_t   & Ref_vector3;
+typedef vector_t    & Ref_vector;
+typedef rotation_t  & Ref_rotation;
+typedef T_rotation_t& Ref_matrixX3;
+typedef T_rotation_t& Ref_matrix43;
+typedef matrix_t    & Ref_matrixXX;
+
+typedef const vector2_t   & Cref_vector2;
+typedef const vector3_t   & Cref_vector3;
+typedef const vector_t    & Cref_vector;
+typedef const rotation_t  & Cref_rotation;
+typedef const T_rotation_t& Cref_matrixX3;
+typedef const T_rotation_t& Cref_matrix43;
+typedef const matrix_t    & Cref_matrixXX;
+#endif
+
+} //namespace robust_equilibrium
+
+#endif //_ROBUST_EQUILIBRIUM_LIB_CONFIG_HH
diff --git a/include/robust-equilibrium-lib/solver_LP_abstract.hh b/include/robust-equilibrium-lib/solver_LP_abstract.hh
new file mode 100644
index 0000000..41ad038
--- /dev/null
+++ b/include/robust-equilibrium-lib/solver_LP_abstract.hh
@@ -0,0 +1,34 @@
+#ifndef ROBUST_EQUILIBRIUM_LIB_SOLVER_LP_ABSTRACT_HH
+#define ROBUST_EQUILIBRIUM_LIB_SOLVER_LP_ABSTRACT_HH
+
+#include <Eigen/Dense>
+#include <robust-equilibrium-lib/config.hh>
+
+namespace robust_equilibrium
+{
+
+enum ROBUST_EQUILIBRIUM_DLLAPI SolverLP
+{
+  SOLVER_LP_QPOASES
+};
+
+class ROBUST_EQUILIBRIUM_DLLAPI SolverLPAbstract
+{
+private:
+  std::string m_name;
+
+public:
+
+  SolverLPAbstract(std::string name);
+
+  /** Solve the linear program
+   *  minimize    c' x
+   *  subject to  lb <= A x <= ub
+   */
+  virtual bool solve(Cref_vectorX c, Cref_matrixXX A, Cref_vectorX lb, Cref_vectorX ub) = 0;
+
+};
+
+} // end namespace robust_equilibrium
+
+#endif //ROBUST_EQUILIBRIUM_LIB_SOLVER_LP_ABSTRACT_HH
diff --git a/include/robust-equilibrium-lib/solver_LP_qpoases.hh b/include/robust-equilibrium-lib/solver_LP_qpoases.hh
new file mode 100644
index 0000000..e69de29
diff --git a/include/robust-equilibrium-lib/static_equilibrium.hh b/include/robust-equilibrium-lib/static_equilibrium.hh
new file mode 100644
index 0000000..3fcc887
--- /dev/null
+++ b/include/robust-equilibrium-lib/static_equilibrium.hh
@@ -0,0 +1,43 @@
+#ifndef ROBUST_EQUILIBRIUM_LIB_STATIC_EQUILIBRIUM_H
+#define ROBUST_EQUILIBRIUM_LIB_STATIC_EQUILIBRIUM_H
+
+#include <Eigen/Dense>
+#include <robust-equilibrium-lib/config.hh>
+#include <robust-equilibrium-lib/solver_LP_abstract.hh>
+
+namespace robust_equilibrium
+{
+
+enum ROBUST_EQUILIBRIUM_DLLAPI StaticEquilibriumAlgorithm
+{
+  STATIC_EQUILIBRIUM_ALGORITHM_LP,
+  STATIC_EQUILIBRIUM_ALGORITHM_PP,
+  STATIC_EQUILIBRIUM_ALGORITHM_IP,
+  STATIC_EQUILIBRIUM_ALGORITHM_DIP
+};
+
+class ROBUST_EQUILIBRIUM_DLLAPI StaticEquilibrium
+{
+private:
+  StaticEquilibriumAlgorithm  m_algorithm;
+  SolverLPAbstract*           m_solver;
+
+public:
+  StaticEquilibrium(unsigned int generatorsPerContact, SolverLP solver_type);
+
+  bool setNewContacts(Cref_matrixX3 contactPoints, Cref_matrixX3 contactNormals,
+                      Cref_vectorX frictionCoefficients, StaticEquilibriumAlgorithm alg);
+
+  double computeEquilibriumRobustness(Cref_vector2 com);
+
+  double checkRobustEquilibrium(Cref_vector2 com, double e_max=0.0);
+
+  double findExtremumOverLine(Cref_vector2 a, double b, double e_max=0.0);
+
+  double findExtremumInDirection(Cref_vector2 direction, double e_max=0.0);
+
+};
+
+} // end namespace robust_equilibrium
+
+#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..3ff2216
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 2.6)
+
+include_directories("${SRC_DIR}")
+include_directories("${INCLUDE_DIR}")
+include_directories("${EIGEN3_INCLUDE_DIR}")
+include_directories("${CDD_INCLUDE_DIR}")
+
+SET(LIBRARY_NAME ${PROJECT_NAME})
+
+SET(${LIBRARY_NAME}_SOURCES
+    ${INCLUDE_DIR}/robust-equilibrium-lib/config.hh
+    ${INCLUDE_DIR}/robust-equilibrium-lib/solver_LP_abstract.hh
+    ${INCLUDE_DIR}/robust-equilibrium-lib/solver_LP_qpoases.hh
+    ${INCLUDE_DIR}/robust-equilibrium-lib/static_equilibrium.hh
+    static_equilibrium.cpp
+    solver_LP_qpoases.cpp
+  )
+
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src)
+ADD_LIBRARY(${LIBRARY_NAME} SHARED ${${LIBRARY_NAME}_SOURCES})
+
+if ( MSVC )
+	SET(CMAKE_DEBUG_POSTFIX d)
+endif ( MSVC )
+
+TARGET_LINK_LIBRARIES(robust-equilibrium-lib ${CDD_LIBRARY})
+
+SET_TARGET_PROPERTIES(robust-equilibrium-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
+SET_TARGET_PROPERTIES(robust-equilibrium-lib PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
+
+INSTALL(TARGETS ${LIBRARY_NAME} DESTINATION lib)
diff --git a/src/solver_LP_qpoases.cpp b/src/solver_LP_qpoases.cpp
new file mode 100644
index 0000000..e69de29
diff --git a/src/static_equilibrium.cpp b/src/static_equilibrium.cpp
new file mode 100644
index 0000000..a136d38
--- /dev/null
+++ b/src/static_equilibrium.cpp
@@ -0,0 +1,39 @@
+#include <robust-equilibrium-lib/static_equilibrium.hh>
+
+namespace robust_equilibrium
+{
+
+
+StaticEquilibrium::StaticEquilibrium(unsigned int generatorsPerContact, SolverLP solver_type)
+{
+
+}
+
+bool StaticEquilibrium::setNewContacts(Cref_matrixX3 contactPoints, Cref_matrixX3 contactNormals,
+                      Cref_vectorX frictionCoefficients, StaticEquilibriumAlgorithm alg)
+{
+  return true;
+}
+
+double StaticEquilibrium::computeEquilibriumRobustness(Cref_vector2 com)
+{
+  return 0.0;
+}
+
+double StaticEquilibrium::checkRobustEquilibrium(Cref_vector2 com, double e_max)
+{
+  return 0.0;
+}
+
+double StaticEquilibrium::findExtremumOverLine(Cref_vector2 a, double b, double e_max)
+{
+  return 0.0;
+}
+
+double StaticEquilibrium::findExtremumInDirection(Cref_vector2 direction, double e_max)
+{
+  return 0.0;
+}
+
+
+} // end namespace robust_equilibrium
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..d52109d
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.6)
+
+include_directories("${SRC_DIR}")
+include_directories("${INCLUDE_DIR}")
+include_directories("${EIGEN3_INCLUDE_DIR}")
+include_directories("${CDD_INCLUDE_DIR}")
+
+PROJECT(robust-equilibrium-lib)
+
+if ( MSVC )
+	SET(CMAKE_DEBUG_POSTFIX d)
+endif ( MSVC )
+
+add_executable(test_static_equilibrium test_static_equilibrium.cpp)
+add_executable(test_LP_solvers test_LP_solvers.cpp)
+
+TARGET_LINK_LIBRARIES(test_LP_solvers robust-equilibrium-lib)
+TARGET_LINK_LIBRARIES(test_static_equilibrium robust-equilibrium-lib)
+#~ TARGET_LINK_LIBRARIES(polytopetest polytope ${SRC_DIR}/../external/cddlib-094b/lib-src/libcdd.a)
diff --git a/test/test_LP_solvers.cpp b/test/test_LP_solvers.cpp
new file mode 100644
index 0000000..d56f6b7
--- /dev/null
+++ b/test/test_LP_solvers.cpp
@@ -0,0 +1,5 @@
+int main()
+{
+    int ret = 0;
+    return ret;
+}
diff --git a/test/test_static_equilibrium.cpp b/test/test_static_equilibrium.cpp
new file mode 100644
index 0000000..71642fc
--- /dev/null
+++ b/test/test_static_equilibrium.cpp
@@ -0,0 +1,140 @@
+#include <vector>
+#include <Eigen/Dense>
+#include <Eigen/src/Core/util/Macros.h>
+
+#include "cdd/cddmp.h"
+#include "cdd/setoper.h"
+#include "cdd/cddtypes.h"
+#include "cdd/cdd.h"
+
+#include <robust-equilibrium-lib/static_equilibrium.hh>
+
+using namespace robust_equilibrium;
+using namespace Eigen;
+
+typedef Eigen::AngleAxis<value_type> angle_axis_t;
+
+
+void init_library()
+{
+  dd_set_global_constants();dd_debug = false;
+}
+
+void release_library()
+{
+  //dd_free_global_constants();
+}
+
+bool uniform(Cref_matrixXX lower_bounds, Cref_matrixXX upper_bounds, Ref_matrixXX out)
+{
+
+  assert(lower_bounds.rows()==out.rows());
+  assert(upper_bounds.rows()==out.rows());
+  assert(lower_bounds.cols()==out.cols());
+  assert(upper_bounds.cols()==out.cols());
+  for(int i=0; i<out.rows(); i++)
+    for(int j=0; j<out.cols(); j++)
+      out(i,j) = (rand()/ value_type(RAND_MAX))*(upper_bounds(i,j)-lower_bounds(i,j)) + lower_bounds(i,j);
+}
+
+bool euler_matrix(double roll, double pitch, double yaw, Ref_rotation R)
+{
+  R = (angle_axis_t(roll, Vector3::UnitX())
+       * angle_axis_t(pitch, Vector3::UnitY())
+       * angle_axis_t(yaw, Vector3::UnitZ())).toRotationMatrix();
+}
+
+bool generate_rectangle_contacts(double lx, double ly, Cref_vector3 pos, Cref_vector3 rpy,
+                                 Ref_matrix43 p, Ref_matrix43 N)
+{
+  // compute rotation matrix
+  Quaternion<value_type> q = angle_axis_t(rpy(0), Vector3::UnitX())
+                             * angle_axis_t(rpy(1), Vector3::UnitY())
+                             * angle_axis_t(rpy(2), Vector3::UnitZ());
+  //euler_matrix(rpy[0], rpy[1], rpy[2], R);
+  // contact points in local frame
+  p << lx,  ly, 0,
+       lx, -ly, 0,
+      -lx, -ly, 0,
+      -lx,  ly, 0;
+  // contact points in world frame
+  p.row(0) = pos + q*p.row(0);
+  p.row(1) = pos + q*p.row(1);
+  p.row(2) = pos + q*p.row(2);
+  p.row(3) = pos + q*p.row(3);
+  // normal direction in local frame
+  RVector3 n;
+  n << 0, 0, 1;
+  // normal directions in world frame
+  n = q*n;
+  N << n, n, n, n;
+  return true;
+}
+
+int main()
+{
+  int ret = 0;
+  double mu = 0.3;  // friction coefficient
+  unsigned int generatorsPerContact = 4;
+  unsigned int N_CONTACTS = 8;
+  unsigned int N_POINTS = 50;   // number of com positions to test
+  double MIN_FEET_DISTANCE = 0.3;
+  double LX = 0.5*0.2172;        // half foot size in x direction
+  double LY = 0.5*0.138;         // half foot size in y direction
+  RVector3 CONTACT_POINT_LOWER_BOUNDS, CONTACT_POINT_UPPER_BOUNDS;
+  CONTACT_POINT_LOWER_BOUNDS <<-0.5, -0.5,  0.0;
+  CONTACT_POINT_UPPER_BOUNDS << 0.5,  0.5,  1.0;
+  double gamma = atan(mu);   // half friction cone angle
+  RVector3 RPY_LOWER_BOUNDS, RPY_UPPER_BOUNDS;
+  RPY_LOWER_BOUNDS << -2*gamma, -2*gamma, -M_PI;
+  RPY_UPPER_BOUNDS << +2*gamma, +2*gamma, +M_PI;
+  double X_MARG = 0.07;
+  double Y_MARG = 0.07;
+
+  StaticEquilibrium solver(generatorsPerContact, SOLVER_LP_QPOASES);
+  MatrixXX contact_pos = MatrixXX::Zero(N_CONTACTS, 3);
+  MatrixXX contact_rpy = MatrixXX::Zero(N_CONTACTS, 3);
+  MatrixXX p = MatrixXX::Zero(4*N_CONTACTS,3); // contact points
+  MatrixXX N = MatrixXX::Zero(4*N_CONTACTS,3); // contact normals
+  VectorX frictionCoefficients(N_CONTACTS);
+  frictionCoefficients.fill(mu);
+
+  // Generate contact positions and orientations
+  bool collision;
+  for(int i=0; i<N_CONTACTS; i++)
+  {
+    while(true) // generate contact position
+    {
+      uniform(CONTACT_POINT_LOWER_BOUNDS, CONTACT_POINT_UPPER_BOUNDS, contact_pos.row(i));
+      collision = false;
+      for(int j=0; j<i-1; j++)
+        if((contact_pos.row(i)-contact_pos.row(j)).norm() < MIN_FEET_DISTANCE)
+          collision = true;
+      if(collision==false)
+        break;
+    }
+
+    // generate contact orientation
+    uniform(RPY_LOWER_BOUNDS, RPY_UPPER_BOUNDS, contact_rpy.row(i));
+    generate_rectangle_contacts(LX, LY, contact_pos.row(i), contact_rpy.row(i),
+                                p.middleRows<4>(i*4), N.middleRows<4>(i*4));
+  }
+
+  solver.setNewContacts(p, N, frictionCoefficients, STATIC_EQUILIBRIUM_ALGORITHM_PP);
+
+
+  RVector2 com_LB, com_UB;
+  com_LB(0) = p.col(0).minCoeff()-X_MARG;
+  com_UB(0) = p.col(0).maxCoeff()+X_MARG;
+  com_LB(1) = p.col(1).minCoeff()-Y_MARG;
+  com_UB(1) = p.col(1).maxCoeff()+Y_MARG;
+  MatrixXX com(N_POINTS,2);
+  for(int i=0; i<N_POINTS; i++)
+  {
+    uniform(com_LB, com_UB, com.row(i));
+    double robustness = solver.checkRobustEquilibrium(com.row(i), 0.0);
+    printf("CoM position (%.3f, %.3f) robustness %.3f\n", com(i,0), com(i,1), robustness);
+  }
+
+  return ret;
+}
-- 
GitLab