PDA

View Full Version : Arduino Robot Tutorial/ROS



Atom
07-10-2011, 03:24 PM
First off I'd like to thank Fregs for starting rosserial on the ROS wiki.Without his code this tutorial wouldnt be possible.. :D

1. In order to run this tutorial you must have ROS installed running linux on your pc, with rosserial installed

http://www.ros.org/wiki/diamondback/Installation/Ubuntu
http://www.ros.org/wiki/rosserial

2. You are going to need an arduino and arduino Ide 0022 installed on your ubuntu.

http://arduino.cc/en/Main/Software

3. You will need the following hardware but if you know what you are doing you can change something..

A.. arduino uno
B.. sparkfun motoshield (http://www.sparkfun.com/products/9815 )
C.. encoders (http://www.acroname.com/robotics/parts/R346-WW-12-KIT.html)
D.. a robot base (check motorshield specs for compatiable motors)

jronald
07-10-2011, 10:03 PM
This tutorial looks interesting. Can you post the Arduino code?

Atom
07-11-2011, 02:41 AM
This tutorial is still in development... Im actually rethinking using the UNO . Not sure if I can get motorshield,quadrature encoders and a ping all on the UNO. I might go with a megamini or 2 UNO's .But I can share the basic motor drive code I have so far and someone may comment on ideas or improvements.
Here is some code to get you moving, but it uses cpp node you have to compile in ROS ..

http://answers.ros.org/question/1081/how-can-ros-communicate-with-my-microcontroller

This was my first approach but now I am moving towards Fregs packages so I will keep updating this tutorial as I get things worked out..

1.Load sketch to uno

=======================
// Test program for Sparkfun Ardumoto board with servos attached
// Copyright 2009 mechomaniac.com

// To use, connect the Arduino to a computer and send commans using a serial terminal.
// eg AR40# motor A forwards with a speed of 40
// S120# servo 1 to position 20 degrees


#include <Servo.h>

#define PwmPinMotorA 3 // this has been moved from pin 11 on the original Ardumoto
#define PwmPinMotorB 11
#define DirectionPinMotorA 12
#define DirectionPinMotorB 13
#define SerialSpeed 115200
#define BufferLength 16
#define LineEnd '#'
#define PinServo1 7
#define PinServo2 8
#define PinServo3 9
#define DefaultServoPosition 90

Servo servo1;
Servo servo2;
Servo servo3;
char inputBuffer[BufferLength];

void setup()
{
// motor and servo pins must be outputs
pinMode(PwmPinMotorA, OUTPUT);
pinMode(PwmPinMotorB, OUTPUT);
pinMode(DirectionPinMotorA, OUTPUT);
pinMode(DirectionPinMotorB, OUTPUT);
pinMode(PinServo1, OUTPUT);
pinMode(PinServo2, OUTPUT);
pinMode(PinServo3, OUTPUT);
// attach servos and set servo-specific timing details
servo1.attach(PinServo1, 600, 2100); // Tower Pro SG90 servo
servo2.attach(PinServo2, 700, 2300); // Sanwa SRM-102 servo
servo3.attach(PinServo3, 600, 2100); // Tower Pro SG90 servo
// default servo positions
servo1.write(DefaultServoPosition);
servo2.write(DefaultServoPosition);
servo3.write(DefaultServoPosition);

Serial.begin(SerialSpeed);
}

// process a command string
void HandleCommand(char* input, int length)
{
Serial.println(input);
if (length < 2) { // not a valid command
return;
}
int value = 0;
// calculate number following command
if (length > 2) {
value = atoi(&input[2]);
}
int* command = (int*)input;
// check commands
// note that the two bytes are swapped, ie 'RA' means command AR
switch(*command) {
case 'FA':
// motor A forwards
analogWrite(PwmPinMotorA, value);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case 'RA':
// motor A reverse
analogWrite(PwmPinMotorA, value);
digitalWrite(DirectionPinMotorA, LOW);
break;
case 'FB':
// motor B forwards
analogWrite(PwmPinMotorB, value);
digitalWrite(DirectionPinMotorB, LOW);
break;
case 'RB':
// motor B reverse
analogWrite(PwmPinMotorB, value);
digitalWrite(DirectionPinMotorB, HIGH);
break;
case '1S':
// servo1
servo1.write(value);
break;
case '2S':
// servo2
servo2.write(value);
break;
case '3S':
// servo 3
servo3.write(value);
break;
default:
Serial.println("unknown command");
break;
}
}

void loop()
{
// get a command string form the serial port
int inputLength = 0;
do {
while (!Serial.available()); // wait for input
inputBuffer[inputLength] = Serial.read(); // read it in
} while (inputBuffer[inputLength] != LineEnd && ++inputLength < BufferLength);
inputBuffer[inputLength] = 0; // add null terminator
HandleCommand(inputBuffer, inputLength);
}

======================================

2. roscore
3. rosrun "yourpackagedirectoy" r2Serial
4. rostopic pub /uc0Command std_msgs/String "RB120#" (use rostopic to publish serial data,see comments in arduino sketch for control parameters)


This is just to get you communicating to the arduino. I'm rewriting the sketch for rosserial using ros msgs so that I can use the turtlebot/sim teleop_key node. Im working on it but Im not the best programmer :sad: Maybe Ferg's can point us in the right direction...

Also if you read the sketch. It has servo commands setup. I was thinking about pan and tilt with mini servos you may want to edit if you wish, but this will get things rolling ....

Atom
07-11-2011, 04:16 AM
Also I am using a bluetooth silvermate to go wireless. But I will add this to the tutorial later to avoid any more confusion. .