Update- Laser Cat

I cant think of a good name, but im sure theres a good one somewhere, if any of you think of anything let me know.

 

Laser Cat

 

The idea of this project is to help me learn a few things needed for my longterm project Airborne bot. It is basicaly a laser controlled by an arduino using two servos. It is for my two cats Harry and Fifi (girls cat. Fifi ffs! ) to play with.

 

WHen it is complete it will enable me to move the laser using a web page with a control panel and a video feed the user will click a position on the video feed and the laser will move to that point with the cats chasing it. Each time a cat manages to hit the laser point with its paw it will gain a point. THe first one to ten will get a treat which will be thrown to it from the unit.

 

Im using processing to build the control panel for it to process the image from the camera and send serial output to the arduino to give the servos their position. The scoring will be worked out by dividing the target wall up into paw sized grid blocks. I think i can work out whether the cat has scored by working out if there is a change in color in the wall in that grid and if the grid thats changed is the one that the laser is in at the time, my theory is that thelicght cream wall with eiher go ginger or black letting me know which cat got the point. Possible problems that i will have to work round is differentiating between cat paw color change and laser color change.

 

So far i have the base unit built so that i can lay some code down, and i have the video feed going to processing and being displayed on screen. The servo is able to move along the x axis controled by mouse clicks. However im finding it difficult to control two servos through serial communication.

 

Eventually i plan to have the unit completely wireless and mounted in the garden.

 

The aims of this project are to help me gain a better understanding of the following areas:

 

 

serial communication

working with coordinates

controling things with processing

working with video

wireless communication

 

 

 

Update 13/ april/ 09

Ive finaly finished writing the code for the control of it. Unfortunatly i have played with it so much that my ginger cat is frustrated with it and the black cat isnt here so i cant post a video of them playing with it yet.

 

 

 

Here is the arduino code:

#include <Servo.h>

 

 

 

Servo myservo1; // create servo object to control a servo

 

Servo myservo2;

 

 

 

int userInput[3]; // raw input from serial buffer, 3 bytes

 

int startbyte; // start byte, begin reading input

 

int pos = 0; // variable to store the servo position

 

int i; // iterator

 

 

 

void setup()

 

{

 

// attaches the servos on pin 9 and 10 to the servo object

myservo1.attach(9); //x axis

myservo2.attach(10); //y axis

Serial.begin(9600);

 

}

 

 

void loop()

 

{

 

// if the buffer has the right ammount of data in it

 

if (Serial.available() > 2) {

 

//read the first byte

 

startbyte = Serial.read();

// if it's really the startbyte (255)

 

if (startbyte == 255) {

 

// then get the next two bytes

for (i=0;i<2;i++) {

 

userInput[i] = Serial.read();

 

}

 

 

// first byte is the servo we want to move

 

int servo1 = userInput[0];

 

// second byte = which position?

 

int servoPosition1 = userInput[1];

 

// print some debug lines to the serial port

 

Serial.print("Servo: " );

 

Serial.print(servo1);

 

Serial.print(" Move: ");

 

// map the input from the serial port to the min and max for the

 

// camera width

 

servoPosition1 = map(servoPosition1, 0, 179, 78,108);

 

Serial.print(servoPosition1);

 

myservo1.write(servoPosition1);

 

}

 

//repeat for servo 2

 

if (startbyte == 254) {

 

// then get the next two bytes

 

for (i=0;i<2;i++) {

 

userInput[i] = Serial.read();

 

}

 

 

int servo2 = userInput[0];

 

// second byte = which position?

 

int servoPosition2= userInput[1];

Serial.print("Servo: " );

Serial.print(servo2);

Serial.print(" Move: ");

Serial.print(servoPosition2);

servoPosition2 = map(servoPosition2, 119, 1, 54, 78);

Serial.print(servoPosition2);

myservo2.write(servoPosition2);

 

}

}

 

}

 

 

 

I need to neaten the code up a bit and correct an error with recognising which server to move, but it works.

 

Here is the processing code:

import fullscreen.*;

 

import processing.serial.*;

import processing.video.*;

FullScreen fs;

Serial port;

//set up a few settings for the gui. you need to change this to the

// screen resolution you are using

int scrnWidth=1024; //width of screen, full screen comming soon!!

int scrnHeight=768; //height of screen

int camSizeX=640; //width of cam box

int camSizeY=480; //height of cam box

 

// layout settings.

int leftMargin = round((scrnWidth - camSizeX) / 2);

 

int camPosX=leftMargin;//x coordinate of top left corner of camera box

int camPosY=0;//y coordinate of top left corner of camera box

int textOffsetX=leftMargin + 0;

int textOffsetY = camSizeY + 5;

 

// serial in variables to hold any values given back from the arduino

String returnText="";

 

 

Serial myPort; // The serial port

Capture cam;

int inByte =0;

int read=0;

void setup()

{

size(scrnWidth, scrnHeight);

// Create the fullscreen object

// fs = new FullScreen(this);

 

// enter fullscreen mode

// fs.enter();

 

 

 

cam = new Capture(this, camSizeX, camSizeY);

 

//set up the text settings

 

 

//sets the port to the one your arduino is using

myPort = new Serial(this, "COM3", 9600);

 

}

 

void draw()

{

 

PFont font;

font = loadFont("Verdana-48.vlw");

textFont(font);

 

background(32, 62, 22);

//guideLines();

 

camDisplay(); //put cam on screen

 

mousePos(); // put mouse pos on screen

 

 

 

//drawGrid();

 

while (myPort.available() > 0) {

int gb = myPort.read();

char fg = char(gb);

println(fg);

 

String inBuffer = myPort.readString();

if (inBuffer != null) {

println(inBuffer);

returnText=inBuffer;

}

 

// text("Recieved", 5, 482);

//text(inByte, 220, 482);

}

 

}

 

 

void mousePressed() {

fill(6, 191, 41);

int posNewX = round( 179 - (mouseX - 190) / 3.6 ) ;

int posNewY =mouseY / 4;

 

 

 

char c = char(255);

 

myPort.write(c);

myPort.write(char(1));

myPort.write(posNewX);

text( "Here:" + posNewX, 5, 560);

 

 

char d = char(254);

 

myPort.write(d);

myPort.write(char(2));

myPort.write(char(posNewY));

text( posNewY, 5, 540);

 

}

 

 

 

void mousePos(){

 

fill(6, 191, 41);

textSize(14);

text("mouseX: " + mouseX + " / " + "mouseY" + mouseY, textOffsetX, camSizeY-10);

//text(mouseX, 210, 510);

int msPo=179 - round(mouseX / 3.6);

text("sent " + msPo, textOffsetX, camSizeY + 20);

text(returnText, textOffsetX, camSizeY + 40);

//text("mouseY", 5, 441);

//text(mouseY, 210, 441);

 

}

 

void camDisplay(){

 

if (cam.available() == true) {

cam.read();

image(cam, camPosX, camPosY);

// The following does the same, and is faster when just drawing the image

// without any additional resizing, transformations, or tint.

//set(160, 100, cam);

}

 

 

}

 

void guideLines(){

stroke(240, 17, 17);

line(78, 0, 78, scrnHeight);

line(108, 0, 108, scrnHeight);

 

}

 

void drawGrid(){

stroke(36, 137, 48);

for (int i = 10; i < scrnWidth; i+=10) {

line(i, 00, i, scrnHeight);

 

//line(i, 0, i, 150);

}

for (int i = camPosY; i < camPosY + camSizeY + 10; i+=10){

//ne(0, i, scrnWidth, i);

line(camPosX, i, camSizeX, i );

 

//line(i, 0, i, 150);

}

}

 

To get processing to pic up my cam i had to install vdig, there are ways to do it without vdig though, see the processing.org site for details.

 

As soon sd my cat gets in i will post a video , in the meantime im going to tidy my code up.

 

 


This is a companion discussion topic for the original entry at https://community.robotshop.com/robots/show/update-laser-cat

cats and lasers = fun

my cat goes MAD when it sees a laser point, it will never stop chasing it no matter how long it tries :P… oh and nice work!

fun idea

I love the rewards for the cats. That, to me, is a new twist in the lazorred cat tease gizmo.

Keeping score will be difficult indeed. How would you know it was indeed a paw that hit the rigth square? Or is this grid really high up a wall? Which would exclude tails, heads, rumps, etc from being detected.

**thanks **
cheers

collusion

To be honest im not 100% sure yet, i can get as far as checking the grid squares around it to get a rough position for the main mass of the cat but differentiating from the tail is proving to be a little more tricky, But that is assuming that the paw is to the left, right or above the cat. If i keep it above the cats head then i could possibly rule out the tail that way. I was planning on making the drid squares just wider than a cats paw and then counting a measure of two grid squares width as a score.

I dont think i will find a solution till i crack on with it, im not 100% sure i can make it work.

problems you don’t know for sure you can solve

those are the best

to solve…

Its working…

Updated above, video comming.

**nice project you have!!! **

nice project you have!!! and very ambitious :wink: I will look forward to see more of your improvements

cats are so funny :slight_smile:

Nice
Very cool idea. I used to have a siamese cat that would chase a laser pointer endlessly. Are you doing any signal processing on the video stream to track the cats?

Not as of yet

I have written a piece of code to track a lighter. Im going to skip the wireless part for now and concentrate on that till i have the money to buy what i need.

Amazing! What an awsome
Amazing! What an awsome idea! Poor cat tho… :slight_smile: