Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with plugin code? #44

Open
AIWintermuteAI opened this issue Nov 27, 2018 · 5 comments
Open

Issue with plugin code? #44

AIWintermuteAI opened this issue Nov 27, 2018 · 5 comments
Labels

Comments

@AIWintermuteAI
Copy link

AIWintermuteAI commented Nov 27, 2018

I wrote a following plugin for rapiro voice control. Unforunately it doesn't seem to work.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

# Plugin for Rapiro speech recognition
def run(readable_results, data, rawbuf):
    if ('rapiro_activate'  in readable_results):
		os.environ['ISLISTENING'] = '1'
                execute('echo \"#PR000G255B000T010\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
    if ('rapiro_sleep'  in readable_results):
		os.environ['ISLISTENING'] = '0'
                execute('echo \"#PR000G000B255T010\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
    if ('rapiro_shutdown'  in readable_results):
		os.environ['ISLISTENING'] = '0'
		execute('echo \"#Z\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
                execute('echo \"#PR000G000B000T010000\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
		execute('sudo shutdown now')

		
    if (os.environ['ISLISTENING'] == '1'):
        if ('stop_action' in readable_results):
                execute('echo \"#M0\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')

        if ('go_forward' in readable_results):
                execute('echo \"#M1\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')

        if ('go_back' in readable_results):
                execute('echo \"#M2\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
				
        if ('go_left' in readable_results):
                execute('echo \"#M4\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')

        if ('go_right' in readable_results):
                execute('echo \"#M3\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')	

        if ('wave_hand' in readable_results):
                execute('echo \"#M5\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')	
       
        if ('action_six' in readable_results):
                execute('echo \"#M6\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')

        if ('action_seven' in readable_results):
                execute('echo \"#M7\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
				
        if ('wave_goodbye' in readable_results):
                execute('echo \"#M8\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')

        if ('action_nine' in readable_results):
                execute('echo \"#M9\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')	
		
				
def execute(command):
    command_line = command
    os.system(command_line)

I launch it with the following script

import os
import subprocess

os.environ['ISLISTENING'] = '0'
os.system('echo \"#PR000G000B255T010\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0')
subprocess.Popen('python sopare.py -l')

Sopare freezes right after start. If I use ./sopare.py -v -t test for training very often the following error starts appearing "[Errno -9988] Stream closed"

Does somebody else having similiar issues?
Before when i was using fewer commands(3-4) and no environmental variables everything was working fine.

@bishoph
Copy link
Owner

bishoph commented Nov 27, 2018

What does freezes mean? Do you get any error messages? Why do you launch SOPARE via a subprocess and not directly as you can do all the startup stuff within the plugin?

Beside all the questions: executing a process in a plugin should be avoided. Instead, start a thread and launch the process decoupled from the plugin.

@AIWintermuteAI
Copy link
Author

No error messages, just doesn't produce any output after launching.
I probably don't understand well enough how the sopare plugins work. My understanding was that the content of the plugin executes after something was recognized in the sound stream.
This is why I created separate python script to be executed by cron on boot - it changes the color of the RGB LED in robot's eyes to Blue(means finished boot procedure), creates environmental variable and spawns sopare process(which inherits that environmental variable).
If I launch sopare with cron, will the plugin script get executed immediately after sopare was launched?

By process in the plugin you mean executing a shell command? It used to work quite good before, when there were less if-conditions. What is a better way?

@bishoph
Copy link
Owner

bishoph commented Nov 27, 2018

I recommend to start and use SOPARE directly to see output like warnings and error messages until you got a working system.

A SOPARE plugin is part of the analysis thread. Each plugin gets initialized shortly after SOPARE starts. And it's called when something gets recognized. As it's part of SOPARE each and every slowdown/hickup/wait-time pulls down the SOPARE main thread. And invoking an external thread is time consuming and can pile up and therefore should be handled by a separate thread or invoked via a queue or whatever you can imagine to decouple it.

Some interesting background information is served here: https://www.bishoph.org/sopare-architecture-and-plugins/

@AIWintermuteAI
Copy link
Author

It worked great with a simple example

def run(readable_results, data, rawbuf):
    if ('rapiro_activate'  in readable_results):
            command_line = 'echo \"#M0\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0'
            os.system(command_line)
    if ('rapiro_sleep'  in readable_results):
            command_line = 'echo \"#M1\" | sudo minicom -b 57600 -o -D /dev/ttyAMA0'
            os.system(command_line)

Then I moved the os.system to a separate function for convenience and added the environmental variable ISLISTENING. The code is in the first post.

I had a look at all sopare documentation before starting to work :)
Actually that article was the reason I wrote on_boot.py script.
default
It says here that plugin gets activated only when sound level is above threshold. Which is not suitable for me for two reasons:

  1. I need a script that is executed when SOPARE starts listening(meaning Raspberry Pi boot is finished and robot is ready to take commands)
  2. I cannot declare environmental variable in the plugin, since plugin gets called every time when sound is above threshold. I need that environmental variable declared once and then can be changed in the plugin code.
    Admittedly there are other ways to preserve a state, apart from environmental variable. For example writing data to a text file. Or adding that variable to bash shell. I'll see what I can come up with.

What I am trying to achieve is following:
The robot upon recognizing "Rapiro, activate!" will switch to a "listening state", in which it will listen for different commands(go forward, turn left etc). It will switch to sleep mode when "Rapiro, sleep!" is recognized.
Do you have any suggestions how to achieve that in a thread-safely manner?

@bishoph
Copy link
Owner

bishoph commented Nov 28, 2018

The plugin gets initialized and referenced when SOPARE starts once. On top of this the "run" function in the referenced plugin is called whenever there is a match.

Maybe you find this plugin example helpful:
https://github.com/bishoph/Misc/blob/master/robotic_arm_control.py

This means you can declare what you want once and check for matches/follow up stuff in the "run" function.

And I see that there is room for optimization and a more detailed explanation...thx for pointing out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants