ros-drivers / rosserial

A ROS client library for small, embedded devices, such as Arduino. See: http://wiki.ros.org/rosserial
523 stars 527 forks source link

Arduino Due _SAM3XA_ baud_rate limitation at 115200 #415

Open lancemk opened 5 years ago

lancemk commented 5 years ago

My project require to publish IMU topic up to 150Hz using Arduino DUE using rosserial_python node_serial.py. We hooked up DUE and MPU9250 via i2c connection, and DUE transfer data stream via USB 2.0. Arduino sketch is as shown below:

#define _SAM3XA_
#include <ros.h>
#include <tf/transform_broadcaster.h>
#include <geometry_msgs/Vector3.h>
#include <sensor_msgs/Imu.h>

ros::NodeHandle_<ArduinoHardware, 5, 5, 256, 512> nh;   
sensor_msgs::Imu imu_msg;
ros::Publisher imu_topic("IMU_TOPIC", &imu_msg);

char base_link[] = "/base_link";
char odom[] = "/odom";

void setup() {
  nh.getHardware()->setBaud(115200);
  nh.initNode();
  nh.advertise(imu_topic);

  // start communication with IMU 
  status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: ");
    Serial.println(status);
    while(1) {}
  }
  nh.loginfo("IMU initialization successful");
 // setting the IMU
}

void loop() {

  IMU.readSensor();
  if (nh.connected()) {
  imu_msg.header.stamp = nh.now();
  imu_msg.header.frame_id = odom;

  imu_msg.linear_acceleration.x = // <TYPE_IMU_ACCEL> ;
  imu_msg.linear_acceleration.y = // <TYPE_IMU_ACCEL>;
  imu_msg.linear_acceleration.z = // <TYPE_IMU_ACCEL>;

  imu_msg.angular_velocity.x = // <TYPE_IMU_GYRO>; 
  imu_msg.angular_velocity.y = // <TYPE_IMU_GYRO>; 
  imu_msg.angular_velocity.z = // <TYPE_IMU_GYRO>; 

  imu_topic.publish(&imu_msg);

  } else {
    if(false) Serial.println("Not Connected");
  }
  nh.spinOnce();
  delayMicroseconds(1250);
}

Current topic frequency of maximum 36Hz by running rostopic hz /<TOPIC_NAME> at baud_rate = 115200. A higher baud rate setting node_serial node shows error:

[ERROR] Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino

Have tried to looked into ArduinoHardware.h https://github.com/ros-drivers/rosserial/blob/40f61b98e6865ec4127d8949158ee607d62a3aaf/rosserial_arduino/src/ros_lib/ArduinoHardware.h , but changing the baud_rate here does not help. Would like to seek help on increasing DUE MCU's baud rate.

Meanwhile, I have found an Arduino Core for SAM3X CPU library https://github.com/arduino/ArduinoCore-sam. Am trying the library. Will update if the baud_rate is able to be increased.

romainreignier commented 5 years ago

Did you try the C++ version of the rosserial server ,rosserial_server. See usage here.

Some time ago I manage to use it at 1,000,000 bauds to get at least 100 Hz on pushing a topic. But it was on a STM32, not an Arduino DUE.

vyosypenko commented 5 years ago

Try to remove delayMicroseconds(1250), and publish messages via a timer interrupt.

so the code should be while(1) { nh.spinOnce(); }

TimerISR // required time { IMU.readSensor(); if (nh.connected()) { imu_msg.header.stamp = nh.now(); imu_msg.header.frame_id = odom;

imu_msg.linear_acceleration.x = // ; imu_msg.linear_acceleration.y = // ; imu_msg.linear_acceleration.z = // ;

imu_msg.angular_velocity.x = // ; imu_msg.angular_velocity.y = // ; imu_msg.angular_velocity.z = // ;

imu_topic.publish(&imu_msg);

} else { if(false) Serial.println("Not Connected"); } }

I always get the error: "Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino"

if use while(1) { nh.spinOnce(); some delay() }

Looks like this is a bug in Rosserial

rikba commented 4 years ago

Maybe this helps. https://github.com/ros-drivers/rosserial/pull/475