ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

Rosserial_arduino use on an arduino uno with IMU (I2C/Wire library)

asked 2015-01-31 15:09:51 -0600

nvoltex gravatar image

updated 2015-02-02 15:54:19 -0600

Hey! I have been testing the rosserial_arduino ( http://wiki.ros.org/rosserial ) in order to run a ROS node on arduino. I tested some of the examples and thought I had the hang of it. (In case it's useful: I'm running Ubuntu 14.04 on a macbook pro).

However I'm unable to get the arduino node to publish information from the IMU connected to the arduino UNO. The IMU is the MPU9150 and I'm using an implementation of the I2Cdev library found here: https://github.com/richards-tech/MPU9... (I have tried a different library, in order to understand if the problem was related to this specific library, but ended up with the same problem). If I only use the MPU9150 library, that is, if I don't try to use resserial, I'm able to get the IMU data on the arduino and print it on the serial monitor. However, if I try to use rosserial I'm unable to make the node work.

When I run the serial_node from rosserial I get the following output:

nmirod@nmirod:/$ rosrun rosserial_python serial_node.py _port:=/dev/ttyACM1 _baud:=57600
[INFO] [WallTime: 1422735802.267338] ROS Serial Python Node
[INFO] [WallTime: 1422735802.270908] Connecting to /dev/ttyACM1 at 57600 baud
/home/nmirod/catkin_ws/src/rosserial/rosserial_python/src/rosserial_python/SerialClient.py:336: SyntaxWarning: The publisher should be created with an explicit keyword argument 'queue_size'. Please see http://wiki.ros.org/rospy/Overview/Publishers%20and%20Subscribers for more information.
self.pub_diagnostics = rospy.Publisher('/diagnostics', diagnostic_msgs.msg.DiagnosticArray)
[ERROR] [WallTime: 1422735819.375623] Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino

Notice that the SyntaxWarning appears even in the tutorial examples. After some testing it seems that this problem is related to the use of the Wire library. Commenting the functions that perform the initialization and reading of the IMU, I' able to get a msg on the desired topic (although constant). However, if I try to run the node as it is, I get the "Unable to sync with device" error.

Is this problem associated with the "Wire library"/I2C communication? Can you help me out?

EDIT: Is it possible to use Serial.print()'s in combination with rosserial? When I wrote this sketch I had the caution to remove all debug prints, to be sure it wouldn't scramble the communication with ros. However, when I was out of options I decided to try to use some Serial.print()'s for debugging and it seems that using Serial.begin(57600) solved the problem (same baud rate as the node).

Althought the problem seems to be solved I still would like to understand what's going on so that if something similar happens down the road I know what to do.

EDIT2: Here is the code:

#include "ros.h"
#include "rospy_tutorials/Floats.h"

#include "freeram.h"
#include "mpu.h"
#include "I2Cdev.h"

ros::NodeHandle  nh;

float aux[] = {9, 9, 9, 9 ...
(more)
edit retag flag offensive close merge delete

Comments

I've used the i2c library without any isseus. Try publishing slower on the arduino.

tonybaltovski gravatar image tonybaltovski  ( 2015-01-31 17:24:14 -0600 )edit

Could you check my edit? I still don't understand what's happening.

nvoltex gravatar image nvoltex  ( 2015-02-01 05:28:00 -0600 )edit
1

Can you post your code? Did you try slowing down the publishing rate?

tonybaltovski gravatar image tonybaltovski  ( 2015-02-01 13:41:01 -0600 )edit

I have added the code, but note that it's the code before adding the subscriber. By slowing down the publishing rate are you talking about the baudrate used on the node? (thanks for helping!)

nvoltex gravatar image nvoltex  ( 2015-02-02 11:13:23 -0600 )edit
1

I meant adding delay(15); or publishing at a certain rate. You maybe overfilling the serial buffer.

tonybaltovski gravatar image tonybaltovski  ( 2015-02-02 12:47:18 -0600 )edit

At the time I tried using different delays however it didn't help. With the addition of Serial.begin() it started working, althought I don't know why that would help. However when I try to add a subscriber to the node, the IMU stops responding (I think he fails to initialize).

nvoltex gravatar image nvoltex  ( 2015-02-02 13:01:01 -0600 )edit
1

Try initializing the node before you start the i2c comm. Also, try manually setting the baud nh.getHardware()->setBaud(BAUD); before the node initializes.

tonybaltovski gravatar image tonybaltovski  ( 2015-02-02 13:50:13 -0600 )edit

I tried your suggestions and still got the same problem. I made an edit with some new information and the code I'm using right now.

nvoltex gravatar image nvoltex  ( 2015-02-02 14:32:33 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
0

answered 2015-02-06 06:55:09 -0600

nvoltex gravatar image

updated 2015-02-06 06:57:51 -0600

In the original problem I was trying to use the DMP of the MPU9150 in order to do the calculations to obtain the Yaw, Pitch and Roll directly from the MPU. However it seemed like the rosserial communication was messing up the DMP configuration and I wasn't able to make the DMP configuration to work once I tried to add both a subscriber and a publisher to the node.

The work-around I ended up using is to simply get the raw data from the IMU (magnetometer, gyro and accelerometer) and publish it to the desired topic. Then I could add a subscriber and I would still be able to get the raw data from the IMU. This raw data is then processed by a node on the PC and outputs the desired information to another topic.

Note: I would like to thanks tonybaltovski for all the help and I leave here the link to his repository where he uses rosserial in combination with I2C communication with a IMU: https://github.com/tonybaltovski/ros_...

edit flag offensive delete link more

Comments

Try declaring your node handle before you include wire.

tonybaltovski gravatar image tonybaltovski  ( 2015-02-09 21:52:45 -0600 )edit

I already tried that and it didn't solve the problem. Unfortunately I wasn't able to receive an answer from the developers of the library. Tried to contact the developers of rosserial, but no response either.

nvoltex gravatar image nvoltex  ( 2015-02-11 06:44:44 -0600 )edit
1

answered 2015-02-02 18:52:59 -0600

updated 2015-02-02 18:53:45 -0600

I was able to run this on an Uno:

#include <ros.h>
#include <rospy_tutorials/Floats.h>
#include <std_msgs/Empty.h>

//#include "freeram.h"
//#include "mpu.h"
//#include "I2Cdev.h"
//#include "Wire.h"


//PORTS ASSIGNING
const int motor11       = 8;
const int motor12       = 7;
const int motor21       = 5;
const int motor22       = 4;
const int motorcontrol1 = 6;
const int motorcontrol2 = 11;

//MOTOR CONTROL VARIABLES
int motorflag = 0;
float motor1output = 0;
float motor2output = 0;

ros::NodeHandle  nh;



float aux[] = {9, 9, 9, 9};
rospy_tutorials::Floats msg;

ros::Publisher IMUdata("IMUdata", &msg);

int ret;

void receiveMotorControl(const rospy_tutorials::Floats& controlarray){
  motor1output = controlarray.data[0];
  motor2output = controlarray.data[1];
  motorflag = 1;
  nh.loginfo("Got a callback");
}
ros::Subscriber<rospy_tutorials::Floats> sub("motorControl", &receiveMotorControl);

void setup()
{ 
  nh.getHardware()->setBaud(57600);
  nh.initNode();
  nh.advertise(IMUdata);
  nh.subscribe(sub);

  //Wire.begin();
  //Fastwire::setup(400,0);

  //ret = mympu_open(200);
  msg.data_length = 4;

  //PORT SETUP
  pinMode(motor11, OUTPUT);
  pinMode(motor12, OUTPUT);
  pinMode(motor21, OUTPUT);
  pinMode(motor22, OUTPUT);
   while (!nh.connected()) 
  {
    nh.spinOnce();
  }
  nh.loginfo("Connected to microcontroller.");

}

void loop()
{ 
//  if(motorflag == 1){
//    motorControl();
//  }

  //ret = mympu_update();

  //if(ret == 0){
  //    aux[0] = mympu.ypr[0];
  //    aux[1] = mympu.ypr[1];
  //    aux[2] = mympu.ypr[2];
  //}
  //aux[3] = ret;

  //msg.data = aux;

  IMUdata.publish( &msg );
  nh.spinOnce();
  delay(1000);
}

void motorControl(){
  if(motorflag){
    if(motor1output >= 0){
      digitalWrite(motor11, HIGH);
      digitalWrite(motor12, LOW);
      analogWrite(motorcontrol1, motor1output);
    }
    else{
      digitalWrite(motor11, LOW);
      digitalWrite(motor12, HIGH);
      analogWrite(motorcontrol1, abs(motor1output));
    }
    if(motor2output >= 0){
      digitalWrite(motor21, HIGH);
      digitalWrite(motor22, LOW);
      analogWrite(motorcontrol2, motor2output);
    }
    else{
      digitalWrite(motor21, LOW);
      digitalWrite(motor22, HIGH);
      analogWrite(motorcontrol2, abs(motor2output));
    }
    motorflag = 0;
  }
}
edit flag offensive delete link more

Comments

That code I would be able to run as well since the problem is connected with the rosserial connection scrambling the I2C communication.

nvoltex gravatar image nvoltex  ( 2015-02-03 06:26:25 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-01-31 15:09:51 -0600

Seen: 6,032 times

Last updated: Feb 06 '15