Skip to content

Commit

Permalink
Launch gz_spawn_model from xml (#551)
Browse files Browse the repository at this point in the history
Spawn models from XML.
Signed-off-by: Carlos Agüero <[email protected]>
Co-authored-by: Addisu Z. Taddese <[email protected]>
  • Loading branch information
caguero authored May 24, 2024
1 parent 10c1bd2 commit d92c1bd
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 0 deletions.
1 change: 1 addition & 0 deletions ros_gz_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ install(FILES
install(FILES
"launch/gz_server.launch"
"launch/gz_server.launch.py"
"launch/gz_spawn_model.launch"
"launch/gz_spawn_model.launch.py"
"launch/ros_gz_sim.launch"
"launch/ros_gz_sim.launch.py"
Expand Down
28 changes: 28 additions & 0 deletions ros_gz_sim/launch/gz_spawn_model.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<launch>
<arg name="world" default="" />
<arg name="file" default="" />
<arg name="xml_string" default="" />
<arg name="topic" default="" />
<arg name="name" default="" />
<arg name="allow_renaming" default="False" />
<arg name="x" default="" />
<arg name="y" default="" />
<arg name="z" default="" />
<arg name="roll" default="" />
<arg name="pitch" default="" />
<arg name="yaw" default="" />
<gz_spawn_model
world="$(var world)"
file="$(var file)"
xml_string="$(var xml_string)"
topic="$(var topic)"
name="$(var name)"
allow_renaming="$(var allow_renaming)"
x="$(var x)"
y="$(var y)"
z="$(var z)"
roll="$(var roll)"
pitch="$(var pitch)"
yaw="$(var yaw)">
</gz_spawn_model>
</launch>
2 changes: 2 additions & 0 deletions ros_gz_sim/ros_gz_sim/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@

"""Actions module."""

from .gz_spawn_model import GzSpawnModel
from .gzserver import GzServer


__all__ = [
'GzSpawnModel',
'GzServer',
]
207 changes: 207 additions & 0 deletions ros_gz_sim/ros_gz_sim/actions/gz_spawn_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# Copyright 2024 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Module for the gz_spawn_model action."""

from typing import List
from typing import Optional

from launch.action import Action
from launch.actions import IncludeLaunchDescription
from launch.frontend import Entity, expose_action, Parser
from launch.launch_context import LaunchContext
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.some_substitutions_type import SomeSubstitutionsType
from launch.substitutions import PathJoinSubstitution
from launch_ros.substitutions import FindPackageShare


@expose_action('gz_spawn_model')
class GzSpawnModel(Action):
"""Action that executes a gz_spawn_model ROS node."""

def __init__(
self,
*,
world: Optional[SomeSubstitutionsType] = None,
file: Optional[SomeSubstitutionsType] = None,
xml_string: Optional[SomeSubstitutionsType] = None,
topic: Optional[SomeSubstitutionsType] = None,
name: Optional[SomeSubstitutionsType] = None,
allow_renaming: Optional[SomeSubstitutionsType] = None,
x: Optional[SomeSubstitutionsType] = None,
y: Optional[SomeSubstitutionsType] = None,
z: Optional[SomeSubstitutionsType] = None,
roll: Optional[SomeSubstitutionsType] = None,
pitch: Optional[SomeSubstitutionsType] = None,
yaw: Optional[SomeSubstitutionsType] = None,
**kwargs
) -> None:
"""
Construct a gz_spawn_model action.
All arguments are forwarded to `ros_gz_sim.launch.gz_spawn_model.launch.py`,
so see the documentation of that class for further details.
:param: world World name.
:param: file SDF filename.
:param: xml_string XML string.
:param: topic Get XML from this topic.
:param: name Name of the entity.
:param: allow_renaming Whether the entity allows renaming or not.
:param: x X coordinate.
:param: y Y coordinate.
:param: z Z coordinate.
:param: roll Roll orientation.
:param: pitch Pitch orientation.
:param: yaw Yaw orientation.
"""
super().__init__(**kwargs)
self.__world = world
self.__file = file
self.__xml_string = xml_string
self.__topic = topic
self.__name = name
self.__allow_renaming = allow_renaming
self.__x = x
self.__y = y
self.__z = z
self.__roll = roll
self.__pitch = pitch
self.__yaw = yaw

@classmethod
def parse(cls, entity: Entity, parser: Parser):
"""Parse gz_spawn_model."""
_, kwargs = super().parse(entity, parser)

world = entity.get_attr(
'world', data_type=str,
optional=True)

file = entity.get_attr(
'file', data_type=str,
optional=True)

xml_string = entity.get_attr(
'xml_string', data_type=str,
optional=True)

topic = entity.get_attr(
'topic', data_type=str,
optional=True)

name = entity.get_attr(
'name', data_type=str,
optional=True)

allow_renaming = entity.get_attr(
'allow_renaming', data_type=str,
optional=True)

x = entity.get_attr(
'x', data_type=str,
optional=True)

y = entity.get_attr(
'y', data_type=str,
optional=True)

z = entity.get_attr(
'z', data_type=str,
optional=True)

roll = entity.get_attr(
'roll', data_type=str,
optional=True)

pitch = entity.get_attr(
'pitch', data_type=str,
optional=True)

yaw = entity.get_attr(
'yaw', data_type=str,
optional=True)

if isinstance(world, str):
world = parser.parse_substitution(world)
kwargs['world'] = world

if isinstance(file, str):
file = parser.parse_substitution(file)
kwargs['file'] = file

if isinstance(xml_string, str):
xml_string = parser.parse_substitution(xml_string)
kwargs['xml_string'] = xml_string

if isinstance(topic, str):
topic = parser.parse_substitution(topic)
kwargs['topic'] = topic

if isinstance(name, str):
name = parser.parse_substitution(name)
kwargs['name'] = name

if isinstance(allow_renaming, str):
allow_renaming = parser.parse_substitution(allow_renaming)
kwargs['allow_renaming'] = allow_renaming

if isinstance(x, str):
x = parser.parse_substitution(x)
kwargs['x'] = x

if isinstance(y, str):
y = parser.parse_substitution(y)
kwargs['y'] = y

if isinstance(z, str):
z = parser.parse_substitution(z)
kwargs['z'] = z

if isinstance(roll, str):
roll = parser.parse_substitution(roll)
kwargs['roll'] = roll

if isinstance(pitch, str):
pitch = parser.parse_substitution(pitch)
kwargs['pitch'] = pitch

if isinstance(yaw, str):
yaw = parser.parse_substitution(yaw)
kwargs['yaw'] = yaw

return cls, kwargs

def execute(self, context: LaunchContext) -> Optional[List[Action]]:
"""Execute the action."""
gz_spawn_model_description = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[PathJoinSubstitution([FindPackageShare('ros_gz_sim'),
'launch',
'gz_spawn_model.launch.py'])]),
launch_arguments=[('world', self.__world),
('file', self.__file),
('xml_string', self.__xml_string),
('topic', self.__topic),
('name', self.__name),
('allow_renaming', self.__allow_renaming),
('x', self.__x),
('y', self.__y),
('z', self.__z),
('roll', self.__roll),
('pitch', self.__pitch),
('yaw', self.__yaw), ])

return [gz_spawn_model_description]

0 comments on commit d92c1bd

Please sign in to comment.