diff --git a/README.md b/README.md
index fe586f98c..c08222b81 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ The CT was designed with the following features in mind:
- solve large scale optimal control problems in MPC fashion.
- **Robot Modelling, Rigid Body Kinematics and Dynamics**:
- - straight-forward interface to the state-of the art rigid body dynamics modelling tool RobCoGen.
+ - straight-forward interface to the state-of the art rigid body dynamics modelling tool [RobCoGen][robcogen-url].
- implementation of a basic nonlinear-programming inverse kinematics solver for fix-base robots.
- **Automatic Differentiation**:
@@ -196,9 +196,10 @@ The four different main modules are detailed in the following.
- Operational Space Controllers
- Basic soft **auto-differentiable contact model** for arbitrary frames (ct::rbd::EEContactModel)
- **Actuator dynamics** (ct::rbd::ActuatorDynamics)
- - Backend uses RobCoGen \cite frigerioCodeGen,
+ - Backend uses [RobCoGen][robcogen-url],
a highly efficient Rigid Body Dynamics library
+[robcogen-url]: https://robcogenteam.bitbucket.io/
### ct_models
diff --git a/ct/CMakeLists.txt b/ct/CMakeLists.txt
index 0df155c5c..8890c7609 100644
--- a/ct/CMakeLists.txt
+++ b/ct/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.14.7)
+cmake_minimum_required(VERSION 3.5)
project(ct VERSION 3.0.2 LANGUAGES CXX)
#Make sure metapackage does not fail when building documentation
diff --git a/ct/cmake/explicitTemplateHelpers.cmake b/ct/cmake/explicitTemplateHelpers.cmake
index e9a2bdee3..a6c4c6635 100644
--- a/ct/cmake/explicitTemplateHelpers.cmake
+++ b/ct/cmake/explicitTemplateHelpers.cmake
@@ -1,21 +1,30 @@
# reads the templates from file
function(ct_getDimensionsFromLine LineContent)
- string(REGEX REPLACE "," ";" LineContent ${LineContent})
+ #message(WARNING "received line content: \n " ${LineContent})
+
+ STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}")
+ STRING(REGEX REPLACE "\n" ";" LineContent "${LineContent}")
+
+ foreach(NameAndValue ${LineContent})
- foreach(NameAndValue ${LineContent})
# Strip leading spaces
string(REGEX REPLACE "^[ ]+" "" NameAndValue ${NameAndValue})
# Find variable name
string(REGEX MATCH "^[^=]+" Name ${NameAndValue})
# Find the value
string(REPLACE "${Name}=" "" Value ${NameAndValue})
-
- # Set the variable
+ # strip unnecessaray white space from Value
+ string(REGEX REPLACE " " "" Value ${Value})
+
+ # Set the variables
+ if(Name STREQUAL "MANIFOLD")
+ set(MANIFOLD_PRESPEC "${Value}" PARENT_SCOPE)
+ endif()
+
if(Name STREQUAL "STATE_DIM")
set(STATE_DIM_PRESPEC "${Value}" PARENT_SCOPE)
endif()
- # Set the variable
if(Name STREQUAL "CONTROL_DIM")
set(CONTROL_DIM_PRESPEC "${Value}" PARENT_SCOPE)
endif()
@@ -32,7 +41,6 @@ function(ct_getDimensionsFromLine LineContent)
set(VEL_DIM_PRESPEC "${Value}" PARENT_SCOPE)
endif()
endforeach()
-
endfunction()
@@ -42,12 +50,22 @@ function(ct_configure_explicit_templates ConfigFile ConfigDir LibPrefix)
FILE(READ "${ConfigFile}" contents)
STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}")
- STRING(REGEX REPLACE "\n" ";" contents "${contents}")
+ STRING(REGEX REPLACE "\n\n" ";" contents "${contents}")
- #message(WARNING "file content: ${contents}")
+ #message(WARNING "loaded file content: \n ${contents}")
foreach(line ${contents})
- #message(WARNING "extracting variables from line: ${line}")
+
+ # check if line contains comments (starting with #)
+ string(FIND ${line} "#" _idx_comment_start)
+ # if comment found, skip that line
+ if(${_idx_comment_start} GREATER -1)
+ message(ERROR " Found a comment '#' in explicit template spec -- please remove it, comments are not (yet) supported in prespec configs.")
+ continue()
+ endif()
+
+ #message(WARNING "extracting variables from line:\n ${line}")
+ set(MANIFOLD_PRESPEC "")
set(STATE_DIM_PRESPEC "")
set(CONTROL_DIM_PRESPEC "")
set(SCALAR_PRESPEC "")
@@ -57,19 +75,23 @@ function(ct_configure_explicit_templates ConfigFile ConfigDir LibPrefix)
ct_getDimensionsFromLine(${line})
- #message(WARNING "extracted: STATE_DIM=${STATE_DIM_PRESPEC}, CONTROL_DIM=${STATE_DIM_PRESPEC}, SCALAR=${SCALAR_PRESPEC}")
+ #message(WARNING "extracted: MANIFOLD=${MANIFOLD_PRESPEC} STATE_DIM=${STATE_DIM_PRESPEC}, CONTROL_DIM=${CONTROL_DIM_PRESPEC}, SCALAR=${SCALAR_PRESPEC}")
string(REGEX REPLACE "[^0-9a-zA-Z]+" "" SCALAR_PRESPEC_CLEAN ${SCALAR_PRESPEC})
- set(CURRENT_LIB_NAME "${LibPrefix}-${STATE_DIM_PRESPEC}-${CONTROL_DIM_PRESPEC}-${SCALAR_PRESPEC_CLEAN}-${POS_DIM_PRESPEC}-${VEL_DIM_PRESPEC}")
-
- if(STATE_DIM_PRESPEC AND CONTROL_DIM_PRESPEC AND SCALAR_PRESPEC)
- #message(WARNING "Will configure now")
- ct_configureFiles(${ConfigDir} ${STATE_DIM_PRESPEC}, ${CONTROL_DIM_PRESPEC}, ${SCALAR_PRESPEC} ${POS_DIM_PRESPEC} ${VEL_DIM_PRESPEC})
+ string(REGEX REPLACE "[^0-9a-zA-Z]+" "" MANIFOLD_PRESPEC_CLEAN ${MANIFOLD_PRESPEC})
+
+ set(CURRENT_LIB_NAME "${LibPrefix}-${MANIFOLD_PRESPEC_CLEAN}-${CONTROL_DIM_PRESPEC}-${SCALAR_PRESPEC_CLEAN}-${POS_DIM_PRESPEC}-${VEL_DIM_PRESPEC}")
+ #message(WARNING "Current lib name: \n ${CURRENT_LIB_NAME}")
+
+ if(MANIFOLD_PRESPEC AND CONTROL_DIM_PRESPEC AND SCALAR_PRESPEC)
+ message(WARNING "Will configure now")
+ ct_configureFiles(${ConfigDir} ${MANIFOLD_PRESPEC}, ${CONTROL_DIM_PRESPEC}, ${SCALAR_PRESPEC} ${POS_DIM_PRESPEC} ${VEL_DIM_PRESPEC})
elseif()
#message(WARNING "Nothing to configure")
endif()
if(CURRENT_SRCS)
+ #message(WARNING "the current sources are \n ${CURRENT_SRCS}")
set(${CURRENT_LIB_NAME}_SRCS ${CURRENT_SRCS} PARENT_SCOPE)
list(APPEND LIB_NAMES "${CURRENT_LIB_NAME}")
endif()
@@ -81,15 +103,16 @@ endfunction()
# finds cpp.in files and configures them
-function(ct_configureFiles ConfigDir STATE_DIM_PRESPEC, CONTROL_DIM_PRESPEC, SCALAR_PRESPEC, POS_DIM_PREPSEC, VEL_DIM_PRESPEC)
+function(ct_configureFiles ConfigDir MANIFOLD_PRESPEC, CONTROL_DIM_PRESPEC, SCALAR_PRESPEC, POS_DIM_PREPSEC, VEL_DIM_PRESPEC)
set(CURRENT_SRCS "")
file(GLOB_RECURSE files "${ConfigDir}*.in")
#message(WARNING "files to configure in directory ${ConfigDir}:\n ${files}")
foreach(file ${files})
+ string(REGEX REPLACE "[^0-9a-zA-Z]+" "" MANIFOLD_PRESPEC_CLEAN ${MANIFOLD_PRESPEC})
string(REGEX REPLACE "[^0-9a-zA-Z]+" "" SCALAR_PRESPEC_CLEAN ${SCALAR_PRESPEC})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" outputFile ${file})
string(REPLACE ".cpp.in" "" outputFile ${outputFile})
- set(outputFile "${outputFile}-${STATE_DIM_PRESPEC}-${CONTROL_DIM_PRESPEC}-${SCALAR_PRESPEC_CLEAN}-${POS_DIM_PRESPEC}-${VEL_DIM_PRESPEC}.cpp")
+ set(outputFile "${outputFile}-${MANIFOLD_PRESPEC_CLEAN}-${CONTROL_DIM_PRESPEC}-${SCALAR_PRESPEC_CLEAN}-${POS_DIM_PRESPEC}-${VEL_DIM_PRESPEC}.cpp")
#message(WARNING "configuring file \n ${file} to \n ${outputFile} ")
set(DOUBLE_OR_FLOAT false)
if((SCALAR_PRESPEC MATCHES "double") OR (SCALAR_PRESPEC MATCHES "float")) #STREQUAL did not work
diff --git a/ct/config/explicit_templates.cfg b/ct/config/explicit_templates.cfg
index c9bca24cf..748e7e26c 100644
--- a/ct/config/explicit_templates.cfg
+++ b/ct/config/explicit_templates.cfg
@@ -1,4 +1,32 @@
-STATE_DIM=2, CONTROL_DIM=1, POS_DIM=1, VEL_DIM=1, SCALAR=double
-STATE_DIM=12, CONTROL_DIM=4, POS_DIM=6, VEL_DIM=6, SCALAR=double
+MANIFOLD=ct::core::EuclideanState<2, double>
+CONTROL_DIM=1
+POS_DIM=1
+VEL_DIM=1
+SCALAR=double
+
+MANIFOLD=ct::core::ManifoldState
+CONTROL_DIM=6
+POS_DIM=6
+VEL_DIM=6
+SCALAR=double
+
+MANIFOLD=ct::core::ManifoldState ## todo this case should be covered
+CONTROL_DIM=3
+POS_DIM=3
+VEL_DIM=3
+SCALAR=double
+
+#MANIFOLD=ManifoldState ## todo this case should be covered
+#CONTROL_DIM=3
+#POS_DIM=3
+#VEL_DIM=3
+#SCALAR=double
+
+# todo rewrite all of this
+#STATE_DIM=2, CONTROL_DIM=1, POS_DIM=1, VEL_DIM=1, SCALAR=double
+#STATE_DIM=12, CONTROL_DIM=4, POS_DIM=6, VEL_DIM=6, SCALAR=double
#STATE_DIM=12, CONTROL_DIM=6, POS_DIM=6, VEL_DIM=6, SCALAR=double
#STATE_DIM=2, CONTROL_DIM=2, POS_DIM=1, VEL_DIM=1, SCALAR=ct::core::ADScalar
+
+
+
diff --git a/ct_core/CMakeLists.txt b/ct_core/CMakeLists.txt
index 89840ce8f..139453ca3 100755
--- a/ct_core/CMakeLists.txt
+++ b/ct_core/CMakeLists.txt
@@ -1,18 +1,20 @@
-cmake_minimum_required (VERSION 3.14.7)
+cmake_minimum_required (VERSION 3.5)
include(${CMAKE_CURRENT_SOURCE_DIR}/../ct/cmake/compilerSettings.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/../ct/cmake/explicitTemplateHelpers.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/../ct/cmake/clang-cxx-dev-tools.cmake)
-
project(ct_core VERSION 3.0.2 LANGUAGES CXX)
-
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++14 -Wall -Wfatal-errors")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread -std=c++14 -Wall -Wfatal-errors")
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
+option(CT_DISABLE_NUMERIC_MANIFOLD_CHECKS off)
+if(CT_DISABLE_NUMERIC_MANIFOLD_CHECKS)
+ list(APPEND ct_core_COMPILE_DEFINITIONS CT_DISABLE_NUMERIC_MANIFOLD_CHECKS)
+endif()
set(ct_core_LIBS "")
@@ -21,6 +23,13 @@ find_package(Eigen3 REQUIRED)
find_package(Boost COMPONENTS REQUIRED)
## find and include optional dependencies
+find_package(manif QUIET)
+if(manif_FOUND)
+ message(STATUS "Found manif")
+ list(APPEND ct_core_COMPILE_DEFINITIONS CT_USE_MANIF)
+ list(APPEND ct_core_target_include_dirs ${manif_INCLUDE_DIRS})
+endif(manif_FOUND)
+
find_package(llvm QUIET)
find_package(clang QUIET)
if(LLVM_FOUND AND CLANG_FOUND)
@@ -63,18 +72,30 @@ else()
message(STATUS "COMPILING WITHOUT QWT")
endif()
-find_package(Python COMPONENTS Development NumPy QUIET)
-if (Python_FOUND AND ${Python_VERSION_MAJOR} EQUAL 3)
- message(STATUS "Found python " ${Python_VERSION})
- list(APPEND ct_core_COMPILE_DEFINITIONS PLOTTING_ENABLED)
- set(PLOTTING_ENABLED ON)
- message(STATUS "Python library path ... " ${Python_LIBRARIES})
- list(APPEND ct_core_LIBS ${Python_LIBRARIES})
+if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
+ find_package(PythonLibs 3 QUIET)
+ if (PYTHONLIBS_FOUND)
+ message(STATUS "Found python 3")
+ list(APPEND ct_core_COMPILE_DEFINITIONS PLOTTING_ENABLED)
+ set(PLOTTING_ENABLED ON)
+ message(STATUS "Python library path ... " ${PYTHON_LIBRARY})
+ list(APPEND ct_core_LIBS ${PYTHON_LIBRARY})
+ else()
+ message(STATUS "Python 3 not found, plotting will not be available")
+ endif()
else()
- message(STATUS "Python 3 not found, plotting will not be available")
+ find_package(Python COMPONENTS Development NumPy QUIET)
+ if (Python_FOUND AND ${Python_VERSION_MAJOR} EQUAL 3)
+ message(STATUS "Found python " ${Python_VERSION})
+ list(APPEND ct_core_COMPILE_DEFINITIONS PLOTTING_ENABLED)
+ set(PLOTTING_ENABLED ON)
+ message(STATUS "Python library path ... " ${Python_LIBRARIES})
+ list(APPEND ct_core_LIBS ${Python_LIBRARIES})
+ else()
+ message(STATUS "Python 3 not found, plotting will not be available")
+ endif()
endif()
-
## configure files required for code-generation
set(CODEGEN_TEMPLATE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/templates")
set(CODEGEN_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
@@ -87,13 +108,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/ct/core/templateDir.h.in ${CM
## define the directories to be included in all ct_core targets
list(APPEND ct_core_target_include_dirs ${EIGEN3_INCLUDE_DIR})
-list(APPEND ct_core_target_include_dirs ${Python_INCLUDE_DIRS})
-list(APPEND ct_core_target_include_dirs ${Python_NumPy_INCLUDE_DIRS})
+if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
+ list(APPEND ct_core_target_include_dirs ${PYTHON_INCLUDE_DIRS})
+else()
+ list(APPEND ct_core_target_include_dirs ${Python_INCLUDE_DIRS})
+ list(APPEND ct_core_target_include_dirs ${Python_NumPy_INCLUDE_DIRS})
+endif()
list(APPEND ct_core_target_include_dirs ${QWT_INCLUDE_DIR})
list(APPEND ct_core_target_include_dirs $)
list(APPEND ct_core_target_include_dirs $)
list(APPEND ct_core_target_include_dirs $)
+
## declare prespec libraries
set(PRESPEC_LIB_NAMES "")
@@ -113,7 +139,7 @@ if(USE_PRESPEC)
endif()
-## create ct_core libraries
+# plotting
add_library(ct_plot SHARED src/core/plot/plot.cpp)
target_include_directories(ct_plot PUBLIC ${ct_core_target_include_dirs})
target_compile_definitions(ct_plot PUBLIC ${ct_core_COMPILE_DEFINITIONS})
@@ -125,12 +151,13 @@ target_compile_definitions(ct_core INTERFACE ${ct_core_COMPILE_DEFINITIONS})
target_link_libraries(ct_core INTERFACE
${ct_core_LIBS}
${PRESPEC_LIB_NAMES}
+ #ct_core_explicit
ct_plot
pthread
dl # required for gcc compatibility
)
-
+
##################
# BUILD EXAMPLES #
##################
@@ -198,4 +225,3 @@ endif()
#################
add_subdirectory(doc)
-
diff --git a/ct_core/examples/include/ct/core/examples/CustomController.h b/ct_core/examples/include/ct/core/examples/CustomController.h
index 0f19b7a04..8914da485 100644
--- a/ct_core/examples/include/ct/core/examples/CustomController.h
+++ b/ct_core/examples/include/ct/core/examples/CustomController.h
@@ -6,30 +6,31 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
/*!
- * A simple custom PD controller for an oscillator
+ * A simple custom PD controller
*
* see \ref DampedOscillatorCustomController.cpp on how to use it.
*
* \example CustomController.h
*/
//! an example controller class that takes a 2-dimensional state and outputs a 1-dimensional control action
-class CustomController : public ct::core::Controller<2, 1>
+class CustomController : public ct::core::Controller, 1, ct::core::CONTINUOUS_TIME>
{
public:
static const size_t state_dim = 2; // two states
static const size_t control_dim = 1; // one control action
+ using State = ct::core::EuclideanState;
+ using ControlVector = ct::core::ControlVector;
+
//! default constructor
- CustomController(const ct::core::ControlVector& uff, // feedforward control
- const double& kp, // P gain
- const double& kd // D gain
+ CustomController(const ControlVector& uff, // feedforward control
+ const double& kp, // P gain
+ const double& kd // D gain
)
: uff_(uff), kp_(kp), kd_(kd)
{
}
- //! destructor
- ~CustomController() {}
//! copy constructor
CustomController(const CustomController& other) : uff_(other.uff_), kp_(other.kp_), kd_(other.kd_) {}
//! clone method, needs to be implemented, overrides ct::core::Controller::clone()
@@ -39,16 +40,14 @@ class CustomController : public ct::core::Controller<2, 1>
}
//! override the compute control method with a custom control law
- void computeControl(const ct::core::StateVector& state,
- const double& t,
- ct::core::ControlVector& controlAction) override
+ void computeControl(const State& state, const double& t, ControlVector& controlAction) override
{
controlAction = uff_; // apply feedforward control
controlAction(0) -= kp_ * state(0) + kd_ * state(1); // add feedback control
}
private:
- ct::core::ControlVector uff_; //! feedforward control action
- double kp_; //! P gain
- double kd_; //! D gain
+ ControlVector uff_; //! feedforward control action
+ double kp_; //! P gain
+ double kd_; //! D gain
};
diff --git a/ct_core/examples/include/ct/core/examples/Masspoint.h b/ct_core/examples/include/ct/core/examples/Masspoint.h
index 9702d8167..0656a5b82 100644
--- a/ct_core/examples/include/ct/core/examples/Masspoint.h
+++ b/ct_core/examples/include/ct/core/examples/Masspoint.h
@@ -1,49 +1,50 @@
/*!
* \brief This example shows how to define your own system.
*
- * \note This generates a "System", not a "ControlledSystem". If you wanted to use
- * this system for controller design, you should derive from "ControlledSystem"
+ * The system created here is a simple mass-point second-order dynamics in one dimension.
+ * Therefore, the state dimension is 2, and the control dimension is 1
+ *
+ * \note This generates a "System" in continuous-time, not a "ControlledSystem".
+ * If you wanted to use this system for controller design, you should derive from "ControlledSystem"
+ * instead.
*
* \example Masspoint.h
*/
#pragma once
-#include // as usual, include CT
+#include
-// create a class that derives from ct::core::System
-class Masspoint : public ct::core::System<2>
+// create a class that derives from ct::core::System in continuous time
+class Masspoint : public ct::core::System, ct::core::CONTINUOUS_TIME>
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
-
- static const size_t STATE_DIM = 2;
- // constructor
- Masspoint(double mass, double d) : mass_(mass), d_(d) {}
+ // convenience definitions, with state-space dimension 2. Define control dimension=1
+ static constexpr size_t state_dim = 2;
+ using State = ct::core::EuclideanState;
+ using StateDerivative = State::Tangent;
- // copy constructor
+ // constructor
+ Masspoint(const double mass, const double damping) : mass_(mass), d_(damping) {}
+ // copy constructor (required)
Masspoint(const Masspoint& other) : mass_(other.mass_), d_(other.d_) {}
-
- // destructor
- ~Masspoint() = default;
-
- // clone method for deep copying
+ // clone method for deep copying (required)
Masspoint* clone() const override
{
return new Masspoint(*this); // calls copy constructor
}
- // The system dynamics. We override this method which gets called by e.g. the Integrator
- void computeDynamics(const ct::core::StateVector& x,
- const ct::core::Time& t,
- ct::core::StateVector& derivative) override
+ // The system dynamics. We override this method, which gets called by e.g. the Integrator,
+ // or by the system linearizers
+ void computeDynamics(const State& x, const double& time, StateDerivative& dxdt) override
{
// first part of state derivative is the velocity
- derivative(0) = x(1);
+ dxdt(0) = x(1);
// second part is the acceleration which is caused by damper forces
- derivative(1) = -d_ / mass_ * x(1);
+ dxdt(1) = -d_ / mass_ * x(1);
}
private:
diff --git a/ct_core/examples/src/DampedOscillator.cpp b/ct_core/examples/src/DampedOscillator.cpp
index 7f5b915db..580bb63b1 100644
--- a/ct_core/examples/src/DampedOscillator.cpp
+++ b/ct_core/examples/src/DampedOscillator.cpp
@@ -13,7 +13,8 @@ int main(int argc, char** argv)
const size_t state_dim = ct::core::SecondOrderSystem::STATE_DIM; // = 2
// create a state
- ct::core::StateVector x;
+ using State = ct::core::EuclideanState;
+ State x;
// we initialize it at a point with unit deflection and zero velocity
x(0) = 1.0;
@@ -24,7 +25,7 @@ int main(int argc, char** argv)
std::shared_ptr oscillator(new ct::core::SecondOrderSystem(w_n));
// create an integrator
- ct::core::Integrator integrator(oscillator);
+ ct::core::Integrator integrator(oscillator);
// simulate 1000 steps
double dt = 0.001;
diff --git a/ct_core/examples/src/DampedOscillatorCustomController.cpp b/ct_core/examples/src/DampedOscillatorCustomController.cpp
index de69239c4..95f24ac8d 100644
--- a/ct_core/examples/src/DampedOscillatorCustomController.cpp
+++ b/ct_core/examples/src/DampedOscillatorCustomController.cpp
@@ -20,7 +20,8 @@ int main(int argc, char** argv)
const size_t control_dim = ct::core::SecondOrderSystem::CONTROL_DIM; // = 1
// create a state
- ct::core::StateVector x;
+ using State = ct::core::EuclideanState;
+ State x;
// we initialize it at a point with unit deflection and zero velocity
x(0) = 1.0;
@@ -41,7 +42,7 @@ int main(int argc, char** argv)
oscillator->setController(controller);
// create an integrator
- ct::core::Integrator integrator(oscillator, ct::core::IntegrationType::RK4);
+ ct::core::Integrator integrator(oscillator, ct::core::IntegrationType::RK4);
// simulate 1000 steps
double dt = 0.001;
diff --git a/ct_core/examples/src/MasspointIntegration.cpp b/ct_core/examples/src/MasspointIntegration.cpp
index 7c059f704..48298a85b 100644
--- a/ct_core/examples/src/MasspointIntegration.cpp
+++ b/ct_core/examples/src/MasspointIntegration.cpp
@@ -9,13 +9,14 @@
int main(int argc, char** argv)
{
// a damped oscillator has two states, position and velocity
- const size_t state_dim = Masspoint::STATE_DIM; // = 2
+ const size_t state_dim = Masspoint::state_dim; // = 2
// create a state
- ct::core::StateVector x;
+ using State = Masspoint::State;
+ State x;
- // we initialize it at 0
- x.setZero();
+ // we initialize it at 1
+ x << 1, 0;
// create our mass point instance
double mass = 1.0;
@@ -23,7 +24,7 @@ int main(int argc, char** argv)
std::shared_ptr masspoint(new Masspoint(mass, d));
// create an integrator
- ct::core::Integrator integrator(masspoint);
+ ct::core::Integrator integrator(masspoint);
// simulate 1000 steps
double dt = 0.001;
diff --git a/ct_core/include/ct/core/Common b/ct_core/include/ct/core/Common
index c96582cc1..017bc09b2 100644
--- a/ct_core/include/ct/core/Common
+++ b/ct_core/include/ct/core/Common
@@ -14,4 +14,7 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#include "common/Interpolation.h"
#include "common/linspace.h"
#include "common/activations/Activations.h"
+#include "common/EigenIsNan.h"
+#include "common/EigenFileExport.h"
+
diff --git a/ct_core/include/ct/core/Control b/ct_core/include/ct/core/Control
index 906768f02..fc8a9c8f5 100644
--- a/ct_core/include/ct/core/Control
+++ b/ct_core/include/ct/core/Control
@@ -5,14 +5,11 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
-#include "control/continuous_time/Controller.h"
-#include "control/discrete_time/DiscreteController.h"
-
+#include "control/Controller.h"
+#include "control/ConstantController.h"
#include "control/StateFeedbackController.h"
-#include "control/continuous_time/ConstantController.h"
-#include "control/continuous_time/ConstantStateFeedbackController.h"
-#include "control/continuous_time/ConstantTrajectoryController.h"
-#include "control/continuous_time/siso/PIDController.h"
-#include "control/continuous_time/siso/PIDController-impl.h"
-#include "control/continuous_time/siso/StepInputController.h"
-#include "control/continuous_time/mimo/LinearFunctions.h"
+
+//#include "control/continuous_time/siso/PIDController.h"
+//#include "control/continuous_time/siso/PIDController-impl.h"
+//#include "control/continuous_time/siso/StepInputController.h"
+//#include "control/continuous_time/mimo/LinearFunctions.h"
diff --git a/ct_core/include/ct/core/Control-impl b/ct_core/include/ct/core/Control-impl
index 9c7393b62..994c7d77f 100644
--- a/ct_core/include/ct/core/Control-impl
+++ b/ct_core/include/ct/core/Control-impl
@@ -5,5 +5,5 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
+#include "control/ConstantController-impl.h"
#include "control/StateFeedbackController-impl.h"
-#include "control/continuous_time/ConstantController-impl.h"
diff --git a/ct_core/include/ct/core/Integration b/ct_core/include/ct/core/Integration
index 729abf394..1e8b0069c 100644
--- a/ct_core/include/ct/core/Integration
+++ b/ct_core/include/ct/core/Integration
@@ -5,12 +5,24 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
+#include "integration/internal/StepperBase.h"
+#include "integration/internal/StepperCTBase.h"
+#include "integration/internal/StepperEulerCT.h"
+#include "integration/internal/StepperRK4CT.h"
+#include "integration/internal/StepperODEInt.h"
+#include "integration/internal/StepperODEIntDenseOutput.h"
+#include "integration/internal/StepperODEIntControlled.h"
+
#include "integration/Observer.h"
-#include "integration/Integrator.h"
-#include "integration/IntegratorSymplectic.h"
+
+#include "integration/EventHandler.h"
#include "integration/EventHandlers/KillIntegrationEventHandler.h"
#include "integration/EventHandlers/MaxStepsEventHandler.h"
#include "integration/EventHandlers/SubstepRecorder.h"
+
+#include "integration/Integrator.h"
+#include "integration/IntegratorSymplectic.h"
+
#include "integration/sensitivity/Sensitivity.h"
#include "integration/sensitivity/SensitivityApproximation.h"
#include "integration/sensitivity/SensitivityIntegrator.h"
diff --git a/ct_core/include/ct/core/Integration-impl b/ct_core/include/ct/core/Integration-impl
index 5c23c0dee..264592958 100644
--- a/ct_core/include/ct/core/Integration-impl
+++ b/ct_core/include/ct/core/Integration-impl
@@ -5,6 +5,18 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
+#include "integration/internal/StepperBase-impl.h"
+#include "integration/internal/StepperCTBase-impl.h"
+#include "integration/internal/StepperEulerCT-impl.h"
+#include "integration/internal/StepperRK4CT-impl.h"
+#include "integration/internal/StepperODEInt-impl.h"
+#include "integration/internal/StepperODEIntControlled-impl.h"
+#include "integration/internal/StepperODEIntDenseOutput-impl.h"
+
+#include "integration/EventHandlers/KillIntegrationEventHandler-impl.h"
+#include "integration/EventHandlers/MaxStepsEventHandler-impl.h"
+#include "integration/EventHandlers/SubstepRecorder-impl.h"
+
#include "integration/Observer-impl.h"
#include "integration/Integrator-impl.h"
#include "integration/IntegratorSymplectic-impl.h"
diff --git a/ct_core/include/ct/core/Internal b/ct_core/include/ct/core/Internal
index 7ef7c4059..6abbde1a6 100644
--- a/ct_core/include/ct/core/Internal
+++ b/ct_core/include/ct/core/Internal
@@ -13,4 +13,5 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#include "internal/traits/TraitSelector.h"
#include "internal/traits/TraitSelectorSpecs.h"
#include "internal/traits/DoubleTrait.h"
+#include "internal/traits/EvaluatorOutTypeTraits.h"
diff --git a/ct_core/include/ct/core/Simulation-impl b/ct_core/include/ct/core/Simulation-impl
deleted file mode 100644
index 589e8bc23..000000000
--- a/ct_core/include/ct/core/Simulation-impl
+++ /dev/null
@@ -1,8 +0,0 @@
-/**********************************************************************************************************************
-This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
-Licensed under the BSD-2 license (see LICENSE file in main directory)
-**********************************************************************************************************************/
-
-#pragma once
-
-// put impl files here
diff --git a/ct_core/include/ct/core/Systems b/ct_core/include/ct/core/Systems
index 4879af7d7..902673511 100644
--- a/ct_core/include/ct/core/Systems
+++ b/ct_core/include/ct/core/Systems
@@ -5,37 +5,22 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
-#include "systems/continuous_time/System.h"
-#include "systems/continuous_time/ControlledSystem.h"
-#include "systems/continuous_time/SecondOrderSystem.h"
-#include "systems/continuous_time/ControlledSystem.h"
-#include "systems/continuous_time/SwitchedControlledSystem.h"
-#include "systems/continuous_time/linear/LinearSystem.h"
-#include "systems/continuous_time/linear/SwitchedLinearSystem.h"
-#include "systems/continuous_time/linear/LTISystem.h"
+#include "systems/System.h"
+#include "systems/ControlledSystem.h"
+#include "systems/SecondOrderSystem.h"
+#include "systems/SymplecticSystem.h"
+#include "systems/LinearSystem.h"
+#include "systems/LTISystem.h"
+#include "systems/SwitchedControlledSystem.h"
+#include "systems/SwitchedLinearSystem.h"
#include "systems/linearizer/DynamicsLinearizerNumDiff.h"
+#include "systems/linearizer/SystemLinearizer.h"
#ifdef CPPADCG
-#include "systems/linearizer/DynamicsLinearizerAD.h"
-#include "systems/linearizer/DynamicsLinearizerADCG.h"
+ #include "systems/linearizer/DynamicsLinearizerAD.h"
+ #include "systems/linearizer/AutoDiffLinearizer.h"
+ #include "systems/linearizer/DynamicsLinearizerADCG.h"
+ #include "systems/linearizer/ADCodegenLinearizer.h"
#endif
-#include "systems/continuous_time/linear/SystemLinearizer.h"
-#ifdef CPPADCG
-#include "systems/continuous_time/linear/AutoDiffLinearizer.h"
-#include "systems/continuous_time/linear/ADCodegenLinearizer.h"
-#endif
-
-#include "systems/discrete_time/DiscreteControlledSystem.h"
-#include "systems/discrete_time/SwitchedDiscreteControlledSystem.h"
-#include "systems/discrete_time/SystemDiscretizer.h"
-
-#include "systems/discrete_time/linear/DiscreteLinearSystem.h"
-#include "systems/discrete_time/linear/DiscreteLTISystem.h"
-#include "systems/discrete_time/linear/SwitchedDiscreteLinearSystem.h"
-#include "systems/discrete_time/linear/DiscreteSystemLinearizer.h"
-
-#ifdef CPPADCG
-#include "systems/discrete_time/linear/DiscreteSystemLinearizerAD.h"
-#include "systems/discrete_time/linear/DiscreteSystemLinearizerADCG.h"
-#endif
+#include "systems/discretizer/SystemDiscretizer.h"
diff --git a/ct_core/include/ct/core/Systems-impl b/ct_core/include/ct/core/Systems-impl
index c16e5ad27..f59cbcc54 100644
--- a/ct_core/include/ct/core/Systems-impl
+++ b/ct_core/include/ct/core/Systems-impl
@@ -5,5 +5,8 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
-// put impl files here
-#include "systems/discrete_time/SystemDiscretizer-impl.h"
+#include "systems/System-impl.h"
+#include "systems/ControlledSystem-impl.h"
+#include "systems/SecondOrderSystem-impl.h"
+
+#include "systems/discretizer/SystemDiscretizer-impl.h"
diff --git a/ct_core/include/ct/core/Types b/ct_core/include/ct/core/Types
index 87f226eac..2e21a2ffb 100644
--- a/ct_core/include/ct/core/Types
+++ b/ct_core/include/ct/core/Types
@@ -8,8 +8,12 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#include "types/Time.h"
#include "types/AutoDiff.h"
+
+#include "types/ManifoldState.h"
+#include "types/EuclideanState.h"
+#include "types/EuclideanStateSymplectic.h"
+
#include "types/ControlVector.h"
-#include "types/StateVector.h"
#include "types/OutputVector.h"
#include "types/FeedbackMatrix.h"
#include "types/StateMatrix.h"
@@ -21,10 +25,14 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#include "types/arrays/ScalarArray.h"
#include "types/arrays/TimeArray.h"
#include "types/arrays/MatrixArrays.h"
+#include "types/arrays/ManifArrays.h"
#include "types/arrays/ArrayHelpers.h"
-#include "types/trajectories/DiscreteTrajectoryBase.h"
+#include "types/trajectories/DiscreteTrajectory.h"
#include "types/trajectories/ScalarTrajectory.h"
#include "types/trajectories/MatrixTrajectories.h"
+#include "types/TypeTraits.h"
+#include "types/TypeMacros.h"
+
diff --git a/ct_core/include/ct/core/Types-impl b/ct_core/include/ct/core/Types-impl
index 1fd96dfcb..cc9497949 100644
--- a/ct_core/include/ct/core/Types-impl
+++ b/ct_core/include/ct/core/Types-impl
@@ -5,5 +5,5 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
-// put implementations here
+#include "types/ManifoldState-impl.h"
diff --git a/ct_core/include/ct/core/common/EigenFileExport.h b/ct_core/include/ct/core/common/EigenFileExport.h
new file mode 100644
index 000000000..7d0c9aab2
--- /dev/null
+++ b/ct_core/include/ct/core/common/EigenFileExport.h
@@ -0,0 +1,132 @@
+/**********************************************************************************************************************
+This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
+Licensed under the BSD-2 license (see LICENSE file in main directory)
+**********************************************************************************************************************/
+
+#include
+#include
+#include
+
+#include
+
+namespace ct::core {
+
+//
+// @brief Save Eigen-types or vectors of Eigen-types to text file.
+// Currently ordinary Eigen matrices and quaternion types are supported.
+//
+// Usage examples:
+// // writing an eigen matrix
+// Eigen::Matrix3d m = Eigen::Matrix3d::Random();
+// EigenFileExport::mat_to_file(EigenFileExport::OctaveFormat(), "/tmp/eigen_mat.csv", m, "test mat");
+//
+// // writing a vector of eigen matrices
+// std::vector> m_vec(3, Eigen::Matrix3d::Random());
+// EigenFileExport::mat_to_file(EigenFileExport::OctaveFormat(), "/tmp/eigen_mat_vec.csv", m_vec, "some title.");
+//
+// // writing a quaternion
+// Eigen::Quaterniond q(Eigen::Quaterniond::Identity());
+// EigenFileExport::quat_to_file(EigenFileExport::OctaveFormat(), "/tmp/quat.csv", q, "test quat");
+//
+// // writing a vector of quaternions
+// std::vector> q_vec(
+// 5, Eigen::Quaterniond::Identity());
+// EigenFileExport::quat_to_file(EigenFileExport::OctaveFormat(), "/tmp/quat_vec.csv", q_vec);
+//
+class EigenFileExport
+{
+public:
+ // Create CSV formatting option, precision can be custimized if desired.
+ static const Eigen::IOFormat CSVFormat(int precision = Eigen::StreamPrecision)
+ {
+ return Eigen::IOFormat(precision, Eigen::DontAlignCols, ", ", "\n");
+ }
+ // Create Octave formatting option, precision can be custimized if desired.
+ static const Eigen::IOFormat OctaveFormat(int precision = Eigen::StreamPrecision)
+ {
+ return Eigen::IOFormat(precision, 0, ", ", ";\n", "", "", "[", "]");
+ }
+ // Create comma init formatting option, precision can be custimized if desired.
+ static const Eigen::IOFormat CommaInitFormat(int precision = Eigen::StreamPrecision)
+ {
+ return Eigen::IOFormat(precision, Eigen::DontAlignCols, ", ", ", ", "", "", " << ", ";");
+ }
+ // Create a clean formatting option, precision can be custimized if desired.
+ static const Eigen::IOFormat CleanFormat(int precision = Eigen::StreamPrecision)
+ {
+ return Eigen::IOFormat(precision, 0, ", ", "\n", "[", "]");
+ }
+ // create default full-info formatting option, precision can be custimized if desired.
+ static const Eigen::IOFormat HeavyFormat(int precision = Eigen::FullPrecision)
+ {
+ return Eigen::IOFormat(precision, 0, ", ", ";\n", "[", "]", "[", "]");
+ }
+
+ //! Save a single matrix to single text file.
+ template
+ static void mat_to_file(const Eigen::IOFormat fmt,
+ const std::string& filename,
+ const Eigen::MatrixBase& m,
+ const std::string& heading = "")
+ {
+ std::ofstream file(filename.c_str());
+ if (!heading.empty())
+ file << heading << "\n";
+ file << m.format(fmt);
+
+ file.close();
+ }
+
+ //! Save a single quaternion to a single text file.
+ template
+ static void quat_to_file(const Eigen::IOFormat fmt,
+ const std::string& filename,
+ const Eigen::QuaternionBase& q,
+ const std::string& heading = "")
+ {
+ std::ofstream file(filename.c_str());
+ if (!heading.empty())
+ file << heading << "\n";
+ file << q.coeffs().transpose().format(fmt);
+
+ file.close();
+ }
+
+ // Save a vector of matrices to a single text file.
+ template >
+ static void mat_to_file(const Eigen::IOFormat fmt,
+ const std::string& filename,
+ const std::vector& m_vec,
+ const std::string& heading = "")
+ {
+ std::ofstream file(filename.c_str());
+
+ if (!heading.empty())
+ file << heading << "\n";
+
+ for (size_t i = 0; i < m_vec.size(); i++)
+ file << m_vec[i].format(fmt) << "\n";
+
+ file.close();
+ }
+
+ // Save a vector of quaternions to a single text file.
+ template >>
+ static void quat_to_file(const Eigen::IOFormat fmt,
+ const std::string& filename,
+ const std::vector, Alloc>& q_vec,
+ const std::string& heading = "")
+ {
+ std::ofstream file(filename.c_str());
+
+ if (!heading.empty())
+ file << heading << "\n";
+
+ for (size_t i = 0; i < q_vec.size(); i++)
+ file << q_vec[i].coeffs().transpose().format(fmt) << "\n";
+
+ file.close();
+ }
+};
+
+} // namespace ct::core
diff --git a/ct_core/include/ct/core/common/EigenIsNan.h b/ct_core/include/ct/core/common/EigenIsNan.h
new file mode 100644
index 000000000..811a28c7d
--- /dev/null
+++ b/ct_core/include/ct/core/common/EigenIsNan.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include
+#include
+
+namespace ct {
+namespace core {
+
+/*
+ * \brief returns true if an eigen-type is nan
+ */
+template
+inline bool eigen_is_nan(const Eigen::MatrixBase& x)
+{
+ return ((x.array() != x.array())).all();
+}
+
+} // namespace core
+} // namespace ct
\ No newline at end of file
diff --git a/ct_core/include/ct/core/common/Interpolation.h b/ct_core/include/ct/core/common/Interpolation.h
index 98dd00026..4b887be64 100644
--- a/ct_core/include/ct/core/common/Interpolation.h
+++ b/ct_core/include/ct/core/common/Interpolation.h
@@ -44,18 +44,15 @@ class Interpolation
//! Copy Constructor
Interpolation(const Interpolation& arg) : index_(arg.index_), type_(arg.type_) {}
//! This method performs the interpolation
- /*!
- * @param timeArray timing information of the data points
- * @param dataArray the data points in form of a DiscreteArray
- * @param enquiryTime the time where to evaluate the interpolation
- * @param enquiryData the result of the interpolation
- * @param greatestLessTimeStampIndex the smallest index corresponding to a time smaller than the inquired Time
- */
+
+
+ template
void interpolate(const tpl::TimeArray& timeArray,
const DiscreteArray_t& dataArray,
const SCALAR& enquiryTime,
Data_T& enquiryData,
- int greatestLessTimeStampIndex = -1)
+ LAMBDA&& interp_functional,
+ const int greatestLessTimeStampIndex = -1)
{
if (timeArray.size() == 0)
throw std::runtime_error("Interpolation.h : TimeArray is size 0.");
@@ -78,11 +75,13 @@ class Interpolation
int ind;
if (greatestLessTimeStampIndex == -1)
- ind = findIndex(timeArray, enquiryTime);
+ {
+ ind = this->findIndex(timeArray, enquiryTime);
+ }
else
{
- ind = greatestLessTimeStampIndex;
- index_ = greatestLessTimeStampIndex;
+ this->index_ = greatestLessTimeStampIndex;
+ ind = this->findIndex(timeArray, enquiryTime);
}
if (enquiryTime < timeArray.front())
@@ -99,11 +98,29 @@ class Interpolation
SCALAR alpha = (enquiryTime - timeArray.at(ind + 1)) / (timeArray.at(ind) - timeArray.at(ind + 1));
+ // perform the actual evaluation of the interpolation
+ enquiryData = std::forward(interp_functional)(dataArray.at(ind), dataArray.at(ind + 1), alpha);
+ }
+
- if (type_ == InterpolationType::LIN)
- enquiryData = alpha * dataArray.at(ind) + (1 - alpha) * dataArray.at(ind + 1);
- else if (type_ == InterpolationType::ZOH)
- enquiryData = dataArray.at(ind);
+ void interpolate(const tpl::TimeArray& timeArray,
+ const DiscreteArray_t& dataArray,
+ const SCALAR& enquiryTime,
+ Data_T& enquiryData,
+ const int greatestLessTimeStampIndex = -1)
+ {
+ // define elementary lambda routines for interpolation between two data points
+ // ZOH-interpolation
+ auto interpolate_ZOH = [](const auto& p0, const auto& p1, const auto& alpha) { return p0; };
+ // LIN-interpolation
+ auto interpolate_LIN = [](const auto& p0, const auto& p1, const auto& alpha) {
+ return p1 + alpha * (p0 - p1); // manif-compatible notation
+ };
+
+ if (this->type_ == InterpolationType::LIN)
+ interpolate(timeArray, dataArray, enquiryTime, enquiryData, interpolate_LIN, greatestLessTimeStampIndex);
+ else if (this->type_ == InterpolationType::ZOH)
+ interpolate(timeArray, dataArray, enquiryTime, enquiryData, interpolate_ZOH, greatestLessTimeStampIndex);
else
throw std::runtime_error("Unknown Interpolation type!");
}
@@ -163,5 +180,5 @@ class Interpolation
};
-} // namespace ct
} // namespace core
+} // namespace ct
diff --git a/ct_core/include/ct/core/common/linspace.h b/ct_core/include/ct/core/common/linspace.h
index b8271c9dd..6715bb771 100644
--- a/ct_core/include/ct/core/common/linspace.h
+++ b/ct_core/include/ct/core/common/linspace.h
@@ -5,35 +5,36 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
+#include
+#include
+
namespace ct {
namespace core {
//! replicates the well-known linspace command from MATLAB in C++
/*!
- * linspace provides exactly the same properties and functionality like in MATLAB.
- *
- * - N denotes the number of points, so you will obtain N-1 intervals
- * - a is the start of the interval
- * - b is the end of the interval
- *
- * Unit test \ref LinspaceTest.cpp illustrates the use of linspace.
- *
- * */
-template
-TRAJECTORY_T linspace(const typename TRAJECTORY_T::value_type& a,
- const typename TRAJECTORY_T::value_type& b,
- const size_t N)
+ * linspace provides exactly the same properties and functionality like in MATLAB.
+ *
+ * - N denotes the number of points, so you will obtain N-1 intervals
+ * - a is the start of the interval
+ * - b is the end of the interval
+ *
+ * Unit test \ref LinspaceTest.cpp illustrates the use of linspace.
+ *
+ */
+template
+ARRAY_T linspace(const typename ARRAY_T::value_type& a, const typename ARRAY_T::value_type& b, const size_t N)
{
if (N < 1)
throw std::runtime_error("ERROR in CT_LINSPACE: N<1.");
- typename TRAJECTORY_T::value_type h = (b - a) / (N - 1);
- TRAJECTORY_T traj(N);
+ auto h = (b - a) / (N - 1);
+ ARRAY_T traj(N);
- typename TRAJECTORY_T::iterator it;
- typename TRAJECTORY_T::value_type val;
+ typename ARRAY_T::iterator it;
+ typename ARRAY_T::value_type val;
- for (it = traj.begin(), val = a; it != traj.end(); ++it, val += h)
+ for (it = traj.begin(), val = a; it != traj.end(); ++it, val = val + h)
*it = val;
return traj;
diff --git a/ct_core/include/ct/core/control/ConstantController-impl.h b/ct_core/include/ct/core/control/ConstantController-impl.h
new file mode 100644
index 000000000..fcee49843
--- /dev/null
+++ b/ct_core/include/ct/core/control/ConstantController-impl.h
@@ -0,0 +1,61 @@
+/**********************************************************************************************************************
+This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
+Licensed under the BSD-2 license (see LICENSE file in main directory)
+**********************************************************************************************************************/
+
+#pragma once
+
+namespace ct {
+namespace core {
+
+template
+ConstantController::ConstantController()
+{
+ u_.setZero();
+}
+
+template
+ConstantController::ConstantController(control_vector_t& u) : Base(), u_(u)
+{
+}
+
+template
+ConstantController::ConstantController(const ConstantController& other)
+ : Base(other), u_(other.u_)
+{
+}
+
+template
+ConstantController* ConstantController::clone() const
+{
+ return new ConstantController(*this);
+}
+
+template
+void ConstantController::computeControl(const MANIFOLD& state,
+ const Time_t& tn,
+ control_vector_t& u)
+{
+ u = u_;
+}
+
+template
+void ConstantController::setControl(const control_vector_t& u)
+{
+ u_ = u;
+}
+
+template
+auto ConstantController::getControl() const -> const control_vector_t&
+{
+ return u_;
+}
+
+template
+auto ConstantController::getDerivativeU0(const MANIFOLD& state,
+ const Time_t tn) -> ControlMatrix
+{
+ return ControlMatrix::Identity();
+}
+} // namespace core
+} // namespace ct
diff --git a/ct_core/include/ct/core/control/continuous_time/ConstantController.h b/ct_core/include/ct/core/control/ConstantController.h
similarity index 62%
rename from ct_core/include/ct/core/control/continuous_time/ConstantController.h
rename to ct_core/include/ct/core/control/ConstantController.h
index 01c4ecace..e322663dd 100644
--- a/ct_core/include/ct/core/control/continuous_time/ConstantController.h
+++ b/ct_core/include/ct/core/control/ConstantController.h
@@ -16,13 +16,17 @@ namespace core {
* This class is useful to integrate a ControlledSystem forward subject to a
* constant control input.
*/
-template
-class ConstantController : public Controller,
- public DiscreteController
+template
+class ConstantController final : public Controller
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+ using SCALAR = typename MANIFOLD::Scalar;
+ using Base = Controller;
+ using Time_t = typename Base::Time_t;
+ using control_vector_t = typename Base::control_vector_t;
+
//! Default constructor
/*!
* Sets the control signal to zero
@@ -34,20 +38,20 @@ class ConstantController : public Controller,
* Initializes the control to a fixed value
* @param u The fixed control signal
*/
- ConstantController(ControlVector& u);
+ ConstantController(control_vector_t& u);
//! Copy constructor
- ConstantController(const ConstantController& other);
+ ConstantController(const ConstantController& other);
//! Destructor
- virtual ~ConstantController();
+ virtual ~ConstantController() = default;
//! Clone operator
/*!
* Clones the controller. Used for cloning ControlledSystem's
* @return pointer to cloned controller
*/
- ConstantController* clone() const override;
+ ConstantController* clone() const override;
//! Computes current control
/*!
@@ -57,34 +61,26 @@ class ConstantController : public Controller,
* @param t The time of the system (ignored)
* @param controlAction The (fixed) control action
*/
- void computeControl(const StateVector& state,
- const SCALAR& t,
- ControlVector& controlAction) override;
-
- //! Equivalent method for discrete version
- void computeControl(const StateVector& state,
- const int n,
- ControlVector& controlAction) override;
+ void computeControl(const MANIFOLD& state, const Time_t& tn, control_vector_t& controlAction) override;
//! Sets the control signal
/*!
*
* @param u The fixed control signal
*/
- void setControl(const ControlVector& u);
+ void setControl(const control_vector_t& u);
//! Get the fixed control signal
/*!
*
* @param u The control input to write the signal to.
*/
- const ControlVector& getControl() const;
+ const control_vector_t& getControl() const;
- virtual ControlMatrix getDerivativeU0(const StateVector& state,
- const SCALAR time) override;
+ virtual ControlMatrix getDerivativeU0(const MANIFOLD& state, const Time_t tn) override;
private:
- ControlVector u_;
+ control_vector_t u_;
};
} // namespace core
} // namespace ct
diff --git a/ct_core/include/ct/core/control/continuous_time/Controller.h b/ct_core/include/ct/core/control/Controller.h
similarity index 77%
rename from ct_core/include/ct/core/control/continuous_time/Controller.h
rename to ct_core/include/ct/core/control/Controller.h
index 633916c0b..a8e0e3490 100644
--- a/ct_core/include/ct/core/control/continuous_time/Controller.h
+++ b/ct_core/include/ct/core/control/Controller.h
@@ -7,12 +7,9 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#include
-#include
-#include
#include
#include
-
namespace ct {
namespace core {
@@ -22,20 +19,25 @@ namespace core {
* ControlledSystem. Any custom controller should derive from this class
* to ensure it is compatible with ControlledSystem and the Integrator.
*/
-template
+template
class Controller
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
- //! Default constructor
- Controller(){};
+
+ using SCALAR = typename MANIFOLD::Scalar;
+ using control_vector_t = ControlVector;
+ using control_matrix_t = ControlMatrix;
+
+ // determin Time_t to be either scalar or int
+ using Time_t = typename std::conditional_t;
+
+ Controller() = default;
+ virtual ~Controller() = default;
//! Copy constructor
Controller(const Controller& other){};
- //! Destructor
- virtual ~Controller(){};
-
//! Deep cloning
/*!
* Has to be implemented by any custom controller.
@@ -53,9 +55,7 @@ class Controller
* @param t current time of the system
* @param controlAction the corresponding control action
*/
- virtual void computeControl(const StateVector& state,
- const SCALAR& t,
- ControlVector& controlAction) = 0;
+ virtual void computeControl(const MANIFOLD& state, const Time_t& t, control_vector_t& u) = 0;
/**
* @brief Returns the the derivative of the control with respect to the
@@ -66,8 +66,7 @@ class Controller
*
* @return The derivatives with respect to u0.
*/
- virtual ControlMatrix getDerivativeU0(const StateVector& state,
- const SCALAR time)
+ virtual control_matrix_t getDerivativeU0(const MANIFOLD& state, const Time_t time)
{
throw std::runtime_error("getDerivativeU0() not implemented for the current controller");
}
@@ -81,8 +80,7 @@ class Controller
*
* @return The derivatives with respect to uF.
*/
- virtual ControlMatrix getDerivativeUf(const StateVector& state,
- const SCALAR time)
+ virtual control_matrix_t getDerivativeUf(const MANIFOLD& state, const Time_t time)
{
throw std::runtime_error("getDerivativeUf() not implemented for the current controller");
}
diff --git a/ct_core/include/ct/core/control/StateFeedbackController-impl.h b/ct_core/include/ct/core/control/StateFeedbackController-impl.h
index ef6930f59..fcb6e61ee 100644
--- a/ct_core/include/ct/core/control/StateFeedbackController-impl.h
+++ b/ct_core/include/ct/core/control/StateFeedbackController-impl.h
@@ -6,43 +6,49 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
namespace ct {
namespace core {
-template
-StateFeedbackController::StateFeedbackController(
- const StateFeedbackController& other)
- : ContinuousBase(), DiscreteBase(), x_ref_(other.x_ref_), uff_(other.uff_), K_(other.K_)
+template
+StateFeedbackController::StateFeedbackController() : Base()
{
}
-template
-StateFeedbackController::StateFeedbackController(
- const StateVectorArray& x_ref,
- const ControlVectorArray& uff,
- const FeedbackArray& K,
- const SCALAR deltaT,
- const SCALAR t0,
- const InterpolationType& intType)
- : x_ref_(x_ref, deltaT, t0, intType), uff_(uff, deltaT, t0, intType), K_(K, deltaT, t0, intType)
+template
+StateFeedbackController::~StateFeedbackController()
+{
+}
+
+template
+StateFeedbackController::StateFeedbackController(const MANIFOLD& x_ref,
+ const ct::core::ControlVector& uff,
+ const ct::core::FeedbackMatrix& K)
+ : StateFeedbackController(ct::core::DiscreteArray(1, x_ref),
+ control_vector_array_t(1, uff),
+ FeedbackArray(1, K),
+ 1.0,
+ 0,
+ ZOH)
{
}
-template
-void StateFeedbackController::computeControl(const state_vector_t& state,
- const SCALAR& t,
- control_vector_t& controlAction)
+template
+StateFeedbackController::StateFeedbackController(
+ const StateFeedbackController& other)
+ : Base(), x_ref_(other.x_ref_), uff_(other.uff_), K_(other.K_)
{
- controlAction = uff_.eval(t) + K_.eval(t) * (state - x_ref_.eval(t));
}
-template
-void StateFeedbackController::computeControl(const state_vector_t& state,
- const int n,
- control_vector_t& controlAction)
+template
+StateFeedbackController::StateFeedbackController(const DiscreteArray& x_ref,
+ const ControlVectorArray& uff,
+ const FeedbackArray& K,
+ const SCALAR deltaT,
+ const SCALAR t0,
+ const InterpolationType& intType)
+ : x_ref_(x_ref, deltaT, t0, intType), uff_(uff, deltaT, t0, intType), K_(K, deltaT, t0, intType)
{
- controlAction = uff_[n] + K_[n] * (state - x_ref_[n]);
}
-template
-void StateFeedbackController::update(const DiscreteArray& x_ref,
+template
+void StateFeedbackController::update(const DiscreteArray& x_ref,
const DiscreteArray& uff,
const DiscreteArray>& K,
const tpl::TimeArray& t)
@@ -63,87 +69,91 @@ void StateFeedbackController::update(const Discr
K_.setTime(tshort);
}
-
-template
-StateFeedbackController*
-StateFeedbackController::clone() const
+template
+void StateFeedbackController::computeControl(const MANIFOLD& state,
+ const Time_t& tn,
+ control_vector_t& u)
{
- return new StateFeedbackController(*this);
+ computeControl_specialized(state, tn, u);
}
+template
+StateFeedbackController* StateFeedbackController::clone()
+ const
+{
+ return new StateFeedbackController(*this);
+}
-template
-const DiscreteArray::state_vector_t>&
-StateFeedbackController::x_ref() const
+template
+const DiscreteArray& StateFeedbackController::x_ref() const
{
return x_ref_.getDataArray();
}
-template
-const DiscreteArray::control_vector_t>&
-StateFeedbackController::uff() const
+template
+const DiscreteArray::control_vector_t>&
+StateFeedbackController::uff() const
{
return uff_.getDataArray();
}
-template
-const DiscreteArray>&
-StateFeedbackController::K() const
+template
+auto StateFeedbackController::K() const
+ -> const DiscreteArray>&
{
return K_.getDataArray();
}
-template
-const tpl::TimeArray& StateFeedbackController::time() const
+template
+auto StateFeedbackController::time() const -> const tpl::TimeArray&
{
return x_ref_.getTimeArray();
}
-template
-StateTrajectory&
-StateFeedbackController::getReferenceStateTrajectory()
+template
+DiscreteTrajectory& StateFeedbackController::getReferenceStateTrajectory()
{
return x_ref_;
}
-template
-const StateTrajectory&
-StateFeedbackController::getReferenceStateTrajectory() const
+template
+auto StateFeedbackController::getReferenceStateTrajectory() const
+ -> const DiscreteTrajectory&
{
return x_ref_;
}
-template
-ControlTrajectory&
-StateFeedbackController::getFeedforwardTrajectory()
+template
+auto StateFeedbackController::getFeedforwardTrajectory()
+ -> ControlTrajectory&
{
return uff_;
}
-template
-const ControlTrajectory&
-StateFeedbackController::getFeedforwardTrajectory() const
+template
+auto StateFeedbackController::getFeedforwardTrajectory() const
+ -> const ControlTrajectory&
{
return uff_;
}
-template
-FeedbackTrajectory&
-StateFeedbackController::getFeedbackTrajectory()
+template
+auto StateFeedbackController::getFeedbackTrajectory()
+ -> FeedbackTrajectory&
{
return K_;
}
-template
-const FeedbackTrajectory&
-StateFeedbackController::getFeedbackTrajectory() const
+template
+auto StateFeedbackController::getFeedbackTrajectory() const
+ -> const FeedbackTrajectory&
{
return K_;
}
-template
-void StateFeedbackController::extractControlTrajectory(
- const StateTrajectory& x_traj,
+template
+void StateFeedbackController::extractControlTrajectory(
+ const DiscreteTrajectory& x_traj,
ControlTrajectory& u_traj)
{
u_traj.clear();
diff --git a/ct_core/include/ct/core/control/StateFeedbackController.h b/ct_core/include/ct/core/control/StateFeedbackController.h
index d04ce7bf8..3478e3148 100644
--- a/ct_core/include/ct/core/control/StateFeedbackController.h
+++ b/ct_core/include/ct/core/control/StateFeedbackController.h
@@ -5,6 +5,9 @@ Licensed under the BSD-2 license (see LICENSE file in main directory)
#pragma once
+#include "Controller.h"
+#include
+
namespace ct {
namespace core {
@@ -35,27 +38,25 @@ namespace core {
* @tparam CONTROL_DIM control vector size
* @tparam SCALAR primitive type
*/
-template
-class StateFeedbackController : public Controller,
- public DiscreteController
+template
+class StateFeedbackController : public Controller
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
- typedef Controller ContinuousBase;
- typedef DiscreteController DiscreteBase;
+ static constexpr size_t STATE_DIM = MANIFOLD::TangentDim;
+ using SCALAR = typename MANIFOLD::Scalar;
- typedef typename DiscreteBase::state_vector_t state_vector_t;
- typedef typename DiscreteBase::control_vector_t control_vector_t;
+ typedef Controller Base;
+ typedef typename Base::control_vector_t control_vector_t;
+ using Time_t = typename Base::Time_t;
- typedef StateVectorArray state_vector_array_t;
typedef ControlVectorArray control_vector_array_t;
typedef FeedbackArray feedback_array_t;
- //! default constructor
- StateFeedbackController() : ContinuousBase(), DiscreteBase() {}
+ StateFeedbackController();
//! copy constructor
- StateFeedbackController(const StateFeedbackController& other);
+ StateFeedbackController(const StateFeedbackController& other);
//! constructor
/*!
@@ -70,18 +71,38 @@ class StateFeedbackController : public Controller& x_ref,
const control_vector_array_t& uff,
const feedback_array_t& K,
const SCALAR deltaT,
const SCALAR t0 = 0.0,
const InterpolationType& intType = ZOH);
+ StateFeedbackController(const MANIFOLD& x_ref,
+ const ct::core::ControlVector& uff,
+ const ct::core::FeedbackMatrix& K);
+
//! destructor
- virtual ~StateFeedbackController(){};
+ virtual ~StateFeedbackController();
//! deep cloning
- StateFeedbackController* clone() const override;
+ StateFeedbackController* clone() const override;
+
+ template