Introduction
The development of this episode mostly focused on the speaking features of SevenOfNine (It's time to call her with her full name) gave the interesting opportunity to experiment some good software applications of Python and Linux Bash together as synchronized and concurrent applications.
Before going in depth on the new hardware settings and software implementation, enjoy with the Art-a-Tronic Episode 5 video.
Audio Out
Adding audio out features to the Raspberry PI 3B+ is a relatively easy operation; you can choose between plenty of solutions, from a USB or Bluetooth speaker to the line out, using the HDMI audio out and sending audio to an external device. Earbuds or amplifier. Adding "speaking" features to Seven of Nine has been a bit challenging. I have tried several possible solutions but not all worked as desired.
The Hardware Choice
As the audio should be a permanent feature of the architecture, I have excluded both USB and Bluetooth devices, focusing the attention on the stereo audio out plug of the Raspberry. I have also tried a nice multi-functional integrated speaker but I had to exclude it too; the speaker should be powered manually (this happens on all the similar devices I tested). The most reliable solution has been adopting a 1W amplifier from Kitronik installed inside the head.
In the above image: the small USB power supply for the amplifier and the PCB fixed back to the Raspberry PI using the same internal head support. Keeping the parts closed made possible to has very short cables; at this point, the head starts being really full of cables!
To reach a good audio level and quality, considering the need to mask an external speaker I have used a smartphone high power speaker. These devices have a very good response covering a wide range of frequencies and are small and lightweight. The images below show the speaker positioning and masking.
This solution – after several days of continuous testing – demonstrated to be reliable to work for a long time without problems.
A Voice for Seven Of Nine
Seven Of Nine should be able to communicate to the Internet but I avoided to have a sort of permanent connection to the cloud creating another Alexa-like engine. This (sort of) Borg should have its own character possibly following a coherent logic in all the parts; for this reason, I decided to exclude any kind of text-to-speech software to generate sentences. I followed a more complicated approach but as far as I can see, the result is not so bad and the possibilities are limitless.
Coherently with the design of the animatronic and the environment with which it reacts and interacts Seven Of Nine speaks using sentences from film, TV series, videos and more. The initial difficult has been finding a method to develop the set systematically: after searching on the net, a great help come from the site playphrase.me where you can search by word or sentence over 350k short pieces of video that you can download. Better to take a try than explain how it works.
But this was only the first part of the job. After selecting a set of phrases (but the list is growing), I converted every video sequence to its corresponding .wav file, cleaned, equalized and then finally saved it in the format Text01.wav ... Textnn.wav Every sentence is also included in a constantly updated index document to make easy programming the audio composition algorithms.
The most updated list of phrases and the PDF index file are available under the Phrases folder of the mannequin GitHub repository.
The Phrases Creation Engine
The video sequence above shows the effect of the phrases generator. To make the scene I have accelerated the frequency of the sentences so sometimes these are replicated.
Using wav file makes easy to play them in the Linux environment. I have created a set of bash commands to select a different sentence from an array based on the accurate pseudo-random generator of the Linux kernel.
#!/bin/bash # Output a random choice between a group # of phrases used periodically to attract # the attention. Phrases are not # context-specific. # -----------------------------------
# Phrases prefix PREFIX="/home/pi/Phrases/Text" SUFFIX=".wav" # Phrases array SIZE=8 SENTENCE=(04 14 15 36 38 39 40 12 16 16) # Chose a random phrase from the set # Note that the modulos of the randome # number in the range is calculated based # on the range + 1 so the last array # value is duplicated NUM=$(($RANDOM % $SIZE)) # Play the phrase aplay $PREFIX${SENTENCE[NUM]}$SUFFIX
The listing above refers to the command chose_phrase.sh As much the phrases in the array increases, as much the randomization is effective. The list I am using in this version is of about 50 sentences but it is growing. To call it recursively, it has been added to the user cron scheduler.
In other cases I have used a similar process making a more sophisticated effect, associating a complex sentence with more than one single phrase. For example, to create an always different sentence built of three parts, I have defined three arrays with three different groups of the sentence part. When the command is launched, from every array phrases group I extract randomly one of the indexes of the list, then three parts are played in sequence; it is very difficult that repeating the command twice the same sentence occurs exactly in the same order.
Connecting Seven Of Nine to the Community
Seven Of Nine not only is part of the Borg colony, permanently connected to the millions of other assimilated civilizations but is also an intruder to the Terrestrian human life. As a matter of fact, Seven Of Nine can spread Borg communications and menacing the human species periodically sending tweets over the Internet.
Register a Twitter Account as Developer
To be able to manage Twitter from a program you should have a developer certificate sent to the server; this is an easy sequence that can be activated with any Twitter account at the address developer.twitter.com
The path to follow to create your own app (or more than one) is well explained after you register your account as a developer and there are many tutorials on the network explaining the process step-by-step. What is important to know, is that after creating your Twitter APP you are provided by foud keys, all indispensable to access the Twitter APIs (directly or through a software library). In my case, I have used Python so the best solution is saving the keys provided by the Twitter App in a text-only Json formatted file.
Your app keys are unique and secret so you should not share them, e.g. on a GitHub repository.
{ "consumer_key": "5MNhH6IXXXX9d8m0inYN", "consumer_secret": "GrfHhNBGeqcqXXXXXXV6fgHUjHIAmUeWRIh8O2UIkqP", "access_token": "18448354-HpXUf6XXXXXUkHzcNNu5wzlFBRwax0eEOiK3", "access_token_secret": "VvH6GM6zXXXXXrXErLNYbNCaM6oMayr6Hphfxba" }
The Json file with the author keys should be similar to the code above. In this case, the keys are fake, you should replace the quoted content with your own keys.
Creating the Twitter Libraries
To build this feature I have created a python command; the simplest way to use the Twitter APIs from Python is installing the Twitter APIs Python wrapper tweepy. Installation is extremely easy and the usage is well documented. To install the library (do it first) you should just launch the following command from the terminal:
pi$>sudo pip3 install tweepy
You see that I used pip3 to install the library for Python3, but you can also use the command pip for Python 2. To manage the library call from different Python scripts I have also created the SevenOfNineTwitter Python class (twitter.py file). You can find this and the other Python classes in the GitHub repository under the folder pyclasses.
The Sending Twitter Python Command
Thanks to the class library that pragmatically manages all the dirty job of initiating the twitter communication, connecting and sending the tweet message, the Python command to send periodically tweets is very simple and the library can be reused by other Python commands that will use Twitter messages in other contexts.
#!/usr/bin/python3 from pyclasses.twitter import SevenOfNineTwitter from picamera import PiCamera tweet = SevenOfNineTwitter() tweet.connectTwitter() camera = PiCamera() camera.capture("/home/pi/images/twitter.jpg") tweet.tweetGeneric(True)
The command before calling the SevenOfNineTwitter class to send the tweet captures an image, overwritten always with the same name. the tweetGeneric() method of the class to the rest. Also, this command has been added to the crontab scheduler to execute recursively. Below some examples from my account Twitter feed.
#artatronic #picasso #designchallenge #sevenofnine says:<<Info assimilated>> @E14Community @element14_Avnet @e14presents @Elegoo_Official @LorenzoPMerlo1 @Hacksterio @Raspberry_Pi pic.twitter.com/Lk8z2FM2cH
— Enrico Miglino (@enricomiglino) April 21, 2019
#artatronic #picasso #designchallenge #sevenofnine says:<<I get it, loud and clear>> @E14Community @element14_Avnet @e14presents @Elegoo_Official @LorenzoPMerlo1 @Hacksterio @Raspberry_Pi pic.twitter.com/zI1Apot2aH
— Enrico Miglino (@enricomiglino) April 20, 2019
#artatronic #picasso #designchallenge #sevenofnine says:<<I can change my shape>> @E14Community @element14_Avnet @e14presents @Elegoo_Official @LorenzoPMerlo1 @Hacksterio @Raspberry_Pi pic.twitter.com/XM9OcKad1v
— Enrico Miglino (@enricomiglino) April 20, 2019
Top Comments