micro-ROS / micro-ROS/micro_ros_arduino

IMU Data Publishing Rate too Small

Open
#1,646 12 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
576
Forks
146
PR merge metrics
No merged PRs in 30d

Description

## Issue template

- Hardware description: ESP32 Dev Module via Arduino IDE
- RTOS:
- Installation type: micro_ros_setup
- Version or commit hash: humble

#### Steps to reproduce the issue
I attach GY-85 IMU module to ESP32 and try to publish the IMU data using I2D Dev Library.
```cpp
#include

#include
#include
#include
#include
#include
#include

#include
#include

#include
#include "I2Cdev.h"
#include "ADXL345.h"

ADXL345 accel;

const float g_to_accel_ = 9.81;
const float mgauss_to_utesla_ = 0.1;
const float utesla_to_tesla_ = 0.000001;

const float accel_cov_ = 0.00001;
const float gyro_cov_ = 0.00001;
const float accel_scale_ = 1 / 256.0;
const float gyro_scale_ = 1 / 14.375;
#define LED_PIN 13
#define RCCHECK(fn) \
{ \
rcl_ret_t temp_rc = fn; \
if ((temp_rc != RCL_RET_OK)) { return false; } \
}
#define EXECUTE_EVERY_N_MS(MS, X) \
do { \
static volatile int64_t init = -1; \
if (init == -1) { init = uxr_millis(); } \
if (uxr_millis() - init > MS) { \
X; \
init = uxr_millis(); \
} \
} while (0)

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

rcl_publisher_t imuPublisher;
sensor_msgs__msg__Imu imuMsg;

bool micro_ros_init_successful;
TaskHandle_t Task1;

enum states {
WAITING_AGENT,
AGENT_AVAILABLE,
AGENT_CONNECTED,
AGENT_DISCONNECTED
} state;

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++;
imu__update();
rcl_publish(&imuPublisher, &imuMsg, NULL);
}
}

// 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_default(
&publisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"std_msgs_msg_Int32"));

// create publisher
RCCHECK(rclc_publisher_init_default(
&imuPublisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(sensor_msgs, msg, Imu),
"imu_msg"));

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

// RCCHECK(rclc_timer_init_default(
// &timer_scanning,
// &support,
// RCL_MS_TO_NS(timer_timeout),
// timer_scanning_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));
// RCCHECK(rclc_executor_add_timer(&executor, &timer_scanning));

return true;
}

void destroy_entities() {
rmw_context_t *rmw_context = rcl_context_get_rmw_context(&support.context);
(void)rmw_uros_set_context_entity_destroy_session_timeout(rmw_context, 0);

rcl_publisher_fini(&publisher, &node);
rcl_publisher_fini(&imuPublisher, &node);
rcl_timer_fini(&timer);
rcl_timer_fini(&timer_scanning);
rclc_executor_fini(&executor);
rcl_node_fini(&node);
rclc_support_fini(&support);
}

void imu__update() {
int16_t ax, ay, az;
accel.getAcceleration(&ax, &ay, &az);

double accelX = ax * (double)accel_scale_ * g_to_accel_;
double accelY = ay * (double)accel_scale_ * g_to_accel_;
double accelZ = az * (double)accel_scale_ * g_to_accel_;

double gyro_cov = 0.00001;
double accel_cov = 0.00001;
double heading_cov = 0.00001;

imuMsg.linear_acceleration.x = accelX;
imuMsg.linear_acceleration.y = accelY;
imuMsg.linear_acceleration.z = accelZ;
imuMsg.linear_acceleration_covariance[0] = accel_cov;
imuMsg.linear_acceleration_covariance[4] = accel_cov;
imuMsg.linear_acceleration_covariance[8] = accel_cov;
}
void setup() {
set_microros_transports();
pinMode(LED_PIN, OUTPUT);

state = WAITING_AGENT;
Wire.begin();
Wire.setClock(400000);
accel.initialize();
if (!accel.testConnection()) { // change to your own address
while (1) {
ESP.restart();
}
}
imuMsg.header.frame_id.data = (char *)"imu_link";
msg.data = 0;
}

void loop() {
switch (state) {
case WAITING_AGENT:
EXECUTE_EVERY_N_MS(500, state = (RMW_RET_OK == rmw_uros_ping_agent(100, 1)) ? AGENT_AVAILABLE : WAITING_AGENT;);
break;
case AGENT_AVAILABLE:
state = (true == create_entities()) ? AGENT_CONNECTED : WAITING_AGENT;
if (state == WAITING_AGENT) {
destroy_entities();
};
break;
case AGENT_CONNECTED:
EXECUTE_EVERY_N_MS(200, state = (RMW_RET_OK == rmw_uros_ping_agent(100, 1)) ? AGENT_CONNECTED : AGENT_DISCONNECTED;);
if (state == AGENT_CONNECTED) {
rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}
break;
case AGENT_DISCONNECTED:
destroy_entities();
state = WAITING_AGENT;
break;
default:
break;
}

if (state == AGENT_CONNECTED) {
digitalWrite(LED_PIN, 1);
} else {
digitalWrite(LED_PIN, 0);
}
}

```
#### Expected behavior
I expect to get 50Hz data rate (Checked using RQT Topic Monitor)

#### Actual behavior
I get only 25 Hz of data rate

#### Additional information
As addition, I have tried to publish empty IMU data (commenting all IMU code so that it is not reading anything) and just inputting constant hardcoded value. I still got 25 Hz of data rate only.

Contributor guide

Open the contributing guide

Research direction

Review loop(), timer_callback(), and the rclc_executor_spin_some call; first compare the 20 ms timer with the 100 ms spin_some timeout and agent ping checks. Reproduce the issue with the IMU code removed, then verify whether the timer callback runs at 50 Hz and compare that with the topic monitor. Done means identifying the limiting path and documenting a reproducible 50 Hz result or a confirmed library limitation.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.