Tuesday, 24 June 2008

Navigating Google maps using the MAC sudden motion detector

I will explain here how I can navigate google maps by tilting my MacBook Pro.

1. Install the native libraries, I used Daniel Shiffman's Java Native libraries. From his website download sms.zip. Extract:

  • sms.jar — contains the Unimotion class
  • libUnimotionLib.jnilib — The java native interface to Unimotion

  • Copy those two files into ~/Library/Java/Extensions/

    2. Now just go to my example and enjoy (it will ask you to "trust" me, since you are giving the applet access to the native libraries that I told you to install above). You may need to restart the browser if you just installed the libs above. I tried it with Firefox 3.0 and Safar1 3.1.1

    If you want to copy and modify the example. Here is the java code for the applet:


    package sms;

    public class Unimotion {

    // Load the JNI Interface
    static {
    System.loadLibrary("UnimotionLib");
    }

    // Native function
    private static native int[] readSMS();

    // Return three values as array
    public static int[] getSMSArray() {
    return readSMS();
    }
    }


    And the following class:


    import java.applet.Applet;
    import java.net.URL;

    public class MapTiltNavigatorApplet extends Applet implements Runnable {
    int initialXYZ[];
    float speedXYZ[] = new float[]{0,0,0};

    public void init () {
    Thread t = new Thread(this);
    t.start();
    initialXYZ = sms.Unimotion.getSMSArray();
    }

    public void run() {
    int refreshTime = getParameter("framesPerSecond")==null?
    80:1000/Integer.parseInt(getParameter("framesPerSecond"));;
    while(true) {
    try {
    Thread.currentThread().sleep(refreshTime);
    } catch (InterruptedException e) {
    }
    calculateSpeed();
    sendMoveToClient();
    }
    }

    void calculateSpeed() {
    int []nowV = sms.Unimotion.getSMSArray();
    for (int i = 0; i <>5.0) speedXYZ[i]=5.0f;
    //decay
    if (speedXYZ[i]>0) speedXYZ[i]-=speedXYZ[i]/5.0;
    if (speedXYZ[i]<0)>1 || Math.abs(speedXYZ[1])>1) {
    this.getAppletContext().showDocument(
    new URL("javascript:click("+speedXYZ[0]+","+speedXYZ[1]+");"));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }


    Easy, isn't it?

    For the Javascript and the exact tag for including the applet just look at the source in my example above.

    If you build the jar for the aplet yourself remember to sign it, since it uses native libraries.

    3 comments:

    AT said...

    it worked on ur website very easy ... now how do i do it on maps.google.com ??

    raul said...

    Good question. An idea is to create a proxy that adds my code to google maps. I will try that when I have some time.

    raul said...

    AT:
    I did something for maps.google.com using GreaseMonkey. You need to install GreaseMonkey plugin (only works on Firefox as far as I know) and after that install this script (just go to the url and GraseMonkey will handle the installation):

    http://fotos.toppunter.com/tiltmap/tiltgmaps.user.js

    Obviously you need to have installed the native libraries as I explain in this post.

    I will add a new entry with a detailed explanation, and will test it a bit more.

    GraseMoneky is pretty nice by the way!