diff --git a/Dockerfile b/Dockerfile index de7c4af..3b29d01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ # Use ROS 2 Humble Hawksbill base image -FROM osrf/ros:humble-desktop-full +FROM osrf/ros:humble-desktop-full-jammy # Update and install dependencies RUN apt-get update && apt-get install -y \ - python3-colcon-common-extensions \ + python3-colcon-common-extensions python3-pip \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt ./ @@ -13,7 +13,7 @@ RUN pip install --no-cache-dir -r requirements.txt WORKDIR /ros2_ws # Copy your ROS 2 package into the workspace -COPY ./ros2_ws/src /ros2_ws/src +COPY ./src /ros2_ws/src # Build your package RUN . /opt/ros/humble/setup.sh && \ diff --git a/README.md b/README.md index e69de29..5906c34 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,78 @@ +# Interactive Robot Learning Framework + +Welcome to the Interactive Robot Learning Framework, a modular and extensible system designed for robotics research and development. This framework utilizes Docker and ROS2 to provide a flexible and isolated environment for experimenting with robot learning algorithms, interaction metrics, objective functions, representation models, benchmark environments, and communication messages. + +## Getting Started + +This section will guide you through the process of setting up the Docker container for the framework. [Final startup instructions will be provided by the user.] + +### Prerequisites + +- Docker +- ROS2 Foxy Fitzroy (or your target ROS2 distribution) + +### Installation + +1. Clone the repository: +```bash +git clone [repository-url] +cd [repository-name] +``` +2. Build the Docker container: +```bash +docker build -t interactive-robot-learning-framework . +``` +3. Launch the Docker container using docker-compose: +```bash +docker-compose up -d +``` + +## Framework Structure + +The Interactive Robot Learning Framework consists of several key ROS2 packages, each responsible for different aspects of robot learning and interaction. Below is an overview of each package: + +### Optimizer ROS2 Package + +- **Description**: Contains various optimization algorithms designed to fine-tune robot learning parameters. +- **Key Components**: Gradient descent, genetic algorithms, simulated annealing, etc. + +### InteractionQuery Package + +- **Description**: Implements metrics to quantify and analyze user interactions with the optimizer, facilitating adaptive learning processes. +- **Key Components**: Engagement level, feedback quality, interaction frequency, etc. + +### ObjectiveFunctions Package + +- **Description**: Houses the objective functions used by optimizers to evaluate the performance of robot learning tasks. +- **Key Components**: Loss functions, reward functions, etc. + +### RepresentationModel Package + +- **Description**: Provides models for representing robot trajectories in a manner conducive to learning and optimization. +- **Key Components**: Graphical models, neural networks, geometric representations, etc. + +### Benchmark Package + +- **Description**: Includes various reinforcement learning (RL) benchmark environments for testing and evaluating learning algorithms. +- **Key Components**: Simulated robotics tasks, navigation challenges, manipulation tasks, etc. + +### InteractionMsgs Package + +- **Description**: Contains all necessary ROS2 messages, services, and actions for facilitating communication within the framework. +- **Key Components**: Custom message definitions, service calls for optimizer control, action definitions for task execution, etc. + +## Starting Up + +[This section will be completed by the user, detailing the steps to initialize the framework and begin experiments.] + +## Contributing + +We welcome contributions to the Interactive Robot Learning Framework! Please read our contributing guidelines for more information on how to participate in the development. + +## License + +[Specify the license under which the framework is released, e.g., MIT, GPL, Apache.] + +## Acknowledgments + +[Optional: Acknowledge any contributions, inspirations, or frameworks that assisted in the development of this project.] diff --git a/docker-compose.yaml b/docker-compose.yaml index c750c7c..2789079 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,9 +1,9 @@ version: '3.8' services: ros2: - build: .. + build: . volumes: - - ./ros2_ws/src:/ros2_ws/src + - ./src:/ros2_ws/src networks: - ros_network tty: true diff --git a/requirements.txt b/requirements.txt index 2c04913..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +0,0 @@ -numpy==1.26.4 diff --git a/src/InteractionMetrics/InteractionMetrics/MaxAcquisition.py b/src/InteractionMetrics/InteractionMetrics/MaxAcquisition.py deleted file mode 100644 index 90dbd47..0000000 --- a/src/InteractionMetrics/InteractionMetrics/MaxAcquisition.py +++ /dev/null @@ -1,55 +0,0 @@ -import numpy as np -from scipy.stats import norm - - -class MaxAcqQuery: - def __init__(self, threshold, gp, - nr_test, nr_weights, - lower=-1.0, upper=1.0, - acq="Expected Improvement", - **kwargs): - self.threshold = threshold - self.gp = gp - self.nr_test = nr_test - self.nr_weights = nr_weights - self.lower = lower - self.upper = upper - self.acq = acq - - self.seed = kwargs.get('seed', None) - self.kappa = kwargs.get('kappa', 2.576) - self.beta = kwargs.get('beta', 1.2) - self.X = kwargs.get('X', None) - - self.rng = np.random.default_rng(self.seed) - - def query(self): - X_test = self.rng.uniform(self.lower, self.upper, (self.nr_test, self.nr_weights)) - max_acq = 0 - - if self.acq == "Expected Improvement": - if self.X is None: - raise ValueError - y_hat = self.gp.predict(self.X) - best_y = max(y_hat) - mu, sigma = self.gp.predict(X_test, return_std=True) - z = (mu - best_y - self.kappa) / sigma - ei = (mu - best_y - self.kappa) * norm.cdf(z) + sigma * norm.pdf(z) - max_acq = np.max(ei) - - if self.acq == "Probability of Improvement": - if self.X is None: - raise ValueError - y_hat = self.gp.predict(self.X) - best_y = max(y_hat) - mu, sigma = self.gp.predict(X_test, return_std=True) - z = (mu - best_y - self.kappa) / sigma - pi = norm.cdf(z) - max_acq = np.max(pi) - - if self.acq == "Upper Confidence Bound": - mu, sigma = self.gp.predict(X_test, return_std=True) - cb = mu + self.beta * sigma - max_acq = np.max(cb) - - return max_acq > self.threshold diff --git a/src/InteractionMetrics/InteractionMetrics/__init__.py b/src/InteractionMetrics/InteractionMetrics/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/InteractionMetrics/package.xml b/src/InteractionMetrics/package.xml deleted file mode 100644 index 97c540a..0000000 --- a/src/InteractionMetrics/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - InteractionMetrics - 0.0.0 - TODO: Package description - niko - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/src/InteractionMetrics/resource/InteractionMetrics b/src/InteractionMetrics/resource/InteractionMetrics deleted file mode 100644 index e69de29..0000000 diff --git a/src/InteractionMetrics/setup.cfg b/src/InteractionMetrics/setup.cfg deleted file mode 100644 index b01a7f8..0000000 --- a/src/InteractionMetrics/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script_dir=$base/lib/InteractionMetrics -[install] -install_scripts=$base/lib/InteractionMetrics diff --git a/src/InteractionMetrics/setup.py b/src/InteractionMetrics/setup.py deleted file mode 100644 index 64dcaad..0000000 --- a/src/InteractionMetrics/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import find_packages, setup - -package_name = 'InteractionMetrics' - -setup( - name=package_name, - version='0.0.0', - packages=find_packages(exclude=['test']), - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='niko', - maintainer_email='nikolaus.feith@unileoben.ac.at', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/src/InteractionMetrics/test/test_copyright.py b/src/InteractionMetrics/test/test_copyright.py deleted file mode 100644 index 97a3919..0000000 --- a/src/InteractionMetrics/test/test_copyright.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -# Remove the `skip` decorator once the source file(s) have a copyright header -@pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/src/InteractionMetrics/test/test_flake8.py b/src/InteractionMetrics/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/src/InteractionMetrics/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/src/InteractionMetrics/test/test_pep257.py b/src/InteractionMetrics/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/src/InteractionMetrics/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/src/InteractionMsgs/CMakeLists.txt b/src/InteractionMsgs/CMakeLists.txt deleted file mode 100644 index f905a4d..0000000 --- a/src/InteractionMsgs/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required(VERSION 3.8) -project(InteractionMsgs) - -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic) -endif() - -# find dependencies -find_package(ament_cmake REQUIRED) -# uncomment the following section in order to fill in -# further dependencies manually. -# find_package( REQUIRED) - -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - # the following line skips the linter which checks for copyrights - # comment the line when a copyright and license is added to all source files - set(ament_cmake_copyright_FOUND TRUE) - # the following line skips cpplint (only works in a git repo) - # comment the line when this package is in a git repo and when - # a copyright and license is added to all source files - set(ament_cmake_cpplint_FOUND TRUE) - ament_lint_auto_find_test_dependencies() -endif() - -ament_package() diff --git a/src/InteractionMetrics/InteractionMetrics/Improvement.py b/src/InteractionQuery/InteractionQuery/improvement.py similarity index 100% rename from src/InteractionMetrics/InteractionMetrics/Improvement.py rename to src/InteractionQuery/InteractionQuery/improvement.py diff --git a/src/InteractionQuery/InteractionQuery/query_node.py b/src/InteractionQuery/InteractionQuery/query_node.py new file mode 100644 index 0000000..b18cde9 --- /dev/null +++ b/src/InteractionQuery/InteractionQuery/query_node.py @@ -0,0 +1,4 @@ +import rclpy +from rclpy.node import Node + +from interaction_msgs.srv import Query \ No newline at end of file diff --git a/src/InteractionMetrics/InteractionMetrics/Random.py b/src/InteractionQuery/InteractionQuery/random.py similarity index 98% rename from src/InteractionMetrics/InteractionMetrics/Random.py rename to src/InteractionQuery/InteractionQuery/random.py index e53d125..8f8f8c8 100644 --- a/src/InteractionMetrics/InteractionMetrics/Random.py +++ b/src/InteractionQuery/InteractionQuery/random.py @@ -8,4 +8,3 @@ class RandomQuery: def query(self): return self.random > self.threshold - \ No newline at end of file diff --git a/src/InteractionMetrics/InteractionMetrics/Regular.py b/src/InteractionQuery/InteractionQuery/regular.py similarity index 100% rename from src/InteractionMetrics/InteractionMetrics/Regular.py rename to src/InteractionQuery/InteractionQuery/regular.py diff --git a/src/interaction_msgs/CMakeLists.txt b/src/interaction_msgs/CMakeLists.txt new file mode 100644 index 0000000..84bd50e --- /dev/null +++ b/src/interaction_msgs/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.8) +project(interaction_msgs) + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +find_package(ament_cmake REQUIRED) +find_package(rosidl_default_generators REQUIRED) + +rosidl_generate_interfaces(${PROJECT_NAME} + "srv/Query.srv" + DEPENDENCIES +) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + set(ament_cmake_copyright_FOUND TRUE) + set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/src/InteractionMsgs/package.xml b/src/interaction_msgs/package.xml similarity index 73% rename from src/InteractionMsgs/package.xml rename to src/interaction_msgs/package.xml index dbb8ddc..568d70d 100644 --- a/src/InteractionMsgs/package.xml +++ b/src/interaction_msgs/package.xml @@ -1,7 +1,7 @@ - InteractionMsgs + interaction_msgs 0.0.0 TODO: Package description niko @@ -9,6 +9,11 @@ ament_cmake + + rosidl_default_generators + rosidl_default_runtime + rosidl_interface_packages + ament_lint_auto ament_lint_common diff --git a/src/interaction_msgs/srv/Query.srv b/src/interaction_msgs/srv/Query.srv new file mode 100644 index 0000000..a543115 --- /dev/null +++ b/src/interaction_msgs/srv/Query.srv @@ -0,0 +1,15 @@ +# random query +float32 threshold + +# regular query +uint16 frequency +uint16 current_episode + +# improvement query +# float32 threshold +uint16 period +uint16 last_queried_episode +float32[] rewards + +--- +bool interaction \ No newline at end of file