diff --git a/capella_ros_tools/modules/capella/parser.py b/capella_ros_tools/modules/capella/parser.py index da98504..0091d8c 100644 --- a/capella_ros_tools/modules/capella/parser.py +++ b/capella_ros_tools/modules/capella/parser.py @@ -49,18 +49,27 @@ def get_enums(self, package: t.Any) -> list[EnumDef]: """Get enums in Capella model.""" enums = [] for enum in package.enumerations: + values = [] + for literal in enum.owned_literals: + try: + type_name = literal.value.type.name + literal_value = literal.value.value + except AttributeError: + type_name = "" + literal_value = "" + + values.append( + EnumValue( + type_name, + literal.name, + literal_value, + literal.description, + ) + ) enums.append( EnumDef( enum.name, - [ - EnumValue( - literal.value.type.name, - literal.name, - literal.value.value, - literal.description, - ) - for literal in enum.owned_literals - ], + values, enum.description, ) ) diff --git a/capella_ros_tools/scripts/capella2msg.py b/capella_ros_tools/scripts/capella2msg.py index 1655b87..5da434e 100644 --- a/capella_ros_tools/scripts/capella2msg.py +++ b/capella_ros_tools/scripts/capella2msg.py @@ -91,13 +91,14 @@ def _add_package(self, current_root: t.Any) -> MessagePkgDef: [ ConstantDef( BaseTypeDef( - CAPELLA_TYPE_TO_MSG[value.type] + CAPELLA_TYPE_TO_MSG.get(value.type) + or "uint8" ), value.name, - str(value.value), + value.value or str(i), value.description.split("\n"), ) - for value in enum.values + for i, value in enumerate(enum.values) ], [], ) diff --git a/docs/source/examples/Export capella.ipynb b/docs/source/examples/Export capella.ipynb index 8a5e4bb..7341e3f 100644 --- a/docs/source/examples/Export capella.ipynb +++ b/docs/source/examples/Export capella.ipynb @@ -9,29 +9,28 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "import capellambse\n", "from capella_ros_tools.scripts import capella2msg\n", "from pathlib import Path" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "msg_path = Path(\"data/coffee_msgs\")\n", - "capella_path = capellambse.filehandler.get_filehandler(\"git+https://github.com/DSD-DBS/coffee-machine\")\n", + "msg_path = Path(\"data/test\")\n", + "capella_path = Path(\"data/melody_model_60\")\n", "layer = \"la\"" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -49,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ diff --git a/docs/source/examples/Parse capella.ipynb b/docs/source/examples/Parse capella.ipynb new file mode 100644 index 0000000..4fc88f0 --- /dev/null +++ b/docs/source/examples/Parse capella.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parse Capella" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from capella_ros_tools.modules.capella.parser import CapellaModel\n", + "from pathlib import Path" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + } + ], + "source": [ + "model = CapellaModel(Path(\"data/melody_model_60\"), \"la\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Wand Objects'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.get_packages(model.data)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[ClassDef(name='Wand', properties=[ClassProperty(type_name='String', type_pkg_name=None, name='owner', min_card='1', max_card='1', description=''), ClassProperty(type_name='Wand Core', type_pkg_name=None, name='core', min_card='1', max_card='1', description=''), ClassProperty(type_name='Wand Wood', type_pkg_name=None, name='wood', min_card='1', max_card='1', description='')], description=''),\n", + " ClassDef(name='Class 2', properties=[], description='')]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.get_classes(model.data)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[EnumDef(name='Wand Core', values=[EnumValue(type='', name='Unicorn Hair', value='', description=''), EnumValue(type='', name='Dragon Heartstring', value='', description=''), EnumValue(type='', name='Pheonix Feather', value='', description=''), EnumValue(type='', name='Thestral Tail-Hair', value='', description='')], description=''),\n", + " EnumDef(name='Wand Wood', values=[EnumValue(type='', name='Apple', value='', description=''), EnumValue(type='', name='Cedar', value='', description=''), EnumValue(type='', name='Ebony', value='', description=''), EnumValue(type='', name='Elder', value='', description=''), EnumValue(type='', name='Holly', value='', description='')], description='')]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.get_enums(model.data)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".capella_venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/examples/Parse capella.ipynb.license b/docs/source/examples/Parse capella.ipynb.license new file mode 100644 index 0000000..f6f3181 --- /dev/null +++ b/docs/source/examples/Parse capella.ipynb.license @@ -0,0 +1,2 @@ +# Copyright DB InfraGO AG and contributors +# SPDX-License-Identifier: CC0-1.0 diff --git a/docs/source/examples/Parse messages.ipynb b/docs/source/examples/Parse messages.ipynb index 5ce665e..bec90e7 100644 --- a/docs/source/examples/Parse messages.ipynb +++ b/docs/source/examples/Parse messages.ipynb @@ -15,7 +15,7 @@ "source": [ "from capella_ros_tools.modules.messages.parser import MessageDef\n", "from pathlib import Path\n", - "from IPython.display import display\n" + "from IPython.display import display" ] }, { @@ -72,56 +72,10 @@ { "data": { "text/html": [ - "
# This message defines meta information for a camera. It should be in a
# camera namespace on topic \"camera_info\" and accompanied by up to five
# image topics named:
#
# image_raw - raw data from the camera driver, possibly Bayer encoded
# image - monochrome, distorted
# image_color - color, distorted
# image_rect - monochrome, rectified
# image_rect_color - color, rectified
#
# The image_pipeline contains packages (image_proc, stereo_image_proc)
# for producing the four processed image topics from image_raw and
# camera_info. The meaning of the camera parameters are described in
# detail at http://www.ros.org/wiki/image_pipeline/CameraInfo.
#
# The image_geometry package provides a user-friendly interface to
# common operations using this meta information. If you want to, e.g.,
# project a 3d point into image coordinates, we strongly recommend
# using image_geometry.
#
# If the camera is uncalibrated, the matrices D, K, R, P should be left
# zeroed out. In particular, clients may assume that K[0] == 0.0
# indicates an uncalibrated camera.
#######################################################################
# Image acquisition info #
#######################################################################
#######################################################################
# Calibration Parameters #
#######################################################################
# These are fixed during camera calibration. Their values will be the #
# same in all messages until the camera is recalibrated. Note that #
# self-calibrating systems may \"recalibrate\" frequently. #
# #
# The internal parameters can be used to warp a raw (distorted) image #
# to: #
# 1. An undistorted image (requires D and K) #
# 2. A rectified image (requires D, K, R) #
# The projection matrix P projects 3D points into the rectified image.#
#######################################################################
#######################################################################
# Operational Parameters #
#######################################################################
# These define the image region actually captured by the camera #
# driver. Although they affect the geometry of the output image, they #
# may be changed freely without recalibrating the camera. #
#######################################################################
# Copyright DB InfraGO AG and contributors
# SPDX-License-Identifier: CC0-1.0
#
# This message holds a collection of N-dimensional points, which may
# contain additional information such as normals, intensity, etc. The
# point data is stored as a binary blob, its layout described by the
# contents of the \"fields\" array.
#
# The point cloud data may be organized 2d (image-like) or 1d (unordered).
# Point clouds organized as 2d images may be produced by camera depth sensors
# such as stereo or time-of-flight.
# This message holds the status of an individual component of the robot.
# This message holds a collection of N-dimensional points, which may
# contain additional information such as normals, intensity, etc. The
# point data is stored as a binary blob, its layout described by the
# contents of the \"fields\" array.
#
# The point cloud data may be organized 2d (image-like) or 1d (unordered).
# Point clouds organized as 2d images may be produced by camera depth sensors
# such as stereo or time-of-flight.