The FollowMeBot follows the user based on the color of his or her shirt. The device hosts a webcam on a servo to find the object and orient the robot. The color is chosen through the user interface with push buttons. Currently, the MATLAB code supports red and green detection. The purpose of FollowMeBot is to be able to follow the user in order to be helpful for daily tasks.
Dependencies: Rectangle Servo TextLCD mbed
Fork of FollowMeBot3 by
Revision 1:6c399fc35deb, committed 2013-11-18
- Comitter:
- dhamilton31
- Date:
- Mon Nov 18 21:09:13 2013 +0000
- Parent:
- 0:3ed56271dd2d
- Child:
- 2:0b362c662997
- Commit message:
- how many things must I commit?!?
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Rectangle.lib Mon Nov 18 21:09:13 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/projetremote/code/Rectangle/#d9c0709ba2ce
--- a/Servo.lib Mon Nov 11 19:22:13 2013 +0000 +++ b/Servo.lib Mon Nov 18 21:09:13 2013 +0000 @@ -1,1 +1,1 @@ -https://mbed.org/users/simon/code/Servo/#d67ccd284081 +https://mbed.org/users/simon/code/Servo/#dec99beeafee
--- a/iRobot.cpp Mon Nov 11 19:22:13 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -#include "mbed.h" -#include "iRobot.h" - -// Definitions of iRobot Create OpenInterface Command Numbers -// See the Create OpenInterface manual for a complete list - - iRobot::iRobot(PinName tx, PinName rx) : device(tx, rx){ - speed_left = 200; - speed_right = 200; - } - -// Start - send start and safe mode, start streaming sensor data -void iRobot::start() { - // device.printf("%c%c", Start, SafeMode); - device.putc(Start); - device.putc(SafeMode); - wait(.5); - // device.printf("%c%c%c", SensorStream, char(1), BumpsandDrops); - device.putc(SensorStream); - device.putc(1); - device.putc(BumpsandDrops); - wait(.5); -} -// Stop - turn off drive motors -void iRobot::stop() { - device.printf("%c%c%c%c%c", DriveDirect, char(0), char(0), char(0), char(0)); -} -// Forward - turn on drive motors -void iRobot::forward() { - device.printf("%c%c%c%c%c", DriveDirect, char((speed_right>>8)&0xFF), char(speed_right&0xFF), - char((speed_left>>8)&0xFF), char(speed_left&0xFF)); - -} -// Reverse - reverse drive motors -void iRobot::reverse() { - device.printf("%c%c%c%c%c", DriveDirect, char(((-speed_right)>>8)&0xFF), char((-speed_right)&0xFF), - char(((-speed_left)>>8)&0xFF), char((-speed_left)&0xFF)); - -} -// Left - drive motors set to rotate to left -void iRobot::left() { - device.printf("%c%c%c%c%c", DriveDirect, char((speed_right>>8)&0xFF), char(speed_right&0xFF), - char(((-speed_left)>>8)&0xFF), char((-speed_left)&0xFF)); -} -// Right - drive motors set to rotate to right -void iRobot::right() { - device.printf("%c%c%c%c%c", DriveDirect, char(((-speed_right)>>8)&0xFF), char((-speed_right)&0xFF), - char((speed_left>>8)&0xFF), char(speed_left&0xFF)); - -} -// Charger - search and return to charger using IR beacons (if found) -void iRobot::charger() { - device.printf("%c%c", Demo, char(1)); -} -// Play Song - define and play a song -void iRobot::playsong() { // Send out notes & duration to define song and then play song - - device.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", - Song, char(0), char(16), char(91), char(24), char(89), char(12), char(87), char(36), char(87), - char(24), char(89), char(12), char(91), char(24), char(91), char(12), char(91), char(12), char(89), - char(12),char(87), char(12), char(89), char(12), char(91), char(12), char(89), char(12), char(87), - char(24), char(86), char(12), char(87), char(48)); - - wait(.2); - device.printf("%c%c", PlaySong, char(0)); -} \ No newline at end of file
--- a/iRobot.h Mon Nov 11 19:22:13 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -#ifndef __IROBOT__ -#define __IROBOT__ - -#include "mbed.h" - -class iRobot -{ - -public: - - iRobot(PinName tx, PinName rx); - void start(); - void forward(); - void reverse(); - void left(); - void right(); - void stop(); - void playsong(); - void charger(); - -private: - - // Create Command // Arguments - static const char Start = 128; - static const char SafeMode = 131; - static const char FullMode = 132; - static const char Drive = 137; // 4: [Vel. Hi] [Vel Low] [Rad. Hi] [Rad. Low] - static const char DriveDirect = 145; // 4: [Right Hi] [Right Low] [Left Hi] [Left Low] - static const char Demo = 136; // 2: Run Demo x - static const char Sensors = 142; // 1: Sensor Packet ID - static const char CoverandDock = 143; // 1: Return to Charger - static const char SensorStream = 148; // x+1: [# of packets requested] IDs of requested packets to stream - static const char QueryList = 149; // x+1: [# of packets requested] IDs of requested packets to stream - static const char StreamPause = 150; // 1: 0 = stop stream, 1 = start stream - static const char PlaySong = 141; - static const char Song = 140; - static const char BumpsandDrops = 7; - static const char Distance = 19; - static const char Angle = 20; - - int speed_left; - int speed_right; - Serial device; -}; - -#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iRobot/iRobot.cpp Mon Nov 18 21:09:13 2013 +0000 @@ -0,0 +1,143 @@ +#include "mbed.h" +#include "iRobot.h" + +// Definitions of iRobot Create OpenInterface Command Numbers +// See the Create OpenInterface manual for a complete list + +iRobot::iRobot(PinName tx, PinName rx) : device(tx, rx) +{ + speed_left = 100; + speed_right = 100; + // set baud rate for Create factory default + device.baud(57600); +} + +void iRobot::changeSpeed(int speed) +{ + speed_left = speed; + speed_right = speed; +} + +char iRobot::sensorCode() +{ + char error = Sensor_Data_Byte_Error; + Sensor_Data_Byte_Error = 0; + return error; +} + +// Start - send start and safe mode, start streaming sensor data +void iRobot::start() +{ + // device.printf("%c%c", Start, SafeMode); + device.putc(Start); + device.putc(SafeMode); + wait(.5); + // device.printf("%c%c%c", SensorStream, char(1), BumpsandDrops); + device.putc(SensorStream); + device.putc(1); + device.putc(BumpsandDrops); + wait(.2); + // Setup a serial interrupt function to receive data + device.attach(this, &iRobot::receive_sensor); +} +// Stop - turn off drive motors +void iRobot::stop() +{ + device.printf("%c%c%c%c%c", DriveDirect, char(0), char(0), char(0), char(0)); +} +// Forward - turn on drive motors +void iRobot::forward() +{ + device.printf("%c%c%c%c%c", DriveDirect, char((speed_right>>8)&0xFF), char(speed_right&0xFF), + char((speed_left>>8)&0xFF), char(speed_left&0xFF)); + +} +// Reverse - reverse drive motors +void iRobot::reverse() +{ + device.printf("%c%c%c%c%c", DriveDirect, char(((-speed_right)>>8)&0xFF), char((-speed_right)&0xFF), + char(((-speed_left)>>8)&0xFF), char((-speed_left)&0xFF)); + +} +// Left - drive motors set to rotate to left +void iRobot::left() +{ + device.printf("%c%c%c%c%c", DriveDirect, char((speed_right>>8)&0xFF), char(speed_right&0xFF), + char(((-speed_left)>>8)&0xFF), char((-speed_left)&0xFF)); +} +// Right - drive motors set to rotate to right +void iRobot::right() +{ + device.printf("%c%c%c%c%c", DriveDirect, char(((-speed_right)>>8)&0xFF), char((-speed_right)&0xFF), + char((speed_left>>8)&0xFF), char(speed_left&0xFF)); + +} +// Charger - search and return to charger using IR beacons (if found) +void iRobot::charger() +{ + device.printf("%c%c", Demo, char(1)); +} + +// Play Song - define and play a song +void iRobot::playsong() // Send out notes & duration to define song and then play song +{ + + device.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + Song, char(0), char(16), char(91), char(24), char(89), char(12), char(87), char(36), char(87), + char(24), char(89), char(12), char(91), char(24), char(91), char(12), char(91), char(12), char(89), + char(12),char(87), char(12), char(89), char(12), char(91), char(12), char(89), char(12), char(87), + char(24), char(86), char(12), char(87), char(48)); + + wait(.2); + device.printf("%c%c", PlaySong, char(0)); +} + +// Interrupt Routine to read in serial sensor data packets - BumpandDrop sensor only +void iRobot::receive_sensor() +{ + char start_character; +// Loop just in case more than one character is in UART's receive FIFO buffer + while (device.readable()) { + switch (Sensor_byte_count) { +// Wait for Sensor Data Packet Header of 19 + case 0: { + start_character = device.getc(); + if (start_character == 19) Sensor_byte_count++; + break; + } +// Number of Packet Bytes + case 1: { + Sensor_Num_Bytes = device.getc(); + Sensor_byte_count++; + break; + } +// Sensor ID of next data value + case 2: { + Sensor_ID = device.getc(); + Sensor_byte_count++; + break; + } +// Sensor data value + case 3: { + Sensor_Data_Byte = device.getc(); + if(Sensor_Data_Byte != 0){ + Sensor_Data_Byte_Error = Sensor_Data_Byte; + } + Sensor_byte_count++; + break; + } +// Read Checksum and update LEDs with sensor data + case 4: { + Sensor_Checksum = device.getc(); + // Could add code here to check the checksum and ignore a bad data packet + /*led1 = Sensor_Data_Byte &0x01; + led2 = Sensor_Data_Byte &0x02; + led3 = Sensor_Data_Byte &0x04; + led4 = Sensor_Data_Byte &0x08;*/ + Sensor_byte_count = 0; + break; + } + } + } + return; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iRobot/iRobot.h Mon Nov 18 21:09:13 2013 +0000 @@ -0,0 +1,56 @@ +#ifndef __IROBOT__ +#define __IROBOT__ + +#include "mbed.h" + +class iRobot +{ + +public: + + iRobot(PinName tx, PinName rx); + void start(); + void forward(); + void reverse(); + void left(); + void right(); + void stop(); + void playsong(); + void charger(); + void changeSpeed(int speed); + void receive_sensor(); + char sensorCode(); + +private: + + // Create Command // Arguments + static const char Start = 128; + static const char SafeMode = 131; + static const char FullMode = 132; + static const char Drive = 137; // 4: [Vel. Hi] [Vel Low] [Rad. Hi] [Rad. Low] + static const char DriveDirect = 145; // 4: [Right Hi] [Right Low] [Left Hi] [Left Low] + static const char Demo = 136; // 2: Run Demo x + static const char Sensors = 142; // 1: Sensor Packet ID + static const char CoverandDock = 143; // 1: Return to Charger + static const char SensorStream = 148; // x+1: [# of packets requested] IDs of requested packets to stream + static const char QueryList = 149; // x+1: [# of packets requested] IDs of requested packets to stream + static const char StreamPause = 150; // 1: 0 = stop stream, 1 = start stream + static const char PlaySong = 141; + static const char Song = 140; + static const char BumpsandDrops = 7; + static const char Distance = 19; + static const char Angle = 20; + /* Global variables with sensor packet info */ + char Sensor_byte_count; + char Sensor_Data_Byte; + char Sensor_Data_Byte_Error; + char Sensor_ID; + char Sensor_Num_Bytes; + char Sensor_Checksum; + + int speed_left; + int speed_right; + Serial device; +}; + +#endif \ No newline at end of file
--- a/main.cpp Mon Nov 11 19:22:13 2013 +0000 +++ b/main.cpp Mon Nov 18 21:09:13 2013 +0000 @@ -1,17 +1,51 @@ #include "mbed.h" #include "iRobot.h" #include "Servo.h" +#include "Rectangle.h" -DigitalOut myled(LED1); +// Macros/Constants +#define MAX_VIEW_X 1024 // maximum X value input from camera +#define MAX_VIEW_Y 1024 // maximum Y value input from camera +#define CENTER_BOX_TOLLERANCE 15 // Size of our box +#define TO_SERVO_DIVISOR 100.0 // Value to divide by to get the amount to move the servo by -int main() { - iRobot followMeBot(p9, p10); - Servo servoHor(p22); - Servo servoVer(p21); +// Hardware sensors and devices +DigitalOut myled(LED1); +iRobot followMeBot(p9, p10); +Servo servoHor(p22); +Servo servoVer(p21); +AnalogIn irSensorFront(p20); +AnalogIn irSensorLeft(p19); +AnalogIn irSensorRight(p18); +Serial pc(USBTX, USBRX); // tx, rx + +// Software variables +char serial_rx_buffer[128]; // Input buffer for data from the PC +int xpos, ypos; // x and y positions read from matlab +Rectangle centerBox((MAX_VIEW_X/2)+CENTER_BOX_TOLLERANCE, (MAX_VIEW_Y/2)+CENTER_BOX_TOLLERANCE, + (MAX_VIEW_X/2)-CENTER_BOX_TOLLERANCE,(MAX_VIEW_Y/2)-CENTER_BOX_TOLLERANCE); // Creates a box to examine if the camera is well enough centered + +int main() +{ + followMeBot.start(); + while(1) { - myled = 1; - wait(0.2); - myled = 0; - wait(0.2); } } + +void moveCamera() +{ + if(!centerBox.is_touch(xpos, ypos)) { + float temp; + temp = servoHor.read() + ((float)centerBox.getCenterX() - (float)xpos)/TO_SERVO_DIVISOR; + if(temp > 0 && temp <= 1) { + servoHor = temp; + } + temp = servoVer.read() + ((float)centerBox.getCenterY() - (float)ypos)/TO_SERVO_DIVISOR; + if(temp > 0 && temp <= 1) { + servoVer = temp; + } + } +} + +