From fec5bfb003d830bb02ea2d3d07bb9d41625ee8c8 Mon Sep 17 00:00:00 2001 From: hello-sanchez Date: Mon, 25 Jul 2022 11:29:32 -0700 Subject: [PATCH] Init commit of speech to text tutorial. --- example_8.md | 144 +++++++++++++++++++++++++++++++++++++++++++++ src/speech_text.py | 58 ++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 example_8.md create mode 100755 src/speech_text.py diff --git a/example_8.md b/example_8.md new file mode 100644 index 0000000..8334a70 --- /dev/null +++ b/example_8.md @@ -0,0 +1,144 @@ +# Example 8 + +This example will showcase how to save the interpreted speech from Stretch's [ReSpeaker Mic Array v2.0](https://wiki.seeedstudio.com/ReSpeaker_Mic_Array_v2.0/) to a text file. + + +

+ +

+ + + +Begin by running the `sample_respeaker.launch` file in a terminal. +```bash +# Terminal 1 +roslaunch respeaker_ros sample_respeaker.launch +``` + +Then run the speech_text node. + +```bash +# Terminal 2 +cd catkin_ws/src/stretch_tutorials/src/ +python speech_text.py +``` + +The ReSpeaker will be listening and will start to interpret speech and save the transcript to a text file. To stop shutdown the node, type **Ctrl** + **c** in the terminal. + +### The Code +```python +#!/usr/bin/env python + +import rospy +import os +from speech_recognition_msgs.msg import SpeechRecognitionCandidates + +class SpeechText: + """ + A class that saves the interpreted speech from the ReSpeaker Microphone Array to a text file. + """ + def __init__(self): + """ + Initialize subscriber and directory to save speech to text file. + """ + self.sub = rospy.Subscriber("speech_to_text", SpeechRecognitionCandidates, self.callback) + self.save_path = '/home/hello-robot/catkin_ws/src/stretch_tutorials/stored_data + rospy.loginfo("Listening to speech.") + + def callback(self,msg): + """ + A callback function that receives the speech transcript and appends the + transcript to a text file. + :param self: The self reference. + :param msg: The SpeechRecognitionCandidates message type. + """ + transcript = ' '.join(map(str,msg.transcript)) + file_name = 'speech.txt' + completeName = os.path.join(self.save_path, file_name) + + with open(completeName, "a+") as file_object: + file_object.write("\n") + file_object.write(transcript) + +if __name__ == '__main__': + rospy.init_node('speech_text') + SpeechText() + rospy.spin() +``` + + +### The Code Explained +Now let's break the code down. + +```python +#!/usr/bin/env python +``` +Every Python ROS [Node](http://wiki.ros.org/Nodes) will have this declaration at the top. The first line makes sure your script is executed as a Python script. + + +```python +import rospy +import os +``` + +You need to import rospy if you are writing a ROS Node. + +```python +from speech_recognition_msgs.msg import SpeechRecognitionCandidates +``` + +Import SpeechRecognitionCandidates from the speech_recgonition_msgs so that we can receive the interpreted speech. + +```python +def __init__(self): + """ + Initialize subscriber and directory to save speech to text file. + """ + self.sub = rospy.Subscriber("speech_to_text", SpeechRecognitionCandidates, self.callback) +``` + +Set up a subscriber. We're going to subscribe to the topic "speech_to_text", looking for SpeechRecognitionCandidates messages. When a message comes in, ROS is going to pass it to the function "callback" automatically. + +```python +self.save_path = '/home/hello-robot/catkin_ws/src/stretch_tutorials/stored_data +``` + +Define the directory to save the text file. + +```python +transcript = ' '.join(map(str,msg.transcript)) +``` + +Take all items in the iterable list and join them into a single string named transcript. + +```python +file_name = 'speech.txt' +completeName = os.path.join(self.save_path, file_name) +``` + +Define the file name and create a complete path directory. + + +```python +with open(completeName, "a+") as file_object: + file_object.write("\n") + file_object.write(transcript) +``` + +Append the transcript to the text file. + +```python +rospy.init_node('speech_text') +SpeechText() + +``` +The next line, rospy.init_node(NAME, ...), is very important as it tells rospy the name of your node -- until rospy has this information, it cannot start communicating with the ROS Master. In this case, your node will take on the name talker. NOTE: the name must be a base name, i.e. it cannot contain any slashes "/". + +Instantiate the class with `SpeechText()` + +```python +rospy.spin() +``` +Give control to ROS. This will allow the callback to be called whenever new +messages come in. If we don't put this line in, then the node will not work, +and ROS will not process any messages. diff --git a/src/speech_text.py b/src/speech_text.py new file mode 100755 index 0000000..826ad08 --- /dev/null +++ b/src/speech_text.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# Import modules +import rospy +import os + +# Import SpeechRecognitionCandidates from the speech_recognition_msgs package +from speech_recognition_msgs.msg import SpeechRecognitionCandidates + + +class SpeechText: + """ + A class that saves the interpreted speech from the ReSpeaker Microphone Array to a text file. + """ + def __init__(self): + """ + Initialize subscriber and directory to save speech to text file. + """ + # Initialize subscriber + self.sub = rospy.Subscriber("speech_to_text", SpeechRecognitionCandidates, self.callback) + + # Create path to save captured images to the stored data folder + self.save_path = '/home/hello-robot/catkin_ws/src/stretch_tutorials/stored_data' + + # Create log message + rospy.loginfo("Listening to speech.") + + def callback(self,msg): + """ + A callback function that receives the speech transcript and appends the + transcript to a text file. + :param self: The self reference. + :param msg: The SpeechRecognitionCandidates message type. + """ + # Take all items in the iterable list and join them into a single string + transcript = ' '.join(map(str,msg.transcript)) + + # Define the file name and create a complete path name + file_name = 'speech.txt' + completeName = os.path.join(self.save_path, file_name) + + # Append 'hello' at the end of file + with open(completeName, "a+") as file_object: + file_object.write("\n") + file_object.write(transcript) + + +if __name__ == '__main__': + # Initialize the node and name it speech_text + rospy.init_node('speech_text') + + # Instantiate the SpeechText class + SpeechText() + + # Give control to ROS. This will allow the callback to be called whenever new + # messages come in. If we don't put this line in, then the node will not work, + # and ROS will not process any messages + rospy.spin()