diff --git a/.github/actions/build-test-python/entrypoint.sh b/.github/actions/build-test-python/entrypoint.sh index 7933628ec..b1737f537 100755 --- a/.github/actions/build-test-python/entrypoint.sh +++ b/.github/actions/build-test-python/entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/sh -l echo ">>> Installing control libraries..." -bash /github/workspace/source/install.sh --auto --no-controllers --no-dynamical-systems --no-robot-model || exit 1 +bash /github/workspace/source/install.sh --auto --no-controllers --no-robot-model || exit 1 bash /github/workspace/protocol/install.sh --auto || exit 1 echo ">>> Building Python bindings..." diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index ae0602e8f..96cdb983f 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -25,7 +25,7 @@ jobs: if: ${{ github.event_name == 'release' }} shell: bash run: | - TAG="${GITHUB_REF#refs-tags/}" + TAG="${GITHUB_REF#refs/tags/}" TAG="${TAG/\//-}" mkdir -p doxygen/docs/versions sudo mv doxygen/docs/html doxygen/docs/versions/${TAG} diff --git a/CHANGELOG.md b/CHANGELOG.md index 559652986..e16f5936c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG Release Versions: +- [5.0.0](#500) - [4.1.0](#410) - [4.0.0](#400) - [3.1.0](#310) @@ -8,6 +9,119 @@ Release Versions: - [2.0.0](#200) - [1.0.0](#100) +## 5.0.0 + +Version 5.0.0 refactors the dynamical systems and controllers libraries with a +factory pattern and parameter interface for easier creation, manipulation and +substitution of these classes. This major change breaks any implementations using +dynamical systems or controllers from the prior version. + +See the updated documentation for usage guidelines for the new DynamicalSystemsFactory +and ControllerFactory. + +This release also includes substantial improvements to the python bindings, including +class bindings for the dynamical systems library. Additional fixes and improvements +have been made throughout the framework. + +### Breaking changes + +This release contains the following breaking changes: +- Relocate `Jacobian` and `JointState` family headers +- Refactor dynamical system classes to use `IDynamicalSystem` base interface +- Refactor controller classes to use `IController` base interface + +**state_representation** + +To make joint-space files more structurally consistent with Cartesian-space files, +the following headers have been relocated. +- `state_representation/robot/Joint*.hpp` headers are now in `state_representation/space/joint/Joint*.hpp` +- `state_representation/robot/Jacobian.hpp` header is now in `state_representation/space/Jacobian.hpp` + +Any C++ implementations that include the files from a prior version should update the file paths +in the `#include` directives. The namespaces themselves in C++ and Python are unaffected. + +**dynamical_systems** + +The previous DS classes inheriting from the concrete `DynamicalSystem` base class have been +refactored and partially renamed to inherit from the new abstract `IDynamicalSystem` base class. + +- `dynamical_systems::Blending` has been removed +- `dynamical_systems::Circular` has been refactored +- `dynamical_systems::DynamicalSystem` has been refactored and renamed to `dynamical_systems::IDynamicalSystem` +- `dynamical_systems::Linear` has been refactored and renamed to `dynamical_systems::PointAttractor` +- `dynamical_systems::Ring` has been refactored +- `dynamical_systems::DefaultDynamicalSystem` has been introduced + +It is no longer recommended to directly instantiate and use these classes. The new factory method +`dynamical_systems::DynamicalSystemFactory::create_dynamical_system(type)` should be used instead. +See the documentation for more information. + +**controllers** + +The previous controller classes inheriting from the concrete `Controller` base class have been +refactored and partially renamed to inherit from the new abstract `IController` base class. + +- `controllers::Controller` has been refactored and renamed to `controllers::Controller` +- `controllers::CartesianTwistController` has been refactored and renamed to `controllers::CompliantTwist` +- `controllers::Dissipative` has been refactored +- `controllers::Impedance` has been refactored +- `controllers::VelocityImpedance` has been refactored + +It is no longer recommended to directly instantiate and use these classes. The new factory method +`controllers::ControllerFactory::create_controller(type)` should be used instead. +See the documentation for more information. + +### Features + +**state_representation** +- Add CartesianAcceleration class in state representation (#248) + +**dynamical_systems** +- Create DS interface and DS factory classes (#227) +- Refactor Linear DS to PointAttractor DS with factory (#229) +- Refactor Circular DS with factory (#230) +- Refactor Ring DS with factory and remove old DS base class (#231) +- Refactor dynamical systems using factory pattern (#233) +- Propagate DS refactor to demos (#234) +- Avoid exception with the default DS in evaluate (#237) +- Add the `set_parameter_value` function in the DS base class (#236) +- Remove the `set_base_frame` logic for `JointState` based DS + and override `is_compatible` for PointAttractor DS (#236, #239) +- Return a state that has same name as input in PointAttractor (#241) +- Update README of dynamical systems (#242) + +**controllers** +- Add IController and ControllerFactory and refactor Controllers (#253, #254, #255) + +**python** +- Add python bindings for dynamical_systems module (#238) + +**clproto** +- Update pybindings and clproto with CartesianAcceleration (#250) + +### Fixes and improvements + +**state_representation** +- Add static method to create Parameter pointer (#226) +- Templated get_value method for Parameter (#228) +- Mark the JointState as filled when one index was set (#245) +- Add ParameterMap base class (#247) +- Relocate Jacobian and JointState family files to the 'space/' directory (#249, #251) + +**python** +- Add support for copy module in Python bindings (#232) +- Add empty constructors and python bindings for the + Shape and Ellipsoid classes (#235) + +**general** +- Install Eigen version 3.4 manually (#240) + +### Behind the scenes + +- Fix tag generation for release docs (#225) +- Add user sshd configuration and user 'developer' in base Dockerfile + and update all the Dockerfiles and scripts (#244, #246) + ## 4.1.0 Version 4.1.0 contains a few improvements to the behaviour and usage of the libraries, diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 41728d8b9..4a0295bda 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ Step 2: If not already done, [create a remote toolchain in CLion](https://www.je using the following credentials: - Host: `127.0.0.1` - Port: `2222` (or custom specified port) - - User name: `remote` + - User name: `developer` - Authentication type: `Key pair` Step 3: If not already done, [create a CMake profile that uses the remote toolchain](https://www.jetbrains.com/help/clion/remote-projects-support.html#CMakeProfile). diff --git a/Dockerfile.base b/Dockerfile.base index fc19201a2..666971714 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 AS core-build-dependencies +FROM ubuntu:20.04 as core-build-dependencies ENV DEBIAN_FRONTEND=noninteractive # install core compilation and access dependencies for building the libraries @@ -28,9 +28,12 @@ RUN echo "deb [arch=amd64] http://robotpkg.openrobots.org/packages/debian/pub $( && curl http://robotpkg.openrobots.org/packages/debian/robotpkg.key \ | apt-key add - +RUN wget -c https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz -O - | tar -xz +RUN cd eigen-3.4.0 && mkdir build && cd build && cmake .. && make install +RUN rm -r eigen-3.4.0 + # install dependencies for building the libraries RUN apt-get update && apt-get install -y \ - libeigen3-dev \ robotpkg-pinocchio \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -66,19 +69,56 @@ WORKDIR /home RUN rm -rf /tmp/* -FROM project-dependencies as development-dependencies +FROM project-dependencies as ssh-configuration RUN apt-get update && apt-get install -y \ - clang \ + sudo \ + libssl-dev \ + ssh \ iputils-ping \ + rsync \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Configure sshd server settings +RUN ( \ + echo 'LogLevel DEBUG2'; \ + echo 'PubkeyAuthentication yes'; \ + echo 'Subsystem sftp /usr/lib/openssh/sftp-server'; \ + ) > /etc/ssh/sshd_config_development \ + && mkdir /run/sshd + +ENV USER developer +ENV HOME /home/${USER} + +# create amd configure a new user +ARG UID=1000 +ARG GID=1000 +RUN addgroup --gid ${GID} ${USER} +RUN adduser --gecos "Remote User" --uid ${UID} --gid ${GID} ${USER} && yes | passwd ${USER} +RUN usermod -a -G dialout ${USER} +RUN echo "${USER} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/99_aptget +RUN chmod 0440 /etc/sudoers.d/99_aptget && chown root:root /etc/sudoers.d/99_aptget + +# Configure sshd entrypoint to authorise the new user for ssh access and +# optionally update UID and GID when invoking the container with the entrypoint script +COPY ./docker/sshd_entrypoint.sh /sshd_entrypoint.sh +RUN chmod 744 /sshd_entrypoint.sh + +# create the credentials to be able to pull private repos using ssh +RUN mkdir /root/.ssh/ && ssh-keyscan github.com | tee -a /root/.ssh/known_hosts + +RUN echo "session required pam_limits.so" | tee --append /etc/pam.d/common-session > /dev/null + + +FROM ssh-configuration as development-dependencies + +RUN apt-get update && apt-get install -y \ + clang \ gdb \ - libssl-dev \ python \ python3-dev \ python3-pip \ - rsync \ - ssh \ - sudo \ tar \ unzip \ && apt-get clean \ diff --git a/Dockerfile.proto b/Dockerfile.proto index 3ddcc1997..60aeee26c 100644 --- a/Dockerfile.proto +++ b/Dockerfile.proto @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 AS build-stage +FROM ubuntu:20.04 as build-stage ARG PROTOBUF_VERSION=3.17.0 ENV DEBIAN_FRONTEND=noninteractive @@ -25,7 +25,8 @@ RUN ./autogen.sh \ && make \ && make install -FROM ubuntu:20.04 AS google-dependencies + +FROM ubuntu:20.04 as google-dependencies COPY --from=build-stage /usr/local/include/google /usr/local/include/google COPY --from=build-stage /usr/local/lib/libproto* /usr/local/lib/ COPY --from=build-stage /usr/local/bin/protoc /usr/local/bin diff --git a/demos/control_loop_examples/Dockerfile b/demos/control_loop_examples/Dockerfile index 88e5f380d..d1b556100 100644 --- a/demos/control_loop_examples/Dockerfile +++ b/demos/control_loop_examples/Dockerfile @@ -1,4 +1,4 @@ -FROM control-libraries/source-dependencies as runtime-demonstrations +FROM epfl-lasa/control-libraries/source:install WORKDIR /tmp/ COPY . ./control_loop_examples @@ -7,4 +7,6 @@ WORKDIR /tmp/control_loop_examples/build RUN cmake .. && make -j all && make install WORKDIR /usr/local/bin -RUN rm -rf /tmp/demos/ \ No newline at end of file +RUN rm -rf /tmp/demos/ + +USER developer \ No newline at end of file diff --git a/demos/control_loop_examples/run-demo.sh b/demos/control_loop_examples/run-demo.sh index ce9b65a07..b23ac496f 100755 --- a/demos/control_loop_examples/run-demo.sh +++ b/demos/control_loop_examples/run-demo.sh @@ -1,36 +1,44 @@ #!/usr/bin/env bash -# Build a docker image to compile the library and run tests -MULTISTAGE_TARGET="runtime-demonstrations" -REBUILD=0 -while getopts 'r' opt; do - case $opt in - r) REBUILD=1 ;; - *) echo 'Error in command line parsing' >&2 - exit 1 - esac -done -shift "$(( OPTIND - 1 ))" - -NAME=$(echo "${PWD##*/}" | tr _ -)/$MULTISTAGE_TARGET -TAG="latest" -TARGET_SCRIPT=${1} +IMAGE_NAME=epfl-lasa/control-libraries/control-loop-examples +IMAGE_TAG=latest -BUILD_FLAGS=(--target "${MULTISTAGE_TARGET}") -BUILD_FLAGS+=(-t "${NAME}:${TAG}") +HELP_MESSAGE="Usage: run-demo.sh [-s