Search This Blog

Wednesday, April 25, 2012

Invention of the week: Now, meet then

Augmented reality application for war crimes. Imagine walking through the ruins of Auschwitz, and you find yourself looking mostly at building foundations and fields. Now hold up your phone, or put on your smart specs, and instead of empty streets and fields, you see the camp as it was, in color, filled with people.

Yuck, but it does make the experience more palpable. Since it's an application, you can embody your narrators. Stand in front of a barracks building, and summon a guard to tell you, in your native language, about his job. Now summon a prisoner, and get the actual story.

Of course, this would work for lots of things.  Imagine seeing Bandelier or Mesa Verde through the eyes of an inhabitant.

Experience the stinking, damp, rotting failure of the initial Jamestown colony as you and your fellows die slowly, of starvation and disease.

No need to thank me, I’m just doing my part to make museum-going a vaguely nauseating experience. 

Sunday, April 22, 2012

NetDuino Plus–steerable webcam

Did some practice with the Netduino Plus this weekend, trying to see how hard it would be to make a remotely-steerable webcam.  Answer:  not very hard at all.  Right now I just have it hooked up to a potentiometer on the left.  (The other one was for the other servo, but it turned out I only had a continuous rotation one in the box, so I just have the yaw axis working despite having a a pitch-axis pot on the board.)

The code's pretty simple, too.  See below.  Now I just integrate this as a thread/subroutine with the tiny-webserver code from last week and fabricate a mount for the webcam.  I've found some interesting libraries/modules for the .NET Micro Framework at CodePlex.  Check out:  http://neonmikawebserver.codeplex.com/

The webcam itself is a Linksys WVC54GCA, which is a standalone unit with a built-in webserver, so I'll probably wrap a simple steering UI around the URLs available on the camera.

NetduinoPlusServoControl

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
namespace BlinkLED {
    public class Program {
        static OutputPort led = new OutputPort(Pins.GPIO_PIN_D13, false);
        static AnalogInput pot = new AnalogInput(Pins.GPIO_PIN_A0);
        static int SensorValue = 0;
        static int LastSensorValue = SensorValue;
        const int ErrorBand = 50;
        const int PotRange = 1023 - 0;
        //  Parallax Standard Servo range seems to be roughly 2300-400
        const int ServoFullLeft = 2300;
        const int ServoFullRight = 400;
        const int Middle = (ServoFullLeft + ServoFullRight) / 2;
        const int ServoPulseDuration = 20000;
        const int ServoRange = ServoFullLeft - ServoFullRight;
        public static void Main() {
            PWM Servo = new PWM(Pins.GPIO_PIN_D10);
            //            int Position = Middle;
            while (true) {
                //  0 (fastest/full right) - 1024 (slowest/full left)
                SensorValue = pot.Read();
                if (SensorValue > LastSensorValue + ErrorBand || SensorValue < LastSensorValue - ErrorBand) {
                    Debug.Print("Potentiometer-> Last value: " + LastSensorValue.ToString() + "  Current value: " + SensorValue.ToString());
                    float NormalizedValue = ((float) SensorValue / ((float) PotRange / (float) ServoRange)) + ServoFullRight;
                    Debug.Print("Set servo to " + ((int) NormalizedValue).ToString());
                    //                Servo.SetDutyCycle(0);
                    Servo.SetPulse(ServoPulseDuration, (uint) NormalizedValue);
                }
                //  Enable for flashy LED
                //led.Write(true);
                //Thread.Sleep(SensorValue);
                //led.Write(false);
                //  Don't adjust more than 4x/second
                Thread.Sleep(250);
                LastSensorValue = SensorValue;
            }
        }
    }
}