micro-ROS / micro_ros_setup

Support macros for building micro-ROS-based firmware.
Apache License 2.0
336 stars 128 forks source link

rclc_support_init freezes microros while not running the agent #665

Open N-K1998 opened 9 months ago

N-K1998 commented 9 months ago

Issue template

I am trying to define a custom transport for microros and I have encountered a problem. After defining the custom callbacks and all that is needed the rclc_support_init freezes the program.

Does rclc_support_init function need an agent running to work properly?

pablogs9 commented 9 months ago

Yes, normally rclc_support_init needs the micro-ROS Agent, if your use case does not guarantee the presence of the Agent, take a look at the reconnection example: https://docs.vulcanexus.org/en/latest/rst/tutorials/micro/handle_reconnections/handle_reconnections.html

N-K1998 commented 9 months ago

Ok, so I need to implement one. Thank you.

pablogs9 commented 9 months ago

Please report if this solves the issue and close on this case

N-K1998 commented 9 months ago

Yes, ofc. Is it normal that the program does not give an error but it literally stops?

pablogs9 commented 9 months ago

Well normally rclc_support_init tries to connect multiple times before returning. By default 10 times and up to 1 second per try: https://github.com/eProsima/Micro-XRCE-DDS-Client/blob/97175304425c5bee87c6fddd99de1ef8d0c394dc/CMakeLists.txt#L57-L58

So it would be normal that without an agent rclc_support_init takes up to 10 seconds. If it takes more, maybe you are having a hard fault in the execution.

N-K1998 commented 9 months ago

Do the custom transport functions run on separate tasks? (Microros running on freeRTOS) I mean the one that you can specify in rmw_uros_set_custom_transport.

pablogs9 commented 9 months ago

No, micro-ROS do not spawn any thread/task, every API call will run exclusively in the thread it is called.

N-K1998 commented 9 months ago

In this documentation https://www.freertos.org/2020/09/micro-ros-on-freertos.html it states that: "Using the FreeRTOS scheduler, micro-ROS is able to manage its main task and the priorities of the tasks in charge of the transport layers. Usually, tasks in charge of networking stack or serial interfaces have to be preempted over the micro-ROS app". I supposed there were tasks for executing custom transport code, for example, to execute the custom_read loop.

pablogs9 commented 9 months ago

No, there aren't.

At some transport implementations, maybe the network stack has a task for handling incoming/outcoming packets, but no task is created by the micro-ROS stack itself.

On the other hand, micro-ROS API can be used for different tasks at the user application level, but thread-safe operation shall be enabled.

N-K1998 commented 9 months ago

Considering a FreeRTOS task where I call rmw_uros_set_custom_transport and then I put the application code (publish/subscribe). How the application code will be able to execute if the custom read executes in a loop in the same task? Or maybe, the solution is to reserve a task for the microros init code and another for executing the microros application.

pablogs9 commented 9 months ago

Because the micro-ROS stack, reads from your custom transport callback in the executor spin. If you debug the application, you will see that under the hood, the executor spin will end here:

https://github.com/micro-ROS/rmw_microxrcedds/blob/bc4eb312ac4601a4137c35f4a56b9b83b4b18339/rmw_microxrcedds_c/src/rmw_wait.c#L108

And under the hood, the middleware will call your read transport operation.