Once upon a time a
subdivision swimming pool caused a minor problem, but to a problem
solving geek a problem is a problem that needs an answer. So
what were the problem and the solution? Well for all you legal
types it is rabbits eating in my garden. So for the sake of
this discussion we are talking about rabbits, however I must make a
disclaimer that in motion detection and autofire if an unwitting
person is trespassing on my property and happens to walk into the
field of fire... well we will refer to them as collateral
damage. Well the problem was Adult rabbits and little
rabbits cutting between two houses instead of just walking an extra
few feet to the pathway to the concrete pond. The little rabbits
were never really the problem, it was the adults, there is nothing
like being on your deck and some adult rabbit cutting between
your house and the neighbor's and they just look at you like "What
is there something wrong?" Never asking if it was ok, just doing
it. Some how I have to believe they would have an issue if I
say ran laps around their house for my exercise program, but I
digress... So I have this problem of rabbits cutting in my yard, it
does not matter the time and of course it is from Memorial day to
Labor day, before and after that time frame the traffic reduces
greatly. Of course the most active time is during swim meet
season when I also have to deal with an extra 100 rabbits or so from
different subdivisions. Ok I have a problem, so I must have
goals or objectives that have to be met in order for the ROI to be
there. So my defined goals were:
Must have automatic fire
ability
Must be able to detect
motion
Must be able to record the
event
Must be able to turn off auto fire mode
and take on manual control
Must be able to "Water the
Lawn"
Must be able to cover a 30 foot field
of fire
Must have a range of about 25 to 35
feet
Must have the ability to work at night
with all of the above features
Must be able to Play back any
recordings and laugh while sitting on the deck drinking a
beer.
So
what was the solution? This I pondered and opened up my book
of knowledge called the Internet and using the glorious thing called
searching, I started to come up with an idea. The picture
above is actually prototype number two. I will briefly talk
about Prototype one, but since media player in a browser has a 5
second buffer(yes I tried to override it, but it ignored
my override values) that I can not override anywhere, I had to
move on to version two. To meet the requirements/objectives I
decided the first prototype needed the following
items.
PVC pipe, Copper Ice maker pipe, and a
few other plumbing parts
Old computer, 1.7 GHz with a gig of
ram
USB Web
camera
Like I
said above I ran into a problem with media player in a browser, so
if anyone know the answer to this problem please let me know.
Here is some photos and video of prototype one.
**** Video is a 6 meg file, still
learning on making the format "Web" friendly
***
As you can see I have met
a bunch of my goals in prototype 1, I can shoot about 30 feet and
can cover a field of fire of about 30 feet. I can also control
the movement of the barrel by a servo and a Phidget device. In
this version in the top bunker "Window" I have a web camera
mounted to the barrel and it shows the video of what it sees as
the barrel moves. I control this all via a web page that was
written in C# and using ASP 2.0 with a little bit of
Ajax thrown
in. But as I have said before media player force me to version
2.
One issue that I did want to point
out is when dealing with controlling your phidget devices from a web
page, I ran into a state problem. the solution was
to declare the phidget variable as a static variable. This
allowed me to maintain control over the servos between postbacks. I do
believe a better answer which I am working on is to create all calls
to the servo and X10 from a web service. I have included the
code to the web service, it still needs some work on it,
namely turning everything into a singleton type call, I do not want
multiple instances of the object.
static
Phidgets.Servo
enc1;
So
what is version 2 and what lessons did we learn in version 1?
Well in version 1, I found out latency is not your friend; you have
about 6 seconds to before target was out of range and also
that cheap water hoses will burst under
pressure. "Rabbits" are stupid, if they walk to close to either
house they feel enclosed, so they walk right down the middle, giving
a great field of fire. They also react to sound, it will
either make them stop and look for the sound or at the least keep
walking but look for the sound, and this offers great photo shoot
opportunities. Another lesson learnt was that X10
works, but could work better, in time I will just switch to
relays. The in ground sprinkler solenoid worked great, it
offered almost instant on, and has only a 2 second
wait to turn off (time for solenoid to
release). Version 2 needed to do everything version 1could
do and then some, so back to the drawing board.
I decided to
go back to a thick client, dump the web camera and moved to an
Infrared camera. The most important upgrade was to an open
source library that I found called Aforge. Andrew Kirillov has
done a fantastic job with his
library
. It held
the foundation of version 2's code base. It provided me with
the motion detection I needed plus had an avi
writer sample. He also had some great topics on
"codeproject.com" on uses of his library. This is what had me
replace the web camera with an IP camera. Other thing that I did was
replace all hoses with PVC pipe, I liked the easy setup and
flexibility of the hose, but they can not hold up to the pressure
day after day. So to recap I still am using the same turret
concept in version 1 that was in version 2. I removed the
mobile web camera and now have a fixed infrared camera, replaced all
hoses with PVC pipes. Added Aforge libraries and his Camera
control. Added in sound and ability to record from the point
of motion to a fixed time after motion is no longer detected.
And finally switched to a thick windows client. This is some
finished photos:
Yes I know that the
plumbing could be better, but this is only a prototype, in fact some
of it will disappear based on lessons/enhancements that will be made
to version 2 that is why it is called a prototype so we
can learn.
The code is very simple most of the
complexity was already done for me by some of the others who created
the libraries that I am using. I simply put a bunch of parts
together, some of the things that I did, plus some of the changes to
the libraries; I will go over. Like I stated before, each of
the libraries have good working samples and I would suggest you
start there. From that point you can work any of the code I
did into your projects as you like.
This method
shows all of the functionality in one call so I am showing it for
its simplicity.
MyGun
myGun =
new MyGun(); //defined at the form level as I
use this object for manual control also.
public void
HolyHandGrenade()
{
log += "In Holy Grenade " + DateTime.Now.ToString() + "
,";
SoundPlayer sp = new
SoundPlayer("Daffy04.wav");
sp.Play();
myGun.Grenade();
sp = new
SoundPlayer("Sam35.wav");
sp.Play();
// leave on for 10 seconds, servo is moving back and forth at
this
time
Thread.Sleep(10000);
try
{
if
(thread.IsAlive)
{
thread.Abort();
}
// kill the current
thread
}
catch (Exception
e)
{
bridgeErrMsg += ",BridgeViewer.HolyGrenade => " + e.Message + " "
+
myGun.errmsg;
log += "In Holy Grenade execp " + DateTime.Now.ToString() + "
,";
}
finally
{
myGun.ReLoadGun();
log += "In Holy Grenade finally " + DateTime.Now.ToString() + "
,";
}
}
One of the
more important things (this is also demostrated in the Aforge
samples, it is what I followed ) is that you will need to
setup some events in your code that will be triggered by the
Camera control. The events that I am currently using are the
"NewFrame" and "Alarm" events. They are setup by the OpenVideoSource
and CloseVideoSource method calls. Needless to say the Alarm
event is fired everytime motion is detected. The key thing to
remember here is that the alarm is firing with every new frame that
the camera takes that is many in a second. I only want to fire
the gun if it is not currently firing and motion is detected.
In the NewFrame event this is fired every time the camera takes a
picture, again remember this is many times a second. This
event is where the code is writing to an AVI file frame by frame,
but this too I wanted to control, so if I did not want to capture
everything to video I could override the defaults. My future
plan here will be to replace the current AVI writer with one using
directx so I will be able to capture video and sound. Also I
plan to add a gun site to the frames here so in manual mode you will
be able to see a cross hair and it would move as you would move a
joystick.
// Open video
source private void
OpenVideoSource(IVideoSource
source)
{
// set busy
cursor
this.Cursor = Cursors.WaitCursor;
// close previous video
source
CloseVideoSource();
// create
camera
MotionDetector.Camera camera = new MotionDetector.Camera(source,
detector);
// start
camera
camera.Start();
// attach camera to camera
window
cameraWindow.Camera = camera;
// set
event
handlers
camera.NewFrame += new
EventHandler(camera_NewFrame);
camera.Alarm += new
EventHandler(camera_Alarm);
camera.VideoSourceError += new
EventHandler(camera_VideoSourceError);
// start
timer
timer.Start();
this.Cursor =
Cursors.Default;
}
// Close current
video source private
void
CloseVideoSource()
{
MotionDetector.Camera camera = cameraWindow.Camera;
if (camera !=
null)
{
// stop
timer
timer.Stop();
camera.NewFrame -= new
EventHandler(camera_NewFrame);
camera.Alarm -= new
EventHandler(camera_Alarm);
camera.VideoSourceError -= new
EventHandler(camera_VideoSourceError);
// detach camera from camera
window
cameraWindow.Camera =
null;
Application.DoEvents();
// signal camera to
stop
camera.SignalToStop();
// wait 2 seconds until camera
stops
for (int i = 0; (i < 20) && (camera.IsRunning);
i++)
{
Thread.Sleep(100);
}
if
(camera.IsRunning)
camera.Stop();
camera = null;
// reset motion
detector
if (detector !=
null)
detector.Reset();
} }
Like I have already stated, most all of the
samples from AForge are pretty straight forward
and easy to use, almost all of the above snipit of
code came from one of the samples. One thing I did do
was break the camera control out into a project by itself. Once this was created
I just had to simply drag and drop the control on a form like any
other .Net control and do whatever I wanted from with
in my application. One change I did implement in the Camera control was to setup
a property to give me more control on the sensitivity for
motion detection, I felt the default was way to sensitive for my
needs and wanted a way to adjust
it.
public double
AlarmLevel
{
get
{
return alarmLevel;
}
set
{
alarmLevel =
value;
} }
As for my Gun class, it is made up of two
other classes. One of these classes handles the Phidget devices
the other handles the X10 devices. The Gun Class just puts it
all together. The web service I have enclosed demostrates all of
this and it is pretty straight forward to understand. If you
still have questions feel fee to send me an email. web service
code is here .
So
with version 2 where are we and what did we learn?
Motion detection works great, sometimes to
good.
We
now have video and it is meeting the goal of having something to
laugh about.
Auto
fire works and combine it with "Holy Hand Grenade" mode and you
cover a lot of territory.
You
can teach "Rabbits" new tricks.
PVC
was the right move.
Servo controller boards do not like thunder
storms, keep it water tight
A
lot more "Rabbits" cut through than I thought, some
even riding bikes on my lawn
Do
not shoot your wife, even by accident (might not be a version 3 :)
).
Your
kid will use it like running through a lawn
sprinkler
Ok
so what type of enhancements are we talking here (some of these are
already in the works)? Well just brain
storming...
Create a click once client so
I can deploy to friends to have manual
fun.
Add in Microsoft's new Robot
SDK
Put functionality of servo and
X10 control in a web service (already did this and it opens oh so
many ideas. cell phones come to mind...also what waterhobo.com is
needed for...)
Have motion detection that
goes to motion tracking.
Switch from only horizontal to
both horizontal and vertical (Pan and Tilt) for
barrel
Switch to directX avi
recording, I want to record sound and
video
Using directX, add in Joystick
capability even from remote over the web (using web
service)
Make it more
portable
Add in pop up in ground
sprinklers
Create Infrared Spot light to
help cameras at night.
In closing I
have learnt a great deal and have a great deal of rework
to do, in some cases things were to complex and in others
there was just not enough functionality for what I
wanted to do, but I do know it can be done, and I do love
a challenge, so it will be. And finally a note from the
WaterHobo, well I did not catch any rabbits, but man you
would not believe all of the collateral damage or people that "Just"
happened to trespass on my yard, some as late as 11:30 at
night. They choose to ignore my "Pest" control signs, I guess that is why we
call them collateral damage....
Stay tuned for more
videos and version 3, its coming...
If you
would like to know more email me (Tim Higgins) at
tbh726@gmail.com