From cfd073bbcb6857193ba3f7c24f038b98e6b55885 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Tue, 20 Jul 2021 09:49:07 +0200 Subject: [PATCH 1/4] Update galactic memory handling tutorial --- .../advanced/handling_type_memory/index.md | 129 +++++++++++++++++- 1 file changed, 126 insertions(+), 3 deletions(-) diff --git a/_docs/tutorials/advanced/handling_type_memory/index.md b/_docs/tutorials/advanced/handling_type_memory/index.md index 6bc61fa6..c2707dca 100644 --- a/_docs/tutorials/advanced/handling_type_memory/index.md +++ b/_docs/tutorials/advanced/handling_type_memory/index.md @@ -7,6 +7,10 @@ This page aims to explain how to handle messages and types memory in micro-ROS. First of all, since the micro-ROS user is in an embedded C99 environment, it is important to be aware of what messages and ROS 2 types are being used in order to handle memory correctly. +The micro-ROS type memory handling has changed in the latest micro-ROS Galactic distribution, two approaches are presented in this tutorial: micro-ROS Foxy and micro-ROS Galactic and beyond. + +# micro-ROS Foxy + By watching the `.msg` or `.srv` of the types used in a micro-ROS application, you can determine the type of each member. Currently, the following types are supported: - Basic type - Array type @@ -58,7 +62,7 @@ In the case of `MyType.msg`, the `values` sequence member is represented in C99 ```c typedef struct rosidl_runtime_c__int32__Sequence -{ +{ int32_t* data; /* The pointer to an array of int32 */ size_t size; /* The number of valid items in data */ size_t capacity; /* The number of allocated items in data */ @@ -94,7 +98,7 @@ for(int32_t i = 0; i < 3; i++){ ## Compound types in micro-ROS -When dealing with a compound type, the user should recursively inspect the types in order to determine how to handle each internal member. +When dealing with a compound type, the user should recursively inspect the types in order to determine how to handle each internal member. For example in the `MyType.msg` example, the `header` member has the following structure: @@ -148,7 +152,7 @@ int8[10] coefficients string name ``` -In this case, the generated typesupport will be: +In this case, the generated typesupport will be: ```c typedef struct mypackage__msg__MyComplexType @@ -191,3 +195,122 @@ for(int32_t i = 0; i < 3; i++){ mymsg.multiheaders.size++; } ``` + +# micro-ROS Galactic + +Due to the inclusion of [`rosidl_typesupport_introspection_c`](https://github.com/ros2/rosidl/tree/master/rosidl_typesupport_introspection_c) in micro-ROS Galactic distribution, an automated memory handling for micro-ROS types is available. The tools related to this feature are available in the package [`micro_ros_utilities`](https://github.com/micro-ROS/micro_ros_utilities). + +The documentation of the package [`micro_ros_utilities`](https://github.com/micro-ROS/micro_ros_utilities) are available [here](https://micro.ros.org/docs/api/utils/). + +This package is able to auto-assign memory to a certain message struct using default dynamic memory allocators, for example, using the previouly declated type: + +```c +mypackage__msg__MyType mymsg; + +static micro_ros_utilities_memory_conf_t conf = {0}; + +bool success = micro_ros_utilities_create_message_memory( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyType), + &mymsg, + conf +); +``` + +This code will init all the string and sequences recursively in `MyType` type. The size of this memory slots will be by default the ones in [`micro_ros_utilities_memory_conf_default`](https://github.com/micro-ROS/micro_ros_utilities/blob/c829971bd33ac1f14a94aa722476110b4b59eaf9/include/micro_ros_utilities/type_utilities.h#L51), that is: +- String will have 20 characters +- ROS 2 types sequences will have a length of 5 +- Basic types sequences will have a length of 5 + +This defaults can be overriden using: + +```c +mypackage__msg__MyType mymsg; + +static micro_ros_utilities_memory_conf_t conf = {0}; + +conf.max_string_capacity = 50; +conf.max_ros2_type_sequence_capacity = 5; +conf.max_basic_type_sequence_capacity = 5; + +bool success = micro_ros_utilities_create_message_memory( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyType), + &mymsg, + conf +); +``` + +A complex rules approach can be used as in the following example: + +```c +mypackage__msg__MyComplexType mymsg; + +static micro_ros_utilities_memory_conf_t conf = {0}; + +micro_ros_utilities_memory_rule_t rules[] = { + {"multiheaders", 4}, + {"multiheaders.frame_id", 60}, + {"name", 10} +}; +conf.rules = rules; +conf.n_rules = sizeof(rules) / sizeof(rules[0]); + +// member values of MyComplexType will have the default max_basic_type_sequence_capacity + +bool success = micro_ros_utilities_create_message_memory( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType), + &mymsg, + conf +); +``` + +Is also possible to use a user-provided buffer to allocate memory: + +```c +mypackage__msg__MyComplexType mymsg; + +static micro_ros_utilities_memory_conf_t conf = {0}; + +static uint8_t my_buffer[1000]; + +bool success = micro_ros_utilities_create_static_message_memory( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType), + &mymsg, + conf, + my_buffer, + sizeof(my_buffer) +); +``` + +The library provides utilies for calculating the size that both approaches will use with a certain configuration. Notice that this amount of memory is only the dynamic usage or the usage in the user provided buffer, `sizeof(mypackage__msg__MyComplexType)` is not taken into account. + +```c +mypackage__msg__MyComplexType mymsg; + +static micro_ros_utilities_memory_conf_t conf = {0}; + +size_t dynamic_size = micro_ros_utilities_get_dynamic_size( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType), + conf +); + +size_t static_size = micro_ros_utilities_get_static_size( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType), + conf +); +``` + +Finally, a destruction function is also provided for messages allocated in dynamic memory: + + +```c +mypackage__msg__MyComplexType mymsg; + +// Memory allocation using micro_ros_utilities_create_message_memory +// ... + +bool success = micro_ros_utilities_destroy_message_memory( + ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType), + &mymsg, + conf +); +``` From bdc546d53ddc9978b3d11504c1269b0e7375d774 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Tue, 20 Jul 2021 09:53:48 +0200 Subject: [PATCH 2/4] Update --- _docs/tutorials/advanced/handling_type_memory/index.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/_docs/tutorials/advanced/handling_type_memory/index.md b/_docs/tutorials/advanced/handling_type_memory/index.md index c2707dca..51c48150 100644 --- a/_docs/tutorials/advanced/handling_type_memory/index.md +++ b/_docs/tutorials/advanced/handling_type_memory/index.md @@ -7,7 +7,13 @@ This page aims to explain how to handle messages and types memory in micro-ROS. First of all, since the micro-ROS user is in an embedded C99 environment, it is important to be aware of what messages and ROS 2 types are being used in order to handle memory correctly. -The micro-ROS type memory handling has changed in the latest micro-ROS Galactic distribution, two approaches are presented in this tutorial: micro-ROS Foxy and micro-ROS Galactic and beyond. +The micro-ROS type memory handling has changed in the latest micro-ROS Galactic distribution, two approaches are presented in this tutorial: micro-ROS Foxy and micro-ROS Galactic and beyond: + +- [micro-ROS Foxy](#micro-ros-foxy) + - [Sequence types in micro-ROS](#sequence-types-in-micro-ros) + - [Compound types in micro-ROS](#compound-types-in-micro-ros) + - [Sequences of compound types](#sequences-of-compound-types) +- [micro-ROS Galactic](#micro-ros-galactic) # micro-ROS Foxy From cbe936db3363d961ab7d967b63be6cef313fc488 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Wed, 21 Jul 2021 10:43:42 +0200 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Antonio Cuadros <49162117+Acuadros95@users.noreply.github.com> --- _docs/tutorials/advanced/handling_type_memory/index.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/_docs/tutorials/advanced/handling_type_memory/index.md b/_docs/tutorials/advanced/handling_type_memory/index.md index 51c48150..b6f3178d 100644 --- a/_docs/tutorials/advanced/handling_type_memory/index.md +++ b/_docs/tutorials/advanced/handling_type_memory/index.md @@ -206,7 +206,7 @@ for(int32_t i = 0; i < 3; i++){ Due to the inclusion of [`rosidl_typesupport_introspection_c`](https://github.com/ros2/rosidl/tree/master/rosidl_typesupport_introspection_c) in micro-ROS Galactic distribution, an automated memory handling for micro-ROS types is available. The tools related to this feature are available in the package [`micro_ros_utilities`](https://github.com/micro-ROS/micro_ros_utilities). -The documentation of the package [`micro_ros_utilities`](https://github.com/micro-ROS/micro_ros_utilities) are available [here](https://micro.ros.org/docs/api/utils/). +The documentation of the package [`micro_ros_utilities`](https://github.com/micro-ROS/micro_ros_utilities) is available [here](https://micro.ros.org/docs/api/utils/). This package is able to auto-assign memory to a certain message struct using default dynamic memory allocators, for example, using the previouly declated type: @@ -245,7 +245,7 @@ bool success = micro_ros_utilities_create_message_memory( ); ``` -A complex rules approach can be used as in the following example: +To customize the length of each member of the struct, a complex rules approach can be used as in the following example: ```c mypackage__msg__MyComplexType mymsg; @@ -311,8 +311,7 @@ Finally, a destruction function is also provided for messages allocated in dynam ```c mypackage__msg__MyComplexType mymsg; -// Memory allocation using micro_ros_utilities_create_message_memory -// ... +// Release memory previously allocated with micro_ros_utilities_create_message_memory bool success = micro_ros_utilities_destroy_message_memory( ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType), From 8a472b81d0f10817a073ece63598b2a203e6afd1 Mon Sep 17 00:00:00 2001 From: Antonio Cuadros <49162117+Acuadros95@users.noreply.github.com> Date: Wed, 21 Jul 2021 10:49:22 +0200 Subject: [PATCH 4/4] Update _docs/tutorials/advanced/handling_type_memory/index.md Co-authored-by: Pablo Garrido --- _docs/tutorials/advanced/handling_type_memory/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/tutorials/advanced/handling_type_memory/index.md b/_docs/tutorials/advanced/handling_type_memory/index.md index b6f3178d..5619e914 100644 --- a/_docs/tutorials/advanced/handling_type_memory/index.md +++ b/_docs/tutorials/advanced/handling_type_memory/index.md @@ -260,7 +260,7 @@ micro_ros_utilities_memory_rule_t rules[] = { conf.rules = rules; conf.n_rules = sizeof(rules) / sizeof(rules[0]); -// member values of MyComplexType will have the default max_basic_type_sequence_capacity +// member named "values" of MyComplexType will have the default max_basic_type_sequence_capacity bool success = micro_ros_utilities_create_message_memory( ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType),