module FANUC
module Ekg
# :stopdoc:
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
# :startdoc:
# Returns the version string for the library.
#
def self.version
@version ||= File.read(path('version.txt')).strip
end
# Returns the library path for the module. If any arguments are given,
# they will be joined to the end of the libray path using
# File.join.
#
def self.libpath( *args, &block )
rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
if block
begin
$LOAD_PATH.unshift LIBPATH
rv = block.call
ensure
$LOAD_PATH.shift
end
end
return rv
end
# Returns the lpath for the module. If any arguments are given,
# they will be joined to the end of the path using
# File.join.
#
def self.path( *args, &block )
rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
if block
begin
$LOAD_PATH.unshift PATH
rv = block.call
ensure
$LOAD_PATH.shift
end
end
return rv
end
# Utility method used to require all files ending in .rb that lie in the
# directory below this file that has the same name as the filename passed
# in. Optionally, a specific _directory_ name can be passed in such that
# the _filename_ does not have to be equivalent to the directory.
#
def self.require_all_libs_relative_to( fname, dir = nil )
dir ||= ::File.basename(fname, '.*')
search_me = ::File.expand_path(
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
Dir.glob(search_me).sort.each {|rb| require rb}
end
# what parser should we use
if RUBY_VERSION.to_f >= 1.9
require 'csv'
PARSER = CSV
else
require 'faster_csv'
PARSER = FasterCSV
end
class Bin
attr_accessor :collision_counts
def initialize
@collision_counts = []
end
def total
@collision_counts.inject {|sum,x| sum+x}
end
def [](id)
@collision_counts[id-1]
end
end
class Alarm
attr_reader :occured_at, :error_text, :safety_io, :velocity, :torque, :angle, :disturbance_torque
def initialize(options={})
@occured_at = options["DateTime"]
@error_text = options["ErrorText"]
@safety_io = options["Safety I/O"]
@velocity = {
:j1 => options["Vel J1[%]"],
:j2 => options["Vel J2[%]"],
:j3 => options["Vel J3[%]"],
:j4 => options["Vel J4[%]"],
:j5 => options["Vel J5[%]"]
}
@torque = {
:j1 => options["Torq J1[%]"],
:j2 => options["Torq J2[%]"],
:j3 => options["Torq J3[%]"],
:j4 => options["Torq J4[%]"],
:j5 => options["Torq J5[%]"]
}
@angle = {
:j1 => options["Angle J1[rad]"],
:j2 => options["Angle J2[rad]"],
:j3 => options["Angle J3[rad]"],
:j4 => options["Angle J4[rad]"],
:j5 => options["Angle J5[rad]"],
}
@disturbance_torque = {
:j1 => options["DistTorq J1[%]"],
:j2 => options["DistTorq J2[%]"],
:j3 => options["DistTorq J3[%]"],
:j4 => options["DistTorq J4[%]"],
:j5 => options["DistTorq J5[%]"]
}
end
end
class EkgData
attr_accessor :bins, :alarms
def initialize
@bins = {
:zero => Bin.new,
:v1t1 => Bin.new,
:v2t1 => Bin.new,
:v1t2 => Bin.new,
:v2t2 => Bin.new
}
@alarms = {
:recent => [],
:worst => []
}
end
def axis(id)
@sum = 0
@bins.each do |key,bin|
@sum += bin[id]
end
# should i remove bin 0?
@sum
end
end
class << self
def open(file_path)
File.open(file_path)
end
def split(file)
@output = {}
@str = ""
file.each do |line|
next if line == "Severity\n"
next if line == "Group,Bin0,BinV1T1,BinV2T1,BinV1T2,BinV2T2\n"
next if line == "MRA_Num,DateTime,ErrorText,Safety I/O,Vel J1[%],Vel J2[%],Vel J3[%],Vel J4[%],Vel J5[%],Vel J6[%],Vel J7[%],Vel J8[%],Torq J1[%],Torq J2[%],Torq J3[%],Torq J4[%],Torq J5[%],Torq J6[%],Torq J7[%],Torq J8[%],Angle J1[rad],Angle J2[rad],Angle J3[rad],Angle J4[rad],Angle J5[rad],Angle J6[rad],Angle J7[rad],Angle J8[rad],DistTorq J1[%],DistTorq J2[%],DistTorq J3[%],DistTorq J4[%],DistTorq J5[%],DistTorq J6[%],DistTorq J7[%],DistTorq J8[%]\n"
next if line == "Num,DateTime,ErrorText,Safety I/O,Vel J1[%],Vel J2[%],Vel J3[%],Vel J4[%],Vel J5[%],Vel J6[%],Vel J7[%],Vel J8[%],Torq J1[%],Torq J2[%],Torq J3[%],Torq J4[%],Torq J5[%],Torq J6[%],Torq J7[%],Torq J8[%],Angle J1[rad],Angle J2[rad],Angle J3[rad],Angle J4[rad],Angle J5[rad],Angle J6[rad],Angle J7[rad],Angle J8[rad],DistTorq J1[%],DistTorq J2[%],DistTorq J3[%],DistTorq J4[%],DistTorq J5[%],DistTorq J6[%],DistTorq J7[%],DistTorq J8[%]\n"
if line == "Most Recent Alarms(MRA) for Group 1\n"
@output[:bins] = @str
@str = ""
next
end
if line == "Worst Disturbance Alarms for Group 1\n"
@output[:recent] = @str
@str = ""
next
end
@str += line
end
@output[:worst] = @str
return @output
end
def parse(file_path)
@ekg_data = FANUC::Ekg::EkgData.new
f = open(file_path)
output = split(f) # split the output into 3 usable CSV sections
# parse bins
PARSER.parse(output[:bins],:headers=>"Group,Bin0,BinV1T1,BinV2T1,BinV1T2,BinV2T2") do |line|
@ekg_data.bins[:zero].collision_counts << line['Bin0'].to_i
@ekg_data.bins[:v1t1].collision_counts << line['BinV1T1'].to_i
@ekg_data.bins[:v2t1].collision_counts << line['BinV2T1'].to_i
@ekg_data.bins[:v1t2].collision_counts << line['BinV1T2'].to_i
@ekg_data.bins[:v2t2].collision_counts << line['BinV2T2'].to_i
end
# parse recent alarms
PARSER.parse(output[:recent],:headers => "MRA_Num,DateTime,ErrorText,Safety I/O,Vel J1[%],Vel J2[%],Vel J3[%],Vel J4[%],Vel J5[%],Vel J6[%],Vel J7[%],Vel J8[%],Torq J1[%],Torq J2[%],Torq J3[%],Torq J4[%],Torq J5[%],Torq J6[%],Torq J7[%],Torq J8[%],Angle J1[rad],Angle J2[rad],Angle J3[rad],Angle J4[rad],Angle J5[rad],Angle J6[rad],Angle J7[rad],Angle J8[rad],DistTorq J1[%],DistTorq J2[%],DistTorq J3[%],DistTorq J4[%],DistTorq J5[%],DistTorq J6[%],DistTorq J7[%],DistTorq J8[%]") do |line|
@ekg_data.alarms[:recent] << Ekg::Alarm.new(line.to_hash)
end
# parse worst disturbances
PARSER.parse(output[:worst],:headers=>"Num,DateTime,ErrorText,Safety I/O,Vel J1[%],Vel J2[%],Vel J3[%],Vel J4[%],Vel J5[%],Vel J6[%],Vel J7[%],Vel J8[%],Torq J1[%],Torq J2[%],Torq J3[%],Torq J4[%],Torq J5[%],Torq J6[%],Torq J7[%],Torq J8[%],Angle J1[rad],Angle J2[rad],Angle J3[rad],Angle J4[rad],Angle J5[rad],Angle J6[rad],Angle J7[rad],Angle J8[rad],DistTorq J1[%],DistTorq J2[%],DistTorq J3[%],DistTorq J4[%],DistTorq J5[%],DistTorq J6[%],DistTorq J7[%],DistTorq J8[%]") do |line|
@ekg_data.alarms[:worst] << Ekg::Alarm.new(line.to_hash)
end
@ekg_data
end
end
end # module Ekg
end # module FANUC
FANUC::Ekg.require_all_libs_relative_to(__FILE__)