From 9b53bd8a70b0086b1005cc2d622acd3b6b7f357b Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sat, 18 Sep 2021 22:49:55 -0500 Subject: [PATCH] Initial FieldPlanner page for planning robot route --- lib/pages/field_planner.rb | 127 +++++++++++++++++++++++++++++ lib/simulator/field.rb | 11 ++- lib/states/editor.rb | 18 +++- timecrafters_configuration_tool.rb | 1 + 4 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 lib/pages/field_planner.rb diff --git a/lib/pages/field_planner.rb b/lib/pages/field_planner.rb new file mode 100644 index 0000000..0006717 --- /dev/null +++ b/lib/pages/field_planner.rb @@ -0,0 +1,127 @@ +module TAC + class Pages + class FieldPlanner < Page + def setup + header_bar("Field Planner") + + body.clear do + flow(width: 1.0, height: 1.0) do + @field_container = stack width: 0.5, height: 1.0 do + background 0xff_111111 + end + + @points_container = stack width: 0.5, height: 1.0 do + end + end + end + + @field = TAC::Simulator::Field.new(container: @field_container, season: :skystone, simulation: nil) + @nodes = [] + @unit = :inches + end + + def draw + super + + @field.draw + + display_path + end + + def update + super + + @field.update + + measure_path + end + + def button_down(id) + super + + if @field_container.hit?(window.mouse_x, window.mouse_y) + x = (window.mouse_x - @field_container.x) / @field.scale + y = (window.mouse_y - @field_container.y) / @field.scale + + case id + when Gosu::MS_LEFT # Add Node + @nodes << CyberarmEngine::Vector.new(x, y, 0) + + measure_path + + refresh_panel + + when Gosu::MS_RIGHT # Delete Node + result = @nodes.find do |node| + Gosu.distance( + node.x, + node.y, + x, + y + ) <= 1.5 + end + + @nodes.delete(result) if result + + measure_path + + refresh_panel + end + end + end + + def display_path + last_node = @nodes.first + @nodes.each_with_index do |current_node, i| + Gosu.draw_circle( + current_node.x * @field.scale + @field_container.x, + current_node.y * @field.scale + @field_container.y, + 3, 7 + ) + + next if i.zero? + + Gosu.draw_line( + last_node.x * @field.scale + @field_container.x, + last_node.y * @field.scale + @field_container.y, + Gosu::Color::GREEN, + current_node.x * @field.scale + @field_container.x, + current_node.y * @field.scale + @field_container.y, + Gosu::Color::GREEN, + 3 + ) + + last_node = current_node + end + end + + def measure_path + @total_distance = 0 + + v1 = @nodes.first + @nodes.each_with_index do |v2, i| + next if i.zero? + + @total_distance += Gosu.distance( + v1.x + @field_container.x, + v1.y + @field_container.y, + v2.x + @field_container.x, + v2.y + @field_container.y + ) + + v1 = v2 + end + end + + def refresh_panel + @points_container.clear do + title "Nodes: #{@nodes.count} - Length: #{@total_distance.round}" + + @nodes.each do |v| + para "Vector #{v.x.round}:#{v.y.round}" + end + end + end + end + end +end \ No newline at end of file diff --git a/lib/simulator/field.rb b/lib/simulator/field.rb index bf300a4..d9c0359 100644 --- a/lib/simulator/field.rb +++ b/lib/simulator/field.rb @@ -1,6 +1,8 @@ module TAC class Simulator class Field + attr_reader :scale + def initialize(container:, season:, simulation:) @container = container @season = season @@ -24,8 +26,8 @@ module TAC Gosu.scale(@scale) do self.send(:"draw_field_#{@season}") - @simulation.robots.each(&:draw) - @simulation.robots.each { |robot| robot.queue.first.draw if robot.queue.first && @simulation.show_paths } + @simulation&.robots&.each(&:draw) + @simulation&.robots&.each { |robot| robot.queue.first.draw if robot.queue.first && @simulation.show_paths } end end end @@ -165,8 +167,9 @@ module TAC end def update - @position.x, @position.y = @container.x, @container.y - @size = @container.width + @position.x = @container.x + @position.y = @container.y + @size = [@container.width, @container.height].min @scale = @size.to_f / @field_size end end diff --git a/lib/states/editor.rb b/lib/states/editor.rb index a06cefa..2d15f1c 100644 --- a/lib/states/editor.rb +++ b/lib/states/editor.rb @@ -50,7 +50,7 @@ class Editor < CyberarmEngine::GuiState end @container = flow(width: 1.0, height: 1.0) do - @navigation = stack(width: 64, height: 1.0) do + @navigation = stack(width: 64, height: 1.0, scroll: true) do background 0xff_333333 button get_image("#{TAC::ROOT_PATH}/media/icons/home.png"), margin: 4, tip: "Home", image_width: 1.0 do @@ -80,6 +80,10 @@ class Editor < CyberarmEngine::GuiState button get_image("#{TAC::ROOT_PATH}/media/icons/zoom.png"), margin: 4, tip: "Search", image_width: 1.0 do page(TAC::Pages::Search) end + + button get_image("#{TAC::ROOT_PATH}/media/icons/joystickLeft.png"), margin: 4, tip: "Field Planner", image_width: 1.0 do + page(TAC::Pages::FieldPlanner) + end end @content = stack(width: window.width - @navigation.style.width, height: 1.0) do @@ -137,6 +141,18 @@ class Editor < CyberarmEngine::GuiState end end + def button_down(id) + super + + @page&.button_down(id) + end + + def button_up(id) + super + + @page&.button_up(id) + end + def recalc @window_controls.style.x = window.width - @window_controls.width @container.style.height = window.height - @header_bar.height diff --git a/timecrafters_configuration_tool.rb b/timecrafters_configuration_tool.rb index 1044555..85c6b85 100644 --- a/timecrafters_configuration_tool.rb +++ b/timecrafters_configuration_tool.rb @@ -26,6 +26,7 @@ require_relative "lib/pages/simulator" require_relative "lib/pages/configurations" require_relative "lib/pages/presets" require_relative "lib/pages/search" +require_relative "lib/pages/field_planner" require_relative "lib/simulator/robot" require_relative "lib/simulator/field" require_relative "lib/simulator/simulation"