Showing posts with label github. Show all posts
Showing posts with label github. Show all posts

Tuesday, 4 October 2011

Over The Air 2011: Exploding the Gap Between Web and Native

James Hugman - Engineer at Future Platforms @jhugman

  • Web vs Native is a false dilemma
    • the answer is: it depends, or it’s both
  • often a lot of display in UI
  • story of the glastonbury app
    • Orange app for iPhone, Android and Nokia
  • three/four phases of content:
    • before (and before embargo)
    • during
    • after
  • lots of data
    • 3000 bands, 65 stages – timings could change

experimentation & research

  • assumed offline and native UI
  • but native was too expensive for three platforms
  • how do you make native in web technologies?
    • every phone has a different web view
    • Android users don’t like seeing iPhone UX
    • and Android back button can exit app if you’re not careful
    • there is no release cycle of WebKit
      • manufacturers just take the trunk and fix bugs
    • dev and cpu time spent getting UI just right
  • Titanium: write your UI in Javascript, render natively
    • ListViews either don’t look right, or leak memory
    • doesn’t always deal with latest design patterns – can’t override platform-specific behaviours
  • Impact for iOS: javascript talks to OpenGL
    • experimental & proprietary
    • morphed into appMobi’s DirectCanvas
  • game{closure}
    • pre-alpha – HTML5
    • also node.js
    • debug your mobile app and your browser app all in the same browser
  • but Game UI is not platform UI
    • easier to make cross-platform game UI as the UI is brand-specific, not platform specific
  • important to get events passing between rendering and UI logic
    • all frameworks bundle their own Javascript engine
    • Android users don’t like big apps – Titanium hello world is 6Mb!

new platform

  • Kirin requirements:
    • native, platform appropriate UIs
    • minimal download
  • design:
    • native UI
    • JS application logic
    • native platform
  • advantages:
    • raw events processed natively
    • only app-specific events passed through to app
  • “the keyhole”
    • instantiate an invisible web-view
    • build proxies for objects
    • javascript calls into native and the other way
  • modular javascript using CommonJS
    • each screen has its own module (one file each)
  • threading using asynchronous APIs, inspired by node.js
  • native-specific features available as services
    • e.g. Location, SQL, Network access
    • same Javascript to native bridge
    • JS just uses a require(...)

releasing as open source

  • available now on github
  • as a 0.5 release
  • apache license
  • looking for feedback
  • iOS and Android only at the moment (Qt coming later)
  • Windows Phone 7 might come later

Q&A

  • testing & debugging:
    • build script runs node.js
      • so can include unit tests at build time with assert
      • have console access
      • no actual debugger
  • why port model code – isn’t it simple?
    • but if using database on device, then model not so portable (Core Data doesn’t port well)
  • porting pain? scaling to iPad?
    • most of pain was electronic programme guide
    • download & syncing

Sunday, 10 October 2010

Over The Air Hack - a LEGO robot with an iPhone brain

IMG_6032

As promised, here are the details of my Over The Air hack — The Eyes Have It — which won prizes for “Best Hardware Hack” and “Best Use of Other Features” in the overnight hack-a-thon competition. I also took it along to Mobile Monday London’s Demo Night on the following Monday.

The hack was a LEGO Mindstorms robot with an iPhone brain that followed faces in front of it and steered towards them. It performed well on stage, following me as I gestured towards it, just like a small pet.

The hack was composed of two parts: an iPhone app that detected faces in the video feed from the front-facing camera; and the LEGO robot that took instructions from the iPhone and steered accordingly.

Communication

Getting the two parts to communicate was one of the trickiest areas to get right, and caused extra headaches before each presentation. Both LEGO Mindstorms and the iPhone can communicate over Bluetooth, but Apple has restricted Bluetooth communication to companies that will pay the Apple “Made For iPhone” license fee or that use particular hardware. Bluetooth comms is not available through the standard SDK and apparently needs some kind of “secret handshake” to work.

Unfortunately, Mindstorms came out a while before the iPhone and uses a different Bluetooth chip; and LEGO and Apple haven’t managed to do a deal to provide Mindstorms access from the iPhone (perhaps because LEGO has open sourced much of their software?). LEGO has now released an Android app to showcase mobile phone integration, so let's hope Apple can work with them to get some iPhone apps too.

So no Bluetooth, and Apple won’t let you talk over the dock connector either… That left feeding information to the robot through one of its five senses — a touch-sensitive button, an ultrasound distance sensor, a microphone, a light sensor or the motors themselves (which can detect rotation).

A quick search on LEGO Mindstorms iPhone brought up the iPhoneRobot which used the light sensor to pick up different greys on the screen. This was a great start, but it wasn’t quite what I was looking for. For a start, it required the LeJOS firmware on the Mindstorms brick — this is a cut-down Java VM that replaces the built-in LEGO firmware. I’ve left my Mindstorms with the default LEGO firmware as I use it with my 7 year-old son. He’s not quite ready for Java, but can easily understand the Labview-based visual programming that comes with the Mindstorms kit. Secondly, the robot itself wasn’t quite suitable — I wanted a robot that would recognise faces, so I needed the iPhone to be pointing upwards towards people’s heads rather than along the ground.

Motor skills — building the robot

Designing a new robot from scratch takes quite a while and I only had overnight. Unlike normal LEGO with bumps and holes, the Mindstorms kit uses the new-style LEGO Technic, which is mostly holes and connectors. Also, LEGO’s own sample models are pretty complex, as they are built to look like animals or people as well as interact.

Fortunately, I found a great site with designs for quick Mindstorms models that are easier to hack to do what you want. Some of the ideas are amazing — especially a Segway that actually balances! I started with the 3-Motor Chassis and added the distance sensor on the front to prevent crashes. I also added the button sensor on the side to help with starting and stopping the program, as the iPhone was in the way of the program buttons on the Mindstorms block.

Here’s some pictures of the final result, holding the iPhone pointing upwards. I’ll try and generate some build instructions later.

Computer vision — the iPhone app

Humans are exceptionally good at seeing faces. Our brains have been trained from birth to detect and analyse faces very quickly. We can tell which way people are looking from far away and even see faces in random patterns.

Computers have a harder time of it, although recent developments have massively improved what is possible. Companies such as Polar Rose have shown demonstrations of both face detection (finding out where any faces are in an image or video) and facial recognition (matching the detected faces against a database of known images) running in real-time on mobile phones. Unfortunately, their code is not available to an overnight hacker, though they’ve recently been bought by Apple so we may see interesting capabilities in future iPhones.

However, Intel launched an open source project back in 1999 called OpenCV (for Computer Vision) and not only is it still going strong, but the library is easily compatible with the iPhone and has a git repository of a ready-built library. OpenCV is all about providing well-optimised functions for real-time computer vision, so that developers do not have to reinvent the wheel. It includes face detection algorithms and a guy called Roy has posted some examples of how to get face detection working on an iPhone video feed.

Roy’s sample code was written for iOS 3, and iOS 4 provides much easier methods for accessing the video feed from the device. I updated Roy’s code to use the new AVCaptureVideoDataOutput class that provides direct access to uncompressed video frames from any iPhone camera. This bit took a little while longer than it should have done, as the video feed is provided as landscape (you’re recording a video, right?) whereas its preview feed is oriented the same way as the camera. This was not obvious, and made worse by the fact that face detection algorithms do not work when the image is rotated by 90°… There was a point in the early hours of Saturday morning when I thought there would be no face detection at all!

Anyway, following Roy’s recommendations, I scaled down the input image and adjusted the parameters of the OpenCV face detection call. At the moment I transpose the image before sending it to the detection algorithm, but I suspect it would be faster to use a rotated Haar feature set (the bits that the algorithm picks out in each image to match faces). I also didn’t use Roy’s changes to use integer arithmetic rather than floating point — it turns out that the iPhone 4G has enough grunt to cope with the standard OpenCV code.

You can get the iPhone code from my github repository and try it for yourself. Note that it’s hardwired to use the front-facing camera at the moment. If you don’t have an iPhone 4 just change the AVCaptureDevice to point to the ID of the other camera and the rest of the code should still work (though possibly a little more slowly…).

Light and dark — the LEGO program

So now I had a robot base and an iPhone app that could see faces. The next step was to connect the two together using the light sensor.

LEGO provide a drag and drop programming interface for Mindstorms that lets you build up programs using blocks such as “move motor”, “wait for sensor input” and control logic of loops and if/else switches. It’s quite capable and makes simple programs relatively easy, but using variables and arithmetic can be a little cumbersome.

The main issue in getting the robot to drive was calibrating the light sensor, especially when each demo was under different lighting. After a fair amount of tweaking (some just minutes before presenting at Mobile Monday London’s demo night), the best results turned out to be when I crammed a small piece of cardboard into the hinge that held the light sensor onto the iPhone…

You can download the “.rbtx” file from my github repository, but for those who don’t have the LEGO software, the algorithm is essentially:

  1. Calibrate the sensor when pointing at the black and white squares to either side of the control square on the iPhone screen
    • The robot prompts for each reading with its display and waits for you to press the button between each sensor reading
    • The program reads the raw values from the sensor and calculates its own scaling values, as the built-in calibration routines turn on the light on the sensor — this works for reading black lines on a white sheet of paper but isn’t so good at reading the backlit screen of the iPhone…
  2. Wait for another button press to start the robot moving — so you can step back and make sure your face is in frame
  3. Read the raw value of the light sensor, convert it into a value between -90 and +90, and then steer that amount, then repeat
    • The program checks that the light sensor value is within a reasonable range before steering, otherwise the robot tends to go round in tight circles and you have to run round it like a lunatic trying to get your face in the camera frame!
  4. When the distance sensor picks up something closer than 6 inches, stop, play a sound and show a beating heart on the display (“I’ve found you!”)
  5. Start moving again when the button is pressed

To give you an idea of what this looks like in the Mindstorms NXT software, here’s a picture of the program!

Prizes

Thanks to Monotype for the beautiful poster of Gill Sans Bold Extra Condensed. They were going to give me two, but were happy to swap one for a copy of FontExplorer Pro instead, so I can see my digital fonts presented almost as prettily. Apparently, it’s now available for Windows as well as Mac OS X.

Wednesday, 29 July 2009

EyeTV Export with HandBrake script

EyeTV by Elgato is an excellent piece of software that turns a Mac into a Personal Video Recorder. You can record programs using a tuner and play them back at any time. We have an iMac stuck to the wall in our living room that acts as our TV and media player. Even the babysitter can use the PVR interface and we get to use full apps like iPhoto and Spotify on our TV.

EyeTV records video using the format that it’s sent over the air. This is currently MPEG-2 for Freeview programs, which is decent quality but reasonably large files. I’d like to be able to archive my recordings using a better encoding such as H.264. However, EyeTV’s (and Apple’s) built-in options for exporting video are pretty poor. They generally take a long time to create poor quality video at an unimpressive compression ratio.

HandBrake is an open-source video transcoder. It can transcode between many video formats and has built-in presets for compressing different kinds of video. It’s great at taking EyeTV recordings and transcoding them into space-efficient, high quality H.264 MKV or MP4 files.

Fitting the two together is a bit of a pain. EyeTV has Applescript support but HandBrake doesn’t. Instead HandBrake has a command-line version that is available for separate download (see the downloads for Command Line Interface).

I wanted to be able to choose a suitable HandBrake export preset (some of my recordings are cartoons, some are movies) and a destination folder and export several recordings at once. Since transcoding video is a CPU hog, I also wanted to use the HandBrake encoding queue, but this isn’t available in the command-line version.

Various people have written scripts to take EyeTV recordings and encode them using HandBrake, but they weren’t quite what I wanted. Most of them were intended to import the results into iTunes so that files are available to AppleTV. I did’t need this — I just want smaller files. And none of them had an encoding queue — they all ran in the foreground.

So I wrestled with Applescript (it felt like banging my head against a brick wall several times), honed my shell script skills and built the EyeTV Export with HandBrake script. The script can be added to the EyeTV scripts menu, so that you can select multiple recordings in EyeTV and export them directly. The script will prompt you for a HandBrake encoding preset and an output directory and will pass of the encodes to a background shell script that runs one encode at a time. If you have Growl (also highly recommended), the script will announce completed encoding processes in a friendly manner (otherwise it will pop up a dialog).

I hope you find it useful. Please add comments below!

Instructions

  1. Download the script (or get the source from GitHub)
  2. Put it in /Library/Application Support/EyeTV/Scripts and restart EyeTV (see EyeTV Applescript instructions for details)
  3. Download the HandBrake Command Line Interface (HandBrakeCLI) and move it somewhere appropriate. I use /usr/local/bin/, but the script will ask you to find it if it’s not there
  4. Select one or more recordings and choose “Export with HandBrake” from the Scripts menu (just between Window and Help)