Skip to content

Commit

Permalink
[service introspection] generate service_event messages (#700)
Browse files Browse the repository at this point in the history
* add service event message

Signed-off-by: Brian Chen <brian.chen@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
  • Loading branch information
ihasdapie authored Feb 2, 2023
1 parent a46056c commit a63f32e
Show file tree
Hide file tree
Showing 31 changed files with 582 additions and 15 deletions.
1 change: 1 addition & 0 deletions rosidl_adapter/rosidl_adapter/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
SERVICE_REQUEST_RESPONSE_SEPARATOR = '---'
SERVICE_REQUEST_MESSAGE_SUFFIX = '_Request'
SERVICE_RESPONSE_MESSAGE_SUFFIX = '_Response'
SERVICE_EVENT_MESSAGE_SUFFIX = '_Event'

ACTION_REQUEST_RESPONSE_SEPARATOR = '---'
ACTION_GOAL_SUFFIX = '_Goal'
Expand Down
32 changes: 30 additions & 2 deletions rosidl_cmake/cmake/rosidl_generate_interfaces.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,49 @@ macro(rosidl_generate_interfaces target)
# afterwards all remaining interface files are .idl files
list(APPEND _idl_tuples ${_idl_adapter_tuples})

# to generate action interfaces, we need to depend on "action_msgs"
# Check for any action or service interfaces
# Which have implicit dependencies that need to be found
foreach(_tuple ${_interface_tuples})
# We use the parent directory name to identify if the interface is an action or service
string(REGEX REPLACE ".*:([^:]*)$" "\\1" _tuple_file "${_tuple}")
get_filename_component(_parent_dir "${_tuple_file}" DIRECTORY)
get_filename_component(_parent_dir ${_parent_dir} NAME)

if("${_parent_dir}" STREQUAL "action")
# Actions depend on the packages service_msgs and action_msgs
find_package(service_msgs QUIET)
if(NOT ${service_msgs_FOUND})
message(FATAL_ERROR
"Unable to generate action interface for '${_tuple_file}'. "
"In order to generate action interfaces you must add a depend tag "
"for 'service_msgs' in your package.xml.")
endif()
ament_export_dependencies(service_msgs)
list_append_unique(_ARG_DEPENDENCIES "service_msgs")
find_package(action_msgs QUIET)
if(NOT ${action_msgs_FOUND})
message(FATAL_ERROR
"Unable to generate action interface for '${_tuple_file}'. "
"In order to generate action interfaces you must add a depend tag "
"for 'action_msgs' in your package.xml.")
endif()
list_append_unique(_ARG_DEPENDENCIES "action_msgs")
ament_export_dependencies(action_msgs)
list_append_unique(_ARG_DEPENDENCIES "action_msgs")

# It is safe to break out of the loop since services only depend on service_msgs
# Which has already been found above
break()
elseif("${_parent_dir}" STREQUAL "srv")
# Services depend on service_msgs
find_package(service_msgs QUIET)
if(NOT ${service_msgs_FOUND})
message(FATAL_ERROR
"Unable to generate service interface for '${_tuple_file}'. "
"In order to generate service interfaces you must add a depend tag "
"for 'service_msgs' in your package.xml.")
endif()
ament_export_dependencies(service_msgs)
list_append_unique(_ARG_DEPENDENCIES "service_msgs")
endif()
endforeach()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES})
)
list(APPEND _generated_sources
"${_output_path}/${_parent_folder}/detail/${_header_name}__functions.c"
"${_output_path}/${_parent_folder}/detail/${_header_name}__type_support.c"
)
endforeach()

Expand All @@ -52,15 +53,18 @@ set(target_dependencies
"${rosidl_generator_c_BIN}"
${rosidl_generator_c_GENERATOR_FILES}
"${rosidl_generator_c_TEMPLATE_DIR}/action__type_support.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/action__type_support.c.em"
"${rosidl_generator_c_TEMPLATE_DIR}/idl.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/idl__functions.c.em"
"${rosidl_generator_c_TEMPLATE_DIR}/idl__functions.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/idl__struct.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/idl__type_support.c.em"
"${rosidl_generator_c_TEMPLATE_DIR}/idl__type_support.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/msg__functions.c.em"
"${rosidl_generator_c_TEMPLATE_DIR}/msg__functions.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/msg__struct.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/msg__type_support.h.em"
"${rosidl_generator_c_TEMPLATE_DIR}/srv__type_support.c.em"
"${rosidl_generator_c_TEMPLATE_DIR}/srv__type_support.h.em"
${rosidl_generate_interfaces_ABS_IDL_FILES}
${_dependency_files})
Expand Down
14 changes: 14 additions & 0 deletions rosidl_generator_c/resource/action__type_support.c.em
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@# Included from rosidl_generator_c/resource/idl__type_support.c.em
@{
TEMPLATE(
'srv__type_support.c.em',
package_name=package_name, service=action.send_goal_service,
interface_path=interface_path, include_directives=include_directives)
}@

@{
TEMPLATE(
'srv__type_support.c.em',
package_name=package_name, service=action.get_result_service,
interface_path=interface_path, include_directives=include_directives)
}@
21 changes: 21 additions & 0 deletions rosidl_generator_c/resource/idl__functions.c.em
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ TEMPLATE(
package_name=package_name, interface_path=interface_path,
message=service.response_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__functions.c.em',
package_name=package_name, interface_path=interface_path,
message=service.event_message, include_directives=include_directives)
}@
@[end for]@
@
@#######################################################################
Expand Down Expand Up @@ -109,6 +116,13 @@ TEMPLATE(
message=action.send_goal_service.response_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__functions.c.em',
package_name=package_name, interface_path=interface_path,
message=action.send_goal_service.event_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__functions.c.em',
Expand All @@ -123,6 +137,13 @@ TEMPLATE(
message=action.get_result_service.response_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__functions.c.em',
package_name=package_name, interface_path=interface_path,
message=action.get_result_service.event_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__functions.c.em',
Expand Down
20 changes: 20 additions & 0 deletions rosidl_generator_c/resource/idl__functions.h.em
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ TEMPLATE(
message=service.response_message)
}@

@{
TEMPLATE(
'msg__functions.h.em',
package_name=package_name, interface_path=interface_path,
message=service.event_message)
}@
@[end for]@
@
@#######################################################################
Expand Down Expand Up @@ -116,6 +122,13 @@ TEMPLATE(
message=action.send_goal_service.response_message)
}@

@{
TEMPLATE(
'msg__functions.h.em',
package_name=package_name, interface_path=interface_path,
message=action.send_goal_service.event_message)
}@

@{
TEMPLATE(
'msg__functions.h.em',
Expand All @@ -130,6 +143,13 @@ TEMPLATE(
message=action.get_result_service.response_message)
}@

@{
TEMPLATE(
'msg__functions.h.em',
package_name=package_name, interface_path=interface_path,
message=action.get_result_service.event_message)
}@

@{
TEMPLATE(
'msg__functions.h.em',
Expand Down
21 changes: 21 additions & 0 deletions rosidl_generator_c/resource/idl__struct.h.em
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ TEMPLATE(
message=service.response_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__struct.h.em',
package_name=package_name, interface_path=interface_path,
message=service.event_message, include_directives=include_directives)
}@

@[end for]@
@
@#######################################################################
Expand Down Expand Up @@ -113,6 +120,13 @@ TEMPLATE(
message=action.send_goal_service.response_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__struct.h.em',
package_name=package_name, interface_path=interface_path,
message=action.send_goal_service.event_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__struct.h.em',
Expand All @@ -127,6 +141,13 @@ TEMPLATE(
message=action.get_result_service.response_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__struct.h.em',
package_name=package_name, interface_path=interface_path,
message=action.get_result_service.event_message, include_directives=include_directives)
}@

@{
TEMPLATE(
'msg__struct.h.em',
Expand Down
70 changes: 70 additions & 0 deletions rosidl_generator_c/resource/idl__type_support.c.em
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// generated from rosidl_generator_c/resource/idl__type_support.c.em
// with input from @(package_name):@(interface_path)
// generated code does not contain a copyright notice
@
@#######################################################################
@# EmPy template for generating <idl>__type_support.c files
@#
@# Context:
@# - package_name (string)
@# - interface_path (Path relative to the directory named after the package)
@# - content (IdlContent, list of elements, e.g. Messages or Services)
@#######################################################################
@{
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
include_base = '/'.join(include_parts)

include_directives = {
'rosidl_typesupport_interface/macros.h',
include_base + '__type_support.h',
include_base + '__struct.h',
include_base + '__functions.h'}
}@

#include <string.h>

@[for header_file in include_directives]@
#include "@(header_file)"
@[end for]@

#ifdef __cplusplus
extern "C"
{
#endif

@#######################################################################
@# Handle service
@#######################################################################
@{
from rosidl_parser.definition import Service
}@
@[for service in content.get_elements_of_type(Service)]@
@{
TEMPLATE(
'srv__type_support.c.em',
package_name=package_name, service=service,
interface_path=interface_path, include_directives=include_directives)
}@

@[end for]@
@
@#######################################################################
@# Handle action
@#######################################################################
@{
from rosidl_parser.definition import Action
}@
@[for action in content.get_elements_of_type(Action)]@
@{
TEMPLATE(
'action__type_support.c.em',
package_name=package_name, action=action,
interface_path=interface_path, include_directives=include_directives)
}@

@[end for]@
#ifdef __cplusplus
}
#endif
10 changes: 10 additions & 0 deletions rosidl_generator_c/resource/msg__struct.h.em
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ from rosidl_parser.definition import FLOATING_POINT_TYPES
from rosidl_parser.definition import INTEGER_TYPES
from rosidl_parser.definition import NamespacedType
from rosidl_parser.definition import OCTET_TYPE
from rosidl_parser.definition import SERVICE_REQUEST_MESSAGE_SUFFIX
from rosidl_parser.definition import SERVICE_RESPONSE_MESSAGE_SUFFIX
from rosidl_generator_c import basetype_to_c
from rosidl_generator_c import idl_declaration_to_c
from rosidl_generator_c import idl_structure_type_sequence_to_c_typename
Expand Down Expand Up @@ -43,6 +45,14 @@ for member in message.structure.members:
'rosidl_runtime_c/u16string.h', [])
member_names.append(member.name)
elif isinstance(type_, NamespacedType):
if (
message.structure.namespaced_type.namespaces[-1] in ['action', 'srv'] and (
type_.name.endswith(SERVICE_REQUEST_MESSAGE_SUFFIX) or
type_.name.endswith(SERVICE_RESPONSE_MESSAGE_SUFFIX))
):
typename = type_.name.rsplit('_', 1)[0]
if typename == message.structure.namespaced_type.name.rsplit('_', 1)[0]:
continue
include_prefix = idl_structure_type_to_c_include_prefix(
type_, 'detail')
member_names = includes.setdefault(
Expand Down
Loading

0 comments on commit a63f32e

Please sign in to comment.