micro-ROS / micro_ros_arduino

micro-ROS library for Arduino
Apache License 2.0
437 stars 113 forks source link

micro-ros-publisher keeps publishing the same value over and over even though I update the message every callback. #1847

Open mathew4STAR opened 4 days ago

mathew4STAR commented 4 days ago

I am using micro ros to send imu data from a esp32 to my laptop running ros(on a virtual machine). The topic shows up, and so does the data except that it just outputs the same values over and over, even If I move the imu, and its completely different from the values I get if I just display the values on serial monitor. Can anyone tell me what going wrong?

Here's the full 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>
#include <sensor_msgs/msg/imu.h>
#include <std_msgs/msg/header.h>

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

rcl_publisher_t publisher;
sensor_msgs__msg__Imu Message;
std_msgs__msg__Header hdr;

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

Adafruit_MPU6050 mpu;

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, &Message, NULL));
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);
    Message.header = hdr;
    Message.linear_acceleration.x = double(a.acceleration.x);
    Message.linear_acceleration.y = double(a.acceleration.y);
    Message.linear_acceleration.z = double(a.acceleration.z);

    Message.angular_velocity.x = double(g.gyro.x);
    Message.angular_velocity.y = double(g.gyro.y);
    Message.angular_velocity.z = double(g.gyro.z);

  }
}

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(sensor_msgs, msg, Imu),
    "imu/data"));

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

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));
  Message.linear_acceleration.x = double(0);
  Message.linear_acceleration.y = double(0);
  Message.linear_acceleration.z = double(0);

  Message.angular_velocity.x = double(0);
  Message.angular_velocity.y = double(0);
  Message.angular_velocity.z = double(0);

}

void loop() {
  delay(100);
  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
  sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);
    Message.header = hdr;
    Message.linear_acceleration.x = double(a.acceleration.x);
    Message.linear_acceleration.y = double(a.acceleration.y);
    Message.linear_acceleration.z = double(a.acceleration.z);

    Message.angular_velocity.x = double(g.gyro.x);
    Message.angular_velocity.y = double(g.gyro.y);
    Message.angular_velocity.z = double(g.gyro.z);
}
hippo5329 commented 4 days ago

You will need to verify the data from the imu driver. You may follow the linorobot2_hardware wiki, https://github.com/hippo5329/linorobot2_hardware/wiki. You may run the test_sensors to check the data from the imu.