ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A answers.ros.org

Discussion about uint8[] type transport in ROS2 python

Hi , I’m trying to start a discussion about what type should uint8[] be converted to

Background:

In ROS1 , `uint8[]` is transported into `string` while other `uint` is transported to `list` .
In Ros 2 , all the `uint` types are transported into `builtins.list`.
But in our tests , we find that when we transport the images using `uint8[]` , the `builtins.list` type shows high latency , cause the transport to `list` in python takes a lot of time
So we changed some codes and transport the `uint8[]` type to `builtins.bytes` and test again , the result is much better

Test comparison result:

 transport 2M image in ROS2 to type `builtins.list` in python : 270ms
 transport 2M image in ROS2 to type 'builtins.bytes' in python : 10ms

issue description :

 In our program , low time latency is very important , and bytes is more suitable in python too . 
 So whether it's better to let the `uint8[]` type convert to `builtins.bytes` instead of `builtins.list` in ROS2.
  (Just like in ROS)

Our attempts

 1. change the code in rosidl to make `uint8[]` convert to `builtins.bytes` directly
    this work well and the time latency is much lower than the original `builtins.list` type 
    but we don't know whether this modification will effect the upper application and algorithm
 2. trying to add a new Primitive type like `imguint8` to convert to `bytes` and `uint8` is still  `list` , but i have some problems in codes , and it's really complicated

So if the attempt 1 seems good to you , we’d like just use the attempt 1 in our code .
But if the builtins.list is important for some upper application or algorithm in existing codes , then we will try to finish attempt 2

link to the attempt 2

Opinion Invitation:
@dirk-thomas
@marguedas

Appreciating your opinion !

Just a few suggestions on maybe how to deal with this:

Given this is kinda a… corner case, just by monkeypatching the method to use a converting method that’s already prepared for the usecase:

from sensor_msgs.msg import Image
Image._CONVERT_TO_PY = Image._pre_compiled_conversion_functions.uint8_to_list
node.create_subscription(Image, '/camera/whatever/image_raw', callback)

Of course, this implies generating the the thing I called _pre_compiled_conversion_functions. A better name would come up from the experts, I’m sure. Or there could be a function to just enable that in a more friendly way:

Image.use_list_conversion()

Or make an option to choose to use the old list way when instantiating a message that contains this specific problem.

from sensor_msgs.msg import Image
Image._CONVERT_TO_PY_MODE = Image._ROS1_COMPATIBILITY_MODE

Or generate two messages when a field of type uint8[] appears:

from sensor_msgs.msg import Image, Image_ROS1

Or even allow for every field the mode of conversion in a generic way (keeping the default the most efficient):

from sensor_msgs.msg import Image
Image.data.conversion_type = list
Image.data.conversion_type = bytes

Well, just throwing some ideas around. The monkeypatching way, with maybe a good method name to make it more friendly is probably my favorite.

Thanks ! I’ll try your suggestion !