Project: Motion Tracking Cat Toy

Hey everyone, I am a 21 year old Computer Scientist (with a career in Software Engineering) that just adopted a kitten to keep me company while my fiancée is finishing up school out-of-town.
(for the people that only want to skim, important points throughout the entire thread will be in bold, and I PROMISE there will be a lot of pictures/videos!)

I have always loved the idea of computer-controlled physical devices, but I have never made anything myself. This project aims to change that.

The idea behind this project has been in my head for YEARS, but until finishing up college, I never had the time/resources to really turn it into a reality.
In my apartment, my livingroom is 12' by 16', with a 12' foot ceiling. The center of the ceiling is perfect vantage point for me to put a laser turret that will autonomously move around to keep the laser dot away from (but still near) my cat.

Equipment list:
1x Arduino Uno R3
2x 28BYJ-48 motors
2x ULN2003 motor controllers
1x ATLASNOVA 650nm <50mw red laser pen (class iiia, safe for the kitty!)
1x Playstation Eye (75 degree FOV, 60fps @ 640x480, 120fps @ 320x240)
1x Home-built computer

Things I will have to construct:
2-axis mount to hold the laser pointer
Algorithms to determine where to position the laser based on the cat's movement

Project Outline
Assuming the laser is projected from a point 18" down from the ceiling (mounted to the bottom center of the ceiling fan), it will need to have a range of motion of 92.8 degrees to be able to position the laser on any point on the entire floor.
<>

My targeting system will be radial, where the position of the dot is determined as a radius length from the center of the room and an angle difference from 0.
<>

The Playstation Eye will be mounted pointing straight down as close as I can to the turret without it blocking movement and without the turret interfering with the video feed. Conveniently, the 16' x 12' of the room perfectly matches to the 4:3 aspect ratio of the webcam, AND the 75 degree FOV from a position of 18" down from the ceiling theoretically gives the camera a viewing area of 16.1' x 12.075', AKA the exact size of the room - what are the chances!? (the difference in this 75 degree angle and the 92.8 degree angle of the turret is because the turret's angle is diagonal while the camera's angle is horizontal)
Using OpenCV running on a powerful computer across the room, I will be able to do very fast and accurate motion tracking on my cat as it walks across the room, calculate the radius and angle from the center, and relay those numbers from C++/Python back to the arduino which will then adjust the stepper motor locations to match. The arduino will be left with the task of finding the quickest path to the new location from its current location, the C++/Python will not keep track of any previous points.

Other calculations(mostly for my reference):
Room is 27648 square inches, camera has 307200 pixels. This means the motion should be able to be tracked to an accuracy of .09 of an inch, assuming each pixel on the camera is unique.
Stepper motor (after reduction) has a step angle of 0.088 degrees, so (if I did the math right) it should have an average precision of roughly 1/4", and if this motor has microstepping then that precision could be even higher! (I don't know much about how microstepping works)

Problems I expect to encounter:
*When laser motion is near the center of the room, I will be in a gimbal lock situation with the turret pointed straight down. This means movement speed will suffer greatly the closer it is to the center of the room, but reading some posts by sbright33 it looks like this motor can be over-driven to turn at fairly fast speeds.
*I am unsure what the delay will be through the path of "motion happens > motion tracked > points determined > points sent > points interpreted > motors moved", but I am confident the bottleneck will be the motors, which using the over-driving method sbright33 talked about, I should be able to reduce that delay down to hopefully be undetectable.
*I am unsure how much data the arduino can handle. I plan on sending a pair of integer numbers (4 bytes each) 60 times per second, so 240 bytes/sec. I believe (could be wrong) the arduino can only handle 9600 baud which is something like 150 bytes/sec. I believe a workaround would be to use 16 bit ints, which would drop that to 120 bytes/sec and still maintain an accuracy higher than the stepper would need.

Future ideas for expansion
*Self-calibration, e.g. motion tracking of the laser to calibrate what points are where so this can be set up anywhere at angles other than straight down.
*Avoidance calibration, e.g. there is a couch here, chair here, tv stand here - don't shine the laser on them, go around them. Keep the dot on the carpet only.

The parts all started showing up yesterday, and now I have everything but the motors.
I was able to get communication to and from the arduino working through python even easier than I was expecting, and I messed a little bit with OpenCV for the motion tracking on the camera.

I will keep track of my build in this thread :slight_smile:
Constructive criticism is encouraged, but be warned: If you tell me "It can't be done" I will only take that as a challenge to prove you wrong (no hard feelings, right?)

*I am unsure how much data the arduino can handle. I plan on sending a pair of integer numbers (4 bytes each) 60 times per second, so 240 bytes/sec. I believe (could be wrong) the arduino can only handle 9600 baud which is something like 150 bytes/sec. I believe a workaround would be to use 16 bit ints, which would drop that to 120 bytes/sec and still maintain an accuracy higher than the stepper would need.

This is the least of your worries - the Arduino can manage 115200 baud easily and people have run it faster sucessfully.

wildbill:
This is the least of your worries - the Arduino can manage 115200 baud easily and people have run it faster sucessfully.

That is great to know, thanks!

I thought 9600 baud sounded really low. I guess the tutorials I used for serial data transfer set it at 9600 just for the heck of it. I'll try for higher numbers this evening :smiley:

Taped the camera on a wall temporarily to test out the default python motion tracking algorithm while just using my hand for the pointer.

Doesn't look half bad, but it definitely needs some fine tuning to determine where to place the laser.

Well, it's been a while, and one wedding and all kinds of other stuff later - I've finally gotten back to work on this.

Here's an update video:

And another taken shortly after that one showing a demo of it moving:

Well, even with 0 interest on this forum for this project, I finished it anyway...

Un-mounted

Proof of concept mounting

Video of it in action

Complete parts list:
Arduino Uno - $30
MK802 Mini Android-based PC Hacked and running Gentoo linux to handle image processing - $45
2x 28BYJ-48 stepper with uln2003a controller - $7
12v power brick to power steppers - Salvaged
Jumper wires - $5
5v Axiz Laser module - $10
Playstation Eye - $20
USB Hub - $20
Misc parts for mounting bracket - $25

It took 2 prototypes to settle on a design.
The original design was going to have the laser coordinates be based on a polar system, since this was to be mounted from the center of the ceiling. This made sense in my head, but in practice with the prototype it was very slow to respond any time the laser was near the center of the plane because many times nearly 90 degrees of rotation was required to get the laser to where it needed to be. I also had problems with wires getting tangled and had to implement a counter so that it would not rotate to the point of winding itself up.....
It was at that point that I decided I would scrap the design and start fresh with a standard Cartesian design that would solve all my problems.

I heavily modified the stepper library from sbright33 to suit my needs. This involved psudo-threading the library so that moth motors could move independently from each other at the same time (technically not the same time, but alternating every few hundred microseconds) as well as creating my own custom coordinate system for it to follow.

At first I also was planning to use wireless USB to transmit the webcam feed from the ceiling down to my main computer which would do motion analyzing and send back the coordinates that movement was detected at. I found an industrial-grade wireless hub, but regardless of what their claims said and after a week of trying different webcams out, it did not have the bandwidth support for HD webcam streams.
After some research, I settled on the MK802 Android MiniPC because of it's hack potential - planning to use it with linux to broadcast the webcam stream over my network to accomplish what the usb hub should have done.

Once I started playing with it, I realized that it had enough power to preform the image processing on its own - significantly slower (about 4fps instead of 60) but still quick enough to provide updates to the arduino faster than the motors could move.

The MK802 uses OpenCV and Python to handle the image processing, and communicates with the arduino over a serial port (the USB hub comes in here to support the webcam and the serial communication from one usb port). It sends the coordinates that the laser should point at, as well as a randomly chosen speed that it should travel on its way to those points. The python script waits until it receives a 'done' transmission from the arduino, and then sends the most recent set of coordinates for the laser.

It draws its power from the source that normally power the lights that connect to the fan, and can be turned on and off from the light switch. The fan can run while this is installed and operating, although I have noticed a bit of interference in the serial communication while the fan is running (magnetic interference, I assume) It can also be put into manual mode and controlled from any computer on the network.

This is GREAT! And just what I've been looking for, (but better than the one I had in mind....) Thanks so much for posting! This is going on my list of "things I plan to do when I have some time some day".... :slight_smile:

Thanks for mentioning my Stepper library! Can't wait to see how your project turns out. Will you post a video when it is working?

Hello.

Could you show more photos of your stepper mounts with each other ?
I try to make similar device but wonder how to mount this steppers to kind of pan-tilt system.
Also very interesting how to solve problem with limits rotation shaft ?

I need to rotate shaft from 0 to 180 or may be more but if it not going round and tear my cables.
What kind of limit do you use ?

ping

sbright33:
Thanks for mentioning my Stepper library! Can't wait to see how your project turns out. Will you post a video when it is working?

No problem! Your stepper library saved me a ton of time in the prototyping stage. Now I've got it completely threaded so both motors can run (nearly-)simultaneously.
I've got it down right now adding more features to it but when I get it mounted again I will take a better video

d00m:
Hello.

Could you show more photos of your stepper mounts with each other ?
I try to make similar device but wonder how to mount this steppers to kind of pan-tilt system.
Also very interesting how to solve problem with limits rotation shaft ?

I need to rotate shaft from 0 to 180 or may be more but if it not going round and tear my cables.
What kind of limit do you use ?

For some reason I didn't get the email notification of a thread reply, sorry!

I'm at work but I will take some pictures of how I secured them when I get home.

Thank you ! I'll wait for pics.

d00m:
Thank you ! I'll wait for pics.

So sorry for the delay!

Here you go:

I drilled a hole in the motor spindle and then used a small nut and bolt to secure it to a piece of aluminum angle bracket. Once you have the aluminum secured to it, you can mount pretty much anything... like another motor!
For the laser I just used epoxy.

Thank you !
Looks like you didn't care about limits rotation shaft ?
How you solve the problem that cable from laser and from second motor (one that with laser) can be going round and torn ?
Did you use some limits in your program code ?

d00m:
Thank you !
Looks like you didn't care about limits rotation shaft ?
How you solve the problem that cable from laser and from second motor (one that with laser) can be going round and torn ?
Did you use some limits in your program code ?

There are no limits in the arduino code, though there should be and it wouldn't be hard to add them. The limits are in the coordinates passed from python to the arduino, if everything is calibrated correctly, the laser should never rotate more than 70 degrees in any direction

If you are needing something that can rotate infinitely, you might want to look into a slip ring like this: Slip Ring with Flange - 22mm diameter, 6 wires, max 240V @ 2A : ID 736 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits

I know this is an old topic but ingenious project.

armpit - I have a few questions,

  1. Do you have to this day, think of using Raspberry Pi2?
  2. Have you built on the project?

I also have a cat, and think of the same idea, with automatic pan tilt laser.

Once again, super cool project!

Regards.
Nicolai