Code Monkey home page Code Monkey logo

micro_ros_arduino's People

Contributors

acuadros95 avatar aentinger avatar amilcarlucas avatar github-actions[bot] avatar mergify[bot] avatar pablogs9 avatar servetcoskun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

micro_ros_arduino's Issues

Example micro-ros_publisher: How to publish new topic

I'm trying to add a new Empty topic into the micro-ros_publisher example but still haven't grasp how does the code works.

Board: OpenCR
PC: Ubuntu 20.0
Arduino IDE: ver 1.8.13

Here is the sketch which I tried to modify:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>
#include <std_msgs/msg/empty.h> //

rcl_publisher_t publisher;
std_msgs__msg__Int32 msg; //

rcl_publisher_t power_pub;
std_msgs__msg__Empty power_msg; //

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}


void error_loop() {
  while (1) {
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    msg.data++;
    RCSOFTCHECK(rcl_publish(&power_pub, &power_msg, NULL)); //
  }
}

void setup() {
  set_microros_transports();

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_default(
            &publisher,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
            "micro_ros_arduino_node_publisher")); //(parent_folder, sub_folder, msg_type), topic_name
  RCCHECK(rclc_publisher_init_default(
            &publisher,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, power_msg, Empty),
            "power_on")); //

  // create timer,
  const unsigned int timer_timeout = 1000;
  RCCHECK(rclc_timer_init_default(
            &timer,
            &support,
            RCL_MS_TO_NS(timer_timeout),
            timer_callback));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));

  msg.data = 1;   //parameter data of Int32 msg
}

void loop() {
  delay(100);
  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

Compilation gives out this error:

Arduino: 1.8.13 (Linux), Board: "OpenCR Board, OpenCR Bootloader"

/home/irsyad/Arduino/save/micro_ros_test/publisher/micro-ros_publisher_empty_210730/micro-ros_publisher_empty_210730.ino: In function 'void setup()':
/home/irsyad/Arduino/libraries/micro_ros_arduino/src/rosidl_runtime_c/message_type_support_struct.h:78:59: error: 'rosidl_typesupport_c__get_message_type_support_handle__std_msgs__power_msg__Empty' was not declared in this scope
     rosidl_typesupport_c, PkgName, MsgSubfolder, MsgName)()
                                                           ^
/home/irsyad/Arduino/save/micro_ros_test/publisher/micro-ros_publisher_empty_210730/micro-ros_publisher_empty_210730.ino:26:43: note: in definition of macro 'RCCHECK'
 #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
                                           ^
/home/irsyad/Arduino/save/micro_ros_test/publisher/micro-ros_publisher_empty_210730/micro-ros_publisher_empty_210730.ino:72:13: note: in expansion of macro 'ROSIDL_GET_MSG_TYPE_SUPPORT'
             ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, power_msg, Empty),
             ^
exit status 1
Error compiling for board OpenCR Board.


This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Hopefully someone can help me out. Thank you

Micro-ros on Teensy3.5

Hey there. I was wondering if its possible that I modify micro_ros_arduino to make it support Teensy3.5?

Example nodes: no communication between micro-ROS agent and ROS2

Hello!

I am fresh new to microROS, and I am testing the publisher example on a Teensy board. I am not able to see the topic advertised by the micro-ROS publisher via ROS2 on my computer.

Setup:

  • Computer: ROS2 Foxy / Ubuntu 20.04
  • Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53
    Board is connected to computer via USB cable.

Steps to reproduce issue:

  • After adding micro_ros_arduino as a .zip library into Arduino IDE, I upload the publisher code on the board (via Arduino IDE).
  • On the computer, I run a micro-ROS agent via command line: ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/serial/by-id/usb-Teensyduino_USB_Serial_6014540-if00 -v6 (as mentioned in ROS Discourse here), which returns:
[1603891560.502795] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3

[1603891560.502964] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6

[1603891561.374699] info     | Root.cpp           | create_client            | create                 | client_key: 0x50E95322, session_id:0x81

[1603891561.374753] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1357468450, address: 1

[1603891561.374864] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 19, data: 0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00

[1603891561.376922] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 112, data: 0000: 81 80 00 00 01 05 66 00 00 0A 00 01 01 02 00 00 57 00 00 00 3C 64 64 73 3E 3C 70 61 72 74 69 63
0020: 69 70 61 6E 74 3E 3C 72 74 70 73 3E 3C 6E 61 6D 65 3E 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75
0040: 69 6E 6F 5F 6E 6F 64 65 3C 2F 6E 61 6D 65 3E 3C 2F 72 74 70 73 3E 3C 2F 70 61 72 74 69 63 69 70
0060: 61 6E 74 3E 3C 2F 64 64 73 3E 00 00 00 00 00 00

[1603891561.380689] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x50E95322, participant_id: 0x000(1)

[1603891561.380755] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 14, data: 0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00

[1603891561.380771] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80

[1603891561.382248] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80

[1603891561.382283] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80

[1603891561.382292] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80

[1603891561.382369] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80

[1603891561.382388] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80

[1603891561.388881] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 148, data: 0000: 81 80 01 00 01 05 89 00 00 0B 00 02 02 02 00 00 7B 00 00 00 3C 64 64 73 3E 3C 74 6F 70 69 63 3E
0020: 3C 6E 61 6D 65 3E 72 74 2F 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F
0040: 70 75 62 6C 69 73 68 65 72 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73
0060: 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E
0080: 3C 2F 74 6F 70 69 63 3E 3C 2F 64 64 73 3E 00 00 01 00 00 00

[1603891561.388938] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80

[1603891561.389098] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x50E95322, topic_id: 0x000(2), participant_id: 0x000(1)

[1603891561.389200] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 14, data: 0000: 81 80 01 00 05 01 06 00 00 0B 00 02 00 00

[1603891561.389223] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80

[1603891561.389234] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80

[1603891561.390459] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80

[1603891561.390492] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80

[1603891561.390508] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80

[1603891561.390571] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80

[1603891561.390596] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80

[1603891561.397112] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 384, data: 0000: 81 80 02 00 01 05 0F 00 00 0C 00 03 03 02 00 00 01 00 00 00 00 00 01 00 01 05 64 01 00 0D 00 05
0020: 05 02 00 00 56 01 00 00 3C 64 64 73 3E 3C 64 61 74 61 5F 77 72 69 74 65 72 3E 3C 68 69 73 74 6F
0040: 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 50 52 45 41 4C 4C 4F 43 41 54 45 44 5F 57 49 54 48
0060: 5F 52 45 41 4C 4C 4F 43 3C 2F 68 69 73 74 6F 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 3C 71
0080: 6F 73 3E 3C 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 6B 69 6E 64 3E 52 45 4C 49 41 42 4C 45 3C 2F
00A0: 6B 69 6E 64 3E 3C 2F 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 2F 71 6F 73 3E 3C 74 6F 70 69 63 3E
00C0: 3C 6B 69 6E 64 3E 4E 4F 5F 4B 45 59 3C 2F 6B 69 6E 64 3E 3C 6E 61 6D 65 3E 72 74 2F 6D 69 63 72
00E0: 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F 70 75 62 6C 69 73 68 65 72 3C 2F 6E 61
0100: 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F
0120: 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E 3C 68 69 73 74 6F 72 79 51 6F 73 3E 3C
0140: 6B 69 6E 64 3E 4B 45 45 50 5F 41 4C 4C 3C 2F 6B 69 6E 64 3E 3C 2F 68 69 73 74 6F 72 79 51 6F 73
0160: 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 61 74 61 5F 77 72 69 74 65 72 3E 3C 2F 64 64 73 3E 00 00 03

[1603891561.397189] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 01 00 02 00 80

[1603891561.397209] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80

[1603891561.397226] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80

[1603891561.397343] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x50E95322, publisher_id: 0x000(3), participant_id: 0x000(1)

[1603891561.397463] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 14, data: 0000: 81 80 02 00 05 01 06 00 00 0C 00 03 00 00

[1603891561.399674] debug    | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x50E95322, datawriter_id: 0x000(5), publisher_id: 0x000(3)

[1603891561.399793] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 14, data: 0000: 81 80 03 00 05 01 06 00 00 0D 00 05 00 00

[1603891561.399827] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80

[1603891561.399845] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80

[1603891561.399858] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80

[1603891561.399871] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80

[1603891561.405610] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80

[1603891561.405667] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 13, data: 0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80

So it seems the serial communication between the node and the board is established. Messages seem to be sent by the board and received by the agent

  • I try to get the messages on ROS2 via rqt, or CLI: ros2 topic echo /[tab tab]. The only topics available are '/parameter_events' and '/rosout'.

Questions

  • Instead of launching the micro-ROS agent via the previous command line, I tried:
    docker run -it --rm -d /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/serial/by-id/usb-Teensyduino_USB_Serial_6014540-if00 -v6 (as mentioned is this repo's readme) wich returns:docker: invalid reference format.
    Or also the command line:
    ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/serial/by-id/usb-Teensyduino_USB_Serial_6014540-if00 (which is from the micro-ros tutorials) which returns:
[1603892595.656215] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3

[1603892596.410382] info     | Root.cpp           | create_client            | create                 | client_key: 0x50E95322, session_id: 0x81

[1603892596.410424] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1357468450, address: 1

The communication between the board and the agent seems to not be established.
Could you please confirm that the CLI ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/serial/by-id/usb-Teensyduino_USB_Serial_6014540-if00 -v6 is the right way to run agent for micro_ros_arduino?

  • According to the micro-ROS tutorials, once the board is flashed and the micro-ROS agent is running, it is possible to get the messages via ros2 topic echo. Is it also the case for micro_ros_arduino, or is there something I am missing?

Thank you for helping!

Running micro_ros_ardiuno on embedded seeeduino zero?

A seeeduino zero (ATSAMD21G18) is embedded in the single board computer that I am working on (link). I have been able to compile the micro-ros_publisher example and upload it to the board, using the arduino zero profile. This was done without patching the arduino board for support precompiled libraries since the example in the micro_ros_arduino repo is for SAM boards, while this is a SAMD board. Is this a correct assumption?

Running the docker command to start micro-ROS Agent seems to be working.

Unfortunately I am not able to see the topics on which the board is supposed to be running when using ros2 topic list.

Although the seeeduino zero is clearly based of the arduino zero, is it possible to run micro-ros on it?

Node doesn't display

Topic doesn't visible after added this line;
rcl_node_options_t node_ops = rcl_node_get_default_options();
node_ops.domain_id = 30;
RCCHECK(rclc_node_init_with_options(&node, "micro_ros_arduino_node", "", &support, &node_ops));
in the ardiuno code

I ran this line
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/serial/by-id/usb-Arduino_LLC_Arduino_Due-if00 -v6
ROS_DOMAIN_ID=30
then re-upload to ardiuno and I get no luck. Restart the laptop doesn't help either :P
image

The top sourced in microros_ws along with the bottom left side. The bottom right side sourced in /opt/ros/foxy just to make sure if it can view the node.

Followed this and I did the same thing, not sure where to take a look now even clear the ros domain in .bashrc.

Is it a new bug or is it something that I missed?

  • Hardware description: Ardiuno DUE
  • RTOS: from the tutorial list
  • Version or commit hash: Foxy

Expected behavior

Display "micro_ros_arduino_node"" node

Actual behavior

Doesn't display the node

Add support for Arduino Portenta

Hi this is great, how about supporting an actual Arduino board ๐Ÿ˜‰ The new Portenta is super powerful (Dual core Cortex M7+M4, wifi,ble and a bunch of other stuff on a small board) and would be a great addition to this project. Would you consider supporting it if we send you some hardware? Let me know :)

Flashing the firmware on ardiuno due issue

I'm hoping this documents is for this one.
I was able to following until the "Building the firmware" section. I'm using ardiuno DUE and I don't see any JTAG on ardiuno DUE. Do you know if there's any tutorial or something for ardiuno DUE?

When I decide to test it by run ros2 run micro_ros_setup build_firmware.sh. Everything seems normal. After that, I run ros2 run micro_ros_setup flash_firmware.sh and it just display an error;

bwuk@robots:~/microros_ws$ ros2 run micro_ros_setup flash_firmware.sh
Flashing firmware for zephyr platform olimex-stm32-e407
Error: Unsuported OpenOCD USB programmer
bwuk@robots:~/microros_ws$ 

Do you know how to do it on ardiuno DUE?

Simple service server: no response is sent

Hi! I am trying to create an "add_two_ints" service server, based on the example from micro-ROS-demos repo here, but modified to get the " void_setup() / void_loop() format ". The server receives the request, but no response is sent to the service client.

Setup:

  • Computer: ROS2 Foxy / Ubuntu 20.04
  • Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53
    Board is connected to computer via USB cable.

Steps to reproduce:

The .ino source code uploaded on the Teensy is:

#include <micro_ros_arduino.h>
#include <example_interfaces/srv/add_two_ints.h>
#include <stdio.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_msgs/msg/int64.h>

// ros:
rcl_init_options_t options;
rcl_node_options_t node_ops;
rcl_node_t node;
rclc_support_t support;
rcl_allocator_t allocator;
rclc_executor_t executor;

// service:
rcl_service_options_t service_options;
rcl_service_t serv;
const rosidl_service_type_support_t * service_type_support;
rcl_wait_set_t wait_set;

// **** SETUP ****
void setup() {
 delay(5000); 
 allocator = rcl_get_default_allocator();

 options = rcl_get_zero_initialized_init_options();
 rcl_init_options_init(&options, rcl_get_default_allocator());

 rclc_support_init(&support, 0, NULL, &allocator);

 node_ops = rcl_node_get_default_options();
 node = rcl_get_zero_initialized_node();
 rclc_node_init_default(&node, "micro_ros_service_server_node", "", &support);

 // init server
 const char * service_name = "/add_two_ints";
 service_options = rcl_service_get_default_options();
 serv = rcl_get_zero_initialized_service();
 service_type_support = ROSIDL_GET_SRV_TYPE_SUPPORT(example_interfaces, srv, AddTwoInts);
 rcl_service_init(&serv, &node, service_type_support, service_name, &service_options);
 wait_set = rcl_get_zero_initialized_wait_set();
 rcl_wait_set_init(&wait_set, 0, 0, 0, 1, 0, 0, &support.context, rcl_get_default_allocator());

 executor = rclc_executor_get_zero_initialized_executor();
 rclc_executor_init(&executor, &support.context, 1, &allocator);
}


//**** LOOP ****
void loop() {
 delay(100);
 rcl_wait_set_clear(&wait_set);

 size_t index;
 rcl_wait_set_add_service(&wait_set, &serv, &index);

 rcl_wait(&wait_set, RCL_MS_TO_NS(1));
 for (size_t i = 0; i < wait_set.size_of_services; i++) {
   if (wait_set.services[i]) {

     rmw_request_id_t req_id;

     example_interfaces__srv__AddTwoInts_Request req;
     example_interfaces__srv__AddTwoInts_Request__init(&req);

     rcl_take_request(&serv, &req_id, &req);

     example_interfaces__srv__AddTwoInts_Response res;
     example_interfaces__srv__AddTwoInts_Response__init(&res);

     res.sum = req.a + req.b;

     rcl_send_response(&serv, &req_id, &res);
   }
 }
 rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}

Once the micro-ROS agent is running, I got the output:

[1604311603.418290] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1604311603.918485] info     | TermiosAgentLinux.cpp | fini                     | server stopped         | fd: 3
[1604311603.918687] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3

[1604311607.854237] info     | Root.cpp           | create_client            | create                 | client_key: 0x01A06D5E, session_id: 0x81
[1604311607.854339] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x27290974, address: 1
[1604311607.854525] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1604311607.857389] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 116, data: 
0000: 81 80 00 00 01 05 6C 00 00 0A 00 01 01 02 00 00 5E 00 00 00 3C 64 64 73 3E 3C 70 61 72 74 69 63
0020: 69 70 61 6E 74 3E 3C 72 74 70 73 3E 3C 6E 61 6D 65 3E 6D 69 63 72 6F 5F 72 6F 73 5F 73 65 72 76
0040: 69 63 65 5F 73 65 72 76 65 72 5F 6E 6F 64 65 3C 2F 6E 61 6D 65 3E 3C 2F 72 74 70 73 3E 3C 2F 70
0060: 61 72 74 69 63 69 70 61 6E 74 3E 3C 2F 64 64 73 3E 00 00 00
[1604311607.863867] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1604311607.865046] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1604311607.865900] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x01A06D5E, participant_id: 0x000(1)
[1604311607.865946] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1604311607.865958] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1604311607.865965] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1604311607.865972] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1604311607.867175] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1604311607.867186] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1604311607.867264] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1604311607.879828] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 352, data: 
0000: 81 80 01 00 01 05 58 01 00 0B 00 08 08 02 00 00 4A 01 00 00 3C 64 64 73 3E 3C 72 65 70 6C 69 65
0020: 72 20 70 72 6F 66 69 6C 65 5F 6E 61 6D 65 3D 22 30 5F 38 22 20 73 65 72 76 69 63 65 5F 6E 61 6D
0040: 65 3D 22 2F 61 64 64 5F 74 77 6F 5F 69 6E 74 73 22 20 72 65 71 75 65 73 74 5F 74 79 70 65 3D 22
0060: 65 78 61 6D 70 6C 65 5F 69 6E 74 65 72 66 61 63 65 73 3A 3A 73 72 76 3A 3A 64 64 73 5F 3A 3A 41
0080: 64 64 54 77 6F 49 6E 74 73 5F 52 65 71 75 65 73 74 5F 22 20 72 65 70 6C 79 5F 74 79 70 65 3D 22
00A0: 65 78 61 6D 70 6C 65 5F 69 6E 74 65 72 66 61 63 65 73 3A 3A 73 72 76 3A 3A 64 64 73 5F 3A 3A 41
00C0: 64 64 54 77 6F 49 6E 74 73 5F 52 65 73 70 6F 6E 73 65 5F 22 3E 3C 72 65 71 75 65 73 74 5F 74 6F
00E0: 70 69 63 5F 6E 61 6D 65 3E 72 71 2F 61 64 64 5F 74 77 6F 5F 69 6E 74 73 52 65 71 75 65 73 74 3C
0100: 2F 72 65 71 75 65 73 74 5F 74 6F 70 69 63 5F 6E 61 6D 65 3E 3C 72 65 70 6C 79 5F 74 6F 70 69 63
0120: 5F 6E 61 6D 65 3E 72 72 2F 61 64 64 5F 74 77 6F 5F 69 6E 74 73 52 65 70 6C 79 3C 2F 72 65 70 6C
0140: 79 5F 74 6F 70 69 63 5F 6E 61 6D 65 3E 3C 2F 72 65 70 6C 69 65 72 3E 3C 2F 64 64 73 3E 00 00 01
[1604311607.879877] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80
[1604311607.879884] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80
[1604311607.879892] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80
[1604311607.880998] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80
[1604311607.881208] debug    | ProxyClient.cpp    | create_replier           | replier created        | client_key: 0x01A06D5E, requester_id: 0x000(7), participant_id: 0x000(1)
[1604311607.881269] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 14, data: 
0000: 81 80 01 00 05 01 06 00 00 0B 00 08 00 00
[1604311607.881280] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.881287] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.881293] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.881301] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.881307] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.886692] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 01 00 80
[1604311607.886751] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.887799] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1604311607.987966] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 24, data: 
0000: 81 80 02 00 08 01 10 00 00 0C 00 08 80 00 00 01 FF FF 00 00 00 00 00 00
[1604311607.988130] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1604311608.087934] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 02 00 80
[1604311608.088091] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1604311608.089162] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 01 00 02 00 80
[1604311608.089334] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1604311608.188686] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80
[1604311608.188825] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1604311608.390812] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80
[1604311608.391055] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80

Then I call the service in another shell with the command:
ros2 service call add_two_ints example_interfaces/srv/AddTwoInts "{a: 1, b: 0}"
, which output is:

waiting for service to become available...
requester: making request: example_interfaces.srv.AddTwoInts_Request(a=1, b=0) 

The micro-ROS agent response is:

[1604311838.727954] debug    | Replier.cpp        | read_fn                  | [==>> DDS <<==]        | client_key: 0x00000000, len: 40, data: 
0000: 01 0F 8E E6 C1 71 01 00 01 00 00 00 00 00 12 03 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00
0020: 00 00 00 00 00 00 00 00
[1604311838.728068] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x01A06D5E, len: 52, data: 
0000: 81 80 02 00 09 01 2C 00 00 0C 00 08 01 0F 8E E6 C1 71 01 00 01 00 00 00 00 00 12 03 00 00 00 00
0020: 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[1604311838.745935] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x01A06D5E, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80

So, the service is recognized as available, and the server receives the request, but the response is not sent.

I also tried to launch the micro-ROS agent via a docker:
sudo docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/teensy -v6
The outputs are the same.

I guess this issue is due to my .ino source code. Do you have any idea what causes this? Thanks for helping!

Micro_ros_arduino on esp32

Hello guys! I'm currently working on a project using an ESP32 board with arduino as component. I would like to use this library to implement ROS2 in my project but I'm having some troubles, and I don kow if it is posible to do what I want. Has anybody tried before to include this library as component and make it work?

Thanks in advance!

Teensy 4.0 not sending messages / agent not receiving

Issue template

  • Hardware description: Teensy 4.0
  • Version or commit hash: Foxy

Steps to reproduce the issue

Added Micro Ros to Sketch -> Include library -> Add .ZIP Library...
Patched Teensyduino (not SAM)
Uploaded micro-ros.publisher.io to the Teensy
docker run -it --rm --net=host -v /dev:/dev -v /dev/shm:/dev/shm --privileged microros/micro-ros-agent:foxy serial --dev /dev/ttyACM0 -v6
Sourced ROS2
/ros2 topic list

Expected behavior

The debug command window should receive messages
Rostopic should be updated with the new node

Actual behavior

No new node
No messages being received by the agent

Here is a log of the console:

beau@beau-VirtualBox:~$ sudo docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/ttyACM0 -v6
[1621970780.817450] info     | TermiosAgentLinux.cpp | init                     | Serial port not found. | device: /dev/ttyACM0, error 2, waiting for connection...
[1621970781.820991] info     | TermiosAgentLinux.cpp | init                     | Serial port not found. | device: /dev/ttyACM0, error 2, waiting for connection...
[1621970782.823024] info     | TermiosAgentLinux.cpp | init                     | Serial port not found. | device: /dev/ttyACM0, error 2, waiting for connection...
[1621970783.851576] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 14
[1621970783.852149] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1621970784.609784] info     | Root.cpp           | create_client            | create                 | client_key: 0x49C73FD7, session_id: 0x81
[1621970784.609883] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1237794775, address: 0
[1621970784.610233] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1621970785.609696] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 112, data: 
0000: 81 80 00 00 01 05 66 00 00 0A 00 01 01 02 00 00 57 00 00 00 3C 64 64 73 3E 3C 70 61 72 74 69 63
0020: 69 70 61 6E 74 3E 3C 72 74 70 73 3E 3C 6E 61 6D 65 3E 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75
0040: 69 6E 6F 5F 6E 6F 64 65 3C 2F 6E 61 6D 65 3E 3C 2F 72 74 70 73 3E 3C 2F 70 61 72 74 69 63 69 70
0060: 61 6E 74 3E 3C 2F 64 64 73 3E 00 00 00 00 00 00
[1621970785.610493] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970785.612410] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
2021-05-25 19:26:25.612 [RTPS_TRANSPORT_SHM Error] Failed init_port fastrtps_port7415: open_and_lock_file failed -> Function open_port_internal
[1621970785.632203] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970785.638049] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970785.643778] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x49C73FD7, participant_id: 0x000(1)
[1621970785.660023] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970785.695054] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1621970785.703735] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.704089] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.706546] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.706956] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.697675] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970785.725670] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.753196] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.761927] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970785.781254] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621970785.913994] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970786.114576] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970786.317080] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970786.517781] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970786.719581] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970786.920651] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970787.121125] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970787.329152] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970787.530277] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970787.730532] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970787.930759] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970788.149264] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970788.349716] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970788.550056] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970788.751023] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970788.951144] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970789.151266] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621970789.362389] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80

Additional information

  • I am using a UBUNTU virtual machine with the Teensy added as a USB device through the oracle UI.
  • I have not used any ROS_DOMAIN_ID and I have checked my environmental variables and this has not been set.
  • The same thing happens when I run an agent from source code.

No message passing through the agent with ROS2 Rolling

Good morning! We are currently trying to migrate our project to ROS2 Rolling, but I have some trouble making messages pass through the agent.

Setup

  • Ubuntu 20.04
  • ROS2 Rolling
  • Teensy 3.2

Steps to reproduce

As we are using a Teensy board, I previously installed the micro-ros-arduino lib for Rolling.

First, I tried to use the agent installed from snap. On Foxy, before migrating to Rolling, the agent was installed from snap release, and everything used to work nicely. I re-install it from snap, having sourced Rolling as ROS_DISTRO. Then I run the agent (micro-ros-agent serial --dev /dev/teensy_elodie -v6 ) and upload on a Teensy board the publisher example. Here's the output of the agent:

[1613119649.240504] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1613119649.740824] info     | TermiosAgentLinux.cpp | fini                     | server stopped         | fd: 3
[1613119649.741063] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1613119650.320015] info     | Root.cpp           | create_client            | create                 | client_key: 0x5083E048, session_id: 0x81
[1613119650.320126] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1350819912, address: 0
[1613119650.320291] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x5083E048, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00

And then it stops.
I run ros2 topic list and ros2 node list in another shell, but nothing is returned.

As a second attempt, I tried to install the agent from source main branch, following these steps:

mkdir uros_ws && cd uros_ws
git clone -b main https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
rosdep update && rosdep install --from-path src --ignore-src -y
colcon build
source install/local_setup.bash
ros2 run micro_ros_setup create_firmware_ws.sh host
ros2 run micro_ros_setup build_firmware.sh
source install/local_setup.bash
ros2 run micro_ros_setup create_agent_ws.sh
ros2 run micro_ros_setup build_agent.sh
source install/local_setup.bash

Note: When running ros2 run micro_ros_setup create_agent_ws.sh, an output surprised me:

=== ./eProsima/Micro-CDR (git) ===

Already on 'foxy'
Your branch is up to date with 'origin/foxy'.

Not sure if this is normal, as I tried to build the agent for Rolling

Then I run the agent (ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/teensy_elodie -v6), and upload the same publisher example as before. The output is the same.

Issue description

The agent returns that the session with the board is established, which is great. But only one message seems to be sent. Plus, ROS doesn't not find the topic nor the micro-ROS node.
No error seems to happen on the board side, as the board's LED is not blinking.

Questions

  • Is the micro-ros-agent snap release adapted for being used with ROS2 Rolling? If not, is a Rolling snap release planned? (we would be very interested in this)
  • Is the main branch corresponding to Rolling version? Can you help me fix the communication between the board, the agent, and ROS?

Thank you very much for your help!

Publishing with `rcl_publish()` takes 10ms

Hello!
Our use case requires us to control the execution frequency of an application running on a Teensy board. But it seems that publishing on topics takes way more time than I was expecting it to.

Setup

  • Computer: ROS2 Foxy / Ubuntu 20.04
  • Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53
    Board is connected to computer via USB cable.

Steps to reproduce

In my own code, my node publishes a std_msgs__msg__Range message. I measured:

  • the time before the function rcl_publish() with function micros(),
  • the time just after rcl_publish() with function micros()
    and publish the difference of these. I measured a "publication duration" between 7ms and 11ms.

(This code is quite long and messy for now, so I won't copy it here. But if you would like to have a look on it, I will make a "lighter/clearer" version of it, in order to post it here. Just let me know.)

I was able to reproduce this issue with your publisher example, which is a std_msgs__msg__Int32 publisher type:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>
#include <std_msgs/msg/float32.h>

rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

// Publication duration measurement variables:
rcl_publisher_t pub_latency;
unsigned long time_before_pub=0;
unsigned long time_after_pub=0;
std_msgs__msg__Float32 pub_duration;

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{  
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    
    time_before_pub = micros();
    
    rcl_publish(&publisher, &msg, NULL);
    
    // Publication duration measurement:
    time_after_pub = micros();
    pub_duration.data = (time_after_pub - time_before_pub);
    rcl_publish(&pub_latency, &pub_duration, NULL);
    
    msg.data++;
  }
}

void setup() {
  
  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  rclc_support_init(&support, 0, NULL, &allocator);

  // create node
  node = rcl_get_zero_initialized_node();
  rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support);
    
  // create publisher
  rclc_publisher_init_default(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "micro_ros_arduino_node_publisher");
    
  // Publication duration measurement publisher init:
  rclc_publisher_init_default(
    &pub_latency,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Float32),
    "pub_duration");
    
  // create timer,
  timer = rcl_get_zero_initialized_timer();
  const unsigned int timer_timeout = 100;
  rclc_timer_init_default(
    &timer,
    &support,
    RCL_MS_TO_NS(timer_timeout),
    timer_callback);

  // create executor
  executor = rclc_executor_get_zero_initialized_executor();
  rclc_executor_init(&executor, &support.context, 1, &allocator);

  unsigned int rcl_wait_timeout = 1;   // in ms
  rclc_executor_set_timeout(&executor, RCL_MS_TO_NS(rcl_wait_timeout));
  rclc_executor_add_timer(&executor, &timer);

  msg.data = 0;
}

void loop() {
  rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}

This code is uploaded to my Teensy board. I run a micro-ROS agent:
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/teensy
And I check out the duration topic:
ros2 topic echo /pub_duration
With this .ino code, I measure a duration between 8ms and 13ms.

Questions

First question (which may be naรฏve): is this an expected behavior? If so, it might be a real problem for us, since we absolutely need to control our loop rate. With only two rcl_publish() per loop in our own code, the actual loop rate is twice inferior to our target rate (ideally 50Hz). If this is inherently due to the rcl_publish() function, is there another and "faster" way to advertise topics using micro-ros-arduino?

Maybe this is linked to the micro-ROS agent I am running. Do you think this could be the case? How can I check this?

I was able to measure time only with Arduino functions (as micros()). May be there is a more reliable way to do so. For instance I tried functions in time.h, as clock_gettime(), but it failed (clock_gettime() was not successfully declared when including time.h).

I also tried to reduce the executor timeout, but results are the same.

Thanks for helping

no ros2 topics visible

Describe the bug
The micro-ros agent is able to communicate with a Teensy 3.2, but the rest of ROS2 is not able to connect to the agent.
I.e. ros2 topic list & ros2 node list show nothing when using micro-ros_publisher example.

To Reproduce
Following instructions in readme:

  1. Download pre-compiled library (.zip)
  2. Include it in your project using Sketch -> Include library -> Add .ZIP Library...
  3. Patch Teensyduino
  4. Upload publisher example to teensy using arduino ide
    (The pub and sub example sketches are listed under incompatible in my examples menu and I get WARNING: library micro_ros_arduino-0.0.1 claims to run on OpenCR, Teensyduino architecture(s) and may be incompatible with your current board which runs on avr architecture(s). but they upload fine)
  5. run micro-ros agent ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0 -v6
  6. run ros2 topic list ros2 node list
    Screenshot from 2020-11-06 14-10-09
    Screenshot shows that messages are sent and received.

Expected behaviour
For micro_ros_arduino_node_publisher to be visible when running ros2 topic list
(Although it is entirely possible I have misunderstood what the example is meant to do!)

System information

  • OS: Ubuntu 20.04
  • ROS 2 Foxy
  • Teensy3.2
  • Arduino IDE 1.8.13
  • Teensyduino 1.53

Additional context
(micro-ROS/micro_ros_setup#179) could be relevant, but I am not opening the serial port twice and the teensy only has one available.

executor only calling subscription callback when 2 datapoints are available

  • Hardware description: micro-ros on Teensy 4.1
  • RTOS: Linux with PREEMPT kernel

I am sending 100 datapoints from the computer to the teensy at 100Hz at the topic control using rclpy
Running ros2 topic hz /control confirms me that data is indeed sent at 100Hz.

At the Teensy, i am recording when the subscription its callback is called by using millis()
Then after all the data is received, i sent the 100 time instances from when the data was received back to the computer on the topic deltat.

Then i take the finite differerence of the timepoints, to get the difference in time between samples being recieved by the Teensy.
Since I send data at 100Hz, I suspect these finite differences to be [10,10,10,10....] (in milliseconds)
But I get [20, 0, 20, 0, 20, 0, 20, 0...]
So i guess my callback on the Teensy only executes when it receives 2 datapoints, although i have ON_NEW_DATA
I tried playing a bit with the qos of the subscription at the side of the Teensy, but it didn't do anything.

As a second question, sometimes there are big spikes in the [20, 0, 20, 0, 20, 0, 20, 0...]
Sometimes I get something more like [20, 0, .... ,1450, 153, 0, 20, 0, 20, 0...]

My code on the side of the Teensy is:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>
#include <std_msgs/msg/int32_multi_array.h>

rcl_publisher_t publisher;
rcl_subscription_t subscriber;
std_msgs__msg__Int32 msg;
std_msgs__msg__Int32 deltat_msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;
int nr_data;
int times[100] = {-1};

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}


void error_loop(){
  while(1){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void subscription_callback(const void * msgin)
{  
  const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
  if (nr_data < 99) {
    nr_data+=1; 
  }  
  times[nr_data] = millis();

}

void setup() {
  set_microros_transports();
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);  
  
  delay(2000);
  nr_data=-1;
  int i = 0;
  for (i = 0; i < 100; ++i) {
    times[i] = -1;
  }

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "teensy_control", "", &support));

  // create subscriber
  //RCCHECK(rclc_subscription_init_default(
  //  &subscriber,
  //  &node,
  //  ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
  //  "control"));  
  rcl_subscription_options_t my_subscription_options = rcl_subscription_get_default_options();
  my_subscription_options.qos.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
  my_subscription_options.qos.depth = 0;
  RCCHECK(rcl_subscription_init(
    &subscriber,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "control",&my_subscription_options));  
  

  // create publisher
  RCCHECK(rclc_publisher_init_default(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "deltat"));    

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback, ON_NEW_DATA));
}


void loop() {
  RCCHECK(rclc_executor_spin_some(&executor, RCL_S_TO_NS(50)));
  if (nr_data>=99){  
    int i = 0;
    for (i = 0; i < 100; ++i) {
      deltat_msg.data = times[i];
      rcl_publish(&publisher, &deltat_msg, NULL); 
      times[i] = -1;
    }
    nr_data=-1;
  }   
}

My code on the side of the computer is (rclpy):

import rclpy
from std_msgs.msg import Int32

msg_act = 0
msg_t = [-2 for _ in range(100)]
k_t = 0
    
def t_callback(msg):
    global msg_t
    global k_t 
    if k_t < 100:
        msg_t[k_t] = msg.data
        k_t+=1
    else:
        rclpy.logging.get_logger("pc_control").info("t is full")

def main(args=None):
    try:
        rclpy.init(args=args)
                

        # Publishing control
        control_node = rclpy.create_node('pc_control')
        publisher = control_node.create_publisher(Int32, 'control', 10)
                
        
        # Timing the publishing
        msg = Int32()
        def timer_callback():
            msg.data = 0
            publisher.publish(msg)
            rclpy.logging.get_logger("pc_control").info('Publishing: "%s"' % msg.data)

        timer_period = 0.01  # seconds
        timer = control_node.create_timer(timer_period, timer_callback)
        timer
    
        # Debuging t
        qos_profile = rclpy.qos.QoSProfile(depth=50)
        qos_profile.history = rclpy.qos.QoSHistoryPolicy.KEEP_ALL
        qos_profile.reliability = rclpy.qos.ReliabilityPolicy.BEST_EFFORT#RELIABLE
        qos_profile.durability = rclpy.qos.DurabilityPolicy.TRANSIENT_LOCAL#VOLATILE  
        t_node = rclpy.create_node('pc_node_sub')
        subscription2 = t_node.create_subscription(Int32, 'deltat', t_callback, qos_profile)
        subscription2       
        
    
        # while rclpy.ok():
        for _ in range(100):
            rclpy.spin_once(control_node)
            
        rclpy.logging.get_logger("pc_control").info('--------------------------------')   
        global k_t 
        while k_t  < 100:
            rclpy.spin_once(t_node)
            rclpy.logging.get_logger("pc_control").info('recieving: "%s"' % msg_t[k_t-1])  
        if -2 in msg_t: # if it did not recieve all data
            rclpy.logging.get_logger("pc_control").info('lengtht: "%s"' % msg_t.index(-2))  
        rclpy.logging.get_logger("pc_control").info('Reading t: "%s"' % msg_t)    
        delta_t = [a-b for a,b in zip(msg_t[1:],msg_t[0:-1])]
        rclpy.logging.get_logger("pc_control").info('Delta_t: "%s"' % delta_t) 
        
    finally:
        control_node.destroy_node()
        t_node.destroy_node()
        rclpy.shutdown()
        
if __name__ == '__main__':
    main()         

A sample output at the computer side is:

[INFO] [1621438212.597541213] [pc_control]: Publishing: "0"
[INFO] [1621438212.605783996] [pc_control]: Publishing: "0"
[INFO] [1621438212.615803231] [pc_control]: Publishing: "0"
[INFO] [1621438212.625875456] [pc_control]: Publishing: "0"
[INFO] [1621438212.635834761] [pc_control]: Publishing: "0"
[INFO] [1621438212.645778896] [pc_control]: Publishing: "0"
[INFO] [1621438212.655886050] [pc_control]: Publishing: "0"
[INFO] [1621438212.665829975] [pc_control]: Publishing: "0"
[INFO] [1621438212.675806600] [pc_control]: Publishing: "0"
[INFO] [1621438212.685841865] [pc_control]: Publishing: "0"
[INFO] [1621438212.695787399] [pc_control]: Publishing: "0"
[INFO] [1621438212.705810734] [pc_control]: Publishing: "0"
[INFO] [1621438212.715789519] [pc_control]: Publishing: "0"
[INFO] [1621438212.725833134] [pc_control]: Publishing: "0"
[INFO] [1621438212.735828719] [pc_control]: Publishing: "0"
[INFO] [1621438212.745833173] [pc_control]: Publishing: "0"
[INFO] [1621438212.755830418] [pc_control]: Publishing: "0"
[INFO] [1621438212.765814333] [pc_control]: Publishing: "0"
[INFO] [1621438212.775817018] [pc_control]: Publishing: "0"
[INFO] [1621438212.785796342] [pc_control]: Publishing: "0"
[INFO] [1621438212.795794367] [pc_control]: Publishing: "0"
[INFO] [1621438212.805848242] [pc_control]: Publishing: "0"
[INFO] [1621438212.815804177] [pc_control]: Publishing: "0"
[INFO] [1621438212.825818941] [pc_control]: Publishing: "0"
[INFO] [1621438212.835772906] [pc_control]: Publishing: "0"
[INFO] [1621438212.845779441] [pc_control]: Publishing: "0"
[INFO] [1621438212.855830786] [pc_control]: Publishing: "0"
[INFO] [1621438212.865836301] [pc_control]: Publishing: "0"
[INFO] [1621438212.875784425] [pc_control]: Publishing: "0"
[INFO] [1621438212.885811710] [pc_control]: Publishing: "0"
[INFO] [1621438212.895835885] [pc_control]: Publishing: "0"
[INFO] [1621438212.905962390] [pc_control]: Publishing: "0"
[INFO] [1621438212.915771174] [pc_control]: Publishing: "0"
[INFO] [1621438212.925810879] [pc_control]: Publishing: "0"
[INFO] [1621438212.935773614] [pc_control]: Publishing: "0"
[INFO] [1621438212.945814769] [pc_control]: Publishing: "0"
[INFO] [1621438212.955807303] [pc_control]: Publishing: "0"
[INFO] [1621438212.965871828] [pc_control]: Publishing: "0"
[INFO] [1621438212.975838183] [pc_control]: Publishing: "0"
[INFO] [1621438212.985894228] [pc_control]: Publishing: "0"
[INFO] [1621438212.995816922] [pc_control]: Publishing: "0"
[INFO] [1621438213.005787597] [pc_control]: Publishing: "0"
[INFO] [1621438213.015849592] [pc_control]: Publishing: "0"
[INFO] [1621438213.025806467] [pc_control]: Publishing: "0"
[INFO] [1621438213.035815262] [pc_control]: Publishing: "0"
[INFO] [1621438213.045790526] [pc_control]: Publishing: "0"
[INFO] [1621438213.055816761] [pc_control]: Publishing: "0"
[INFO] [1621438213.065797236] [pc_control]: Publishing: "0"
[INFO] [1621438213.075806701] [pc_control]: Publishing: "0"
[INFO] [1621438213.085806105] [pc_control]: Publishing: "0"
[INFO] [1621438213.095806300] [pc_control]: Publishing: "0"
[INFO] [1621438213.105842425] [pc_control]: Publishing: "0"
[INFO] [1621438213.115817530] [pc_control]: Publishing: "0"
[INFO] [1621438213.125798364] [pc_control]: Publishing: "0"
[INFO] [1621438213.135826299] [pc_control]: Publishing: "0"
[INFO] [1621438213.145823374] [pc_control]: Publishing: "0"
[INFO] [1621438213.155850559] [pc_control]: Publishing: "0"
[INFO] [1621438213.165858514] [pc_control]: Publishing: "0"
[INFO] [1621438213.175843928] [pc_control]: Publishing: "0"
[INFO] [1621438213.185821343] [pc_control]: Publishing: "0"
[INFO] [1621438213.195822718] [pc_control]: Publishing: "0"
[INFO] [1621438213.205814743] [pc_control]: Publishing: "0"
[INFO] [1621438213.215821797] [pc_control]: Publishing: "0"
[INFO] [1621438213.225808822] [pc_control]: Publishing: "0"
[INFO] [1621438213.235829247] [pc_control]: Publishing: "0"
[INFO] [1621438213.245808522] [pc_control]: Publishing: "0"
[INFO] [1621438213.255856136] [pc_control]: Publishing: "0"
[INFO] [1621438213.265865171] [pc_control]: Publishing: "0"
[INFO] [1621438213.275803486] [pc_control]: Publishing: "0"
[INFO] [1621438213.285792491] [pc_control]: Publishing: "0"
[INFO] [1621438213.295768906] [pc_control]: Publishing: "0"
[INFO] [1621438213.305820400] [pc_control]: Publishing: "0"
[INFO] [1621438213.315771035] [pc_control]: Publishing: "0"
[INFO] [1621438213.325799650] [pc_control]: Publishing: "0"
[INFO] [1621438213.335749545] [pc_control]: Publishing: "0"
[INFO] [1621438213.345777299] [pc_control]: Publishing: "0"
[INFO] [1621438213.355821024] [pc_control]: Publishing: "0"
[INFO] [1621438213.365823809] [pc_control]: Publishing: "0"
[INFO] [1621438213.375793854] [pc_control]: Publishing: "0"
[INFO] [1621438213.385880258] [pc_control]: Publishing: "0"
[INFO] [1621438213.395800303] [pc_control]: Publishing: "0"
[INFO] [1621438213.405819118] [pc_control]: Publishing: "0"
[INFO] [1621438213.415823973] [pc_control]: Publishing: "0"
[INFO] [1621438213.425833578] [pc_control]: Publishing: "0"
[INFO] [1621438213.435766932] [pc_control]: Publishing: "0"
[INFO] [1621438213.445807257] [pc_control]: Publishing: "0"
[INFO] [1621438213.455927532] [pc_control]: Publishing: "0"
[INFO] [1621438213.465915977] [pc_control]: Publishing: "0"
[INFO] [1621438213.475931151] [pc_control]: Publishing: "0"
[INFO] [1621438213.485892686] [pc_control]: Publishing: "0"
[INFO] [1621438213.495801021] [pc_control]: Publishing: "0"
[INFO] [1621438213.505808566] [pc_control]: Publishing: "0"
[INFO] [1621438213.515775630] [pc_control]: Publishing: "0"
[INFO] [1621438213.525831515] [pc_control]: Publishing: "0"
[INFO] [1621438213.535789280] [pc_control]: Publishing: "0"
[INFO] [1621438213.545798045] [pc_control]: Publishing: "0"
[INFO] [1621438213.555904610] [pc_control]: Publishing: "0"
[INFO] [1621438213.565926354] [pc_control]: Publishing: "0"
[INFO] [1621438213.575918199] [pc_control]: Publishing: "0"
[INFO] [1621438213.585875394] [pc_control]: Publishing: "0"
[INFO] [1621438213.595734399] [pc_control]: --------------------------------
[INFO] [1621438213.604038433] [pc_control]: recieving: "1644998"
[INFO] [1621438213.605849133] [pc_control]: recieving: "1645010"
[INFO] [1621438213.609576025] [pc_control]: recieving: "1645010"
[INFO] [1621438213.613635717] [pc_control]: recieving: "1645030"
[INFO] [1621438213.617639009] [pc_control]: recieving: "1645030"
[INFO] [1621438213.621644431] [pc_control]: recieving: "1645050"
[INFO] [1621438213.625681723] [pc_control]: recieving: "1645050"
[INFO] [1621438213.629448775] [pc_control]: recieving: "1645070"
[INFO] [1621438213.633446297] [pc_control]: recieving: "1645070"
[INFO] [1621438213.637439538] [pc_control]: recieving: "1645090"
[INFO] [1621438213.641463840] [pc_control]: recieving: "1645090"
[INFO] [1621438213.645707552] [pc_control]: recieving: "1645110"
[INFO] [1621438213.649441684] [pc_control]: recieving: "1645110"
[INFO] [1621438213.653454716] [pc_control]: recieving: "1645130"
[INFO] [1621438213.657790978] [pc_control]: recieving: "1645130"
[INFO] [1621438213.661637790] [pc_control]: recieving: "1645150"
[INFO] [1621438213.665780672] [pc_control]: recieving: "1645150"
[INFO] [1621438213.669490354] [pc_control]: recieving: "1645170"
[INFO] [1621438213.673451206] [pc_control]: recieving: "1645170"
[INFO] [1621438213.677427767] [pc_control]: recieving: "1645190"
[INFO] [1621438213.681421119] [pc_control]: recieving: "1645190"
[INFO] [1621438213.685703611] [pc_control]: recieving: "1645210"
[INFO] [1621438213.687688732] [pc_control]: recieving: "1645210"
[INFO] [1621438213.689445363] [pc_control]: recieving: "1645230"
[INFO] [1621438213.691036244] [pc_control]: recieving: "1645230"
[INFO] [1621438213.692498755] [pc_control]: recieving: "1645250"
[INFO] [1621438213.693241215] [pc_control]: recieving: "1645250"
[INFO] [1621438213.693950485] [pc_control]: recieving: "1645270"
[INFO] [1621438213.695407996] [pc_control]: recieving: "1645270"
[INFO] [1621438213.696221576] [pc_control]: recieving: "1645290"
[INFO] [1621438213.697659427] [pc_control]: recieving: "1645290"
[INFO] [1621438213.699208378] [pc_control]: recieving: "1645310"
[INFO] [1621438213.699970378] [pc_control]: recieving: "1645310"
[INFO] [1621438213.700753329] [pc_control]: recieving: "1645330"
[INFO] [1621438213.701973629] [pc_control]: recieving: "1645330"
[INFO] [1621438213.702770060] [pc_control]: recieving: "1645350"
[INFO] [1621438213.704501290] [pc_control]: recieving: "1645350"
[INFO] [1621438213.706269751] [pc_control]: recieving: "1645370"
[INFO] [1621438213.707817232] [pc_control]: recieving: "1645370"
[INFO] [1621438213.709196013] [pc_control]: recieving: "1645390"
[INFO] [1621438213.710635833] [pc_control]: recieving: "1645390"
[INFO] [1621438213.711540904] [pc_control]: recieving: "1645410"
[INFO] [1621438213.712468214] [pc_control]: recieving: "1645410"
[INFO] [1621438213.713353615] [pc_control]: recieving: "1645430"
[INFO] [1621438213.714093735] [pc_control]: recieving: "1645430"
[INFO] [1621438213.715077325] [pc_control]: recieving: "1645450"
[INFO] [1621438213.716822666] [pc_control]: recieving: "1645450"
[INFO] [1621438213.717610137] [pc_control]: recieving: "1645470"
[INFO] [1621438213.718408977] [pc_control]: recieving: "1645470"
[INFO] [1621438213.719613018] [pc_control]: recieving: "1645490"
[INFO] [1621438213.720616958] [pc_control]: recieving: "1645490"
[INFO] [1621438213.721674559] [pc_control]: recieving: "1645510"
[INFO] [1621438213.723160949] [pc_control]: recieving: "1645510"
[INFO] [1621438213.724919220] [pc_control]: recieving: "1645530"
[INFO] [1621438213.726360951] [pc_control]: recieving: "1645530"
[INFO] [1621438213.727561301] [pc_control]: recieving: "1645550"
[INFO] [1621438213.728744692] [pc_control]: recieving: "1645550"
[INFO] [1621438213.729930043] [pc_control]: recieving: "1645570"
[INFO] [1621438213.731113703] [pc_control]: recieving: "1645570"
[INFO] [1621438213.732296044] [pc_control]: recieving: "1645590"
[INFO] [1621438213.733551264] [pc_control]: recieving: "1645590"
[INFO] [1621438213.734805075] [pc_control]: recieving: "1645610"
[INFO] [1621438213.736299196] [pc_control]: recieving: "1645610"
[INFO] [1621438213.737531436] [pc_control]: recieving: "1645630"
[INFO] [1621438213.738776417] [pc_control]: recieving: "1645630"
[INFO] [1621438213.740004057] [pc_control]: recieving: "1645650"
[INFO] [1621438213.741271158] [pc_control]: recieving: "1645650"
[INFO] [1621438213.742578259] [pc_control]: recieving: "1645670"
[INFO] [1621438213.743845239] [pc_control]: recieving: "1645670"
[INFO] [1621438213.745264950] [pc_control]: recieving: "1645690"
[INFO] [1621438213.746595470] [pc_control]: recieving: "1645690"
[INFO] [1621438213.747824721] [pc_control]: recieving: "1645710"
[INFO] [1621438213.748731721] [pc_control]: recieving: "1645710"
[INFO] [1621438213.750079872] [pc_control]: recieving: "1645730"
[INFO] [1621438213.751379243] [pc_control]: recieving: "1645730"
[INFO] [1621438213.752237733] [pc_control]: recieving: "1645750"
[INFO] [1621438213.753424074] [pc_control]: recieving: "1645750"
[INFO] [1621438213.754993954] [pc_control]: recieving: "1645770"
[INFO] [1621438213.756455045] [pc_control]: recieving: "1645770"
[INFO] [1621438213.757664496] [pc_control]: recieving: "1645790"
[INFO] [1621438213.758946826] [pc_control]: recieving: "1645790"
[INFO] [1621438213.760291947] [pc_control]: recieving: "1645810"
[INFO] [1621438213.761926638] [pc_control]: recieving: "1645810"
[INFO] [1621438213.763778509] [pc_control]: recieving: "1645830"
[INFO] [1621438213.765526870] [pc_control]: recieving: "1645830"
[INFO] [1621438213.766965920] [pc_control]: recieving: "1645850"
[INFO] [1621438213.767580620] [pc_control]: recieving: "1645850"
[INFO] [1621438213.768203561] [pc_control]: recieving: "1645870"
[INFO] [1621438213.768772541] [pc_control]: recieving: "1645870"
[INFO] [1621438213.769418001] [pc_control]: recieving: "1645890"
[INFO] [1621438213.770122822] [pc_control]: recieving: "1645890"
[INFO] [1621438213.770902872] [pc_control]: recieving: "1645910"
[INFO] [1621438213.772618733] [pc_control]: recieving: "1645910"
[INFO] [1621438213.773022403] [pc_control]: recieving: "1645930"
[INFO] [1621438213.773630283] [pc_control]: recieving: "1645930"
[INFO] [1621438213.774017094] [pc_control]: recieving: "1645950"
[INFO] [1621438213.775121784] [pc_control]: recieving: "1645950"
[INFO] [1621438213.775504904] [pc_control]: recieving: "1645970"
[INFO] [1621438213.776193145] [pc_control]: recieving: "1645970"
[INFO] [1621438213.776706555] [pc_control]: recieving: "1645998"
[INFO] [1621438213.777041325] [pc_control]: Reading t: "[1644998, 1645010, 1645010, 1645030, 1645030, 1645050, 1645050, 1645070, 1645070, 1645090, 1645090, 1645110, 1645110, 1645130, 1645130, 1645150, 1645150, 1645170, 1645170, 1645190, 1645190, 1645210, 1645210, 1645230, 1645230, 1645250, 1645250, 1645270, 1645270, 1645290, 1645290, 1645310, 1645310, 1645330, 1645330, 1645350, 1645350, 1645370, 1645370, 1645390, 1645390, 1645410, 1645410, 1645430, 1645430, 1645450, 1645450, 1645470, 1645470, 1645490, 1645490, 1645510, 1645510, 1645530, 1645530, 1645550, 1645550, 1645570, 1645570, 1645590, 1645590, 1645610, 1645610, 1645630, 1645630, 1645650, 1645650, 1645670, 1645670, 1645690, 1645690, 1645710, 1645710, 1645730, 1645730, 1645750, 1645750, 1645770, 1645770, 1645790, 1645790, 1645810, 1645810, 1645830, 1645830, 1645850, 1645850, 1645870, 1645870, 1645890, 1645890, 1645910, 1645910, 1645930, 1645930, 1645950, 1645950, 1645970, 1645970, 1645998]"
[INFO] [1621438213.777332545] [pc_control]: Delta_t: "[12, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 20, 0, 28]"

Question: Multi-threading with micro_ros_arduino

Question on multi-threading with micro_ros_arduino

  • Hardware description: Teensy4.1
  • Version or commit hash: foxy

Additional information

Thanks a lot for this great library! It's very helpful for our use case.
We are polling from two sensors that are reporting at a high frequency (~200Hz). We want to publish each sensors data on separate publishers with ROS2. Unfortunately we only found examples of single threaded executioners. We have tried using Teensy Threads to solve this problem but are unsure how to proceed properly. Do you have any suggestion on how to implement a multi threaded micro_ros_arduino application?
With ROS1 we were using rosserial_arduino in combination with FreeRTOS and could implement it.

Any help would be greatly appreciated!
Thanks a lot

Teensy 4.0 throws RCL_RET_ERROR/RMW_RET_ERROR when initializing support

  • Teensy 4.0
  • Micro_Ros_Arduino
  • Example Publisher/Subscriber
  • Foxy v1.0.0

Steps to reproduce the issue

installed arduino and teensyduino, updated teensy platform.txt, copied example publisher, built, and deployed firmware

Expected behavior

Example publisher Node constructs and publishes message received by the micro_ros_agent.

Actual behavior

Throws RCL_RET_ERROR/RMW_RET_ERROR in support init (found using print statements)

Additional information

Occurs when:

  • Deployed from Windows or Linux
  • Arduino IDE or PlatformIO
  • With or without Micro_Ros_Agent running

Questions

  • Does the Micro_Ros_Agent need to be running for micro_ros_arduino to initialize?

micro_ros_arduino for ESP32

Hi Guys,

How can I used the micro_ros_arduino library on ESP32?

  • Hardware description: ESP32
  • RTOS: FreeRTOS
  • Installation type: Arduino IDE
  • Version or commit hash: foxy

Is precompiled library available?

Hello! Thank you for having micro-ros work with Arduino!

I am about to test the publisher and subscriber examples. However, I can't find the pre-compiled library, as it seems the release section of the repo is empty, and the link to the library (given in the readme) is dead.
So I am wondering whether the pre-compiled library is available yet, and if so, where to find it. Thanks!

No service response when node has both service server and subscriber

Hi! I encountered an issue that seems really problematic, but quite strange. When my node's executor has both a subscriber and a service server, the response of the server is never sent.

System:

  • Teensy 3.5
  • Ubuntu 20.04, ROS2 Foxy
  • micro-ROS agent is installed from snap
  • to be sure my micro-ROS Arduino lib was up-to-date, I rebuilt it from the latest version

Steps to reproduce

I have a node quite big, with several service severs, publishers, subscribers. Recently, I moved the add_service_to_executor function after the add_service_to_executor functions in the setup. And this causes my node to not sent anymore the service responses.
So I tried to isolate the problem with this minimal code inspired by the micro-ROS Arduino examples:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_srvs/srv/trigger.h>
#include <std_msgs/msg/int32.h>

rcl_subscription_t subscriber;
std_msgs__msg__Int32 msg;

rcl_service_t service;
std_srvs__srv__Trigger_Response res;
std_srvs__srv__Trigger_Request req;

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;

#define LED_PIN 13
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) {rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}

void error_loop(){
  while(1){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void subscription_callback(const void * msgin){  
  const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
  digitalWrite(LED_PIN, (msg->data == 0) ? LOW : HIGH);  
}

void service_callback(const void * req, void * res){
  std_srvs__srv__Trigger_Request * req_in = (std_srvs__srv__Trigger_Request *) req;
  std_srvs__srv__Trigger_Response * res_in = (std_srvs__srv__Trigger_Response *) res;
  res_in->success = true;
}


void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);  
  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create subscriber
  RCCHECK(rclc_subscription_init_default(&subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "topic_int"));
    
  // create service
  RCCHECK(rclc_service_init_default(&service, &node,  ROSIDL_GET_SRV_TYPE_SUPPORT(std_srvs, srv, Trigger), "srv_trigger"));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_service(&executor, &service, &req, &res, service_callback));    // LINE A
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback, ON_NEW_DATA));    // LINE B
}

void loop() {
  delay(100);
  RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

This code is uploaded on a Teensy 3.5.
Then I launch a micro-ROS agent (with verbose): micro-ros-agent serial --dev /dev/teensy -v6
And I call the service with CLI: ros2 service call /srv_trigger std_srvs/srv/Trigger '{}'

Issue description

In my complete code, when I invert LINE A and LINE B, the server does receive the request, but no response is sent.

But the "strange" thing is that with this example code, no matter if LINE B is before or after LINE A, the service response won't be sent. Actually, what happens is that immediately after the board reboots (after the upload or hardware reboot), an error happpens when spinning node, and the board is stuck in the error loop.
But when only LINE A or only LINE B is un-commented, everything works as expected.
So my questions are: can someone reproduce this? Why this example code cannot run with both a subscriber and a server?
If I did something wrong when initializing the subscriber or the server in this example, there could be the same errors in my complete code, which may explains the unconsistent behavior depending on the order of the add_X_to_executor functions...

Precisions

  • I tried to configure the subscriber to best effort QoS (rclc_subscription_init_best_effort), the result is the same
  • I cannot explain why the order of lines within my complete code change something, but not within this example. I am working on it and will update this issue if I got something

Thanks a lot for helping!

Problem with building firmware for Teensy 4.0 and micro-ros

Issue

I have issue with building micro-ros-arduino for teensy 4.0.

Errors

    Linking .pio/build/teensy40/firmware.elf
    .pio/build/teensy40/src/main.cpp.o: In function `timer_callback(rcl_timer_t*, long long)':
    main.cpp:(.text._Z14timer_callbackP11rcl_timer_tx+0xc): undefined reference to `rcl_publish'
    .pio/build/teensy40/src/main.cpp.o: In function `setup':
    main.cpp:(.text.setup+0x16): undefined reference to `rmw_uros_set_custom_transport'
    main.cpp:(.text.setup+0x36): undefined reference to `rcutils_get_default_allocator'
    main.cpp:(.text.setup+0x4c): undefined reference to `rclc_support_init'
    main.cpp:(.text.setup+0x5a): undefined reference to `rclc_node_init_default'
    main.cpp:(.text.setup+0x60): undefined reference to `rosidl_typesupport_c__get_message_type_support_handle__std_msgs__msg__Int32'
    main.cpp:(.text.setup+0x6c): undefined reference to `rclc_publisher_init_default'
    main.cpp:(.text.setup+0x80): undefined reference to `rclc_timer_init_default'
    main.cpp:(.text.setup+0x90): undefined reference to `rclc_executor_init'
    main.cpp:(.text.setup+0x9a): undefined reference to `rclc_executor_add_timer'
    .pio/build/teensy40/src/main.cpp.o: In function `loop':
    main.cpp:(.text.loop+0x14): undefined reference to `rclc_executor_spin_some'

Steps to reproduce the issue

I have cloned micro-ros-arduino repo and I have used platformio for building it. I have put uros_lib inside "lib" folder of platformio.
I have included <Arduino.h> and then I have copied contents of this in main.cpp.

I know that teensy_transports.c.in is for mapping some functions of uros for arduino and also I have tried to cut its contents inside main.cpp, but nothing has changed.

How can I build correctly?

The mentioned functions (rclc_executor_spin_some, rclc_executor_init, ...) are also defined some where inside uros_lib but why they are not detected for compiler?

subscribing to control_msgs/msg/JointJog causes failure

Issue template

  • Hardware description: Teensy 4.1
  • RTOS: Arduino BareMetal
  • Version or commit hash: foxy

Steps to reproduce the issue

While testing the NativeEthernet implementation that I'm working on, I tried to subscribe to a topic that uses the JointJog message and discovered that this message type causes the system to hang.

I've modified the micro-ros_subscriber_twist.ino example to provide a serial example of the problem:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

//#include <geometry_msgs/msg/twist.h> 
#include <control_msgs/msg/joint_jog.h> 


rcl_subscription_t subscriber;
//geometry_msgs__msg__Twist msg; 
control_msgs__msg__JointJog msg; 
rclc_executor_t executor;
rcl_allocator_t allocator;
rclc_support_t support;
rcl_node_t node;


#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}

void error_loop(){
  while(1){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

//twist message cb
void subscription_callback(const void *msgin) {
  //const geometry_msgs__msg__Twist * msg = (const geometry_msgs__msg__Twist *)msgin;
  const control_msgs__msg__JointJog * msg = (const control_msgs__msg__JointJog *)msgin;
  // if velocity in x direction is 0 turn off LED, if 1 turn on LED
  digitalWrite(LED_PIN, (msg->duration == 0) ? LOW : HIGH);
}

void setup() {
  set_microros_transports();
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);  
  
  delay(2000);

  allocator = rcl_get_default_allocator();

   //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create subscriber
  RCCHECK(rclc_subscription_init_default(
    &subscriber,
    &node,
    //ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist), 
	ROSIDL_GET_MSG_TYPE_SUPPORT(control_msgs, msg, JointJog), 
    "micro_ros_arduino_jj_subscriber"));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback, ON_NEW_DATA));

}

void loop() {
  delay(100);
  RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

Command to send message that should change the LED to LOW:
ros2 topic pub /micro_ros_arduino_jj_subscriber control_msgs/msg/JointJog "{ header:{stamp:{sec: 10, nanosec: 20 } , frame_id: 'base_link' } ,joint_names:['blah'], displacements:[100], velocities:[1], duration: 0}"

Expected behavior

LED should turn off

Actual behavior

LED does not turn off

Build errors 'undefined reference' with ROS2 Rolling release

Hi! We are currently trying to migrate our project from ROS2 Foxy to Rolling. The problem is I am not able to build any Arduino code once micro-ROS Rolling is installed.

Setup

  • Ubuntu 20.04, ROS2 Rolling
  • Arduino 1.8.13

Steps to reproduce

I wanted to re-installed micro-ROS from scratch to be sure no Foxy code will be remaining and creating some conflict. So I removed the library installation at ~/Arduino/libraries/micro_ros_arduino and did this:

# patch teensyduino
cd ~/arduino-1.8.13/hardware/teensy/avr/
curl https://raw.githubusercontent.com/micro-ROS/micro_ros_arduino/main/extras/patching_boards/platform_teensy.txt > platform.txt

# install micro_ros_arduino
cd ~/Arduino/libraries/micro_ros_arduino
sudo docker pull microros/micro_ros_arduino_builder:rolling
sudo docker run -it --rm -v $(pwd):/arduino_project microros/micro_ros_arduino_builder:rolling

The build went well. Then I open an example from this repo with Arduino IDE and try to build it.

Issue

The build of the .ino code failed with error undefined reference for every rclc function. For instance, when building the publisher example, I got the following errors:

/tmp/arduino_build_453459/sketch/micro-ros_publisher.ino.cpp.o: In function `timer_callback(rcl_timer_t*, long long)':
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:36: undefined reference to `rcl_publish'
/tmp/arduino_build_453459/sketch/micro-ros_publisher.ino.cpp.o: In function `set_microros_transports':
/home/anaelle/Arduino/libraries/micro_ros_arduino/src/micro_ros_arduino.h:32: undefined reference to `rmw_uros_set_custom_transport'
/tmp/arduino_build_453459/sketch/micro-ros_publisher.ino.cpp.o: In function `setup':
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:49: undefined reference to `rcutils_get_default_allocator'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:52: undefined reference to `rclc_support_init'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:55: undefined reference to `rclc_node_init_default'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:58: undefined reference to `rosidl_typesupport_c__get_message_type_support_handle__std_msgs__msg__Int32'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:58: undefined reference to `rclc_publisher_init_default'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:66: undefined reference to `rclc_timer_init_default'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:73: undefined reference to `rclc_executor_init'
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:74: undefined reference to `rclc_executor_add_timer'
/tmp/arduino_build_453459/sketch/micro-ros_publisher.ino.cpp.o: In function `loop':
/tmp/arduino_modified_sketch_797093/micro-ros_publisher.ino:81: undefined reference to `rclc_executor_spin_some'

I double checked that I was building the example code from the main branch, and that the library installation was complete.
Did I made some mistakes switching from Foxy to Rolling? Are some includes missing?
Thank you very much for your help!

agent foxy not working, rolling yes!

I wrote this issue to ask you if it was a known issue and for other people that have same issue.

I have just installed a fresh ROS2 machine (UPxtreme i7 & Ubuntu 20.04) and putted micro-ros-arduino v1.0.0 on Portenta.

Foxy agent had a strange behavior, similar to issue #111

ros2 topic list not return the micro-ros published topic (I run the publisher example)
Sometimes the right topic appears but ros2 topic echo /microros... not show anything.

This issue was not present on my old installation (release v0.0.4 and still working) and a firmware compiled with v1.0.0 works perfectly with old micro-ros-agent:foxy

I pulled the rolling docker and it works perfectly, probably is it going to be in the next foxy update?
Thank you in advance!

QoS / middleware configuration: modifying buffer stream size

Hi! I am trying to configure a publisher's QoS policy by modifying the colcon.meta file of micro_ros_arduino library. I rather not use labels and .refs files for now.

Setup

  • Computer: Ubuntu 20.04 / ROS2 Foxy
  • Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53

Use case description

I got one std_msgs__msg__Range type publisher running on my Teensy board. I can perfectly get the published messages via ros2 topic echo /my/range/topic, if the messages' frame_id is less than 6 char long. If not, the following error raises when checking out the topic:

terminate called after throwing an instance of 'eprosima::fastcdr::exception::NotEnoughMemoryException'
  what():  Not enough memory in the buffer stream
Aborted (core dumped)

As I got nine different frames ID which should be strings between 19 and 23 char long, I need to increase the stream buffer size. To do so, I tried to follow the micro-ROS tutorials about middleware configuration

Steps to reproduce

As I use a Teensy 3.1 board, the file which should be modified is colcon_lowmem.meta. After any modification of this file, I build the micro_ros_arduino library (only for Teensy 3 type boards) with command lines:
cd /Arduino/libraries/micro_ros_arduino
sudo docker pull microros/micro_ros_arduino_builder:latest
sudo docker run -it --rm -v $(pwd):/arduino_project microros/micro_ros_arduino_builder:latest -p teensy3

  • First, I tried to add the option UCLIENT_SERIAL_TRANSPORT_MTU, which is set at 12 by default, according to the micro-ROS tutorial. So, I modified the colcon_lowmem.meta file to get this:
[...]
        "microxrcedds_client": {
            "cmake-args": [
                [...]
                "-DUCLIENT_SERIAL_TRANSPORT_MTU=24"
            ]
[...]

Once the library is built, I am able to upload the .ino source file on the board. But the application seems "stuck" right after initialization, as when running the micro-ROS agent, the only output is:

[1604914091.300743] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1604914091.801606] info     | TermiosAgentLinux.cpp | fini                     | server stopped         | fd: 3
[1604914091.801736] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1604914091.802472] info     | TermiosAgentLinux.cpp | fini                     | server stopped         | fd: 3
[1604914091.802565] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1604914091.802576] info     | TermiosAgentLinux.cpp | fini                     | server stopped         | fd: 3
[1604914091.802642] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1604914092.981950] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x50E95322, len: 24, data: 
0000: 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 50 E9 53 22 81 00 14 00
[1604914092.982153] info     | SessionManager.hpp | establish_session        | session re-established | client_key: 0x1357468450, address: 1
[1604914092.982287] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x50E95322, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00

... and then stops.

I got the same result when trying to set this option to its default value: "-DUCLIENT_SERIAL_TRANSPORT_MTU=12".
So I guess this is not the right way to set up this option.

  • Then I tried to add the option "RMW_UXRCE_STREAM_HISTORY" instead:
[...]
        "rmw_microxrcedds": {
            "cmake-args": [
                [...]
                "-DRMW_UXRCE_STREAM_HISTORY=10"
            ]
[...]

I tried with different values between 5 and 20.
With this option set up at 5 (which I guess is the default value), I get the same results as before configuring: the buffer stream error is raised.
With any else tested values (example: 20), I cannot upload my .ino code to the board.

Questions

Using custom QoS with .refs files and labels requires to define QoS for every publisher/subscriber that you declare, right? If so, I would really rather configure the QoS without using labels. So, I need to modify my colcon.meta file. Did I miss something about this? It seems that if I modify anything in this file, my application stops working.

Do you have any documentation or example colcon.meta file I could base mine on? It seems to me that micro-ROS tutorial does not list all settings (with definition, boundaries, etc, for each) for QoS/middleware configuration, and I was not able to find more exhaustive (and relevant) documentation about it.

Thank you for your awesome micro_ros_arduino and support!

Unexpected delay between receiving datapoints in Teensy 4.1

I am sending 100 datapoints from my linux computer to a Teensy 4.1 using rclpy and micro ros arduino.
On the Teensy, I time when the data is received using micros(). After sending the 100 datapoints, I sent the timings back to the computer. The code is very similar to my previous issue.

This is to test if I send data at 800Hz, that it is received at 800Hz.
At 800Hz I would expect to receive data each 1250ยตs so i expect to receive an array of timings like:
[1250, 1249, 1251, 1256, 1244, 1251, 1250, 1255...]

But I receive:
[2000, 1000, 1000, 1000, 2000, 1000, 1000, 1000 ...]
It is always exactly a multiple of 1000ยตs.
init_default or best_effort don't seem to have effect on this.
The function micros() is also not at fault, I tested this using standard arduino code.

This leads me to believe that either:

  1. The subscription on the Teensy polls the usb-input each ms (at 1000 Hz).
  2. My computer can only send data each ms.

If 1:
I'm wondering if this polling behavior is expected of running ros2 on a Teensy. I would guess this would be done with interrupts?
Is there any way to make it faster?

If 2:
Although ros2 topic hz ... gives me 800Hz, I suppose this measures the frequency of writing to the topic, not it sending data over the usb-line?
Is there any way to force this to be higher? Either using ros2 or some linux hardware related stuff you might be able to point me to?

Arduino/Genuino Mega or Mega 2560 Support

Is there a way I can compile the micro-ros library to work on the Arduino Mega 2560? I am aware that it's not supported at the moment but if there are steps I could use to get it work, I would appreciate any guidance.

ls: cannot access '*.o': No such file or directory after building the pre-compiled library

Issue template

  • Hardware description: Teensy 3.6
  • RTOS: Ubuntu 20.04
  • Installation type: micro_ros_setup
  • Version or commit hash: galactic branch

Steps to reproduce the issue

cd micro_ros_arduino 
docker run -it --rm -v $(pwd):/project --env MICROROS_LIBRARY_FOLDER=extras microros/micro_ros_static_library_builder:rolling

Expected behavior

No errors after building the library

Actual behavior

Summary: 64 packages finished [5min 4s]
  40 packages had stderr output: action_msgs builtin_interfaces composition_interfaces control_msgs diagnostic_msgs geometry_msgs libyaml_vendor lifecycle_msgs lino_msgs micro_ros_msgs micro_ros_utilities microxrcedds_client nav_msgs rcl rcl_action rcl_interfaces rcl_lifecycle rcl_logging_interface rcl_logging_noop rclc rclc_lifecycle rclc_parameter rcutils rmw rmw_implementation rmw_microxrcedds rosgraph_msgs rosidl_runtime_c rosidl_typesupport_c rosidl_typesupport_microxrcedds_c sensor_msgs shape_msgs statistics_msgs std_msgs stereo_msgs test_msgs tf2_msgs trajectory_msgs unique_identifier_msgs visualization_msgs
ls: cannot access '*.o': No such file or directory

Additional information

I'm trying to build my own version of this library as I want to include a custom message type. I copied the new custom_msg folder in extras/library_generation/extra_packages and ran the docker command to build. I encountered this error:

ls: cannot access '*.o': No such file or directory

with 40 packages having stderr output.

Timer timeout below 500ms doesn't work

The timer calls callback at 2 Hz even though the timeout is less than 0.5s.

To Reproduce

  1. Take the publisher example and reduce the timer timeout to 100ms.
$ diff orig.ino new.ino 
64c64
<   const unsigned int timer_timeout = 1000;
---
>   const unsigned int timer_timeout = 100;
79d78
<   delay(100);
  1. Start the MicroROS agent
$ docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/ttyACM0 -b 115200
  1. Listen for messages
$ ros2 topic hz /micro_ros_arduino_node_publisher
average rate: 1.992
	min: 0.002s max: 1.002s std dev: 0.50018s window: 2
average rate: 1.992
	min: 0.002s max: 1.002s std dev: 0.50020s window: 4
average rate: 1.992
	min: 0.002s max: 1.002s std dev: 0.50017s window: 6
average rate: 1.992
	min: 0.002s max: 1.002s std dev: 0.50016s window: 8

System information (please complete the following information):

  • OS: Ubuntu 20.04
  • ROS 2 Foxy
  • Board: Arduino Zero

rclc_executor_spin_some execution takes too much time after running for more than 15 hours

Hello Micro-ros team! We are currently trying to test the stability of our micro-ROS application when running for quite long periods of time. Some frequency problems appear between 15 and 17 hours of running. Some clues really make me think it has something to do with the rclc_executor_spin_some function.

Setup

  • Teensy 3.2
  • micro-ROS Arduino from main branch (Rolling), built and launched via micro-ROS dockers
  • Ubuntu 20.04 / ROS2 Rolling / FastDDS middleware implementation

Steps to reproduce the issue

I uploaded this code to my Teensy board:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/bool.h>
#include <std_msgs/msg/int64.h>
#include <std_msgs/msg/empty.h>
#include <std_msgs/msg/char.h>
#include <std_msgs/msg/float64.h>

#define DOMAIN_ID 24
#define LED_PIN 13
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}

// Standard bool publisher
rcl_publisher_t bool_pub;
std_msgs__msg__Bool bool_msg;

// Standard float publisher
rcl_publisher_t float_pub;
std_msgs__msg__Float64 float_msg;

// Standard empty publisher
rcl_publisher_t empty_pub;
std_msgs__msg__Empty empty_msg;

// Standard int subscription
rcl_subscription_t int_sub;
std_msgs__msg__Int64 int_msg;

// Standard char subscription
rcl_subscription_t char_sub;
std_msgs__msg__Char char_msg;

// Micro-Ros
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_init_options_t init_options;
rmw_init_options_t* rmw_options;
unsigned int iter = 0;
unsigned long loop_period_millis = 20;
unsigned long start_loop_time;

void error_loop(){
  while(1){
    digitalWrite(LED_PIN, LOW);
    delay(100);
  }
}

// Subscriptions callbacks
void int_cb(const void * msg_in){  
  const std_msgs__msg__Int64 * msg = (const std_msgs__msg__Int64 *)msg_in;
}

void char_cb(const void * msg_in){  
  const std_msgs__msg__Char * msg = (const std_msgs__msg__Char *)msg_in;
}

void setup() {
  set_microros_transports();
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  
  delay(2000);
  
  allocator = rcl_get_default_allocator();

  // Init options to use domain id
  init_options = rcl_get_zero_initialized_init_options();
  RCCHECK(rcl_init_options_init(&init_options, allocator));
  rmw_options = rcl_init_options_get_rmw_init_options(&init_options);
  rcl_init_options_set_domain_id(&init_options, (size_t)DOMAIN_ID);
  RCCHECK(rclc_support_init_with_options(&support, 0, NULL, &init_options, &allocator)); 

  // Init node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // Init bool publisher
  RCCHECK(rclc_publisher_init_best_effort(
    &bool_pub,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Bool),
    "topic_bool"));
  bool_msg.data = false;

  // Init float publisher
  RCCHECK(rclc_publisher_init_best_effort(
    &float_pub,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Float64),
    "topic_float"));
  float_msg.data = 0;
  
  // Init empty publisher
  RCCHECK(rclc_publisher_init_best_effort(
    &empty_pub,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Empty),
    "topic_empty"));
  
  // Init int subscriber
  RCCHECK(rclc_subscription_init_best_effort(
    &int_sub,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int64),
    "topic_int"));
  
  // Init char subscriber
  RCCHECK(rclc_subscription_init_best_effort(
    &char_sub,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Char),
    "topic_char"));

  // Init executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 2, &allocator));
  RCCHECK(rclc_executor_add_subscription(&executor, &int_sub, &int_msg, &int_cb, ON_NEW_DATA));
  RCCHECK(rclc_executor_add_subscription(&executor, &char_sub, &char_msg, &char_cb, ON_NEW_DATA));
  
}

void loop() {
  start_loop_time = millis();
  
  // Spin and publish
  float_msg.data = 1;
  RCSOFTCHECK(rcl_publish(&float_pub, &float_msg, NULL));
  
  if (iter % 5 == 0) {
    RCSOFTCHECK(rcl_publish(&bool_pub, &bool_msg, NULL));
  }
  if (iter % 20 == 0) {
    RCSOFTCHECK(rcl_publish(&empty_pub, &empty_msg, NULL));
  }
  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(1)));
  
  float_msg.data = 2;
  RCSOFTCHECK(rcl_publish(&float_pub, &float_msg, NULL));
  
  // Temporary: empty micro-agent buffer
  while (Serial.available() > 0) {
    char t = Serial.read();
  }
  
  float_msg.data = 3;
  RCSOFTCHECK(rcl_publish(&float_pub, &float_msg, NULL));
  
  // Reset iter value to 0 every 1000 incrementations
  iter++;
  if (iter >= 1000) {
    iter = 0;
  }
  
  // If loop rate is less than required, wait necessary time
  while (millis() - start_loop_time < loop_period_millis) {
    delayMicroseconds(10);
  }
  
  float_msg.data = 4;
  RCSOFTCHECK(rcl_publish(&float_pub, &float_msg, NULL));
}

This code is a very simplified version of our complete application, but it has these basic features that are the "skeleton" of our application:

  • a 50Hz loop,
  • 3 publishers, publishing at 2.5Hz, 10Hz, and 200Hz (we normally need this last one at 100Hz only, but here I put it at 200Hz for debugging reasons I will explain right below this),
  • 2 subscribers (the topics are advertised by a ROS2 node at max 5Hz).

As I said, I use the float_pub for debugging. A float value is attributed at each step of the loop:

  • Step 1: beginning of the loop
  • Step 2: after publishing the other topics and spinning the executor
  • Step 3: after emptying the buffer with Serial.read() (by the way, is this still needed? The agent was regularly freezing, and it was recommended to me as a temporary solution)
  • Step 4: end of the loop, after the delay for getting a 50Hz loop

Thanks to this, according to the data of the message received on topic_float, I am able to check the loop's step currently running. I have a ROS2 node which outputs some errors if the topics topic_float, topic_bool, and topic_empty are not advertised at the expected frequencies. It also allows me to check on the latest message value received on topic_float and how many time has passed since the last received message on this topic. I can sure provide you this piece of code if you think it can help.

I launch the agent via the rolling docker:

sudo docker run -it --rm --net=host -v /dev:/dev --privileged microros/micro-ros-agent:rolling serial --dev /dev/teensy_elodie -v6

Expected behavior

The code on the Teensy spins at the right frequency, without stopping or slowing. And so, my ROS2 node should not outputs any error.

Actual behavior

The fisrt thing I was able to catch is the outputs from the debbuging ROS2 node. During a long time, there are some errors showing up very rarely, but nothing really problematic. But at least 15 hours and 30 minutes (sometimes it took up to 16 hours and 45 minutes) after launching, the ROS2 debugging node floods with errors, about all three topics not being correctly advertised. I was able to reproduce this at least 5 times under different conditions: with/without the agent ping feature, with custom/standard messages. I provided the simpler code I was able to test for now. The behavior is the same in any case: the frequency is dramatically slowed down at least 15h30 after launch.

So I ran ros2 topic hz for all three topics, and the mean frequencies were 0.25Hz, 1Hz, and 20Hz. So precisely 10 times less than expected.

Thanks to my the debugging topic topic_float, I was able to compute the max and mean time between each loop's step, when running at normal frequency, and when the frequency is divided by 10. Here is the complete spreadsheet I used for computing these values (there is a tab for normal frequency and another for slowed-down frequency):
float_timestamp.xls. But briefly, these are the interesting results (values are given as milliseconds):

Step Normal frequency - Max duration Slow frequency - Max duration Normal frequency - Mean duration Slow frequency - Mean duration
1 --> 2 4.3 205.0 0.2 162.8
2 --> 3 25.1 0.1 5.3 0.04
3 --> 4 20.0 0.1 18.9 0.04
4 --> 1 0.02 0.2 0.02 0.06

First, since that the step 3 (3 --> 4) corresponds to the delay imposed in order to get a 50Hz loop, please note that is normal that this step duration drops, as the loop takes 10 times more time to execute than expected.
Secondly, the step 1 (1 --> 2) takes almost 1000 times more time that during a loop executing at expected frequency. So, as step 1 only consists in publishing the other topics and in spinning the executor, I really think it has something to do with the rclc_executor_spin_some function. It seems that this function execution drastically slows down after approximately 15 - 17 hours.

The funny part is that after approximately 27 - 30 hours of running, the frequency just speeds up and gets back to the expected value (I was able to reproduce this only twice for the moment, and I haven't had the time to let it run more than 30 hours to check if the problem keeps happening chronically)

Additional information

I have just launched 4 other tests to determine more precisely what could cause this latency, with theses following differences from the code I gave above:

  • A test without any pointer copy within the subscription's callbacks (the callbacks just do nothing)
  • A test without any spin neither any subscription
  • A test without subscription, but a 1-handler executor and calling rclc_executor_spin_some in the loop (even if there is nothing to do when spinning)
  • A test with only one publisher instead of three

I will let you know the results of these next week.

Thanks for your help!

Edit: I was able to reproduce a third time the frequency that goes back to normal after 30 hours. I will let this test run by the week-end to check if the frequency drops down again within the 15 next hours.

Edit 2: I have two results that might be interesting:

  • After 30 hours, the frequency doesn't seem to drop down anymore (this test has been running for 64 hours). The problem happened after 16h30 and seems to have definitely disappear after 30 hours
  • The test without any spin neither any subscription was launched 42 hours ago, and my ROS2 debugging node has not output any error.

Unstable micro-agent from docker (Foxy/Rolling)

Hello micro-ROS team!
I have some trouble to open a stable session between my board and the micro-ROS agent, when launched from Foxy docker.

Setup

  • Ubuntu 20.04
  • ROS2 Rolling
  • RMW implementation forced to FastRTPS
  • Teensy 3.2

Steps to reproduce

Build micro-ROS Arduino for Foxy:

cd ~/Arduino/libraries
git clone -b foxy https://github.com/micro-ROS/micro_ros_arduino.git
cat ~/path_to_meta_file/colcon_lowmem.meta > ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/colcon_lowmem.meta
cd ~/Arduino/libraries/micro_ros_arduino
sudo docker pull microros/micro_ros_arduino_builder:foxy
sudo docker run -it --rm -v $(pwd):/arduino_project microros/micro_ros_arduino_builder:foxy -p teensy32

The meta file I use is just a bit modified in order to be able to use re-connection features:

{
    "names": {
        "tracetools": {
            "cmake-args": [
                "-DTRACETOOLS_DISABLED=ON",
                "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF"
            ]
        },
        "rosidl_typesupport": {
            "cmake-args": [
                "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON"
            ]
        },
        "rcl": {
            "cmake-args": [
                "-DBUILD_TESTING=OFF",
                "-DRCL_COMMAND_LINE_ENABLED=OFF",
                "-DRCL_LOGGING_ENABLED=OFF"
            ]
        },
        "rcutils": {
            "cmake-args": [
                "-DENABLE_TESTING=OFF",
                "-DRCUTILS_NO_FILESYSTEM=ON",
                "-DRCUTILS_NO_THREAD_SUPPORT=ON",
                "-DRCUTILS_NO_64_ATOMIC=ON",
                "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON"
            ]
        },
        "microxrcedds_client": {
            "cmake-args": [
                "-DUCLIENT_PIC=OFF",
                "-DUCLIENT_PROFILE_UDP=OFF",
                "-DUCLIENT_PROFILE_TCP=OFF",
                "-DUCLIENT_PROFILE_DISCOVERY=OFF",
                "-DUCLIENT_PROFILE_SERIAL=OFF",
                "-UCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON",
                "-DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS=3"
            ]
        },
        "rmw_microxrcedds": {
            "cmake-args": [
                "-DRMW_UXRCE_ENTITY_CREATION_DESTROY_TIMEOUT=0",
                "-DRMW_UXRCE_MAX_NODES=1",
                "-DRMW_UXRCE_MAX_PUBLISHERS=3",
                "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=2",
                "-DRMW_UXRCE_MAX_SERVICES=1",
                "-DRMW_UXRCE_MAX_CLIENTS=0",
                "-DRMW_UXRCE_MAX_HISTORY=1",
                "-DRMW_UXRCE_TRANSPORT=custom"
            ]
        }
    }
}

Then I launch the micro-ROS agent with the board connected:

sudo docker run -it --rm --net=host -v /dev:/dev --privileged microros/micro-ros-agent:foxy serial --dev /dev/teensy -v6

Then I upload some examples on the board, for instance re-connection example or the publisher example.

Issue description

I noticed that the behavior of the agent is really unstable, it would often do one of the following:
1 - I sometimes cannot open a session. In this case, the output is just:

[1616083974.580827] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 4
[1616083974.580939] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6

I would try several times to reload the code on the board, or to re-launch the agent. It can take a dozen of tries before the session is established.
It especially happens with the publisher example. Is it possible that the custom meta file is interfering with applications that don't use the re-connection features?

2 - Once the session is open, everything run smoothly, the agent output shows all the messages being published and I can get them with ros2 topic echo. But after a while, the agent just freezes and no message are passed anymore. There is no error, but the agent output is stopped. May be the first case is also some kind agent freeze.

3 - After a few tries trying to launch the agent, I noticed with ros2 topic node that the node running on the board was present twice. With htop, I noticed an agent running in a docker but I was not able to kill the process. After a computer reboot, it was gone. It only happened once.

4 - I encountered more "specific" errors. For instance: the re-connection example doesn't always work, or a custom node only publishes one topic instead of three. But it may be related to the previous cases, so I can detail this later on if it is still relevant.

Sorry it is a bit vague. Both (1) and (2) cases are really easy to reproduce since it happens really frequently, but the freeze seems to happen randomly and I was not able to find more precisely what can cause this.

Thanks a lot for support!

micro_ros_arduino will stop after 30~40 minutes.

Hi! Thank you for the great project! I am working on a project using ROS2 robot. I am trying to connect with the micro ROS agent from my Teensy board. It was successful. However, teensy will stop after 30~40 minutes.

Does it occur in your environment?

  • Hardware description:

    Tested board: Teensy 4.0 and 4.1

  • Installation type:

    micro-ros-Agent: I was followed micro-ros instruction

    micro-ros-Arduino: I was test each way arduino IDE and platformio.(In platformio used rebuilded library)

  • system information (please complete the following information):
    OS: Ubuntu 20.04
    ROS 2 Foxy

  • Version

    micro_ros_setup: foxy (#275 Commits on Feb 11, 2021)

    micro_ros_arduino: foxy (#99~#154 every version tested)

    Micro-DDS-XRCE: foxy (#219 Commits on Feb 15, 2021)

Steps to reproduce the issue

  • Upload the script using Arduino IDE or Platformio.(script: micro-ros_recconectioin_example and micro-ros_publisher)

  • Connect micro-ros agent

    # Terminal 1
    ros2 run micro_ros_agent micro_ros_agent serial --dev [boardID]] -v6
  • Output messages from a topic

    # Terminal 2
    ros2 topic echo /int32_publisher_rclc
  • publisher will stop

    • micro-ros-agent and topic echo terminal will stop update
    # Terminal 1
    0020: 00 00 00 00
    [1614855668.344434] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x75078075, len: 16, data: 
    0000: 80 00 00 00 02 01 08 00 00 09 FF FD 02 00 00 00
    [1614855668.344590] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x75078075, len: 36, data: 
    0000: 80 00 00 00 06 01 1C 00 00 09 FF FD 00 00 01 0D 58 52 43 45 01 00 01 0F 00 01 0D 00 01 00 00 00
    0020: 00 00 00 00 #<- this is the last message. 
    
    # Terminal 2
    data: 1
    ~~~~~~
    data: 2106
    ---
    data: 2107
    ---
    data: 2108
    ---       #<- this is the last message

Thanks in advance!

micro ros agent generates error message: [RTPS_PARTICIPANT Error] Couldn't create persistence service for transient/persistent writer

Issue template

  • Hardware description: Teensy 4.1
  • RTOS: arduinio baremetal
  • Version or commit hash: foxy

Steps to reproduce the issue

Run the micro ros agent either using Serial or UDP. Both of these generated the error:

ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0 -b 115200 -v 6

ros2 run micro_ros_agent micro_ros_agent udp4 -p 8080 -v 6

I tested this with both the Serial example examples/micro-ros_publisher/micro-ros_publisher.ino and the NativeEthernet implementation I'm trying to get into the main branch but now I can't test it to make sure my changes work.

Expected behavior

Agent should run without errors

Actual behavior

Agent generates the following output including error:


chrisk@brain:~/code/micro-ros/microros_ws$ ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0 -b 115200 -v 6
[1621704360.515726] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 4
[1621704360.515868] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1621704361.519688] info     | Root.cpp           | create_client            | create                 | client_key: 0x49C73FD7, session_id: 0x81
[1621704361.519839] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1237794775, address: 0
[1621704361.520043] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1621704362.519398] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 56, data: 
0000: 81 80 00 00 01 05 2E 00 00 0A 00 01 01 03 00 00 1F 00 00 00 00 01 00 00 17 00 00 00 6D 69 63 72
0020: 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 00 00 00 00 00 00
[1621704362.520401] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621704362.522376] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621704362.526377] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1621704362.530316] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x49C73FD7, participant_id: 0x000(1)
[1621704362.530655] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1621704362.530825] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621704362.530977] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621704362.531062] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621704362.531033] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621704362.531143] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1621704362.531260] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 100, data: 
0000: 81 80 01 00 01 05 5A 00 00 0B 00 02 02 03 00 00 4C 00 00 00 24 00 00 00 72 74 2F 6D 69 63 72 6F
0020: 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F 70 75 62 6C 69 73 68 65 72 00 00 01 01 00
0040: 1C 00 00 00 73 74 64 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74 33 32 5F 00
0060: 00 01 00 00
[1621704362.531550] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x49C73FD7, topic_id: 0x000(2), participant_id: 0x000(1)
[1621704362.531753] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 14, data: 
0000: 81 80 01 00 05 01 06 00 00 0B 00 02 00 00
[1621704362.531836] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1621704362.532017] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1621704362.533334] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 24, data: 
0000: 81 80 02 00 01 05 10 00 00 0C 00 03 03 03 00 00 02 00 00 00 00 00 00 01
[1621704362.533398] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 02 00 02 00 80
[1621704362.533535] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x49C73FD7, publisher_id: 0x000(3), participant_id: 0x000(1)
[1621704362.533679] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 14, data: 
0000: 81 80 02 00 05 01 06 00 00 0C 00 03 00 00
[1621704362.533722] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1621704362.533743] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1621704362.533990] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1621704362.535225] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 36, data: 
0000: 81 80 03 00 01 05 19 00 00 0D 00 05 05 03 00 00 0B 00 00 00 00 02 01 00 03 00 00 00 00 00 00 00
0020: 03 00 00 00
2021-05-22 10:26:02.535 [RTPS_PARTICIPANT Error] Couldn't create persistence service for transient/persistent writer -> Function createWriter
2021-05-22 10:26:02.535 [DATA_WRITER Error] Problem creating associated Writer -> Function enable
[*** LOG ERROR #0001 ***] [2021-05-22 10:26:02] [] {argument index out of range}
[1621704362.535435] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 14, data: 
0000: 81 80 03 00 05 01 06 00 00 0D 00 05 80 00
[1621704362.535443] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1621704362.535592] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 03 00 03 00 80
[1621704362.535614] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x49C73FD7, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1621704362.536682] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x49C73FD7, len: 13, data:

Additional information

My best guess is that this is due to changes that took place between when I originally forked over a month ago and today when I tried to rebase

Int64MultiArray subscriber not working

Issue template

using OpenCR to control dynamixels. The subscriber(Int64MultiArray) is not working. When I change the message type to Int32 it is working. I read the documentation and initialized the array(mentioned below).
kindly inform me how to implement it.

int64_t array_tic[2]= {left_tick,right_tick};
int64_t value[10] = {0,0,0,0,0,0,0,0,0,0};

goal_vel = std_msgs__msg__Int64MultiArray__create();
      goal_vel->data.capacity = 10;
      goal_vel->data.data = (int64_t*)malloc(goal_vel->data.capacity * sizeof(int64_t));
      goal_vel->data.size = sizeof(value)/sizeof(int64_t);memcpy(goal_vel->data.data, value,sizeof(value));
//            
      ticks = std_msgs__msg__Int64MultiArray__create();  
      ticks->data.capacity = 2;
      ticks->data.data = (int64_t*)malloc(sizeof(array_tic));   
      ticks->data.size = sizeof(array_tic)/sizeof(int64_t);memcpy(ticks->data.data,array_tic,sizeof(array_tic));

//////Callback function:

void subscription_callback(const void * msgin)
{  
    const std_msgs__msg__Int64MultiArray * goal_vel = (const std_msgs__msg__Int64MultiArray *)msgin;
    int64_t left_front; 
    
//    value[0] = int64_t(goal_vel->data.data[0]);    
    //left_front = int32_t(msg->data);
    dxl.setGoalVelocity(DXL_ID,value[0]);
}

micro_ros_arduino on Portenta interfaced with Jetson Xavier NX

Hello guys! I'm currently working on a project using ROS2 Dashing installed on a Jetson Xavier NX to do some high-level robotics control. For the low-level controller I'm using a Portenta H7 and I will like to interface the Jetson Xavier NX with the Portenta via Ethernet (with the Vision Shield). I want to be able to send ROS2 messages to the Portenta, and then perform other processes with this information.

Will this be possible with your library? As I see that you work with the ROS2 Foxy version, and I have Dashing installed on my Jetson NX. I would appreciate any guidance.

Thanks in advance!

Custom messages/services generation

Hello! I would like to generate custom messages (and then soon, custom services), in order to be able to import them as libraries in my source code .ino. I have some methods in mind, but I don't know exactly how to proceed to get it "cleanly" done.

Setup

  • Computer: ROS2 Foxy / Ubuntu 20.04
  • Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53

Questions

So, first method would consists in running a script generating the libraries. We used to do so by using this .py script from rosserial_arduino package (as on ROS1, we use rosserial to communicate with our Teensy board). Would it be possible to use such kind of script to generate our custom messages/services for micro_ros_arduino?

Second method is the one mentionned in micro-ROS demos, which generates the libraries (and custom libraries) at build time. This method requires a CMakeLists.txt file. But mircro_ros_arduino library doesn't currently use a CMakeLists.txt for building. Plus, it seems the libraries generated for "standard" micro-ROS are not supported by micro_ros_arduino, is this right? Is there any equivalent method for micro_ros_arduino, allowing to generate a custom library at build time?

Actually, I guess library generation is done when building micro_ros_arduino, as mentionned in the repo's readme with command line:
docker run -it --rm -v $(pwd):/arduino_project micro_ros_arduino_builder
Using this, where to put the .msg and .srv (or other?) source files to get them processed? We are not really used to dockers, is it possible to run this micro_ros_arduino_builder, but not inside your docker, and get our custom libraries generated?

Thanks for you help!

receiving Int32MultiArray msg errors out / locks up micro-ros-arduino (Teensy4.0)

Issue template

  • Hardware description: Teensy 4.0
  • RTOS: N/A
  • Installation type: foxy: micro ros setup teensyduino" add library zip file
  • Version or commit hash: microros: foxy microros_arduino: current as of #294

Steps to reproduce the issue

After modifying the example micro-ros_subscriber.ino to accept Int32MultiArray no matter what I try any Int32MultiArray message either causes an error or locks up microros-arduino.

When I run the example for Int32 everything behaves as expected.

modified source code

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_msgs/msg/int32_multi_array.h>

rcl_subscription_t subscriber;
std_msgs__msg__Int32MultiArray msg;

rclc_executor_t executor;

rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

//#define LED_PIN 13
const bool heartbeats[] = {1, 0, 1, 0, 0, 0, 0, 0};

#define RCCHECK(fn)              \
  {                              \
    rcl_ret_t temp_rc = fn;      \
    if ((temp_rc != RCL_RET_OK)) \
    {                            \
      error_loop();              \
    }                            \
  }
#define RCSOFTCHECK(fn)          \
  {                              \
    rcl_ret_t temp_rc = fn;      \
    if ((temp_rc != RCL_RET_OK)) \
    {                            \
    }                            \
  }

void error_loop()
{
  while (1)
  {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(100);
  }
}

void leg_callback(const void *msgin)
{
  const std_msgs__msg__Int32MultiArray *msg = (const std_msgs__msg__Int32MultiArray *)msgin;
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void setup()
{
  set_microros_transports();

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  delay(5000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create subscriber
  RCCHECK(rclc_subscription_init_default(
      &subscriber,
      &node,
      ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32MultiArray),
      "legs"));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &leg_callback, ON_NEW_DATA));
}

void loop()
{
  digitalWrite(LED_BUILTIN, heartbeats[((millis() >> 7) & 7)]);
  RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(1)));
}

agent log (initialization)

alansrobotlab@pop-os:~/tbot_ws$ ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM8  baudrate=115200 -v6
[1622503899.915229] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1622503899.915349] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1622503900.815396] info     | Root.cpp           | create_client            | create                 | client_key: 0x796FD27B, session_id: 0x81
[1622503900.815438] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x2037371515, address: 0
[1622503900.815488] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1622503901.815309] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 56, data: 
0000: 81 80 00 00 01 05 2E 00 00 0A 00 01 01 03 00 00 1F 00 00 00 00 01 00 20 17 00 00 00 6D 69 63 72
0020: 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 00 00 00 00 00 00
[1622503901.816276] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1622503901.818274] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1622503901.818527] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x796FD27B, participant_id: 0x000(1)
[1622503901.818586] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1622503901.818594] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1622503901.818609] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1622503901.818613] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1622503901.818733] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1622503901.818742] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 80, data: 
0000: 81 80 01 00 01 05 48 00 00 0B 00 02 02 03 00 00 3A 00 00 00 08 00 00 00 72 74 2F 6C 65 67 73 00
0020: 00 01 00 00 26 00 00 00 73 74 64 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74
0040: 33 32 4D 75 6C 74 69 41 72 72 61 79 5F 00 00 01
[1622503901.818792] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x796FD27B, topic_id: 0x000(2), participant_id: 0x000(1)
[1622503901.818810] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 14, data: 
0000: 81 80 01 00 05 01 06 00 00 0B 00 02 00 00
[1622503901.818814] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1622503901.818952] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1622503901.818960] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 24, data: 
0000: 81 80 02 00 01 05 10 00 00 0C 00 04 04 03 00 00 02 00 00 00 00 00 00 01
[1622503901.819004] debug    | ProxyClient.cpp    | create_subscriber        | subscriber created     | client_key: 0x796FD27B, subscriber_id: 0x000(4), participant_id: 0x000(1)
[1622503901.819017] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 14, data: 
0000: 81 80 02 00 05 01 06 00 00 0C 00 04 00 00
[1622503901.819020] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1622503901.819142] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1622503901.819148] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 36, data: 
0000: 81 80 03 00 01 05 1A 00 00 0D 00 06 06 03 00 00 0C 00 00 00 00 02 01 00 03 00 00 00 00 00 00 00
0020: 00 04 00 00
[1622503901.819287] debug    | ProxyClient.cpp    | create_datareader        | datareader created     | client_key: 0x796FD27B, datareader_id: 0x000(6), subscriber_id: 0x000(4)
[1622503901.819300] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 14, data: 
0000: 81 80 03 00 05 01 06 00 00 0D 00 06 00 00
[1622503901.819302] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1622503901.819443] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1622503901.819449] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x796FD27B, len: 24, data: 
0000: 81 80 04 00 08 01 10 00 00 0E 00 06 80 00 00 01 FF FF 00 00 00 00 00 00
[1622503901.819495] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x796FD27B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 05 00 00 00 80

Expected behavior

micro-ros-arduino accepts an Int32MultiArray message.

Actual behavior

when sending the following message micro-ros-arduino goes into the 100ms error loop:

ros2 topic pub /legs std_msgs/msg/Int32MultiArray "layout:
  dim: []
  data_offset: 0
data: [1500, 1500, 1500]" --once 
[1622504712.809934] debug    | DataReader.cpp     | read_fn                  | [==>> DDS <<==]        | client_key: 0x00000000, len: 24, data: 
0000: 00 00 00 00 00 00 00 00 03 00 00 00 DC 05 00 00 DC 05 00 00 DC 05 00 00
[1622504712.810002] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x790A5FA1, len: 36, data: 
0000: 81 80 04 00 09 01 1C 00 00 0E 00 06 00 00 00 00 00 00 00 00 03 00 00 00 DC 05 00 00 DC 05 00 00
0020: DC 05 00 00
[1622504712.820117] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x790A5FA1, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 05 00 00 00 80

when sending this message micro-ros-arduino locks up:

ros2 topic pub /legs std_msgs/msg/Int32MultiArray "layout:
  dim:   
  - label: ''
    size: 0
    stride: 0
  data_offset: 0
data:
- 0" --once
[1622504668.298336] debug    | DataReader.cpp     | read_fn                  | [==>> DDS <<==]        | client_key: 0x00000000, len: 32, data: 
0000: 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
[1622504668.298399] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x790A5FA1, len: 44, data: 
0000: 81 80 04 00 09 01 24 00 00 0E 00 06 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0020: 00 00 00 00 01 00 00 00 00 00 00 00

Additional information

rclc_support_init() hangs

Issue template

  • Hardware description: Teensy 4.1
  • RTOS: micro_ros_arduino bare metal
  • Version or commit hash: foxy

Steps to reproduce the issue

I am trying to implement a NativeEthernet transport over TCP for the Teensy 4.1 board using the WIFI transport as my starting point.

Agent Launch Command:
ros2 run micro_ros_agent micro_ros_agent tcp4 -p 8080 -v 6

Teensy Code full code attached to this issue as .gz, but I'm including inline what I believe are the key parts:

examples/micro-ros_publisher_native_ethernet/micro-ros_publisher_native_ethernet.ino

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>

#ifndef ARDUINO_TEENSY41
#error This example has only been tested on Teensy 4.1
#endif



// The implementation will attempt to assign the client IP address using DHCP
// If DHCP fails, the following self assigned IP will be used instaed
IPAddress fallback_client_ip( 192,168,7,100 );

//For TCP connections, we need to know the agent IP address 
IPAddress agent_ip( 192,168,7,217 );


//self assigned mac address
//there are blocks of allowed self assigned mac addresses similar to IP
byte mac[] = {
	0x02, 0x47, 0x00, 0x00, 0x00, 0x01
};


//For TCP connections, we need to know the agent IP port
uint agent_port = 8080;


rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}


void error_loop(){

  Serial.println( "error loop a");
  while(1){

    Serial.println( "error loop b");
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{  
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    msg.data++;
  }
}

void setup() {

	if(!Serial) {
		Serial.begin( 115200  ); 
		delay(1000);
	}
	


	Serial.println("Setup start");

// TCP -- 
// Mac Address
// IP Address if DHCP fails
// Agent IP address
// PORT


// UDP
// TCP or UDP 
// IP Address if DHCP fails





  //set_microros_wifi_transports("WIFI SSID", "WIFI PASS", "192.168.1.57", 8888);
  //



  set_microros_native_ethernet_tcp_4_transports( mac, fallback_client_ip, agent_ip, agent_port  );

  Serial.println("Setup 1");
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);  
  
  delay(2000);

  Serial.println("Setup 2");
  allocator = rcl_get_default_allocator();

  Serial.println("Setup 2.2");

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));


  Serial.println("Setup 3");
  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_native_ethernet_node", "", &support));

  Serial.println("Setup 4");

  // create publisher
  RCCHECK(rclc_publisher_init_best_effort(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "topic_name"));

  msg.data = 0;

	Serial.println("Setup end");
}

void loop() {
	Serial.println("publish....");
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    msg.data++;
}


src/micro_ros_arduino.h

#ifndef MICRO_ROS_ARDUINO
#define MICRO_ROS_ARDUINO

// ---- Build fixes -----
//Removing __attribute__ not supported by gcc-arm-none-eabi-5_4
#define __attribute__(x)

#ifdef ARDUINO_SAMD_ZERO
// Avoid macro usage in https://github.com/eProsima/Micro-XRCE-DDS-Client/blob/66df0a6df20063d246dd638ac3d33eb2e652fab2/include/uxr/client/core/session/session.h#L97
// beacuse of https://github.com/arduino/ArduinoCore-samd/blob/0b60a79c4b194ed2e76fead95caf1bbce8960049/cores/arduino/sync.h#L28
#define synchronized synchronized
#endif
// ----------------------

#include <uxr/client/transport.h> 
#include <rmw_microros/rmw_microros.h>

extern "C" bool arduino_transport_open(struct uxrCustomTransport * transport);
extern "C" bool arduino_transport_close(struct uxrCustomTransport * transport);
extern "C" size_t arduino_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
extern "C" size_t arduino_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

static inline void set_microros_transports(){
	rmw_uros_set_custom_transport(
		true,
		NULL,
		arduino_transport_open,
		arduino_transport_close,
		arduino_transport_write,
		arduino_transport_read
	);
}

#ifdef TARGET_PORTENTA_H7_M7

#include <WiFi.h>
#include <WiFiUdp.h>

extern "C" bool arduino_wifi_transport_open(struct uxrCustomTransport * transport);
extern "C" bool arduino_wifi_transport_close(struct uxrCustomTransport * transport);
extern "C" size_t arduino_wifi_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
extern "C" size_t arduino_wifi_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

struct micro_ros_agent_locator {
	IPAddress address;
	int port;
};

static inline void set_microros_wifi_transports(char * ssid, char * pass, char * agent_ip, uint agent_port){
	while (WiFi.begin(ssid, pass) != WL_CONNECTED)
	{
    	delay(500);
	}

	static struct micro_ros_agent_locator locator;
	locator.address.fromString(agent_ip);
	locator.port = agent_port;

	rmw_uros_set_custom_transport(
		false,
		(void *) &locator,
		arduino_wifi_transport_open,
		arduino_wifi_transport_close,
		arduino_wifi_transport_write,
		arduino_wifi_transport_read
	);
}

#endif // TARGET_PORTENTA_H7_M7


#ifdef ARDUINO_TEENSY41

#include <SPI.h>
#include <NativeEthernet.h>

extern EthernetClient client;


extern "C" bool arduino_native_ethernet_tcp_4_transport_open(struct uxrCustomTransport * transport);
extern "C" bool arduino_native_ethernet_tcp_4_transport_close(struct uxrCustomTransport * transport);
extern "C" size_t arduino_native_ethernet_tcp_4_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
extern "C" size_t arduino_native_ethernet_tcp_4_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

struct micro_ros_agent_locator {
	IPAddress address;
	int port;
}; 

// static inline void set_microros_native_ethernet_transports(char * ssid, char * pass, char * agent_ip, uint agent_port){
static inline void set_microros_native_ethernet_tcp_4_transports(byte mac[],IPAddress fallback_client_ip, IPAddress agent_ip , uint agent_port){

	if(!Serial) {
		Serial.begin(9600);
        //wait a bit for serial to get ready
		/*
		while( !Serial.availableForWrite() ) {
			delay(100);
		}
		*/
		delay(1000);
	}
		
	Serial.println("Initialize NativeEthernet with DHCP..."); 
	if (Ethernet.begin(mac) == 0) {
    	Serial.println("Failed to configure Ethernet using DHCP");
    	// Check for Ethernet hardware present
    	if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      		Serial.println("Ethernet hardware was not found.  Sorry, can't run without hardware. :(");
      		while (true) {
        		delay(1); // do nothing, no point running without Ethernet hardware
      		}
    	}
    	if (Ethernet.linkStatus() == LinkOFF) {
   			Serial.println("No ethernet link detected.");
    	}

    	// try to congifure using IP address instead of DHCP:

    	Serial.println("Using self assigned IP");
    	Ethernet.begin(mac, fallback_client_ip);
  	} else {
    	Serial.print(" CK - DHCP assigned IP ");
    	Serial.println(Ethernet.localIP());
  	}


	static struct micro_ros_agent_locator locator;
	locator.address = agent_ip;
	locator.port = agent_port;

  	Serial.println("Creating custom transport");
	rmw_uros_set_custom_transport(
		true,
		(void *) &locator,
		arduino_native_ethernet_tcp_4_transport_open,
		arduino_native_ethernet_tcp_4_transport_close,
		arduino_native_ethernet_tcp_4_transport_write,
		arduino_native_ethernet_tcp_4_transport_read
	); 
  	Serial.println("done Creating custom transport");
}






#endif // TARGET_ARDUINO_TEENSY41

#endif  // MICRO_ROS_ARDUINO

Expected behavior

Example code should execute cleanly and enter the main loop

Actual behavior

rclc_support_init() hangs preventing main loop from executing

Output on Serial Monitor from Teensy:

Setup start
Initialize NativeEthernet with DHCP...
 CK - DHCP assigned IP 192.168.7.185
Creating custom transport
done Creating custom transport
Setup 1
Setup 2
Setup 2.2
Open()
Open(): Connect....
 Connected!
 client NOT avail
Write()
Write() 1
Write() 2
End Write()
Read()
Read() printed about 100 times

Output from agent:

(base) chrisk@brain:~/code/micro-ros/test_ws$ ros2 run micro_ros_agent micro_ros_agent tcp4 -p 8080  -v 6
[1620401286.196109] info     | TCPv4AgentLinux.cpp | init                     | CK running...          | port: 8080
[1620401286.196242] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1620401304.816081] debug    | TCPv4AgentLinux.cpp | recv_message             | [==>> TCP <<==]        | client_key: 0x00000000, len: 126, data: 
0000: 00 18 00 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 01 ED 53 00 81 00 FC 01 B2 FD 7E 00 00
0020: 18 00 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 01 ED 53 00 81 00 FC 01 B2 FD 7E 00 00 18
0040: 00 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 01 ED 53 00 81 00 FC 01 B2 FD 7E 00 00 18 00
0060: 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 01 ED 53 00 81 00 FC 01 B2 FD 7E 00 00 18

Additional information

I would like to keep debugging this, but I'm not sure how best to approach that at this point and would appreciate any/all suggestions.

native_ethernet.tar.gz

Adding both a timer and subscription to the executor seems to cause error_loop() to run

Issue template

Steps to reproduce the issue

Hi!

I just started experimenting with micro-ros today and ran into an issue with trying to add both a timer and subscriber to the executor at the same time.

I uploaded this code to a Teensy:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>

rcl_publisher_t publisher;
rcl_subscription_t subscriber;

std_msgs__msg__Int32 cmd_msg;
std_msgs__msg__Int32 state_msg;

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}

void error_loop() {
  while (1) {
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void subscription_callback(const void * msgin)
{
  const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
  state_msg.data = msg->data;
  RCSOFTCHECK(rcl_publish(&publisher, &state_msg, NULL));
}


void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &state_msg, NULL));
  }
}

void setup() {
  set_microros_transports();

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "camera_servo", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_default(
            &publisher,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
            "camera_servo/state_angular_pos"));

  // create subscriber
  RCCHECK(rclc_subscription_init_default(
            &subscriber,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
            "camera_servo/cmd_angular_pos"));

  // create timer,
  const unsigned int timer_timeout = 100;
  RCCHECK(rclc_timer_init_default(
            &timer,
            &support,
            RCL_MS_TO_NS(timer_timeout),
            timer_callback));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &cmd_msg, &subscription_callback, ON_NEW_DATA));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));

  state_msg.data = 0;
}

void loop() {
  delay(100);
  RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

Expected behavior

It is very possible that I made some very basic mistake here, to be honest... but I expected this code to republish the last message it got from the subscriber at 10Hz (and publish one extra time immediately in the incoming message callback).

Actual behavior

Instead, it entered the error loop immediately after I ran ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0.

Additional information

Both the publisher and subscriber examples work fine for me, and I basically just tried to run them at the same time.
If I comment out one of the following lines:

RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &cmd_msg, &subscription_callback, ON_NEW_DATA));
RCCHECK(rclc_executor_add_timer(&executor, &timer));

Everything works as expected... so I'm a bit confused... does the executor not support adding both a timer and a subscription?
Or am I making some type of beginner mistake here? Really cant tell :P

Test connection with micro ROS agent

Hello! I am trying to test the connection with the micro ROS agent from my Teensy board.

Setup

  • Computer: ROS2 Foxy / Ubuntu 20.04
  • Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53

Desired behavior

I would like to check the connection to the micro ROS agent every loop. Depending on whether the board is connected to the agent at the beginning of each loop, different functions should be executed. I also switch off the board LED if not connected (and switch it back on otherwise). To test the connection, I tried something like this: auto-discovering agent demo code. My code looks like this:

bool connected_to_micro_ROS_agent = false;

rmw_init_options_t* rmw_options;
rclc_executor_t executor;
rclc_support_t support;
rcl_node_t node;
unsigned int rcl_wait_timeout = 100;   // in ms

void checkConnectionMicroROSAgent(){
  if (rmw_uros_discover_agent(rmw_options) != RCL_RET_OK) {
    // Turn LED off if not connected
    connected_to_micro_ROS_agent = false;
    digitalWrite(LED_PIN, LOW);
  }else{
    // Turn LED on if connected
    connected_to_micro_ROS_agent = true;
    digitalWrite(LED_PIN, HIGH);
  } return;
}

void setup(){
  // Turn LED on during init
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  // Init ROS
  // options
  rclc_support_init(&support, 0, NULL, &rcl_get_default_allocator());
  rmw_options = rcl_init_options_get_rmw_init_options(&rcl_get_zero_initialized_init_options()); 
  //  node
  node = rcl_get_zero_initialized_node();
  rclc_node_init_default(&node, "micro_ros_teensy_node", "", &support);
  // executor
  executor = rclc_executor_get_zero_initialized_executor();
  rclc_executor_init(&executor, &support.context, 1, &rcl_get_default_allocator());
  rclc_executor_set_timeout(&executor, RCL_MS_TO_NS(rcl_wait_timeout));

   // Init publishers, subscribers, etc...
   // [...]
}

void loop(){
   checkConnectionMicroROSAgent();

    if (!connected_to_micro_ROS_agent){
     // functions to execute if no connection
    // [...]
   } else {
     // functions to execute if connection
     // [...]
   }

   // functions to execute anyway
   // [...]

}

Actual behavior

The board LED is switched off right after initialization, and never switched on again. So it seems that there is no agent detected.
However, I have an agent running. Plus, if there are publishers in the section "functions to execute if no connection" or "function to execute anyway", the topics are well advertised.
I guess the problem is coming from the connection test, or the rmw_options initialization (may be both...). Could you help me out with this please?

Edit: If the agent is killed with the Teensy application is looping, the LED stays off. If the agent is not running when the application is firstly launched, the LED stays on (and switches off once the agent is launched). Does the application wait for an agent to enter void loop()? If so, is there a way to avoid this behavior?

request documentation: how to add new boards and custom messages?

Hi! Thank you for your project! It is very useful!
I'm testing micro-ros for arduino to use as a "rosserial" for ROS2.
I would like to add to other arduino compatible boards like Bluepill (stm32f103) and Iot node L475, but I'm not able to find any documentation on how to add. :'(
I need also to add custom topic formats (e.g. custom joint messages) but I don't understand how I can add them.
Sorry for the "noob" issue.
Thank you in advance.

[old gcc version] undefined reference to `__ctype_ptr__'

Issue template

  • Hardware description: STM32F103
  • RTOS: RT-Thread
  • Installation type: libmicroros.a
  • Version or commit hash: foxy

Steps to reproduce the issue

$ sudo apt install gcc-arm-none-eabi
$ arm-none-eabi-nm -C --defined-only -g cortex-m3/libmicroros.a | grep __ctype_ptr__
$ # Indeed, there is no output of __ctype_ptr__

Additional information

I notice that the gcc version being used to generate libmicroros.a is 5.4, which is a little outdated.

This could cause the error undefined reference to __ctype_ptr__ if someone uses a newer version of gcc.

https://stackoverflow.com/questions/54940410/gnu-toolchain-newlib-compatibility-between-toolchain-versions-undefined-symb

Build from source error

Hi! I would like to install micro-ROS from sources but a build error happens.

Steps to reproduce the issue

I cloned micro-ROS Arduino and copied a custom meta file:

cd ~/arduino-1.8.13/hardware/teensy/avr/
curl https://raw.githubusercontent.com/micro-ROS/micro_ros_arduino/main/extras/patching_boards/platform_teensy.txt > platform.txt
cd ~/Arduino/libraries
git clone -b main https://github.com/micro-ROS/micro_ros_arduino.git
cd ~
cat ~/colcon_lowmem.meta > ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/colcon_lowmem.meta

Then I cloned the micro_ros_setup repo and followed the tutorials:

mkdir microros_ws && cd microros_ws/
git clone -b main https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
sudo apt update && rosdep update
rosdep install --from-path src --ignore-src -y
colcon build
source install/local_setup.bash
ros2 run micro_ros_setup create_firmware_ws.sh generate_lib
ros2 run micro_ros_setup build_firmware.sh ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/teensy32_toolchain.cmake ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/colcon_lowmem.meta

Issue description

This last command failed:

Crosscompiled environment: cleaning path
Building firmware for generate_lib platform generic
Using provided meta: /home/anaelle/Arduino/libraries/micro_ros_arduino/extras/library_generation/colcon_lowmem.meta
Starting >>> rcutils 
Starting >>> rosidl_cli
Starting >>> rosidl_typesupport_interface
Starting >>> microcdr
Starting >>> rmw_implementation_cmake
Starting >>> tracetools
Starting >>> tracetools_trace
Starting >>> test_interface_files
Starting >>> tracetools_read
Starting >>> libyaml_vendor
--- stderr: tracetools                                                               
gcc: warning: โ€˜-mcpu=โ€™ is deprecated; use โ€˜-mtune=โ€™ or โ€˜-march=โ€™ instead
g++: warning: โ€˜-mcpu=โ€™ is deprecated; use โ€˜-mtune=โ€™ or โ€˜-march=โ€™ instead
g++: error: unrecognized command line option โ€˜-mthumbโ€™
gcc: error: unrecognized command line option โ€˜-mthumbโ€™
make[2]: *** [CMakeFiles/tracetools.dir/build.make:79: CMakeFiles/tracetools.dir/src/utils.cpp.obj] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: *** [CMakeFiles/tracetools.dir/build.make:66: CMakeFiles/tracetools.dir/src/tracetools.c.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:81: CMakeFiles/tracetools.dir/all] Error 2
make: *** [Makefile:144: all] Error 2
---
Failed   <<< tracetools [0.93s, exited with code 2]
Aborted  <<< rosidl_typesupport_interface [0.96s]
Aborted  <<< rmw_implementation_cmake [0.94s]
Aborted  <<< test_interface_files [0.92s]
Aborted  <<< microcdr [1.04s]                                                                   
Aborted  <<< rosidl_cli [1.10s]                                                                 
Aborted  <<< tracetools_read [1.06s]
Aborted  <<< tracetools_trace [1.08s]
Aborted  <<< rcutils [1.13s]
Aborted  <<< libyaml_vendor [1.09s]

Summary: 0 packages finished [1.53s]
  1 package failed: tracetools
  9 packages aborted: libyaml_vendor microcdr rcutils rmw_implementation_cmake rosidl_cli rosidl_typesupport_interface test_interface_files tracetools_read tracetools_trace
  3 packages had stderr output: microcdr rcutils tracetools
  51 packages not processed

Additional information

The Cmakefile I provided is directly taken from this repo and is unchanged.
The error doesn't seem to be related to my custom meta file, but here it is if needed:

{
    "names": {
        "tracetools": {
            "cmake-args": [
                "-DTRACETOOLS_DISABLED=ON",
                "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF"
            ]
        },
        "rosidl_typesupport": {
            "cmake-args": [
                "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON"
            ]
        },
        "rcl": {
            "cmake-args": [
                "-DBUILD_TESTING=OFF",
                "-DRCL_COMMAND_LINE_ENABLED=OFF",
                "-DRCL_LOGGING_ENABLED=OFF"
            ]
        },
        "rcutils": {
            "cmake-args": [
                "-DENABLE_TESTING=OFF",
                "-DRCUTILS_NO_FILESYSTEM=ON",
                "-DRCUTILS_NO_THREAD_SUPPORT=ON",
                "-DRCUTILS_NO_64_ATOMIC=ON",
                "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON"
            ]
        },
        "microxrcedds_client": {
            "cmake-args": [
                "-DUCLIENT_PIC=OFF",
                "-DUCLIENT_PROFILE_UDP=OFF",
                "-DUCLIENT_PROFILE_TCP=OFF",
                "-DUCLIENT_PROFILE_DISCOVERY=OFF",
                "-DUCLIENT_PROFILE_SERIAL=OFF",
                "-UCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON",
                "-DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS=3"
            ]
        },
        "rmw_microxrcedds": {
            "cmake-args": [
                "-DRMW_UXRCE_ENTITY_CREATION_DESTROY_TIMEOUT=0",
                "-DRMW_UXRCE_MAX_NODES=1",
                "-DRMW_UXRCE_MAX_PUBLISHERS=3",
                "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=2",
                "-DRMW_UXRCE_MAX_SERVICES=1",
                "-DRMW_UXRCE_MAX_CLIENTS=0",
                "-DRMW_UXRCE_MAX_HISTORY=1",
                "-DRMW_UXRCE_TRANSPORT=custom"
            ]
        }
    }
}

I can precise that I have no problem to build the micro-ROS Arduino library from docker, and that I can also launch the micro-ROS agent from a docker. So maybe there is just a something missing here, I might have forget a step. Sorry if it is the case.

Just for information, the reason why I try to use micro-ROS from sources is that I would like to be able to launch it as a node, with a launch file or ros2 cli.

Thanks a lot for helping!

Edit: Sorry I have forgotten to say that I posted this issue in this repo because of the error (that seems directly related to the CMakeFile provided when building a firmware), and that this CMakeFile is directly from micro-ROS Arduino repo.

Reproducible builds

Issue template

  • Hardware description: teensy3.2, stm32f7
  • RTOS:
  • Installation type: running library_generation.sh script
  • Version or commit hash: foxy

Steps to reproduce the issue

when building the library with library_generation.sh it will download the latest packages and build the static libmicroros.a libraries, but is there a way to lock the package versions to have a reproducible builds?

How to use array data?

Hello:

I want to send a array data from my Arduino to my PC.
I tried this code

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{  
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &outMsg, NULL));
  }
  int a[10]={0};
  outMsg.data = a;
}

but it showed up

error: no match for 'operator=' (operand types are 'rosidl_runtime_c__int32__Sequence' and 'int [10]') outMsg.data = a;

It seems the type int a[10] is not correct, so what kinds of type should I use ?
Thank you!

uros spin function does not work when using static library

Issue Configurations

  • Hardware description: Teensy 4.0 & Teensy 4.1 (Platformio IDE) & STM32G474 (with CubeIDE)
  • RTOS: NO
  • Installation type: using static library
  • Version or commit hash: foxy

Steps to reproduce the issue

Just follow this link and then add the library that is createwd by uros to your project.
For cmake, I have used the flags exactly the same with this link.

Expected behavior

I have to see that the uros timer must publish every 1 second.

Actual behavior

We can not see any ROS2 messages in ROS2 network. But if we remove the spin function and then run rcl_publish(&publisher, &msg, NULL) function manually, we can see the ROS2 message in ROS2 network.

Also I have to note that this project was successfully implemented on STM32G474 in platformio using Arduino framework, but when we are using Platformio IDE for Teensy, or STM32Cube for STM32 microcontrollers, we can see this problem!!!!!

So we can understand that platformio does work generally, but why it is not working for other microcontrollers such as Teensy?
Also I have tested for Teensy4.0 but nothing has changed.

Also I have tested with other cmake files (used for building static library of uros). And I have added these two functions (mkdir & usleep) to "default_transport.cpp" but nothing has changed:

`
  int clock_gettime(clockid_t unused, struct timespec *tp) __attribute__ ((weak));
  int usleep(unsigned int ms) __attribute__ ((weak));
  int mkdir(const char * path, int value) __attribute__ ((weak));

 int mkdir(const char * path, int value)
  {
    return 0;
  }

  int usleep(unsigned int ms)
  {
    delayMicroseconds((uint32_t)ms);
    return ms;
  }

  int clock_gettime(clockid_t unused, struct timespec *tp)
  {
    (void)unused;
    static uint32_t rollover = 0;
    static uint64_t last_measure = 0;

    uint64_t m = micros();
    tp->tv_sec = m / 1000000;
    tp->tv_nsec = (m % 1000000) * 1000;

    // Rollover handling
    rollover += (m < last_measure) ? 1 : 0;
    uint64_t rollover_extra_us = rollover * micro_rollover_useconds;
    tp->tv_sec += rollover_extra_us / 1000000;
    tp->tv_nsec += (rollover_extra_us % 1000000) * 1000;
    last_measure = m;

    return 0;
  }
`

Uros Agent output

    root@fa05c9c1d36e:/microros_ws# ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0
    [1628654979.489550] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
    [1628654981.353120] info     | SessionManager.hpp | establish_session        | session re-established | client_key: 0x7D248957, address: 0
    [1628654982.375272] info     | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x7D248957, participant_id: 0x000(1)
    [1628654982.375782] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x7D248957, topic_id: 0x000(2), participant_id: 0x000(1)
    [1628654982.376126] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x7D248957, publisher_id: 0x000(3), participant_id: 0x000(1)
    [1628654982.376709] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x7D248957, datawriter_id: 0x000(5), publisher_id: 0x000(3)

Code

We are simply using the code in this link.

Odometry publisher breaks the program

Describe the bug
Calling rcl_publish(&publisherOdom, &msgOdom, NULL) crashes the program.

Firmware
I tried to create a minimal example just by adding odometry publisher to the provided publisher example:
https://github.com/micro-ROS/micro_ros_arduino/blob/foxy/examples/micro-ros_publisher/micro-ros_publisher.ino

ROS2 Odometry Publisher
#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <nav_msgs/msg/odometry.h>
#include <std_msgs/msg/int32.h>

rcl_publisher_t publisherOdom;
rcl_publisher_t publisherInt32;
nav_msgs__msg__Odometry msgOdom;
std_msgs__msg__Int32 msgInt32;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}


void error_loop(){
  while(1){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{  
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisherInt32, &msgInt32, NULL));
    rcl_publish(&publisherOdom, &msgOdom, NULL);    // <<<<< This line crashes the program!
  }
}

void setup() {
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);  
  
  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_default(
    &publisherOdom,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(nav_msgs, msg, Odometry),
    "odom"));

  RCCHECK(rclc_publisher_init_default(
    &publisherInt32,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "micro_ros_arduino_node_publisher"));

  // create timer,
  const unsigned int timer_timeout = 1000;
  RCCHECK(rclc_timer_init_default(
    &timer,
    &support,
    RCL_MS_TO_NS(timer_timeout),
    timer_callback));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));
}

void loop() {
  delay(100);
  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

To Reproduce

  1. Flash the code above
  2. Run the agent: docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/ttyACM0 -b 115200 -v6
  3. Check available topics ros2 topic list -t - you should see /micro_ros_arduino_node_publisher [std_msgs/msg/Int32] and
    /odom [nav_msgs/msg/Odometry]
  4. Listen for the messages on the /odom topic ros2 topic echo /odom
  5. No messages are received :(

Expected behaviour
We should receive the messages on /odom topic.

System information

  • OS: Ubuntu 20.04
  • ROS 2 Foxy

Additional information

Agent log with `rcl_publish(&publisherOdom, &msgOdom, NULL)`
$ docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/ttyACM0 -b 115200 -v6
[1606654921.941889] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 12
[1606654921.942016] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1606654922.852489] info     | Root.cpp           | create_client            | create                 | client_key: 0x7D248957, session_id: 0x81
[1606654922.852631] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x2099546455, address: 1
[1606654922.852849] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1606654922.877001] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 112, data: 
0000: 81 80 00 00 01 05 66 00 00 0A 00 01 01 02 00 00 57 00 00 00 3C 64 64 73 3E 3C 70 61 72 74 69 63
0020: 69 70 61 6E 74 3E 3C 72 74 70 73 3E 3C 6E 61 6D 65 3E 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75
0040: 69 6E 6F 5F 6E 6F 64 65 3C 2F 6E 61 6D 65 3E 3C 2F 72 74 70 73 3E 3C 2F 70 61 72 74 69 63 69 70
0060: 61 6E 74 3E 3C 2F 64 64 73 3E 00 00 00 00 00 00
[1606654922.885120] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x7D248957, participant_id: 0x000(1)
[1606654922.885392] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1606654922.885458] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1606654922.885994] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1606654922.990814] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 120, data: 
0000: 81 80 01 00 01 05 70 00 00 0B 00 02 02 02 00 00 62 00 00 00 3C 64 64 73 3E 3C 74 6F 70 69 63 3E
0020: 3C 6E 61 6D 65 3E 72 74 2F 6F 64 6F 6D 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 6E 61
0040: 76 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 4F 64 6F 6D 65 74 72 79 5F 3C 2F 64 61
0060: 74 61 54 79 70 65 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 64 73 3E 00 00 01
[1606654922.991541] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x7D248957, topic_id: 0x000(2), participant_id: 0x000(1)
[1606654922.991840] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 01 00 05 01 06 00 00 0B 00 02 00 00
[1606654922.991918] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1606654922.992367] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1606654922.992550] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 24, data: 
0000: 81 80 02 00 01 05 0F 00 00 0C 00 03 03 02 00 00 01 00 00 00 00 00 01 00
[1606654922.992954] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x7D248957, publisher_id: 0x000(3), participant_id: 0x000(1)
[1606654922.993104] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 02 00 05 01 06 00 00 0C 00 03 00 00
[1606654922.993151] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1606654922.993659] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1606654922.994701] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 340, data: 
0000: 81 80 03 00 01 05 4B 01 00 0D 00 05 05 02 00 00 3D 01 00 00 3C 64 64 73 3E 3C 64 61 74 61 5F 77
0020: 72 69 74 65 72 3E 3C 68 69 73 74 6F 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 50 52 45 41 4C
0040: 4C 4F 43 41 54 45 44 5F 57 49 54 48 5F 52 45 41 4C 4C 4F 43 3C 2F 68 69 73 74 6F 72 79 4D 65 6D
0060: 6F 72 79 50 6F 6C 69 63 79 3E 3C 71 6F 73 3E 3C 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 6B 69 6E
0080: 64 3E 52 45 4C 49 41 42 4C 45 3C 2F 6B 69 6E 64 3E 3C 2F 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C
00A0: 2F 71 6F 73 3E 3C 74 6F 70 69 63 3E 3C 6B 69 6E 64 3E 4E 4F 5F 4B 45 59 3C 2F 6B 69 6E 64 3E 3C
00C0: 6E 61 6D 65 3E 72 74 2F 6F 64 6F 6D 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 6E 61 76
00E0: 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 4F 64 6F 6D 65 74 72 79 5F 3C 2F 64 61 74
0100: 61 54 79 70 65 3E 3C 68 69 73 74 6F 72 79 51 6F 73 3E 3C 6B 69 6E 64 3E 4B 45 45 50 5F 41 4C 4C
0120: 3C 2F 6B 69 6E 64 3E 3C 2F 68 69 73 74 6F 72 79 51 6F 73 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 61
0140: 74 61 5F 77 72 69 74 65 72 3E 3C 2F 64 64 73 3E 00 00 03 00
[1606654922.996237] debug    | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x7D248957, datawriter_id: 0x000(5), publisher_id: 0x000(3)
[1606654922.996396] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 03 00 05 01 06 00 00 0D 00 05 00 00
[1606654922.996458] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1606654922.996884] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1606654922.997900] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 148, data: 
0000: 81 80 04 00 01 05 89 00 00 0E 00 12 02 02 00 00 7B 00 00 00 3C 64 64 73 3E 3C 74 6F 70 69 63 3E
0020: 3C 6E 61 6D 65 3E 72 74 2F 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F
0040: 70 75 62 6C 69 73 68 65 72 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73
0060: 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E
0080: 3C 2F 74 6F 70 69 63 3E 3C 2F 64 64 73 3E 00 00 01 00 00 00
[1606654922.998253] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x7D248957, topic_id: 0x001(2), participant_id: 0x000(1)
[1606654922.998400] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 04 00 05 01 06 00 00 0E 00 12 00 00
[1606654922.998475] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 05 00 00 00 80
[1606654922.998882] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 05 00 00 00 80
[1606654922.999020] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 24, data: 
0000: 81 80 05 00 01 05 0F 00 00 0F 00 13 03 02 00 00 01 00 00 00 00 00 01 73
[1606654922.999270] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x7D248957, publisher_id: 0x001(3), participant_id: 0x000(1)
[1606654922.999416] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 05 00 05 01 06 00 00 0F 00 13 00 00
[1606654922.999487] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 06 00 00 00 80
[1606654923.000105] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 06 00 00 00 80
[1606654923.102641] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 364, data: 
0000: 81 80 06 00 01 05 64 01 00 10 00 15 05 02 00 00 56 01 00 00 3C 64 64 73 3E 3C 64 61 74 61 5F 77
0020: 72 69 74 65 72 3E 3C 68 69 73 74 6F 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 50 52 45 41 4C
0040: 4C 4F 43 41 54 45 44 5F 57 49 54 48 5F 52 45 41 4C 4C 4F 43 3C 2F 68 69 73 74 6F 72 79 4D 65 6D
0060: 6F 72 79 50 6F 6C 69 63 79 3E 3C 71 6F 73 3E 3C 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 6B 69 6E
0080: 64 3E 52 45 4C 49 41 42 4C 45 3C 2F 6B 69 6E 64 3E 3C 2F 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C
00A0: 2F 71 6F 73 3E 3C 74 6F 70 69 63 3E 3C 6B 69 6E 64 3E 4E 4F 5F 4B 45 59 3C 2F 6B 69 6E 64 3E 3C
00C0: 6E 61 6D 65 3E 72 74 2F 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F 70
00E0: 75 62 6C 69 73 68 65 72 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73 67
0100: 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E 3C
0120: 68 69 73 74 6F 72 79 51 6F 73 3E 3C 6B 69 6E 64 3E 4B 45 45 50 5F 41 4C 4C 3C 2F 6B 69 6E 64 3E
0140: 3C 2F 68 69 73 74 6F 72 79 51 6F 73 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 61 74 61 5F 77 72 69 74
0160: 65 72 3E 3C 2F 64 64 73 3E 00 00 13
[1606654923.104343] debug    | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x7D248957, datawriter_id: 0x001(5), publisher_id: 0x001(3)
[1606654923.104555] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 06 00 05 01 06 00 00 10 00 15 00 00
[1606654923.104658] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 07 00 00 00 80
[1606654923.105097] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 07 00 00 00 80
[1606654923.906575] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 07 00 07 01 08 00 00 11 00 15 00 00 00 00
[1606654923.906842] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606654923.907025] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 08 00 00 00 80
Agent log without `rcl_publish(&publisherOdom, &msgOdom, NULL)`
$ docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev /dev/ttyACM0 -b 115200 -v6
[1606655020.841045] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 12
[1606655020.841166] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1606655021.400493] info     | Root.cpp           | create_client            | create                 | client_key: 0x7D248957, session_id: 0x81
[1606655021.400665] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x2099546455, address: 1
[1606655021.400927] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1606655021.500569] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 112, data: 
0000: 81 80 00 00 01 05 66 00 00 0A 00 01 01 02 00 00 57 00 00 00 3C 64 64 73 3E 3C 70 61 72 74 69 63
0020: 69 70 61 6E 74 3E 3C 72 74 70 73 3E 3C 6E 61 6D 65 3E 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75
0040: 69 6E 6F 5F 6E 6F 64 65 3C 2F 6E 61 6D 65 3E 3C 2F 72 74 70 73 3E 3C 2F 70 61 72 74 69 63 69 70
0060: 61 6E 74 3E 3C 2F 64 64 73 3E 00 00 00 00 00 00
[1606655021.507946] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x7D248957, participant_id: 0x000(1)
[1606655021.508287] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1606655021.508362] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1606655021.508818] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1606655021.610626] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 120, data: 
0000: 81 80 01 00 01 05 70 00 00 0B 00 02 02 02 00 00 62 00 00 00 3C 64 64 73 3E 3C 74 6F 70 69 63 3E
0020: 3C 6E 61 6D 65 3E 72 74 2F 6F 64 6F 6D 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 6E 61
0040: 76 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 4F 64 6F 6D 65 74 72 79 5F 3C 2F 64 61
0060: 74 61 54 79 70 65 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 64 73 3E 00 00 01
[1606655021.611411] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x7D248957, topic_id: 0x000(2), participant_id: 0x000(1)
[1606655021.611618] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 01 00 05 01 06 00 00 0B 00 02 00 00
[1606655021.611692] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1606655021.612187] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1606655021.612327] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 24, data: 
0000: 81 80 02 00 01 05 0F 00 00 0C 00 03 03 02 00 00 01 00 00 00 00 00 01 00
[1606655021.612718] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x7D248957, publisher_id: 0x000(3), participant_id: 0x000(1)
[1606655021.612870] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 02 00 05 01 06 00 00 0C 00 03 00 00
[1606655021.612931] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1606655021.613399] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1606655021.614494] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 340, data: 
0000: 81 80 03 00 01 05 4B 01 00 0D 00 05 05 02 00 00 3D 01 00 00 3C 64 64 73 3E 3C 64 61 74 61 5F 77
0020: 72 69 74 65 72 3E 3C 68 69 73 74 6F 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 50 52 45 41 4C
0040: 4C 4F 43 41 54 45 44 5F 57 49 54 48 5F 52 45 41 4C 4C 4F 43 3C 2F 68 69 73 74 6F 72 79 4D 65 6D
0060: 6F 72 79 50 6F 6C 69 63 79 3E 3C 71 6F 73 3E 3C 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 6B 69 6E
0080: 64 3E 52 45 4C 49 41 42 4C 45 3C 2F 6B 69 6E 64 3E 3C 2F 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C
00A0: 2F 71 6F 73 3E 3C 74 6F 70 69 63 3E 3C 6B 69 6E 64 3E 4E 4F 5F 4B 45 59 3C 2F 6B 69 6E 64 3E 3C
00C0: 6E 61 6D 65 3E 72 74 2F 6F 64 6F 6D 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 6E 61 76
00E0: 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 4F 64 6F 6D 65 74 72 79 5F 3C 2F 64 61 74
0100: 61 54 79 70 65 3E 3C 68 69 73 74 6F 72 79 51 6F 73 3E 3C 6B 69 6E 64 3E 4B 45 45 50 5F 41 4C 4C
0120: 3C 2F 6B 69 6E 64 3E 3C 2F 68 69 73 74 6F 72 79 51 6F 73 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 61
0140: 74 61 5F 77 72 69 74 65 72 3E 3C 2F 64 64 73 3E 00 00 03 00
[1606655021.616317] debug    | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x7D248957, datawriter_id: 0x000(5), publisher_id: 0x000(3)
[1606655021.616454] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 03 00 05 01 06 00 00 0D 00 05 00 00
[1606655021.616515] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1606655021.616938] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1606655021.617872] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 148, data: 
0000: 81 80 04 00 01 05 89 00 00 0E 00 12 02 02 00 00 7B 00 00 00 3C 64 64 73 3E 3C 74 6F 70 69 63 3E
0020: 3C 6E 61 6D 65 3E 72 74 2F 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F
0040: 70 75 62 6C 69 73 68 65 72 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73
0060: 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E
0080: 3C 2F 74 6F 70 69 63 3E 3C 2F 64 64 73 3E 00 00 01 00 00 00
[1606655021.618275] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x7D248957, topic_id: 0x001(2), participant_id: 0x000(1)
[1606655021.618425] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 04 00 05 01 06 00 00 0E 00 12 00 00
[1606655021.618531] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 05 00 00 00 80
[1606655021.619107] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 05 00 00 00 80
[1606655021.619274] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 24, data: 
0000: 81 80 05 00 01 05 0F 00 00 0F 00 13 03 02 00 00 01 00 00 00 00 00 01 73
[1606655021.619516] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x7D248957, publisher_id: 0x001(3), participant_id: 0x000(1)
[1606655021.619633] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 05 00 05 01 06 00 00 0F 00 13 00 00
[1606655021.619680] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 06 00 00 00 80
[1606655021.620314] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 06 00 00 00 80
[1606655021.722760] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 364, data: 
0000: 81 80 06 00 01 05 64 01 00 10 00 15 05 02 00 00 56 01 00 00 3C 64 64 73 3E 3C 64 61 74 61 5F 77
0020: 72 69 74 65 72 3E 3C 68 69 73 74 6F 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 50 52 45 41 4C
0040: 4C 4F 43 41 54 45 44 5F 57 49 54 48 5F 52 45 41 4C 4C 4F 43 3C 2F 68 69 73 74 6F 72 79 4D 65 6D
0060: 6F 72 79 50 6F 6C 69 63 79 3E 3C 71 6F 73 3E 3C 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 6B 69 6E
0080: 64 3E 52 45 4C 49 41 42 4C 45 3C 2F 6B 69 6E 64 3E 3C 2F 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C
00A0: 2F 71 6F 73 3E 3C 74 6F 70 69 63 3E 3C 6B 69 6E 64 3E 4E 4F 5F 4B 45 59 3C 2F 6B 69 6E 64 3E 3C
00C0: 6E 61 6D 65 3E 72 74 2F 6D 69 63 72 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 6E 6F 64 65 5F 70
00E0: 75 62 6C 69 73 68 65 72 3C 2F 6E 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73 67
0100: 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E 3C
0120: 68 69 73 74 6F 72 79 51 6F 73 3E 3C 6B 69 6E 64 3E 4B 45 45 50 5F 41 4C 4C 3C 2F 6B 69 6E 64 3E
0140: 3C 2F 68 69 73 74 6F 72 79 51 6F 73 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 61 74 61 5F 77 72 69 74
0160: 65 72 3E 3C 2F 64 64 73 3E 00 00 13
[1606655021.724216] debug    | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x7D248957, datawriter_id: 0x001(5), publisher_id: 0x001(3)
[1606655021.724337] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 14, data: 
0000: 81 80 06 00 05 01 06 00 00 10 00 15 00 00
[1606655021.724371] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 07 00 00 00 80
[1606655021.724800] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 07 00 00 00 80
[1606655022.426674] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 07 00 07 01 08 00 00 11 00 15 00 00 00 00
[1606655022.426929] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655022.427459] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 08 00 00 00 80
[1606655023.428856] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 08 00 07 01 08 00 00 12 00 15 00 00 00 00
[1606655023.429059] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655023.429223] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 09 00 00 00 80
[1606655024.430195] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 09 00 07 01 08 00 00 13 00 15 00 00 00 00
[1606655024.430506] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655024.430704] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 0A 00 00 00 80
[1606655025.432498] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 0A 00 07 01 08 00 00 14 00 15 00 00 00 00
[1606655025.432756] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655025.433077] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 0B 00 00 00 80
[1606655026.434848] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 0B 00 07 01 08 00 00 15 00 15 00 00 00 00
[1606655026.435076] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655026.435246] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 0C 00 00 00 80
[1606655027.436324] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 0C 00 07 01 08 00 00 16 00 15 00 00 00 00
[1606655027.436470] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655027.436560] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 0D 00 00 00 80
[1606655028.437801] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 0D 00 07 01 08 00 00 17 00 15 00 00 00 00
[1606655028.437957] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655028.438111] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 0E 00 00 00 80
[1606655029.439905] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 0E 00 07 01 08 00 00 18 00 15 00 00 00 00
[1606655029.440099] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655029.440228] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 0F 00 00 00 80
[1606655030.441554] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 0F 00 07 01 08 00 00 19 00 15 00 00 00 00
[1606655030.441781] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655030.441934] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 10 00 00 00 80
[1606655031.443977] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 10 00 07 01 08 00 00 1A 00 15 00 00 00 00
[1606655031.444233] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655031.444397] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 11 00 00 00 80
[1606655032.446012] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x7D248957, len: 16, data: 
0000: 81 80 11 00 07 01 08 00 00 1B 00 15 00 00 00 00
[1606655032.446224] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000001, len: 4, data: 
0000: 00 00 00 00
[1606655032.446345] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x7D248957, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 12 00 00 00 80

micro_ros_arduino with Teensy 4.1

Hello everyone,
I am currently working on a project at a company to investigate the possibility of having micro_ros on a teensy. The main goal was to check if it would be possible to have nodes initiated on the micro controller independently (without a host system with ROS 2) during boot-up.

Going through the examples and other documents related to micro-ros I learned that almost all applications required the presence of micro-ros Agent for initiating the nodes on the micro-controller.

I would like to know if this could be achieved using micro_ros.

Thanks in advance

Not getting subscription callbacks anymore after I add a timer

Hi!

Is there some official forum for user help connected to this project?

I'm having a bunch of beginner issues using micro-ros on Arduino that are tricky to find answers to online.
Is this the right place maybe? https://answers.ros.org/questions/scope:all/sort:activity-desc/tags:micro-ROS

I would be willing to help with answering questions from other new users of this project if there was some reasonably clean forum for it. Ros Answers for micro-ros seems kind of all over the place in terms of what is discussed there.

Gonna ask another beginner question here even though I don't feel it is the right place.
Don't hesitate to tell me to stop if you don't want this kind of questions here :)

  • Hardware description: openCR
  • Version or commit hash: galactic

Steps to reproduce the issue

I have been making a simple node for controlling a servo and linear motor via ros-topics and am having some trouble getting timers, subscribers and reconnection to work at the same time. When I add the timer to the executor, the subscription callbacks stops working. Here is the code:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>

rcl_publisher_t publisher;
rcl_subscription_t servo_subscriber;
rcl_subscription_t camera_elevator_subscriber;

std_msgs__msg__Int32 servo_cmd_msg;
std_msgs__msg__Int32 camera_elevator_cmd_msg;

std_msgs__msg__Int32 servo_state_msg;

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

bool micro_ros_init_successful;


#include <Servo.h>

Servo camera_servo;

int pos = 90;    // variable to store the servo position
int vel = 0;

#define LED_PIN 13
#define SERVO_PIN 5
#define ELEVATOR_ENABLE_PIN 50
#define ELEVATOR_DIRECTION_PIN 51

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){return false;}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
  (void) last_call_time;
  if (timer != NULL) {
    camera_servo.write(pos);
    rcl_publish(&publisher, &servo_state_msg, NULL);
  }
}

void servo_subscription_callback(const void * msgin)
{
  const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
  pos = msg->data;
  servo_state_msg.data = pos;
  RCSOFTCHECK(rcl_publish(&publisher, &servo_state_msg, NULL));
  camera_servo.write(pos);
}

void camera_elevator_subscription_callback(const void * msgin)
{
  const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
  servo_state_msg.data = msg->data;
  if (msg->data == 0)
  {
    // stop
    digitalWrite(ELEVATOR_ENABLE_PIN, LOW);
  } else if (msg->data > 0)
  {
    // move up
    digitalWrite(ELEVATOR_ENABLE_PIN, HIGH);
    digitalWrite(ELEVATOR_DIRECTION_PIN, HIGH);

  } else {
    // move down
    digitalWrite(ELEVATOR_ENABLE_PIN, HIGH);
    digitalWrite(ELEVATOR_DIRECTION_PIN, LOW);
  }
}


bool create_entities()
{  
  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "teensy_hardware_interface", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_default(
            &publisher,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
            "camera_servo/state_angular_pos"));

  // create servo_subscriber
  RCCHECK(rclc_subscription_init_default(
            &servo_subscriber,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
            "camera_servo/cmd_angular_pos"));

  // create camera elevator_subscriber
  RCCHECK(rclc_subscription_init_default(
            &camera_elevator_subscriber,
            &node,
            ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
            "camera_elevator/cmd_vel"));

  // create timer,
  const unsigned int timer_timeout = 100;
  RCCHECK(rclc_timer_init_default(
            &timer,
            &support,
            RCL_MS_TO_NS(timer_timeout),
            timer_callback));

  // create executor
  executor = rclc_executor_get_zero_initialized_executor();
  RCCHECK(rclc_executor_init(&executor, &support.context, 3, &allocator)); // 3 handles
  RCCHECK(rclc_executor_add_subscription(&executor, &servo_subscriber, &servo_cmd_msg, &servo_subscription_callback, ON_NEW_DATA));
  RCCHECK(rclc_executor_add_subscription(&executor, &camera_elevator_subscriber, &camera_elevator_cmd_msg, &camera_elevator_subscription_callback, ON_NEW_DATA));
  
  //Having issues getting subscriptions to work at the same time as timer
  RCCHECK(rclc_executor_add_timer(&executor, &timer));

  micro_ros_init_successful = true;
}

void destroy_entities()
{
  rcl_publisher_fini(&publisher, &node);
  rcl_subscription_fini(&servo_subscriber, &node);
  rcl_subscription_fini(&camera_elevator_subscriber, &node);
  rcl_node_fini(&node);
  rcl_timer_fini(&timer);
  rclc_executor_fini(&executor);
  rclc_support_fini(&support);

  micro_ros_init_successful = false;
}


void setup() {
  set_microros_transports();

  pinMode(LED_PIN, OUTPUT);
  pinMode(ELEVATOR_ENABLE_PIN, OUTPUT);
  pinMode(ELEVATOR_DIRECTION_PIN, OUTPUT);
  
  digitalWrite(LED_PIN, HIGH);
  digitalWrite(ELEVATOR_ENABLE_PIN, LOW);
  digitalWrite(ELEVATOR_DIRECTION_PIN, LOW);

  camera_servo.attach(SERVO_PIN); // use pin 9
 
  micro_ros_init_successful = false;
  servo_state_msg.data = 0;
}

void loop() {
  
  uint32_t delay = 100000;
  if (RMW_RET_OK == rmw_uros_ping_agent(50, 2))
  {
    delay = 100000;
    if (!micro_ros_init_successful) {
      create_entities();
    } else {
      rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
    }
  } 
  else if (micro_ros_init_successful)
  {
    destroy_entities();
  }

  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  delayMicroseconds(delay); 
}

Expected behavior

I did not expect that adding a 10Hz timer would affect the processing of subscription callbacks.

Actual behavior

The timer callback works when I add it but subscription callbacks stop working.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.