micro-ROS / micro_ros_raspberrypi_pico_sdk

Raspberry Pi Pico (RP2040) and micro-ROS integration
Apache License 2.0
184 stars 58 forks source link

Pico + microROS + FreeRTOS - Implementation attempt. #707

Closed MiguelMartinez-HAW closed 2 years ago

MiguelMartinez-HAW commented 2 years ago

I am trying to use the FreeRTOS scheduler to run microROS on a RPi Pico.

Steps to reproduce the issue

I followed the tutorial mentioned above. Then I expanded the basic example to have two publishers and two subscribers. From ROS2, I have two publishers; then, the two subscribers in the Pico would read the data being published, modify it and publish it, which I could monitor from the terminal using the echo command. That worked well.

On the other hand, I followed this tutorial to make use of the FreeRTOS and turn on some LEDs. That also worked well.

Finally, I combined both programs, so I basically put what's on the main loop of the microROS program inside a function called run_uros and created a task with FreeRTOS to run it as:

xTaskCreate(run_uros, "microROS", 512, NULL, 1, NULL);
vTaskStartScheduler();

Expected behavior

I am not sure if this is the right approach to use FreeRTOS together with microROS, but given that it runs only one task, I would expect it to run the same. The idea is that later I could implement other tasks, such as reading sensors and controlling actuators.

Actual behavior

The behavior is almost as expected. The only problem that I'm having is that I am receiving data from the publishers in the MCU very slowly. I publish data through ROS2 and I have to wait about 15 seconds to see it published by the Pico. Am I wrong for using this approach? Is there a better approach? Should I put the microROS callbacks in FreeRTOS tasks? Any guidance would be appreciated.

pablogs9 commented 2 years ago

Provide steps for replicating this issue. Try to avoid extra configuration (FreeRTOS). We would like to replicate this slow behavior of the micro-ROS API.

If this behavior is not replicable without FreeRTOS, it might be related to your task's configuration. Remember that micro-ROS is not thread-safe and you need to enable a flag in the middleware: https://github.com/eProsima/Micro-XRCE-DDS-Client/blob/fda7242ed93a81915a75157a56be11fcbd025a98/CMakeLists.txt#L67

MiguelMartinez-HAW commented 2 years ago

All I did was follow this tutorial, then I modified the .c file to incorporate 2 publishers and 2 subscribers. It all worked well. Then I followed this tutorial to add FreeRTOS. I did nothing else. I attach my source code as txt and CMakeLists file if you can take a look. I am using the micro_ros_raspberrypi_pico_sdk. I don't see where I can enable the multithread support there.

CMakeLists.txt pico_micro_ros_example_dot_c.txt

pablogs9 commented 2 years ago

Sorry but I do have not much bandwidth to look at this, but I see that your micro-ROS task has a low priority and also just 512 of the stack. Try to increase this stack, and the priority in order to see if something changes.

MiguelMartinez-HAW commented 2 years ago

Sorry but I do have not much bandwidth to look at this, but I see that your micro-ROS task has a low priority and also just 512 of the stack. Try to increase this stack, and the priority in order to see if something changes.

That actually helped, to the point that it's hard to see the delay with the naked eye. Thank you for the suggestion. I'd like to analyze the behavior with an oscilloscope.

I know FreeRTOS is not officially supported to use MicroROS on the Pico but what do you think of my approach to use FreeRTOS and put the executor spin in a task? I'm ok with using only one node for the 2 publishers and 2 subscribers. Do you think there would be any downsides to this method?

I am now concerned with enabling multithreaded support, as the microROS-Pico SDK doesn't seem to contain a CMakeLists file like the one you pointed out. Is there any other way to enable this for the Pico or would that be necessary if I do all microROS-related operations in one task?

pablogs9 commented 2 years ago

I know FreeRTOS is not officially supported to use MicroROS on the Pico but what do you think of my approach to use FreeRTOS and put the executor spin in a task? I'm ok with using only one node for the 2 publishers and 2 subscribers. Do you think there would be any downsides to this method?

It's okay to have a node in a task.

I am now concerned with enabling multithreaded support, as the microROS-Pico SDK doesn't seem to contain a CMakeLists file like the one you pointed out. Is there any other way to enable this for the Pico or would that be necessary if I do all microROS-related operations in one task?

You will need to rebuild the library with this support enabled. This can be tricky due to the implementation in this system. But take a look here: https://github.com/micro-ROS/micro_ros_raspberrypi_pico_sdk#how-to-build-the-precompiled-library

MiguelMartinez-HAW commented 2 years ago

Thank you for your help!