X-Git-Url: https://defiant.homedns.org/gitweb/?p=ros_wild_thumper.git;a=blobdiff_plain;f=scripts%2Fasr_vosk.rb;fp=scripts%2Fasr_vosk.rb;h=bc7394937c57342208c3e7237089cbf5bbea0092;hp=0000000000000000000000000000000000000000;hb=00c6403ee3673ae0b1e4b064f65c56f6ce5bc33a;hpb=b0346ccd1f5566f3134ed47fd28f8330d7d2d76b diff --git a/scripts/asr_vosk.rb b/scripts/asr_vosk.rb new file mode 100755 index 0000000..bc73949 --- /dev/null +++ b/scripts/asr_vosk.rb @@ -0,0 +1,115 @@ +#!/usr/bin/ruby +# export AUDIODEV=plughw:CARD=ArrayUAC10,0 +# rec -q -t alsa -c 1 -b 16 -r 16000 -t wav - silence -l 1 0.1 0.3% -1 2.0 0.3% | ./asr_vosk.rb - + +require 'logger' +require 'websocket-eventmachine-client' +require 'json' +require 'ros' +require 'std_msgs/String' + +KEYWORDS = ["wild thumper"] +CONFIG = { + "config": { + "phrase_list": ["angle", "backward", "by", "centimeter", "compass", "current", "decrease", "default", "degree", "down", "eight", "eighteen", "eighty", "eleven", "fifteen", "fifty", "five", "forty", "forward", "four", "fourteen", "get", "go", "hundred", "increase", "left", "light", "lights", "meter", "mic", "minus", "motion", "mute", "nine", "nineteen", "ninety", "off", "on", "one", "position", "pressure", "right", "secure", "set", "seven", "seventeen", "seventy", "silence", "six", "sixteen", "sixty", "speed", "stop", "temp", "temperature", "ten", "thirteen", "thirty", "three", "to", "turn", "twelve", "twenty", "two", "up", "velocity", "voltage", "volume", "wild thumper", "zero"], + "sample_rate": 16000.0 + } +} + +class Speak + def initialize(node) + @logger = Logger.new(STDOUT) + @jsgf_enabled = false + @publisher = node.advertise('asr_result', Std_msgs::String) + + EM.run do + Signal.trap("INT") { send_eof } + @ws = WebSocket::EventMachine::Client.connect(:uri => 'ws://192.168.36.4:2700') + + def send_eof + @ws.send '{"eof" : 1}' + end + + def run + while true do + data = ARGF.read(16000) + if data + @ws.send data, :type => :binary + else + send_eof + break + end + end + end + + @ws.onopen do + @logger.info "Running.." + @ws.send CONFIG.to_json + + Thread.new { + run + } + end + + @ws.onmessage do |msg, type| + d = JSON.parse(msg) + handle_result(d) + end + + @ws.onclose do |code, reason| + puts "Disconnected with status code: #{code}" + exit + end + end + end + + def handle_result(msg) + if msg.has_key? "result" + msg["result"].each do |result| + @logger.debug "word=" + result["word"] + end + + text = msg["text"] + @logger.debug "text=" + msg["text"] + if KEYWORDS.include? text + keyword_detect(text) + return + end + if @jsgf_enabled + final_result(msg["text"]) + end + end + end + + # Enables/Disables the jsgf pipeline branch + def enable_jsgf(bEnable) + @jsgf_enabled = bEnable + end + + # Result of jsgf pipeline branch + def final_result(hyp) + @logger.info "final: " + hyp + enable_jsgf(false) + + # Publish pocketsphinx result as ros message + msg = Std_msgs::String.new + msg.data = hyp + @publisher.publish(msg) + end + + def keyword_detect(hyp) + @logger.debug "Got keyword: " + hyp + enable_jsgf(true) + end +end + +if __FILE__ == $0 + node = ROS::Node.new('asr_vosk') + app = Speak.new(node) + begin + node.spin + rescue Interrupt + ensure + node.shutdown + end +end