From 11e926d144b412c65ae99ca3f968e421cb0a5cd4 Mon Sep 17 00:00:00 2001 From: Pesterenan Date: Fri, 21 Feb 2025 00:20:44 -0300 Subject: [PATCH 1/2] [MP-7]: Refactoring krpc connection code --- src/main/java/com/pesterenan/MechPeste.java | 146 ++++++++++++------ .../com/pesterenan/model/ActiveVessel.java | 2 +- .../com/pesterenan/views/StatusJPanel.java | 1 - 3 files changed, 100 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/pesterenan/MechPeste.java b/src/main/java/com/pesterenan/MechPeste.java index da9689e..aa78fac 100644 --- a/src/main/java/com/pesterenan/MechPeste.java +++ b/src/main/java/com/pesterenan/MechPeste.java @@ -5,12 +5,17 @@ import java.awt.event.ActionEvent; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import javax.swing.DefaultListModel; import javax.swing.ListModel; +import javax.swing.SwingUtilities; import com.pesterenan.model.ActiveVessel; import com.pesterenan.resources.Bundle; @@ -34,9 +39,15 @@ public class MechPeste { private static int currentVesselId = -1; private static ActiveVessel currentVessel = null; - public static void main(String[] args) { - MechPeste.newInstance().connectToKSP(); - MechPeste.newInstance().checkActiveVessel(); + public static Connection getConnection() { + return connection; + } + + public static SpaceCenter getSpaceCenter() { + return spaceCenter; + } + + private MechPeste() { } public static MechPeste newInstance() { @@ -46,12 +57,16 @@ public static MechPeste newInstance() { return mechPeste; } - public static Connection getConnection() { - return connection; - } - - public static SpaceCenter getSpaceCenter() { - return spaceCenter; + public static void main(String[] args) { + MechPeste mp = MechPeste.newInstance(); + try { + SwingUtilities.invokeAndWait(() -> { + MainGui.newInstance(); + }); + } catch (InvocationTargetException | InterruptedException e) { + System.err.println("Error while invoking GUI: " + e.getMessage()); + } + mp.connectToKSP(); } public static ListModel getActiveVessels(String search) { @@ -119,7 +134,7 @@ public static void cancelControl(ActionEvent e) { } private static boolean filterVessels(Vessel vessel, String search) { - if (search == "all") { + if ("all".equals(search)) { return true; } double TEN_KILOMETERS = 10000.0; @@ -130,12 +145,12 @@ private static boolean filterVessels(Vessel vessel, String search) { final Vector vesselPos = new Vector(vessel.position(active.getSurfaceReferenceFrame())); final double distance = Vector.distance(activePos, vesselPos); switch (search) { - case "closest" : + case "closest": if (distance < TEN_KILOMETERS) { return true; } break; - case "samebody" : + case "samebody": return true; } } @@ -144,10 +159,6 @@ private static boolean filterVessels(Vessel vessel, String search) { return false; } - private MechPeste() { - MainGui.newInstance(); - } - public KRPC.GameScene getCurrentGameScene() throws RPCException { return krpc.getCurrentGameScene(); } @@ -160,53 +171,94 @@ public void connectToKSP() { setStatusMessage(Bundle.getString("status_connecting")); try { connection = Connection.newInstance("MechPeste - Pesterenan"); - krpc = KRPC.newInstance(connection); + krpc = KRPC.newInstance(getConnection()); spaceCenter = SpaceCenter.newInstance(getConnection()); setStatusMessage(Bundle.getString("status_connected")); isBtnConnectVisible(false); + this.startSchedulerLoop(); } catch (IOException e) { setStatusMessage(Bundle.getString("status_error_connection")); + System.err.println("Error: " + e.getMessage()); isBtnConnectVisible(true); } } - public void checkConnection() { - try { - if (!MechPeste.newInstance().getCurrentGameScene().equals(KRPC.GameScene.FLIGHT)) { - setStatusMessage(Bundle.getString("status_ready")); + private void startSchedulerLoop() { + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.scheduleAtFixedRate(() -> { + if (!isConnectionAlive()) { + System.err.println("Connection dropped, shutting down scheduler loop."); + scheduler.shutdown(); + setStatusMessage(Bundle.getString("status_error_connection")); + isBtnConnectVisible(true); + } + + if (!isOnFlightScene()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } return; } - getConnection().close(); - } catch (RPCException | NullPointerException | IOException e) { - setStatusMessage(Bundle.getString("status_error_connection")); - isBtnConnectVisible(true); + + checkAndUpdateActiveVessel(); + updateTelemetryData(); + updateUI(); + }, 0, 250, TimeUnit.MILLISECONDS); + } + + private boolean isConnectionAlive() { + try { + krpc.getStatus(); + } catch (RPCException e) { + return false; + } + return true; + } + + private boolean isOnFlightScene() { + try { + return this.getCurrentGameScene().equals(KRPC.GameScene.FLIGHT); + } catch (RPCException e) { + return false; } } - private void checkActiveVessel() { - while (getConnection() != null) { + private void checkAndUpdateActiveVessel() { + try { + int activeVesselId = spaceCenter.getActiveVessel().hashCode(); + if (currentVesselId != activeVesselId) { + currentVessel = new ActiveVessel(); + currentVesselId = currentVessel.getCurrentVesselId(); + } + } catch (RPCException | NullPointerException e) { + System.err.println("Error while updating active vessel: " + e.getMessage()); + } + } + + private void updateTelemetryData() { + if (currentVesselId == -1) + return; + try { + currentVessel.recordTelemetryData(); + } catch (RPCException e) { + System.err.println("Error while getting telemetry: " + e.getMessage()); + currentVesselId = -1; + } + } + + private void updateUI() { + SwingUtilities.invokeLater(() -> { try { - if (!MechPeste.newInstance().getCurrentGameScene().equals(KRPC.GameScene.FLIGHT)) { - Thread.sleep(100); - return; + if (currentVessel.hasModuleRunning()) { + setStatusMessage(currentVessel.getCurrentStatus()); } - int activeVesselId = spaceCenter.getActiveVessel().hashCode(); - // If the current active vessel changes, create a new connection - if (currentVesselId != activeVesselId) { - currentVessel = new ActiveVessel(); - currentVesselId = currentVessel.getCurrentVesselId(); - } - if (currentVesselId != -1) { - currentVessel.recordTelemetryData(); - if (currentVessel.hasModuleRunning()) { - setStatusMessage(currentVessel.getCurrentStatus()); - } - FunctionsAndTelemetryJPanel.updateTelemetry(currentVessel.getTelemetryData()); - CreateManeuverJPanel.updatePanel(getCurrentManeuvers()); - } - Thread.sleep(100); - } catch (RPCException | InterruptedException ignored) { + FunctionsAndTelemetryJPanel.updateTelemetry(currentVessel.getTelemetryData()); + CreateManeuverJPanel.updatePanel(getCurrentManeuvers()); + } catch (Error e) { + System.err.println("Erro ao atualizar UI: " + e.getMessage()); } - } + }); } } diff --git a/src/main/java/com/pesterenan/model/ActiveVessel.java b/src/main/java/com/pesterenan/model/ActiveVessel.java index 849d94f..2e8a221 100644 --- a/src/main/java/com/pesterenan/model/ActiveVessel.java +++ b/src/main/java/com/pesterenan/model/ActiveVessel.java @@ -76,7 +76,7 @@ private void initializeParameters() { verticalVelocity = getConnection().addStream(flightParameters, "getVerticalSpeed"); horizontalVelocity = getConnection().addStream(flightParameters, "getHorizontalSpeed"); } catch (RPCException | StreamException e) { - MechPeste.newInstance().checkConnection(); + System.err.println("Error while initializing parameters for active vessel: " + e.getMessage()); } } diff --git a/src/main/java/com/pesterenan/views/StatusJPanel.java b/src/main/java/com/pesterenan/views/StatusJPanel.java index e3f6e34..d54effc 100644 --- a/src/main/java/com/pesterenan/views/StatusJPanel.java +++ b/src/main/java/com/pesterenan/views/StatusJPanel.java @@ -70,7 +70,6 @@ public static void isBtnConnectVisible(boolean visible) { } private void handleConnect(ActionEvent e) { - setStatusMessage(Bundle.getString("status_connecting")); MechPeste.newInstance().connectToKSP(); } } From 7df92a9a2862b4fe0969be7dcf7491a7715bf86a Mon Sep 17 00:00:00 2001 From: Pesterenan Date: Mon, 24 Feb 2025 09:01:37 -0300 Subject: [PATCH 2/2] [MP-7]: Improving code with Dependency Injection --- .settings/org.eclipse.jdt.apt.core.prefs | 2 + .settings/org.eclipse.jdt.core.prefs | 27 +- pom.xml | 2 +- src/main/java/com/pesterenan/MechPeste.java | 254 ++---------------- .../pesterenan/controllers/Controller.java | 6 +- .../controllers/DockingController.java | 19 +- .../controllers/LandingController.java | 32 +-- .../controllers/LiftoffController.java | 16 +- .../controllers/ManeuverController.java | 52 ++-- .../controllers/RoverController.java | 46 ++-- .../com/pesterenan/model/ActiveVessel.java | 126 +++++---- .../pesterenan/model/ConnectionManager.java | 97 +++++++ .../com/pesterenan/model/VesselManager.java | 208 ++++++++++++++ .../java/com/pesterenan/utils/Module.java | 78 ++++-- .../java/com/pesterenan/utils/Navigation.java | 31 ++- .../com/pesterenan/utils/PathFinding.java | 23 +- .../pesterenan/views/ChangeVesselDialog.java | 31 ++- .../views/CreateManeuverJPanel.java | 94 ++++--- .../com/pesterenan/views/DockingJPanel.java | 46 ++-- .../views/FunctionsAndTelemetryJPanel.java | 55 ++-- .../com/pesterenan/views/LandingJPanel.java | 51 ++-- .../com/pesterenan/views/LiftoffJPanel.java | 50 +++- .../java/com/pesterenan/views/MainGui.java | 168 ++++++++---- .../com/pesterenan/views/RoverJPanel.java | 45 +++- .../pesterenan/views/RunManeuverJPanel.java | 69 +++-- .../com/pesterenan/views/StatusDisplay.java | 7 + .../com/pesterenan/views/StatusJPanel.java | 31 ++- 27 files changed, 1019 insertions(+), 647 deletions(-) create mode 100644 .settings/org.eclipse.jdt.apt.core.prefs create mode 100644 src/main/java/com/pesterenan/model/ConnectionManager.java create mode 100644 src/main/java/com/pesterenan/model/VesselManager.java create mode 100644 src/main/java/com/pesterenan/views/StatusDisplay.java diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..d4313d4 --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 0f0bc12..3d58a74 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,22 +1,19 @@ -# Java Version +eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=disabled +org.eclipse.jdt.core.compiler.release=disabled org.eclipse.jdt.core.compiler.source=1.8 - -# Indentation -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.indentation.size=4 - -# Braces +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line - -# Line Wrapping -org.eclipse.jdt.core.formatter.lineSplit=120 -org.eclipse.jdt.core.formatter.join_wrapped_lines=false - -# Other -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.indentation.size=4 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=false +org.eclipse.jdt.core.formatter.lineSplit=120 +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 diff --git a/pom.xml b/pom.xml index 3936d8f..71cf327 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.pesterenan MechPeste - 0.8.0 + 0.8.1 diff --git a/src/main/java/com/pesterenan/MechPeste.java b/src/main/java/com/pesterenan/MechPeste.java index aa78fac..250cc73 100644 --- a/src/main/java/com/pesterenan/MechPeste.java +++ b/src/main/java/com/pesterenan/MechPeste.java @@ -1,264 +1,50 @@ package com.pesterenan; -import static com.pesterenan.views.StatusJPanel.isBtnConnectVisible; -import static com.pesterenan.views.StatusJPanel.setStatusMessage; - -import java.awt.event.ActionEvent; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import javax.swing.DefaultListModel; -import javax.swing.ListModel; import javax.swing.SwingUtilities; -import com.pesterenan.model.ActiveVessel; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Vector; -import com.pesterenan.views.CreateManeuverJPanel; -import com.pesterenan.views.FunctionsAndTelemetryJPanel; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; import com.pesterenan.views.MainGui; - -import krpc.client.Connection; -import krpc.client.RPCException; -import krpc.client.services.KRPC; -import krpc.client.services.SpaceCenter; -import krpc.client.services.SpaceCenter.Node; -import krpc.client.services.SpaceCenter.Vessel; +import com.pesterenan.views.StatusDisplay; public class MechPeste { - private static KRPC krpc; - private static MechPeste mechPeste; - private static SpaceCenter spaceCenter; - private static Connection connection; - private static int currentVesselId = -1; - private static ActiveVessel currentVessel = null; + private static MechPeste instance; + private ConnectionManager connectionManager = null; + private VesselManager vesselManager; - public static Connection getConnection() { - return connection; + public ConnectionManager getConnectionManager() { + return connectionManager; } - public static SpaceCenter getSpaceCenter() { - return spaceCenter; + public VesselManager getVesselManager() { + return vesselManager; } private MechPeste() { } public static MechPeste newInstance() { - if (mechPeste == null) { - mechPeste = new MechPeste(); + if (instance == null) { + instance = new MechPeste(); } - return mechPeste; + return instance; } public static void main(String[] args) { - MechPeste mp = MechPeste.newInstance(); + MechPeste app = MechPeste.newInstance(); try { - SwingUtilities.invokeAndWait(() -> { - MainGui.newInstance(); - }); + SwingUtilities.invokeAndWait(() -> MainGui.newInstance()); } catch (InvocationTargetException | InterruptedException e) { System.err.println("Error while invoking GUI: " + e.getMessage()); + e.printStackTrace(); } - mp.connectToKSP(); - } - - public static ListModel getActiveVessels(String search) { - DefaultListModel list = new DefaultListModel<>(); - try { - List vessels = spaceCenter.getVessels(); - vessels = vessels.stream().filter(v -> filterVessels(v, search)).collect(Collectors.toList()); - vessels.forEach(v -> { - try { - String vesselName = v.hashCode() + " - \t" + v.getName(); - list.addElement(vesselName); - } catch (RPCException ignored) { - } - }); - } catch (RPCException | NullPointerException ignored) { - } - return list; - } - - public static ListModel getCurrentManeuvers() { - DefaultListModel list = new DefaultListModel<>(); - try { - List maneuvers = getSpaceCenter().getActiveVessel().getControl().getNodes(); - maneuvers.forEach(m -> { - try { - String maneuverStr = String.format("%d - Dv: %.1f {P: %.1f, N: %.1f, R: %.1f} AP: %.1f, PE: %.1f", - maneuvers.indexOf(m) + 1, m.getDeltaV(), m.getPrograde(), m.getNormal(), m.getRadial(), - m.getOrbit().getApoapsisAltitude(), m.getOrbit().getPeriapsisAltitude()); - list.addElement(maneuverStr); - } catch (RPCException ignored) { - } - }); - } catch (RPCException | NullPointerException ignored) { - } - return list; - } - public static String getVesselInfo(int selectedIndex) { - try { - Vessel activeVessel = spaceCenter.getVessels().stream().filter(v -> v.hashCode() == selectedIndex) - .findFirst().get(); - String name = activeVessel.getName().length() > 40 - ? activeVessel.getName().substring(0, 40) + "..." - : activeVessel.getName(); - String vesselInfo = String.format("Nome: %s\t\t\t | Corpo: %s", name, - activeVessel.getOrbit().getBody().getName()); - return vesselInfo; - } catch (RPCException | NullPointerException ignored) { - } - return ""; + StatusDisplay statusDisplay = MainGui.newInstance().getStatusPanel(); + app.connectionManager = new ConnectionManager("MechPeste - Pesterenan", statusDisplay); + app.vesselManager = new VesselManager(app.connectionManager, statusDisplay); + app.vesselManager.startUpdateLoop(); } - public static void changeToVessel(int selectedIndex) { - try { - Vessel activeVessel = spaceCenter.getVessels().stream().filter(v -> v.hashCode() == selectedIndex) - .findFirst().get(); - spaceCenter.setActiveVessel(activeVessel); - } catch (RPCException | NullPointerException e) { - System.out.println(Bundle.getString("status_couldnt_switch_vessel")); - } - } - - public static void cancelControl(ActionEvent e) { - currentVessel.cancelControl(); - } - - private static boolean filterVessels(Vessel vessel, String search) { - if ("all".equals(search)) { - return true; - } - double TEN_KILOMETERS = 10000.0; - try { - Vessel active = MechPeste.getSpaceCenter().getActiveVessel(); - if (vessel.getOrbit().getBody().getName().equals(active.getOrbit().getBody().getName())) { - final Vector activePos = new Vector(active.position(active.getSurfaceReferenceFrame())); - final Vector vesselPos = new Vector(vessel.position(active.getSurfaceReferenceFrame())); - final double distance = Vector.distance(activePos, vesselPos); - switch (search) { - case "closest": - if (distance < TEN_KILOMETERS) { - return true; - } - break; - case "samebody": - return true; - } - } - } catch (RPCException ignored) { - } - return false; - } - - public KRPC.GameScene getCurrentGameScene() throws RPCException { - return krpc.getCurrentGameScene(); - } - - public void startModule(Map commands) { - currentVessel.startModule(commands); - } - - public void connectToKSP() { - setStatusMessage(Bundle.getString("status_connecting")); - try { - connection = Connection.newInstance("MechPeste - Pesterenan"); - krpc = KRPC.newInstance(getConnection()); - spaceCenter = SpaceCenter.newInstance(getConnection()); - setStatusMessage(Bundle.getString("status_connected")); - isBtnConnectVisible(false); - this.startSchedulerLoop(); - } catch (IOException e) { - setStatusMessage(Bundle.getString("status_error_connection")); - System.err.println("Error: " + e.getMessage()); - isBtnConnectVisible(true); - } - } - - private void startSchedulerLoop() { - ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); - scheduler.scheduleAtFixedRate(() -> { - if (!isConnectionAlive()) { - System.err.println("Connection dropped, shutting down scheduler loop."); - scheduler.shutdown(); - setStatusMessage(Bundle.getString("status_error_connection")); - isBtnConnectVisible(true); - } - - if (!isOnFlightScene()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return; - } - - checkAndUpdateActiveVessel(); - updateTelemetryData(); - updateUI(); - }, 0, 250, TimeUnit.MILLISECONDS); - } - - private boolean isConnectionAlive() { - try { - krpc.getStatus(); - } catch (RPCException e) { - return false; - } - return true; - } - - private boolean isOnFlightScene() { - try { - return this.getCurrentGameScene().equals(KRPC.GameScene.FLIGHT); - } catch (RPCException e) { - return false; - } - } - - private void checkAndUpdateActiveVessel() { - try { - int activeVesselId = spaceCenter.getActiveVessel().hashCode(); - if (currentVesselId != activeVesselId) { - currentVessel = new ActiveVessel(); - currentVesselId = currentVessel.getCurrentVesselId(); - } - } catch (RPCException | NullPointerException e) { - System.err.println("Error while updating active vessel: " + e.getMessage()); - } - } - - private void updateTelemetryData() { - if (currentVesselId == -1) - return; - try { - currentVessel.recordTelemetryData(); - } catch (RPCException e) { - System.err.println("Error while getting telemetry: " + e.getMessage()); - currentVesselId = -1; - } - } - - private void updateUI() { - SwingUtilities.invokeLater(() -> { - try { - if (currentVessel.hasModuleRunning()) { - setStatusMessage(currentVessel.getCurrentStatus()); - } - FunctionsAndTelemetryJPanel.updateTelemetry(currentVessel.getTelemetryData()); - CreateManeuverJPanel.updatePanel(getCurrentManeuvers()); - } catch (Error e) { - System.err.println("Erro ao atualizar UI: " + e.getMessage()); - } - }); - } } diff --git a/src/main/java/com/pesterenan/controllers/Controller.java b/src/main/java/com/pesterenan/controllers/Controller.java index c0901f7..8552d27 100644 --- a/src/main/java/com/pesterenan/controllers/Controller.java +++ b/src/main/java/com/pesterenan/controllers/Controller.java @@ -1,11 +1,13 @@ package com.pesterenan.controllers; import com.pesterenan.model.ActiveVessel; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; public class Controller extends ActiveVessel implements Runnable { - public Controller() { - super(); + public Controller(ConnectionManager connectionManager, VesselManager vesselManager) { + super(connectionManager, vesselManager); } public void run() { diff --git a/src/main/java/com/pesterenan/controllers/DockingController.java b/src/main/java/com/pesterenan/controllers/DockingController.java index 978fb31..916250d 100644 --- a/src/main/java/com/pesterenan/controllers/DockingController.java +++ b/src/main/java/com/pesterenan/controllers/DockingController.java @@ -1,16 +1,14 @@ package com.pesterenan.controllers; -import static com.pesterenan.MechPeste.getConnection; -import static com.pesterenan.MechPeste.getSpaceCenter; - import java.util.Map; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.Module; import com.pesterenan.utils.Utilities; import com.pesterenan.utils.Vector; import com.pesterenan.views.DockingJPanel; -import com.pesterenan.views.StatusJPanel; import krpc.client.RPCException; import krpc.client.services.Drawing; @@ -48,9 +46,12 @@ public class DockingController extends Controller { private double lastZTargetPos = 0.0; private long sleepTime = 25; private DOCKING_STEPS dockingStep; + private ConnectionManager connectionManager; - public DockingController(Map commands) { - super(); + public DockingController(ConnectionManager connectionManager, VesselManager vesselManager, + Map commands) { + super(connectionManager, vesselManager); + this.connectionManager = connectionManager; this.commands = commands; initializeParameters(); } @@ -59,8 +60,8 @@ private void initializeParameters() { try { DOCKING_MAX_SPEED = Double.parseDouble(commands.get(Module.MAX_SPEED.get())); SAFE_DISTANCE = Double.parseDouble(commands.get(Module.SAFE_DISTANCE.get())); - drawing = Drawing.newInstance(getConnection()); - targetVessel = getSpaceCenter().getTargetVessel(); + drawing = Drawing.newInstance(connectionManager.getConnection()); + targetVessel = connectionManager.getSpaceCenter().getTargetVessel(); control = getActiveVessel().getControl(); vesselRefFrame = getActiveVessel().getReferenceFrame(); orbitalRefVessel = getActiveVessel().getOrbitalReferenceFrame(); @@ -160,7 +161,7 @@ public void startDocking() { Thread.sleep(sleepTime); } } catch (RPCException | InterruptedException | IllegalArgumentException e) { - StatusJPanel.setStatusMessage("Docking interrupted."); + setCurrentStatus("Docking interrupted."); } } diff --git a/src/main/java/com/pesterenan/controllers/LandingController.java b/src/main/java/com/pesterenan/controllers/LandingController.java index 57cdc6f..0841f38 100644 --- a/src/main/java/com/pesterenan/controllers/LandingController.java +++ b/src/main/java/com/pesterenan/controllers/LandingController.java @@ -1,9 +1,9 @@ package com.pesterenan.controllers; -import static com.pesterenan.MechPeste.getSpaceCenter; - import java.util.Map; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.ControlePID; import com.pesterenan.utils.Module; @@ -16,6 +16,9 @@ public class LandingController extends Controller { + private enum MODE { + DEORBITING, APPROACHING, GOING_UP, HOVERING, GOING_DOWN, LANDING, WAITING + } public static final double MAX_VELOCITY = 5; private static final long sleepTime = 50; private static final double velP = 0.05; @@ -33,20 +36,14 @@ public class LandingController extends Controller { private double altitudeErrorPercentage; private float maxTWR; - public LandingController(Map commands) { - super(); + public LandingController(ConnectionManager connectionManager, VesselManager vesselManager, + Map commands) { + super(connectionManager, vesselManager); this.commands = commands; - this.navigation = new Navigation(getActiveVessel()); + this.navigation = new Navigation(connectionManager, getActiveVessel()); this.initializeParameters(); } - private void initializeParameters() { - altitudeCtrl = new ControlePID(getSpaceCenter(), sleepTime); - velocityCtrl = new ControlePID(getSpaceCenter(), sleepTime); - altitudeCtrl.setOutput(0, 1); - velocityCtrl.setOutput(0, 1); - } - @Override public void run() { if (commands.get(Module.MODULO.get()).equals(Module.HOVERING.get())) { @@ -57,6 +54,13 @@ public void run() { } } + private void initializeParameters() { + altitudeCtrl = new ControlePID(getConnectionManager().getSpaceCenter(), sleepTime); + velocityCtrl = new ControlePID(getConnectionManager().getSpaceCenter(), sleepTime); + altitudeCtrl.setOutput(0, 1); + velocityCtrl.setOutput(0, 1); + } + private void hoverArea() { try { hoverAltitude = Double.parseDouble(commands.get(Module.HOVER_ALTITUDE.get())); @@ -277,8 +281,4 @@ private double calculateEllipticTrajectory(double a, double b) { double semiMinor = Math.min(a * 2, b * 2); return Math.PI * Math.sqrt((semiMajor * semiMajor + semiMinor * semiMinor)) / 4; } - - private enum MODE { - DEORBITING, APPROACHING, GOING_UP, HOVERING, GOING_DOWN, LANDING, WAITING - } } diff --git a/src/main/java/com/pesterenan/controllers/LiftoffController.java b/src/main/java/com/pesterenan/controllers/LiftoffController.java index 2901639..4dfb85e 100644 --- a/src/main/java/com/pesterenan/controllers/LiftoffController.java +++ b/src/main/java/com/pesterenan/controllers/LiftoffController.java @@ -1,12 +1,11 @@ package com.pesterenan.controllers; -import static com.pesterenan.MechPeste.getSpaceCenter; - import java.util.HashMap; import java.util.List; import java.util.Map; -import com.pesterenan.MechPeste; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.ControlePID; import com.pesterenan.utils.Module; @@ -32,10 +31,11 @@ public class LiftoffController extends Controller { private String gravityCurveModel = Module.CIRCULAR.get(); private Navigation navigation; - public LiftoffController(Map commands) { - super(); + public LiftoffController(ConnectionManager connectionManager, VesselManager vesselManager, + Map commands) { + super(connectionManager, vesselManager); this.commands = commands; - this.navigation = new Navigation(getActiveVessel()); + this.navigation = new Navigation(connectionManager, getActiveVessel()); initializeParameters(); } @@ -48,7 +48,7 @@ private void initializeParameters() { setGravityCurveModel(commands.get(Module.INCLINATION.get())); willOpenPanelsAndAntenna = Boolean.parseBoolean(commands.get(Module.OPEN_PANELS.get())); willDecoupleStages = Boolean.parseBoolean(commands.get(Module.STAGE.get())); - thrControl = new ControlePID(getSpaceCenter(), 25); + thrControl = new ControlePID(getConnectionManager().getSpaceCenter(), 25); thrControl.setOutput(0.0, 1.0); } @@ -133,7 +133,7 @@ private void circularizeOrbitOnApoapsis() { commands.put(Module.MODULO.get(), Module.MANEUVER.get()); commands.put(Module.FUNCTION.get(), Module.APOAPSIS.get()); commands.put(Module.FINE_ADJUST.get(), String.valueOf(false)); - MechPeste.newInstance().startModule(commands); + getVesselManager().startModule(commands); } private void jettisonFairings() throws RPCException, InterruptedException { diff --git a/src/main/java/com/pesterenan/controllers/ManeuverController.java b/src/main/java/com/pesterenan/controllers/ManeuverController.java index 40356e9..83af766 100644 --- a/src/main/java/com/pesterenan/controllers/ManeuverController.java +++ b/src/main/java/com/pesterenan/controllers/ManeuverController.java @@ -1,20 +1,19 @@ package com.pesterenan.controllers; -import static com.pesterenan.MechPeste.getConnection; -import static com.pesterenan.MechPeste.getSpaceCenter; - import java.util.List; import java.util.Map; import org.javatuples.Triplet; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.Attributes; import com.pesterenan.utils.ControlePID; import com.pesterenan.utils.Module; import com.pesterenan.utils.Navigation; import com.pesterenan.utils.Vector; -import com.pesterenan.views.RunManeuverJPanel; +import com.pesterenan.views.MainGui; import krpc.client.RPCException; import krpc.client.Stream; @@ -36,16 +35,17 @@ public class ManeuverController extends Controller { private boolean fineAdjustment; private double lowOrbitAltitude; - public ManeuverController(Map commands) { - super(); + public ManeuverController(ConnectionManager connectionManager, VesselManager vesselManager, + Map commands) { + super(connectionManager, vesselManager); this.commands = commands; - this.navigation = new Navigation(getActiveVessel()); + this.navigation = new Navigation(connectionManager, getActiveVessel()); initializeParameters(); } private void initializeParameters() { - ctrlRCS = new ControlePID(getSpaceCenter(), 25); - ctrlManeuver = new ControlePID(getSpaceCenter(), 25); + ctrlRCS = new ControlePID(getConnectionManager().getSpaceCenter(), 25); + ctrlManeuver = new ControlePID(getConnectionManager().getSpaceCenter(), 25); ctrlManeuver.setPIDValues(1, 0.001, 0.1); ctrlRCS.setOutput(0.5, 1.0); fineAdjustment = canFineAdjust(commands.get(Module.FINE_ADJUST.get())); @@ -178,7 +178,7 @@ private Node createManeuverAtClosestIncNode(Orbit targetOrbit) { double[] dv = {0, 0, 0}; try { double[] incNodesUt = getTimeToIncNodes(targetOrbit); - uTatClosestNode = Math.min(incNodesUt[0], incNodesUt[1]) - getSpaceCenter().getUT(); + uTatClosestNode = Math.min(incNodesUt[0], incNodesUt[1]) - getConnectionManager().getSpaceCenter().getUT(); } catch (Exception ignored) { } return createManeuver(uTatClosestNode, dv); @@ -195,18 +195,18 @@ private void alignPlanesWithTargetVessel() { try { Vessel vessel = getActiveVessel(); Orbit vesselOrbit = getActiveVessel().getOrbit(); - Orbit targetVesselOrbit = getSpaceCenter().getTargetVessel().getOrbit(); + Orbit targetVesselOrbit = getConnectionManager().getSpaceCenter().getTargetVessel().getOrbit(); boolean hasManeuverNodes = vessel.getControl().getNodes().size() > 0; System.out.println("hasManeuverNodes: " + hasManeuverNodes); if (!hasManeuverNodes) { - RunManeuverJPanel.createManeuver(); + MainGui.newInstance().getCreateManeuverPanel().createManeuver(); } java.util.List currentManeuvers = vessel.getControl().getNodes(); Node currentManeuver = currentManeuvers.get(0); double[] incNodesUt = {vesselOrbit.uTAtTrueAnomaly(vesselOrbit.trueAnomalyAtAN(targetVesselOrbit)), vesselOrbit.uTAtTrueAnomaly(vesselOrbit.trueAnomalyAtDN(targetVesselOrbit))}; boolean closestIsAN = incNodesUt[0] < incNodesUt[1]; - RunManeuverJPanel.positionManeuverAt(closestIsAN ? "ascending" : "descending"); + MainGui.newInstance().getCreateManeuverPanel().positionManeuverAt(closestIsAN ? "ascending" : "descending"); double currentInclination = Math .toDegrees(currentManeuver.getOrbit().relativeInclination(targetVesselOrbit)); ctrlManeuver.setTimeSample(25); @@ -231,15 +231,15 @@ private void rendezvousWithTargetVessel() { currentManeuvers = getActiveVessel().getControl().getNodes(); lastManeuverNode = currentManeuvers.get(currentManeuvers.size() - 1); lastManeuverNodeUT += lastManeuverNode.getUT(); - RunManeuverJPanel.createManeuver(lastManeuverNodeUT); + MainGui.newInstance().getCreateManeuverPanel().createManeuver(lastManeuverNodeUT); } else { - RunManeuverJPanel.createManeuver(); + MainGui.newInstance().getCreateManeuverPanel().createManeuver(); } currentManeuvers = getActiveVessel().getControl().getNodes(); lastManeuverNode = currentManeuvers.get(currentManeuvers.size() - 1); Orbit activeVesselOrbit = getActiveVessel().getOrbit(); - Orbit targetVesselOrbit = getSpaceCenter().getTargetVessel().getOrbit(); + Orbit targetVesselOrbit = getConnectionManager().getSpaceCenter().getTargetVessel().getOrbit(); ReferenceFrame currentBodyRefFrame = activeVesselOrbit.getBody().getNonRotatingReferenceFrame(); double angularDiff = 10; @@ -271,7 +271,8 @@ private void rendezvousWithTargetVessel() { } angularDiff = calculatePhaseAngle( lastManeuverNode.getOrbit().positionAt(maneuverUT, currentBodyRefFrame), - getSpaceCenter().getTargetVessel().getOrbit().positionAt(maneuverUT, currentBodyRefFrame)); + getConnectionManager().getSpaceCenter().getTargetVessel().getOrbit().positionAt(maneuverUT, + currentBodyRefFrame)); maneuverUT = lastManeuverNode.getUT(); lastManeuverNode.setUT(lastManeuverNode.getUT() + ctrlManeuver.calculate(-angularDiff * 100, 0)); System.out.println(angularDiff); @@ -363,11 +364,11 @@ private double compareOrbitParameter(Orbit maneuverOrbit, Orbit targetOrbit, Com } private Orbit getTargetOrbit() throws RPCException { - if (getSpaceCenter().getTargetBody() != null) { - return getSpaceCenter().getTargetBody().getOrbit(); + if (getConnectionManager().getSpaceCenter().getTargetBody() != null) { + return getConnectionManager().getSpaceCenter().getTargetBody().getOrbit(); } - if (getSpaceCenter().getTargetVessel() != null) { - return getSpaceCenter().getTargetVessel().getOrbit(); + if (getConnectionManager().getSpaceCenter().getTargetVessel() != null) { + return getConnectionManager().getSpaceCenter().getTargetVessel().getOrbit(); } return null; } @@ -375,7 +376,8 @@ private Orbit getTargetOrbit() throws RPCException { private Node createManeuver(double laterTime, double[] deltaV) { Node maneuverNode = null; try { - getActiveVessel().getControl().addNode(getSpaceCenter().getUT() + laterTime, (float) deltaV[0], + getActiveVessel().getControl().addNode(getConnectionManager().getSpaceCenter().getUT() + laterTime, + (float) deltaV[0], (float) deltaV[1], (float) deltaV[2]); List currentNodes = getActiveVessel().getControl().getNodes(); maneuverNode = currentNodes.get(currentNodes.size() - 1); @@ -440,7 +442,8 @@ public void executeBurn(Node maneuverNode, double burnDuration) { double burnStartTime = maneuverNode.getTimeTo() - (burnDuration / 2.0) - (fineAdjustment ? 5 : 0); setCurrentStatus(Bundle.getString("status_maneuver_warp")); if (burnStartTime > 30) { - getSpaceCenter().warpTo((getSpaceCenter().getUT() + burnStartTime - 10), 100000, 4); + getConnectionManager().getSpaceCenter() + .warpTo((getConnectionManager().getSpaceCenter().getUT() + burnStartTime - 10), 100000, 4); } // Mostrar tempo de ignição: setCurrentStatus(String.format(Bundle.getString("status_maneuver_duration"), burnDuration)); @@ -454,7 +457,8 @@ public void executeBurn(Node maneuverNode, double burnDuration) { Thread.sleep(100); } // Executar a manobra: - Stream> remainingBurn = getConnection().addStream(maneuverNode, + Stream> remainingBurn = getConnectionManager().getConnection().addStream( + maneuverNode, "remainingBurnVector", maneuverNode.getReferenceFrame()); setCurrentStatus(Bundle.getString("status_maneuver_executing")); while (maneuverNode != null) { diff --git a/src/main/java/com/pesterenan/controllers/RoverController.java b/src/main/java/com/pesterenan/controllers/RoverController.java index 64ad213..b9adb12 100644 --- a/src/main/java/com/pesterenan/controllers/RoverController.java +++ b/src/main/java/com/pesterenan/controllers/RoverController.java @@ -1,25 +1,27 @@ package com.pesterenan.controllers; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.javatuples.Pair; +import org.javatuples.Triplet; + +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.ControlePID; import com.pesterenan.utils.Module; import com.pesterenan.utils.PathFinding; import com.pesterenan.utils.Utilities; import com.pesterenan.utils.Vector; + import krpc.client.RPCException; import krpc.client.StreamException; import krpc.client.services.SpaceCenter.ReferenceFrame; import krpc.client.services.SpaceCenter.SolarPanel; import krpc.client.services.SpaceCenter.SolarPanelState; -import org.javatuples.Pair; -import org.javatuples.Triplet; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static com.pesterenan.MechPeste.getSpaceCenter; public class RoverController extends Controller { private final ControlePID sterringCtrl = new ControlePID(); @@ -32,9 +34,12 @@ public class RoverController extends Controller { private Vector targetPoint = new Vector(); private Vector roverDirection = new Vector(); private MODE currentMode; + private ConnectionManager connectionManager; - public RoverController(Map commands) { - super(); + public RoverController(ConnectionManager connectionManager, VesselManager vesselManager, + Map commands) { + super(connectionManager, vesselManager); + this.connectionManager = connectionManager; this.commands = commands; initializeParameters(); } @@ -44,7 +49,7 @@ private void initializeParameters() { maxSpeed = Float.parseFloat(commands.get(Module.MAX_SPEED.get())); roverReferenceFrame = getActiveVessel().getReferenceFrame(); roverDirection = new Vector(getActiveVessel().direction(roverReferenceFrame)); - pathFinding = new PathFinding(); + pathFinding = new PathFinding(getConnectionManager(), getVesselManager()); acelCtrl.setOutput(0, 1); sterringCtrl.setOutput(-1, 1); isAutoRoverRunning = true; @@ -77,7 +82,7 @@ private void setTarget() { } if (commands.get(Module.ROVER_TARGET_TYPE.get()).equals(Module.TARGET_VESSEL.get())) { Vector targetVesselPosition = new Vector( - getSpaceCenter().getTargetVessel().position(orbitalReferenceFrame)); + connectionManager.getSpaceCenter().getTargetVessel().position(orbitalReferenceFrame)); setCurrentStatus("Calculando rota até o alvo..."); pathFinding.buildPathToTarget(targetVesselPosition); } @@ -179,7 +184,8 @@ private void rechargeRover() throws RPCException, StreamException, InterruptedEx if (chargeTime < 1 || chargeTime > 21600) { chargeTime = 3600; } - getSpaceCenter().warpTo((getSpaceCenter().getUT() + chargeTime), 10000, 4); + connectionManager.getSpaceCenter().warpTo((connectionManager.getSpaceCenter().getUT() + chargeTime), 10000, + 4); getActiveVessel().getControl().setLights(true); } } @@ -267,22 +273,26 @@ private Vector calculateRaycastDirection(Vector point, Vector direction, double private Vector transformDirection(Vector vector) throws RPCException { return new Vector( - getSpaceCenter().transformDirection(vector.toTriplet(), roverReferenceFrame, surfaceReferenceFrame)); + connectionManager.getSpaceCenter().transformDirection(vector.toTriplet(), roverReferenceFrame, + surfaceReferenceFrame)); } private Vector posSurfToRover(Vector vector) throws RPCException { return new Vector( - getSpaceCenter().transformPosition(vector.toTriplet(), surfaceReferenceFrame, roverReferenceFrame)); + connectionManager.getSpaceCenter().transformPosition(vector.toTriplet(), surfaceReferenceFrame, + roverReferenceFrame)); } private Vector posRoverToSurf(Vector vector) throws RPCException { return new Vector( - getSpaceCenter().transformPosition(vector.toTriplet(), roverReferenceFrame, surfaceReferenceFrame)); + connectionManager.getSpaceCenter().transformPosition(vector.toTriplet(), roverReferenceFrame, + surfaceReferenceFrame)); } private Vector posOrbToSurf(Vector vector) throws RPCException { return new Vector( - getSpaceCenter().transformPosition(vector.toTriplet(), orbitalReferenceFrame, surfaceReferenceFrame)); + connectionManager.getSpaceCenter().transformPosition(vector.toTriplet(), orbitalReferenceFrame, + surfaceReferenceFrame)); } private void setRoverThrottle(double throttle) throws RPCException, StreamException { diff --git a/src/main/java/com/pesterenan/model/ActiveVessel.java b/src/main/java/com/pesterenan/model/ActiveVessel.java index 2e8a221..164fa29 100644 --- a/src/main/java/com/pesterenan/model/ActiveVessel.java +++ b/src/main/java/com/pesterenan/model/ActiveVessel.java @@ -1,19 +1,24 @@ package com.pesterenan.model; -import com.pesterenan.MechPeste; +import java.util.HashMap; +import java.util.Map; + import com.pesterenan.controllers.Controller; +import com.pesterenan.controllers.DockingController; import com.pesterenan.controllers.LandingController; import com.pesterenan.controllers.LiftoffController; import com.pesterenan.controllers.ManeuverController; import com.pesterenan.controllers.RoverController; -import com.pesterenan.controllers.DockingController; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.Module; import com.pesterenan.utils.Telemetry; import com.pesterenan.utils.Vector; + +import krpc.client.Connection; import krpc.client.RPCException; import krpc.client.Stream; import krpc.client.StreamException; +import krpc.client.services.SpaceCenter; import krpc.client.services.SpaceCenter.AutoPilot; import krpc.client.services.SpaceCenter.CelestialBody; import krpc.client.services.SpaceCenter.Flight; @@ -21,15 +26,11 @@ import krpc.client.services.SpaceCenter.Vessel; import krpc.client.services.SpaceCenter.VesselSituation; -import java.util.HashMap; -import java.util.Map; - -import static com.pesterenan.MechPeste.getConnection; -import static com.pesterenan.MechPeste.getSpaceCenter; - public class ActiveVessel { protected Vessel activeVessel; + protected SpaceCenter spaceCenter; + protected Connection connection; private final Map telemetryData = new HashMap<>(); public AutoPilot ap; public Flight flightParameters; @@ -53,31 +54,23 @@ public class ActiveVessel { protected long timer = 0; private String currentStatus = Bundle.getString("status_ready"); private boolean runningModule; - - public ActiveVessel() { + private ConnectionManager connectionManager; + private VesselManager vesselManager; + + public ActiveVessel(ConnectionManager connectionManager, VesselManager vesselManager) { + this.connectionManager = connectionManager; + this.vesselManager = vesselManager; + this.connection = connectionManager.getConnection(); + this.spaceCenter = connectionManager.getSpaceCenter(); initializeParameters(); } - private void initializeParameters() { - try { - setActiveVessel(getSpaceCenter().getActiveVessel()); - currentVesselId = getActiveVessel().hashCode(); - ap = getActiveVessel().getAutoPilot(); - currentBody = getActiveVessel().getOrbit().getBody(); - gravityAcel = currentBody.getSurfaceGravity(); - orbitalReferenceFrame = currentBody.getReferenceFrame(); - surfaceReferenceFrame = getActiveVessel().getSurfaceReferenceFrame(); - flightParameters = getActiveVessel().flight(orbitalReferenceFrame); - totalMass = getConnection().addStream(getActiveVessel(), "getMass"); - altitude = getConnection().addStream(flightParameters, "getMeanAltitude"); - surfaceAltitude = getConnection().addStream(flightParameters, "getSurfaceAltitude"); - apoapsis = getConnection().addStream(getActiveVessel().getOrbit(), "getApoapsisAltitude"); - periapsis = getConnection().addStream(getActiveVessel().getOrbit(), "getPeriapsisAltitude"); - verticalVelocity = getConnection().addStream(flightParameters, "getVerticalSpeed"); - horizontalVelocity = getConnection().addStream(flightParameters, "getHorizontalSpeed"); - } catch (RPCException | StreamException e) { - System.err.println("Error while initializing parameters for active vessel: " + e.getMessage()); - } + public ConnectionManager getConnectionManager() { + return connectionManager; + } + + public VesselManager getVesselManager() { + return vesselManager; } public String getCurrentStatus() { @@ -128,7 +121,7 @@ public void liftoff() { setCurrentStatus(String.format(Bundle.getString("status_launching_in"), count)); Thread.sleep(100); } - getSpaceCenter().setActiveVessel(activeVessel); + spaceCenter.setActiveVessel(activeVessel); getActiveVessel().getControl().activateNextStage(); } setCurrentStatus(Bundle.getString("status_liftoff")); @@ -137,25 +130,6 @@ public void liftoff() { } } - protected void decoupleStage() throws RPCException, InterruptedException { - setCurrentStatus(Bundle.getString("status_separating_stage")); - MechPeste.getSpaceCenter().setActiveVessel(getActiveVessel()); - double currentThrottle = getActiveVessel().getControl().getThrottle(); - throttle(0); - Thread.sleep(1000); - getActiveVessel().getControl().activateNextStage(); - throttleUp(currentThrottle, 1); - } - - protected void throttleUp(double throttleAmount, double seconds) throws RPCException, InterruptedException { - double secondsElapsed = 0; - while (secondsElapsed < seconds) { - throttle(secondsElapsed / seconds * throttleAmount); - secondsElapsed += 0.1; - Thread.sleep(100); - } - } - public double getTWR() throws RPCException, StreamException { return getActiveVessel().getAvailableThrust() / (totalMass.get() * gravityAcel); } @@ -175,24 +149,23 @@ public void startModule(Map commands) { runningModule = false; } if (currentFunction.equals(Module.LIFTOFF.get())) { - controller = new LiftoffController(commands); + controller = new LiftoffController(this.connectionManager, this.vesselManager, commands); runningModule = true; } if (currentFunction.equals(Module.HOVERING.get()) || currentFunction.equals(Module.LANDING.get())) { - controller = new LandingController(commands); + controller = new LandingController(this.connectionManager, this.vesselManager, commands); runningModule = true; } if (currentFunction.equals(Module.MANEUVER.get())) { - controller = new ManeuverController(commands); + controller = new ManeuverController(this.connectionManager, this.vesselManager, commands); runningModule = true; } if (currentFunction.equals(Module.ROVER.get())) { - controller = new RoverController(commands); + controller = new RoverController(this.connectionManager, this.vesselManager, commands); runningModule = true; } if (currentFunction.equals(Module.DOCKING.get())) { - controller = new DockingController(commands); - System.out.println("escolheu modulo docking"); + controller = new DockingController(this.connectionManager, this.vesselManager, commands); runningModule = true; } controllerThread = new Thread(controller, currentVesselId + " - " + currentFunction); @@ -235,4 +208,45 @@ public void cancelControl() { public boolean hasModuleRunning() { return runningModule; } + + protected void decoupleStage() throws RPCException, InterruptedException { + setCurrentStatus(Bundle.getString("status_separating_stage")); + spaceCenter.setActiveVessel(getActiveVessel()); + double currentThrottle = getActiveVessel().getControl().getThrottle(); + throttle(0); + Thread.sleep(1000); + getActiveVessel().getControl().activateNextStage(); + throttleUp(currentThrottle, 1); + } + + protected void throttleUp(double throttleAmount, double seconds) throws RPCException, InterruptedException { + double secondsElapsed = 0; + while (secondsElapsed < seconds) { + throttle(secondsElapsed / seconds * throttleAmount); + secondsElapsed += 0.1; + Thread.sleep(100); + } + } + + private void initializeParameters() { + try { + setActiveVessel(spaceCenter.getActiveVessel()); + currentVesselId = getActiveVessel().hashCode(); + ap = getActiveVessel().getAutoPilot(); + currentBody = getActiveVessel().getOrbit().getBody(); + gravityAcel = currentBody.getSurfaceGravity(); + orbitalReferenceFrame = currentBody.getReferenceFrame(); + surfaceReferenceFrame = getActiveVessel().getSurfaceReferenceFrame(); + flightParameters = getActiveVessel().flight(orbitalReferenceFrame); + totalMass = connection.addStream(getActiveVessel(), "getMass"); + altitude = connection.addStream(flightParameters, "getMeanAltitude"); + surfaceAltitude = connection.addStream(flightParameters, "getSurfaceAltitude"); + apoapsis = connection.addStream(getActiveVessel().getOrbit(), "getApoapsisAltitude"); + periapsis = connection.addStream(getActiveVessel().getOrbit(), "getPeriapsisAltitude"); + verticalVelocity = connection.addStream(flightParameters, "getVerticalSpeed"); + horizontalVelocity = connection.addStream(flightParameters, "getHorizontalSpeed"); + } catch (RPCException | StreamException e) { + System.err.println("Error while initializing parameters for active vessel: " + e.getMessage()); + } + } } diff --git a/src/main/java/com/pesterenan/model/ConnectionManager.java b/src/main/java/com/pesterenan/model/ConnectionManager.java new file mode 100644 index 0000000..89f1337 --- /dev/null +++ b/src/main/java/com/pesterenan/model/ConnectionManager.java @@ -0,0 +1,97 @@ +package com.pesterenan.model; + +import java.io.IOException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.swing.SwingUtilities; + +import com.pesterenan.resources.Bundle; +import com.pesterenan.views.StatusDisplay; + +import krpc.client.Connection; +import krpc.client.RPCException; +import krpc.client.services.KRPC; +import krpc.client.services.SpaceCenter; + +public class ConnectionManager { + private KRPC krpc; + private Connection connection; + private SpaceCenter spaceCenter; + private final StatusDisplay statusDisplay; + private volatile boolean isConnecting = false; + private ScheduledExecutorService connectionScheduler; + + public ConnectionManager(final String connectionName, final StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; + connectAndMonitor(connectionName); + } + + public Connection getConnection() { + return connection; + } + + public SpaceCenter getSpaceCenter() { + return spaceCenter; + } + + public void connectAndMonitor(final String connectionName) { + if (connectionScheduler != null && !connectionScheduler.isShutdown()) { + return; + } + connectionScheduler = Executors.newSingleThreadScheduledExecutor(); + connectionScheduler.scheduleAtFixedRate(() -> { + if (isConnectionAlive() || isConnecting) { + return; + } + + isConnecting = true; + SwingUtilities.invokeLater(() -> { + statusDisplay.setStatusMessage(Bundle.getString("status_connecting")); + statusDisplay.setBtnConnectVisible(false); + }); + + try { + connection = Connection.newInstance(connectionName); + krpc = KRPC.newInstance(getConnection()); + spaceCenter = SpaceCenter.newInstance(getConnection()); + SwingUtilities.invokeLater(() -> { + statusDisplay.setStatusMessage(Bundle.getString("status_connected")); + statusDisplay.setBtnConnectVisible(false); + }); + } catch (final IOException e) { + SwingUtilities.invokeLater(() -> { + statusDisplay.setStatusMessage(Bundle.getString("status_error_connection")); + statusDisplay.setBtnConnectVisible(true); + }); + } finally { + isConnecting = false; + } + }, 0, 5, TimeUnit.SECONDS); + } + + public boolean isConnectionAlive() { + try { + if (krpc == null) + return false; + krpc.getStatus(); + return true; + } catch (final RPCException e) { + return false; + } + } + + public KRPC.GameScene getCurrentGameScene() throws RPCException { + return krpc.getCurrentGameScene(); + } + + public boolean isOnFlightScene() { + try { + return this.getCurrentGameScene().equals(KRPC.GameScene.FLIGHT); + } catch (final RPCException e) { + return false; + } + } + +} diff --git a/src/main/java/com/pesterenan/model/VesselManager.java b/src/main/java/com/pesterenan/model/VesselManager.java new file mode 100644 index 0000000..f581ab3 --- /dev/null +++ b/src/main/java/com/pesterenan/model/VesselManager.java @@ -0,0 +1,208 @@ +package com.pesterenan.model; + +import java.awt.event.ActionEvent; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import javax.swing.DefaultListModel; +import javax.swing.ListModel; +import javax.swing.SwingUtilities; + +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Vector; +import com.pesterenan.views.FunctionsAndTelemetryJPanel; +import com.pesterenan.views.MainGui; +import com.pesterenan.views.StatusDisplay; + +import krpc.client.Connection; +import krpc.client.RPCException; +import krpc.client.services.SpaceCenter; +import krpc.client.services.SpaceCenter.Node; +import krpc.client.services.SpaceCenter.Vessel; + +public class VesselManager { + private ConnectionManager connectionManager; + private ActiveVessel currentVessel; + private int currentVesselId = -1; + private StatusDisplay statusDisplay; + + public VesselManager(ConnectionManager connectionManager, StatusDisplay statusDisplay) { + this.connectionManager = connectionManager; + this.statusDisplay = statusDisplay; + } + + public Connection getConnection() { + return connectionManager.getConnection(); + } + + public SpaceCenter getSpaceCenter() { + return connectionManager.getSpaceCenter(); + } + + public ActiveVessel getCurrentVessel() { + return currentVessel; + } + + public int getCurrentVesselId() { + return currentVesselId; + } + + public void startUpdateLoop() { + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.scheduleAtFixedRate(() -> { + if (getConnection() == null || getSpaceCenter() == null) { + System.out.println("Connection not established yet, skipping update cycle."); + return; + } + try { + if (!connectionManager.isOnFlightScene()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return; + } + checkAndUpdateActiveVessel(); + updateTelemetryData(); + updateUI(); + } catch (RPCException e) { + System.err.println("RPC Error: " + e.getMessage()); + } + }, 0, 250, TimeUnit.MILLISECONDS); + } + + public ListModel getCurrentManeuvers() { + DefaultListModel list = new DefaultListModel<>(); + try { + List maneuvers = this.getSpaceCenter().getActiveVessel().getControl().getNodes(); + maneuvers.forEach(m -> { + try { + String maneuverStr = String.format("%d - Dv: %.1f {P: %.1f, N: %.1f, R: %.1f} AP: %.1f, PE: %.1f", + maneuvers.indexOf(m) + 1, m.getDeltaV(), m.getPrograde(), m.getNormal(), m.getRadial(), + m.getOrbit().getApoapsisAltitude(), m.getOrbit().getPeriapsisAltitude()); + list.addElement(maneuverStr); + } catch (RPCException ignored) { + } + }); + } catch (RPCException | NullPointerException ignored) { + } + return list; + } + + public void startModule(Map commands) { + currentVessel.startModule(commands); + } + + public ListModel getActiveVessels(String search) { + DefaultListModel list = new DefaultListModel<>(); + try { + List vessels = getSpaceCenter().getVessels(); + vessels = vessels.stream().filter(v -> filterVessels(v, search)).collect(Collectors.toList()); + vessels.forEach(v -> { + try { + String vesselName = v.hashCode() + " - \t" + v.getName(); + list.addElement(vesselName); + } catch (RPCException vesselNameError) { + System.err.println("Couldn't add vessel name to list. Error: " + vesselNameError.getMessage()); + } + }); + } catch (RPCException rpcOrNpeException) { + System.err.println("Couldn't get vessel list, Error: " + rpcOrNpeException.getMessage()); + } + return list; + } + + public String getVesselInfo(int selectedIndex) { + try { + Vessel activeVessel = this.getSpaceCenter().getVessels().stream().filter(v -> v.hashCode() == selectedIndex) + .findFirst().get(); + String name = activeVessel.getName().length() > 40 + ? activeVessel.getName().substring(0, 40) + "..." + : activeVessel.getName(); + String vesselInfo = String.format("Nome: %s\t\t\t | Corpo: %s", name, + activeVessel.getOrbit().getBody().getName()); + return vesselInfo; + } catch (RPCException | NullPointerException ignored) { + } + return ""; + } + + public void changeToVessel(int selectedIndex) { + try { + Vessel activeVessel = getSpaceCenter().getVessels().stream().filter(v -> v.hashCode() == selectedIndex) + .findFirst().get(); + getSpaceCenter().setActiveVessel(activeVessel); + } catch (RPCException | NullPointerException e) { + System.out.println(Bundle.getString("status_couldnt_switch_vessel")); + } + } + + public void cancelControl(ActionEvent e) { + currentVessel.cancelControl(); + } + + private void checkAndUpdateActiveVessel() throws RPCException { + Vessel activeVessel = getSpaceCenter().getActiveVessel(); + int activeVesselId = activeVessel.hashCode(); + if (currentVesselId != activeVesselId) { + currentVessel = new ActiveVessel(connectionManager, this); + currentVesselId = currentVessel.getCurrentVesselId(); + MainGui.getInstance().setVesselManager(this); + } + } + + private void updateTelemetryData() { + if (currentVesselId == -1 || currentVessel == null) + return; + try { + currentVessel.recordTelemetryData(); + } catch (RPCException e) { + System.err.println("Error while recording telemetry: " + e.getMessage()); + currentVessel = null; + currentVesselId = -1; + } + } + + private void updateUI() { + SwingUtilities.invokeLater(() -> { + if (currentVessel != null) { + FunctionsAndTelemetryJPanel.updateTelemetry(currentVessel.getTelemetryData()); + MainGui.getInstance().getCreateManeuverPanel().updatePanel(getCurrentManeuvers()); + if (currentVessel.hasModuleRunning()) { + statusDisplay.setStatusMessage(currentVessel.getCurrentStatus()); + } + } + }); + } + + private boolean filterVessels(Vessel vessel, String search) { + if ("all".equals(search)) { + return true; + } + double TEN_KILOMETERS = 10000.0; + try { + Vessel active = this.getSpaceCenter().getActiveVessel(); + if (vessel.getOrbit().getBody().getName().equals(active.getOrbit().getBody().getName())) { + final Vector activePos = new Vector(active.position(active.getSurfaceReferenceFrame())); + final Vector vesselPos = new Vector(vessel.position(active.getSurfaceReferenceFrame())); + final double distance = Vector.distance(activePos, vesselPos); + switch (search) { + case "closest": + if (distance < TEN_KILOMETERS) { + return true; + } + break; + case "samebody": + return true; + } + } + } catch (RPCException ignored) { + } + return false; + } +} diff --git a/src/main/java/com/pesterenan/utils/Module.java b/src/main/java/com/pesterenan/utils/Module.java index 2a6b5cd..fcd7ebe 100644 --- a/src/main/java/com/pesterenan/utils/Module.java +++ b/src/main/java/com/pesterenan/utils/Module.java @@ -2,36 +2,56 @@ public enum Module { - ADJUST("Ajustar"), APOAPSIS("Apoastro"), CIRCULAR("Circular"), CREATE_MANEUVER("CRIAR_MANOBRAS"), CUBIC( - "Cúbica"), DIRECTION("Direção"), DOCKING("DOCKING"), EXECUTE("Executar"), EXPONENCIAL( - "Exponencial"), FINE_ADJUST("Ajuste Fino"), FUNCTION("Função"), HOVERING( - "HOVER"), HOVER_AFTER_LANDING("SOBREVOO PÓS POUSO"), HOVER_ALTITUDE( - "Altitude Sobrevoo"), INCLINATION("Inclinação"), LAND("Pousar nave"), LANDING( - "LANDING"), LIFTOFF("LIFTOFF"), LOW_ORBIT("ÓRBITA BAIXA"), MANEUVER( - "MANEUVER"), MAP_MARKER("Marcador no mapa"), MARKER_NAME( - "Nome do marcador"), MAX_SPEED( - "Velocidade Máxima"), MAX_TWR("Max_TWR"), MODULO( - "Módulo"), OPEN_PANELS( - "Abrir Painéis"), PERIAPSIS( - "Periastro"), QUADRATIC( - "Quadrática"), RENDEZVOUS( - "Rendezvous"), ROLL( - "Rolagem"), ROVER( - "ROVER"), ROVER_TARGET_TYPE( - "Tipo de Alvo do Rover"), SAFE_DISTANCE( - "Distância Segura"), SINUSOIDAL( - "Sinusoidal"), STAGE( - "Usar Estágios"), TARGET_VESSEL( - "Nave alvo"), TELEMETRY( - "TELEMETRY"); + ADJUST("Ajustar"), APOAPSIS("Apoastro"), CIRCULAR("Circular"), CREATE_MANEUVER("CRIAR_MANOBRAS"), CUBIC( + "Cúbica"), + DIRECTION("Direção"), DOCKING("DOCKING"), EXECUTE("Executar"), EXPONENCIAL( + "Exponencial"), + FINE_ADJUST("Ajuste Fino"), FUNCTION("Função"), HOVERING( + "HOVER"), + HOVER_AFTER_LANDING("SOBREVOO PÓS POUSO"), HOVER_ALTITUDE( + "Altitude Sobrevoo"), + INCLINATION("Inclinação"), LAND("Pousar nave"), LANDING( + "LANDING"), + LIFTOFF("LIFTOFF"), LOW_ORBIT("ÓRBITA BAIXA"), MANEUVER( + "MANEUVER"), + MAP_MARKER("Marcador no mapa"), MARKER_NAME( + "Nome do marcador"), + MAX_SPEED( + "Velocidade Máxima"), + MAX_TWR("Max_TWR"), MODULO( + "Módulo"), + OPEN_PANELS( + "Abrir Painéis"), + PERIAPSIS( + "Periastro"), + QUADRATIC( + "Quadrática"), + RENDEZVOUS( + "Rendezvous"), + ROLL( + "Rolagem"), + ROVER( + "ROVER"), + ROVER_TARGET_TYPE( + "Tipo de Alvo do Rover"), + SAFE_DISTANCE( + "Distância Segura"), + SINUSOIDAL( + "Sinusoidal"), + STAGE( + "Usar Estágios"), + TARGET_VESSEL( + "Nave alvo"), + TELEMETRY( + "TELEMETRY"); - final String t; + final String t; - Module(String t) { - this.t = t; - } + Module(String t) { + this.t = t; + } - public String get() { - return this.t; - } + public String get() { + return this.t; + } } diff --git a/src/main/java/com/pesterenan/utils/Navigation.java b/src/main/java/com/pesterenan/utils/Navigation.java index 9e8792d..5294880 100644 --- a/src/main/java/com/pesterenan/utils/Navigation.java +++ b/src/main/java/com/pesterenan/utils/Navigation.java @@ -5,8 +5,8 @@ import krpc.client.StreamException; import org.javatuples.Triplet; -import static com.pesterenan.MechPeste.getConnection; -import static com.pesterenan.MechPeste.getSpaceCenter; +import com.pesterenan.model.ConnectionManager; + import static krpc.client.services.SpaceCenter.*; public class Navigation { @@ -22,8 +22,10 @@ public class Navigation { private Flight flightParameters; private Stream horizontalSpeed; private ReferenceFrame orbitalReference; + private ConnectionManager connectionManager; - public Navigation(Vessel currentVessel) { + public Navigation(ConnectionManager connectionManager, Vessel currentVessel) { + this.connectionManager = connectionManager; this.currentVessel = currentVessel; initializeParameters(); } @@ -33,21 +35,23 @@ private void initializeParameters() { // drawing = Drawing.newInstance(getConexao()); orbitalReference = currentVessel.getOrbit().getBody().getReferenceFrame(); flightParameters = currentVessel.flight(orbitalReference); - horizontalSpeed = getConnection().addStream(flightParameters, "getHorizontalSpeed"); + horizontalSpeed = connectionManager.getConnection().addStream(flightParameters, "getHorizontalSpeed"); } catch (RPCException | StreamException ignored) { } } public void aimAtManeuver(Node maneuver) throws RPCException { - aimAtDirection(getSpaceCenter().transformDirection(PROGRADE, maneuver.getReferenceFrame(), orbitalReference)); + aimAtDirection(connectionManager.getSpaceCenter().transformDirection(PROGRADE, maneuver.getReferenceFrame(), + orbitalReference)); } public void aimForLanding() throws RPCException, StreamException { Vector currentPosition = new Vector(currentVessel.position(orbitalReference)); - Vector retrograde = new Vector(getSpaceCenter().transformPosition(RETROGRADE, + Vector retrograde = new Vector(connectionManager.getSpaceCenter().transformPosition(RETROGRADE, currentVessel.getSurfaceVelocityReferenceFrame(), orbitalReference)).subtract(currentPosition); - Vector radial = new Vector(getSpaceCenter().transformDirection(RADIAL, currentVessel.getSurfaceReferenceFrame(), - orbitalReference)); + Vector radial = new Vector( + connectionManager.getSpaceCenter().transformDirection(RADIAL, currentVessel.getSurfaceReferenceFrame(), + orbitalReference)); double angleLimit = Utilities.remap(0, 10, 0, 0.9, horizontalSpeed.get(), true); Vector landingVector = Utilities.linearInterpolation(radial, retrograde, angleLimit); aimAtDirection(landingVector.toTriplet()); @@ -132,17 +136,20 @@ public void aimForLanding() throws RPCException, StreamException { // } public void aimAtPrograde() throws RPCException { - aimAtDirection(getSpaceCenter().transformDirection(PROGRADE, currentVessel.getSurfaceVelocityReferenceFrame(), + aimAtDirection(connectionManager.getSpaceCenter().transformDirection(PROGRADE, + currentVessel.getSurfaceVelocityReferenceFrame(), orbitalReference)); } public void aimAtRadialOut() throws RPCException { - aimAtDirection(getSpaceCenter().transformDirection(RADIAL, currentVessel.getSurfaceReferenceFrame(), - orbitalReference)); + aimAtDirection( + connectionManager.getSpaceCenter().transformDirection(RADIAL, currentVessel.getSurfaceReferenceFrame(), + orbitalReference)); } public void aimAtRetrograde() throws RPCException { - aimAtDirection(getSpaceCenter().transformDirection(RETROGRADE, currentVessel.getSurfaceVelocityReferenceFrame(), + aimAtDirection(connectionManager.getSpaceCenter().transformDirection(RETROGRADE, + currentVessel.getSurfaceVelocityReferenceFrame(), orbitalReference)); } diff --git a/src/main/java/com/pesterenan/utils/PathFinding.java b/src/main/java/com/pesterenan/utils/PathFinding.java index f55510f..8dd1a3f 100644 --- a/src/main/java/com/pesterenan/utils/PathFinding.java +++ b/src/main/java/com/pesterenan/utils/PathFinding.java @@ -1,6 +1,9 @@ package com.pesterenan.utils; import com.pesterenan.controllers.Controller; +import com.pesterenan.model.ConnectionManager; +import com.pesterenan.model.VesselManager; + import krpc.client.RPCException; import krpc.client.services.Drawing; import krpc.client.services.SpaceCenter; @@ -15,9 +18,6 @@ import java.util.List; import java.util.stream.Collectors; -import static com.pesterenan.MechPeste.getConnection; -import static com.pesterenan.MechPeste.getSpaceCenter; - public class PathFinding extends Controller { private WaypointManager waypointManager; @@ -27,17 +27,17 @@ public class PathFinding extends Controller { private Drawing drawing; private Drawing.Polygon polygonPath; - public PathFinding() { - super(); + public PathFinding(ConnectionManager connectionManager, VesselManager vesselManager) { + super(connectionManager, vesselManager); initializeParameters(); } private void initializeParameters() { try { - waypointManager = getSpaceCenter().getWaypointManager(); + waypointManager = getConnectionManager().getSpaceCenter().getWaypointManager(); waypointsToReach = new ArrayList<>(); pathToTarget = new ArrayList<>(); - drawing = Drawing.newInstance(getConnection()); + drawing = Drawing.newInstance(getConnectionManager().getConnection()); } catch (RPCException ignored) { } } @@ -194,7 +194,8 @@ private Vector calculateNextPoint(Vector currentPoint, Vector targetDirection) t public double raycastDistance(Vector currentPoint, Vector targetDirection, SpaceCenter.ReferenceFrame reference, double searchDistance) throws RPCException { return Math.min( - getSpaceCenter().raycastDistance(currentPoint.toTriplet(), targetDirection.toTriplet(), reference), + getConnectionManager().getSpaceCenter().raycastDistance(currentPoint.toTriplet(), + targetDirection.toTriplet(), reference), searchDistance); } @@ -206,11 +207,13 @@ private Vector getPosOnSurface(Vector vector) throws RPCException { private Vector transformSurfToOrb(Vector vector) throws IOException, RPCException { return new Vector( - getSpaceCenter().transformPosition(vector.toTriplet(), surfaceReferenceFrame, orbitalReferenceFrame)); + getConnectionManager().getSpaceCenter().transformPosition(vector.toTriplet(), surfaceReferenceFrame, + orbitalReferenceFrame)); } private Vector transformOrbToSurf(Vector vector) throws IOException, RPCException { return new Vector( - getSpaceCenter().transformPosition(vector.toTriplet(), orbitalReferenceFrame, surfaceReferenceFrame)); + getConnectionManager().getSpaceCenter().transformPosition(vector.toTriplet(), orbitalReferenceFrame, + surfaceReferenceFrame)); } } diff --git a/src/main/java/com/pesterenan/views/ChangeVesselDialog.java b/src/main/java/com/pesterenan/views/ChangeVesselDialog.java index 188801c..328ae06 100644 --- a/src/main/java/com/pesterenan/views/ChangeVesselDialog.java +++ b/src/main/java/com/pesterenan/views/ChangeVesselDialog.java @@ -1,13 +1,24 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; + +import java.awt.event.ActionEvent; -import javax.swing.*; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionEvent; -import java.awt.event.ActionEvent; -import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import com.pesterenan.model.VesselManager; public class ChangeVesselDialog extends JDialog implements UIMethods { @@ -16,8 +27,10 @@ public class ChangeVesselDialog extends JDialog implements UIMethods { private JList listActiveVessels; private JButton btnChangeToVessel; private JRadioButton rbClosestVessels, rbOnSameBody, rbAllVessels; + private VesselManager vesselManager; - public ChangeVesselDialog() { + public ChangeVesselDialog(VesselManager vesselManager) { + this.vesselManager = vesselManager; initComponents(); setupComponents(); layoutComponents(); @@ -36,7 +49,7 @@ public void initComponents() { rbAllVessels = new JRadioButton("Todas as naves"); // Misc: - listActiveVessels = new JList<>(MechPeste.getActiveVessels("closest")); + listActiveVessels = new JList<>(vesselManager.getActiveVessels("closest")); listActiveVessels.setToolTipText("Aqui são mostradas as naves próximas de acordo com o filtro da esquerda."); } @@ -132,11 +145,11 @@ protected void handleChangeToVessel(ActionEvent e) { return; } int vesselHashCode = Integer.parseInt(listActiveVessels.getSelectedValue().split(" - ")[0]); - MechPeste.changeToVessel(vesselHashCode); + vesselManager.changeToVessel(vesselHashCode); } protected void handleBuildVesselList(ActionEvent e) { - listActiveVessels.setModel(MechPeste.getActiveVessels(e.getActionCommand())); + listActiveVessels.setModel(vesselManager.getActiveVessels(e.getActionCommand())); } protected void handleListActiveVesselsValueChanged(ListSelectionEvent e) { @@ -147,7 +160,7 @@ protected void handleListActiveVesselsValueChanged(ListSelectionEvent e) { return; } int vesselId = Integer.parseInt(selectedValue.split(" - ")[0]); - lblVesselStatus.setText(MechPeste.getVesselInfo(vesselId)); + lblVesselStatus.setText(vesselManager.getVesselInfo(vesselId)); btnChangeToVessel.setEnabled(true); } } diff --git a/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java b/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java index a47af7e..8fc1eab 100644 --- a/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java +++ b/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java @@ -1,6 +1,35 @@ package com.pesterenan.views; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JSlider; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import javax.swing.border.TitledBorder; + import com.pesterenan.MechPeste; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.ControlePID; @@ -10,22 +39,6 @@ import krpc.client.services.SpaceCenter.Vessel; import krpc.client.services.SpaceCenter.VesselSituation; -import javax.swing.*; -import javax.swing.border.TitledBorder; - -import org.javatuples.Pair; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Locale; -import java.util.Map; - -import static com.pesterenan.views.MainGui.PNL_DIMENSION; -import static com.pesterenan.views.MainGui.BTN_DIMENSION; - public class CreateManeuverJPanel extends JPanel implements ActionListener, UIMethods { private static JLabel lblManeuverInfo; @@ -38,13 +51,20 @@ public class CreateManeuverJPanel extends JPanel implements ActionListener, UIMe private static ButtonGroup bgManeuverType; private static Map sliderValues = new HashMap<>(); private final ControlePID ctrlManeuver = new ControlePID(); + private VesselManager vesselManager; + private StatusDisplay statusDisplay; - public CreateManeuverJPanel() { + public CreateManeuverJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + } + @Override public void initComponents() { // Labels: @@ -277,10 +297,10 @@ public void layoutComponents() { add(pnlBackButton, BorderLayout.SOUTH); } - public static void updatePanel(ListModel list) { + public void updatePanel(ListModel list) { try { boolean hasManeuverNodes = list.getSize() > 0; - boolean hasTargetVessel = MechPeste.getSpaceCenter().getTargetVessel() != null; + boolean hasTargetVessel = vesselManager.getSpaceCenter().getTargetVessel() != null; listCurrentManeuvers.setModel(list); listCurrentManeuvers.setSelectedIndex(selectedManeuverIndex); btnDeleteManeuver.setEnabled(hasManeuverNodes); @@ -305,20 +325,19 @@ private static void handleChangeButtonText(int value) { btnDecrease.setText("- " + formattedValue + suffix); } - private void createManeuver() { + public void createManeuver() { try { - createManeuver(MechPeste.getSpaceCenter().getUT() + 60); + createManeuver(vesselManager.getSpaceCenter().getUT() + 60); } catch (RPCException e) { } } - private void createManeuver(double atFutureTime) { + public void createManeuver(double atFutureTime) { try { - MechPeste.newInstance(); - Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel(); + Vessel vessel = vesselManager.getSpaceCenter().getActiveVessel(); if (vessel.getSituation() != VesselSituation.ORBITING) { - StatusJPanel.setStatusMessage("Não é possível criar a manobra fora de órbita."); + statusDisplay.setStatusMessage("Não é possível criar a manobra fora de órbita."); return; } vessel.getControl().addNode(atFutureTime, 0, 0, 0); @@ -329,35 +348,34 @@ private void createManeuver(double atFutureTime) { private void deleteManeuver() { try { MechPeste.newInstance(); - Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel(); + Vessel vessel = vesselManager.getSpaceCenter().getActiveVessel(); Node currentManeuver = vessel.getControl().getNodes().get(selectedManeuverIndex); currentManeuver.remove(); } catch (Exception e) { } } - private void positionManeuverAt(String node) { + public void positionManeuverAt(String node) { try { - MechPeste.newInstance(); - Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel(); + Vessel vessel = vesselManager.getSpaceCenter().getActiveVessel(); Orbit orbit = vessel.getOrbit(); Node currentManeuver = vessel.getControl().getNodes().get(selectedManeuverIndex); double timeToNode = 0; switch (node) { case "apoapsis" : - timeToNode = MechPeste.getSpaceCenter().getUT() + orbit.getTimeToApoapsis(); + timeToNode = vesselManager.getSpaceCenter().getUT() + orbit.getTimeToApoapsis(); break; case "periapsis" : - timeToNode = MechPeste.getSpaceCenter().getUT() + orbit.getTimeToPeriapsis(); + timeToNode = vesselManager.getSpaceCenter().getUT() + orbit.getTimeToPeriapsis(); break; case "ascending" : double ascendingAnomaly = orbit - .trueAnomalyAtAN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit()); + .trueAnomalyAtAN(vesselManager.getSpaceCenter().getTargetVessel().getOrbit()); timeToNode = orbit.uTAtTrueAnomaly(ascendingAnomaly); break; case "descending" : double descendingAnomaly = orbit - .trueAnomalyAtDN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit()); + .trueAnomalyAtDN(vesselManager.getSpaceCenter().getTargetVessel().getOrbit()); timeToNode = orbit.uTAtTrueAnomaly(descendingAnomaly); break; } @@ -371,8 +389,7 @@ private void positionManeuverAt(String node) { private void changeManeuverDeltaV(String command) { try { - MechPeste.newInstance(); - Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel(); + Vessel vessel = vesselManager.getSpaceCenter().getActiveVessel(); Node currentManeuver = vessel.getControl().getNodes().get(selectedManeuverIndex); String maneuverType = bgManeuverType.getSelection().getActionCommand(); float currentSliderValue = sliderValues.get(sldScale.getValue()); @@ -402,16 +419,17 @@ private void changeManeuverDeltaV(String command) { private void changeOrbit(String command) { try { - MechPeste.newInstance(); Vessel vessel; - vessel = MechPeste.getSpaceCenter().getActiveVessel(); + vessel = vesselManager.getSpaceCenter().getActiveVessel(); Node currentManeuver = vessel.getControl().getNodes().get(selectedManeuverIndex); double currentOrbitPeriod = vessel.getOrbit().getPeriod(); if (command == "next_orbit") { currentManeuver.setUT(currentManeuver.getUT() + currentOrbitPeriod); } else { double newUT = currentManeuver.getUT() - currentOrbitPeriod; - newUT = newUT < MechPeste.getSpaceCenter().getUT() ? MechPeste.getSpaceCenter().getUT() + 60 : newUT; + newUT = newUT < vesselManager.getSpaceCenter().getUT() + ? vesselManager.getSpaceCenter().getUT() + 60 + : newUT; currentManeuver.setUT(newUT); } } catch (RPCException ignored) { diff --git a/src/main/java/com/pesterenan/views/DockingJPanel.java b/src/main/java/com/pesterenan/views/DockingJPanel.java index 151c929..7224f73 100644 --- a/src/main/java/com/pesterenan/views/DockingJPanel.java +++ b/src/main/java/com/pesterenan/views/DockingJPanel.java @@ -1,19 +1,26 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Module; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; -import javax.swing.*; -import javax.swing.border.TitledBorder; -import java.awt.*; +import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; -import static com.pesterenan.views.MainGui.BTN_DIMENSION; -import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; -import static com.pesterenan.views.MainGui.PNL_DIMENSION; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.border.TitledBorder; + +import com.pesterenan.model.VesselManager; +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Module; public class DockingJPanel extends JPanel implements UIMethods { @@ -25,12 +32,21 @@ public class DockingJPanel extends JPanel implements UIMethods { private JTextField txfMaxSpeed, txfSafeDistance; private JButton btnBack, btnStartDocking; - public DockingJPanel() { + private VesselManager vesselManager; + + private StatusDisplay statusDisplay; + + public DockingJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + } + @Override public void initComponents() { // Labels: @@ -130,25 +146,25 @@ private void handleStartDocking(ActionEvent e) { commands.put(Module.MODULO.get(), Module.DOCKING.get()); commands.put(Module.SAFE_DISTANCE.get(), txfSafeDistance.getText()); commands.put(Module.MAX_SPEED.get(), txfMaxSpeed.getText()); - MechPeste.newInstance().startModule(commands); + vesselManager.startModule(commands); } } private boolean validateTextFields() { try { if (Float.parseFloat(txfMaxSpeed.getText()) > 10) { - StatusJPanel.setStatusMessage("Velocidade de acoplagem muito alta. Tem que ser menor que 10m/s."); + statusDisplay.setStatusMessage("Velocidade de acoplagem muito alta. Tem que ser menor que 10m/s."); return false; } if (Float.parseFloat(txfSafeDistance.getText()) > 200) { - StatusJPanel.setStatusMessage("Distância segura muito alta. Tem que ser menor que 200m."); + statusDisplay.setStatusMessage("Distância segura muito alta. Tem que ser menor que 200m."); return false; } } catch (NumberFormatException e) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_lift_stat_only_numbers")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_lift_stat_only_numbers")); return false; } catch (IllegalArgumentException e) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_rover_waypoint_name_not_empty")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_rover_waypoint_name_not_empty")); return false; } return true; diff --git a/src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java b/src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java index 816b06a..b6593bd 100644 --- a/src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java +++ b/src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java @@ -1,20 +1,25 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Module; -import com.pesterenan.utils.Telemetry; -import com.pesterenan.utils.Utilities; - -import javax.swing.*; -import javax.swing.border.TitledBorder; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.util.Map; -import static com.pesterenan.views.MainGui.PNL_DIMENSION; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.TitledBorder; + +import com.pesterenan.MechPeste; +import com.pesterenan.model.VesselManager; +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Module; +import com.pesterenan.utils.Telemetry; +import com.pesterenan.utils.Utilities; public class FunctionsAndTelemetryJPanel extends JPanel implements UIMethods { @@ -26,12 +31,22 @@ public class FunctionsAndTelemetryJPanel extends JPanel implements UIMethods { private static JLabel lblAltitudeValue, lblSurfaceAltValue, lblApoapsisValue; private static JLabel lblPeriapsisValue, lblVertSpeedValue, lblHorzSpeedValue; - public FunctionsAndTelemetryJPanel() { + private VesselManager vesselManager; + + private StatusDisplay statusDisplay; + + public FunctionsAndTelemetryJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + btnCancel.setEnabled(true); + } + @Override public void initComponents() { // Labels: @@ -65,9 +80,10 @@ public void setupComponents() { setLayout(new BorderLayout()); // Setting up components: - btnCancel.addActionListener(MechPeste::cancelControl); + btnCancel.addActionListener(e -> cancelCurrentAction(e)); btnCancel.setMaximumSize(btnFuncDimension); btnCancel.setPreferredSize(btnFuncDimension); + btnCancel.setEnabled(false); btnLanding.addActionListener(this::changeFunctionPanel); btnLanding.setActionCommand(Module.LANDING.get()); btnLanding.setMaximumSize(btnFuncDimension); @@ -90,6 +106,11 @@ public void setupComponents() { btnDocking.setPreferredSize(btnFuncDimension); } + private void cancelCurrentAction(ActionEvent e) { + statusDisplay.setStatusMessage("Canceling current action..."); + vesselManager.cancelControl(e); + } + @Override public void layoutComponents() { @@ -172,22 +193,22 @@ public static void updateTelemetry(Map telemetryData) { synchronized (telemetryData) { for (Telemetry key : telemetryData.keySet()) { switch (key) { - case ALTITUDE : + case ALTITUDE: lblAltitudeValue.setText(Utilities.convertToMetersMagnitudes(telemetryData.get(key))); break; - case ALT_SURF : + case ALT_SURF: lblSurfaceAltValue.setText(Utilities.convertToMetersMagnitudes(telemetryData.get(key))); break; - case APOAPSIS : + case APOAPSIS: lblApoapsisValue.setText(Utilities.convertToMetersMagnitudes(telemetryData.get(key))); break; - case PERIAPSIS : + case PERIAPSIS: lblPeriapsisValue.setText(Utilities.convertToMetersMagnitudes(telemetryData.get(key))); break; - case VERT_SPEED : + case VERT_SPEED: lblVertSpeedValue.setText(Utilities.convertToMetersMagnitudes(telemetryData.get(key)) + "/s"); break; - case HORZ_SPEED : + case HORZ_SPEED: lblHorzSpeedValue.setText(Utilities.convertToMetersMagnitudes(telemetryData.get(key)) + "/s"); break; } diff --git a/src/main/java/com/pesterenan/views/LandingJPanel.java b/src/main/java/com/pesterenan/views/LandingJPanel.java index a547286..3ae167f 100644 --- a/src/main/java/com/pesterenan/views/LandingJPanel.java +++ b/src/main/java/com/pesterenan/views/LandingJPanel.java @@ -1,21 +1,30 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Module; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; -import javax.swing.*; -import javax.swing.border.Border; -import javax.swing.border.EtchedBorder; -import javax.swing.border.TitledBorder; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; -import static com.pesterenan.views.MainGui.BTN_DIMENSION; -import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; -import static com.pesterenan.views.MainGui.PNL_DIMENSION; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.Border; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import com.pesterenan.model.VesselManager; +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Module; public class LandingJPanel extends JPanel implements UIMethods { private static final long serialVersionUID = 1L; @@ -23,13 +32,21 @@ public class LandingJPanel extends JPanel implements UIMethods { private JTextField txfHover, txfMaxTWR; private JButton btnHover, btnAutoLanding, btnBack; private JCheckBox chkHoverAfterLanding; + private VesselManager vesselManager; + + private StatusDisplay statusDisplay; - public LandingJPanel() { + public LandingJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + } + @Override public void initComponents() { // Labels: @@ -140,6 +157,10 @@ public void layoutComponents() { } private void handleLandingAction(ActionEvent e) { + if (vesselManager == null) { + statusDisplay.setStatusMessage("Conexão não estabelecida ao pousar."); + return; + } try { Map commands = new HashMap<>(); commands.put(Module.MODULO.get(), e.getActionCommand()); @@ -147,13 +168,13 @@ private void handleLandingAction(ActionEvent e) { commands.put(Module.HOVER_ALTITUDE.get(), txfHover.getText()); commands.put(Module.MAX_TWR.get(), txfMaxTWR.getText()); commands.put(Module.HOVER_AFTER_LANDING.get(), String.valueOf(chkHoverAfterLanding.isSelected())); - MechPeste.newInstance().startModule(commands); + vesselManager.startModule(commands); MainGui.backToTelemetry(e); chkHoverAfterLanding.setSelected(false); } catch (NumberFormatException nfe) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_land_hover_alt_err")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_land_hover_alt_err")); } catch (NullPointerException npe) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_land_hover_alt")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_land_hover_alt")); } } diff --git a/src/main/java/com/pesterenan/views/LiftoffJPanel.java b/src/main/java/com/pesterenan/views/LiftoffJPanel.java index b7b0e10..672d929 100644 --- a/src/main/java/com/pesterenan/views/LiftoffJPanel.java +++ b/src/main/java/com/pesterenan/views/LiftoffJPanel.java @@ -1,19 +1,31 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Module; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; -import javax.swing.*; -import javax.swing.border.TitledBorder; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; -import static com.pesterenan.views.MainGui.BTN_DIMENSION; -import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; -import static com.pesterenan.views.MainGui.PNL_DIMENSION; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; + +import com.pesterenan.model.VesselManager; +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Module; public class LiftoffJPanel extends JPanel implements UIMethods { @@ -25,13 +37,22 @@ public class LiftoffJPanel extends JPanel implements UIMethods { private JComboBox cbGravityCurveModel; private JSlider sldRoll; private JCheckBox chkOpenPanels, chkDecoupleStages; + private VesselManager vesselManager; - public LiftoffJPanel() { + private StatusDisplay statusDisplay; + + public LiftoffJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + btnLiftoff.setEnabled(true); + } + @Override public void initComponents() { // Labels: @@ -50,6 +71,7 @@ public void initComponents() { // Buttons: btnLiftoff = new JButton(Bundle.getString("pnl_lift_btn_liftoff")); + btnLiftoff.setEnabled(false); btnBack = new JButton(Bundle.getString("pnl_lift_btn_back")); // Checkboxes: @@ -190,13 +212,17 @@ private boolean validateTextFields() { Float.parseFloat(txfHeading.getText()); Float.parseFloat(txfLimitTWR.getText()); } catch (NumberFormatException e) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_lift_stat_only_numbers")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_lift_stat_only_numbers")); return false; } return true; } private void handleLiftoff(ActionEvent e) { + if (vesselManager == null) { + statusDisplay.setStatusMessage("Conexão não estabelecida."); + return; + } if (validateTextFields()) { Map commands = new HashMap<>(); commands.put(Module.MODULO.get(), Module.LIFTOFF.get()); @@ -207,7 +233,7 @@ private void handleLiftoff(ActionEvent e) { commands.put(Module.INCLINATION.get(), cbGravityCurveModel.getSelectedItem().toString()); commands.put(Module.STAGE.get(), String.valueOf(chkDecoupleStages.isSelected())); commands.put(Module.OPEN_PANELS.get(), String.valueOf(chkOpenPanels.isSelected())); - MechPeste.newInstance().startModule(commands); + vesselManager.startModule(commands); MainGui.backToTelemetry(e); } } diff --git a/src/main/java/com/pesterenan/views/MainGui.java b/src/main/java/com/pesterenan/views/MainGui.java index fa79424..6baf6b4 100644 --- a/src/main/java/com/pesterenan/views/MainGui.java +++ b/src/main/java/com/pesterenan/views/MainGui.java @@ -1,51 +1,138 @@ package com.pesterenan.views; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Module; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; -import javax.swing.*; +import javax.swing.Box; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.JTabbedPane; +import javax.swing.UIManager; import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import com.pesterenan.model.VesselManager; +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Module; public class MainGui extends JFrame implements ActionListener, UIMethods { private static final long serialVersionUID = 1L; - private final Dimension APP_DIMENSION = new Dimension(480, 300); public static final Dimension PNL_DIMENSION = new Dimension(464, 216); public static final Dimension BTN_DIMENSION = new Dimension(110, 25); public static final EmptyBorder MARGIN_BORDER_10_PX_LR = new EmptyBorder(0, 10, 0, 10); - private static MainGui mainGui = null; - private static StatusJPanel pnlStatus; - private static FunctionsAndTelemetryJPanel pnlFunctionsAndTelemetry; - private final JPanel ctpMainGui = new JPanel(); + private static MainGui instance = null; + private final static JPanel cardJPanels = new JPanel(); + + private final static CardLayout cardLayout = new CardLayout(0, 0); + + public static MainGui getInstance() { + return instance; + } + + public static MainGui newInstance() { + if (instance == null) { + instance = new MainGui(); + } + return instance; + } + + public static Rectangle centerDialogOnScreen() { + Dimension SCREEN_DIMENSIONS = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension DIALOG_DIMENSIONS = new Dimension(400, 240); + int w = DIALOG_DIMENSIONS.width; + int h = DIALOG_DIMENSIONS.height; + int x = (SCREEN_DIMENSIONS.width - w) / 2; + int y = (SCREEN_DIMENSIONS.height - h) / 2; + return new Rectangle(x, y, w, h); + } + + public static JPanel getCardJPanels() { + return cardJPanels; + } + + public static void changeToPage(ActionEvent e) { + cardLayout.show(cardJPanels, e.getActionCommand()); + } + + public static void backToTelemetry(ActionEvent e) { + cardLayout.show(cardJPanels, Module.TELEMETRY.get()); + } + + public static Component createMarginComponent(int width, int height) { + Component marginComp = Box.createRigidArea(new Dimension(width, height)); + return marginComp; + } + + private FunctionsAndTelemetryJPanel pnlFunctionsAndTelemetry; + + private StatusJPanel pnlStatus; + + private final Dimension APP_DIMENSION = new Dimension(480, 300); + + private final JPanel ctpMainGui = new JPanel(); + private JMenuBar menuBar; private JMenu mnFile, mnOptions, mnHelp; private JMenuItem mntmInstallKrpc, mntmExit, mntmChangeVessels, mntmAbout; - - private final static CardLayout cardLayout = new CardLayout(0, 0); private LiftoffJPanel pnlLiftoff; private LandingJPanel pnlLanding; + private CreateManeuverJPanel pnlCreateManeuvers; + private RunManeuverJPanel pnlRunManeuvers; + private RoverJPanel pnlRover; + private DockingJPanel pnlDocking; + private VesselManager vesselManager; private MainGui() { initComponents(); setupComponents(); layoutComponents(); } - public static MainGui newInstance() { - if (mainGui == null) { - mainGui = new MainGui(); - } - return mainGui; + public FunctionsAndTelemetryJPanel getFunctionsAndTelemetryPanel() { + return pnlFunctionsAndTelemetry; + } + + public StatusJPanel getStatusPanel() { + return pnlStatus; + } + + public LiftoffJPanel getLiftoffPanel() { + return pnlLiftoff; + } + + public LandingJPanel getLandingPanel() { + return pnlLanding; + } + + public CreateManeuverJPanel getCreateManeuverPanel() { + return pnlCreateManeuvers; + } + + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + pnlFunctionsAndTelemetry.setVesselManager(vesselManager); + pnlDocking.setVesselManager(vesselManager); + pnlRover.setVesselManager(vesselManager); + pnlLiftoff.setVesselManager(vesselManager); + pnlLanding.setVesselManager(vesselManager); + pnlCreateManeuvers.setVesselManager(vesselManager); + pnlRunManeuvers.setVesselManager(vesselManager); } @Override @@ -70,14 +157,14 @@ public void initComponents() { mntmAbout = new JMenuItem(Bundle.getString("main_mntm_about")); // Panels - pnlFunctionsAndTelemetry = new FunctionsAndTelemetryJPanel(); - pnlLiftoff = new LiftoffJPanel(); - pnlLanding = new LandingJPanel(); - pnlCreateManeuvers = new CreateManeuverJPanel(); - pnlRunManeuvers = new RunManeuverJPanel(); - pnlRover = new RoverJPanel(); - pnlDocking = new DockingJPanel(); pnlStatus = new StatusJPanel(); + pnlFunctionsAndTelemetry = new FunctionsAndTelemetryJPanel(getStatusPanel()); + pnlLiftoff = new LiftoffJPanel(getStatusPanel()); + pnlLanding = new LandingJPanel(getStatusPanel()); + pnlCreateManeuvers = new CreateManeuverJPanel(getStatusPanel()); + pnlRunManeuvers = new RunManeuverJPanel(getStatusPanel()); + pnlRover = new RoverJPanel(getStatusPanel()); + pnlDocking = new DockingJPanel(getStatusPanel()); } @Override @@ -150,10 +237,6 @@ public void actionPerformed(ActionEvent e) { } } - private void handleMntmMultiControlActionPerformed(ActionEvent e) { - new ChangeVesselDialog(); - } - protected void handleMntmInstallKrpcActionPerformed(ActionEvent e) { new InstallKrpcDialog(); } @@ -162,34 +245,11 @@ protected void handleMntmExitActionPerformed(ActionEvent e) { System.exit(0); } - public static Rectangle centerDialogOnScreen() { - Dimension SCREEN_DIMENSIONS = Toolkit.getDefaultToolkit().getScreenSize(); - Dimension DIALOG_DIMENSIONS = new Dimension(400, 240); - int w = DIALOG_DIMENSIONS.width; - int h = DIALOG_DIMENSIONS.height; - int x = (SCREEN_DIMENSIONS.width - w) / 2; - int y = (SCREEN_DIMENSIONS.height - h) / 2; - return new Rectangle(x, y, w, h); - } - - public static JPanel getCardJPanels() { - return cardJPanels; - } - - public static void changeToPage(ActionEvent e) { - cardLayout.show(cardJPanels, e.getActionCommand()); - } - - public static void backToTelemetry(ActionEvent e) { - cardLayout.show(cardJPanels, Module.TELEMETRY.get()); - } - protected void handleMntmAboutActionPerformed(ActionEvent e) { new AboutJFrame(); } - public static Component createMarginComponent(int width, int height) { - Component marginComp = Box.createRigidArea(new Dimension(width, height)); - return marginComp; + private void handleMntmMultiControlActionPerformed(ActionEvent e) { + new ChangeVesselDialog(vesselManager); } } diff --git a/src/main/java/com/pesterenan/views/RoverJPanel.java b/src/main/java/com/pesterenan/views/RoverJPanel.java index 008a16d..20692c6 100644 --- a/src/main/java/com/pesterenan/views/RoverJPanel.java +++ b/src/main/java/com/pesterenan/views/RoverJPanel.java @@ -1,20 +1,29 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; -import com.pesterenan.resources.Bundle; -import com.pesterenan.utils.Module; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; -import javax.swing.*; -import javax.swing.border.EtchedBorder; -import javax.swing.border.TitledBorder; -import java.awt.*; +import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; -import static com.pesterenan.views.MainGui.BTN_DIMENSION; -import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; -import static com.pesterenan.views.MainGui.PNL_DIMENSION; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import com.pesterenan.model.VesselManager; +import com.pesterenan.resources.Bundle; +import com.pesterenan.utils.Module; public class RoverJPanel extends JPanel implements UIMethods { @@ -25,13 +34,21 @@ public class RoverJPanel extends JPanel implements UIMethods { private JButton btnBack, btnDrive; private ButtonGroup bgTargetChoice; private JRadioButton rbTargetVessel, rbWaypointOnMap; + private VesselManager vesselManager; + + private StatusDisplay statusDisplay; - public RoverJPanel() { + public RoverJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + } + @Override public void initComponents() { // Labels: @@ -148,7 +165,7 @@ private void handleDriveTo(ActionEvent e) { commands.put(Module.ROVER_TARGET_TYPE.get(), bgTargetChoice.getSelection().getActionCommand()); commands.put(Module.MARKER_NAME.get(), txfWaypointName.getText()); commands.put(Module.MAX_SPEED.get(), txfMaxSpeed.getText()); - MechPeste.newInstance().startModule(commands); + vesselManager.startModule(commands); } } @@ -161,10 +178,10 @@ private boolean validateTextFields() { throw new IllegalArgumentException(); } } catch (NumberFormatException e) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_rover_max_speed_above_3")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_rover_max_speed_above_3")); return false; } catch (IllegalArgumentException e) { - StatusJPanel.setStatusMessage(Bundle.getString("pnl_rover_waypoint_name_not_empty")); + statusDisplay.setStatusMessage(Bundle.getString("pnl_rover_waypoint_name_not_empty")); return false; } return true; diff --git a/src/main/java/com/pesterenan/views/RunManeuverJPanel.java b/src/main/java/com/pesterenan/views/RunManeuverJPanel.java index 90cd3ee..ce592b6 100644 --- a/src/main/java/com/pesterenan/views/RunManeuverJPanel.java +++ b/src/main/java/com/pesterenan/views/RunManeuverJPanel.java @@ -1,6 +1,26 @@ package com.pesterenan.views; +import static com.pesterenan.views.MainGui.BTN_DIMENSION; +import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; +import static com.pesterenan.views.MainGui.PNL_DIMENSION; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.CompoundBorder; +import javax.swing.border.TitledBorder; + import com.pesterenan.MechPeste; +import com.pesterenan.model.VesselManager; import com.pesterenan.resources.Bundle; import com.pesterenan.utils.ControlePID; import com.pesterenan.utils.Module; @@ -11,34 +31,28 @@ import krpc.client.services.SpaceCenter.Vessel; import krpc.client.services.SpaceCenter.VesselSituation; -import javax.swing.*; -import javax.swing.border.CompoundBorder; -import javax.swing.border.TitledBorder; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashMap; -import java.util.Map; - -import static com.pesterenan.views.MainGui.BTN_DIMENSION; -import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; -import static com.pesterenan.views.MainGui.PNL_DIMENSION; - public class RunManeuverJPanel extends JPanel implements ActionListener, UIMethods { private static final long serialVersionUID = 1L; + private StatusDisplay statusDisplay; + private JLabel lblExecute; private JButton btnLowerOrbit, btnApoapsis, btnPeriapsis, btnExecute, btnBack, btnAlignPlanes, btnRendezvous; private JCheckBox chkFineAdjusment; private final ControlePID ctrlManeuver = new ControlePID(); + private VesselManager vesselManager; - public RunManeuverJPanel() { + public RunManeuverJPanel(StatusDisplay statusDisplay) { + this.statusDisplay = statusDisplay; initComponents(); setupComponents(); layoutComponents(); } + public void setVesselManager(VesselManager vesselManager) { + this.vesselManager = vesselManager; + } + public void initComponents() { // Labels: lblExecute = new JLabel(Bundle.getString("pnl_mnv_lbl_exec_mnv")); @@ -56,23 +70,22 @@ public void initComponents() { chkFineAdjusment = new JCheckBox(Bundle.getString("pnl_mnv_chk_adj_mnv_rcs")); } - public static void createManeuver() { + public void createManeuver() { System.out.println("Create maneuver"); try { - createManeuver(MechPeste.getSpaceCenter().getUT() + 60); + createManeuver(vesselManager.getSpaceCenter().getUT() + 60); } catch (RPCException e) { } } - public static void createManeuver(double atFutureTime) { + public void createManeuver(double atFutureTime) { System.out.println("Create maneuver overloaded"); try { - MechPeste.newInstance(); - Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel(); + Vessel vessel = vesselManager.getSpaceCenter().getActiveVessel(); System.out.println("vessel: " + vessel); if (vessel.getSituation() != VesselSituation.ORBITING) { - StatusJPanel.setStatusMessage("Não é possível criar a manobra fora de órbita."); + statusDisplay.setStatusMessage("Não é possível criar a manobra fora de órbita."); return; } vessel.getControl().addNode(atFutureTime, 0, 0, 0); @@ -80,28 +93,28 @@ public static void createManeuver(double atFutureTime) { } } - public static void positionManeuverAt(String node) { + public void positionManeuverAt(String node) { try { MechPeste.newInstance(); - Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel(); + Vessel vessel = vesselManager.getSpaceCenter().getActiveVessel(); Orbit orbit = vessel.getOrbit(); Node currentManeuver = vessel.getControl().getNodes().get(0); double timeToNode = 0; switch (node) { case "apoapsis" : - timeToNode = MechPeste.getSpaceCenter().getUT() + orbit.getTimeToApoapsis(); + timeToNode = vesselManager.getSpaceCenter().getUT() + orbit.getTimeToApoapsis(); break; case "periapsis" : - timeToNode = MechPeste.getSpaceCenter().getUT() + orbit.getTimeToPeriapsis(); + timeToNode = vesselManager.getSpaceCenter().getUT() + orbit.getTimeToPeriapsis(); break; case "ascending" : double ascendingAnomaly = orbit - .trueAnomalyAtAN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit()); + .trueAnomalyAtAN(vesselManager.getSpaceCenter().getTargetVessel().getOrbit()); timeToNode = orbit.uTAtTrueAnomaly(ascendingAnomaly); break; case "descending" : double descendingAnomaly = orbit - .trueAnomalyAtDN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit()); + .trueAnomalyAtDN(vesselManager.getSpaceCenter().getTargetVessel().getOrbit()); timeToNode = orbit.uTAtTrueAnomaly(descendingAnomaly); break; } @@ -235,6 +248,6 @@ protected void handleManeuverFunction(String maneuverFunction) { commands.put(Module.MODULO.get(), Module.MANEUVER.get()); commands.put(Module.FUNCTION.get(), maneuverFunction.toString()); commands.put(Module.FINE_ADJUST.get(), String.valueOf(chkFineAdjusment.isSelected())); - MechPeste.newInstance().startModule(commands); + MechPeste.newInstance().getVesselManager().startModule(commands); } } diff --git a/src/main/java/com/pesterenan/views/StatusDisplay.java b/src/main/java/com/pesterenan/views/StatusDisplay.java new file mode 100644 index 0000000..ba0b2ec --- /dev/null +++ b/src/main/java/com/pesterenan/views/StatusDisplay.java @@ -0,0 +1,7 @@ +package com.pesterenan.views; + +public interface StatusDisplay { + void setStatusMessage(String message); + + void setBtnConnectVisible(boolean visible); +} diff --git a/src/main/java/com/pesterenan/views/StatusJPanel.java b/src/main/java/com/pesterenan/views/StatusJPanel.java index d54effc..6f31baf 100644 --- a/src/main/java/com/pesterenan/views/StatusJPanel.java +++ b/src/main/java/com/pesterenan/views/StatusJPanel.java @@ -1,17 +1,22 @@ package com.pesterenan.views; -import com.pesterenan.MechPeste; -import com.pesterenan.resources.Bundle; - -import javax.swing.*; - import static com.pesterenan.views.MainGui.BTN_DIMENSION; import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Dimension; import java.awt.event.ActionEvent; -public class StatusJPanel extends JPanel implements UIMethods { +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import com.pesterenan.MechPeste; +import com.pesterenan.resources.Bundle; + +public class StatusJPanel extends JPanel implements UIMethods, StatusDisplay { private static final long serialVersionUID = 1L; private static JLabel lblStatus; @@ -61,15 +66,19 @@ public void layoutComponents() { add(pnlMain, BorderLayout.CENTER); } - public static void setStatusMessage(String newStatus) { - lblStatus.setText(newStatus); + @Override + public void setStatusMessage(String message) { + lblStatus.setText(message); } - public static void isBtnConnectVisible(boolean visible) { + @Override + public void setBtnConnectVisible(boolean visible) { btnConnect.setVisible(visible); } private void handleConnect(ActionEvent e) { - MechPeste.newInstance().connectToKSP(); + setStatusMessage(Bundle.getString("status_connecting")); + setBtnConnectVisible(false); + MechPeste.newInstance().getConnectionManager().connectAndMonitor("MechPeste - Pesterenan"); } }