From 382a533e9d3a03eed40f653516b62590396e2388 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sat, 13 Dec 2014 12:59:41 -0500 Subject: [PATCH 01/13] add pry to project --- multilateration.gemspec | 1 + spec/spec_helper.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/multilateration.gemspec b/multilateration.gemspec index 45d6c2d..a579df2 100644 --- a/multilateration.gemspec +++ b/multilateration.gemspec @@ -20,5 +20,6 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "rake" + spec.add_development_dependency "pry" spec.add_development_dependency "rspec", "~> 3.0" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2752f9f..2f32440 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,4 @@ +require 'pry' require 'multilateration' # This file was generated by the `rspec --init` command. Conventionally, all From a85676229079d7a9c02962af51bbc4aed43177f7 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sat, 13 Dec 2014 17:56:54 -0500 Subject: [PATCH 02/13] remove ---require spec_helper as it breaks rspec --seed in rspec 3.1 --- .rspec | 1 - 1 file changed, 1 deletion(-) diff --git a/.rspec b/.rspec index 83e16f8..4e1e0d2 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1 @@ --color ---require spec_helper From 57b63317b93c96c04e8195d045831c0e37c10819 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sat, 13 Dec 2014 18:43:55 -0500 Subject: [PATCH 03/13] Add rantly to the project --- lib/multilateration.rb | 2 ++ multilateration.gemspec | 3 +++ 2 files changed, 5 insertions(+) diff --git a/lib/multilateration.rb b/lib/multilateration.rb index e7650a9..0e21668 100644 --- a/lib/multilateration.rb +++ b/lib/multilateration.rb @@ -1,3 +1,5 @@ +require "rantly" + require "matrix" require "multilateration/version" diff --git a/multilateration.gemspec b/multilateration.gemspec index a579df2..465d11b 100644 --- a/multilateration.gemspec +++ b/multilateration.gemspec @@ -22,4 +22,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rake" spec.add_development_dependency "pry" spec.add_development_dependency "rspec", "~> 3.0" + + spec.add_dependency "rantly", "~> 0.3" + end From eb50da8570d294f3f2b6a507aa4f7d1303748acb Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sat, 13 Dec 2014 18:46:48 -0500 Subject: [PATCH 04/13] add Multilateration::SignalEventsGenerator class --- lib/multilateration.rb | 1 + .../signal_events_generator.rb | 89 +++++++++++++++++++ .../signal_events_generator_spec.rb | 26 ++++++ 3 files changed, 116 insertions(+) create mode 100644 lib/multilateration/signal_events_generator.rb create mode 100644 spec/multilateration/signal_events_generator_spec.rb diff --git a/lib/multilateration.rb b/lib/multilateration.rb index 0e21668..23a6e9b 100644 --- a/lib/multilateration.rb +++ b/lib/multilateration.rb @@ -3,6 +3,7 @@ require "matrix" require "multilateration/version" +require "multilateration/signal_events_generator" require "multilateration/solver" require "multilateration/time_of_arrival_strategies/source_vector_distance" diff --git a/lib/multilateration/signal_events_generator.rb b/lib/multilateration/signal_events_generator.rb new file mode 100644 index 0000000..0a3f1fd --- /dev/null +++ b/lib/multilateration/signal_events_generator.rb @@ -0,0 +1,89 @@ +module Multilateration + class SignalEventsGenerator + + TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S.%N%z" + + def self.generate + begin + new( + receiver_count: 5, + coordinate_num_dimensions: 3, + coordinate_max_area: 1000, + coordinate_max_precision: 4, + signal_propagation_max_speed: 500, + signal_propagation_max_precision: 4, + ).generate + end + end + + attr_reader :receiver_count, :coordinate_num_dimensions, :coordinate_max_area, :coordinate_max_precision, :signal_propagation_max_speed, :signal_propagation_max_precision + private :receiver_count, :coordinate_num_dimensions, :coordinate_max_area, :coordinate_max_precision, :signal_propagation_max_speed, :signal_propagation_max_precision + + def initialize(receiver_count:, coordinate_num_dimensions:, coordinate_max_area:, coordinate_max_precision:, signal_propagation_max_speed:, signal_propagation_max_precision:) + @receiver_count = receiver_count + @coordinate_num_dimensions = coordinate_num_dimensions + @coordinate_max_area = coordinate_max_area + @coordinate_max_precision = coordinate_max_precision + @signal_propagation_max_speed = signal_propagation_max_speed + @signal_propagation_max_precision = signal_propagation_max_precision + end + + def generate(rc: receiver_count) + signal_events = [] + + emission_timestamp = random_high_resolution_timestamp + emitter_coordinate = random_coordinate + receiver_coordinates = rc.times.map { random_coordinate } + + signal_events << signal_event_for(:emitter, emitter_coordinate, emission_timestamp) + + receiver_coordinates.each do |coordinate| + signal_events << signal_event_for(:receiver, coordinate, propagation_timestamp(emission_timestamp, emitter_coordinate, coordinate)) + end + + signal_events + end + + private + + def signal_event_for(type, coordinate, time) + {type: type, coordinate: coordinate, time: time} + end + + def propagation_timestamp(emission_timestamp, emitter_coordinate, coordinate) + propagation_duration = distance_between_coordinates(emitter_coordinate, coordinate) / random_signal_propagation_speed + propagation_time = timestamp_to_time(emission_timestamp) - propagation_duration + time_to_timestamp(propagation_time) + end + + def distance_between_coordinates(coordinate1, coordinate2) + vector1 = coordinate_to_vector(coordinate1) + vector2 = coordinate_to_vector(coordinate2) + Math.sqrt((vector1 - vector2).map { |component| component.abs**2 }.reduce(&:+)) + end + + def random_signal_propagation_speed(spms: signal_propagation_max_speed, spmp: signal_propagation_max_precision) + Rantly { range(1, spms) + float.round(range(0, spmp)) } + end + + def random_high_resolution_timestamp + time_to_timestamp Time.at(Rantly { integer(1_000_000_000) + float }) + end + + def random_coordinate(cnd: coordinate_num_dimensions, cma: coordinate_max_area, cmp: coordinate_max_precision) + Rantly(cnd) { range(-cma, cma) + float.round(range(0, cmp)) } + end + + def coordinate_to_vector(coordinate) + Vector.elements(coordinate) + end + + def time_to_timestamp(time) + time.utc.strftime(TIMESTAMP_FORMAT) + end + + def timestamp_to_time(timestamp) + Time.parse(timestamp).utc + end + end +end diff --git a/spec/multilateration/signal_events_generator_spec.rb b/spec/multilateration/signal_events_generator_spec.rb new file mode 100644 index 0000000..a543a36 --- /dev/null +++ b/spec/multilateration/signal_events_generator_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe Multilateration::SignalEventsGenerator do + describe '.generate' do + subject(:generate) { described_class.generate } + + let(:signal_event_matcher) do + { + coordinate: [be_a(Numeric), be_a(Numeric), be_a(Numeric)], # [368, -454, 978.9] + time: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}\+0{4}$/) # "1945-12-22T18:13:16.144102423+0000" + } + end + + let(:signal_event_emitter_matcher) { signal_event_matcher.merge(type: :emitter) } + let(:signal_event_receiver_matcher) { signal_event_matcher.merge(type: :receiver) } + + specify { expect(generate).to match [ + signal_event_emitter_matcher, + signal_event_receiver_matcher, + signal_event_receiver_matcher, + signal_event_receiver_matcher, + signal_event_receiver_matcher, + signal_event_receiver_matcher, + ] } + end +end From 45c3001b6043c4ac88abe075005442cf03725736 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sat, 13 Dec 2014 18:49:54 -0500 Subject: [PATCH 05/13] remove unused begin statment --- lib/multilateration/signal_events_generator.rb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/multilateration/signal_events_generator.rb b/lib/multilateration/signal_events_generator.rb index 0a3f1fd..cb92151 100644 --- a/lib/multilateration/signal_events_generator.rb +++ b/lib/multilateration/signal_events_generator.rb @@ -4,16 +4,14 @@ class SignalEventsGenerator TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S.%N%z" def self.generate - begin - new( - receiver_count: 5, - coordinate_num_dimensions: 3, - coordinate_max_area: 1000, - coordinate_max_precision: 4, - signal_propagation_max_speed: 500, - signal_propagation_max_precision: 4, - ).generate - end + new( + receiver_count: 5, + coordinate_num_dimensions: 3, + coordinate_max_area: 1000, + coordinate_max_precision: 4, + signal_propagation_max_speed: 500, + signal_propagation_max_precision: 4, + ).generate end attr_reader :receiver_count, :coordinate_num_dimensions, :coordinate_max_area, :coordinate_max_precision, :signal_propagation_max_speed, :signal_propagation_max_precision From 0a8b2de33e9e35aa4b0fe093de74399bf809dfe6 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 20:00:19 -0500 Subject: [PATCH 06/13] remove the explicit conversion to utc --- lib/multilateration/signal_events_generator.rb | 4 ++-- spec/multilateration/signal_events_generator_spec.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/multilateration/signal_events_generator.rb b/lib/multilateration/signal_events_generator.rb index cb92151..2577471 100644 --- a/lib/multilateration/signal_events_generator.rb +++ b/lib/multilateration/signal_events_generator.rb @@ -77,11 +77,11 @@ def coordinate_to_vector(coordinate) end def time_to_timestamp(time) - time.utc.strftime(TIMESTAMP_FORMAT) + time.strftime(TIMESTAMP_FORMAT) end def timestamp_to_time(timestamp) - Time.parse(timestamp).utc + Time.parse(timestamp) end end end diff --git a/spec/multilateration/signal_events_generator_spec.rb b/spec/multilateration/signal_events_generator_spec.rb index a543a36..985e8bf 100644 --- a/spec/multilateration/signal_events_generator_spec.rb +++ b/spec/multilateration/signal_events_generator_spec.rb @@ -7,7 +7,7 @@ let(:signal_event_matcher) do { coordinate: [be_a(Numeric), be_a(Numeric), be_a(Numeric)], # [368, -454, 978.9] - time: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}\+0{4}$/) # "1945-12-22T18:13:16.144102423+0000" + time: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}(\+|\-)\d{4}$/) # "1945-12-22T18:13:16.144102423+0000" } end From b50724c5007a655020edf15bfa02b13404d95d1d Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 20:02:06 -0500 Subject: [PATCH 07/13] update the data structure that #generate outputs --- .../signal_events_generator.rb | 33 +++++++++---------- .../signal_events_generator_spec.rb | 18 ++++------ 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/lib/multilateration/signal_events_generator.rb b/lib/multilateration/signal_events_generator.rb index 2577471..8a08820 100644 --- a/lib/multilateration/signal_events_generator.rb +++ b/lib/multilateration/signal_events_generator.rb @@ -27,29 +27,28 @@ def initialize(receiver_count:, coordinate_num_dimensions:, coordinate_max_area: end def generate(rc: receiver_count) - signal_events = [] - - emission_timestamp = random_high_resolution_timestamp - emitter_coordinate = random_coordinate - receiver_coordinates = rc.times.map { random_coordinate } - - signal_events << signal_event_for(:emitter, emitter_coordinate, emission_timestamp) - - receiver_coordinates.each do |coordinate| - signal_events << signal_event_for(:receiver, coordinate, propagation_timestamp(emission_timestamp, emitter_coordinate, coordinate)) - end - - signal_events + signal_propagation_speed = random_signal_propagation_speed + emission_timestamp = random_high_resolution_timestamp + emitter_coordinate = random_coordinate + receiver_coordinates = rc.times.map { random_coordinate } + + { + signal_propagation_speed: signal_propagation_speed, + emitter_event: signal_event_for(emitter_coordinate, emission_timestamp), + receiver_events: receiver_coordinates.map { |coordinate| + signal_event_for(coordinate, propagation_timestamp(signal_propagation_speed, emission_timestamp, emitter_coordinate, coordinate)) + }, + } end private - def signal_event_for(type, coordinate, time) - {type: type, coordinate: coordinate, time: time} + def signal_event_for(coordinate, timestamp) + {coordinate: coordinate, timestamp: timestamp} end - def propagation_timestamp(emission_timestamp, emitter_coordinate, coordinate) - propagation_duration = distance_between_coordinates(emitter_coordinate, coordinate) / random_signal_propagation_speed + def propagation_timestamp(signal_propagation_speed, emission_timestamp, emitter_coordinate, coordinate) + propagation_duration = distance_between_coordinates(emitter_coordinate, coordinate) / signal_propagation_speed propagation_time = timestamp_to_time(emission_timestamp) - propagation_duration time_to_timestamp(propagation_time) end diff --git a/spec/multilateration/signal_events_generator_spec.rb b/spec/multilateration/signal_events_generator_spec.rb index 985e8bf..7e4b4de 100644 --- a/spec/multilateration/signal_events_generator_spec.rb +++ b/spec/multilateration/signal_events_generator_spec.rb @@ -7,20 +7,14 @@ let(:signal_event_matcher) do { coordinate: [be_a(Numeric), be_a(Numeric), be_a(Numeric)], # [368, -454, 978.9] - time: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}(\+|\-)\d{4}$/) # "1945-12-22T18:13:16.144102423+0000" + timestamp: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}(\+|\-)\d{4}$/) # "1945-12-22T18:13:16.144102423+0000" } end - let(:signal_event_emitter_matcher) { signal_event_matcher.merge(type: :emitter) } - let(:signal_event_receiver_matcher) { signal_event_matcher.merge(type: :receiver) } - - specify { expect(generate).to match [ - signal_event_emitter_matcher, - signal_event_receiver_matcher, - signal_event_receiver_matcher, - signal_event_receiver_matcher, - signal_event_receiver_matcher, - signal_event_receiver_matcher, - ] } + specify { expect(generate).to match( + signal_propagation_speed: be_a(Numeric), + emitter_event: signal_event_matcher, + receiver_events: [signal_event_matcher,signal_event_matcher,signal_event_matcher,signal_event_matcher,signal_event_matcher], + )} end end From 3ea13834d88c0bc3f9513a2fc7af2d3449d13103 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 21:12:56 -0500 Subject: [PATCH 08/13] rename signal_events_generator to signal_event_data_generator --- lib/multilateration.rb | 2 +- ...nerator.rb => signal_event_data_generator.rb} | 16 ++++------------ ...ec.rb => signal_event_data_generator_spec.rb} | 5 +++-- 3 files changed, 8 insertions(+), 15 deletions(-) rename lib/multilateration/{signal_events_generator.rb => signal_event_data_generator.rb} (87%) rename spec/multilateration/{signal_events_generator_spec.rb => signal_event_data_generator_spec.rb} (72%) diff --git a/lib/multilateration.rb b/lib/multilateration.rb index 23a6e9b..b90c088 100644 --- a/lib/multilateration.rb +++ b/lib/multilateration.rb @@ -3,7 +3,7 @@ require "matrix" require "multilateration/version" -require "multilateration/signal_events_generator" +require "multilateration/signal_event_data_generator" require "multilateration/solver" require "multilateration/time_of_arrival_strategies/source_vector_distance" diff --git a/lib/multilateration/signal_events_generator.rb b/lib/multilateration/signal_event_data_generator.rb similarity index 87% rename from lib/multilateration/signal_events_generator.rb rename to lib/multilateration/signal_event_data_generator.rb index 8a08820..b9de697 100644 --- a/lib/multilateration/signal_events_generator.rb +++ b/lib/multilateration/signal_event_data_generator.rb @@ -1,5 +1,5 @@ module Multilateration - class SignalEventsGenerator + class SignalEventDataGenerator TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S.%N%z" @@ -44,13 +44,12 @@ def generate(rc: receiver_count) private def signal_event_for(coordinate, timestamp) - {coordinate: coordinate, timestamp: timestamp} + {coordinate: coordinate, time: timestamp} end def propagation_timestamp(signal_propagation_speed, emission_timestamp, emitter_coordinate, coordinate) propagation_duration = distance_between_coordinates(emitter_coordinate, coordinate) / signal_propagation_speed - propagation_time = timestamp_to_time(emission_timestamp) - propagation_duration - time_to_timestamp(propagation_time) + propagation_time = emission_timestamp - propagation_duration end def distance_between_coordinates(coordinate1, coordinate2) @@ -64,7 +63,7 @@ def random_signal_propagation_speed(spms: signal_propagation_max_speed, spmp: si end def random_high_resolution_timestamp - time_to_timestamp Time.at(Rantly { integer(1_000_000_000) + float }) + Time.at(Rantly { integer(1_000_000_000) + float }) end def random_coordinate(cnd: coordinate_num_dimensions, cma: coordinate_max_area, cmp: coordinate_max_precision) @@ -75,12 +74,5 @@ def coordinate_to_vector(coordinate) Vector.elements(coordinate) end - def time_to_timestamp(time) - time.strftime(TIMESTAMP_FORMAT) - end - - def timestamp_to_time(timestamp) - Time.parse(timestamp) - end end end diff --git a/spec/multilateration/signal_events_generator_spec.rb b/spec/multilateration/signal_event_data_generator_spec.rb similarity index 72% rename from spec/multilateration/signal_events_generator_spec.rb rename to spec/multilateration/signal_event_data_generator_spec.rb index 7e4b4de..ff5f8cf 100644 --- a/spec/multilateration/signal_events_generator_spec.rb +++ b/spec/multilateration/signal_event_data_generator_spec.rb @@ -1,13 +1,14 @@ require 'spec_helper' -describe Multilateration::SignalEventsGenerator do +describe Multilateration::SignalEventDataGenerator do describe '.generate' do subject(:generate) { described_class.generate } let(:signal_event_matcher) do { coordinate: [be_a(Numeric), be_a(Numeric), be_a(Numeric)], # [368, -454, 978.9] - timestamp: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}(\+|\-)\d{4}$/) # "1945-12-22T18:13:16.144102423+0000" + # timestamp: match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}(\+|\-)\d{4}$/) # "1945-12-22T18:13:16.144102423+0000" + time: be_a(Time), } end From e3e64c81172d0be409d29892a010ebb5b99cb1c6 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 21:13:52 -0500 Subject: [PATCH 09/13] add SignalEvent class --- lib/multilateration.rb | 1 + lib/multilateration/signal_event.rb | 46 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 lib/multilateration/signal_event.rb diff --git a/lib/multilateration.rb b/lib/multilateration.rb index b90c088..9614ee8 100644 --- a/lib/multilateration.rb +++ b/lib/multilateration.rb @@ -4,6 +4,7 @@ require "multilateration/version" require "multilateration/signal_event_data_generator" +require "multilateration/signal_event" require "multilateration/solver" require "multilateration/time_of_arrival_strategies/source_vector_distance" diff --git a/lib/multilateration/signal_event.rb b/lib/multilateration/signal_event.rb new file mode 100644 index 0000000..7fa2c4a --- /dev/null +++ b/lib/multilateration/signal_event.rb @@ -0,0 +1,46 @@ +module Multilateration + class SignalEvent + include Comparable + + attr_reader :coordinate, :time + private :coordinate, :time + + def initialize(coordinate:, time:) + @coordinate = coordinate + @time = time + end + + def to_h + {coordinate: coordinate, time: time} + end + + def <=>(other) + time_of_arrival <=> other.time_of_arrival + end + + def -(other) + vector - other.vector + end + + def inner_product_sq + vector.inner_product(vector) + end + + def time_difference_of_arrival(other) + time_of_arrival - other.time_of_arrival + end + + def time_of_arrival + time + end + + def distance_between(coordinate) + Math.sqrt((vector - Vector.elements(coordinate)).map { |component| component.abs**2 }.reduce(&:+)) + end + + protected def vector + @vector ||= Vector.elements(coordinate) + end + + end +end From fa02842e7f875196954526122a0a8fd26a3e72c9 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 21:14:25 -0500 Subject: [PATCH 10/13] add generative gem to project --- multilateration.gemspec | 1 + spec/spec_helper.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/multilateration.gemspec b/multilateration.gemspec index 465d11b..a13b77e 100644 --- a/multilateration.gemspec +++ b/multilateration.gemspec @@ -22,6 +22,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rake" spec.add_development_dependency "pry" spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "generative", "~> 0.2" spec.add_dependency "rantly", "~> 0.3" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2f32440..4822d34 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,6 @@ require 'pry' +require 'generative' + require 'multilateration' # This file was generated by the `rspec --init` command. Conventionally, all From c3b621d17fa0686199167dc1cf6998c7f59701f8 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 21:16:05 -0500 Subject: [PATCH 11/13] update Solver class to accept data from SignalEventDataGenerator --- lib/multilateration/solver.rb | 35 +++++++++++++++-------------- spec/multilateration/solver_spec.rb | 31 ++++++++++++++++--------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/lib/multilateration/solver.rb b/lib/multilateration/solver.rb index 46f8dd3..0df835e 100644 --- a/lib/multilateration/solver.rb +++ b/lib/multilateration/solver.rb @@ -1,20 +1,25 @@ module Multilateration class Solver - attr_reader :receivers, :wave_speed, :time_of_arrival_strategy - private :receivers, :wave_speed, :time_of_arrival_strategy + attr_reader :receivers, :signal_propagation_speed + private :receivers, :signal_propagation_speed - def initialize(unsorted_receivers, time_of_arrival_strategy) - @receivers = unsorted_receivers.sort_by { |r| time_of_arrival_strategy.toa(r) } - @wave_speed = time_of_arrival_strategy.wave_speed - @time_of_arrival_strategy = time_of_arrival_strategy + def initialize(receiver_events:, signal_propagation_speed:) + @receivers = receiver_events.map {|e| SignalEvent.new(e) }.sort + @signal_propagation_speed = signal_propagation_speed end - def solved_vector - Vector.elements (ai_matrix * bi_matrix).flat_map.to_a + def solved_signal_event_emitter + time_between = first_receiver.distance_between(solved_coordinate) / signal_propagation_speed + solved_time = (first_receiver.time_of_arrival + time_between) + SignalEvent.new(coordinate: solved_coordinate, time: solved_time).to_h end private + def solved_coordinate + (ai_matrix * bi_matrix).flat_map.to_a + end + def ai_matrix Matrix.rows(middle_receivers.map { |i| ai(i) }).inverse end @@ -29,9 +34,9 @@ def ai(i) end def bi(i) - ( distance(tdoa_between_receivers_first_and(i)) * ( distance_sq(tdoa_between_receivers_first_and_last) - inner_product_sq(last_receiver) )) \ - + ( inner_product_sq(first_receiver) * ( distance(tdoa_between_receivers_first_and(i)) - distance(tdoa_between_receivers_first_and_last) )) \ - + ( distance(tdoa_between_receivers_first_and_last) * ( inner_product_sq(i) - distance_sq(tdoa_between_receivers_first_and(i)) )) + ( distance(tdoa_between_receivers_first_and(i)) * ( distance_sq(tdoa_between_receivers_first_and_last) - last_receiver.inner_product_sq )) \ + + ( first_receiver.inner_product_sq * ( distance(tdoa_between_receivers_first_and(i)) - distance(tdoa_between_receivers_first_and_last) )) \ + + ( distance(tdoa_between_receivers_first_and_last) * ( i.inner_product_sq - distance_sq(tdoa_between_receivers_first_and(i)) )) end def middle_receivers @@ -51,20 +56,16 @@ def tdoa_between_receivers_first_and_last end def tdoa_between_receivers_first_and(other_receiver) - time_of_arrival_strategy.tdoa(other_receiver, first_receiver) + first_receiver.time_difference_of_arrival(other_receiver) end def distance(time, exp=1) - (wave_speed**exp) * (time**exp) + (signal_propagation_speed**exp) * (time**exp) end def distance_sq(time) distance(time, 2) end - def inner_product_sq(vector) - vector.inner_product(vector) - end - end end diff --git a/spec/multilateration/solver_spec.rb b/spec/multilateration/solver_spec.rb index d16f933..56a5aba 100644 --- a/spec/multilateration/solver_spec.rb +++ b/spec/multilateration/solver_spec.rb @@ -1,18 +1,27 @@ require 'spec_helper' describe Multilateration::Solver do - describe "#solved_vector" do - let(:source_vector) { Vector[-20,5,120.2] } - let(:reciver_vector_0) { Vector[0,25,1] } - let(:reciver_vector_1) { Vector[50,20.34,2] } - let(:reciver_vector_2) { Vector[50,50,33] } - let(:reciver_vector_3) { Vector[23,75,4] } - let(:reciver_vector_4) { Vector[100,-100,-5.5] } - let(:time_of_arrival_strategy) { Multilateration::TimeOfArrivalStrategies::SourceVectorDistance.new(source_vector) } - let(:recivers) { [reciver_vector_0, reciver_vector_1, reciver_vector_2, reciver_vector_3, reciver_vector_4] } + describe "#solved_signal_event_emitter" do + generative do + let(:tolerance) { 0.0000001 } - subject(:solved_vector) { described_class.new(recivers, time_of_arrival_strategy).solved_vector } + let(:signal_event_data) { Multilateration::SignalEventDataGenerator.generate } + let(:signal_event_emiter) { signal_event_data.fetch(:emitter_event) } + let(:signal_event_emiter_time) { signal_event_emiter[:time] } + let(:signal_event_emiter_coordinate) { signal_event_emiter[:coordinate] } + let(:signal_event_data_without_emiter) { signal_event_data.reject { |k,v| v == signal_event_emiter } } - specify { expect( solved_vector.magnitude ).to be_within(0.0000000000001).of(source_vector.magnitude) } + subject(:solved_signal_event_emitter) { described_class.new(signal_event_data_without_emiter).solved_signal_event_emitter } + + specify { expect(solved_signal_event_emitter).to match({ + coordinate: [ + be_within(tolerance).of(signal_event_emiter_coordinate[0]), + be_within(tolerance).of(signal_event_emiter_coordinate[1]), + be_within(tolerance).of(signal_event_emiter_coordinate[2]), + ], + time: be_within(tolerance).of(signal_event_emiter_time), + })} + end end + end From fc75c91b4e78a40006d1565d44658cead9233de5 Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 21:16:23 -0500 Subject: [PATCH 12/13] remove old TimeOfArrivalStrategies::SourceVectorDistance --- lib/multilateration.rb | 1 - .../source_vector_distance.rb | 27 ------------------- .../source_vector_distance_spec.rb | 4 --- 3 files changed, 32 deletions(-) delete mode 100644 lib/multilateration/time_of_arrival_strategies/source_vector_distance.rb delete mode 100644 spec/multilateration/time_of_arrival_strategies/source_vector_distance_spec.rb diff --git a/lib/multilateration.rb b/lib/multilateration.rb index 9614ee8..8fb569f 100644 --- a/lib/multilateration.rb +++ b/lib/multilateration.rb @@ -6,7 +6,6 @@ require "multilateration/signal_event_data_generator" require "multilateration/signal_event" require "multilateration/solver" -require "multilateration/time_of_arrival_strategies/source_vector_distance" module Multilateration # Your code goes here... diff --git a/lib/multilateration/time_of_arrival_strategies/source_vector_distance.rb b/lib/multilateration/time_of_arrival_strategies/source_vector_distance.rb deleted file mode 100644 index 242a3c8..0000000 --- a/lib/multilateration/time_of_arrival_strategies/source_vector_distance.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Multilateration - module TimeOfArrivalStrategies - class SourceVectorDistance - attr_reader :source_vector, :wave_speed - private :source_vector - - def initialize(source_vector, wave_speed=1) - @source_vector = source_vector - @wave_speed = wave_speed - end - - def tdoa(vector_a, vector_b) - toa(vector_a) - toa(vector_b) - end - - def toa(target_vector) - distance_between_source_vector_and(target_vector) / wave_speed - end - - private - - def distance_between_source_vector_and(target_vector) - Math.sqrt((target_vector - source_vector).map { |component| component.abs**2 }.reduce(&:+)) - end - end - end -end diff --git a/spec/multilateration/time_of_arrival_strategies/source_vector_distance_spec.rb b/spec/multilateration/time_of_arrival_strategies/source_vector_distance_spec.rb deleted file mode 100644 index 3fa80ee..0000000 --- a/spec/multilateration/time_of_arrival_strategies/source_vector_distance_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'spec_helper' - -describe Multilateration::TimeOfArrivalStrategies::SourceVectorDistance do -end From 3c0ec83aa057090d4a80ad6fca855eea6356aa7c Mon Sep 17 00:00:00 2001 From: Arron Mabrey Date: Sun, 14 Dec 2014 21:17:05 -0500 Subject: [PATCH 13/13] remove unused TIMESTAMP_FORMAT --- lib/multilateration/signal_event_data_generator.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/multilateration/signal_event_data_generator.rb b/lib/multilateration/signal_event_data_generator.rb index b9de697..abace4c 100644 --- a/lib/multilateration/signal_event_data_generator.rb +++ b/lib/multilateration/signal_event_data_generator.rb @@ -1,8 +1,6 @@ module Multilateration class SignalEventDataGenerator - TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S.%N%z" - def self.generate new( receiver_count: 5,