Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5a7f51b
feat(msgs): add EnvironmentData, Snapshot, GetFault, and ListFaultsFo…
bburda Feb 5, 2026
9fb17cb
feat(fault-manager): add UUID generation and rosbag index
bburda Feb 5, 2026
94824ff
feat(fault-manager): add GetFault service with environment data
bburda Feb 5, 2026
8ff17d1
feat(fault-manager): add ListFaultsForEntity service
bburda Feb 5, 2026
e9be59b
feat(gateway): add EntityPathInfo utility for entity path parsing
bburda Feb 5, 2026
1b476b7
feat(gateway): add SOVD-compliant fault response builder
bburda Feb 5, 2026
071e117
feat(gateway): add SOVD bulk-data handlers for all entity types
bburda Feb 5, 2026
a9345ce
refactor: remove legacy snapshot endpoints
bburda Feb 5, 2026
7ec221f
test(gateway): add bulk-data integration tests
bburda Feb 5, 2026
48bd151
fix(bulk-data): resolve rosbag directory path and correct MIME type
bburda Feb 5, 2026
44c794d
docs(gateway): update REST API docs for bulk-data and fault changes
bburda Feb 5, 2026
6e59a00
fix: rename occurence → occurrence in ExtendedDataRecords
bburda Feb 5, 2026
53bb0a5
fix: use chunked streaming, batch rosbag retrieval, and global CORS
bburda Feb 5, 2026
20b3635
refactor: extract shared format_timestamp_ns with gmtime_r null check
bburda Feb 5, 2026
e6623ca
docs: remove trailing whitespace in bulkdata/faults specs
bburda Feb 5, 2026
560ffea
refactor: rename GetFaults → ListFaults and GetRosbags → ListRosbags
bburda Feb 5, 2026
74dfd63
fix: resolve snapshot UX issues (async capture, mutex split, download…
bburda Feb 6, 2026
1d39726
fix: update tests for fault_code-based bulk_data_uri, rename vars, fi…
bburda Feb 6, 2026
100f40c
fix: remove accidentally added dynamic_message_introspection submodule
bburda Feb 6, 2026
3c9006d
fix: resolve docs build warnings treated as errors
bburda Feb 6, 2026
4cce3fe
fix: prevent callback group double-add to executor in snapshot capture
bburda Feb 6, 2026
15fc591
fix: address PR review comments from mfaferek93
bburda Feb 6, 2026
0c1b88e
style: apply ament_clang_format to PR-changed C++ files
bburda Feb 6, 2026
9ea2316
fix: align integration tests with actual fault response schema
bburda Feb 6, 2026
cdb5e29
refactor: remove dead UUID infrastructure from storage layer
bburda Feb 6, 2026
5c3181b
style: fix clang-format issues
bburda Feb 6, 2026
f365bca
fix(test): skip read-only params in set_configuration integration test
bburda Feb 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,4 @@ AMENT_IGNORE

# End of https://www.toptal.com/developers/gitignore/api/ros2,c++,pythonPLAN.md

PLAN.md
PLAN.mdsrc/dynamic_message_introspection/
6 changes: 3 additions & 3 deletions docs/api/messages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ Clear/acknowledge a fault.
string message # Status message or error description
string[] auto_cleared_codes # Symptoms auto-cleared with root cause

GetFaults.srv
~~~~~~~~~~~~~
ListFaults.srv
~~~~~~~~~~~~~~

Query faults from the FaultManager with optional filtering.

Expand Down Expand Up @@ -247,7 +247,7 @@ Query faults from the FaultManager with optional filtering.

.. code-block:: cpp

auto request = std::make_shared<ros2_medkit_msgs::srv::GetFaults::Request>();
auto request = std::make_shared<ros2_medkit_msgs::srv::ListFaults::Request>();
request->filter_by_severity = false;
request->statuses = {"CONFIRMED", "PREFAILED"};

Expand Down
164 changes: 162 additions & 2 deletions docs/api/rest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,172 @@ Query and manage faults.
}

``GET /api/v1/components/{id}/faults/{fault_code}``
Get specific fault details.
Get details of a specific fault including environment data.

**Example Response (200 OK):**

.. code-block:: json

{
"item": {
"code": "MOTOR_OVERHEAT",
"fault_name": "Motor temperature exceeded threshold",
"severity": 2,
"status": {
"aggregatedStatus": "active",
"testFailed": "1",
"confirmedDTC": "1",
"pendingDTC": "0"
}
},
"environment_data": {
"extended_data_records": {
"first_occurrence": "2026-02-04T10:30:00.000Z",
"last_occurrence": "2026-02-04T10:35:00.000Z"
},
"snapshots": [
{
"type": "freeze_frame",
"name": "motor_temperature",
"data": 105.5,
"x-medkit": {
"topic": "/motor/temperature",
"message_type": "sensor_msgs/msg/Temperature",
"full_data": {"temperature": 105.5, "variance": 0.1},
"captured_at": "2026-02-04T10:30:00.123Z"
}
},
{
"type": "rosbag",
"name": "fault_recording",
"bulk_data_uri": "/apps/motor_controller/bulk-data/rosbags/550e8400-e29b-41d4-a716-446655440000",
"size_bytes": 1234567,
"duration_sec": 6.0,
"format": "mcap"
}
]
},
"x-medkit": {
"occurrence_count": 3,
"reporting_sources": ["/powertrain/motor_controller"],
"severity_label": "ERROR"
}
}

**Status Object:**

The ``status`` object follows SOVD fault status specification:

- ``aggregatedStatus``: Overall status (``active``, ``passive``, ``cleared``)
- ``testFailed``: Test failed indicator (``0`` or ``1``)
- ``confirmedDTC``: Confirmed DTC indicator (``0`` or ``1``)
- ``pendingDTC``: Pending DTC indicator (``0`` or ``1``)

**Snapshot Types:**

- ``freeze_frame``: Topic data captured at fault confirmation
- ``rosbag``: Recording file available via bulk-data endpoint

``DELETE /api/v1/components/{id}/faults/{fault_code}``
Clear a fault.

- **200:** Fault cleared
- **404:** Fault not found

Bulk Data Endpoints
-------------------

Download large binary data (rosbags, logs) associated with entities.
All entity types are supported: apps, components, areas, functions, and nested entities.

List Categories
~~~~~~~~~~~~~~~

``GET /api/v1/{entity-path}/bulk-data``

List available bulk-data categories for an entity.

**Supported entity paths:**

- ``/apps/{app-id}``
- ``/components/{component-id}``
- ``/areas/{area-id}``
- ``/functions/{function-id}``
- ``/areas/{area-id}/subareas/{subarea-id}``
- ``/components/{component-id}/subcomponents/{subcomponent-id}``

**Example:**

.. code-block:: bash

curl http://localhost:8080/api/v1/apps/motor_controller/bulk-data

**Response (200 OK):**

.. code-block:: json

{
"items": ["rosbags"]
}

List Bulk Data Items
~~~~~~~~~~~~~~~~~~~~

``GET /api/v1/{entity-path}/bulk-data/{category}``

List all bulk-data items in a category for the entity.

**Example:**

.. code-block:: bash

curl http://localhost:8080/api/v1/apps/motor_controller/bulk-data/rosbags

**Response (200 OK):**

.. code-block:: json

{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "MOTOR_OVERHEAT recording 2026-02-04T10:30:00Z",
"mimetype": "application/x-mcap",
"size": 1234567,
"creation_date": "2026-02-04T10:30:00.000Z",
"x-medkit": {
"fault_code": "MOTOR_OVERHEAT",
"duration_sec": 6.0,
"format": "mcap"
}
}
]
}

Download Bulk Data
~~~~~~~~~~~~~~~~~~

``GET /api/v1/{entity-path}/bulk-data/{category}/{id}``

Download a specific bulk-data file.

**Response Headers:**

- ``Content-Type``: ``application/x-mcap`` (MCAP format) or ``application/x-sqlite3`` (db3)
- ``Content-Disposition``: ``attachment; filename="FAULT_CODE.mcap"``
- ``Access-Control-Expose-Headers``: ``Content-Disposition``

**Example:**

.. code-block:: bash

curl -O -J http://localhost:8080/api/v1/apps/motor_controller/bulk-data/rosbags/550e8400-e29b-41d4-a716-446655440000

**Response Codes:**

- **200 OK**: File content
- **404 Not Found**: Entity, category, or bulk-data ID not found

Authentication Endpoints
------------------------

Expand Down Expand Up @@ -525,14 +683,16 @@ The gateway implements a subset of the SOVD (Service-Oriented Vehicle Diagnostic
- Data access (``/data``)
- Operations (``/operations``, ``/executions``)
- Configurations (``/configurations``)
- Faults (``/faults``)
- Faults (``/faults``) with ``environment_data`` and SOVD status object
- Bulk Data (``/bulk-data``) for binary data downloads (rosbags, logs)

**ros2_medkit Extensions:**

- ``/health`` - Health check endpoint
- ``/version-info`` - Gateway version information
- ``/manifest/status`` - Manifest discovery status
- SSE fault streaming - Real-time fault notifications
- ``x-medkit`` extension fields in responses

See Also
--------
Expand Down
52 changes: 48 additions & 4 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,50 @@ All notable changes to ros2_medkit are documented in this file.
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.1.0/>`_,
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.

[Unreleased]
------------

Added
~~~~~

* SOVD bulk-data endpoints for all entity types:

- ``GET /{entity}/bulk-data`` - list available bulk-data categories
- ``GET /{entity}/bulk-data/{category}`` - list bulk-data descriptors
- ``GET /{entity}/bulk-data/{category}/{id}`` - download bulk-data file

* Inline ``environment_data`` in fault response with:

- ``extended_data_records``: First/last occurrence timestamps
- ``snapshots[]``: Array of freeze_frame and rosbag entries

* SOVD-compliant ``status`` object in fault response with aggregatedStatus,
testFailed, confirmedDTC, pendingDTC fields
* UUID identifiers for rosbag bulk-data items
* ``x-medkit`` extensions with occurrence_count, severity_label

Changed
~~~~~~~

* Fault response structure now SOVD-compliant with ``item`` wrapper
* Rosbag downloads use SOVD bulk-data pattern instead of legacy endpoints
* Rosbag IDs changed from timestamps to UUIDs

Removed
~~~~~~~

* ``GET /faults/{code}/snapshots`` - use ``environment_data`` in fault response
* ``GET /faults/{code}/snapshots/bag`` - use bulk-data endpoint
* ``GET /{entity}/faults/{code}/snapshots`` - use ``environment_data``
* ``GET /{entity}/faults/{code}/snapshots/bag`` - use bulk-data endpoint

**Breaking Changes:**

* Fault response structure changed - clients must update to handle ``item`` wrapper
and ``environment_data`` structure
* Legacy snapshot endpoints removed - migrate to inline snapshots and bulk-data
* Rosbag identifiers changed from timestamps to UUIDs

[0.1.0] - 2026-02-01
--------------------

Expand Down Expand Up @@ -34,7 +78,7 @@ Added
**Fault Manager (ros2_medkit_fault_manager)**

- Centralized fault storage and management node
- ROS 2 services: ``report_fault``, ``get_faults``, ``clear_fault``
- ROS 2 services: ``report_fault``, ``list_faults``, ``clear_fault``
- AUTOSAR DEM-style debounce lifecycle (PREFAILED → CONFIRMED → HEALED → CLEARED)
- Fault aggregation from multiple sources
- Severity escalation
Expand Down Expand Up @@ -65,7 +109,7 @@ Added
- ``Fault.msg``: Fault status message with severity, timestamps, sources
- ``FaultEvent.msg``: Fault event for subscriptions
- ``ReportFault.srv``: Service for reporting faults
- ``GetFaults.srv``: Service for querying faults with filters
- ``ListFaults.srv``: Service for querying faults with filters
- ``ClearFault.srv``: Service for clearing faults

**Documentation**
Expand Down Expand Up @@ -102,11 +146,11 @@ specification adapted for ROS 2:
- Data access (read, write)
- Operations (services, actions with executions)
- Configurations (parameters)
- Faults (query, clear)
- Faults (query, clear) with environment_data
- Bulk data transfer (rosbags via bulk-data endpoints)

Not yet implemented:

- Bulk data transfer
- Software updates
- Locks
- Triggers
Expand Down
21 changes: 15 additions & 6 deletions docs/requirements/specs/bulkdata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,34 @@ BulkData

.. req:: GET /{entity}/bulk-data
:id: REQ_INTEROP_071
:status: open
:tags: BulkData
:status: verified
:tags: BulkData, SOVD

The endpoint shall provide an overview of bulk-data categories supported by the addressed entity.

Gateway supports all entity types: apps, components, areas, functions, and nested entities.
Currently implemented category: ``rosbags``.

.. req:: GET /{entity}/bulk-data/{category}
:id: REQ_INTEROP_072
:status: open
:tags: BulkData
:status: verified
:tags: BulkData, SOVD

The endpoint shall list all bulk-data items available in the addressed bulk-data category on the entity.

Returns BulkDataDescriptor array with id, name, mimetype, size, creation_date fields.
Includes ``x-medkit`` extensions with fault_code, duration_sec, format.

.. req:: GET /{entity}/bulk-data/{category}/{bulk-data-id}
:id: REQ_INTEROP_073
:status: open
:tags: BulkData
:status: verified
:tags: BulkData, SOVD

The endpoint shall return the content of the addressed bulk-data item or its access information (e.g. download location).

Returns binary file content with appropriate Content-Type (application/x-mcap or application/x-sqlite3)
and Content-Disposition headers for browser download.

.. req:: POST /{entity}/bulk-data/{category}
:id: REQ_INTEROP_074
:status: open
Expand Down
28 changes: 16 additions & 12 deletions docs/requirements/specs/faults.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ Faults
.. req:: GET /{entity}/faults/{code}
:id: REQ_INTEROP_013
:status: verified
:tags: Faults
:tags: Faults, SOVD

The endpoint shall return detailed information for the addressed diagnostic fault code,
including environment data captured at fault confirmation.

Response includes:

The endpoint shall return detailed information for the addressed diagnostic fault code.
- ``item``: Fault details with SOVD-compliant ``status`` object (aggregatedStatus, testFailed, confirmedDTC, pendingDTC)
- ``environment_data``: Extended data records (timestamps) and snapshots array
- ``environment_data.snapshots[]``: Array of freeze_frame (topic data) and rosbag (bulk-data reference) entries
- ``x-medkit``: Extension fields (occurrence_count, reporting_sources, severity_label)

.. req:: DELETE /{entity}/faults
:id: REQ_INTEROP_014
Expand All @@ -29,17 +37,13 @@ Faults

The endpoint shall clear the addressed diagnostic fault code for the entity, if permitted.

.. req:: GET /{entity}/faults/{code}/snapshots
.. req:: Fault Snapshot and Rosbag Capture
:id: REQ_INTEROP_088
:status: verified
:tags: Faults, Snapshots

The endpoint shall return topic data snapshots captured when the addressed fault transitioned to CONFIRMED status, enabling post-mortem debugging of system state at the time of fault occurrence.

.. note::
:tags: Faults, BulkData

This endpoint corresponds to SOVD "environment data" concept. In SOVD terminology,
environment data refers to system state captured at the time of fault occurrence
(similar to UDS freeze frames). We use "snapshots" as ROS 2-specific terminology
for consistency with the ROS 2 ecosystem.
When a fault is confirmed, the system shall automatically capture diagnostic snapshots
(freeze-frame topic data) and rosbag recordings as configured. Captured data shall be
stored as environment data associated with the fault and accessible via the bulk-data
endpoints on the fault's reporting entity.

Loading