Skip to content

rmw_uros_ping_agent is acting as a delay in the code #506

@B00M3RSIX

Description

@B00M3RSIX

OK, so i tried to implement the implement the example (modified micro-ros_reconnection_example.ino) in my code and faced some weird behaviour as my code took a lot more executiontime than before. Then I was playing around with the example itself and could reproduce it.
I found out that rmw_uros_ping_agent is acting as a delay in the code.

Setup

  • Hardware description: teensy 4.0
  • RTOS: none
  • Installation type: PlatformIO as IDE, uROS Agent running in Docker on XavierNX, teensy connected via USB-serial (/dev/ttyACM0)
  • Version or commit hash: galactic 2.0.1

Steps to reproduce the issue

modified micro-ros_reconnection_example.ino
(see code listing below)

Expected behavior

Returning with RMW_RET_OK==true from rmw_uros_ping_agent as fast as possible, when ping succeeded.
Wait for timeout if Ping is not successful and retry the given amount of attemts and return with RMW_RET_OK==false.

Actual behavior

Wether Ping is successful or not, rmw_uros_ping_agent is blocking the code the full timeoutperiod and is acting as a delay.
if (RMW_RET_OK == rmw_uros_ping_agent(500, 2)) --> Loop takes alway ~500 ms if Ping is ok
if (RMW_RET_OK == rmw_uros_ping_agent(10, 2)) --> Loop takes alway ~10 ms also if Ping is ok
if (RMW_RET_OK == rmw_uros_ping_agent(1, 2)) --> Loop takes alway ~1 ms also if Ping is ok

Additional information

#include <micro_ros_arduino.h>
#include <Arduino.h>                                   //<--------------- Added (for PlatformIO)
#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <rmw_microros/rmw_microros.h>

#include <std_msgs/msg/int32.h>

#define LED_PIN 13
#define ROS_LED_PIN 23                                          //<--------------- Added
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){return false;}}

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

elapsedMicros tc; // ADDED TO MEASURE CYCLETIME OF LOOP INC MICROS

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

// Functions create_entities and destroy_entities can take several seconds.
// In order to reduce this rebuild the library with 
// - RMW_UXRCE_ENTITY_CREATION_DESTROY_TIMEOUT=0
// - UCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS=3

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, "int32_publisher_rclc", "", &support));

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

	// create timer,
	const unsigned int timer_timeout = 1;       //<--------------- Modified
	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, 1, &allocator));
	RCCHECK(rclc_executor_add_timer(&executor, &timer));

	micro_ros_init_successful = true;
}

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

	micro_ros_init_successful = false;
}

void setup() {
  Serial4.begin(115200);                                  //<--------------- Added
  set_microros_transports(); 
  pinMode(LED_PIN, OUTPUT);
  pinMode(ROS_LED_PIN, OUTPUT);              //<--------------- Added
  digitalWrite(LED_PIN, HIGH);  
  digitalWrite(ROS_LED_PIN, LOW);                //<--------------- Added

  micro_ros_init_successful = false;
  msg.data = 0;
}

void loop() {
   uint32_t delay = 100000;
  if (RMW_RET_OK == rmw_uros_ping_agent(1, 2))                          //<--------------- Modified
  {
    delay = 500000;
    if (!micro_ros_init_successful) {
      create_entities();
      digitalWrite(ROS_LED_PIN, HIGH);               //<--------------- Added
      Serial4.println("Create");                                                          //<--------------- Added
    } else {
      rclc_executor_spin_some(&executor, RCL_MS_TO_NS(1));     //<--------------- Modified
    }
  } 
  else if (micro_ros_init_successful)
  {
    digitalWrite(ROS_LED_PIN, LOW);               //<--------------- Added
    destroy_entities();
    Serial4.println("Destroy");                                      //<--------------- Added
  }
  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  //delayMicroseconds(delay);                           <--------------- removed

  Serial4.println(tc);                           //<--------------- Added
  tc = 0;                                            //<--------------- Added

}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions