Skip to content

Commit

Permalink
Added Sphinx documentation (#48)
Browse files Browse the repository at this point in the history
* added documentation workflow
* added metapackage with doc
* updated doc
  • Loading branch information
mcbed authored Mar 28, 2023
1 parent a8e9756 commit 298f057
Show file tree
Hide file tree
Showing 19 changed files with 1,315 additions and 67 deletions.
60 changes: 60 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Documentation

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build_documentation:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

- name: Install dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq doxygen graphviz plantuml
pip install sphinx-rtd-theme
pip install sphinxcontrib-plantuml
pip install sphinx-mdinclude
pip install breathe
pip install exhale
- name: Build doxygen
run: |
cd ./documentation/doxygen/
doxygen
cd ../..
- name: Build documentation
run: |
cd ./documentation/sphinx/
make html
cd ../..
- name: Create commit
run: |
git clone https://github.com/ICube-Robotics/ethercat_driver_ros2.git --branch gh-pages --single-branch gh-pages
mkdir -p gh-pages/docs/
mkdir -p gh-pages/api/
cp -r ./documentation/sphinx/_build/html/* gh-pages/
cp -r ./documentation/doxygen/_build/html/* gh-pages/api/
cd gh-pages
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add .
git commit -m "Update documentation" -a || true
- name: Push changes
uses: ad-m/github-push-action@master
with:
branch: gh-pages
directory: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
70 changes: 3 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,78 +7,14 @@ Implementation of a `Hardware Interface` for simple Ethercat module integration
## About
[EtherCAT](https://www.ethercat.org/default.htm) provides applications with the capacity of reliable, real-time communication between systems and is therefore a common industrial standard. In order to simplify the development/deployment of new application using EtherCAT modules, the `ethercat_driver` allows to combine them with [`ros2_control`](https://github.com/ros-controls/ros2_control). This driver proposes a generic ways to parametrise and assemble `Hardware Interfaces` based on EtherCAT modules that can be defined using parameter files.

## Usage
### 1. Installation
Installation steps for [IgH EtherCAT Master for Linux](https://etherlab.org/en/ethercat/) and the driver can be found [here](INSTALL.md).

### 2. Description
#### Hardwre Interfaces and EtherCAT Master
The `ethercat_driver` is designed in such a way that each EtherCAT Master is defined in `ros2_control` as a specific `Hardware Interface`. This is done in the `ros2_control` description file, where the EtherCAT driver is loaded as `Hardware Interface` and linked to an EtherCAT Master by its ID:
```xml
<ros2_control name="mySystem" type="system">
<hardware>
<plugin>ethercat_driver/EthercatDriver</plugin>
<param name="master_id">0</param>
<param name="control_frequency">100</param>
</hardware>
</ros2_control>
```
**NOTE**: As in the current implementation of `ros2_control` there is no information about the system update frequency, it needs to be passed here as parameter. This is only needed systems that include EtherCAT modules that use the Distributed Clock.

#### EtherCAT Slave modules as Plugins
In this driver, the EtherCAT Slave modules are defined as [Plugins](https://docs.ros.org/en/foxy/Tutorials/Pluginlib.html) and can be parametrized in the `ros2_control` description file :
```xml
<ec_module name="ECModule">
<plugin>ethercat_plugins/ECModule</plugin>
<param name="alias">0</param>
<param name="position">1</param>
</ec_module>
```
All modules have `alias` and `position` parameters that specify their address in the EtherCAT Bus topology. Additional parameters can be specified depending on the purpose of the module. A list of implemented modules and their parameters can be found [here](ethercat_plugins/available_plugins.md).

#### Interfacing controllers with EtherCAT Slave modules
In `ros2_control` the access to resources within a system from a controller is done by means of [`Hardware Resources`](https://github.com/ros-controls/roadmap/blob/master/design_drafts/hardware_access.md). For this purpose `state_interface` and `command_interface` tags need to be defined and associated with the module functionalities.
Also, for better understanding of the overall system, the pupropose of the used modules need to be clearly identified and sorted into the following types:
- `<joint>`: logical component actuated by at least one actuator with read-write capacity.
- `<sensor>`: logical component to read-only states from system.
- `<gpio>`: logical component for general purpose IO systems.

**NOTE**: These components have the possibility to include parameters that will be used to link particular states and commands to the slave module input/outputs.

Here is an example of a `gpio` resource built using 2 EtherCAT IO modules, where digital commands are mapped on ports 4 and 6 of the digital output module and analog states are read from ports 1 and 4 of the analog input module:
```xml
<gpio name="myGPIO">
<command_interface name="dig_output.1"/>
<command_interface name="dig_output.2"/>
<state_interface name="dig_output.1"/>
<state_interface name="dig_output.2"/>
<state_interface name="ana_input.1"/>
<state_interface name="ana_input.2"/>
<ec_module name="EL3104">
<plugin>ethercat_plugins/Beckhoff_EL3104</plugin>
<param name="alias">0</param>
<param name="position">1</param>
<param name="ai.1">ana_input.1</param>
<param name="ai.4">ana_input.2</param>
</ec_module>
<ec_module name="EL2008">
<plugin>ethercat_plugins/Beckhoff_EL2008</plugin>
<param name="alias">0</param>
<param name="position">2</param>
<param name="do.4">dig_output.2</param>
<param name="do.6">dig_output.1</param>
</ec_module>
</gpio>
```

**NOTE** : To send commands to `gpio` resources, a generic controller was developed and can be found [here](https://github.com/mcbed/ros2_controllers/tree/gpio_controllers).
**For more information, please check the [documentation](https://ICube-Robotics.github.io/ethercat_driver_ros2/).**

## Acknowledgments
Parts of the driver are based on the implementation of [`SimplECAT`](https://bitbucket.org/bsoe/simplecat/src/master/).

## Contacts ##
![icube](https://icube.unistra.fr/fileadmin/templates/DUN/icube/images/logo.png)

[ICube Laboratory](https://plateforme.icube.unistra.fr), [University of Strasbourg](https://www.unistra.fr/), France
[ICube Laboratory](https://icube.unistra.fr), [University of Strasbourg](https://www.unistra.fr/), France

__Maciej Bednarczyk:__ [[email protected]](mailto:[email protected]), @github: [mcbed](mailto:macbednarczyk@gmail.com)
__Maciej Bednarczyk:__ [[email protected]](mailto:[email protected]), @github: [mcbed](https://github.com/mcbed)
4 changes: 4 additions & 0 deletions ethercat_driver_ros2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.8)
project(ethercat_driver_ros2 NONE)
find_package(ament_cmake REQUIRED)
ament_package()
23 changes: 23 additions & 0 deletions ethercat_driver_ros2/doxygen/Doxyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# All settings not listed here will use the Doxygen default values.

PROJECT_NAME = "ethercat_driver_ros2"
PROJECT_NUMBER = main
PROJECT_BRIEF = "C++ ROS test"

# Use these lines to include the generated logging.hpp (update install path if needed)
INPUT = ../../ethercat_driver/include ../../ethercat_interface/include

RECURSIVE = YES
OUTPUT_DIRECTORY = _build

EXTRACT_ALL = YES
SORT_MEMBER_DOCS = NO

GENERATE_LATEX = NO
GENERATE_XML = YES

ENABLE_PREPROCESSING = YES

DOT_GRAPH_MAX_NODES = 101

FILE_PATTERNS = *.cpp *.h *.hpp *.md
18 changes: 18 additions & 0 deletions ethercat_driver_ros2/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>ethercat_driver_ros2</name>
<version>1.0.0</version>
<description>Meta-package aggregating the ethercat_driver_ros2 packages and documentation</description>
<maintainer email="[email protected]">Maciej Bednarczyk</maintainer>
<license>Apache License 2.0</license>

<buildtool_depend>ament_cmake</buildtool_depend>
<exec_depend>ethercat_driver</exec_depend>
<exec_depend>ethercat_interface</exec_depend>
<exec_depend>ethercat_plugins</exec_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
24 changes: 24 additions & 0 deletions ethercat_driver_ros2/sphinx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile clean

clean:
rm -rf "_doxygen/" "api/"
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
17 changes: 17 additions & 0 deletions ethercat_driver_ros2/sphinx/_static/css/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

.wy-table-responsive table td,
.wy-table-responsive table th {
white-space:normal;
}

tr {
white-space: normal;
}

thead {
white-space: normal;
}

table {
white-space: normal;
}
100 changes: 100 additions & 0 deletions ethercat_driver_ros2/sphinx/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Copyright 2022 ICube Laboratory, University of Strasbourg
#
# 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.

# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
from pathlib import Path

# -- Project information -----------------------------------------------------

project = "ethercat_driver_ros2"
copyright = "2023, ICUBE Laboratory, University of Strasbourg"
author = "Maciej Bednarczyk, Philippe Zanne, Laurent Barbé"

# The full version, including alpha/beta/rc tags
release = "1.0.0"


# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx_rtd_theme",
"sphinx_mdinclude",
"sphinx.ext.imgmath",
"sphinx.ext.todo",
"sphinx.ext.graphviz",
"sphinxcontrib.plantuml",
"breathe",
]

breathe_default_project = "ethercat_driver_ros2"


def get_package(package: str):
path = Path(__file__).parent.parent.parent.joinpath(f"{package}/include/{package}")
files_gen = path.glob("*.hpp")
files = []
for file in files_gen:
files.append(file.name)
return (path, files)


breathe_projects = {
"ethercat_driver_ros2": "../doxygen/_build/xml/",
}


# Tell sphinx what the primary language being documented is.
primary_domain = "cpp"

# Tell sphinx what the pygments highlight language should be.
highlight_language = "cpp"


# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_logo = "images/logo-icube.png"
html_css_files = ["css/custom.css"]
pygments_style = "sphinx"
Loading

0 comments on commit 298f057

Please sign in to comment.