-
Notifications
You must be signed in to change notification settings - Fork 102
Adding New Tool
New tools added to the OpenDR GitHub repo should provide the following files:
- source code to apply the tool for training and inference
- ROS and ROS2 nodes using the tool for inference
- documentation of the tools including:
- a short description of the method itself. It is not necessary to give all the details, but it is good to link to the related paper or reference if any.
- details description of the API needed by the user to apply the tool to her scenario
- step-by-step description about how to run the example
- ROS/ROS2 documentation entries
- unit tests
- example (preferably using Webots) of how to apply the tool to a scenario
- at least one pretrained model ready for inference
The following instructions will provide paths using the following wildcards:
-
<type>
: tool type, e.g.,control
,perception
,planning
-
<task_name>
: task addressed by the tool, for example "pose_estimation" -
<algorithm_name>
: name of the algorithms used to solve the task, for example, "lightweight_open_pose"
New tools should follow the OpenDR code guidelines and ensure a common interface:
- the public API should extend the
engine.BaseLearner
abstract class - all the perception algorithms should inherit and extent the
engine.Learner
class and implement these methods:- fit()
- eval()
- infer()
- the public API should use the OpenDR data wrappers to provide a homogeneous API
- they should be compatible with the style guidelines
The source code of the tool has to be stored in the /src/<type>/<task_name>/<algorithm_name>
folder.
The expected files are:
-
README.md
: containing a short description of the task and algorithms (1-2 lines), the list of the sources of third-party code (if any), and the modifications to the original code -
<algorithm_name>_learner.py
: main class providing the entry point to the functionality -
algorithm/
: folder containing the algorithm implementation -
dependencies.ini
: list of dependencies needed to run the tool. See Dependencies section for more details about the format.
The files in /src
are tested by the CI (Continuous Integration) system to check the compatibility with the OpenDR guidelines.
Tests on original files taken from third-party that are copied and pasted without modifications can be skipped.
In particular, the OpenDR license test should be skipped because it is now allowed to change license and copyrights of third-party code.
It is possible to skip tests for a folder by adding the path to the skippedDirectoryPaths
variable in the test itself.
Tests are run automatically based on the label set in the pull request. The following options are available:
-
test sources
(mandatory): ensures codestyle guides are met. -
test tools
(mandatory): installs the toolkit from sources and ensures the addition does not introduce conflicts with existing tools. -
test release
(mandatory if a pip wheel is created): generates a pip wheel from the current branch, installs it on a clean system and ensures the test provided in the test suite works accordingly.
If not modified and available on a public GitHub repo, third-party code should be linked (as a "submodule") instead of copied in the OpenDR repository. If not available on a GitHub repo or some modifications are applied:
- commit the algorithms sources in the OpenDR repo
- specify the link to the original code in the tool
README.md
file, the author, and list all the modifications
OpenDR license doesn't have to be applied on third-party code!
OpenDR Apache License version 2.0 is a permissive license: work can be redistributed even for commercial use. So, third-party code integrated into the OpenDR toolkit should also be permissive. Non-commercial licensed code cannot be integrated. Common compatible licenses are:
- MIT
- BSD: 3-clause and 2-clause (but not 4-clause) You can find more details here: http://www.apache.org/legal/resolved.html#category-a
Dependencies will be automatically installed using a script and the Makefile system.
For each tool, a dependencies.ini
file should be created listing all the dependencies required to run the method.
This file should be written using the INI format.
Three different sections are supported:
-
runtime
: includes dependencies required to execute the tool -
compilation
: includes dependencies required to compile the C/C++ code. Python tools requireruntime
dependencies only. -
device
: includes theopendr_device
key
In the runtime
and compilation
section, the following keys can be used:
-
python
: listing the python modules. The value syntax should be the standard pip requirements file format -
python-dependencies
: listing additional python packages that will be installed before thepython
dependencies to resolve prerequisites -
linux
: listing all the system packages required on Linux systems that will be installed using the system package manager -
macOS
: not implemented yet -
windows
: not implemented yet
In the device
section, the following keys can be used:
-
opendr_device
: with valid optionscpu
andgpu
. If the listed dependencies strictly require a GPU, the key has to be set togpu
. Otherwise, i.e., if a CPU suffices, the key should be set tocpu
or can be omitted.
Here is a sample dependencies.ini
file.
[runtime]
python=torch==1.7.1
opencv-python
linux=unzip wget
[compilation]
linux=g++
[device]
opendr_device=cpu
The new tool should be accompanied by a ROS node and a ROS2 node demonstrating its inference capabilities through ROS.
The ROS nodes should be placed in /projects/opendr_ws/src/opendr_<type>/scripts/
and declared in CMakeLists.txt
located in
/projects/opendr_ws/src/opendr_<type>/
, e.g. the CMakeLists.txt
file for the opendr_perception
package. Any additional ROS dependencies should be declared in package.xml
located in
/projects/opendr_ws/src/opendr_<type>/
, e.g. the package.xml
file for the opendr_perception
package.
The new node should be as consistent with already existing nodes as possible. Some important points are:
- Node file name should be consistent with other nodes, i.e.
<task_name>_node.py
, or<task_name>_<algorithm_name>_node.py
if there are multiple nodes per <task_name> with different <algorithm_names>. - Similarly, when initializing the node its name should be
opendr_<task_name>_node
oropendr_<task_name>_<algorithm_name>_node
so it is easily identifiable through ROS. - When initializing the input topic subscriber make sure to set the queue appropriately so the node does not suffer from any delay, see known issues.
- OpenDR ROS nodes use
argparse
so as to have a consistent interface and to streamline their usage. Consequently, the node should have a similar interface to other existing nodes depending on its input/output modality. - In addition to the previous point, it is important that arguments should follow a naming format similar to other ROS nodes,
e.g. image input topics should be similar to
input_rgb_image_topic
orinput_infra_image_topic
. - The node should define some helpful shortcuts in
argparse
, e.g.-i
for the input topic argument. - All OpenDR nodes have default topic names for their most expected usage, so they are plug and play for simple testing.
For example a node that takes RGB images as input, should default to
/usb_cam/image_raw
input topic so it works with the basicusb_cam
package straight away. - The device on which the node will execute (CPU/GPU) should be handled automatically, depending on the argument provided.
- Check whether the new node needs any new bridge methods for its data input/output and make sure it uses OpenDR data formats.
- If the node requires any custom service or message, it can be added in the
opendr_bridge
package, similar to other OpenDR services and messages. Remember to declare the new messages and services in CMakeLists.txt.
The ROS2 nodes should be placed in /projects/opendr_ws_2/src/opendr_<type>/opendr_<type>/
and declared in
setup.py
located in /projects/opendr_ws_2/src/opendr_<type>/
, e.g. the setup.py
file for the opendr_perception
package. Any additional ROS2 dependencies should be declared in package.xml
located in
/projects/opendr_ws_2/src/opendr_<type>/
, e.g. the package.xml
file for the opendr_perception
package.
The ROS2 node should follow the same guidelines as the ROS node source code above with the following differences:
- The node initialization and setting of the queue from points 2 and 3 from above are done in slightly different ways as can be seen here and here, but the same rules apply.
- The default input topic name of
usb_cam
from point 7 is/image_raw
for the ROS2 package. - The
opendr_bridge
package of ROS2 for point 9 from above can be found here. - ROS2 requires a C++ package to define services and messages, so any custom services and messages needed are defined in the
opendr_interface
package instead ofopendr_bridge
in ROS, here and here respectively. Remember to declare the new messages and services in CMakeLists.txt.
All the documentation needed by the user should be added in the /docs/reference
folder, i.e. in the Reference Manual of the OpenDR toolkit.
A single file named after the method should be added and should contain these informations:
- Description of the method
- Specifications of the API
- Instructions to run the example
- ROS/ROS2 node documentation
Adding documentation directly in the code is recommended to make the code more readable and understandable. But this is not considered part of the OpenDR API documentation needed to use the toolkit.
When adding a new documentation file, please also make sure to add it to the documentation index: https://github.com/opendr-eu/opendr/blob/master/docs/reference/index.md
This includes a description of the method: what is the purpose of the method, which are the techniques used, an overview of the performance, etc. This is not intended to be a detailed description of how the method is implemented or all the research behind it, but it should give enough information to the user to understand if this method could be applied to his scenario. It is good to link to the related paper or similar so that interested users can look into the details.
All the public methods of the tool have to be listed and described. This includes the description of the function arguments, returned values, and functionality.
The last section of the documentation page should include the step-by-step instructions to run the provided example. A short description of the example and the expected result should able be included.
If the nodes are perception nodes, new entries should be added in the ROS README index and ROS2 README index, that link to the corresponding entries on the main ROS README and main ROS2 README respectively.
If any new bridge methods are added in the opendr_bridge
packages, they should be documented in
ROS opendr_bridge
doc
and ROS2 opendr_bridge
doc respectively.
Unit tests are run by the CI system regularly (e.g., every night) or upon request from a GitHub Pull Request.
For each tool, we should provide some tests to check the main tool functionalities and check for regression issues.
The test file should be added at /test/sources/tools/<type>/<task_name>/<algorithm_name>
.
For Python implementation, the Python unittest
framework is used.
If you add a new folder for testing your tool, then make sure that it is included in the test package list at: https://github.com/opendr-eu/opendr/blob/master/.github/workflows/tests_suite.yml A total of four entries should be added in the following jobs:
-
test-tools
: always -
test-wheel
: only if a pip wheel should be created for the added tool, in which case it should also be added to./packages.txt
. -
test-wheel-separate
: only if a pip wheel should be created for the added tool, in which case it should also be added to./packages.txt
. -
test-docker
: always
If the test needed specific dependencies besides the tool dependencies, they should be added in /tests/sources/requirements.txt
.
This file uses the standard pip requirements file format.
The example files have to be added to a dedicated folder in the /projects
folder.
For example: /projects/<type>/<task_name>/algorithm_name
The example should be as simple as possible but still providing a meaningful application where the tool's potentialities are demonstrated.
It should preferably be a Webots project.
Keeping in mind that OpenDR is a set of many different tools it is important to carefully choose the dependencies and try when possible and meaningful to reuse dependencies already included instead of adding new ones.
New dependencies needed to run this specific example and that are not generically needed to run the tool, should be listed in the /projects/<type>/<task_name>/<algorithm_name>/dependencies.ini
file.
More information about listing dependencies is specified in the Dependencies section.
The example should be designed in such a way that it is as simple and fast to execute as possible but still providing a meaningful application example.
Please check all these points before contributing a tool:
- The main functionality is provided in a Learner-based class.
- infer(), train() and eval() work correctly with OpenDR data types (e.g., Dataset, Image, Target, etc.).
- save() and load() functions are provided.
- Any binary models or data are removed from the contributed files. Binary models and/or data should go to the FTP server.
- There is no duplicate functionality in the code that is provided elsewhere (e.g. pip package, other repo that can be linked, etc.). If so, this should not be re-included in the repository.
- There is no leftover functionality that is not going to be used in the contributed code. If so, this should be removed to make the code easier to maintain.
- Appropriate tests to ensure that the code runs correctly (at least one interface check that checks that model works correctly with OpenDR datatypes and at least one functionality check with a pre-trained model).
- A continuous integration test for the tool has been added to
.github/workflows/tests_sources.yml
,.github/workflows/tests_suite.yml
and.github/workflows/tests_suite_develop.yml
. - Documentation has been included:
- A markdown document should be included under
./docs/reference
, choosing a meaningful name like for examplelightweight-open-pose.md
. The document should state all the methods provided by the tool, the arguments it takes, the default values and lastly a snippet about how to use the tool. - The documentation index must reference the tool documentation.
- The demo provided along with the tool should include a
README.md
file that explains how the demo can be run and which are the available parameters. - The documentation index must reference the demo.
- ROS and ROS2 nodes are provided, and their documentation entries are added.
- At least one pre-trained model is provided.
- A meaningful name has been used for the PR.
- Make sure you update the documentation index (please also refer to https://github.com/opendr-eu/opendr/blob/master/docs/reference/index.md)
- Make sure that an appropriate
__init__.py
file has been created to expose the public interface of your implementation. - A changelog entry should be added about the added tool in the
CHANGELOG.md
file.
Nice to have (not mandatory at the moment):
- C-based Inference Interface
- DL model optimization targeting specific platforms based on a third-party tool (e.g., ONNX, TensorRT, etc.)