Target detection and tracking

In this lab, we'll explore the problems involved in detecting and locating a target (again using calculus). This little widget is an infrared detector cell. It costs about $1.50 at solarbotics. For this demonstration, we'll assume that we can afford to buy two of these guys and some pipe (pvc will work nicely, but cardboard works too if you're on a budget).

We'll assume that our target is either a) hot or b) marked with a handy IR emitter, like so (about 70 cents each):

If we mount the detector at the end of a short length of pvc pipe (cardboard will work too if we're on a budget), then it will detect IR light only when the tube is pointing at the emitter.

Show[{Graphics3D[Cylinder[{{0,0,0},{1,0,0}},0.1]],Graphics3D[Line[{{0,0,0},{-5,0,0}}]],Graphics3D[Sphere[{-5,0,0},0.1]]},ViewPoint->Front,Boxed->False]

A Rotating Scanner to Detect Incoming Projectiles!

So the basic idea here is to mount two such detectors on the ends of an armature, and then rotate it, waiting until we detect IR light at each detector, then recording the times at which we see IR light. We'll use this information to solve for the location of the IR emitter. Here the red lines coming from each detector show us where it's looking:

D1Pos[r_,theta_] := {r*Cos[theta],r*Sin[theta],0};
D1Dir[r_,theta_] := { - Sin[theta], Cos[theta],0};
D2Pos[r_,theta_] := {r*Cos[theta+Pi],r*Sin[theta + Pi],0};
D2Dir[r_,theta_] := {+ Sin[theta + Pi],- Cos[theta+Pi],0};

Detector[r_,theta_,col1_,col2_] := {Graphics3D[Cylinder[{D1Pos[r,theta],D1Pos[r,theta] + D1Dir[r,theta]},0.1]],
Graphics3D[Cylinder[{{0,0,0},{0,0,-1}},0.5]],
Graphics3D[Cylinder[{D2Pos[r,theta],D2Pos[r,theta] + D2Dir[r,theta]},0.1]],
Graphics3D[Rotate[Cuboid[{-r,-0.1,-0.1},{r,0.1,0.1}],theta,{0,0,1}]],
Graphics3D[Cuboid[{-0.1,-1.5 r,0},{0.1,0.1,0}]],
ParametricPlot3D[{r*Cos[u],r*Sin[u],0},{u,0,2*Pi}],
ParametricPlot3D[D1Pos[r,theta] + s*D1Dir[r,theta],{s,0,50},PlotStyle->{col1}],
ParametricPlot3D[D2Pos[r,theta] + s*D2Dir[r,theta],{s,0,50},PlotStyle->{col2}]

 };

Manipulate[Show[Detector[2,theta,Red,Red],ImageSize->{400,400},PlotRange->{{-3,3},{-3,3},{-3,3}},ViewPoint->Top,Boxed->False],{theta,0,2*Pi}]

Detector1Angle[X_,r_,theta_] := Module[{dist,phi},
VectorAngle[Flatten[{X,0}] - D1Pos[r,theta],D1Dir[r,theta]]
];

Detector2Angle[X_,r_,theta_] := Module[{dist,phi},
VectorAngle[Flatten[{X,0}] - D2Pos[r,theta],D2Dir[r,theta]]
];

DetectorFun[phi_] := HeavisidePi[5*phi]*Cos[10*Pi/2.0*phi];

What does the scanner see when you have a stationary source?

Now let's discuss what the detector sees when there's a (stationary) source present. Each of the two IR detectors will go hot when it's pointed at the IR source, which will happen once per revolution.

Manipulate[
BPlot = Plot[{DetectorFun[Detector1Angle[Source,2,t]],
DetectorFun[Detector2Angle[Source,2,t]]},{t,0,2*Pi},PlotRange->{All,All},Filling->Axis,
AxesLabel->{Style["Angle (time)",Medium,FontFamily->"Helvetica",Bold],Style["IR",Medium,FontFamily->"Helvetica",Bold]},PlotLabel->Style["Detector Response to an Stationary Source",Medium,FontFamily->"Helvetica",Bold]];Manipulate[Grid[{{Show[{Detector[2,theta,If[VectorAngle[{Source[[1]],Source[[2]],0}-D1Pos[2,theta],D1Dir[2,theta]] < 0.02,Red,Black],If[VectorAngle[{Source[[1]],Source[[2]],0}-D2Pos[2,theta],D2Dir[2,theta]] < 0.02,Red,Black]],Graphics3D[Sphere[Flatten[{Source,0}],0.2]]},ImageSize->{600,400},PlotRange->{{-3,12},{-3,6},{-3,3}},ViewPoint->Top,Boxed->False]},
{Show[{BPlot,
Graphics[Rectangle[{Dynamic[theta]-0.01,0},{Dynamic[theta]+0.01,1}],Style[Thick,Purple]] },ImageSize->{600,200},AspectRatio->1/5]}

}],{theta,0,2*Pi}],{{Source,{7.5,3.5}, Dynamic[Grid[{{"Source ", Source}},ItemSize->10]]},{-3,1},{12,6}}]

Goal: Solve for the location of the stationary source as a function of these two times.

How can we predict the location of the source from this information?

Suppose the source is moving? We'll need more samples, and have more fun.

First, we have some not very interesting computer code to work out the points where the different detectors fire as a function of the path of the incoming projectile.

SourcePt[t_] := {12-0.5*t,4};

ScanPts[f_,a_,b_] := Module[{i},Table[{a+i*(b-a)/1000,If[f[a+i*(b-a)/1000] < 0.1,1,0]},{i,0,1000}]];
DA1[t_] := Detector1Angle[SourcePt[t],2,t];
DA2[t_] := Detector2Angle[SourcePt[t],2,t];

BPlot2 = ListLinePlot[{ScanPts[DA1,0,10*Pi],ScanPts[DA2,0,10*Pi]},PlotRange->{All,All},Filling->Axis,
AxesLabel->{Style["Angle (time)",Medium,FontFamily->"Helvetica",Bold],Style["IR",Medium,FontFamily->"Helvetica",Bold]},PlotLabel->Style["Detector Response to an Stationary SourcePt",Medium,FontFamily->"Helvetica",Bold]];

D1 = ScanPts[DA1,0,10*Pi];D2 = ScanPts[DA2,0,10*Pi];

StrikePts[Data_] := Module[{Lefts,Rights},
Lefts=Select[Table[i,{i,2,Length[Data]}],Data[[#-1,2]] == 0 && Data[[#,2]] ≠ 0 &];
Rights = Select[Table[i,{i,2,Length[Data]-1}],Data[[#+1,2]] == 0 && Data[[#,2]] ≠ 0 &];
Table[(Data[[Lefts[[i]],1]] + Data[[Rights[[i]],1]])/2.0,{i,1,Length[Lefts]}]
]

StrikeData = Union[StrikePts[D1],StrikePts[D2]]

Here's the interactive demo of this case (the overflying plane):

Manipulate[Grid[{{Show[{Detector[2,theta,If[VectorAngle[Flatten[{SourcePt[theta],0}]-D1Pos[2,theta],D1Dir[2,theta]] < 0.02,Red,Black],If[VectorAngle[Flatten[{SourcePt[theta],0}]-D2Pos[2,theta],D2Dir[2,theta]] < 0.02,Red,Black]],Graphics3D[Sphere[Flatten[{SourcePt[theta],0}],0.2]]},ImageSize->{600,400},PlotRange->{{-3,12},{-3,6},{-3,3}},ViewPoint->Top,Boxed->False]},
{Show[{BPlot2,
Graphics[Rectangle[{theta-0.01,0},{theta+0.01,1}],Style[Thick,Purple]] },ImageSize->{600,200},AspectRatio->1/5]}
}],{theta,0,10*Pi}]

Next goal: Suppose we're spinning a projectile on the end of the arm. At what time do we release it?