Albeit a small one. Here's two recent videos of the robot, still remote controlled at this stage, as I'm working on getting Kinect data sent via ROS, but the high bandwidth seems to be causing problems. However, I've already got a setup where I can mount my laptop to the robot, connect the Arduino via USB and steer the whole thing from a third computer over the Wifi network using ROS.
I'm using a 12V lead-acid battery and a L298 motor driver. My motors only take 6V, so the PWM pins are running at a maximum of 50%. I'll upload the code soon.
Showing posts with label control. Show all posts
Showing posts with label control. Show all posts
Wednesday, October 12, 2011
Friday, July 1, 2011
Preliminary robot control script
I haven't updated in a while, mainly because I kept on changing and adding things about the code which controls the robot. This mostly includes ROS (Robot Operating System) functionality related to Android devices, as my plan is to mount my G2 to the robot for things like GPS and orientation polling, automatic navigation or webcam feeds. I'm coming along on that code, but for now I'll just share the bare-bones python code which lets a user control the robot with the arrow buttons on a keyboard.
As you can see, pygame is used for the keyboard input (which is probably not optimal, but I will later use the pygame window to display actual data). Checksum is not implemented yet, mainly because I'm lazy, and also because the robot has been working fine without it anyway. I'll still fix it at some point just for good practice.
import serial
import pygame
import time
import sys
pygame.init()
forward=False
left=False
right=False
back=False
q=False
speed=220
screen = pygame.display.set_mode((100,100))
#ser=serial.Serial("/dev/ttyUSB0")
ser=serial.Serial("COM12")
while True:
pygame.event.pump()
key=pygame.key.get_pressed()
forward=key[pygame.K_UP]
left=key[pygame.K_LEFT]
right=key[pygame.K_RIGHT]
back=key[pygame.K_DOWN]
q=key[pygame.K_q]
if forward and not ((left or right) or back):
LDirection="+"
RDirection="+"
LSpeed=chr(254)
RSpeed=chr(254)
elif back and not ((left or right) or forward):
LDirection="-"
RDirection="-"
LSpeed=chr(254)
RSpeed=chr(254)
elif left and not ((forward or right) or back):
LDirection="-"
RDirection="+"
LSpeed=chr(254)
RSpeed=chr(254)
elif right and not ((forward or left) or back):
LDirection="+"
RDirection="-"
LSpeed=chr(254)
RSpeed=chr(254)
elif (forward and left) and not (right or back):
LDirection="+"
RDirection="+"
LSpeed=chr(200)
RSpeed=chr(254)
elif (forward and right) and not (left or back):
LDirection="+"
RDirection="+"
LSpeed=chr(254)
RSpeed=chr(200)
elif (back and right) and not (left or forward):
LDirection="-"
RDirection="-"
LSpeed=chr(254)
RSpeed=chr(200)
elif (back and left) and not (right or forward):
LDirection="-"
RDirection="-"
LSpeed=chr(200)
RSpeed=chr(254)
else:
LDirection="-"
RDirection="-"
LSpeed=chr(0)
RSpeed=chr(0)
#checksum=ord(LDirection)+ord(LSpeed)+ord(RDirection)+ord(RSpeed)
string="s"+LDirection+LSpeed+RDirection+RSpeed+"0"+"e"
ser.write(string)
print string
if q:
pygame.quit()
sys.exit()
ser.close()
time.sleep(0.1)
As you can see, pygame is used for the keyboard input (which is probably not optimal, but I will later use the pygame window to display actual data). Checksum is not implemented yet, mainly because I'm lazy, and also because the robot has been working fine without it anyway. I'll still fix it at some point just for good practice.
Sunday, June 5, 2011
Robot schematic and Arduino sketch
Last week I posted some pictures of a robot I've started building, at the moment it's really just a remote controlled car. I've put together a schematic showing the various pin connections. I use an Arduino Uno, an XBee radio, and an L293D motor driver chip, as well as two motors (mine are 9v).

Blue and red obviously represent power and ground lines, green connections represent digital or PWM signals from and to the Arduino, and the magenta lines are PWMs from the L293D, I chose a different color because they will run at a higher voltage than the Arduino PWMs, and they power the motors.
On the Arduino, I'm running the following sketch:
As you can see, the Arduino will read its serial port (the XBee) for the character "s", which will indicate the start of a control packet. once it's found this, it reads the next characters, these will make up the rest of the packet:
Next up: the PC side script that sends packets to the robot.

Blue and red obviously represent power and ground lines, green connections represent digital or PWM signals from and to the Arduino, and the magenta lines are PWMs from the L293D, I chose a different color because they will run at a higher voltage than the Arduino PWMs, and they power the motors.
On the Arduino, I'm running the following sketch:
char index;
char serialbuff[7];
char ch;
int x=0;
int lSpeed;
int rSpeed;
int LMOTOR_DIR = 12; // Non PWM pin for direction control
int LMOTOR_PWM = 11; // PWM controlled pin.
int RMOTOR_DIR = 7;
int RMOTOR_PWM = 6;
void setup() {
Serial.begin(9600);
// Set the pins to output.
pinMode(LMOTOR_DIR, OUTPUT);
pinMode(LMOTOR_PWM, OUTPUT);
pinMode(RMOTOR_DIR, OUTPUT);
pinMode(RMOTOR_PWM, OUTPUT);
// And set these to a initial value to make sure.
digitalWrite(LMOTOR_DIR, LOW);
digitalWrite(LMOTOR_PWM, LOW);
digitalWrite(RMOTOR_DIR, LOW);
digitalWrite(RMOTOR_PWM, LOW);
}
void loop() {
switch(x){
case 0:{
ch=(char)Serial.read();
if(ch=='s'){
x=1;
serialbuff[0]=ch;
index=1;
}
}
break;
case 1:{
ch=(char)Serial.read();
if(ch!=-1){
serialbuff[index]=ch;
index++;
if(index==7){
x=2;
}
}
}
break;
case 2:{
if(serialbuff[6]=='e'){
x=3;
}
else{
x=4;
}
}
break;
case 3:{
if(serialbuff[1]=='+'){
digitalWrite(LMOTOR_DIR, HIGH);
lSpeed = 255-serialbuff[2];
}
else{
digitalWrite(LMOTOR_DIR, LOW);
lSpeed = serialbuff[2];
}
if(serialbuff[3]=='+'){
digitalWrite(RMOTOR_DIR, HIGH);
rSpeed = 255-serialbuff[4];
}
else{
digitalWrite(RMOTOR_DIR, LOW);
rSpeed = serialbuff[4];
}
analogWrite(LMOTOR_PWM, lSpeed);
analogWrite(RMOTOR_PWM, rSpeed);
x=4;
}
break;
case 4:{
index=0;
x=0;
}
break;
}
}
As you can see, the Arduino will read its serial port (the XBee) for the character "s", which will indicate the start of a control packet. once it's found this, it reads the next characters, these will make up the rest of the packet:
- serialbuff[1] is either "+" or "-", indicating the direction of the left motor.
- serialbuff[2] is the speed of the left motor and can be between 0 and 255
- serialbuff[3] and [4] are the same as [1] and [2], but for the right motor
- serialbuff[5] will eventually act as a checksum, though I haven't implemented this properly yet
- serialbuff[6] must be "e" to indicate the end of a packet, otherwise the packet is discarded and loop restarts
Next up: the PC side script that sends packets to the robot.
Subscribe to:
Posts (Atom)