<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nokia PUSH &#187; The Haptic Guide</title>
	<atom:link href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.nokia.com/pushn900</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 10 May 2010 17:40:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>So, the Big Presentation is Over&#8230; Now What?</title>
		<link>http://blogs.nokia.com/pushn900/2010/03/02/so-the-big-presentation-is-over-now-what/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/03/02/so-the-big-presentation-is-over-now-what/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 15:37:22 +0000</pubDate>
		<dc:creator>timothy2</dc:creator>
				<category><![CDATA[The Haptic Guide]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1956</guid>
		<description><![CDATA[ ]]></description>
			<content:encoded><![CDATA[<p>It was a great experience presenting the Haptic Guide project to the public for the first time this weekend.  It was awesome to meet so many different people from so many backgrounds over the course of last weekend, but even more surprising was the genuine interest so many people showed in the project.</p>
<p>I talked with people who studied haptics for their thesis in university, and people who currently develop haptic devices for people with disabilities.  I talked with people who have no sense of direction, and people who do but know someone with no sense of direction.  I talked with people from all over the world.  I think that in general, it was just one of the most unique experiences I have had.  So, i want to extend another big thanks to Nokia and all the people behind the scenes that made this event happen!</p>
<p>Going forward, we plan to develop the Haptic Guide much further.  In fact, we have already begun on new prototypes.  For any who are interested, we will be tracking future progress on our new website: <a title="Haptic Guide Home Page" href="http://www.hapticguide.com">http://www.hapticguide.com</a></p>
<p>We hope that one day, you will see this product in stores alongside cell phones and GPS units.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/03/02/so-the-big-presentation-is-over-now-what/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Haptic Guide, Episode 4</title>
		<link>http://blogs.nokia.com/pushn900/2010/02/08/haptic-guide-episode-4/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/02/08/haptic-guide-episode-4/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 09:24:37 +0000</pubDate>
		<dc:creator>mattbrawn</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[The Haptic Guide]]></category>
		<category><![CDATA[Videos]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1898</guid>
		<description><![CDATA[Here&#8217;s the fourth video update from the Haptic Guide team.

Following on from Episode 3, this video checks in with the team just before they took off for the PUSH N900 Showcase in London. Find out about a few of their last minute hiccups and what they thought of the PUSH projct as a whole. 
If [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the fourth video update from the <a href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/">Haptic Guide</a> team.</p>
<p><object width="380" height="250"><param name="movie" value="http://www.youtube.com/v/-bLI-2oCKrc&#038;hl=en_GB&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/-bLI-2oCKrc&#038;hl=en_GB&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="380" height="250"></embed></object></p>
<p>Following on from <a href="http://blogs.nokia.com/pushn900/2010/01/27/haptic-guide-episode-3/">Episode 3</a>, this video checks in with the team just before they took off for the PUSH N900 Showcase in London. Find out about a few of their last minute hiccups and what they thought of the PUSH projct as a whole. </p>
<p>If you&#8217;ve missed the first three video updates from the Haptic Guide team then you can check the links below:<br />
<a href="http://blogs.nokia.com/pushn900/2009/12/18/haptic-guide-episode-1/">Haptic Guide, Episode 1</a><br />
<a href="http://blogs.nokia.com/pushn900/2010/01/16/haptic-guide-episode-2/">Haptic Guide, Episode 2</a><br />
<a href="http://blogs.nokia.com/pushn900/2010/01/28/haptic-guide-episode-3/">Haptic Guide, Episode 3</a></p>
<p>And if you want to check out all the team&#8217;s blog entries, head on over to their <a href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/">Team</a> page. </p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/02/08/haptic-guide-episode-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Haptic Guide, Episode 3</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/28/haptic-guide-episode-3/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/28/haptic-guide-episode-3/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 12:46:58 +0000</pubDate>
		<dc:creator>mattbrawn</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[The Haptic Guide]]></category>
		<category><![CDATA[Videos]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1791</guid>
		<description><![CDATA[Here’s the third video update from the Haptic Guide team. 

The video follows the team as they test out their haptic belt prototype in a bid to change the way we use GPS. 
If you’ve missed the first two video updates from the team then they’re linked below:
Haptic Guide, Episode 1
]]></description>
			<content:encoded><![CDATA[<p>Here’s the third video update from the <a href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/">Haptic Guide</a> team. </p>
<p><object width="380" height="250"><param name="movie" value="http://www.youtube.com/v/hAd2n-6ZFPk&#038;hl=en_GB&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/hAd2n-6ZFPk&#038;hl=en_GB&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="380" height="250"></embed></object></p>
<p>The video follows the team as they test out their haptic belt prototype in a bid to change the way we use GPS. </p>
<p>If you’ve missed the first two video updates from the team then they’re linked below:<br />
<a href="http://blogs.nokia.com/pushn900/2009/12/18/haptic-guide-episode-1/">Haptic Guide, Episode 1</a><br />
<a href="http://blogs.nokia.com/pushn900/2010/01/16/haptic-guide-episode-2/>Haptic Guide, Episode 2</a></p>
<p>Or you can check out their <a href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/">Haptic Guide</a> team page for all of their updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/28/haptic-guide-episode-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>La fin</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/25/la-fin/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/25/la-fin/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 19:57:19 +0000</pubDate>
		<dc:creator>timothy2</dc:creator>
				<category><![CDATA[The Haptic Guide]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1743</guid>
		<description><![CDATA[We have two fully functional haptic compass belts capable of interfacing with the Nokia N900.]]></description>
			<content:encoded><![CDATA[<p>As it would seem, the Haptic Guide project is now complete.  We have two fully functional haptic compass belts capable of interfacing with the Nokia N900.  The third wasn&#8217;t possible due to my tendency to wreck critical parts.  The phone software is now fully functional and has been cleaned up with the last few features: some nice banner notifications, a device selection pop-up dialog, and a shiny graphical mini-compass.</p>
<p>Overall, I think Mike and I were able to accomplish the primary (and many secondary) goals that we set out to accomplish with this project.  Two working vibrational haptic belts and a phone-based, internet-connected application to allow turn-by-turn geo-coded photo finding without reliance on visual or auditory cues.  This belt and software combination has many potential uses, from acting as a tourist sightseeing platform without the distraction of constantly checking a screen, to a simplified geo-caching tool, to finding a lost child (or spouse) if they have an N900 with them, and more.  Our final videos should make it up online before too long and we look forward to giving a live demo.</p>
<p>I want to extend a huge thank you to Nokia for making this project possible.  It was a great learning experience and a lot of fun to do.</p>
<p>-Tim</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/25/la-fin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Haptic Guide, Episode 2</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/16/haptic-guide-episode-2/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/16/haptic-guide-episode-2/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 14:16:51 +0000</pubDate>
		<dc:creator>mattbrawn</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[The Haptic Guide]]></category>
		<category><![CDATA[Videos]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1628</guid>
		<description><![CDATA[Here&#8217;s the second installment from the Haptic Guide team. 

This video follows the team as they undergo completing the first prototype of their wearable &#8216;touring platform&#8217; that lets its users share photos and be guided the to thier locations without distraction from the sights around them. 
If you missed the first installment from the Haptic [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the second installment from the <a href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/">Haptic Guide</a> team. </p>
<p><object width="380" height="250"><param name="movie" value="http://www.youtube.com/v/v5sE2KfWgrY&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/v5sE2KfWgrY&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="380" height="250"></embed></object></p>
<p>This video follows the team as they undergo completing the first prototype of their wearable &#8216;touring platform&#8217; that lets its users share photos and be guided the to thier locations without distraction from the sights around them. </p>
<p>If you missed the first installment from the Haptic Guide, then you can check it out <a href="http://blogs.nokia.com/pushn900/2009/12/18/haptic-guide-episode-1/">here</a> or head on over to their <a href="http://blogs.nokia.com/pushn900/category/the-haptic-guide/">team</a> page to check out all their latest blog updates. </p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/16/haptic-guide-episode-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Episode 1 Mashup</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/15/the-episode-1-mashup/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/15/the-episode-1-mashup/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 09:49:54 +0000</pubDate>
		<dc:creator>mattbrawn</dc:creator>
				<category><![CDATA[KAPing with the N900]]></category>
		<category><![CDATA[Light Hack Crew]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Sketch your World]]></category>
		<category><![CDATA[Solderin Skaters]]></category>
		<category><![CDATA[The Haptic Guide]]></category>
		<category><![CDATA[Videos]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1615</guid>
		<description><![CDATA[Not had the chance to check out all of the team updates yet? Well, here&#8217;s a nifty roundup from all of the five PUSH teams that&#8217;s a great mashup of each of their progress videos so far.

If you wanna check out the teams in a bit more detail, head on over to the Teams page [...]]]></description>
			<content:encoded><![CDATA[<p>Not had the chance to check out all of the team updates yet? Well, here&#8217;s a nifty roundup from all of the five PUSH teams that&#8217;s a great mashup of each of their progress videos so far.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="380" height="250" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/HZ0V82Y8PgI&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="380" height="250" src="http://www.youtube.com/v/HZ0V82Y8PgI&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>If you wanna check out the teams in a bit more detail, head on over to the <a href="http://blogs.nokia.com/pushn900/the-teams/">Teams</a> page or you can watch each of their first progress videos which I&#8217;ve linked below for all you PUSH lovers.</p>
<p><a href="http://blogs.nokia.com/pushn900/2009/12/15/solderin-skaters-episode-1/">Solderin Skaters, Episode 1</a><br />
<a href="http://blogs.nokia.com/pushn900/2009/12/18/haptic-guide-episode-1/">Haptic Guide, Episode 1</a><br />
<a href="http://blogs.nokia.com/pushn900/2009/12/23/light-hack-crew-episode-1/">Light Hack Crew, Episode 1</a><br />
<a href="http://blogs.nokia.com/pushn900/2010/01/07/sketch-your-world-episode-1/">Sketch Your World, Episode 1</a><br />
<a href="http://blogs.nokia.com/pushn900/2010/01/12/kaping-with-the-n900-episode-1/">KAPing With The N900, Episode 1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/15/the-episode-1-mashup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My N900 Can Walk Me Home</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/14/my-n900-can-walk-me-home/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/14/my-n900-can-walk-me-home/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 19:36:56 +0000</pubDate>
		<dc:creator>timothy2</dc:creator>
				<category><![CDATA[The Haptic Guide]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1609</guid>
		<description><![CDATA[I activated a picture of my place and was able to successfully follow the directions all the way home...]]></description>
			<content:encoded><![CDATA[<p>The night before last, we performed the first tests of the new turn-by-turn directions functionality of the software on the N900.</p>
<p>First, some background.  The original milestone in the software was to take your current location (in GPS coordinates) and the target location (from GPS coordinates stored in a jpeg image taken from the N900&#8217;s camera) and use some calculus to determine bearing and distance to the target.  This we achieved a week or so ago.  This method alone would work for a target that is fairly close to where you are currently.  But as the distance increases, it becomes harder to discern the direction as the bearing changes caused by moving are more subtle.  Instead, we wanted to take your starting point and your destination and break it down into any number of &#8220;legs&#8221; so that you have turn-by-turn directions to the target that are easier to follow.  The downside to this is the requirement of having Internet access available.  In Canada, the N900 doesn&#8217;t seem to work fully with any of the current cellular service providers, so we are are limited to step-by-step directions only where we can get Wifi internet service.</p>
<p>After some late-night research, I was able to find a way to take two GPS coordinates and generate turn-by-turn directions for them.  So, when you first load a photo, the N900 will now request directions and use those if they are available.  Otherwise, it will just use the start/end point as before.</p>
<p>A couple of bugs surfaced on the first attempt, but after a couple of minor adjustments to the code (like a larger &#8220;in range of target&#8221; radius) everything worked beautifully.  On the way home, I activated a picture of my place and was able to successfully follow the instructions all the way home, with it changing to the next waypoint just as I came to the correct intersection to turn at, almost exactly like you would expect from a professional GPS device.</p>
<p>The finish line is definitely in sight as Mike said.  I have just got to do a bit of clean up, add a couple more relatively minor UI/display features, some additional testing, and we will have a functional product ready for demo.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/14/my-n900-can-walk-me-home/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tales from the basement</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/14/tales-from-the-basement/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/14/tales-from-the-basement/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 16:55:05 +0000</pubDate>
		<dc:creator>Mike77</dc:creator>
				<category><![CDATA[The Haptic Guide]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1605</guid>
		<description><![CDATA[Almost done!!!]]></description>
			<content:encoded><![CDATA[<p>Mike77 crawling out of the basement with an update for you.</p>
<p>Well, time&#8217;s running out, and I&#8217;m almost done! AHAHAHAHAHAHA!  The prototype (ugly as it may be) was a huge learning exercise for us, (and my first step into leather working).  It&#8217;s amazing to me how much faster the Mark II is coming along, and how much better it looks.  We&#8217;ve made some design decisions we hope you&#8217;ll like, including using a reversible belt!  We can run happily with the feedback belt looking like a regular leather belt or flip it around so the world can see the motors and wires!  Now, in this day and age it may not be entirely appropriate to walk down the street with various wires and lights buzzing and blinking away on your belt&#8230;</p>
<p>We made the decision to relocate just about all the fancier electronics to the water-resistant cellphone carrier for better protection from the elements and I&#8217;m still impressed at how it all just tucks right into a very small space right beside the N900 itself.  The N900 remains entirely usable as a phone during navigation, which was important to us.  Tim&#8217;s made huge strides on the UI on the phone as well, I can&#8217;t believe he&#8217;s teaching himself python as he goes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/14/tales-from-the-basement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Bluetooth Code Example</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/08/python-bluetooth-code-example/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/08/python-bluetooth-code-example/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 22:00:21 +0000</pubDate>
		<dc:creator>timothy2</dc:creator>
				<category><![CDATA[The Haptic Guide]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1562</guid>
		<description><![CDATA[I&#8217;ve made an interesting discovery through this project about Linux (or projects that originated from Linux) and Maemo programming.  Most documents, library references, tutorials, etc. seem to make make the assumption that anybody reading the document already knows a lot about Linux programming, just not about that particular item/library you are reading about. Since I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve made an interesting discovery through this project about Linux (or projects that originated from Linux) and Maemo programming.  Most documents, library references, tutorials, etc. seem to make make the assumption that anybody reading the document already knows a lot about Linux programming, just not about that particular item/library you are reading about. Since I started from essentially a clean slate, a lot of the research I had to do into learning how to get Bluetooth working in Python required me to piece together various fragments of code until I had a completely working bluetooth communication class from start to finish (device discovery, name lookups, device selection, socket connection, data communication, to getting a multi-threaded receive function running).  This whole project, for me, has been 75% research and 20% code.</p>
<p>To make life easier for everyone, I wanted post up the complete code for how our bluetooth communication class is implemented.  That way, at least somewhere on the internet is an easy to find, complete (though likely not optimal) example of how to do bluetooth from the N900.  But I do apologize now, because this is probably going to be a very long post&#8230;  I have added in a lot of comments to help with readability, they should explain what is going on throughout.  If you have any questions, leave a comment and I&#8217;ll try to answer as soon as I can.</p>
<p>In order for this example to work on your N900 and recognize the bluetooth module, you will need to install python-bluez (in the extras-devel repository).  From an X Terminal, run these commands:</p>
<pre style="padding-left: 30px;">sudo gainroot
apt-get install python-bluez</pre>
<p>Here are the python files:</p>
<p><strong>BeltConnection.py:</strong></p>
<pre style="padding-left: 30px;">import threading
from bluetooth import *

# Because the application is multi-threaded, this is keep it thread-safe
_bclock = threading.Lock()

# This class Manages all connection stuff
class BeltConnection:
 def __init__(self):
   # Variable declaration
   self.isConnected = False
   self.lastKnownHeading = 0

 def connect(self):
   # This is the prefix of the device name to match
   target_name = "FireFly-"
   target_address = None
   number_of_tries = 2

   # Loop a couple times in case the device/name isn't found the first time
   while target_address is None and number_of_tries &gt; 0:
     number_of_tries = number_of_tries - 1

     # Discover bluetooth devices in the vicinity
     print "Searching for belt..."
     nearby_devices = discover_devices()

     # Loop through each device and check its name for a prefix match
     for btaddr in nearby_devices:
       btname = lookup_name(btaddr)
       print " -Found device: %s (%s)" % (btname, btaddr)
       if btname is not None and btname.startswith(target_name) == True:
         # Use the first device it finds that matches name
         print '    Found firefly.'
         target_address = btaddr
         break

   if target_address is not None:
     # Begin the actual connection device using BT network socket communication
     self.sock=BluetoothSocket( RFCOMM )
     try: self.sock.connect((target_address, 1))
     except:
       print "Unable to connect to belt"
       self.isConnected = False
     else:
       # if connection succeeded, create the multi-thread "receiver"
       # which will handle receiving data in the background automatically
       print "Connected to belt (%s)" % (target_address)
       self.isConnected = True
       self.receiver = __ReceiverThread__(self)
       self.receiver.start()
   else:
     print "Could not locate belt."
     self.isConnected = False

 def sendHeading(self, newheading):
   # If connected, send the heading byte (0-255) to the belt
   if self.isConnected == True:
     self.sock.send(newheading)

 def getCurrentHeading(self):
   heading = 0
   # Acquire a thread lock (for safety) and return the last received heading
   _bclock.acquire()
   try: heading = self.lastKnownHeading
   finally: _bclock.release()
   return heading

 def disconnect(self):
   # If connected, do the socket cleanup stuff
   if self.isConnected == True:
     self.sock.close()
     self.isConnected = False
     print "Disconnected from belt"

# This is a private class that uses threading to receive data from the belt
class __ReceiverThread__ (threading.Thread):
 def __init__(self, parent):
   self.parent = parent
   threading.Thread.__init__(self)

 def run(self):
   data = ""
   while self.parent.isConnected == True:
     # Wait indefinitely until a byte is received.  This is likely not the
     # best way to do this.  For production, it would be better to use the
     # 'select' module to get notification when data is ready.
     data = self.parent.sock.recv(1)

     # Verify received
     if data != "":
       # Convert the byte (0-255) to a heading (0-359) and update belt
       # manager with new heading within the thread lock
       heading = int(float(ord(data))/256*360)                
       _bclock.acquire()
       try: self.parent.lastKnownHeading = heading
       finally: _bclock.release()
     else:
       # If nothing was received, this usually means the socket closed from the
       # remote end, so notify that the belt is disconnected.
       print "Remote client disconnected"
       self.parent.disconnect()</pre>
<p><strong>HapticGuide.py:</strong></p>
<pre style="padding-left: 30px;"># This is a fairly large file, so I've cut out a lot of the extra stuff
# that isn't neccessary for this example. Image loading/parsing, gps, etc.

import sys
import gtk
import gobject
import hildon
import threading

# My custom data manager module
from BeltConnection import *

# This is ESSENTIAL if you are using multi-threading in a GTK app.  There are
# cleaner ways to do the same using gobject, but I'm using the brute force for
# the sake of sanity
gtk.gdk.threads_init()

# The overall UI form class
class HapticGuideUI:
 # A thread lock, in case needed
 lock = threading.Lock()
 # A frequency of the loop call (in milliseconds)
 TIMEOUT = 200

 def on_window_destroy(self, widget, data=None):
   self.belt.disconnect()
   gtk.main_quit()

 def on_window_delete(self, widget, data=None):
   self.belt.disconnect()
   gtk.main_quit()
   return False

 def on_send_click(self, widget, data=None):
   # Parse the custom heading to a value value and send to the belt.
   newHeading = self.manualHeading.get_text()
   self.manualHeading.set_text('')
   try: self.targetHeading = int(newHeading)
   except: print "invalid heading.  must be 0-359."
   else:
     if self.targetHeading&gt;=0 and self.targetHeading&lt;=359:
       adjusted = int(float(self.targetHeading)/360*256)
       self.belt.sendHeading(chr(adjusted))
       print 'New heading: %d   adjusted: %d' % (self.targetHeading, adjusted)
     else:
       print 'invalid heading.  must be 0-359.'

 def on_connect_click(self, widget, data=None):
   if self.belt.isConnected == False:
     self.belt.connect()

 def loop(self):
   # Get latest heading update from belt manager and display update if different from prev
   heading = self.belt.getCurrentHeading()
   if heading != self.lastBeltHeading:
     self.lastBeltHeading = heading
     print 'Current heading: %d' % (heading)
     # Update last received heading on UI
     self.currentHeading.set_text('%d' %(heading))  
   return True

 def __init__(self):
   self.app = hildon.Program.get_instance()    
   gtk.set_application_name("Haptic Guide")

   # This is the brilliant GTK+ Glade builder that lets me keep the entire UI
   # code in a .glade (xml) file to be loaded dynamically.
   builder = gtk.Builder()
   builder.add_from_file("HapticGuide.glade") 

   # Get variables to each of the ui widgets we will need to work with
   self.window = builder.get_object("window1")
   self.manualHeading = builder.get_object("manual_heading")
   self.currentHeading = builder.get_object("lbl_current_heading")

   # Create the belt object to handle data communication
   self.belt = BeltConnection()

   # Initialize tracking variables
   self.lastBeltHeading = 0

   # Connect signals exposed in the glade file to local functions
   signals = { "on_window_destroy" : self.on_window_destroy, \
               "on_window_delete" : self.on_window_delete, \
               "on_connect_clicked" : self.on_connect_click, \
               "on_send_clicked" : self.on_send_click }
   builder.connect_signals(signals)

 def show(self):
   self.window.show_all()
   # Add a recurring timeout call so we can continuously update headings
   gobject.timeout_add(self.TIMEOUT, self.loop)

if __name__ == "__main__":
 # Show the UI window
 ui = HapticGuideUI()
 ui.show()

 # The threads_enter() and threads_leave() calls are ESSENTIAL for apps with
 # multi-threaded intereaction
 gtk.gdk.threads_enter()
 gtk.main()
 gtk.gdk.threads_leave()</pre>
<p><strong>HapticGuide.glade</strong> (as requested, older version but it should work):</p>
<pre style="padding-left: 30px;">&lt;?xml version="1.0"?&gt;
&lt;interface&gt;
 &lt;requires lib="gtk+" version="2.14"/&gt;
 &lt;!-- interface-naming-policy project-wide --&gt;
 &lt;object id="window1"&gt;
 &lt;property name="width_request"&gt;800&lt;/property&gt;
 &lt;property name="height_request"&gt;480&lt;/property&gt;
 &lt;signal name="destroy_event" handler="on_window_destroy"/&gt;
 &lt;signal name="delete_event" handler="on_window_delete"/&gt;
 &lt;child&gt;
 &lt;object id="notebook1"&gt;
 &lt;property name="width_request"&gt;800&lt;/property&gt;
 &lt;property name="height_request"&gt;380&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="can_focus"&gt;True&lt;/property&gt;
 &lt;property name="group_id"&gt;0&lt;/property&gt;
 &lt;child&gt;
 &lt;object id="panelTarget"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;child&gt;
 &lt;object id="btnLoadImage"&gt;
 &lt;property name="label" translatable="yes"&gt;Load
Image&lt;/property&gt;
 &lt;property name="width_request"&gt;138&lt;/property&gt;
 &lt;property name="height_request"&gt;92&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="can_focus"&gt;True&lt;/property&gt;
 &lt;property name="receives_default"&gt;True&lt;/property&gt;
 &lt;signal name="clicked" handler="on_load_clicked"/&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="x"&gt;656&lt;/property&gt;
 &lt;property name="y"&gt;170&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="btn_connect"&gt;
 &lt;property name="label" translatable="yes"&gt;Connect
To Belt&lt;/property&gt;
 &lt;property name="width_request"&gt;138&lt;/property&gt;
 &lt;property name="height_request"&gt;92&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="can_focus"&gt;True&lt;/property&gt;
 &lt;property name="receives_default"&gt;True&lt;/property&gt;
 &lt;accessibility&gt;
 &lt;relation type="flows-to" target="manual_heading"/&gt;
 &lt;/accessibility&gt;
 &lt;signal name="clicked" handler="on_connect_clicked"/&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="x"&gt;656&lt;/property&gt;
 &lt;property name="y"&gt;58&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="aspectframe2"&gt;
 &lt;property name="width_request"&gt;650&lt;/property&gt;
 &lt;property name="height_request"&gt;288&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label_xalign"&gt;0&lt;/property&gt;
 &lt;property name="shadow_type"&gt;none&lt;/property&gt;
 &lt;child&gt;
 &lt;object id="imgTargetPic"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="stock"&gt;gtk-missing-image&lt;/property&gt;
 &lt;/object&gt;
 &lt;/child&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="y"&gt;4&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="aspectframe1"&gt;
 &lt;property name="width_request"&gt;100&lt;/property&gt;
 &lt;property name="height_request"&gt;80&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label_xalign"&gt;0&lt;/property&gt;
 &lt;property name="shadow_type"&gt;none&lt;/property&gt;
 &lt;child&gt;
 &lt;object id="image3"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="stock"&gt;gtk-go-up&lt;/property&gt;
 &lt;/object&gt;
 &lt;/child&gt;
 &lt;/object&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="lblTargetCoords"&gt;
 &lt;property name="width_request"&gt;794&lt;/property&gt;
 &lt;property name="height_request"&gt;32&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;Target Location:      NOT SET&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="y"&gt;313&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="lblCurrentCoords"&gt;
 &lt;property name="width_request"&gt;794&lt;/property&gt;
 &lt;property name="height_request"&gt;32&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;Current Location:      UNKNOWN&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="y"&gt;289&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;/object&gt;
 &lt;/child&gt;
 &lt;child type="tab"&gt;
 &lt;object id="tabImage"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;Target&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="tab_fill"&gt;False&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="image2"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="pixbuf"&gt;map-sim.png&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;1&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child type="tab"&gt;
 &lt;object id="tabMap"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;Map&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;1&lt;/property&gt;
 &lt;property name="tab_fill"&gt;False&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="panelManual"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="orientation"&gt;vertical&lt;/property&gt;
 &lt;child&gt;
 &lt;object id="lbl_current_heading"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;0&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;0&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="hbox1"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;child&gt;
 &lt;object id="label4"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;New Heading (0-359): &lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;0&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="manual_heading"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="can_focus"&gt;True&lt;/property&gt;
 &lt;property name="invisible_char"&gt;&amp;#x25CF;&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;1&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child&gt;
 &lt;object id="btn_send"&gt;
 &lt;property name="label" translatable="yes"&gt;send&lt;/property&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="can_focus"&gt;True&lt;/property&gt;
 &lt;property name="receives_default"&gt;True&lt;/property&gt;
 &lt;accessibility&gt;
 &lt;relation type="flows-to" target="manual_heading"/&gt;
 &lt;/accessibility&gt;
 &lt;signal name="clicked" handler="on_send_clicked"/&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;2&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;1&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;2&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;child type="tab"&gt;
 &lt;object id="tabManual"&gt;
 &lt;property name="visible"&gt;True&lt;/property&gt;
 &lt;property name="label" translatable="yes"&gt;Manual Control&lt;/property&gt;
 &lt;/object&gt;
 &lt;packing&gt;
 &lt;property name="position"&gt;2&lt;/property&gt;
 &lt;property name="tab_fill"&gt;False&lt;/property&gt;
 &lt;/packing&gt;
 &lt;/child&gt;
 &lt;/object&gt;
 &lt;/child&gt;
 &lt;/object&gt;
&lt;/interface&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/08/python-bluetooth-code-example/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Sweet Smell of Success</title>
		<link>http://blogs.nokia.com/pushn900/2010/01/07/the-sweet-smell-of-success/</link>
		<comments>http://blogs.nokia.com/pushn900/2010/01/07/the-sweet-smell-of-success/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 18:28:57 +0000</pubDate>
		<dc:creator>timothy2</dc:creator>
				<category><![CDATA[The Haptic Guide]]></category>

		<guid isPermaLink="false">http://blogs.nokia.com/pushn900/?p=1570</guid>
		<description><![CDATA[Last night, Mike and I performed our first true integration test of the prototype belt and it went far better than I expected.  The test was fairly simple; it involved me running the N900 and Mike wearing the belt.  I would send directional commands to the belt and Mike would follow the haptic (vibrational) feedback [...]]]></description>
			<content:encoded><![CDATA[<p>Last night, Mike and I performed our first true integration test of the prototype belt and it went far better than I expected.  The test was fairly simple; it involved me running the N900 and Mike wearing the belt.  I would send directional commands to the belt and Mike would follow the haptic (vibrational) feedback and show me which direction I was telling him to go.</p>
<p>I fired up the application and connected to the belt over bluetooth and Mike stood across the room with his back to me.  It took a minute or so to get used to it, but very soon Mike was able to accurately show me which direction I was telling him to go.  There were just a couple of small problems: 1) Human error &#8211; I had trouble remembering my own directions, so I would send a bearing in one direction and get mixed up which way I was telling him to go and 2) There is a minor sensory perception that was unexpected.  When the belt was facing the direction and I sent a bearing directly behind, the difference was not very noticeable.  To fix this, we will have to do a smooth transition from the initial motor to the new going through all the motors along the way.  This will feel more natural to the wearer and should resolve that problem.</p>
<p>Overall, we deemed this first test a major success and we learned a couple things in the process.  The software and hardware communication works well but more importantly, the belt appears to have a VERY quick learning time and starts to feel completely natural after only a couple minutes of wearing it.</p>
<p>A video of our first test will likely be posted somewhere in the near future.</p>
<p>-Tim</p>
<p><img id="myFxSearchImg" style="border: medium none; position: absolute; z-index: 2147483647; opacity: 0.6; display: none;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADsElEQVR4nK2VTW9VVRSGn33OPgWpYLARbKWhQlCHTogoSkjEkQwclEQcNJEwlfgD/AM6NBo1xjhx5LyJ0cYEDHGkJqhtBGKUpm3SFii3vb2956wPB/t+9raEgSs52fuus89613rftdcNH8/c9q9++oe/Vzb5P+3McyNcfm2CcPj9af9w6gwjTwzvethx3Bx3x8xwd1wNM8dMcTNUHTfFLPnX6nVmZpeIYwf3cWD/PhbrvlPkblAzVFurKS6GmmGqqComaS+qmBoTI0Ncu3mXuGvWnrJ+ZSxweDgnkHf8ndVTdbiT3M7cQp2Z31dRTecHAfqydp4ejhwazh6Zezfnu98E1WIQwB3crEuJ2Y45PBTAQUVR9X4At66AppoEVO1Q8sgAOKJJjw6Am6OquDmvHskZ3R87gW+vlHz98zpmiqphkkRVbQtsfPTOC30lJKFbFTgp83bWh7Zx/uX1B6w3hI3NkkZTqEpBRDBRzG2AQHcwcYwEkOGkTERREbLQ/8HxJwuW7zdYrzfZ2iopy4qqEspKaDYravVm33k1R91Q69FA1VBRzFIVvXbx5AgXT44A8MWP81yfu0utIR2aVK3vfCnGrcUNxp8a7gKYKiLCvY2SUvo/aNtnM3e49ucK9S3p0aDdaT0UAVsKi2tVi6IWwNL9JvdqTdihaz79/l+u/rHMxmaJVMLkS2OoKKLWacdeE3IsSxctc2D5Qcl6vUlVVgNt+fkPPcFFmTw1xruvT7SCd7nuVhDQvECzJH90h0azRKoKFRkAmP5lKTWAGRdefoZL554FQNUxB92WvYeA5UN4PtSqwB2phKqsqMpBgAunRhFR3j49zuU3jnX8k6fHEQKXzh1jbmGDuYU6s4t1rt6socUeLLZHhYO2AHSHmzt19ihTZ48O8Hzl/AmunD/BjTvrvPfNX3hWsNpwJCvwYm+ngug4UilSCSq6k8YPtxDwfA+WRawIWFbgscDiULcCEaWqBFOlrLazurupOSHLqGnEKJAY8TwBEHumqUirAjNm52vEPPRV4p01XXMPAQhUBjcWm9QZwijwokgAeYHlHYA06KR1cT6ZvoV56pDUJQEjw0KeaMgj1hPEY4vz2A4eW0/e1qA7KtQdsxTYAG0H3iG4xyK1Y+xm7XmEPOJZDiENzLi2WZHngeOjj2Pe+sMg4GRYyLAsx7ME4FnsyTD9pr0PEc8zPGRAwKXBkYOPEd96cZRvf11g9MDe7e3R4Z4Q+vyEnn3P4t0XzK/W+ODN5/kPfRLewAJVEQ0AAAAASUVORK5CYII%3D" alt="" width="24" height="24" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.nokia.com/pushn900/2010/01/07/the-sweet-smell-of-success/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

