Skip to content

Commit

Permalink
Launch ros_gz_bridge from xml (#550)
Browse files Browse the repository at this point in the history
* Add gzserver with ability to load an SDF file or string

Signed-off-by: Addisu Z. Taddese <[email protected]>
  • Loading branch information
caguero authored May 23, 2024
1 parent ac0b1a5 commit 10c1bd2
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ros_gz_bridge/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ find_package(gz-transport REQUIRED)
find_package(gz_msgs_vendor REQUIRED)
find_package(gz-msgs REQUIRED)

# Install the python module for this package
ament_python_install_package(${PROJECT_NAME})

set(GZ_MSGS_VERSION_FULL ${gz-msgs_VERSION})

set(BRIDGE_MESSAGE_TYPES
Expand Down
16 changes: 16 additions & 0 deletions ros_gz_bridge/launch/ros_gz_bridge.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<launch>
<arg name="config_file" default="" />
<arg name="container_name" default="ros_gz_container" />
<arg name="namespace" default="" />
<arg name="use_composition" default="False" />
<arg name="use_respawn" default="False" />
<arg name="log_level" default="info" />
<ros_gz_bridge
config_file="$(var config_file)"
container_name="$(var container_name)"
namespace="$(var namespace)"
use_composition="$(var use_composition)"
use_respawn="$(var use_respawn)"
log_level="$(var log_level)">
</ros_gz_bridge>
</launch>
4 changes: 4 additions & 0 deletions ros_gz_bridge/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@

<author>Shivesh Khaitan</author>
<author>Louise Poubel</author>
<author email="[email protected]">Carlos Agüero</author>

<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>ament_cmake_python</buildtool_depend>
<buildtool_depend>pkg-config</buildtool_depend>
<buildtool_depend>rosidl_pycommon</buildtool_depend>

<depend>actuator_msgs</depend>
<depend>geometry_msgs</depend>
<depend>gps_msgs</depend>
<depend>launch</depend>
<depend>launch_ros</depend>
<depend>nav_msgs</depend>
<depend>rclcpp</depend>
<depend>rclcpp_components</depend>
Expand Down
Empty file.
6 changes: 6 additions & 0 deletions ros_gz_bridge/ros_gz_bridge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@

from rosidl_pycommon import expand_template

from . import actions

__all__ = [
'actions',
]


@dataclass
class MessageMapping:
Expand Down
22 changes: 22 additions & 0 deletions ros_gz_bridge/ros_gz_bridge/actions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 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.

"""Actions module."""

from .ros_gz_bridge import RosGzBridge


__all__ = [
'RosGzBridge',
]
135 changes: 135 additions & 0 deletions ros_gz_bridge/ros_gz_bridge/actions/ros_gz_bridge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# 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 ros_gz bridge 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('ros_gz_bridge')
class RosGzBridge(Action):
"""Action that executes a ros_gz bridge ROS [composable] node."""

def __init__(
self,
*,
config_file: Optional[SomeSubstitutionsType] = None,
container_name: Optional[SomeSubstitutionsType] = None,
namespace: Optional[SomeSubstitutionsType] = None,
use_composition: Optional[SomeSubstitutionsType] = None,
use_respawn: Optional[SomeSubstitutionsType] = None,
log_level: Optional[SomeSubstitutionsType] = None,
**kwargs
) -> None:
"""
Construct a ros_gz bridge action.
All arguments are forwarded to `ros_gz_bridge.launch.ros_gz_bridge.launch.py`,
so see the documentation of that class for further details.
:param: config_file YAML config file.
:param: container_name Name of container that nodes will load in if use composition.
:param: namespace Top-level namespace.
:param: use_composition Use composed bringup if True.
:param: use_respawn Whether to respawn if a node crashes (when composition is disabled).
:param: log_level Log level.
"""
super().__init__(**kwargs)
self.__config_file = config_file
self.__container_name = container_name
self.__namespace = namespace
self.__use_composition = use_composition
self.__use_respawn = use_respawn
self.__log_level = log_level

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

config_file = entity.get_attr(
'config_file', data_type=str,
optional=False)

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

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

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

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

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

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

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

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

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

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

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

return cls, kwargs

def execute(self, context: LaunchContext) -> Optional[List[Action]]:
"""Execute the action."""
ros_gz_bridge_description = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[PathJoinSubstitution([FindPackageShare('ros_gz_bridge'),
'launch',
'ros_gz_bridge.launch.py'])]),
launch_arguments=[('config_file', self.__config_file),
('container_name', self.__container_name),
('namespace', self.__namespace),
('use_composition', self.__use_composition),
('use_respawn', self.__use_respawn),
('log_level', self.__log_level), ])

return [ros_gz_bridge_description]
3 changes: 3 additions & 0 deletions ros_gz_bridge/setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[options.entry_points]
launch.frontend.launch_extension =
ros_gz_bridge = ros_gz_bridge
1 change: 1 addition & 0 deletions ros_gz_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ install(FILES
"launch/gz_server.launch"
"launch/gz_server.launch.py"
"launch/gz_spawn_model.launch.py"
"launch/ros_gz_sim.launch"
"launch/ros_gz_sim.launch.py"
"launch/ros_gz_spawn_model.launch.py"
DESTINATION share/${PROJECT_NAME}/launch
Expand Down
24 changes: 24 additions & 0 deletions ros_gz_sim/launch/ros_gz_sim.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<launch>
<arg name="config_file" default="" />
<arg name="container_name" default="ros_gz_container" />
<arg name="namespace" default="" />
<arg name="use_composition" default="False" />
<arg name="use_respawn" default="False" />
<arg name="log_level" default="info" />
<arg name="world_sdf_file" default="empty.sdf" />
<arg name="world_sdf_string" default="" />
<gz_server
world_sdf_file="$(var world_sdf_file)"
world_sdf_string="$(var world_sdf_string)"
container_name="$(var container_name)"
use_composition="$(var use_composition)">
</gz_server>
<ros_gz_bridge
config_file="$(var config_file)"
container_name="$(var container_name)"
namespace="$(var namespace)"
use_composition="$(var use_composition)"
use_respawn="$(var use_respawn)"
log_level="$(var log_level)">
</ros_gz_bridge>
</launch>

0 comments on commit 10c1bd2

Please sign in to comment.