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
}
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
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