Mycroft Community Forum

Looking for help to Redirect Dialogue output for a robot

Hi,
I am trying to redirect the mycroft dialogue to a robot I have. But I am a bit lost as to where to interface with the dialogue output to send it to my robots. Also I am curious what method for doing this would be the most efficient and easiest for other people to replicate. I tried searching the forums but didn’t come across anything. I just need the string and my robot will perform its own tts. Thought: make the robot its own tts in mycroft, a skill that captures all output dialogue and redirects it. I am testing this with a Cozmo robot.
Joseph

TTS has been moved to a plugin-style, so that may be your easiest option. Secondarily to that you’d have to read things off the message bus.

Also curious how the cozmo hacking is going, since I have one in my house.

Thanks,
Im just now looking into how the TTS plugin is working. I was hoping for a skill as it would be easier for the beginner to use. Still trying to figure out where to pick up on the message bus besides command line.

I just got a Cozmo for my kid. Its been pretty fun. I already had a Vector and have him running a custom program built off of Vectorator/ google AIY vision on a pi3/ and some other mods. I have him and Cozmo so they run together and chat, Mostly Cozmo asks Vector questions and Vector responds. They Google AIY vision is alright but the models are a little limited when it comes to common household objects, great at identifying animals though.

Hey there, if you want to access the speakable strings from the message bus you can either create a new TTS plugin as suggested, or you could set the Mycroft TTS module to dummy which will stop it from generating any spoken output:

mycroft-config set tts.module dummy

and listen on the message bus for the speak messages. A Skill doing this would look like:

from mycroft import MycroftSkill

class SpeechSkill(MycroftSkill):

    def initialize(self):
        self.bus.on('speak', self.handle_speech)

    def handle_speech(self, message):
        tts_string = message.data['utterance']
        self.log.info(tts_string)
        # Do something with this string...

def create_skill():
    return SpeechSkill()

You might also want to modify the play_wav_cmdline, play_mp3_cmdline, and play_ogg_cmdline settings in mycroft.conf in order to redirect other sounds to your robot.

1 Like

Thank you Gez!
That is exactly what I was looking for. I will give this a try on my day off and let you guys know how it goes. I’ll post the code and maybe a video when I get it working.
Joseph

1 Like

Here is what I am using right now. I am going to add some more features and clean it up but this is working great.

from mycroft import MycroftSkill, intent_file_handler
import cozmo
import time
import random
cSay = ‘hello’
class Cozmo(MycroftSkill):

#def __init__(self):
 #   MycroftSkill.__init__(self)

def initialize(self):
    self.bus.on('speak', self.handle_speech)

def handle_speech(self, message):
    global cSay
    tts_string = message.data['utterance']
    self.log.info(tts_string)
    print(f'tts string {tts_string}')
    cSay = str(tts_string)
    time.sleep(.1)
    #cozmo.robot.Robot.say_text(tts_string).wait_for_completed()
    #with cozmo.robot.Robot as robot:
    #    robot.say_text(cSay).wait_for_completed()
    cozmo.run_program(self.cozmo_program)
    cozmo.run_program(self.cozmo_animate)
    # Do something with this string...

def cozmo_program(self, robot: cozmo.robot.Robot):
    global cSay
    robot.say_text(cSay).wait_for_completed()


def cozmo_animate(self, robot: cozmo.robot.Robot):
    # grab a list of animation triggers
    all_animation_triggers = robot.anim_triggers

    # randomly shuffle the animations
    random.shuffle(all_animation_triggers)

    # select the first three animations from the shuffled list
    triggers = 1
    chosen_triggers = all_animation_triggers[:triggers]
    print('Playing {} random animations:'.format(triggers))

    # play the three random animations one after the other, waiting for each to complete
    for trigger in chosen_triggers:
        print('Playing {}'.format(trigger.name))
        robot.play_anim_trigger(trigger).wait_for_completed()


    # grab animation triggers that have 'WinGame' in their name
    chosen_triggers = [trigger for trigger in robot.anim_triggers if 'WinGame' in trigger.name]
1 Like