One of the things that the Terminator will have is a missile launcher, which I started hacking here. The missile launcher Api is controlled by time. Specifically, you tell it to turn in a certain direction for a certain amount of time.

1 member this.moveMissleLauncher(data, interval:int) =
2 if devicePresent then
3 this.SwitchLed(true)
4 this.sendUSBData(data)
5 Thread.Sleep(interval)
6 this.sendUSBData(this.STOP)
7 this.SwitchLed(false)
8

The challenge is converting that duration into X,Y Cartesian coordinates the way the Kinect and the phidget laser system does. And before getting Cartesian coordinates, we needed to get the polar coordinates. This is how we did it.

First, we tackled the pan (X coordinate) of the missile launcher. The launcher is a on a square base and the full range of the launcher is 45 degrees to 315 degrees.

With some experimentation, we determined that the total time it takes the turret to traverse from 45 degrees to 315 degrees (270 total degrees) is 6346 Milliseconds. Assume that the motor is consistent (which is a big if using cheap electronics), it takes the motor about 23.5 milliseconds to move 1 degree on the X axis.

The tilt was more of a challenge. We needed a way of measuring the total range along the Y axis. To that end, we placed the turret 300 millimeters away from the wall. We then placed a laser pointer on the turret and put a level on it to ensure that it was a 0 degrees and marked the wall. We then moved the turret to its highest position and then to its lowest, marking the wall with those points. We then measured the distance to the highest and lowest point on the wall.

Assuming the wall was vertical, we could then use this site to figure out the angle of the turret. We first calculated the length of the unknown side using the Pythagorean theorem (300^{2} + 235^{2} = X^{2}) = Sqrt(90000 + 55225) = 381

With all three sides known, we went over to this great site to use some basic trigonometry to help solve the angle problem. Since we are looking at the angle between adjacent and hypotenuse, we need to determine the inverse cosine via this formula: cos(θ) = Adjacent / Hypotenuse. cos(θ) = 300/381 or cos(θ) = .7874 or (θ) = cos^{-1}.7874 or .6642. This means our rocket launcher can move up about 66 degrees and by doing the same calculation for down, it can move down about -8 degrees. Since 66+8 equals 74, we decided to round to 75.

We then determined that the total time it takes the rocket launcher to traverse from its max up position to level was 710 milliseconds. Dividing 66 into 710, each degree takes about 10.7 milliseconds.

So with handy chart in place, we are ready to map the polar coordinates to the Missile Launcher

I added the adjustment values to the type

1 let tiltMultiplier = 10.7
2 let panMultiplier = 23.1
3

So now it is a question of keeping track of where the launcher is pointed at and then calling the correct adjustments. To that end, I created a couple of mutable variables and set them to 90 when the missile launcher initializes

1 let mutable currentPan = 0.
2 let mutable currentTilt = 0.
3

1 member this.Reset() =
2 if devicePresent then
3 this.moveMissleLauncher(this.LEFT,6346)
4 this.moveMissleLauncher(this.RIGHT,3173)
5 this.moveMissleLauncher(this.UP,807)
6 this.moveMissleLauncher(this.DOWN,710)
7 currentPan <- 90.
8 currentTilt <- 90.
9 ()

I then implemented the method for the interface to acquire the target. Note that I am pretty liberal with with my use of explanatory variables.

1 member this.AquireTarget(X:float, Y:float) =
2 match X = 0.0, Y = 0.0 with
3 | true,true -> false
4 | true,false -> false
5 | false,true -> false
6 | false, false ->
7 let tilt = X
8 let pan = Y
9
10 let tiltChange = currentTilt - tilt
11 let panChange = currentPan - pan
12
13 let tiltChange' = int tiltChange
14 let panChange' = int panChange
15
16 let tiltChange'' = abs(tiltChange)
17 let panChange'' = abs(panChange)
18
19 match tiltChange' with
20 | tiltChange' when tiltChange' > 0 -> this.Down(tiltChange''); currentTilt <- tilt
21 | tiltChange' when tiltChange' < 0 -> this.Up(tiltChange''); currentTilt <- tilt
22 | tiltChange' when tiltChange' = 0 -> ()
23 | _ -> ()
24
25 match panChange' with
26 | panChange' when panChange' > 0 -> this.Left(panChange''); currentPan <- pan
27 | panChange' when panChange' < 0 -> this.Right(panChange''); currentPan <- pan
28 | panChange' when panChange' = 0 -> ()
29 | _ -> ()
30 true
31

And with that, we have another weapons system we can add to our kinect Terminiator