Skip to content

Commit d8fb304

Browse files
committed
feat(docs): restructure requirements and automate verification traceability
- Restructure documentation layout: - Move requirement specifications to `docs/requirements/specs/` - Add `introduction.rst` and update indices - Move design assets to `src/ros2_medkit_gateway/design/` - Implement automated verification reporting: - Add `scripts/generate_verification.py` to scan C++ and Python tests for `@verifies` tags - Generate `docs/requirements/verification.rst` automatically during build - Add `docs/requirements/coverage.rst` with coverage statistics and matrices - Configure `sphinx-needs` for bidirectional traceability - Update CI/CD: - Add verification generation step to `docs.yml` workflow - Update `.gitignore` to exclude generated documentation artifacts - Traceability: - Annotate `test_gateway_node.cpp` and `test_integration.test.py` with requirement IDs - Update `docs/README.md` with usage instructions for the new workflow
1 parent 469c1d6 commit d8fb304

40 files changed

Lines changed: 1395 additions & 1215 deletions

.github/workflows/docs.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ jobs:
4242
sudo apt-get install -y graphviz plantuml
4343
pip install -e docs/.[dev]
4444
45+
- name: Generate verification report
46+
run: python3 scripts/generate_verification.py
47+
4548
- name: Check links
4649
working-directory: docs
4750
run: sphinx-build -b linkcheck . _build/linkcheck
@@ -66,4 +69,3 @@ jobs:
6669
- name: Deploy to GitHub Pages
6770
id: deployment
6871
uses: actions/deploy-pages@v4
69-

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ instance/
107107

108108
# Sphinx documentation
109109
docs/_build/
110+
docs/requirements/verification.rst
110111

111112
# PyBuilder
112113
.pybuilder/

docs/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,48 @@ Requirements are managed using `sphinx-needs`. To add a new requirement:
8585
Description of the requirement.
8686
```
8787

88+
## Traceability and Testing
89+
90+
We use a bidirectional traceability approach to link Requirements to Tests and Code.
91+
92+
### 1. Link Code to Test Case
93+
94+
In your test code (C++ or Python), add comments to indicate which Requirement ID is being verified. The `generate_verification.py` script will automatically scan these tags and generate the `verification.rst` file.
95+
96+
**Supported Tags:**
97+
* `@verifies REQ_ID_1, REQ_ID_2` (Preferred)
98+
* `Links to: REQ_ID` (Legacy)
99+
* `Verifies: REQ_ID` (Legacy)
100+
101+
#### C++ Example (`.cpp`)
102+
103+
```cpp
104+
TEST_F(TestGatewayNode, test_health_endpoint) {
105+
// @verifies REQ_SOVD_001
106+
auto node = std::make_shared<GatewayNode>();
107+
// ...
108+
}
109+
```
110+
111+
#### Python Example (`.py`)
112+
113+
```python
114+
def test_root_endpoint(self):
115+
"""
116+
Test GET / returns gateway status and version.
117+
118+
@verifies REQ_SOVD_010
119+
"""
120+
data = self._get_json('/')
121+
```
122+
123+
This establishes the chain: **Requirement** <-> **Test Implementation (Code)** <-> **Verification Report**.
124+
125+
**Note:** Only tests that verify at least one requirement will be included in the generated report.
126+
88127
## CI/CD
89128

90129
The documentation is automatically built and deployed to GitHub Pages via GitHub Actions. The workflow is defined in `.github/workflows/docs.yml`.
130+
131+
The `verification.rst` file is automatically generated during the CI build process, ensuring that the documentation always reflects the current state of the code.
132+

docs/conf.py

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,30 @@
33
# For the full list of built-in configuration values, see the documentation:
44
# https://www.sphinx-doc.org/en/master/usage/configuration.html
55

6+
import matplotlib
7+
8+
matplotlib.use("Agg")
9+
import matplotlib.pyplot as plt
10+
11+
# Ensure readable plots
12+
matplotlib.rcParams["figure.facecolor"] = "white"
13+
matplotlib.rcParams["text.color"] = "black"
14+
matplotlib.rcParams["legend.frameon"] = True
15+
matplotlib.rcParams["legend.framealpha"] = 0.8
16+
matplotlib.rcParams["legend.facecolor"] = "white"
17+
matplotlib.rcParams["legend.edgecolor"] = "gray"
18+
matplotlib.rcParams["figure.autolayout"] = True
19+
matplotlib.rcParams["figure.figsize"] = [10, 6]
20+
matplotlib.rcParams["savefig.bbox"] = "tight"
21+
22+
from datetime import datetime
23+
624
# -- Project information -----------------------------------------------------
725
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
826

927
project = "ros2_medkit"
10-
copyright = "2025, selfpatch"
11-
author = "bburda"
28+
project_copyright = f"{datetime.now().year}, selfpatch"
29+
author = "selfpatch Team"
1230

1331
version = "0.1.0"
1432
release = "0.1.0"
@@ -19,14 +37,27 @@
1937
extensions = [
2038
"sphinx.ext.autodoc",
2139
"sphinx.ext.viewcode",
40+
"sphinx.ext.intersphinx",
2241
"sphinx_needs",
2342
"sphinxcontrib.plantuml",
2443
]
2544

2645
templates_path = ["_templates"]
2746
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
2847

48+
# The suffix(es) of source filenames
49+
source_suffix = {
50+
".rst": "restructuredtext",
51+
}
52+
53+
# The master toctree document
54+
master_doc = "index"
55+
56+
# The language for content autogenerated by Sphinx
57+
language = "en"
58+
2959
# -- Options for Sphinx-Needs ------------------------------------------------
60+
needs_build_json = True
3061
needs_types = [
3162
dict(
3263
directive="req",
@@ -73,15 +104,30 @@
73104
},
74105
]
75106

76-
77107
# -- Options for HTML output -------------------------------------------------
78108
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
79109

80110
html_theme = "sphinx_rtd_theme"
81111
html_static_path = ["_static"]
82112
html_css_files = ["custom.css"]
113+
html_title = f"{project} Documentation"
83114

115+
html_theme_options = {
116+
"prev_next_buttons_location": "bottom",
117+
"style_external_links": False,
118+
"collapse_navigation": False,
119+
"sticky_navigation": True,
120+
"navigation_depth": 4,
121+
"includehidden": True,
122+
"titles_only": False,
123+
}
124+
125+
# -- Options for intersphinx extension ---------------------------------------
126+
intersphinx_mapping = {
127+
"python": ("https://docs.python.org/3", None),
128+
"sphinx": ("https://www.sphinx-doc.org/en/master", None),
129+
}
84130

85131
# -- Options for PlantUML ----------------------------------------------------
86132
plantuml = "java -Djava.awt.headless=true -jar /usr/share/plantuml/plantuml.jar"
87-
133+
plantuml_output_format = "svg"

docs/design/index.rst

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,10 @@
11
Architecture
22
============
33

4-
This section contains design documentation for the ros2_medkit_gateway project.
4+
This section contains design documentation for the ros2_medkit project packages.
55

6-
Architecture Diagram
7-
--------------------
6+
.. toctree::
7+
:maxdepth: 1
88

9-
The following diagram shows the relationships between the main components of the gateway.
10-
11-
.. uml:: architecture.puml
12-
:caption: ROS 2 Medkit Gateway Class Architecture
13-
14-
Main Components
15-
---------------
16-
17-
1. **GatewayNode** - The main ROS 2 node that orchestrates the system
18-
- Extends ``rclcpp::Node``
19-
- Manages periodic discovery and cache refresh
20-
- Runs the REST server in a separate thread
21-
- Provides thread-safe access to the entity cache
22-
23-
2. **DiscoveryManager** - Discovers ROS 2 entities and maps them to the SOVD hierarchy
24-
- Discovers Areas from node namespaces
25-
- Discovers Components from nodes, topics, and services
26-
- Extracts the entity hierarchy from the ROS 2 graph
27-
28-
3. **RESTServer** - Provides the HTTP/REST API
29-
- Serves endpoints: ``/health``, ``/``, ``/areas``, ``/components``, ``/areas/{area_id}/components``
30-
- Retrieves cached entities from the GatewayNode
31-
- Runs on configurable host and port
32-
33-
4. **Data Models** - Entity representations
34-
- ``Area`` - Physical or logical domain
35-
- ``Component`` - Hardware or software component
36-
- ``EntityCache`` - Thread-safe cache of discovered entities
9+
ros2_medkit_gateway/index
3710

docs/design/ros2_medkit_gateway

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../src/ros2_medkit_gateway/design

docs/index.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@
66
ros2_medkit documentation
77
=========================
88

9-
Add your content using ``reStructuredText`` syntax. See the
10-
`reStructuredText <https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html>`_
11-
documentation for details.
12-
9+
Welcome to the documentation for **ros2_medkit**.
1310

1411
.. toctree::
1512
:maxdepth: 2
16-
:caption: Contents:
13+
:caption: General
1714

18-
requirements/index
15+
introduction
1916
design/index
20-
verification
17+
18+
.. toctree::
19+
:maxdepth: 4
20+
:caption: Requirements Engineering
21+
22+
requirements/index
2123

docs/introduction.rst

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Introduction
2+
============
3+
4+
ros2_medkit
5+
-----------
6+
7+
Modern, SOVD-compatible diagnostics for ROS 2 robots, built around an entity tree
8+
(Area / Component / Function / App) for runtime discovery, health modeling, and troubleshooting.
9+
10+
What is ros2_medkit?
11+
--------------------
12+
13+
ros2_medkit is an experiment in **modern diagnostics for ROS 2–based systems**.
14+
15+
Instead of hardcoding knowledge about every node, topic, or ECU, ros2_medkit models a robot
16+
as a **diagnostic entity tree**:
17+
18+
- **Area** – physical or logical domain (e.g. ``base``, ``arm``, ``safety``, ``navigation``)
19+
- **Component** – hardware or software component within an area
20+
- **Function** – capability provided by one or more components
21+
- **App** – deployable software unit (node, container, process)
22+
23+
The goal is to make this tree **compatible with the SOVD (Service-Oriented Vehicle Diagnostics) model**,
24+
so the same concepts can be used across robots, vehicles, and other embedded systems.
25+
26+
Status
27+
------
28+
29+
**Early prototype / work in progress**
30+
31+
This is a personal open source project to explore diagnostic patterns for ROS 2.
32+
APIs, architecture, and naming may change at any time.
33+
34+
Target Use Cases
35+
----------------
36+
37+
- Runtime discovery of what is actually running on the robot
38+
- Health state modeled per Area / Component / Function / App
39+
- Better remote troubleshooting and fleet-level observability for ROS 2 robots

docs/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dependencies = [
1515
"sphinx-needs>=1.0",
1616
"sphinx-rtd-theme",
1717
"sphinxcontrib-plantuml",
18+
"matplotlib",
1819
]
1920

2021
[project.optional-dependencies]

0 commit comments

Comments
 (0)