uint8 humidity # percent
float32 pressure # kph
uint16 co
+float32 dew_point # degree celsius
bool ventilate
--- /dev/null
+#!/usr/bin/ruby
+
+require 'gst'
+require 'pry'
+require 'logger'
+require 'ros'
+require 'std_msgs/String'
+
+class Speak
+ def initialize(node)
+ @logger = Logger.new(STDOUT)
+ @publisher = node.advertise('asr_result', Std_msgs::String)
+ @pipeline = Gst.parse_launch('alsasrc device="plughw:1,0" ! audio/x-raw,format=S16LE,channels=1,rate=16000 ! cutter leaky=true name=cutter'\
+ ' ! tee name=jsgf ! queue leaky=downstream ! valve name=valve_jsgf drop=true ! pocketsphinx name=asr_jsgf ! fakesink async=false jsgf.'\
+ ' ! pocketsphinx name=asr_kws ! fakesink async=false'\
+ )
+ # Ignore everything below the configured volume
+ cutter = @pipeline.get_by_name('cutter')
+ cutter.set_property('threshold-dB', -20)
+ cutter.set_property('pre-length', 100000000) # pocketsphinx needs about 0.1s before start
+ cutter.set_property('run-length', 1300000000)
+
+ asr_jsgf = @pipeline.get_by_name('asr_jsgf')
+ asr_jsgf.set_property('hmm', 'pocketsphinx/adapt/cmusphinx-en-us-5.2')
+ asr_jsgf.set_property('mllr', 'pocketsphinx/adapt/mllr_matrix')
+ asr_jsgf.set_property('jsgf', 'data/robot.jsgf')
+
+ asr_kws = @pipeline.get_by_name('asr_kws')
+ asr_kws.set_property('hmm', 'pocketsphinx/adapt/cmusphinx-en-us-5.2')
+ asr_kws.set_property('mllr', 'pocketsphinx/adapt/mllr_matrix')
+ asr_kws.set_property('kws', 'data/keywords.kws')
+
+ bus = @pipeline.bus()
+ bus.add_watch do |bus, message|
+ case message.type
+ when Gst::MessageType::EOS
+ loop.quit
+ when Gst::MessageType::ERROR
+ p message.parse_error
+ binding.pry # open console
+ loop.quit
+ when Gst::MessageType::ELEMENT
+ if message.src.name == "asr_kws"
+ if message.structure.get_value(:final).value
+ keyword_detect(message.structure.get_value(:hypothesis).value, message.structure.get_value(:confidence).value)
+ end
+ elsif message.src.name == "asr_jsgf"
+ if message.structure.get_value(:final).value
+ final_result(message.structure.get_value(:hypothesis).value, message.structure.get_value(:confidence).value)
+ end
+ elsif message.src.name == "cutter"
+ if message.structure.get_value(:above).value
+ @logger.debug "Start recording.."
+ else
+ @logger.debug "Stop recording"
+ end
+ end
+ end
+ true
+ end
+
+ @pipeline.play
+ end
+
+ # Enables/Disables the jsgf pipeline branch
+ def enable_jsgf(bEnable)
+ valve = @pipeline.get_by_name('valve_jsgf')
+ valve.set_property("drop", !bEnable)
+ end
+
+ # Result of jsgf pipeline branch
+ def final_result(hyp, confidence)
+ @logger.info "final: " + hyp + " " + confidence.to_s
+ 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, confidence)
+ @logger.debug "Got keyword: " + hyp
+ enable_jsgf(true)
+ end
+
+ def stop
+ @pipeline.stop
+ end
+end
+
+if __FILE__ == $0
+ node = ROS::Node.new('asr_pocketsphinx')
+ app = Speak.new(node)
+ loop = GLib::MainLoop.new(nil, false)
+ begin
+ Thread.new {
+ loop.run
+ }
+ node.spin
+ rescue Interrupt
+ ensure
+ app.stop
+ node.shutdown
+ loop.quit
+ end
+end
--- /dev/null
+#!/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
+++ /dev/null
-#!/usr/bin/ruby
-
-require 'gst'
-require 'pry'
-require 'logger'
-require 'ros'
-require 'std_msgs/String'
-
-class Speak
- def initialize(node)
- @logger = Logger.new(STDOUT)
- @publisher = node.advertise('asr_result', Std_msgs::String)
- @pipeline = Gst.parse_launch('alsasrc device="plughw:1,0" ! audio/x-raw,format=S16LE,channels=1,rate=16000 ! cutter leaky=true name=cutter'\
- ' ! tee name=jsgf ! queue leaky=downstream ! valve name=valve_jsgf drop=true ! pocketsphinx name=asr_jsgf ! fakesink async=false jsgf.'\
- ' ! pocketsphinx name=asr_kws ! fakesink async=false'\
- )
- # Ignore everything below the configured volume
- cutter = @pipeline.get_by_name('cutter')
- cutter.set_property('threshold-dB', -20)
- cutter.set_property('pre-length', 100000000) # pocketsphinx needs about 0.1s before start
- cutter.set_property('run-length', 1300000000)
-
- asr_jsgf = @pipeline.get_by_name('asr_jsgf')
- asr_jsgf.set_property('hmm', 'pocketsphinx/adapt/cmusphinx-en-us-5.2')
- asr_jsgf.set_property('mllr', 'pocketsphinx/adapt/mllr_matrix')
- asr_jsgf.set_property('jsgf', 'data/robot.jsgf')
-
- asr_kws = @pipeline.get_by_name('asr_kws')
- asr_kws.set_property('hmm', 'pocketsphinx/adapt/cmusphinx-en-us-5.2')
- asr_kws.set_property('mllr', 'pocketsphinx/adapt/mllr_matrix')
- asr_kws.set_property('kws', 'data/keywords.kws')
-
- bus = @pipeline.bus()
- bus.add_watch do |bus, message|
- case message.type
- when Gst::MessageType::EOS
- loop.quit
- when Gst::MessageType::ERROR
- p message.parse_error
- binding.pry # open console
- loop.quit
- when Gst::MessageType::ELEMENT
- if message.src.name == "asr_kws"
- if message.structure.get_value(:final).value
- keyword_detect(message.structure.get_value(:hypothesis).value, message.structure.get_value(:confidence).value)
- end
- elsif message.src.name == "asr_jsgf"
- if message.structure.get_value(:final).value
- final_result(message.structure.get_value(:hypothesis).value, message.structure.get_value(:confidence).value)
- end
- elsif message.src.name == "cutter"
- if message.structure.get_value(:above).value
- @logger.debug "Start recording.."
- else
- @logger.debug "Stop recording"
- end
- end
- end
- true
- end
-
- @pipeline.play
- end
-
- # Enables/Disables the jsgf pipeline branch
- def enable_jsgf(bEnable)
- valve = @pipeline.get_by_name('valve_jsgf')
- valve.set_property("drop", !bEnable)
- end
-
- # Result of jsgf pipeline branch
- def final_result(hyp, confidence)
- @logger.info "final: " + hyp + " " + confidence.to_s
- 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, confidence)
- @logger.debug "Got keyword: " + hyp
- enable_jsgf(true)
- end
-
- def stop
- @pipeline.stop
- end
-end
-
-if __FILE__ == $0
- node = ROS::Node.new('pocketsphinx')
- app = Speak.new(node)
- loop = GLib::MainLoop.new(nil, false)
- begin
- Thread.new {
- loop.run
- }
- node.spin
- rescue Interrupt
- ensure
- app.stop
- node.shutdown
- loop.quit
- end
-end
# Board warming offset
TEMP_ERROR = -3.0 # -5 # degree celsius
PRESSURE_ERROR = -2.5
+A_dew_point = 17.271
+B_dew_point = 237.7
"""
LDR:
msg.pressure = pressure
msg.co = co
msg.ventilate = True if ventilate > 1.10 else False
+ tmp = ((A_dew_point * temp) / (B_dew_point + temp)) + log(humidity/100.0)
+ msg.dew_point = (B_dew_point * tmp) / (A_dew_point - tmp)
self.pub.publish(msg)