Skip to content

Commit

Permalink
Merge pull request #17 from v0-e/rust-based-codegen
Browse files Browse the repository at this point in the history
Alternative gen for .msg and conversion headers
  • Loading branch information
jpbusch authored Jun 17, 2024
2 parents 428f3bb + 4b29035 commit e5beb17
Show file tree
Hide file tree
Showing 36 changed files with 4,704 additions and 18 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ jobs:
matrix:
include:
- message: cam
script: ./utils/codegen/asn1ToRosMsg.py asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn asn1/raw/cam_en302637_2/cdd/ITS-Container.asn -o etsi_its_msgs/etsi_its_cam_msgs/msg
script: ./utils/codegen/codegen-py/asn1ToRosMsg.py asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn asn1/raw/cam_en302637_2/cdd/ITS-Container.asn -o etsi_its_msgs/etsi_its_cam_msgs/msg
- message: denm
script: ./utils/codegen/asn1ToRosMsg.py asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn asn1/raw/denm_en302637_3/cdd/ITS-Container.asn -o etsi_its_msgs/etsi_its_denm_msgs/msg
script: ./utils/codegen/codegen-py/asn1ToRosMsg.py asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn asn1/raw/denm_en302637_3/cdd/ITS-Container.asn -o etsi_its_msgs/etsi_its_denm_msgs/msg

steps:
- name: Checkout code
Expand Down Expand Up @@ -84,9 +84,9 @@ jobs:
matrix:
include:
- message: cam
script: ./utils/codegen/asn1ToConversionHeader.py asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn asn1/raw/cam_en302637_2/cdd/ITS-Container.asn -t cam -o etsi_its_conversion/etsi_its_cam_conversion/include/etsi_its_cam_conversion
script: ./utils/codegen/codegen-py/asn1ToConversionHeader.py asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn asn1/raw/cam_en302637_2/cdd/ITS-Container.asn -t cam -o etsi_its_conversion/etsi_its_cam_conversion/include/etsi_its_cam_conversion
- message: denm
script: ./utils/codegen/asn1ToConversionHeader.py asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn asn1/raw/denm_en302637_3/cdd/ITS-Container.asn -t denm -o etsi_its_conversion/etsi_its_denm_conversion/include/etsi_its_denm_conversion
script: ./utils/codegen/codegen-py/asn1ToConversionHeader.py asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn asn1/raw/denm_en302637_3/cdd/ITS-Container.asn -t denm -o etsi_its_conversion/etsi_its_denm_conversion/include/etsi_its_denm_conversion

steps:
- name: Checkout code
Expand All @@ -107,4 +107,4 @@ jobs:
echo "Code generation script resulted in changes to the repository"
git diff
exit 1
fi
fi
8 changes: 4 additions & 4 deletions .gitlab-ci.codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ etsi_its_cam_msgs:
needs: []
script:
- >
./utils/codegen/asn1ToRosMsg.py
./utils/codegen/codegen-py/asn1ToRosMsg.py
asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn
asn1/raw/cam_en302637_2/cdd/ITS-Container.asn
-o etsi_its_msgs/etsi_its_cam_msgs/msg
Expand All @@ -73,7 +73,7 @@ etsi_its_denm_msgs:
needs: []
script:
- >
./utils/codegen/asn1ToRosMsg.py
./utils/codegen/codegen-py/asn1ToRosMsg.py
asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn
asn1/raw/denm_en302637_3/cdd/ITS-Container.asn
-o etsi_its_msgs/etsi_its_denm_msgs/msg
Expand All @@ -85,7 +85,7 @@ etsi_its_cam_conversion:
needs: []
script:
- >
./utils/codegen/asn1ToConversionHeader.py
./utils/codegen/codegen-py/asn1ToConversionHeader.py
asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn
asn1/raw/cam_en302637_2/cdd/ITS-Container.asn
-t cam
Expand All @@ -97,7 +97,7 @@ etsi_its_denm_conversion:
needs: []
script:
- >
./utils/codegen/asn1ToConversionHeader.py
./utils/codegen/codegen-py/asn1ToConversionHeader.py
asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn
asn1/raw/denm_en302637_3/cdd/ITS-Container.asn
-t denm
Expand Down
66 changes: 62 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"name": "CAM asn1ToRosMsg",
"type": "python",
"request": "launch",
"program": "utils/codegen/asn1ToRosMsg.py",
"program": "utils/codegen/codegen-py/asn1ToRosMsg.py",
"args": [
"asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn",
"asn1/raw/cam_en302637_2/cdd/ITS-Container.asn",
Expand All @@ -48,7 +48,7 @@
"name": "DENM asn1ToRosMsg",
"type": "python",
"request": "launch",
"program": "utils/codegen/asn1ToRosMsg.py",
"program": "utils/codegen/codegen-py/asn1ToRosMsg.py",
"args": [
"asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn",
"asn1/raw/denm_en302637_3/cdd/ITS-Container.asn",
Expand All @@ -62,7 +62,7 @@
"name": "CAM asn1ToConversionHeader",
"type": "python",
"request": "launch",
"program": "utils/codegen/asn1ToConversionHeader.py",
"program": "utils/codegen/codegen-py/asn1ToConversionHeader.py",
"args": [
"asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn",
"asn1/raw/cam_en302637_2/cdd/ITS-Container.asn",
Expand All @@ -77,7 +77,65 @@
"name": "DENM asn1ToConversionHeader",
"type": "python",
"request": "launch",
"program": "utils/codegen/asn1ToConversionHeader.py",
"program": "utils/codegen/codegen-py/asn1ToConversionHeader.py",
"args": [
"asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn",
"asn1/raw/denm_en302637_3/cdd/ITS-Container.asn",
"-t", "denm",
"-o", "etsi_its_conversion/etsi_its_denm_conversion/include/etsi_its_denm_conversion"
],
"console": "integratedTerminal",
"justMyCode": true
},

{
"name": "CAM asn1ToRosMsg (rgen)",
"type": "python",
"request": "launch",
"program": "utils/codegen/codegen-rust/asn1ToRosMsg.py",
"args": [
"asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn",
"asn1/raw/cam_en302637_2/cdd/ITS-Container.asn",
"-o", "etsi_its_msgs/etsi_its_cam_msgs/msg"
],
"console": "integratedTerminal",
"justMyCode": true
},

{
"name": "DENM asn1ToRosMsg (rgen)",
"type": "python",
"request": "launch",
"program": "utils/codegen/codegen-rust/asn1ToRosMsg.py",
"args": [
"asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn",
"asn1/raw/denm_en302637_3/cdd/ITS-Container.asn",
"-o", "etsi_its_msgs/etsi_its_denm_msgs/msg"
],
"console": "integratedTerminal",
"justMyCode": true
},

{
"name": "CAM asn1ToConversionHeader (rgen)",
"type": "python",
"request": "launch",
"program": "utils/codegen/codegen-rust/asn1ToConversionHeader.py",
"args": [
"asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn",
"asn1/raw/cam_en302637_2/cdd/ITS-Container.asn",
"-t", "cam",
"-o", "etsi_its_conversion/etsi_its_cam_conversion/include/etsi_its_cam_conversion"
],
"console": "integratedTerminal",
"justMyCode": true
},

{
"name": "DENM asn1ToConversionHeader (rgen)",
"type": "python",
"request": "launch",
"program": "utils/codegen/codegen-rust/asn1ToConversionHeader.py",
"args": [
"asn1/raw/denm_en302637_3/DENM-PDU-Descriptions.asn",
"asn1/raw/denm_en302637_3/cdd/ITS-Container.asn",
Expand Down
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,17 @@ The ROS message files are auto-generated based on the [ASN.1 definitions](https:

```bash
# etsi_its_messages$
./utils/codegen/asn1ToRosMsg.py \
./utils/codegen/codegen-py/asn1ToRosMsg.py \
asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn \
asn1/raw/cam_en302637_2/cdd/ITS-Container.asn \
-o etsi_its_msgs/etsi_its_cam_msgs/msg
```

Note that an alternative Rust-based code generation is currently being tested, which might offer better support for more complex message types such as SPATEM/MAPEM or CPM.

```bash
# etsi_its_messages$
./utils/codegen/codegen-rust/asn1ToRosMsg.py \
asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn \
asn1/raw/cam_en302637_2/cdd/ITS-Container.asn \
-o etsi_its_msgs/etsi_its_cam_msgs/msg
Expand Down Expand Up @@ -179,7 +189,18 @@ The C++ conversion functions are auto-generated based on the [ASN.1 definitions]

```bash
# etsi_its_messages$
./utils/codegen/asn1ToConversionHeader.py \
./utils/codegen/codegen-py/asn1ToConversionHeader.py \
asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn \
asn1/raw/cam_en302637_2/cdd/ITS-Container.asn \
-t cam \
-o etsi_its_conversion/etsi_its_cam_conversion/include/etsi_its_cam_conversion
```

Note that an alternative Rust-based code generation is currently being tested, which might offer better support for more complex message types such as SPATEM/MAPEM or CPM.

```bash
# etsi_its_messages$
./utils/codegen/codegen-rust/asn1ToConversionHeader.py \
asn1/raw/cam_en302637_2/CAM-PDU-Descriptions.asn \
asn1/raw/cam_en302637_2/cdd/ITS-Container.asn \
-t cam \
Expand All @@ -191,9 +212,6 @@ The C++ conversion functions are auto-generated based on the [ASN.1 definitions]

All *etsi_its_messages* packages are released as official ROS / ROS 2 packages and can easily be installed via a package manager.

> [!WARNING]
> The initial release may not have been synced to the package managers yet. In the meantime, please refer to installation from source as shown below.
```bash
sudo apt update
sudo apt install ros-$ROS_DISTRO-etsi-its-messages
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
103 changes: 103 additions & 0 deletions utils/codegen/codegen-rust/asn1ToConversionHeader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python3

# ==============================================================================
# MIT License
#
# Copyright (c) 2023 Institute for Automotive Engineering (ika), RWTH Aachen University
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ==============================================================================

import argparse
import glob
import os
import re
import shutil
import subprocess
import tempfile

def parseCli():
"""Parses script's CLI arguments.
Returns:
argparse.Namespace: arguments
"""

parser = argparse.ArgumentParser(
description="Creates conversion headers from ASN1 definitions.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument("files", type=str, nargs="+", help="ASN1 files")
parser.add_argument("-o", "--output-dir", type=str, required=True, help="output directory")
parser.add_argument("-td", "--temp-dir", type=str, default=None, help="temporary directory for mounting files to container; uses tempfile by default")
parser.add_argument("-t", "--type", type=str, required=True, help="ASN1 type")
parser.add_argument("-di", "--docker-image", type=str, default="ghcr.io/ika-rwth-aachen/etsi_its_messages:rgen", help="rgen Docker image")

args = parser.parse_args()

return args

def main():

args = parseCli()

# create output directory
os.makedirs(args.output_dir, exist_ok=True)

# create temporary directories for running rgen in docker container
with tempfile.TemporaryDirectory() as temp_input_dir:
with tempfile.TemporaryDirectory() as temp_output_dir:

if args.temp_dir is None:
container_input_dir = temp_input_dir
container_output_dir = temp_output_dir
else:
container_input_dir = os.path.join(args.temp_dir, "input")
container_output_dir = os.path.join(args.temp_dir, "output")
os.makedirs(container_input_dir, exist_ok=True)
os.makedirs(container_output_dir, exist_ok=True)

# copy input asn1 files to temporary directory
for f in args.files:
shutil.copy(f, container_input_dir)

# run rgen docker container to generate conversion headers
subprocess.run(["docker", "run", "--rm", "-u", f"{os.getuid()}:{os.getgid()}", "-v", f"{container_input_dir}:/input:ro", "-v", f"{container_output_dir}:/output", args.docker_image, 'conversion-headers', args.message], check=True)

# add auto-gen info, remove in-file type and message name info (optional)
for f in glob.glob(os.path.join(container_output_dir, "*.h")):
with open(f, "r") as file:
msg = file.read()

msg = re.sub(r"^////\s([\w-]+)\s.*\b",
"// --- Auto-generated by asn1ToConversionHeader.py -----------------------------",
msg,
flags=re.MULTILINE)

with open(f, "w") as file:
file.write(msg)

# move generated conversion headers to output directories
for f in glob.glob(os.path.join(container_output_dir, "*.h")):
shutil.move(f, os.path.join(args.output_dir, os.path.basename(f)))


if __name__ == "__main__":

main()
Loading

0 comments on commit e5beb17

Please sign in to comment.