class Nmea::Gps

Constants

SENTENCE_NAMES
TALKER_ID

Attributes

callbacks[RW]
gps_serial_port[RW]
initial_sentence[RW]
track_thread[RW]
update_hz[RW]

Public Class Methods

new(serial_port, hz: 1) click to toggle source
# File lib/nmea_gps/gps.rb, line 9
def initialize(serial_port, hz: 1)
  self.callbacks        = {}
  self.gps_serial_port  = serial_port
  self.update_hz        = 1.second.to_f / (hz.to_i.zero? ? 1 : hz.to_i)
end

Public Instance Methods

stop!() click to toggle source
# File lib/nmea_gps/gps.rb, line 36
def stop!
  return unless self.track_thread.respond_to? :kill
  
  self.track_thread.kill 
  self.track_thread = nil
end
track!() click to toggle source
# File lib/nmea_gps/gps.rb, line 25
def track!
  return if self.track_thread

  self.track_thread = Thread.new do 
    loop do 
      callback!
      frequency
    end
  end
end

Private Instance Methods

callback!() click to toggle source
# File lib/nmea_gps/gps.rb, line 85
def callback!
  sentences_in_a_cycle.each do |sentence, raw_sentence_lines_in_array|
    begin
      target_class = "Nmea::Gps::#{sentence.to_s.camelcase}".constantize

      object = if sentence == :gsv
              raw_sentence_lines_in_array.sort.collect do |raw_sentence|
                target_class.new raw_sentence
              end
            else
              target_class.new(raw_sentence_lines_in_array.first)
            end

      self.callbacks[sentence].call object         if self.callbacks[sentence]
      self.callbacks[:all].call [sentence, object] if self.callbacks[:all]
    rescue => ex
      self.callbacks[:error].call ex if self.callbacks[:error]
    end
  end

rescue => ex
  self.callbacks[:error].call ex if self.callbacks[:error]
end
ensure_sentence() { |*buffer| ... } click to toggle source
# File lib/nmea_gps/gps.rb, line 68
def ensure_sentence
  yield *@buffer if @buffer

  raw_sentence_line = self.gps_serial_port.gets("\r\n").strip
  return unless match = raw_sentence_line.match(sentence_name_reg)
  
  sentence = match[1].downcase.to_sym
  if sentence == self.initial_sentence
    @buffer = [sentence, raw_sentence_line]
    throw :done_one_cycle 
  end

  yield sentence, raw_sentence_line

  self.initial_sentence ||= sentence unless sentence == :gsv 
end
frequency() click to toggle source
# File lib/nmea_gps/gps.rb, line 48
def frequency
  sleep self.update_hz
end
sentence_name_reg() click to toggle source
# File lib/nmea_gps/gps.rb, line 64
def sentence_name_reg
  @sentence_name_reg ||= /\A\$#{TALKER_ID}([#{SENTENCE_NAMES.join.chars.uniq.sort.join.upcase}]{3})/
end
sentences_in_a_cycle() click to toggle source
# File lib/nmea_gps/gps.rb, line 52
def sentences_in_a_cycle
  Hash.new{|hash, key| hash[key] = [] }.tap do |set|
    catch(:done_one_cycle) do
      loop do 
        ensure_sentence do |sentence, raw_sentence_line|
          set[sentence] << raw_sentence_line
        end
      end
    end
  end
end