Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

translator from LaunchConfiguration to YML #86

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
68 changes: 68 additions & 0 deletions src/rosdiscover/ros2_translator/arch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from typing import Any, Dict, List
import argparse
import json
from launch import LaunchDescription, LaunchDescriptionEntity
from launch.launch_context import LaunchContext
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import IncludeLaunchDescription
from launch_ros.actions import Node
NodeDescription = Dict[str, Any]


class NodeDescriptionExtractor:
def __init__(self) -> None:
self.__unnamed_nodes = 0

def _node_to_description(self, node: Node) -> NodeDescription:
# Note: The code directly accesses variables since there are no getters for
# these specific variables in launch.
# This code might break with changed implementations of launch
output: NodeDescription = {}
if node._Node__node_name:
name_entry = node._Node__node_name
output['name'] = node._Node__node_name
else:
name_entry = f'unknown{self.__unnamed_nodes}'
self.__unnamed_nodes += 1
output['name'] = name_entry
if node._Node__node_namespace:
output['namespace'] = node._Node__node_namespace
if node._Node__node_executable:
output['executable'] = node._Node__node_executable
if node._Node__package:
output['package'] = node._Node__package
return output

def _extract_descriptions(self,
entity: LaunchDescriptionEntity,
context: LaunchContext
) -> List[NodeDescription]:
descriptions: List[NodeDescription] = []
if isinstance(entity, LaunchDescription) or isinstance(entity, IncludeLaunchDescription): # noqa
for sub_entity in entity.visit(context):
descriptions += self._extract_descriptions(sub_entity, context)
elif isinstance(entity, Node):
descriptions = [self._node_to_description(entity)]
else:
print(f'UNKNOWN ENTITY: {type(entity)}')
return descriptions

def extract(self, filename: str) -> List[NodeDescription]:
context = LaunchContext()
launch_description_source = \
PythonLaunchDescriptionSource(args.launchfile)
launch_description = LaunchDescription([
IncludeLaunchDescription(launch_description_source)
])
return self._extract_descriptions(launch_description, context)


if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Find nodes')
parser.add_argument('launchfile', type=str)
parser.add_argument('--output', type=str, default='arch.json')
args = parser.parse_args()
extractor = NodeDescriptionExtractor()
output = extractor.extract(args.launchfile)
with open(args.output, 'w') as f:
f.write(json.dumps(output, indent=2))