Skip to content

Commit

Permalink
docs: Fixed docs to reflect current implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
huyenngn committed Mar 7, 2024
1 parent cad6dc6 commit 8214ada
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 147 deletions.
66 changes: 66 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Export local",
"type": "debugpy",
"request": "launch",
"module": "capella_ros_tools",
"args": [
"export",
"-m",
"tests/data/melody_model_60",
"-l",
"la",
"-o",
"tests/data/melody_msgs"
]
},
{
"name": "Export git",
"type": "debugpy",
"request": "launch",
"module": "capella_ros_tools",
"args": [
"export",
"-m",
"git+https://github.com/DSD-DBS/coffee-machine",
"-l",
"oa",
"-o",
"tests/data/coffee_msgs"
]
},
{
"name": "Import local",
"type": "debugpy",
"request": "launch",
"module": "capella_ros_tools",
"args": [
"import",
"-i",
"tests/data/data_model/example_msgs",
"-m",
"tests/data/empty_project_52",
"-l",
"la",
"--no-deps"
]
},
{
"name": "Import git",
"type": "debugpy",
"request": "launch",
"module": "capella_ros_tools",
"args": [
"import",
"-i",
"git+https://github.com/DSD-DBS/dsd-ros-msg-definitions-oss",
"-m",
"tests/data/empty_project_52",
"-l",
"la"
]
}
]
}
2 changes: 2 additions & 0 deletions .vscode/launch.json.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SPDX-FileCopyrightText: Copyright DB InfraGO AG
SPDX-License-Identifier: CC0-1.0
48 changes: 26 additions & 22 deletions capella_ros_tools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,20 @@ def cli():


@cli.command("import")
@click.argument(
"messages",
@click.option(
"-i",
"--input",
type=str,
required=True,
)
@click.argument(
"model",
@click.option(
"-m" "--model",
type=cli_helpers.ModelCLI(),
required=True,
)
@click.argument(
"layer",
@click.option(
"-l",
"--layer",
type=click.Choice(["oa", "la", "sa", "pa"], case_sensitive=False),
required=True,
)
Expand All @@ -44,47 +46,48 @@ def cli():
is_flag=True,
help="Don’t install message dependencies.",
)
@click.option("--port", type=int, help="Open model viewer on given port.")
@click.option(
"-p", "--port", type=int, help="Open model viewer on given port."
)
def import_msgs(
messages: str,
input: str,
model: capellambse.MelodyModel,
layer: str,
no_deps: bool,
port: int,
) -> None:
"""Import ROS messages into a Capella data package.
MESSAGES: File path or git URL to ROS messages.
MODEL: Path to Capella model.
LAYER: Layer of Capella model to import elements to.
"""
"""Import ROS messages into a Capella data package."""

from capella_ros_tools.scripts import import_msgs as importer

root_uuid = getattr(model, layer).uuid
types_uuid = model.sa.data_package.uuid

yml = importer.Importer(messages, no_deps)(root_uuid, types_uuid)
yml = importer.Importer(input, no_deps)(root_uuid, types_uuid)
decl.apply(model, io.StringIO(yml))

if port:
raise NotImplementedError("Open model with model explorer.")


@cli.command("export")
@click.argument("model", type=cli_helpers.ModelCLI, required=True)
@click.argument(
"layer",
@click.option("-m", "--model", type=cli_helpers.ModelCLI, required=True)
@click.option(
"-l",
"--layer",
type=click.Choice(["oa", "la", "sa", "pa"], case_sensitive=False),
required=True,
)
@click.argument(
"messages", type=click.Path(path_type=pathlib.Path), required=True
@click.option(
"-o",
"--output",
type=click.Path(path_type=pathlib.Path),
default=pathlib.Path.cwd() / "export",
)
def export_capella(
model: capellambse.MelodyModel,
layer: str,
msg_path: pathlib.Path,
output: pathlib.Path,
):
"""Export Capella data package to ROS messages.
Expand All @@ -94,7 +97,8 @@ def export_capella(
"""
from capella_ros_tools.scripts import export_capella as exporter

exporter.Exporter(model, layer, msg_path)()
current_pkg = getattr(model, layer).data_package
exporter.export(current_pkg, output)


if __name__ == "__main__":
Expand Down
122 changes: 55 additions & 67 deletions capella_ros_tools/scripts/export_capella.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pathlib
import re

import capellambse
from capellambse.model.crosslayer import information

from capella_ros_tools import data_model
Expand All @@ -17,75 +16,64 @@ def _clean_name(name: str) -> str:
return re.sub(r"\W", "", name)


class Exporter:
"""Class for exporting a Capella data package as ROS messages."""

def __init__(
self,
model: capellambse.MelodyModel,
layer: str,
output_path: pathlib.Path,
):
self._data_package = getattr(model, layer).data_package
output_path.mkdir(parents=True, exist_ok=True)
self._output_path = output_path

def _handle_pkg(
self,
current_pkg: information.DataPkg,
current_path: pathlib.Path,
):
for cls_obj in current_pkg.classes:
cls_def = data_model.MessageDef(
cls_obj.name, [], [], cls_obj.description
def export(current_pkg: information.DataPkg, current_path: pathlib.Path):
"""Export a Capella data package to ROS messages."""
for cls_obj in current_pkg.classes:
fields = []
for prop_obj in cls_obj.owned_properties:
type_def = data_model.TypeDef(
name=prop_obj.type.name,
card=data_model.Range(
prop_obj.min_card.value, prop_obj.max_card.value
),
)
for prop_obj in cls_obj.owned_properties:
type_def = data_model.TypeDef(
prop_obj.type.name,
data_model.Range(
prop_obj.min_card.value, prop_obj.max_card.value
),
)
prop_def = data_model.FieldDef(
type_def, prop_obj.name, prop_obj.description
)
cls_def.fields.append(prop_def)
(current_path / f"{_clean_name(cls_obj.name)}.msg").write_text(
str(cls_def)
prop_def = data_model.FieldDef(
type=type_def,
name=prop_obj.name,
description=prop_obj.description,
)
fields.append(prop_def)
cls_def = data_model.MessageDef(
name=cls_obj.name,
fields=fields,
enums=[],
description=cls_obj.description,
)
(current_path / f"{_clean_name(cls_obj.name)}.msg").write_text(
str(cls_def)
)

for enum_obj in current_pkg.enumerations:
enum_def = data_model.EnumDef(
enum_obj.name, [], enum_obj.description
for enum_obj in current_pkg.enumerations:
literals = []
for i, lit_obj in enumerate(enum_obj.owned_literals):
try:
type_name = lit_obj.value.type.name
except AttributeError:
type_name = "uint8"
try:
literal_value = lit_obj.value.value
except AttributeError:
literal_value = i
type_def = data_model.TypeDef(
type_name, data_model.Range("1", "1")
)
for i, lit_obj in enumerate(enum_obj.owned_literals):
try:
type_name = lit_obj.value.type.name
except AttributeError:
type_name = "uint8"
try:
literal_value = lit_obj.value.value
except AttributeError:
literal_value = i
type_def = data_model.TypeDef(
type_name, data_model.Range("1", "1")
)
lit_def = data_model.ConstantDef(
type_def,
lit_obj.name,
literal_value,
lit_obj.description,
)
enum_def.literals.append(lit_def)
(current_path / f"{_clean_name(enum_obj.name)}.msg").write_text(
str(enum_def)
lit_def = data_model.ConstantDef(
type=type_def,
name=lit_obj.name,
value=literal_value,
description=lit_obj.description,
)
literals.append(lit_def)
enum_def = data_model.EnumDef(
name=enum_obj.name,
literals=literals,
description=enum_obj.description,
)
(current_path / f"{_clean_name(enum_obj.name)}.msg").write_text(
str(enum_def)
)

for pkg_obj in current_pkg.packages:
pkg_path = current_path / _clean_name(pkg_obj.name)
pkg_path.mkdir(parents=True, exist_ok=True)
self._handle_pkg(pkg_obj, pkg_path)

def __call__(self):
"""Export the Capella data package as ROS messages."""
self._handle_pkg(self._data_package, self._output_path)
for pkg_obj in current_pkg.packages:
pkg_path = current_path / _clean_name(pkg_obj.name)
pkg_path.mkdir(parents=True, exist_ok=True)
export(pkg_obj, pkg_path)
21 changes: 16 additions & 5 deletions docs/source/howtos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,35 @@ Import ROS2 Messages:
---------------------
.. code-block:: bash
$ python -m capella_ros_tools import tests/data/example_msgs tests/data/empty_model la --exists-action=skip --port=5000 --no-deps
python -m capella_ros_tools import \
-i tests/data/data_model/example_msgs \
-m tests/data/empty_project_52 -l la \
--port=5000 --no-deps
Import ROS2 Messages from Git Repository:
-----------------------------------------
.. code-block:: bash
$ python -m capella_ros_tools import git+https://github.com/DSD-DBS/dsd-ros-msg-definitions-oss tests/data/empty_model la --exists-action=skip --port=5000
python -m capella_ros_tools import \
-i git+https://github.com/DSD-DBS/dsd-ros-msg-definitions-oss \
-m tests/data/empty_project_52 -l la \
--port=5000
Export Capella data package:
------------------------------------
.. code-block:: bash
$ python -m capella_ros_tools export tests/data/melody_model_60 la tests/data/melody_msgs
python -m capella_ros_tools export \
-m tests/data/melody_model_60 -l la \
-o tests/data/melody_msgs
Export Capella data package from Git Repository:
--------------------------------------------------------
.. code-block:: bash
$ python -m capella_ros_tools export git+https://github.com/DSD-DBS/coffee-machine oa tests/data/coffee_msgs
python -m capella_ros_tools export \
-m git+https://github.com/DSD-DBS/coffee-machine -l oa \
-o tests/data/coffee_msgs
Note: When exporting Capella enumerations, if the enumeration values are not defined in the Capella model, the values will be set to 0, 1, 2, 3, etc. and the datatype will be set to unit8.
.. note::
When exporting Capella enumerations, if the enumeration literal values are not defined in the Capella model, the values will be set to 0, 1, 2, 3, etc. and the value's type will be set to unit8.
27 changes: 4 additions & 23 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,22 @@ Overview

Capella ROS Tools is a command-line application written in Python, designed to facilitate the seamless integration of ROS2 and Capella MBSE tools. Key features include:

* generate ROS2 message files (.msg) from Capella models
* generate Capella elements and objects from ROS2 message files
* support input sources through both local file paths and Git repositories
* display snapshots of Capella model elements in a tree structure

If you want a quickstart at how to use this tool, head right into the
:ref:`Usage section <usage>`.
* Export Capella model elements as ROS2 message (.msg) files.
* Import ROS2 message (.msg) files as Capella model elements.
* Works with local and remote message files/Capella projects.


.. toctree::
:maxdepth: 2
:caption: Contents:

.. toctree::
:maxdepth: 2
:caption: Usage

usage


.. toctree::
:maxdepth: 2
:caption: Examples

howtos

.. toctree::
:maxdepth: 2
:caption: ROS2 Messages Layout

messages

.. toctree::
:maxdepth: 3
:caption: API reference
:caption: API reference:

code/modules

Expand Down
Loading

0 comments on commit 8214ada

Please sign in to comment.