-
Notifications
You must be signed in to change notification settings - Fork 46
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
Generate msg/srv from within an 'action' directory/module #15
Generate msg/srv from within an 'action' directory/module #15
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apojomovsky I left a few comments !
@@ -105,15 +105,15 @@ const rosidl_message_type_support_t * | |||
ROSIDL_GET_MSG_TYPE_SUPPORT(@(pkg_name), @(subfolder), @(spec.msg_name)); | |||
|
|||
int8_t | |||
_register_msg_type__@(type_name)(PyObject * pymodule) | |||
_register_msg_type__@(type_name)__@(subfolder)(PyObject * pymodule) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apojomovsky consider reversing the order of interpolated variables, as in _register_msg_type__@(subfolder)_@(type_name)(PyObject * pymodule)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you're right! Thanks for the suggestion, done!
|
||
int8_t | ||
_register_srv_type__@(type_name)(PyObject * pymodule) | ||
_register_srv_type__@(type_name)__@(subfolder)(PyObject * pymodule) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apojomovsky same as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, thanks!
@[ if spec.base_type.pkg_name != field.type.pkg_name]@ | ||
ROSIDL_GENERATOR_C_IMPORT | ||
@[ end if]@ | ||
PyObject * @(field.type.pkg_name)__@(lowercase_field_type)__convert_to_py(void * raw_ros_message); | ||
PyObject * @(field.type.pkg_name)__@(subfolder)__@(lowercase_field_type)__convert_to_py(void * raw_ros_message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apojomovsky I don't think this will be true in general e.g. a _Request
message that is part of a service definition below srv/
could have a field that's a message described in a message definition below msg/
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I just restored this line. Thanks!
Thanks for the review @hidmic , I just finished addressing your comments. Could you PTAL? |
@@ -65,6 +67,15 @@ foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) | |||
list(APPEND _generated_srv_py_files | |||
"${_output_path}/${_parent_folder}/_${_module_name}.py" | |||
) | |||
elseif(_parent_folder STREQUAL "action") | |||
if("_${_module_name}_s.c" MATCHES "(.*)__response(.*)" OR "_${_module_name}_s.c" MATCHES "(.*)__request(.*)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works for services, but not messages. After adding action/Something.msg
in test_msgs I see this traceback
undefined symbol: test_msgs__action__something__convert_from_py
342: (test_publisher) pid 7968: ['/usr/bin/python3', '/home/developer/workspaces/ros2-dev0/src/ros2/system_tests/test_communication/test/publisher_py.py', 'BoundedArrayPrimitives', '/test_time_23_08_40'] (stderr > stdout, all > console)
342: (test_subscriber) pid 7969: ['/home/developer/workspaces/ros2-dev0/build/test_communication/test_subscriber_cpp', 'BoundedArrayPrimitives', '/test_time_23_08_40'] (stderr > stdout, all > console)
342: [test_publisher] exception in talker:
342: [test_publisher] Traceback (most recent call last):
342: [test_publisher] File "/home/developer/workspaces/ros2-dev0/install/rosidl_generator_py/lib/python3.6/site-packages/rosidl_generator_py/import_type_support_impl.py", line 42, in import_type_support
342: [test_publisher] return importlib.import_module(module_name, package=pkg_name)
342: [test_publisher] File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
342: [test_publisher] return _bootstrap._gcd_import(name[level:], package, level)
342: [test_publisher] File "<frozen importlib._bootstrap>", line 994, in _gcd_import
342: [test_publisher] File "<frozen importlib._bootstrap>", line 971, in _find_and_load
342: [test_publisher] File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
342: [test_publisher] File "<frozen importlib._bootstrap>", line 658, in _load_unlocked
342: [test_publisher] File "<frozen importlib._bootstrap>", line 571, in module_from_spec
342: [test_publisher] File "<frozen importlib._bootstrap_external>", line 922, in create_module
342: [test_publisher] File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
342: [test_publisher] ImportError: /home/developer/workspaces/ros2-dev0/install/test_msgs/lib/python3.6/site-packages/test_msgs/test_msgs_s__rosidl_typesupport_c.cpython-36m-x86_64-linux-gnu.so: undefined symbol: test_msgs__action__something__convert_from_py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing this condition gets a little further,
get_filename_component(_ext "${_idl_file}" EXT)
# C files generated for <msg>.msg, <service>_Request.msg and <service>_Response.msg but not <service>.srv
if(_ext STREQUAL ".msg")
list(APPEND _generated_action_c_files
"${_output_path}/${_parent_folder}/_${_module_name}_s.c"
)
endif()
list(APPEND _generated_action_py_files
"${_output_path}/${_parent_folder}/_${_module_name}.py"
)
Edit: NVM, the test communication problem is not caused by this PR
Though test_communication
still fails with
18: [test_publisher] exception in talker:
18: [test_publisher] Traceback (most recent call last):
18: [test_publisher] File "/home/developer/workspaces/ros2-dev0/src/ros2/system_tests/test_communication/test/publisher_py.py", line 63, in <module>
18: [test_publisher] number_of_cycles=args.number_of_cycles)
18: [test_publisher] File "/home/developer/workspaces/ros2-dev0/src/ros2/system_tests/test_communication/test/publisher_py.py", line 27, in talker
18: [test_publisher] msg_mod = getattr(module, message_name)
18: [test_publisher] AttributeError: module 'test_msgs.msg' has no attribute 'Something'
18: [test_subscriber] exception in subscriber:
18: [test_subscriber] Traceback (most recent call last):
18: [test_subscriber] File "/home/developer/workspaces/ros2-dev0/src/ros2/system_tests/test_communication/test/subscriber_py.py", line 81, in <module>
18: [test_subscriber] listener(message_name=args.message_name, namespace=args.namespace)
18: [test_subscriber] File "/home/developer/workspaces/ros2-dev0/src/ros2/system_tests/test_communication/test/subscriber_py.py", line 47, in listener
18: [test_subscriber] msg_mod = getattr(module, message_name)
18: [test_subscriber] AttributeError: module 'test_msgs.msg' has no attribute 'Something'
but I'm not yet sure if the problem is here or there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 98d630c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested with
Repos file
repositories:
ros2/rcl_interfaces:
type: git
url: https://github.com/ros2/rcl_interfaces.git
version: sloretz/msg_srv_in_action
ros2/rosidl:
type: git
url: https://github.com/ros2/rosidl.git
version: hidmic/prepare_for_action_generation
ros2/rosidl_dds:
type: git
url: https://github.com/ros2/rosidl_dds.git
version: hidmic/prepare_for_action_generation
ros2/rosidl_python:
type: git
url: https://github.com/ros2/rosidl_python.git
version: apojomovsky/allow_generating_msg_and_srv_in_action
ros2/rosidl_typesupport:
type: git
url: https://github.com/ros2/rosidl_typesupport.git
version: hidmic/prepare_for_action_generation
ros2/rosidl_typesupport_connext:
type: git
url: https://github.com/ros2/rosidl_typesupport_connext.git
version: hidmic/subfolder_aware_srv_generation
ros2/rosidl_typesupport_fastrtps:
type: git
url: https://github.com/ros2/rosidl_typesupport_fastrtps.git
version: apojomovsky/subfolder_aware_srv_generation
ros2/rosidl_typesupport_opensplice:
type: git
url: https://github.com/ros2/rosidl_typesupport_opensplice.git
version: sservulo/prepare_for_action_generation
ros2/system_tests:
type: git
url: https://github.com/ros2/system_tests.git
version: hidmic/namespace-messages-with-subfolder
Publisher
from time import sleep
import rclpy
from test_msgs.action import Something
# We do not recommend this style as ROS 2 provides timers for this purpose,
# and it is recommended that all nodes call a variation of spin.
# This example is only included for completeness because it is similar to examples in ROS 1.
# For periodic publication please see the other examples using timers.
def main(args=None):
rclpy.init(args=args)
node = rclpy.create_node('minimal_publisher')
publisher = node.create_publisher(Something, 'topic')
msg = Something()
i = 0
while rclpy.ok():
msg.string_value = 'Hello World: %d' % i
i += 1
node.get_logger().info('Publishing: "%s"' % msg.string_value)
publisher.publish(msg)
sleep(0.5) # seconds
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Subscriber
import rclpy
from test_msgs.action import Something
g_node = None
def chatter_callback(msg):
global g_node
g_node.get_logger().info(
'I heard: "%s"' % msg.string_value)
def main(args=None):
global g_node
rclpy.init(args=args)
g_node = rclpy.create_node('minimal_subscriber')
subscription = g_node.create_subscription(Something, 'topic', chatter_callback)
subscription # prevent unused variable warning
while rclpy.ok():
rclpy.spin_once(g_node)
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
g_node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Service Client
from test_msgs.action import Primitives
import rclpy
def main(args=None):
rclpy.init(args=args)
node = rclpy.create_node('minimal_client')
cli = node.create_client(Primitives, 'add_two_ints')
req = Primitives.Request()
req.int8_value = 41
req.int16_value = 1
while not cli.wait_for_service(timeout_sec=1.0):
node.get_logger().info('service not available, waiting again...')
future = cli.call_async(req)
rclpy.spin_until_future_complete(node, future)
if future.result() is not None:
node.get_logger().info(
'Result of add_two_ints: for %d + %d = %d' %
(req.int8_value, req.int16_value, future.result().int32_value))
else:
node.get_logger().info('Service call failed %r' % (future.exception(),))
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Service server
from test_msgs.action import Primitives
import rclpy
g_node = None
def add_two_ints_callback(request, response):
global g_node
response.int32_value = request.int8_value + request.int16_value
g_node.get_logger().info(
'Incoming request\na: %d b: %d' % (request.int8_value, request.int16_value))
return response
def main(args=None):
global g_node
rclpy.init(args=args)
g_node = rclpy.create_node('minimal_service')
srv = g_node.create_service(Primitives, 'add_two_ints', add_two_ints_callback)
while rclpy.ok():
rclpy.spin_once(g_node)
# Destroy the service attached to the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
g_node.destroy_service(srv)
rclpy.shutdown()
if __name__ == '__main__':
main()
Ok, given that we have green light I'm proceeding to merge this and its related PRs |
Closes #13 .
This PR allows the generation of messages and services that are defined in the module
action
.It depends on ros2/rosidl#308 , ros2/rosidl_dds#44 and ros2/rosidl_typesupport#33 to compile successfully.
It was tested with the definitions found in this rcl_interfaces' branch .
connects to ros2/rosidl#301