The Arc Raspberry MKII

Further Developments.

Iron-Man-2-Movie-Theme-Song-9
Note to self for future Pi project: holograms.

Key goals summary:

  1. Improve aesthetics
  2. Get voice responses telling me my location upon a voice command

After the success of the Arc Raspberry I wanted to improve my design, make it more wearable and make it cooler. Again, inspired by Tony Stark I thought of making my own J.A.R.V.I.S.

After some milling around on the internet reading up on speech recognition I came across Jasper.

My imagination lit up with thoughts of a robotic voice telling me where I am, I could simply use the same code from the MKI and implement alongside Jasper – it seemed so simple; the truth, however…

I opted again for a Raspberry Pi A+, this time with a bigger case hoping to fit in more components, I also changed the choice of GPS module to a HAT based solution, rather than the USB based solution of the first.

As this time the device was going to speak instead of have visual clues as to its current location I decided the colour should remain the same – blue being the obvious choice.

Further components.

Further work.

These blog posts are to serve as a demonstration/log of all my builds rather than a build guide, so please forgive any brevity in description of the work performed making these projects. One day I may decide to organise all my notes etc. and make a full build guide.

Until then, onward:

With the GPS HAT I could put the PiGlow module onto it and get in a more central position, rather than having it sit on the Pi’s GPIO pins directly; which on the MKI made it sit off centre of the faceplate. The other advantage to having the HAT is no USB connection required or cabling to handle with it, reducing the size further – I really wanted to be able to wear this one out and about.

At one point I had a run in with the soldering iron:

received_10204974766162221
This hurt.

Since Jasper requires the ability to listen as well as speak I required a USB sound card to get the microphone and speaker outputs, thanks to their guide over at the Jasper website I was able to get this set up relatively easily. The overall installation of Jasper takes quite some time so much caffeine was consumed during.

IMG_20150301_104052
Early comparison shot between the MKII and MK I.

As can be seen above the MKI was rather… rustic in its construction; which while apt considering the conditions Stark made his first reactor in, could be improved. You may have noticed ‘Sugru’ up there in the components section, this stuff is like magic; its a soft adhesive rubber like material that can be moulded and stuck to things – once exposed to air it begins to solidify and adhere to whatever material you attach it to. More info here.

I used the Sugru to cover up some components, such as the battery charger module, as well as assist with the overall construction and strength of the device.

Once the hardware was assembled the device was ready to rumble for the software:

IMG_20150311_055925
Looking better…

With some configuration of Jasper and choosing the voice I wanted, it was time to move onto making a module that contained my GPS code that would be called and activated upon when a certain word was said, for instance ‘location’. I also wanted to get a proper way to shut down the MKII as the MKI I turned off simply by flicking the switch on the battery circuit (not a good idea, can corrupt the SD Card and/or the Raspbian installation).

As I said before I thought this would be simple, it was not. It took once again many hours of chasing red herrings and actual bugs before finally getting it to work. Fortunately now I knew the main functionality worked I didn’t have to wander around in the cold trying to get a result. Instead I was sat at my window with the device waiting for a GPS fix so I could test it worked. After what seemed an eternity of saying “Jasper… Location” – it finally worked and spoke my location to me; it was a moment of pure elation.

Further code.

The main module code:

# -*- coding: utf-8-*-
#import modules
import re, sys, string, os, gps
from time import sleep
import random
import re

#key words for the main jasper program to use for recognition
WORDS = ["LOCATION"]

#alphabet for grid reference
upper = 'ABCDEFGHIJKLMNOPQRSTUVWX'

#locations stored as grid references
Bury = ["JO02IG", "JO02IF", "JO02JG", "JO02JF"]

Thetford = ["JO02IK", "JO02JK", "JO02IJ", "JO02JJ"]

Cambridge = ["JO02AF", "JO02AE", "JO02BE", "JO02BF", "JO02CE", "JO02CF"]

#the main function that is called upon voice recognition
def handle(text, mic, profile):
	location="nosignal"
	messages=("")
	sessiongps = gps.gps("localhost", "2947")
	sessiongps.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)
	while True:
		#gather statistics from tpv (latitude + longitude) then write both to respective variables
		report = sessiongps.next()
		if report['class'] == 'TPV':
				if hasattr(report, 'lat'):
					dec_lat=`report.lat`
					if report['class'] == 'TPV':
						if hasattr(report, 'lon'):
							dec_lon=`report.lon`
							
							#/below code source: http://ham.stackexchange.com/questions/221/how-can-one-convert-from-lat-long-to-grid-square
							adj_lat = float(dec_lat) + 90.0
							adj_lon = float(dec_lon) + 180.0
							
							mhloc=""

							grid_lat_sq = upper[int(adj_lat/10)];
							grid_lon_sq = upper[int(adj_lon/20)];

							grid_lat_field = str(int(adj_lat%10))
							grid_lon_field = str(int((adj_lon/2)%10))

							adj_lat_remainder = (adj_lat - int(adj_lat)) * 60
							adj_lon_remainder = ((adj_lon) - int(adj_lon/2)*2) * 60

							grid_lat_subsq = upper[int(adj_lat_remainder/2.5)]
							grid_lon_subsq = upper[int(adj_lon_remainder/5)]

							mhloc = grid_lon_sq + grid_lat_sq + grid_lon_field + grid_lat_field + grid_lon_subsq + grid_lat_subsq
							#/end
							
							#check grid reference against stored lists and assign resulting location to a variable
							if mhloc in Bury:
								location="Bury Saint Edmunds"
							elif mhloc in Thetford:
								location="Thetford"
							elif mhloc in Cambridge:
								location="Cambridge"
							else:
								location="unknown"
							break
				#set location variable to nosignal if no data is recieved from the GPS
				location="nosignal"	
				#break out of the loop once data has been gathered from the GPS
				break			

	#speech output for unknown locations
	if location == "unknown":
		#list of different messages to say for variety
		messages = ["I'm not entirely sure where you are, Sir.",
		"I don't know this location, Sir. Off travelling are we?"]
		
		#choose a message from above at random
		message = random.choice(messages)

		#output the message to the text to speech engine
		mic.say(message)
	
	#speech output for no signal scenario
	elif location == "nosignal":
		#list of different messages to say for variety
		messages = ["I can't get a signal, Sir.",
		"There doesn't appear to be any data coming from the GPS module, Sir, may I suggest waiting for a fix?"
		,"There is no signal from a GPS satallite; either the GPS module has no fix, or you're no longer on earth, Sir."]
		
		#choose a message from above at random
		message = random.choice(messages)

		#output the message to the text to speech engine
		mic.say(message)
	
	#speech output for known locations - the location retrieved from the lists is put directly into the text to speech engine as a string
	else:
		#list of different messages to say for variety		
		messages = ["You're in " + str(location) + "Sir.",
		"You appear to be in " + str(location) + "Sir."]
		
		#choose a message from above at random
		message = random.choice(messages)

		#output the message to the text to speech engine
		mic.say(message)

#checks the key words are valid after being interpreted by the speech to text engine		
def isValid(text):

    return bool(re.search(r'\blocation\b', text, re.IGNORECASE))

The shut down module code:

# -*- coding: utf-8-*-
#import modules
import re, sys, string, os
from time import sleep
import random

#key words for the main jasper program to use for recognition
WORDS = ["SHUTDOWN"]

#the main function that is called upon voice recognition
def handle(text, mic, profile):

	#list of different messages to say for variety
    messages = ["Shutting the Arc Raspberry down, Sir.",
                "Turning off, Sir.",
                "Good night, Sir.", "Have a good day, Sir"]

	#choose a message from above at random
    message = random.choice(messages)

	#output the message to the text to speech engine
    mic.say(message)
    
	#sleep for 5 seconds to ensure the text to speech output has completed
    sleep(5)
    
	#issue a shutdown command to the operating system
    os.system('sudo halt')

#checks the key words are valid after being interpreted by the speech to text engine
def isValid(text):
    return bool(re.search(r'\bshutdown\b', text, re.IGNORECASE))

This code runs under the main Jasper module so no need to run from rc.local, however; the code to make the PiGlow turn on needs to be in there as well as the code for starting the GPS again:

sleep 15
sudo killall gpsd
sleep 15
sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock
python /home/pi/MKII/arcblue.py &

Jasper itself is called from crontab: (‘crontab -e’ command) and the code within crontab:

@reboot python /home/pi/jasper/jasper.py &

@reboot means whenever the OS boots, again the & symbol makes the script run silently.

And the code for making the device glow blue is rather simple:

from time import sleep
from PyGlow import PyGlow

pyglow = PyGlow()

pyglow.all(0)

try:

  # Loop until users quits with CTRL-C
  while True :
   
	pyglow = PyGlow()

	pyglow.color("blue", 255)
	pyglow.color("white", 25)
	
	sleep(1)
      
except KeyboardInterrupt:
  # Reset GPIO settings
  pyglow.all(0)

Further looks.

The final product:

IMG_20160417_180943
With a nice headphone/mic attached.

The look of the final product in action:

IMG_20150313_194035
This moment.

Further phases.

Once again I was happy with what I accomplished. My thoughts moved forward to what the MKIII would be, this version was wearable – but still too big to practically wear for the theatre release of Age of Ultron, I needed something smaller.

Along came The Pi Zero

Advertisements

One thought on “The Arc Raspberry MKII

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s