diff --git a/.classpath b/.classpath
index 5a6230c..653dfd7 100644
--- a/.classpath
+++ b/.classpath
@@ -1,13 +1,57 @@
-
-
+
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml
new file mode 100644
index 0000000..e6e6dae
--- /dev/null
+++ b/.github/workflows/ci-workflow.yml
@@ -0,0 +1,37 @@
+name: MechPeste CI workflow
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install KRPC as a Local Library
+ run: |
+ mvn install:install-file \
+ -Dfile=./src/main/resources/krpc-java-0.5.2.jar \
+ -DgroupId=io.github.krpc \
+ -DartifactId=krpc-java \
+ -Dversion=0.5.2 \
+ -Dpackaging=jar
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Build MechPeste with Maven
+ run: mvn -B package --file pom.xml
+
+ # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
+ - name: Update dependency graph
+ uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6
diff --git a/.github/workflows/release-new-version.yml b/.github/workflows/release-new-version.yml
new file mode 100644
index 0000000..6e6b866
--- /dev/null
+++ b/.github/workflows/release-new-version.yml
@@ -0,0 +1,37 @@
+name: Release a new MechPeste version
+
+on:
+ workflow_dispatch:
+ pull_request:
+ types:
+ - closed
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out the code
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Build MechPeste with Maven
+ run: mvn -B package --file pom.xml
+
+ - name: Upload Release Artifact
+ uses: actions/upload-release-asset@v1
+ with:
+ upload_url: ${{ github.event.release.upload_url }}
+ asset_path: ./target/MechPeste-${{ steps.maven.outputs.version }}.jar
+ asset_name: MechPeste-${{ steps.maven.outputs.version }}.jar
+ asset_content_type: application/java-archive
+
+ - name: Get Maven version
+ id: maven
+ run: echo "::set-output name=version::$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)"
diff --git a/.gitignore b/.gitignore
index e9ea9a6..4dc29f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,5 @@ local.properties
.loadpath
.metadata
workspace.xml
-settings.json
\ No newline at end of file
+settings.json
+target/
diff --git a/.project b/.project
index 9e5a886..f8b3eba 100644
--- a/.project
+++ b/.project
@@ -10,8 +10,14 @@
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+ org.eclipse.m2e.core.maven2Nature
org.eclipse.jdt.core.javanature
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
index 99f26c0..2b76340 100644
--- a/.settings/org.eclipse.core.resources.prefs
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -1,2 +1,2 @@
eclipse.preferences.version=1
-encoding/=UTF-8
+encoding//src/main/java=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 0c68a61..fa50df0 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -3,5 +3,10 @@ org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+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
diff --git a/.vscode/launch.json b/.vscode/launch.json
index beb5d53..c826b57 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,5 +1,12 @@
{
"configurations": [
+ {
+ "type": "java",
+ "name": "Main",
+ "request": "launch",
+ "mainClass": "com.pesterenan.Main",
+ "projectName": "MechPeste-Java"
+ },
{
"type": "java",
"name": "Launch MechPeste",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..1967018
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "java (build)",
+ "paths": [
+ "${workspace}"
+ ],
+ "isFullBuild": true,
+ "group": "build",
+ "problemMatcher": [],
+ "label": "java (build): Build Workspace",
+ "detail": "$(tools) Build all the Java projects in workspace."
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 3985eb1..c470c4c 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ manobras, e pilotar rovers.
---
É necessário ter o [Java](https://java.com/pt-BR/) instalado para utilizar o "MechPeste.jar".
Uma versão mais atualizada do
-mod [KRPC](https://github.com/krpc/krpc/releases/download/v0.5.1/krpc-0.5.1.zip)
+mod [KRPC](https://github.com/krpc/krpc/releases/download/v0.5.2/krpc-0.5.2.zip)
pode ser instalada diretamente do aplicativo MechPeste pelo menu Arquivo > Instalar KRPC.
## **Como instalar:**
@@ -73,3 +73,25 @@ texto e também a velocidade máxima que o rover pode alcançar.
A velocidade mínima permitida é de 3m/s. Clique em Pilotar e ele comecará a se
mover para o alvo, desviando dos obstáculos à frente.
+
+### Desenvolvimento do MechPeste com Maven
+
+Agora o MechPeste tem como base o gerenciador de dependências Maven. Para poder instalar a biblioteca
+do KRPC no entanto, como não está disponível no repositório público do Maven, é necessário fazer o download
+e instalar a biblioteca KRPC em sua versão 0.5.2 com o seguinte comando:
+
+``` bash
+mvn install:install-file \
+ -Dfile=\krpc-java-0.5.2.jar \
+ -DgroupId=io.github.krpc \
+ -DartifactId=krpc-java \
+ -Dversion=0.5.2 \
+ -Dpackaging=jar \
+```
+Substitua `` pela pasta onde está o arquivo do KRPC. Isso instalará essa biblioteca
+no seu repositório local.
+
+Agora você poderá usar comandos do Maven para instalar e construir a aplicação:
+```bash
+mvn clean install package
+```
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2807bf2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,89 @@
+
+ 4.0.0
+
+ com.pesterenan
+ MechPeste
+ 0.7.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+
+ com.pesterenan.MechPeste
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.3.0
+
+
+
+ com.pesterenan.MechPeste
+
+
+
+ jar-with-dependencies
+
+ MechPeste-${project.version}
+ false
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.maven
+ maven-model
+ 3.3.9
+
+
+ io.github.krpc
+ krpc-java
+ 0.5.2
+
+
+ org.javatuples
+ javatuples
+ 1.2
+
+
+ com.google.protobuf
+ protobuf-java
+ 3.22.1
+
+
+
+
diff --git a/src/com/pesterenan/resources/javatuples-1.2.jar b/src/com/pesterenan/resources/javatuples-1.2.jar
deleted file mode 100644
index 8944308..0000000
Binary files a/src/com/pesterenan/resources/javatuples-1.2.jar and /dev/null differ
diff --git a/src/com/pesterenan/resources/krpc-java-0.5.1.jar b/src/com/pesterenan/resources/krpc-java-0.5.1.jar
deleted file mode 100644
index f2348b8..0000000
Binary files a/src/com/pesterenan/resources/krpc-java-0.5.1.jar and /dev/null differ
diff --git a/src/com/pesterenan/resources/protobuf-java-3.22.1.jar b/src/com/pesterenan/resources/protobuf-java-3.22.1.jar
deleted file mode 100644
index 7685cda..0000000
Binary files a/src/com/pesterenan/resources/protobuf-java-3.22.1.jar and /dev/null differ
diff --git a/src/com/pesterenan/utils/ControlePID.java b/src/com/pesterenan/utils/ControlePID.java
deleted file mode 100644
index a94e5af..0000000
--- a/src/com/pesterenan/utils/ControlePID.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.pesterenan.utils;
-
-public class ControlePID {
- private double limiteMin = -1;
- private double limiteMax = 1;
- private double kp = 0.025;
- private double ki = 0.001;
- private double kd = 0.01;
- private double proportionalTerm, integralTerm, derivativeTerm = 0;
- private double lastValue, lastTime = 0;
-
- public double calcPID(double currentValue, double limitValue) {
- double now = System.currentTimeMillis();
- double changeInTime = now - this.lastTime;
- double timeSample = 25;
-
- if (changeInTime >= timeSample) {
- double error = limitValue - currentValue;
- double changeInValues = (currentValue - this.lastValue);
-
- this.proportionalTerm = this.kp * error;
- this.integralTerm = limitOutput(this.integralTerm + ki * error);
- this.derivativeTerm = kd * -changeInValues;
- this.lastValue = currentValue;
- this.lastTime = now;
- }
- return limitOutput(proportionalTerm + ki * this.integralTerm + derivativeTerm);
- }
-
- private double limitOutput(double valor) {
- return Utilities.clamp(valor, this.limiteMin, this.limiteMax);
- }
-
- public void adjustOutput(double min, double max) {
- if (min > max) {
- return;
- }
- this.limiteMin = min;
- this.limiteMax = max;
- this.integralTerm = limitOutput(this.integralTerm);
-
- }
-
- public void adjustPID(double Kp, double Ki, double Kd) {
- if (Kp > 0) {
- this.kp = Kp;
- }
- if (Ki >= 0) {
- this.ki = Ki;
- }
- if (Kd >= 0) {
- this.kd = Kd;
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/com/pesterenan/utils/Navigation.java b/src/com/pesterenan/utils/Navigation.java
deleted file mode 100644
index 70cc9d8..0000000
--- a/src/com/pesterenan/utils/Navigation.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.pesterenan.utils;
-
-import krpc.client.RPCException;
-import krpc.client.Stream;
-import krpc.client.StreamException;
-import org.javatuples.Triplet;
-
-import static com.pesterenan.MechPeste.getConnection;
-import static com.pesterenan.MechPeste.getSpaceCenter;
-import static krpc.client.services.SpaceCenter.*;
-
-public class Navigation {
-
- public static final Triplet RADIAL = new Triplet<>(1.0, 0.0, 0.0);
- public static final Triplet ANTI_RADIAL = new Triplet<>(-1.0, 0.0, 0.0);
- public static final Triplet PROGRADE = new Triplet<>(0.0, 1.0, 0.0);
- public static final Triplet RETROGRADE = new Triplet<>(0.0, -1.0, 0.0);
- public static final Triplet NORMAL = new Triplet<>(0.0, 0.0, 1.0);
- public static final Triplet ANTI_NORMAL = new Triplet<>(0.0, 0.0, -1.0);
- // private Drawing drawing;
- private Vessel currentVessel;
- private Flight flightParameters;
- private Stream horizontalSpeed;
- private ReferenceFrame orbitalReference;
-
- public Navigation(Vessel currentVessel) {
- this.currentVessel = currentVessel;
- initializeParameters();
- }
-
- private void initializeParameters() {
- try {
-// drawing = Drawing.newInstance(getConexao());
- orbitalReference = currentVessel.getOrbit().getBody().getReferenceFrame();
- flightParameters = currentVessel.flight(orbitalReference);
- horizontalSpeed = getConnection().addStream(flightParameters, "getHorizontalSpeed");
- } catch (RPCException | StreamException ignored) {
- }
- }
-
- public void aimAtManeuver(Node maneuver) throws RPCException {
- aimAtDirection(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, currentVessel.getSurfaceVelocityReferenceFrame(),
- orbitalReference
- )).subtract(currentPosition);
- Vector radial = new Vector(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());
- }
-
-// public void aimAtTarget() throws RPCException, StreamException, InterruptedException {
-// Vector currentPosition = new Vector(naveAtual.position(pontoRefSuperficie));
-// Vector targetPosition = new Vector(centroEspacial.getTargetVessel().position(pontoRefSuperficie));
-// targetPosition.x = 0.0;
-// double distanceToTarget = Vector.distance(currentPosition, targetPosition);
-//
-// Vector toTargetDirection = Vector.targetDirection(currentPosition, targetPosition);
-// Vector oppositeDirection = Vector.targetOppositeDirection(currentPosition, targetPosition);
-// Vector progradeDirection = Vector.targetDirection(currentPosition, new Vector(
-// centroEspacial.transformPosition(PROGRADE, naveAtual.getSurfaceVelocityReferenceFrame(),
-// pontoRefSuperficie
-// )));
-// Vector retrogradeDirection = Vector.targetDirection(currentPosition, new Vector(
-// centroEspacial.transformPosition(RETROGRADE, naveAtual.getSurfaceVelocityReferenceFrame(),
-// pontoRefSuperficie
-// )));
-// progradeDirection.x = 0.0;
-// retrogradeDirection.x = 0.0;
-// drawing.addDirection(toTargetDirection.toTriplet(), pontoRefSuperficie, 10, true);
-// drawing.addDirection(oppositeDirection.toTriplet(), pontoRefSuperficie, 5, true);
-// double pointingToTargetThreshold = Utilities.remap(0, 200, 0, 1, distanceToTarget, true);
-// double speedThreshold = Utilities.remap(0, 20, 0, 1, horizontalSpeed.get(), true);
-//
-// Vector currentDirection =
-// Utilities.linearInterpolation(oppositeDirection, toTargetDirection, pointingToTargetThreshold);
-// double angleCurrentDirection =
-// new Vector(currentDirection.z, currentDirection.y, currentDirection.x).heading();
-// double angleProgradeDirection =
-// new Vector(progradeDirection.z, progradeDirection.y, progradeDirection.x).heading();
-// double deltaAngle = angleProgradeDirection - angleCurrentDirection;
-// System.out.println(deltaAngle);
-// if (deltaAngle > 3) {
-// currentDirection.sum(progradeDirection).normalize();
-// } else if (deltaAngle < -3) {
-// currentDirection.subtract(progradeDirection).normalize();
-// }
-// drawing.addDirection(currentDirection.toTriplet(), pontoRefSuperficie, 25, true);
-//
-//
-// Vector currentDirectionOnOrbitalRef = new Vector(
-// centroEspacial.transformDirection(currentDirection.toTriplet(), pontoRefSuperficie,
-// pontoRefOrbital));
-// Vector radial = new Vector(centroEspacial.transformDirection(RADIAL, pontoRefSuperficie,
-// pontoRefOrbital));
-// Vector speedVector = Utilities.linearInterpolation(retrogradeDirection, progradeDirection, speedThreshold);
-// Vector speedVectorOnOrbitalRef = new Vector(
-// centroEspacial.transformDirection(speedVector.toTriplet(), pontoRefSuperficie,
-// pontoRefOrbital));
-// Vector pointingVector =
-// Utilities.linearInterpolation(currentDirectionOnOrbitalRef, radial.sum(speedVectorOnOrbitalRef),
-// speedThreshold
-// );
-// Thread.sleep(50);
-// drawing.clear(false);
-// aimAtDirection(pointingVector.toTriplet());
-// }
-
- public void aimAtPrograde() throws RPCException {
- aimAtDirection(getSpaceCenter().transformDirection(PROGRADE, currentVessel.getSurfaceVelocityReferenceFrame(),
- orbitalReference
- ));
- }
-
- public void aimAtRadialOut() throws RPCException {
- aimAtDirection(getSpaceCenter().transformDirection(RADIAL, currentVessel.getSurfaceReferenceFrame(),
- orbitalReference
- ));
- }
-
- public void aimAtRetrograde() throws RPCException {
- aimAtDirection(getSpaceCenter().transformDirection(RETROGRADE,
- currentVessel.getSurfaceVelocityReferenceFrame(),
- orbitalReference
- ));
- }
-
- public void aimAtDirection(Triplet currentDirection) throws RPCException {
- currentVessel.getAutoPilot().setReferenceFrame(orbitalReference);
- currentVessel.getAutoPilot().setTargetDirection(currentDirection);
- }
-
-}
diff --git a/src/com/pesterenan/views/InstallKrpcDialog.java b/src/com/pesterenan/views/InstallKrpcDialog.java
deleted file mode 100644
index 2a905fa..0000000
--- a/src/com/pesterenan/views/InstallKrpcDialog.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package com.pesterenan.views;
-
-import com.pesterenan.resources.Bundle;
-import com.pesterenan.updater.KrpcInstaller;
-
-import javax.swing.*;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.border.BevelBorder;
-import javax.swing.border.TitledBorder;
-
-public class InstallKrpcDialog extends JDialog {
- private static final long serialVersionUID = 1L;
- private JLabel lblInstallerInfo;
- private final JSeparator separator = new JSeparator();
- private final JPanel pnlKspFolderPath = new JPanel();
- private final JTextField txfPath = new JTextField();
- private JButton btnBrowsePath;
- private JButton btnDownloadInstall;
- private JButton btnCancel;
- private JPanel pnlStatus;
- private static JLabel lblStatus;
-
- public InstallKrpcDialog() {
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- initComponents();
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
-
- private void initComponents() {
- setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
- setResizable(false);
- setBounds(MainGui.centerDialogOnScreen());
- setAlwaysOnTop(true);
- setModalityType(ModalityType.APPLICATION_MODAL);
- setTitle(Bundle.getString("installer_dialog_title")); //$NON-NLS-1$
-
- lblInstallerInfo = new JLabel(Bundle.getString("installer_dialog_txt_info")); //$NON-NLS-1$
-
- pnlKspFolderPath.setBorder(
- new TitledBorder(null, Bundle.getString("installer_dialog_pnl_path"), TitledBorder.LEADING,//$NON
- // -NLS-1$
- TitledBorder.TOP, null, null
- ));
-
- btnDownloadInstall = new JButton(Bundle.getString("installer_dialog_btn_download")); //$NON
- // -NLS-1$
- btnDownloadInstall.addActionListener((e) -> KrpcInstaller.downloadAndInstallKrpc());
- btnDownloadInstall.setEnabled(false);
-
- btnCancel = new JButton(Bundle.getString("installer_dialog_btn_cancel")); //$NON-NLS-1$
- btnCancel.addActionListener((e) -> this.dispose());
-
- pnlStatus = new JPanel();
- pnlStatus.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
-
- GroupLayout groupLayout = new GroupLayout(getContentPane());
- groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
- .addGroup(groupLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(groupLayout.createParallelGroup(
- Alignment.LEADING)
- .addComponent(
- pnlKspFolderPath,
- GroupLayout.DEFAULT_SIZE,
- 414,
- Short.MAX_VALUE
- )
- .addComponent(
- lblInstallerInfo,
- Alignment.TRAILING,
- GroupLayout.DEFAULT_SIZE,
- 414,
- Short.MAX_VALUE
- )
- .addComponent(separator,
- Alignment.TRAILING,
- GroupLayout.DEFAULT_SIZE,
- 414,
- Short.MAX_VALUE
- )
- .addGroup(
- groupLayout.createSequentialGroup()
- .addComponent(
- btnDownloadInstall)
- .addPreferredGap(
- ComponentPlacement.RELATED,
- 184,
- Short.MAX_VALUE
- )
- .addComponent(
- btnCancel)))
- .addGap(10))
- .addComponent(pnlStatus, Alignment.LEADING, GroupLayout.DEFAULT_SIZE,
- 434, Short.MAX_VALUE
- ));
- groupLayout.setVerticalGroup(groupLayout.createParallelGroup(Alignment.LEADING)
- .addGroup(groupLayout.createSequentialGroup()
- .addContainerGap()
- .addComponent(lblInstallerInfo,
- GroupLayout.PREFERRED_SIZE, 60,
- GroupLayout.PREFERRED_SIZE
- )
- .addGap(2)
- .addComponent(separator,
- GroupLayout.PREFERRED_SIZE, 2,
- GroupLayout.PREFERRED_SIZE
- )
- .addPreferredGap(ComponentPlacement.UNRELATED)
- .addComponent(pnlKspFolderPath,
- GroupLayout.PREFERRED_SIZE, 51,
- GroupLayout.PREFERRED_SIZE
- )
- .addPreferredGap(ComponentPlacement.UNRELATED)
- .addGroup(groupLayout.createParallelGroup(
- Alignment.BASELINE)
- .addComponent(
- btnDownloadInstall)
- .addComponent(btnCancel))
- .addPreferredGap(ComponentPlacement.RELATED, 60,
- Short.MAX_VALUE
- )
- .addComponent(pnlStatus,
- GroupLayout.PREFERRED_SIZE, 25,
- GroupLayout.PREFERRED_SIZE
- )));
-
- lblStatus = new JLabel();
- GroupLayout glPnlStatus = new GroupLayout(pnlStatus);
- glPnlStatus.setHorizontalGroup(glPnlStatus.createParallelGroup(Alignment.LEADING)
- .addGroup(glPnlStatus.createSequentialGroup()
- .addContainerGap()
- .addComponent(lblStatus)
- .addContainerGap(389, Short.MAX_VALUE)));
- glPnlStatus.setVerticalGroup(glPnlStatus.createParallelGroup(Alignment.TRAILING)
- .addGroup(glPnlStatus.createSequentialGroup()
- .addGap(2)
- .addComponent(lblStatus, GroupLayout.DEFAULT_SIZE,
- GroupLayout.DEFAULT_SIZE,
- Short.MAX_VALUE
- )
- .addGap(0)));
- pnlStatus.setLayout(glPnlStatus);
-
- txfPath.setEditable(false);
- txfPath.setColumns(10);
-
- btnBrowsePath = new JButton(Bundle.getString("installer_dialog_btn_browse")); //$NON-NLS-1$
- btnBrowsePath.addActionListener(e -> {
- chooseKSPFolder();
- txfPath.setText(KrpcInstaller.getKspFolder());
- });
- GroupLayout glPnlKspFolderPath = new GroupLayout(pnlKspFolderPath);
- glPnlKspFolderPath.setHorizontalGroup(glPnlKspFolderPath.createParallelGroup(Alignment.LEADING)
- .addGroup(Alignment.TRAILING,
- glPnlKspFolderPath.createSequentialGroup()
- .addContainerGap()
- .addComponent(txfPath,
- GroupLayout.DEFAULT_SIZE,
- 273,
- Short.MAX_VALUE
- )
- .addPreferredGap(
- ComponentPlacement.RELATED)
- .addComponent(btnBrowsePath,
- GroupLayout.PREFERRED_SIZE,
- 103,
- GroupLayout.PREFERRED_SIZE
- )
- .addContainerGap()
- ));
- glPnlKspFolderPath.setVerticalGroup(glPnlKspFolderPath.createParallelGroup(Alignment.LEADING)
- .addGroup(glPnlKspFolderPath.createSequentialGroup()
- .addGroup(
- glPnlKspFolderPath.createParallelGroup(
- Alignment.BASELINE)
- .addComponent(
- txfPath,
- GroupLayout.PREFERRED_SIZE,
- 23,
- GroupLayout.PREFERRED_SIZE
- )
- .addComponent(
- btnBrowsePath))
- .addContainerGap(24,
- Short.MAX_VALUE
- )));
- pnlKspFolderPath.setLayout(glPnlKspFolderPath);
- getContentPane().setLayout(groupLayout);
-
- setVisible(true);
- }
-
- public void chooseKSPFolder() {
- JFileChooser kspDir = new JFileChooser();
- kspDir.setDialogTitle("Escolha a pasta do KSP na Steam");
- kspDir.setMultiSelectionEnabled(false);
- kspDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
- int response = kspDir.showOpenDialog(this);
- if (response == JFileChooser.APPROVE_OPTION) {
- KrpcInstaller.setKspFolder(kspDir.getSelectedFile().getPath());
- btnDownloadInstall.setEnabled(true);
- setStatus("Pasta escolhida, pronto para instalar.");
- } else {
- KrpcInstaller.setKspFolder(null);
- btnDownloadInstall.setEnabled(false);
- setStatus("");
- }
- }
-
- public static void setStatus(String status) {
- lblStatus.setText(status);
- }
-}
diff --git a/src/com/pesterenan/views/UIMethods.java b/src/com/pesterenan/views/UIMethods.java
deleted file mode 100644
index 3a34ae7..0000000
--- a/src/com/pesterenan/views/UIMethods.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.pesterenan.views;
-
-public interface UIMethods {
-
- public void initComponents();
-
- public void setupComponents();
-
- public void layoutComponents();
-}
\ No newline at end of file
diff --git a/src/main/java/com/pesterenan/Main.java b/src/main/java/com/pesterenan/Main.java
new file mode 100644
index 0000000..ceb84df
--- /dev/null
+++ b/src/main/java/com/pesterenan/Main.java
@@ -0,0 +1,229 @@
+package com.pesterenan;
+
+import java.io.IOException;
+
+import com.pesterenan.utils.Utilities;
+import com.pesterenan.utils.Vector;
+
+import krpc.client.Connection;
+import krpc.client.RPCException;
+import krpc.client.services.Drawing;
+import krpc.client.services.Drawing.Line;
+import krpc.client.services.SpaceCenter;
+import krpc.client.services.SpaceCenter.Control;
+import krpc.client.services.SpaceCenter.DockingPort;
+import krpc.client.services.SpaceCenter.ReferenceFrame;
+import krpc.client.services.SpaceCenter.SASMode;
+import krpc.client.services.SpaceCenter.Vessel;
+
+public class Main {
+ private static Connection connection;
+ private static SpaceCenter spaceCenter;
+ private static Drawing drawing;
+ private static Control control;
+
+ private static Vessel activeVessel;
+ private static Vessel targetVessel;
+
+ private static ReferenceFrame orbitalRefVessel;
+ private static ReferenceFrame vesselRefFrame;
+ private static ReferenceFrame orbitalRefBody;
+ private static final double SPEED_LIMIT = 3.0;
+ private static final double DISTANCE_LIMIT = 25.0;
+ private static Line distanceLine;
+ private static Line distLineXAxis;
+ private static Line distLineYAxis;
+ private static Line distLineZAxis;
+ private static DockingPort myDockingPort;
+ private static DockingPort targetDockingPort;
+ private static Vector positionMyDockingPort;
+ private static Vector positionTargetDockingPort;
+
+ private static void initializeParameters() {
+ try {
+ connection = Connection.newInstance();
+ spaceCenter = SpaceCenter.newInstance(connection);
+ drawing = Drawing.newInstance(connection);
+ activeVessel = spaceCenter.getActiveVessel();
+ targetVessel = spaceCenter.getTargetVessel();
+ vesselRefFrame = activeVessel.getReferenceFrame();
+ orbitalRefVessel = activeVessel.getOrbitalReferenceFrame();
+ orbitalRefBody = activeVessel.getOrbit().getBody().getReferenceFrame();
+
+ myDockingPort = activeVessel.getParts().getDockingPorts().get(0);
+ targetDockingPort = targetVessel.getParts().getDockingPorts().get(0);
+
+ positionMyDockingPort = new Vector(myDockingPort.position(orbitalRefVessel));
+ positionTargetDockingPort = new Vector(targetDockingPort.position(orbitalRefVessel));
+
+ createLines(positionMyDockingPort, positionTargetDockingPort);
+
+ } catch (IOException | RPCException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ // Initialize parameters for the script, connection and setup:
+ initializeParameters();
+
+ // Setting up the control
+ control = activeVessel.getControl();
+ control.setSAS(true);
+ control.setRCS(false);
+ control.setSASMode(SASMode.STABILITY_ASSIST);
+
+ Vector targetDirection = new Vector(activeVessel.position(orbitalRefVessel))
+ .subtract(new Vector(targetVessel.position(orbitalRefVessel))).multiply(-1);
+ activeVessel.getAutoPilot().setReferenceFrame(orbitalRefVessel);
+ activeVessel.getAutoPilot().setTargetDirection(targetDirection.toTriplet());
+ activeVessel.getAutoPilot().setTargetRoll(90);
+ activeVessel.getAutoPilot().engage();
+ // Fazer a nave apontar usando o piloto automático, na marra
+ while (Math.abs(activeVessel.getAutoPilot().getError()) > 1) {
+ activeVessel.getAutoPilot().wait_();
+ }
+ control.setRCS(true);
+ activeVessel.getAutoPilot().disengage();
+ control.setSAS(true);
+ control.setSASMode(SASMode.STABILITY_ASSIST);
+
+ // PRIMEIRA PARTE DO DOCKING: APROXIMAÇÃO
+
+ Vector targetPosition = new Vector(targetVessel.position(vesselRefFrame));
+ double lastXTargetPos = targetPosition.x;
+ double lastYTargetPos = targetPosition.y;
+ double lastZTargetPos = targetPosition.z;
+ long sleepTime = 25;
+ double currentXAxisSpeed = 0;
+ double currentYAxisSpeed = 0;
+ double currentZAxisSpeed = 0;
+ while (Math.abs(lastYTargetPos) >= DISTANCE_LIMIT) {
+ targetPosition = new Vector(targetVessel.position(vesselRefFrame));
+
+ // Atualizar posições para linhas
+ positionMyDockingPort = new Vector(myDockingPort.position(vesselRefFrame));
+ positionTargetDockingPort = new Vector(targetDockingPort.position(vesselRefFrame));
+ updateLines(positionMyDockingPort, positionTargetDockingPort);
+
+ // Calcular velocidade de cada eixo:
+ currentXAxisSpeed = (targetPosition.x - lastXTargetPos) * sleepTime;
+ currentYAxisSpeed = (targetPosition.y - lastYTargetPos) * sleepTime;
+ currentZAxisSpeed = (targetPosition.z - lastZTargetPos) * sleepTime;
+
+ // Calcular a aceleração para cada eixo no RCS:
+ float forwardsError = calculateThrottle(DISTANCE_LIMIT, DISTANCE_LIMIT * 2, currentYAxisSpeed,
+ targetPosition.y, SPEED_LIMIT);
+ float sidewaysError = calculateThrottle(0, 10, currentXAxisSpeed, targetPosition.x, SPEED_LIMIT);
+ float upwardsError = calculateThrottle(0, 10, currentZAxisSpeed, targetPosition.z, SPEED_LIMIT);
+ control.setForward((float) forwardsError);
+ control.setRight((float) sidewaysError);
+ control.setUp((float) -upwardsError);
+
+ // Guardar últimas posições:
+ lastXTargetPos = targetPosition.x;
+ lastYTargetPos = targetPosition.y;
+ lastZTargetPos = targetPosition.z;
+ Thread.sleep(sleepTime);
+ }
+
+ // SEGUNDA PARTE APONTAR PRO LADO CONTRARIO:
+ Vector direcaoContrariaDockingPortAlvo = new Vector(targetDockingPort.direction(orbitalRefVessel))
+ .multiply(-1);
+ control.setSAS(false);
+ control.setRCS(false);
+ activeVessel.getAutoPilot().engage();
+ activeVessel.getAutoPilot().setReferenceFrame(orbitalRefVessel);
+ activeVessel.getAutoPilot().setTargetDirection(direcaoContrariaDockingPortAlvo.toTriplet());
+ activeVessel.getAutoPilot().setTargetRoll(90);
+ while (Math.abs(activeVessel.getAutoPilot().getError()) > 1) {
+ activeVessel.getAutoPilot().wait_();
+ }
+ activeVessel.getAutoPilot().disengage();
+ control.setSAS(true);
+ control.setSASMode(SASMode.STABILITY_ASSIST);
+ Thread.sleep(1000);
+ control.setRCS(true);
+
+ while (targetVessel != null) {
+ targetPosition = new Vector(targetDockingPort.position(vesselRefFrame));
+
+ // Atualizar posições para linhas
+ positionMyDockingPort = new Vector(myDockingPort.position(vesselRefFrame));
+ updateLines(positionMyDockingPort, targetPosition);
+
+ // Calcular velocidade de cada eixo:
+ currentXAxisSpeed = (targetPosition.x - lastXTargetPos) * sleepTime;
+ currentYAxisSpeed = (targetPosition.y - lastYTargetPos) * sleepTime;
+ currentZAxisSpeed = (targetPosition.z - lastZTargetPos) * sleepTime;
+
+ // Calcular a aceleração para cada eixo no RCS:
+ float forwardsError = calculateThrottle(5, 10, currentYAxisSpeed,
+ targetPosition.y, SPEED_LIMIT);
+ float sidewaysError = calculateThrottle(-1, 10, currentXAxisSpeed, targetPosition.x, SPEED_LIMIT);
+ float upwardsError = calculateThrottle(-1, 10, currentZAxisSpeed, targetPosition.z, SPEED_LIMIT);
+ control.setForward((float) forwardsError);
+ control.setRight((float) sidewaysError);
+ control.setUp((float) -upwardsError);
+
+ // Guardar últimas posições:
+ lastXTargetPos = targetPosition.x;
+ lastYTargetPos = targetPosition.y;
+ lastZTargetPos = targetPosition.z;
+ Thread.sleep(sleepTime);
+ }
+ // // Close the connection when finished
+ // connection.close();
+ } catch (RPCException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static float calculateThrottle(double minDistance, double maxDistance, double currentSpeed,
+ double currentPosition, double speedLimit) {
+ double limiter = Utilities.remap(minDistance, maxDistance, 0, 1, Math.abs(currentPosition), true);
+ double change = (Utilities.remap(-speedLimit, speedLimit, -1.0, 1.0,
+ currentSpeed + (Math.signum(currentPosition) * (limiter * speedLimit)), true));
+ return (float) change;
+ }
+
+ private static void createLines(Vector start, Vector end) {
+ try {
+ distanceLine = drawing.addLine(start.toTriplet(),
+ end.toTriplet(), vesselRefFrame, true);
+ distLineXAxis = drawing.addLine(start.toTriplet(),
+ new Vector(end.x, 0.0, 0.0).toTriplet(),
+ vesselRefFrame, true);
+ distLineYAxis = drawing.addLine(start.toTriplet(),
+ new Vector(end.x, end.y, 0.0).toTriplet(),
+ vesselRefFrame, true);
+ distLineZAxis = drawing.addLine(start.toTriplet(),
+ end.toTriplet(),
+ vesselRefFrame, true);
+ distanceLine.setThickness(0.5f);
+ distLineXAxis.setThickness(0.25f);
+ distLineYAxis.setThickness(0.25f);
+ distLineZAxis.setThickness(0.25f);
+ distLineXAxis.setColor(new Vector(1.0, 0.0, 0.0).toTriplet());
+ distLineYAxis.setColor(new Vector(0.0, 1.0, 0.0).toTriplet());
+ distLineZAxis.setColor(new Vector(0.0, 0.0, 1.0).toTriplet());
+ } catch (RPCException e) {
+ }
+ }
+
+ private static void updateLines(Vector start, Vector end) {
+ // Updating drawing lines:
+ try {
+ distanceLine.setStart(start.toTriplet());
+ distanceLine.setEnd(end.toTriplet());
+ distLineXAxis.setStart(start.toTriplet());
+ distLineXAxis.setEnd(new Vector(end.x, 0.0, 0.0).toTriplet());
+ distLineYAxis.setStart(distLineXAxis.getEnd());
+ distLineYAxis.setEnd(new Vector(end.x, end.y, 0.0).toTriplet());
+ distLineZAxis.setStart(distLineYAxis.getEnd());
+ distLineZAxis.setEnd(end.toTriplet());
+ } catch (RPCException e) {
+ }
+ }
+}
diff --git a/src/com/pesterenan/MechPeste.java b/src/main/java/com/pesterenan/MechPeste.java
similarity index 78%
rename from src/com/pesterenan/MechPeste.java
rename to src/main/java/com/pesterenan/MechPeste.java
index 4f6fc12..0367073 100644
--- a/src/com/pesterenan/MechPeste.java
+++ b/src/main/java/com/pesterenan/MechPeste.java
@@ -1,26 +1,31 @@
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.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.swing.DefaultListModel;
+import javax.swing.ListModel;
+
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.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 javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import static com.pesterenan.views.StatusJPanel.isBtnConnectVisible;
-import static com.pesterenan.views.StatusJPanel.setStatusMessage;
-
public class MechPeste {
private static KRPC krpc;
private static MechPeste mechPeste;
@@ -29,10 +34,6 @@ public class MechPeste {
private static int currentVesselId = -1;
private static ActiveVessel currentVessel = null;
- private MechPeste() {
- MainGui.newInstance();
- }
-
public static void main(String[] args) {
MechPeste.newInstance().connectToKSP();
MechPeste.newInstance().checkActiveVessel();
@@ -70,6 +71,53 @@ public static ListModel getActiveVessels(String search) {
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 naveAtual = spaceCenter.getVessels().stream().filter(v -> v.hashCode() == selectedIndex).findFirst()
+ .get();
+ String name = naveAtual.getName().length() > 40
+ ? naveAtual.getName().substring(0, 40) + "..."
+ : naveAtual.getName();
+ String vesselInfo = String.format("Nome: %s\t\t\t | Corpo: %s", name,
+ naveAtual.getOrbit().getBody().getName());
+ return vesselInfo;
+ } catch (RPCException | NullPointerException ignored) {
+ }
+ return "";
+ }
+
+ public static void changeToVessel(int selectedIndex) {
+ try {
+ Vessel naveAtual = spaceCenter.getVessels().stream().filter(v -> v.hashCode() == selectedIndex).findFirst()
+ .get();
+ spaceCenter.setActiveVessel(naveAtual);
+ } 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 (search == "all") {
return true;
@@ -96,61 +144,14 @@ private static boolean filterVessels(Vessel vessel, String search) {
return false;
}
- public static String getVesselInfo(int selectedIndex) {
- try {
- Vessel naveAtual =
- spaceCenter.getVessels().stream().filter(v -> v.hashCode() == selectedIndex).findFirst().get();
- String name = naveAtual.getName().length() > 40
- ? naveAtual.getName().substring(0, 40) + "..."
- : naveAtual.getName();
- String vesselInfo =
- String.format("Nome: %s\t\t\t | Corpo: %s", name, naveAtual.getOrbit().getBody().getName());
- return vesselInfo;
- } catch (RPCException | NullPointerException ignored) {
- }
- return "";
- }
-
- public static void changeToVessel(int selectedIndex) {
- try {
- Vessel naveAtual =
- spaceCenter.getVessels().stream().filter(v -> v.hashCode() == selectedIndex).findFirst().get();
- spaceCenter.setActiveVessel(naveAtual);
- } catch (RPCException | NullPointerException e) {
- System.out.println(Bundle.getString("status_couldnt_switch_vessel"));
- }
+ private MechPeste() {
+ MainGui.newInstance();
}
public KRPC.GameScene getCurrentGameScene() throws RPCException {
return krpc.getCurrentGameScene();
}
- private void checkActiveVessel() {
- while (getConnection() != null) {
- try {
- if (!MechPeste.newInstance().getCurrentGameScene().equals(KRPC.GameScene.FLIGHT)) {
- Thread.sleep(100);
- return;
- }
- 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());
- }
- Thread.sleep(100);
- } catch (RPCException | InterruptedException ignored) {
- }
- }
- }
-
public void startModule(Map commands) {
currentVessel.startModule(commands);
}
@@ -182,7 +183,30 @@ public void checkConnection() {
}
}
- public static void cancelControl(ActionEvent e) {
- currentVessel.cancelControl();
+ private void checkActiveVessel() {
+ while (getConnection() != null) {
+ try {
+ if (!MechPeste.newInstance().getCurrentGameScene().equals(KRPC.GameScene.FLIGHT)) {
+ Thread.sleep(100);
+ return;
+ }
+ 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) {
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/com/pesterenan/controllers/Controller.java b/src/main/java/com/pesterenan/controllers/Controller.java
similarity index 100%
rename from src/com/pesterenan/controllers/Controller.java
rename to src/main/java/com/pesterenan/controllers/Controller.java
diff --git a/src/main/java/com/pesterenan/controllers/DockingController.java b/src/main/java/com/pesterenan/controllers/DockingController.java
new file mode 100644
index 0000000..eaea4b7
--- /dev/null
+++ b/src/main/java/com/pesterenan/controllers/DockingController.java
@@ -0,0 +1,297 @@
+package com.pesterenan.controllers;
+
+import static com.pesterenan.MechPeste.getConnection;
+import static com.pesterenan.MechPeste.getSpaceCenter;
+
+import java.util.Map;
+
+import com.pesterenan.utils.Modulos;
+import com.pesterenan.utils.Utilities;
+import com.pesterenan.utils.Vector;
+import com.pesterenan.views.StatusJPanel;
+
+import krpc.client.RPCException;
+import krpc.client.services.Drawing;
+import krpc.client.services.Drawing.Line;
+import krpc.client.services.SpaceCenter.Control;
+import krpc.client.services.SpaceCenter.DockingPort;
+import krpc.client.services.SpaceCenter.ReferenceFrame;
+import krpc.client.services.SpaceCenter.SASMode;
+import krpc.client.services.SpaceCenter.Vessel;
+
+public class DockingController extends Controller {
+
+ private Drawing drawing;
+ private Vessel targetVessel;
+ private Control control;
+
+ private ReferenceFrame orbitalRefVessel;
+ private ReferenceFrame vesselRefFrame;
+ private ReferenceFrame orbitalRefBody;
+ private Line distanceLine;
+ private Line distLineXAxis;
+ private Line distLineYAxis;
+ private Line distLineZAxis;
+ private DockingPort myDockingPort;
+ private DockingPort targetDockingPort;
+ private Vector positionMyDockingPort;
+ private Vector positionTargetDockingPort;
+
+ private final double DISTANCE_LIMIT = 25.0;
+ private double SPEED_LIMIT = 3.0;
+ private double currentXAxisSpeed = 0.0;
+ private double currentYAxisSpeed = 0.0;
+ private double currentZAxisSpeed = 0.0;
+ private double lastXTargetPos = 0.0;
+ private double lastYTargetPos = 0.0;
+ private double lastZTargetPos = 0.0;
+ private long sleepTime = 25;
+ private DOCKING_STEPS dockingStep;
+
+ public DockingController(Map commands) {
+ super();
+ this.commands = commands;
+ initializeParameters();
+ }
+
+ private void initializeParameters() {
+ try {
+ SPEED_LIMIT = Double.parseDouble(commands.get(Modulos.VELOCIDADE_MAX.get()));
+ drawing = Drawing.newInstance(getConnection());
+ targetVessel = getSpaceCenter().getTargetVessel();
+ control = getNaveAtual().getControl();
+ vesselRefFrame = getNaveAtual().getReferenceFrame();
+ orbitalRefVessel = getNaveAtual().getOrbitalReferenceFrame();
+ orbitalRefBody = getNaveAtual().getOrbit().getBody().getReferenceFrame();
+
+ myDockingPort = getNaveAtual().getParts().getDockingPorts().get(0);
+ targetDockingPort = targetVessel.getParts().getDockingPorts().get(0);
+
+ positionMyDockingPort = new Vector(myDockingPort.position(orbitalRefVessel));
+ positionTargetDockingPort = new Vector(targetDockingPort.position(orbitalRefVessel));
+ } catch (RPCException ignored) {
+ }
+ }
+
+ @Override
+ public void run() {
+ if (commands.get(Modulos.MODULO.get()).equals(Modulos.MODULO_DOCKING.get())) {
+ startDocking();
+ }
+ }
+
+ private void pointToTarget(Vector targetDirection) throws RPCException, InterruptedException {
+ getNaveAtual().getAutoPilot().setReferenceFrame(orbitalRefVessel);
+ getNaveAtual().getAutoPilot().setTargetDirection(targetDirection.toTriplet());
+ getNaveAtual().getAutoPilot().setTargetRoll(90);
+ getNaveAtual().getAutoPilot().engage();
+ // Fazer a nave apontar usando o piloto automático, na marra
+ while (Math.abs(getNaveAtual().getAutoPilot().getError()) > 3) {
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+ Thread.sleep(100);
+ System.out.println(getNaveAtual().getAutoPilot().getError());
+ }
+ getNaveAtual().getAutoPilot().disengage();
+ control.setSAS(true);
+ control.setSASMode(SASMode.STABILITY_ASSIST);
+ }
+
+ private void getCloserToTarget(Vector targetPosition) throws InterruptedException, RPCException {
+ lastXTargetPos = targetPosition.x;
+ lastYTargetPos = targetPosition.y;
+ lastZTargetPos = targetPosition.z;
+
+ while (Math.abs(lastYTargetPos) >= DISTANCE_LIMIT) {
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+ targetPosition = new Vector(targetVessel.position(vesselRefFrame));
+ controlShipRCS(targetPosition, DISTANCE_LIMIT);
+ Thread.sleep(sleepTime);
+ }
+
+ }
+
+ public void startDocking() {
+ try {
+ // Setting up the control
+ control.setSAS(true);
+ control.setRCS(false);
+ control.setSASMode(SASMode.STABILITY_ASSIST);
+ createLines(positionMyDockingPort, positionTargetDockingPort);
+
+ // PRIMEIRA PARTE DO DOCKING: APROXIMAÇÃO
+ Vector targetPosition = new Vector(targetVessel.position(vesselRefFrame));
+ if (targetPosition.magnitude() > DISTANCE_LIMIT) {
+ // Apontar para o alvo:
+ Vector targetDirection = new Vector(getNaveAtual().position(orbitalRefVessel))
+ .subtract(new Vector(targetVessel.position(orbitalRefVessel))).multiply(-1);
+ pointToTarget(targetDirection);
+
+ control.setRCS(true);
+
+ getCloserToTarget(targetPosition);
+ }
+
+ control.setSAS(false);
+ control.setRCS(false);
+
+ // SEGUNDA PARTE FICAR DE FRENTE COM A DOCKING PORT:
+ Vector targetDockingPortDirection = new Vector(targetDockingPort.direction(orbitalRefVessel))
+ .multiply(-1);
+ pointToTarget(targetDockingPortDirection);
+
+ Thread.sleep(1000);
+ control.setRCS(true);
+ double safeDistance = 10;
+ while (true) {
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+ targetPosition = new Vector(targetDockingPort.position(vesselRefFrame))
+ .subtract(new Vector(myDockingPort.position(vesselRefFrame)));
+ if (targetPosition.magnitude() < safeDistance) {
+ safeDistance = 1;
+ }
+ controlShipRCS(targetPosition, safeDistance);
+ Thread.sleep(sleepTime);
+ }
+ } catch (RPCException | InterruptedException | IllegalArgumentException e) {
+ StatusJPanel.setStatusMessage("Docking aborted.");
+ }
+ }
+
+ /*
+ * Possibilidades do docking:
+ * primeiro: a nave ta na orientação certa, e só precisa seguir em frente X e Z
+ * = 0, Y positivo
+ * segundo: a nave ta na orientação certa, mas precisa corrigir a posição X e Z,
+ * Y positivo
+ * terceiro: a nave está atrás da docking port, precisa corrigir Y primeiro, Y
+ * negativo
+ * quarto: a nave está atrás da docking port, precisa afastar X e Z longe da
+ * nave primeiro, Y negativo
+ */
+
+ private enum DOCKING_STEPS {
+ APPROACH, LINE_UP_WITH_TARGET, GO_IN_FRONT_OF_TARGET
+ }
+
+ private DOCKING_STEPS checkDockingStep(Vector targetPosition, double forwardsDistanceLimit) {
+ double sidewaysDistance = Math.abs(targetPosition.x);
+ double upwardsDistance = Math.abs(targetPosition.z);
+ boolean isInFrontOfTarget = Math.signum(targetPosition.y) == 1;
+ boolean isOnTheBackOfTarget = Math.signum(targetPosition.y) == -1 && targetPosition.y < forwardsDistanceLimit;
+
+ if (isOnTheBackOfTarget) {
+ return DOCKING_STEPS.GO_IN_FRONT_OF_TARGET;
+ }
+ if (isInFrontOfTarget && (sidewaysDistance > 5 || upwardsDistance > 5)) {
+ return DOCKING_STEPS.LINE_UP_WITH_TARGET;
+ }
+ return DOCKING_STEPS.APPROACH;
+ }
+
+ private void controlShipRCS(Vector targetPosition, double forwardsDistanceLimit) {
+ try {
+ // Atualizar posições para linhas
+ positionMyDockingPort = new Vector(myDockingPort.position(vesselRefFrame));
+ updateLines(positionMyDockingPort, targetPosition);
+
+ // Calcular velocidade de cada eixo:
+ currentXAxisSpeed = (targetPosition.x - lastXTargetPos) * sleepTime;
+ currentYAxisSpeed = (targetPosition.y - lastYTargetPos) * sleepTime;
+ currentZAxisSpeed = (targetPosition.z - lastZTargetPos) * sleepTime;
+
+ dockingStep = checkDockingStep(targetPosition, forwardsDistanceLimit);
+ float forwardsError, upwardsError, sidewaysError = 0;
+ switch (dockingStep) {
+ case APPROACH:
+ // Calcular a aceleração para cada eixo no RCS:
+ forwardsError = calculateThrottle(forwardsDistanceLimit, forwardsDistanceLimit * 3, currentYAxisSpeed,
+ targetPosition.y, SPEED_LIMIT);
+ sidewaysError = calculateThrottle(0, 5, currentXAxisSpeed, targetPosition.x, SPEED_LIMIT);
+ upwardsError = calculateThrottle(0, 5, currentZAxisSpeed, targetPosition.z, SPEED_LIMIT);
+ control.setForward(forwardsError);
+ control.setRight(sidewaysError);
+ control.setUp(-upwardsError);
+ break;
+ case LINE_UP_WITH_TARGET:
+ forwardsError = calculateThrottle(forwardsDistanceLimit, forwardsDistanceLimit * 3, currentYAxisSpeed,
+ targetPosition.y, 0);
+ sidewaysError = calculateThrottle(0, 10, currentXAxisSpeed, targetPosition.x, SPEED_LIMIT);
+ upwardsError = calculateThrottle(0, 10, currentZAxisSpeed, targetPosition.z, SPEED_LIMIT);
+ control.setForward(forwardsError);
+ control.setRight(sidewaysError);
+ control.setUp(-upwardsError);
+ break;
+ case GO_IN_FRONT_OF_TARGET:
+ forwardsError = calculateThrottle(-20, -10, currentYAxisSpeed,
+ targetPosition.y, SPEED_LIMIT);
+ sidewaysError = calculateThrottle(0, 5, currentXAxisSpeed, targetPosition.x, 0);
+ upwardsError = calculateThrottle(0, 5, currentZAxisSpeed, targetPosition.z, 0);
+ control.setForward(forwardsError);
+ control.setRight(sidewaysError);
+ control.setUp(-upwardsError);
+ break;
+ }
+ System.out.println(dockingStep);
+
+ // Guardar últimas posições:
+ lastXTargetPos = targetPosition.x;
+ lastYTargetPos = targetPosition.y;
+ lastZTargetPos = targetPosition.z;
+ } catch (RPCException ignored) {
+ }
+ }
+
+ private float calculateThrottle(double minDistance, double maxDistance, double currentSpeed,
+ double currentPosition, double speedLimit) {
+ double limiter = Utilities.remap(minDistance, maxDistance, 0, 1, Math.abs(currentPosition), true);
+ double change = (Utilities.remap(-speedLimit, speedLimit, -1.0, 1.0,
+ currentSpeed + (Math.signum(currentPosition) * (limiter * speedLimit)), true));
+ return (float) change;
+ }
+
+ private void createLines(Vector start, Vector end) {
+ try {
+ distanceLine = drawing.addLine(start.toTriplet(),
+ end.toTriplet(), vesselRefFrame, true);
+ distLineXAxis = drawing.addLine(start.toTriplet(),
+ new Vector(end.x, 0.0, 0.0).toTriplet(),
+ vesselRefFrame, true);
+ distLineYAxis = drawing.addLine(start.toTriplet(),
+ new Vector(end.x, end.y, 0.0).toTriplet(),
+ vesselRefFrame, true);
+ distLineZAxis = drawing.addLine(start.toTriplet(),
+ end.toTriplet(),
+ vesselRefFrame, true);
+ distanceLine.setThickness(0.5f);
+ distLineXAxis.setThickness(0.25f);
+ distLineYAxis.setThickness(0.25f);
+ distLineZAxis.setThickness(0.25f);
+ distLineXAxis.setColor(new Vector(1.0, 0.0, 0.0).toTriplet());
+ distLineYAxis.setColor(new Vector(0.0, 1.0, 0.0).toTriplet());
+ distLineZAxis.setColor(new Vector(0.0, 0.0, 1.0).toTriplet());
+ } catch (RPCException e) {
+ }
+ }
+
+ private void updateLines(Vector start, Vector end) {
+ // Updating drawing lines:
+ try {
+ distanceLine.setStart(start.toTriplet());
+ distanceLine.setEnd(end.toTriplet());
+ distLineXAxis.setStart(start.toTriplet());
+ distLineXAxis.setEnd(new Vector(end.x, 0.0, 0.0).toTriplet());
+ distLineYAxis.setStart(distLineXAxis.getEnd());
+ distLineYAxis.setEnd(new Vector(end.x, end.y, 0.0).toTriplet());
+ distLineZAxis.setStart(distLineYAxis.getEnd());
+ distLineZAxis.setEnd(end.toTriplet());
+ } catch (RPCException e) {
+ }
+ }
+
+}
diff --git a/src/com/pesterenan/controllers/LandingController.java b/src/main/java/com/pesterenan/controllers/LandingController.java
similarity index 76%
rename from src/com/pesterenan/controllers/LandingController.java
rename to src/main/java/com/pesterenan/controllers/LandingController.java
index 55c0e34..df9072c 100644
--- a/src/com/pesterenan/controllers/LandingController.java
+++ b/src/main/java/com/pesterenan/controllers/LandingController.java
@@ -1,24 +1,28 @@
package com.pesterenan.controllers;
+import static com.pesterenan.MechPeste.getSpaceCenter;
+
+import java.util.Map;
+
import com.pesterenan.resources.Bundle;
import com.pesterenan.utils.ControlePID;
import com.pesterenan.utils.Modulos;
import com.pesterenan.utils.Navigation;
import com.pesterenan.utils.Utilities;
+
import krpc.client.RPCException;
import krpc.client.StreamException;
import krpc.client.services.SpaceCenter.VesselSituation;
-import java.util.Map;
-
public class LandingController extends Controller {
public static final double MAX_VELOCITY = 5;
- private static final double velP = 0.025;
- private static final double velI = 0.001;
- private static final double velD = 0.01;
- private final ControlePID altitudeCtrl = new ControlePID();
- private final ControlePID velocityCtrl = new ControlePID();
+ private static final long sleepTime = 50;
+ private static final double velP = 0.05;
+ private static final double velI = 0.005;
+ private static final double velD = 0.001;
+ private ControlePID altitudeCtrl;
+ private ControlePID velocityCtrl;
private Navigation navigation;
private final int HUNDRED_PERCENT = 100;
private double hoverAltitude;
@@ -37,8 +41,10 @@ public LandingController(Map commands) {
}
private void initializeParameters() {
- altitudeCtrl.adjustOutput(0, 1);
- velocityCtrl.adjustOutput(0, 1);
+ altitudeCtrl = new ControlePID(getSpaceCenter(), sleepTime);
+ velocityCtrl = new ControlePID(getSpaceCenter(), sleepTime);
+ altitudeCtrl.setOutput(0, 1);
+ velocityCtrl.setOutput(0, 1);
}
@Override
@@ -70,12 +76,11 @@ private void hoverArea() {
currentMode = MODE.GOING_UP;
} else {
currentMode = MODE.HOVERING;
- currentMode = MODE.HOVERING;
}
changeControlMode();
} catch (RPCException | StreamException ignored) {
}
- Thread.sleep(50);
+ Thread.sleep(sleepTime);
}
} catch (InterruptedException | RPCException ignored) {
// disengageAfterException(Bundle.getString("status_liftoff_abort"));
@@ -103,7 +108,7 @@ private void autoLanding() {
}
getNaveAtual().getControl().setBrakes(true);
changeControlMode();
- Thread.sleep(100);
+ Thread.sleep(sleepTime);
}
} catch (RPCException | StreamException | InterruptedException e) {
setCurrentStatus(Bundle.getString("status_ready"));
@@ -112,7 +117,7 @@ private void autoLanding() {
private void changeControlMode() throws RPCException, StreamException, InterruptedException {
adjustPIDbyTWR();
- double velPID, altPID;
+ double velPID, altPID = 0;
// Change vessel behavior depending on which mode is active
switch (currentMode) {
case DEORBITING:
@@ -128,19 +133,22 @@ private void changeControlMode() throws RPCException, StreamException, Interrupt
}
break;
case APPROACHING:
- altitudeCtrl.adjustOutput(0, 1);
- velocityCtrl.adjustOutput(0, 1);
+ altitudeCtrl.reset();
+ velocityCtrl.reset();
+ altitudeCtrl.setOutput(0, 1);
+ velocityCtrl.setOutput(0, 1);
double currentVelocity = calculateCurrentVelocityMagnitude();
double zeroVelocity = calculateZeroVelocityMagnitude();
double landingDistanceThreshold = Math.max(hoverAltitude, getMaxAcel(maxTWR) * 3);
double threshold = Utilities.clamp(
((currentVelocity + zeroVelocity) - landingDistanceThreshold) / landingDistanceThreshold, 0,
1);
- altPID = altitudeCtrl.calcPID(currentVelocity / zeroVelocity * HUNDRED_PERCENT, HUNDRED_PERCENT);
- velPID = velocityCtrl.calcPID(velVertical.get(), -Utilities.clamp(altitudeSup.get() * 0.1, 1, 10));
+ altPID = altitudeCtrl.calculate(currentVelocity / sleepTime, zeroVelocity / sleepTime);
+ velPID = velocityCtrl.calculate(velVertical.get() / sleepTime,
+ (-Utilities.clamp(altitudeSup.get() * 0.1, 3, 20) / sleepTime));
throttle(Utilities.linearInterpolation(velPID, altPID, threshold));
navigation.aimForLanding();
- if (threshold < 0.25 || altitudeSup.get() < landingDistanceThreshold) {
+ if (threshold < 0.15 || altitudeSup.get() < landingDistanceThreshold) {
hoverAltitude = landingDistanceThreshold;
getNaveAtual().getControl().setGear(true);
if (hoverAfterApproximation) {
@@ -153,31 +161,39 @@ private void changeControlMode() throws RPCException, StreamException, Interrupt
setCurrentStatus("Se aproximando do momento do pouso...");
break;
case GOING_UP:
- altitudeCtrl.adjustOutput(-0.5, 0.5);
- velocityCtrl.adjustOutput(-0.5, 0.5);
- altPID = altitudeCtrl.calcPID(altitudeErrorPercentage, HUNDRED_PERCENT);
- velPID = velocityCtrl.calcPID(velVertical.get(), MAX_VELOCITY);
+ altitudeCtrl.reset();
+ velocityCtrl.reset();
+ altitudeCtrl.setOutput(-0.5, 0.5);
+ velocityCtrl.setOutput(-0.5, 0.5);
+ altPID = altitudeCtrl.calculate(altitudeErrorPercentage, HUNDRED_PERCENT);
+ velPID = velocityCtrl.calculate(velVertical.get(), MAX_VELOCITY);
throttle(altPID + velPID);
navigation.aimAtRadialOut();
setCurrentStatus("Subindo altitude...");
break;
case GOING_DOWN:
+ altitudeCtrl.reset();
+ velocityCtrl.reset();
controlThrottleByMatchingVerticalVelocity(-MAX_VELOCITY);
navigation.aimAtRadialOut();
setCurrentStatus("Baixando altitude...");
break;
case LANDING:
+ altitudeCtrl.reset();
+ velocityCtrl.reset();
controlThrottleByMatchingVerticalVelocity(
- velHorizontal.get() > 2 ? 0 : -Utilities.clamp(altitudeSup.get() * 0.1, 1, 10));
+ velHorizontal.get() > 4 ? 0 : -Utilities.clamp(altitudeSup.get() * 0.1, 1, 10));
navigation.aimForLanding();
setCurrentStatus("Pousando...");
hasTheVesselLanded();
break;
case HOVERING:
- altitudeCtrl.adjustOutput(-0.5, 0.5);
- velocityCtrl.adjustOutput(-0.5, 0.5);
- altPID = altitudeCtrl.calcPID(altitudeErrorPercentage, HUNDRED_PERCENT);
- velPID = velocityCtrl.calcPID(velVertical.get(), 0);
+ altitudeCtrl.reset();
+ velocityCtrl.reset();
+ altitudeCtrl.setOutput(-0.5, 0.5);
+ velocityCtrl.setOutput(-0.5, 0.5);
+ altPID = altitudeCtrl.calculate(altitudeErrorPercentage, HUNDRED_PERCENT);
+ velPID = velocityCtrl.calculate(velVertical.get(), 0);
throttle(altPID + velPID);
navigation.aimAtRadialOut();
setCurrentStatus("Sobrevoando area...");
@@ -187,8 +203,8 @@ private void changeControlMode() throws RPCException, StreamException, Interrupt
private void controlThrottleByMatchingVerticalVelocity(double velocityToMatch) throws RPCException,
StreamException {
- velocityCtrl.adjustOutput(0, 1);
- throttle(velocityCtrl.calcPID(velVertical.get(), velocityToMatch));
+ velocityCtrl.setOutput(0, 1);
+ throttle(velocityCtrl.calculate(velVertical.get(), velocityToMatch + velHorizontal.get()));
}
private void deOrbitShip() throws RPCException, StreamException, InterruptedException {
@@ -202,13 +218,15 @@ private void deOrbitShip() throws RPCException, StreamException, InterruptedExce
navigation.aimForLanding();
setCurrentStatus(Bundle.getString("status_orienting_ship"));
ap.wait_();
- Thread.sleep(100);
+ Thread.sleep(sleepTime);
}
+ double targetPeriapsis = currentBody.getAtmosphereDepth();
+ targetPeriapsis = targetPeriapsis > 0 ? targetPeriapsis / 2 : -currentBody.getEquatorialRadius() / 2;
while (periastro.get() > -apoastro.get()) {
navigation.aimForLanding();
- throttle(altitudeCtrl.calcPID(-currentBody.getEquatorialRadius() / 2, periastro.get()));
+ throttle(altitudeCtrl.calculate(targetPeriapsis, periastro.get()));
setCurrentStatus(Bundle.getString("status_lowering_periapsis"));
- Thread.sleep(100);
+ Thread.sleep(sleepTime);
}
getNaveAtual().getControl().setRCS(false);
throttle(0.0f);
@@ -220,14 +238,11 @@ private void deOrbitShip() throws RPCException, StreamException, InterruptedExce
*/
private void adjustPIDbyTWR() throws RPCException, StreamException {
double currentTWR = Math.min(getTWR(), maxTWR);
- velocityCtrl.adjustPID(currentTWR * velP, velI, velD);
- altitudeCtrl.adjustPID(currentTWR * velP, velI, velD);
- }
-
- private double calculateCurrentVelocityMagnitude() throws RPCException, StreamException {
- double timeToGround = altitudeSup.get() / velVertical.get();
- double horizontalDistance = velHorizontal.get() * timeToGround;
- return calculateEllipticTrajectory(horizontalDistance, altitudeSup.get());
+ // double currentTWR = getMaxAcel(maxTWR);
+ double pGain = currentTWR / (sleepTime);
+ System.out.println(pGain);
+ altitudeCtrl.setPIDValues(pGain * 0.1, 0.0002, pGain * 0.1 * 2);
+ velocityCtrl.setPIDValues(pGain * 0.1, 0.1, 0.001);
}
private boolean hasTheVesselLanded() throws RPCException {
@@ -246,6 +261,12 @@ private boolean hasTheVesselLanded() throws RPCException {
return false;
}
+ private double calculateCurrentVelocityMagnitude() throws RPCException, StreamException {
+ double timeToGround = altitudeSup.get() / velVertical.get();
+ double horizontalDistance = velHorizontal.get() * timeToGround;
+ return calculateEllipticTrajectory(horizontalDistance, altitudeSup.get());
+ }
+
private double calculateZeroVelocityMagnitude() throws RPCException, StreamException {
double zeroVelocityDistance = calculateEllipticTrajectory(velHorizontal.get(), velVertical.get());
double zeroVelocityBurnTime = zeroVelocityDistance / getMaxAcel(maxTWR);
diff --git a/src/com/pesterenan/controllers/LiftoffController.java b/src/main/java/com/pesterenan/controllers/LiftoffController.java
similarity index 88%
rename from src/com/pesterenan/controllers/LiftoffController.java
rename to src/main/java/com/pesterenan/controllers/LiftoffController.java
index b565948..b81b0d8 100644
--- a/src/com/pesterenan/controllers/LiftoffController.java
+++ b/src/main/java/com/pesterenan/controllers/LiftoffController.java
@@ -1,5 +1,7 @@
package com.pesterenan.controllers;
+import static com.pesterenan.MechPeste.getSpaceCenter;
+
import com.pesterenan.MechPeste;
import com.pesterenan.resources.Bundle;
import com.pesterenan.utils.ControlePID;
@@ -18,14 +20,14 @@
public class LiftoffController extends Controller {
private static final float PITCH_UP = 90;
- private final ControlePID thrControl = new ControlePID();
+ private ControlePID thrControl;
private float currentPitch;
private float finalApoapsisAlt;
private float heading;
private float roll;
private float maxTWR;
- private boolean willDecoupleStages, willDeployPanelsAndRadiators;
+ private boolean willDecoupleStages, willOpenPanelsAndAntenna;
private String gravityCurveModel = Modulos.CIRCULAR.get();
private Navigation navigation;
@@ -43,9 +45,10 @@ private void initializeParameters() {
setRoll(Float.parseFloat(commands.get(Modulos.ROLAGEM.get())));
maxTWR = (float) Utilities.clamp(Float.parseFloat(commands.get(Modulos.MAX_TWR.get())), 1.2, 5.0);
setGravityCurveModel(commands.get(Modulos.INCLINACAO.get()));
- willDeployPanelsAndRadiators = Boolean.parseBoolean(commands.get(Modulos.ABRIR_PAINEIS.get()));
+ willOpenPanelsAndAntenna = Boolean.parseBoolean(commands.get(Modulos.ABRIR_PAINEIS.get()));
willDecoupleStages = Boolean.parseBoolean(commands.get(Modulos.USAR_ESTAGIOS.get()));
- thrControl.adjustOutput(0.0, 1.0);
+ thrControl = new ControlePID(getSpaceCenter(), 25);
+ thrControl.setOutput(0.0, 1.0);
}
@Override
@@ -79,7 +82,7 @@ private void gravityCurve() throws RPCException, StreamException, InterruptedExc
currentPitch = (float) (calculateCurrentPitch(altitudeProgress));
double currentMaxTWR = calculateTWRBasedOnPressure(currentPitch);
ap.setTargetPitch(currentPitch);
- throttle(Math.min(thrControl.calcPID(apoastro.get() / getFinalApoapsis() * 1000, 1000),
+ throttle(Math.min(thrControl.calculate(apoastro.get() / getFinalApoapsis() * 1000, 1000),
getMaxThrottleForTWR(currentMaxTWR)));
if (willDecoupleStages && isCurrentStageWithoutFuel()) {
@@ -87,7 +90,7 @@ private void gravityCurve() throws RPCException, StreamException, InterruptedExc
}
setCurrentStatus(String.format(Bundle.getString("status_liftoff_inclination") + " %.1f", currentPitch));
- Thread.sleep(250);
+ Thread.sleep(25);
if (Thread.interrupted()) {
throw new InterruptedException();
}
@@ -111,22 +114,22 @@ private void finalizeCurve() throws RPCException, StreamException, InterruptedEx
throw new InterruptedException();
}
navigation.aimAtPrograde();
- throttle(thrControl.calcPID(apoastro.get() / getFinalApoapsis() * 1000, 1000));
- Thread.sleep(100);
+ throttle(thrControl.calculate(apoastro.get() / getFinalApoapsis() * 1000, 1000));
+ Thread.sleep(25);
}
throttle(0.0f);
if (willDecoupleStages) {
jettisonFairings();
}
- if (willDeployPanelsAndRadiators) {
- deployPanelsAndRadiators();
+ if (willOpenPanelsAndAntenna) {
+ openPanelsAndAntenna();
}
}
private void circularizeOrbitOnApoapsis() {
setCurrentStatus(Bundle.getString("status_planning_orbit"));
Map commands = new HashMap<>();
- commands.put(Modulos.MODULO.get(), Modulos.MODULO_EXEC_MANOBRAS.get());
+ commands.put(Modulos.MODULO.get(), Modulos.MODULE_MANEUVER.get());
commands.put(Modulos.FUNCAO.get(), Modulos.APOASTRO.get());
commands.put(Modulos.AJUSTE_FINO.get(), String.valueOf(false));
MechPeste.newInstance().startModule(commands);
@@ -148,9 +151,10 @@ private void jettisonFairings() throws RPCException, InterruptedException {
}
}
- private void deployPanelsAndRadiators() throws RPCException, InterruptedException {
+ private void openPanelsAndAntenna() throws RPCException, InterruptedException {
getNaveAtual().getControl().setSolarPanels(true);
getNaveAtual().getControl().setRadiators(true);
+ getNaveAtual().getControl().setAntennas(true);
}
private double calculateCurrentPitch(double currentAltitude) {
diff --git a/src/com/pesterenan/controllers/ManeuverController.java b/src/main/java/com/pesterenan/controllers/ManeuverController.java
similarity index 52%
rename from src/com/pesterenan/controllers/ManeuverController.java
rename to src/main/java/com/pesterenan/controllers/ManeuverController.java
index 398c2d9..10f4f96 100644
--- a/src/com/pesterenan/controllers/ManeuverController.java
+++ b/src/main/java/com/pesterenan/controllers/ManeuverController.java
@@ -1,9 +1,21 @@
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.resources.Bundle;
+import com.pesterenan.utils.Attributes;
import com.pesterenan.utils.ControlePID;
import com.pesterenan.utils.Modulos;
import com.pesterenan.utils.Navigation;
+import com.pesterenan.utils.Vector;
+import com.pesterenan.views.RunManeuverJPanel;
+
import krpc.client.RPCException;
import krpc.client.Stream;
import krpc.client.StreamException;
@@ -11,20 +23,15 @@
import krpc.client.services.SpaceCenter.Node;
import krpc.client.services.SpaceCenter.Orbit;
import krpc.client.services.SpaceCenter.RCS;
+import krpc.client.services.SpaceCenter.ReferenceFrame;
+import krpc.client.services.SpaceCenter.Vessel;
import krpc.client.services.SpaceCenter.VesselSituation;
-import org.javatuples.Triplet;
-
-import java.util.List;
-import java.util.Map;
-
-import static com.pesterenan.MechPeste.getConnection;
-import static com.pesterenan.MechPeste.getSpaceCenter;
public class ManeuverController extends Controller {
public final static float CONST_GRAV = 9.81f;
- private final ControlePID ctrlRCS = new ControlePID();
- private final ControlePID ctrlManeuver = new ControlePID();
+ private ControlePID ctrlRCS;
+ private ControlePID ctrlManeuver;
private Navigation navigation;
private boolean fineAdjustment;
private double lowOrbitAltitude;
@@ -37,38 +44,65 @@ public ManeuverController(Map commands) {
}
private void initializeParameters() {
- ctrlRCS.adjustOutput(0.5, 1.0);
+ ctrlRCS = new ControlePID(getSpaceCenter(), 25);
+ ctrlManeuver = new ControlePID(getSpaceCenter(), 25);
+ ctrlManeuver.setPIDValues(1, 0.001, 0.1);
+ ctrlRCS.setOutput(0.5, 1.0);
fineAdjustment = canFineAdjust(commands.get(Modulos.AJUSTE_FINO.get()));
- lowOrbitAltitude = calculateSafeLowOrbitAltitude();
- System.out.println(lowOrbitAltitude);
+ try {
+ lowOrbitAltitude = new Attributes().getLowOrbitAltitude(currentBody.getName());
+ System.out.println("lowOrbitAltitude: " + lowOrbitAltitude);
+ } catch (RPCException e) {
+ }
}
@Override
public void run() {
calculateManeuver();
- executeNextManeuver();
+ if (!(commands.get(Modulos.FUNCAO.get()).equals(Modulos.RENDEZVOUS.get())
+ || commands.get(Modulos.FUNCAO.get()).equals(Modulos.ORBITA_BAIXA.get())
+ || commands.get(Modulos.FUNCAO.get()).equals(Modulos.AJUSTAR.get()))) {
+ executeNextManeuver();
+ }
}
- private double calculateSafeLowOrbitAltitude() {
- final double safeAltitude = 20000;
- double bodyRadius = 0, atmosphereDepth = 0;
+ private Node biEllipticTransferToOrbit(double targetAltitude, double timeToStart) {
+ double[] totalDv = { 0, 0, 0 };
try {
- bodyRadius = currentBody.getEquatorialRadius();
- System.out.println(bodyRadius);
- atmosphereDepth = currentBody.getAtmosphereDepth();
- System.out.println(atmosphereDepth);
- System.out.println(altitude.get());
- System.out.println(altitudeSup.get());
- System.out.println(apoastro.get());
- } catch (RPCException | StreamException ignored) {
+ Orbit currentOrbit = getNaveAtual().getOrbit();
+ double startingRadius = currentOrbit.getApoapsis();
+ double gravParameter = currentBody.getGravitationalParameter();
+
+ // Delta-v required to leave the current orbit
+ double deltaV1 = Math.sqrt(2 * gravParameter / startingRadius) - Math.sqrt(gravParameter / startingRadius);
+
+ // Calculate the intermediate radius for the intermediate orbit
+ double intermediateRadius = currentBody.getEquatorialRadius() + targetAltitude;
+
+ // Delta-v required to enter the intermediate orbit
+ double deltaV2 = Math.sqrt(gravParameter / intermediateRadius)
+ - Math.sqrt(2 * gravParameter / intermediateRadius);
+
+ // Calculate the final radius for the target orbit
+ double targetRadius = currentBody.getEquatorialRadius() + targetAltitude;
+
+ // Delta-v required to leave the intermediate orbit and enter the target orbit
+ double deltaV3 = Math.sqrt(2 * gravParameter / intermediateRadius)
+ - Math.sqrt(gravParameter / intermediateRadius);
+ double deltaV4 = Math.sqrt(gravParameter / targetRadius) - Math.sqrt(2 * gravParameter / targetRadius);
+
+ // Total delta-v for the bi-elliptic transfer
+ totalDv[0] = deltaV1 + deltaV2 + deltaV3 + deltaV4;
+ } catch (RPCException e) {
+ // Handle the exception
}
- return bodyRadius + (atmosphereDepth > 0 ? atmosphereDepth + safeAltitude : safeAltitude);
+ return createManeuver(timeToStart, totalDv);
}
public void calculateManeuver() {
try {
tuneAutoPilot();
- System.out.println(commands);
+ System.out.println(commands + " calculate maneuvers");
if (commands.get(Modulos.FUNCAO.get()).equals(Modulos.EXECUTAR.get())) {
return;
}
@@ -77,12 +111,15 @@ public void calculateManeuver() {
throw new InterruptedException();
}
if (commands.get(Modulos.FUNCAO.get()).equals(Modulos.AJUSTAR.get())) {
- this.alignPlanes();
+ this.alignPlanesWithTargetVessel();
+ return;
+ }
+ if (commands.get(Modulos.FUNCAO.get()).equals(Modulos.RENDEZVOUS.get())) {
+ this.rendezvousWithTargetVessel();
return;
}
if (commands.get(Modulos.FUNCAO.get()).equals(Modulos.ORBITA_BAIXA.get())) {
- hohmannTransferToOrbit(lowOrbitAltitude, getNaveAtual().getOrbit().getTimeToPeriapsis());
- hohmannTransferToOrbit(lowOrbitAltitude, getNaveAtual().getOrbit().getTimeToPeriapsis());
+ biEllipticTransferToOrbit(lowOrbitAltitude, getNaveAtual().getOrbit().getTimeToPeriapsis());
return;
}
double gravParameter = currentBody.getGravitationalParameter();
@@ -111,7 +148,7 @@ public void matchOrbitApoapsis() {
try {
Orbit targetOrbit = getTargetOrbit();
System.out.println(targetOrbit.getApoapsis() + "-- APO");
- Node maneuver = hohmannTransferToOrbit(targetOrbit.getApoapsis(),
+ Node maneuver = biEllipticTransferToOrbit(targetOrbit.getApoapsis(),
getNaveAtual().getOrbit().getTimeToPeriapsis());
while (true) {
if (Thread.interrupted()) {
@@ -124,37 +161,16 @@ public void matchOrbitApoapsis() {
break;
}
double dvPrograde = maneuver.getPrograde();
- double ctrlOutput = ctrlManeuver.calcPID(currentDeltaApo, 0);
+ double ctrlOutput = ctrlManeuver.calculate(currentDeltaApo, 0);
maneuver.setPrograde(dvPrograde - (ctrlOutput));
- Thread.sleep(50);
+ Thread.sleep(25);
}
} catch (Exception e) {
setCurrentStatus("Não foi possivel ajustar a inclinação");
}
}
- private Node hohmannTransferToOrbit(double targetAltitude, double timeToStart) {
- double[] totalDv = { 0, 0, 0 };
- try {
- double startingRadius = Math.max(getNaveAtual().getOrbit().getApoapsis(),
- getNaveAtual().getOrbit().getPeriapsis());
- System.out.println(startingRadius + " --- " + targetAltitude);
- double gravParameter = currentBody.getGravitationalParameter();
- // Delta-v required to leave the current orbit
- double deltaV1 = Math.sqrt(2 * gravParameter / startingRadius) - Math.sqrt(gravParameter / startingRadius);
- // Delta-v required to enter the target orbit
- double deltaV2 = Math.sqrt(gravParameter / targetAltitude) - Math.sqrt(2 * gravParameter / targetAltitude);
- System.out.println(deltaV1);
- System.out.println(deltaV2);
-
- // Dv taken between the two points
- totalDv[0] = deltaV2 + deltaV1;
- } catch (RPCException e) {
- }
- return createManeuver(timeToStart, totalDv);
- }
-
private Node createManeuverAtClosestIncNode(Orbit targetOrbit) {
double uTatClosestNode = 1;
double[] dv = { 0, 0, 0 };
@@ -173,36 +189,148 @@ private double[] getTimeToIncNodes(Orbit targetOrbit) throws RPCException {
return new double[] { vesselOrbit.uTAtTrueAnomaly(ascendingNode), vesselOrbit.uTAtTrueAnomaly(descendingNode) };
}
- public void alignPlanes() {
+ private void alignPlanesWithTargetVessel() {
try {
- Orbit targetOrbit = getTargetOrbit();
- Node maneuver = createManeuverAtClosestIncNode(targetOrbit);
- double[] incNodesUt = getTimeToIncNodes(targetOrbit);
+ Vessel vessel = getNaveAtual();
+ Orbit vesselOrbit = getNaveAtual().getOrbit();
+ Orbit targetVesselOrbit = getSpaceCenter().getTargetVessel().getOrbit();
+ boolean hasManeuverNodes = vessel.getControl().getNodes().size() > 0;
+ System.out.println("hasManeuverNodes: " + hasManeuverNodes);
+ if (!hasManeuverNodes) {
+ RunManeuverJPanel.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];
- double timeToExecute = 0;
- while (timeToExecute < 5000) {
- if (Thread.interrupted()) {
- throw new InterruptedException();
- }
- double currentDeltaInc = compareOrbitParameter(maneuver.getOrbit(), targetOrbit, Compare.INC);
- String deltaIncFormatted = String.format("%.2f", currentDeltaInc);
- System.out.println(deltaIncFormatted);
- if (deltaIncFormatted.equals(String.format("%.2f", 10.00))) {
- break;
+ RunManeuverJPanel.positionManeuverAt(closestIsAN ? "ascending" : "descending");
+ double currentInclination = Math
+ .toDegrees(currentManeuver.getOrbit().relativeInclination(targetVesselOrbit));
+ ctrlManeuver.setTimeSample(25);
+ while (currentInclination > 0.05) {
+ currentInclination = Math
+ .toDegrees(currentManeuver.getOrbit().relativeInclination(targetVesselOrbit));
+ double ctrlOutput = ctrlManeuver.calculate(currentInclination * 100, 0);
+ currentManeuver.setNormal(currentManeuver.getNormal() + (closestIsAN ? ctrlOutput : -ctrlOutput));
+ Thread.sleep(25);
+ }
+ } catch (Exception err) {
+ System.err.println(err);
+ }
+ }
+
+ private void rendezvousWithTargetVessel() {
+ try {
+ boolean hasManeuverNodes = getNaveAtual().getControl().getNodes().size() > 0;
+ List currentManeuvers = getNaveAtual().getControl().getNodes();
+ Node lastManeuverNode;
+ double lastManeuverNodeUT = 60;
+ if (hasManeuverNodes) {
+ currentManeuvers = getNaveAtual().getControl().getNodes();
+ lastManeuverNode = currentManeuvers.get(currentManeuvers.size() - 1);
+ lastManeuverNodeUT += lastManeuverNode.getUT();
+ RunManeuverJPanel.createManeuver(lastManeuverNodeUT);
+ } else {
+ RunManeuverJPanel.createManeuver();
+ }
+ currentManeuvers = getNaveAtual().getControl().getNodes();
+ lastManeuverNode = currentManeuvers.get(currentManeuvers.size() - 1);
+
+ Orbit activeVesselOrbit = getNaveAtual().getOrbit();
+ Orbit targetVesselOrbit = getSpaceCenter().getTargetVessel().getOrbit();
+ ReferenceFrame currentBodyRefFrame = activeVesselOrbit.getBody().getNonRotatingReferenceFrame();
+
+ double angularDiff = 10;
+ while (angularDiff >= 0.005) {
+ double maneuverUT = lastManeuverNode.getUT();
+ double targetOrbitPosition = new Vector(
+ targetVesselOrbit.positionAt(maneuverUT, currentBodyRefFrame))
+ .magnitude();
+ double maneuverAP = lastManeuverNode.getOrbit().getApoapsis();
+ double maneuverPE = lastManeuverNode.getOrbit().getPeriapsis();
+ ctrlManeuver.setPIDValues(0.25, 0.0, 0.01);
+ ctrlManeuver.setOutput(-100, 100);
+
+ if (targetOrbitPosition < maneuverPE) {
+ while (Math.floor(targetOrbitPosition) != Math.floor(maneuverPE)) {
+ lastManeuverNode.setPrograde(
+ lastManeuverNode.getPrograde()
+ + ctrlManeuver.calculate(maneuverPE / targetOrbitPosition * 1000, 1000));
+ maneuverPE = lastManeuverNode.getOrbit().getPeriapsis();
+ Thread.sleep(25);
+ }
}
- double dvNormal = maneuver.getNormal();
- double ctrlOutput = ctrlManeuver.calcPID(currentDeltaInc, 10.0);// * limitPIDOutput(Math.abs
- // (currentDeltaInc));
- if ((closestIsAN ? currentDeltaInc : -currentDeltaInc) > 0.0) {
- maneuver.setNormal(dvNormal + (ctrlOutput));
- } else {
- maneuver.setNormal(dvNormal - (ctrlOutput));
+
+ if (targetOrbitPosition > maneuverAP) {
+ while (Math.floor(targetOrbitPosition) != Math.floor(maneuverAP)) {
+ lastManeuverNode.setPrograde(
+ lastManeuverNode.getPrograde()
+ + ctrlManeuver.calculate(maneuverAP / targetOrbitPosition * 1000, 1000));
+ maneuverAP = lastManeuverNode.getOrbit().getApoapsis();
+ Thread.sleep(25);
+ }
}
- timeToExecute += 25;
+ angularDiff = calculatePhaseAngle(lastManeuverNode.getOrbit().positionAt(maneuverUT, currentBodyRefFrame),
+ getSpaceCenter().getTargetVessel().getOrbit().positionAt(maneuverUT, currentBodyRefFrame));
+ maneuverUT = lastManeuverNode.getUT();
+ lastManeuverNode.setUT(
+ lastManeuverNode.getUT()
+ + ctrlManeuver.calculate(-angularDiff * 100, 0));
+ System.out.println(angularDiff);
Thread.sleep(25);
}
- } catch (Exception e) {
- setCurrentStatus("Não foi possivel ajustar a inclinação");
+ // double mu = currentBody.getGravitationalParameter();
+ // double time = 1000;
+ //
+ // double hohmannTransferDistance =
+ // lastManeuverNode.getOrbit().getSemiMajorAxis();
+ // double timeOfFlight = Math.PI * Math.sqrt(Math.pow(hohmannTransferDistance,
+ // 3) / mu);
+ // double angle = activeVesselOrbit.getMeanAnomalyAtEpoch();
+ // double omegaInterceptor = Math
+ // .sqrt(mu /
+ // Math.pow(activeVesselOrbit.radiusAt(getSpaceCenter().getUT()), 3));
+ // // rad/s
+ // double omegaTarget = Math.sqrt(mu /
+ // Math.pow(targetVesselOrbit.radiusAt(getSpaceCenter().getUT()), 3)); // rad/s
+ // // double leadAngle = omegaTarget * timeOfFlight; // rad
+ // double leadAngle = targetVesselOrbit.getMeanAnomalyAtEpoch(); // rad
+ // double phaseAngle = Math.PI - leadAngle; // rad
+ // double calcAngle = (phaseAngle - angle);
+ // calcAngle = calcAngle < 0 ? calcAngle + (Math.PI * 2) : calcAngle;
+ // double waitTime = calcAngle / (omegaTarget - omegaInterceptor);
+ // time = waitTime;
+ //
+ // lastManeuverNode.setUT(getSpaceCenter().getUT() + time);
+ // ctrlManeuver.setOutput(-100, 100);
+ // ctrlManeuver.setPIDValues(0.05, 0.1, 0.01);
+ // double closestApproach =
+ // lastManeuverNode.getOrbit().distanceAtClosestApproach(targetVesselOrbit);
+ // System.out.println(closestApproach);
+ // System.out.println("Ajustando tempo de Rendezvous...");
+ // while (Math.round(closestApproach) > 100) {
+ // if (closestApproach < 100000) {
+ // ctrlManeuver.setOutput(-10, 10);
+ // } else if (closestApproach < 10000) {
+ // ctrlManeuver.setOutput(-1, 1);
+ // } else {
+ // ctrlManeuver.setOutput(-100, 100);
+ // }
+ // maneuverUT = ctrlManeuver.calculate(-closestApproach, 0);
+ // lastManeuverNode.setUT(lastManeuverNode.getUT() + maneuverUT);
+ // System.out.println("Closest " + (closestApproach));
+ // closestApproach =
+ // targetVesselOrbit.distanceAtClosestApproach(lastManeuverNode.getOrbit());
+ // Thread.sleep(25);
+ // }
+ // lastManeuverNode.setUT(lastManeuverNode.getUT() -
+ // lastManeuverNode.getOrbit().getPeriod() / 2);
+ } catch (
+
+ Exception err) {
}
}
@@ -331,31 +459,33 @@ public void executeBurn(Node noDeManobra, double duracaoDaQueima) {
Thread.sleep(100);
}
// Executar a manobra:
- Stream> queimaRestante = getConnection().addStream(noDeManobra,
+ Stream> remainingBurn = getConnection().addStream(noDeManobra,
"remainingBurnVector", noDeManobra.getReferenceFrame());
setCurrentStatus(Bundle.getString("status_maneuver_executing"));
while (noDeManobra != null) {
+ double burnDvLeft = remainingBurn.get().getValue1();
if (Thread.interrupted()) {
throw new InterruptedException();
}
- if (queimaRestante.get().getValue1() < (fineAdjustment ? 2 : 0.5)) {
+ if (burnDvLeft < (fineAdjustment ? 2 : 0.5)) {
throttle(0.0f);
break;
}
navigation.aimAtManeuver(noDeManobra);
- throttle(ctrlManeuver.calcPID((noDeManobra.getDeltaV() - Math.floor(queimaRestante.get().getValue1())) /
- noDeManobra.getDeltaV() * 1000, 1000));
- Thread.sleep(50);
+ float limitValue = burnDvLeft > 100 ? 1000 : 100;
+ throttle(ctrlManeuver.calculate((noDeManobra.getDeltaV() - Math.floor(burnDvLeft)) /
+ noDeManobra.getDeltaV() * limitValue, limitValue));
+ Thread.sleep(25);
}
throttle(0.0f);
if (fineAdjustment) {
- adjustManeuverWithRCS(queimaRestante);
+ adjustManeuverWithRCS(remainingBurn);
}
ap.setReferenceFrame(surfaceReferenceFrame);
ap.disengage();
getNaveAtual().getControl().setSAS(true);
getNaveAtual().getControl().setRCS(false);
- queimaRestante.remove();
+ remainingBurn.remove();
noDeManobra.remove();
setCurrentStatus(Bundle.getString("status_ready"));
} catch (StreamException | RPCException e) {
@@ -372,7 +502,7 @@ private void adjustManeuverWithRCS(Stream> remai
if (Thread.interrupted()) {
throw new InterruptedException();
}
- getNaveAtual().getControl().setForward((float) ctrlRCS.calcPID(-remainingDeltaV.get().getValue1() * 10,
+ getNaveAtual().getControl().setForward((float) ctrlRCS.calculate(-remainingDeltaV.get().getValue1() * 10,
0));
Thread.sleep(25);
}
@@ -397,8 +527,29 @@ private boolean canFineAdjust(String string) {
return false;
}
+ private double calculatePhaseAngle(Triplet startPos, Triplet endPos)
+ throws RPCException, InterruptedException {
+ double targetPhaseAngle = 10;
+ double angularDifference = 15;
+ Vector startPosition = new Vector(startPos);
+ Vector endPosition = new Vector(endPos);
+
+ // Phase angle
+ double dot = endPosition.dotProduct(startPosition);
+ double det = endPosition.determinant(startPosition);
+ targetPhaseAngle = Math.atan2(det, dot);
+
+ double targetOrbit = endPosition.magnitude();
+
+ double activeVesselSMA = getNaveAtual().getOrbit().getSemiMajorAxis();
+ angularDifference = targetPhaseAngle + Math.PI
+ * (1 - (1 / (2 * Math.sqrt(2))) * Math.sqrt(Math.pow((activeVesselSMA / targetOrbit + 1), 3)));
+
+ return Math.abs(angularDifference);
+ }
+
enum Compare {
INC, AP, PE
}
-}
\ No newline at end of file
+}
diff --git a/src/com/pesterenan/controllers/RoverController.java b/src/main/java/com/pesterenan/controllers/RoverController.java
similarity index 98%
rename from src/com/pesterenan/controllers/RoverController.java
rename to src/main/java/com/pesterenan/controllers/RoverController.java
index f094e68..aeab195 100644
--- a/src/com/pesterenan/controllers/RoverController.java
+++ b/src/main/java/com/pesterenan/controllers/RoverController.java
@@ -45,8 +45,8 @@ private void initializeParameters() {
roverReferenceFrame = getNaveAtual().getReferenceFrame();
roverDirection = new Vector(getNaveAtual().direction(roverReferenceFrame));
pathFinding = new PathFinding();
- acelCtrl.adjustOutput(0, 1);
- sterringCtrl.adjustOutput(-1, 1);
+ acelCtrl.setOutput(0, 1);
+ sterringCtrl.setOutput(-1, 1);
isAutoRoverRunning = true;
} catch (RPCException ignored) {
}
@@ -206,10 +206,10 @@ private void driveRover() throws RPCException, IOException, StreamException {
double deltaAngle = Math.abs(targetAndRadarAngle - roverAngle);
getNaveAtual().getControl().setSAS(deltaAngle < 1);
// Control Rover Throttle
- setRoverThrottle(acelCtrl.calcPID(velHorizontal.get() / maxSpeed * 50, 50));
+ setRoverThrottle(acelCtrl.calculate(velHorizontal.get() / maxSpeed * 50, 50));
// Control Rover Steering
if (deltaAngle > 1) {
- setRoverSteering(sterringCtrl.calcPID(roverAngle / (targetAndRadarAngle) * 100, 100));
+ setRoverSteering(sterringCtrl.calculate(roverAngle / (targetAndRadarAngle) * 100, 100));
} else {
setRoverSteering(0.0f);
}
@@ -314,4 +314,4 @@ private void setRoverSteering(double steering) throws RPCException {
private enum MODE {
DRIVE, NEXT_POINT, CHARGING
}
-}
\ No newline at end of file
+}
diff --git a/src/com/pesterenan/model/ActiveVessel.java b/src/main/java/com/pesterenan/model/ActiveVessel.java
similarity index 95%
rename from src/com/pesterenan/model/ActiveVessel.java
rename to src/main/java/com/pesterenan/model/ActiveVessel.java
index 2fd88d1..99efa65 100644
--- a/src/com/pesterenan/model/ActiveVessel.java
+++ b/src/main/java/com/pesterenan/model/ActiveVessel.java
@@ -6,6 +6,7 @@
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.Modulos;
import com.pesterenan.utils.Telemetry;
@@ -182,7 +183,7 @@ public void startModule(Map commands) {
controller = new LandingController(commands);
runningModule = true;
}
- if (currentFunction.equals(Modulos.MODULO_EXEC_MANOBRAS.get())) {
+ if (currentFunction.equals(Modulos.MODULE_MANEUVER.get())) {
controller = new ManeuverController(commands);
runningModule = true;
}
@@ -190,6 +191,11 @@ public void startModule(Map commands) {
controller = new RoverController(commands);
runningModule = true;
}
+ if (currentFunction.equals(Modulos.MODULO_DOCKING.get())) {
+ controller = new DockingController(commands);
+ System.out.println("escolheu modulo docking");
+ runningModule = true;
+ }
controllerThread = new Thread(controller, currentVesselId + " - " + currentFunction);
controllerThread.start();
}
@@ -227,7 +233,7 @@ public void cancelControl() {
}
}
- public boolean hasModuleRunning() {
- return runningModule;
- }
+ public boolean hasModuleRunning() {
+ return runningModule;
+ }
}
diff --git a/src/com/pesterenan/resources/Bundle.java b/src/main/java/com/pesterenan/resources/Bundle.java
similarity index 73%
rename from src/com/pesterenan/resources/Bundle.java
rename to src/main/java/com/pesterenan/resources/Bundle.java
index 5866198..3523229 100644
--- a/src/com/pesterenan/resources/Bundle.java
+++ b/src/main/java/com/pesterenan/resources/Bundle.java
@@ -1,12 +1,12 @@
package com.pesterenan.resources;
+import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class Bundle {
- public static final String BUNDLE_NAME = Bundle.class.getPackage().getName() + ".MechPesteBundle"; //$NON-NLS-1$
-
- public static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+ public static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("MechPesteBundle",
+ Locale.getDefault());
private Bundle() {
}
diff --git a/src/com/pesterenan/updater/KrpcInstaller.java b/src/main/java/com/pesterenan/updater/KrpcInstaller.java
similarity index 94%
rename from src/com/pesterenan/updater/KrpcInstaller.java
rename to src/main/java/com/pesterenan/updater/KrpcInstaller.java
index 7d548c5..76e835f 100644
--- a/src/com/pesterenan/updater/KrpcInstaller.java
+++ b/src/main/java/com/pesterenan/updater/KrpcInstaller.java
@@ -16,8 +16,7 @@
public class KrpcInstaller {
static final int BUFFER = 2048;
- private static final String KRPC_GITHUB_LINK =
- "https://github.com/krpc/krpc/releases/download/v0.5.1/krpc-0.5.1.zip";
+ private static final String KRPC_GITHUB_LINK = "https://github.com/krpc/krpc/releases/download/v0.5.2/krpc-0.5.2.zip";
private static String KSP_FOLDER = null;
public static String getKspFolder() {
@@ -43,7 +42,7 @@ public static void downloadKrpc() {
krpcLink = new URL(KRPC_GITHUB_LINK);
ReadableByteChannel readableByteChannel = Channels.newChannel(krpcLink.openStream());
- FileOutputStream fos = new FileOutputStream(KSP_FOLDER + "\\krpc-0.5.1.zip");
+ FileOutputStream fos = new FileOutputStream(KSP_FOLDER + "\\krpc-0.5.2.zip");
fos.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
fos.close();
@@ -60,7 +59,7 @@ public static void unzipKrpc() {
}
BufferedOutputStream dest;
// zipped input
- FileInputStream fis = new FileInputStream(KSP_FOLDER + "\\krpc-0.5.1.zip");
+ FileInputStream fis = new FileInputStream(KSP_FOLDER + "\\krpc-0.5.2.zip");
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
@@ -91,4 +90,4 @@ public static void unzipKrpc() {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/pesterenan/utils/Attributes.java b/src/main/java/com/pesterenan/utils/Attributes.java
new file mode 100644
index 0000000..1046b85
--- /dev/null
+++ b/src/main/java/com/pesterenan/utils/Attributes.java
@@ -0,0 +1,33 @@
+package com.pesterenan.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Attributes {
+
+ private static Map safeLowOrbitAltitudes = new HashMap();
+
+ public Attributes() {
+ safeLowOrbitAltitudes.put("Bop", 10_000.0);
+ safeLowOrbitAltitudes.put("Dres", 20_000.0);
+ safeLowOrbitAltitudes.put("Duna", 60_000.0);
+ safeLowOrbitAltitudes.put("Eeloo", 20_000.0);
+ safeLowOrbitAltitudes.put("Eve", 100_000.0);
+ safeLowOrbitAltitudes.put("Gilly", 10_000.0);
+ safeLowOrbitAltitudes.put("Ike", 20_000.0);
+ safeLowOrbitAltitudes.put("Jool", 220_000.0);
+ safeLowOrbitAltitudes.put("Kerbin", 80_000.0);
+ safeLowOrbitAltitudes.put("Laythe", 80_000.0);
+ safeLowOrbitAltitudes.put("Minmus", 10_000.0);
+ safeLowOrbitAltitudes.put("Moho", 35_000.0);
+ safeLowOrbitAltitudes.put("Mun", 10_000.0);
+ safeLowOrbitAltitudes.put("Pol", 10_000.0);
+ safeLowOrbitAltitudes.put("Sun", 350_000.0);
+ safeLowOrbitAltitudes.put("Tylo", 40_000.0);
+ safeLowOrbitAltitudes.put("Vall", 20_000.0);
+ }
+
+ public double getLowOrbitAltitude(String celestialBody) {
+ return safeLowOrbitAltitudes.getOrDefault(celestialBody, 10_000.0);
+ };
+}
diff --git a/src/main/java/com/pesterenan/utils/ControlePID.java b/src/main/java/com/pesterenan/utils/ControlePID.java
new file mode 100644
index 0000000..51ea12f
--- /dev/null
+++ b/src/main/java/com/pesterenan/utils/ControlePID.java
@@ -0,0 +1,104 @@
+package com.pesterenan.utils;
+
+import krpc.client.RPCException;
+import krpc.client.services.SpaceCenter;
+
+public class ControlePID {
+ private SpaceCenter spaceCenter = null;
+ private double outputMin = -1;
+ private double outputMax = 1;
+ private double kp = 0.025;
+ private double ki = 0.001;
+ private double kd = 0.01;
+ private double integralTerm = 0.0;
+ private double previousError, previousMeasurement, lastTime = 0.0;
+ private double timeSample = 0.025; // 25 millisegundos
+ private double proportionalTerm;
+ private double derivativeTerm;
+
+ public ControlePID() {
+ }
+
+ public ControlePID(SpaceCenter spaceCenter, double timeSample) {
+ this.spaceCenter = spaceCenter;
+ setTimeSample(timeSample);
+ }
+
+ public ControlePID(double kp, double ki, double kd, double outputMin, double outputMax) {
+ this.kp = kp;
+ this.ki = ki;
+ this.kd = kd;
+ this.outputMin = outputMin;
+ this.outputMax = outputMax;
+ }
+
+ public void reset() {
+ this.previousError = 0;
+ this.previousMeasurement = 0;
+ this.proportionalTerm = 0;
+ this.integralTerm = 0;
+ this.derivativeTerm = 0;
+ }
+
+ public double calculate(double measurement, double setPoint) {
+ double now = this.getCurrentTime();
+ double changeInTime = now - lastTime;
+
+ if (changeInTime >= timeSample) {
+ // Error signal
+ double error = setPoint - measurement;
+ // Proportional
+ proportionalTerm = kp * error;
+
+ // Integral
+ // integralTerm += 0.5f * ki * timeSample * (error + previousError);
+ // integralTerm += ki * (error + previousError);
+ integralTerm = ki * (integralTerm + (error * timeSample));
+ integralTerm = limitOutput(integralTerm);
+
+ derivativeTerm = kd * ((error - previousError) / timeSample);
+ previousError = error;
+ lastTime = now;
+ }
+ return limitOutput(proportionalTerm + integralTerm + derivativeTerm);
+ }
+
+ private double limitOutput(double value) {
+ return Utilities.clamp(value, outputMin, outputMax);
+ }
+
+ public void setOutput(double min, double max) {
+ if (min > max) {
+ return;
+ }
+ outputMin = min;
+ outputMax = max;
+ integralTerm = limitOutput(integralTerm);
+ }
+
+ public void setPIDValues(double Kp, double Ki, double Kd) {
+ if (Kp > 0) {
+ this.kp = Kp;
+ }
+ if (Ki >= 0) {
+ this.ki = Ki;
+ }
+ if (Kd >= 0) {
+ this.kd = Kd;
+ }
+ }
+
+ public void setTimeSample(double milliseconds) {
+ timeSample = milliseconds > 0 ? milliseconds / 1000 : timeSample;
+ }
+
+ private double getCurrentTime() {
+ try {
+ return spaceCenter.getUT();
+ } catch (RPCException | NullPointerException ignored) {
+ System.err.println("Não foi possível buscar o tempo do jogo, retornando do sistema");
+ return System.currentTimeMillis();
+ }
+ }
+
+}
diff --git a/src/com/pesterenan/utils/Modulos.java b/src/main/java/com/pesterenan/utils/Modulos.java
similarity index 87%
rename from src/com/pesterenan/utils/Modulos.java
rename to src/main/java/com/pesterenan/utils/Modulos.java
index 85222ba..f31f409 100644
--- a/src/com/pesterenan/utils/Modulos.java
+++ b/src/main/java/com/pesterenan/utils/Modulos.java
@@ -18,21 +18,23 @@ public enum Modulos {
MAX_TWR("Max_TWR"),
MODULO_CRIAR_MANOBRAS("CRIAR_MANOBRAS"),
MODULO_DECOLAGEM("LIFTOFF"),
- MODULO_EXEC_MANOBRAS("MANEUVER"),
+ MODULE_MANEUVER("MANEUVER"),
MODULO_POUSO_SOBREVOAR("HOVER"),
MODULO_POUSO("LANDING"),
MODULO_ROVER("ROVER"),
+ MODULO_DOCKING("DOCKING"),
MODULO_TELEMETRIA("TELEMETRY"),
MODULO("Módulo"),
NAVE_ALVO("Nave alvo"),
NOME_MARCADOR("Nome do marcador"),
ORBITA_BAIXA("ÓRBITA BAIXA"),
PERIASTRO("Periastro"),
- POUSAR("Pousar nave"),
+ POUSAR("Pousar nave"),
QUADRATICA("Quadrática"),
+ RENDEZVOUS("Rendezvous"),
ROLAGEM("Rolagem"),
SINUSOIDAL("Sinusoidal"),
- SOBREVOO_POS_POUSO("SOBREVOO PÓS POUSO"),
+ SOBREVOO_POS_POUSO("SOBREVOO PÓS POUSO"),
TIPO_ALVO_ROVER("Tipo de Alvo do Rover"),
USAR_ESTAGIOS("Usar Estágios"),
VELOCIDADE_MAX("Velocidade Máxima");
diff --git a/src/main/java/com/pesterenan/utils/Navigation.java b/src/main/java/com/pesterenan/utils/Navigation.java
new file mode 100644
index 0000000..389b33e
--- /dev/null
+++ b/src/main/java/com/pesterenan/utils/Navigation.java
@@ -0,0 +1,158 @@
+package com.pesterenan.utils;
+
+import krpc.client.RPCException;
+import krpc.client.Stream;
+import krpc.client.StreamException;
+import org.javatuples.Triplet;
+
+import static com.pesterenan.MechPeste.getConnection;
+import static com.pesterenan.MechPeste.getSpaceCenter;
+import static krpc.client.services.SpaceCenter.*;
+
+public class Navigation {
+
+ public static final Triplet RADIAL = new Triplet<>(1.0, 0.0, 0.0);
+ public static final Triplet ANTI_RADIAL = new Triplet<>(-1.0, 0.0, 0.0);
+ public static final Triplet PROGRADE = new Triplet<>(0.0, 1.0, 0.0);
+ public static final Triplet RETROGRADE = new Triplet<>(0.0, -1.0, 0.0);
+ public static final Triplet NORMAL = new Triplet<>(0.0, 0.0, 1.0);
+ public static final Triplet ANTI_NORMAL = new Triplet<>(0.0, 0.0, -1.0);
+ // private Drawing drawing;
+ private Vessel currentVessel;
+ private Flight flightParameters;
+ private Stream horizontalSpeed;
+ private ReferenceFrame orbitalReference;
+
+ public Navigation(Vessel currentVessel) {
+ this.currentVessel = currentVessel;
+ initializeParameters();
+ }
+
+ private void initializeParameters() {
+ try {
+ // drawing = Drawing.newInstance(getConexao());
+ orbitalReference = currentVessel.getOrbit().getBody().getReferenceFrame();
+ flightParameters = currentVessel.flight(orbitalReference);
+ horizontalSpeed = getConnection().addStream(flightParameters, "getHorizontalSpeed");
+ } catch (RPCException | StreamException ignored) {
+ }
+ }
+
+ public void aimAtManeuver(Node maneuver) throws RPCException {
+ aimAtDirection(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, currentVessel.getSurfaceVelocityReferenceFrame(),
+ orbitalReference))
+ .subtract(currentPosition);
+ Vector radial = new Vector(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());
+ }
+
+ // public void aimAtTarget() throws RPCException, StreamException,
+ // InterruptedException {
+ // Vector currentPosition = new Vector(naveAtual.position(pontoRefSuperficie));
+ // Vector targetPosition = new
+ // Vector(centroEspacial.getTargetVessel().position(pontoRefSuperficie));
+ // targetPosition.x = 0.0;
+ // double distanceToTarget = Vector.distance(currentPosition, targetPosition);
+ //
+ // Vector toTargetDirection = Vector.targetDirection(currentPosition,
+ // targetPosition);
+ // Vector oppositeDirection = Vector.targetOppositeDirection(currentPosition,
+ // targetPosition);
+ // Vector progradeDirection = Vector.targetDirection(currentPosition, new
+ // Vector(
+ // centroEspacial.transformPosition(PROGRADE,
+ // naveAtual.getSurfaceVelocityReferenceFrame(),
+ // pontoRefSuperficie
+ // )));
+ // Vector retrogradeDirection = Vector.targetDirection(currentPosition, new
+ // Vector(
+ // centroEspacial.transformPosition(RETROGRADE,
+ // naveAtual.getSurfaceVelocityReferenceFrame(),
+ // pontoRefSuperficie
+ // )));
+ // progradeDirection.x = 0.0;
+ // retrogradeDirection.x = 0.0;
+ // drawing.addDirection(toTargetDirection.toTriplet(), pontoRefSuperficie, 10,
+ // true);
+ // drawing.addDirection(oppositeDirection.toTriplet(), pontoRefSuperficie, 5,
+ // true);
+ // double pointingToTargetThreshold = Utilities.remap(0, 200, 0, 1,
+ // distanceToTarget, true);
+ // double speedThreshold = Utilities.remap(0, 20, 0, 1, horizontalSpeed.get(),
+ // true);
+ //
+ // Vector currentDirection =
+ // Utilities.linearInterpolation(oppositeDirection, toTargetDirection,
+ // pointingToTargetThreshold);
+ // double angleCurrentDirection =
+ // new Vector(currentDirection.z, currentDirection.y,
+ // currentDirection.x).heading();
+ // double angleProgradeDirection =
+ // new Vector(progradeDirection.z, progradeDirection.y,
+ // progradeDirection.x).heading();
+ // double deltaAngle = angleProgradeDirection - angleCurrentDirection;
+ // System.out.println(deltaAngle);
+ // if (deltaAngle > 3) {
+ // currentDirection.sum(progradeDirection).normalize();
+ // } else if (deltaAngle < -3) {
+ // currentDirection.subtract(progradeDirection).normalize();
+ // }
+ // drawing.addDirection(currentDirection.toTriplet(), pontoRefSuperficie, 25,
+ // true);
+ //
+ //
+ // Vector currentDirectionOnOrbitalRef = new Vector(
+ // centroEspacial.transformDirection(currentDirection.toTriplet(),
+ // pontoRefSuperficie,
+ // pontoRefOrbital));
+ // Vector radial = new Vector(centroEspacial.transformDirection(RADIAL,
+ // pontoRefSuperficie,
+ // pontoRefOrbital));
+ // Vector speedVector = Utilities.linearInterpolation(retrogradeDirection,
+ // progradeDirection, speedThreshold);
+ // Vector speedVectorOnOrbitalRef = new Vector(
+ // centroEspacial.transformDirection(speedVector.toTriplet(),
+ // pontoRefSuperficie,
+ // pontoRefOrbital));
+ // Vector pointingVector =
+ // Utilities.linearInterpolation(currentDirectionOnOrbitalRef,
+ // radial.sum(speedVectorOnOrbitalRef),
+ // speedThreshold
+ // );
+ // Thread.sleep(50);
+ // drawing.clear(false);
+ // aimAtDirection(pointingVector.toTriplet());
+ // }
+
+ public void aimAtPrograde() throws RPCException {
+ aimAtDirection(getSpaceCenter().transformDirection(PROGRADE, currentVessel.getSurfaceVelocityReferenceFrame(),
+ orbitalReference));
+ }
+
+ public void aimAtRadialOut() throws RPCException {
+ aimAtDirection(getSpaceCenter().transformDirection(RADIAL, currentVessel.getSurfaceReferenceFrame(),
+ orbitalReference));
+ }
+
+ public void aimAtRetrograde() throws RPCException {
+ aimAtDirection(getSpaceCenter().transformDirection(RETROGRADE,
+ currentVessel.getSurfaceVelocityReferenceFrame(),
+ orbitalReference));
+ }
+
+ public void aimAtDirection(Triplet currentDirection) throws RPCException {
+ currentVessel.getAutoPilot().setReferenceFrame(orbitalReference);
+ currentVessel.getAutoPilot().setTargetDirection(currentDirection);
+ }
+
+}
diff --git a/src/com/pesterenan/utils/PathFinding.java b/src/main/java/com/pesterenan/utils/PathFinding.java
similarity index 74%
rename from src/com/pesterenan/utils/PathFinding.java
rename to src/main/java/com/pesterenan/utils/PathFinding.java
index 56d2fcd..f5848e0 100644
--- a/src/com/pesterenan/utils/PathFinding.java
+++ b/src/main/java/com/pesterenan/utils/PathFinding.java
@@ -44,8 +44,8 @@ private void initializeParameters() {
public void addWaypointsOnSameBody(String waypointName) throws RPCException {
this.waypointName = waypointName;
- this.waypointsToReach =
- waypointManager.getWaypoints().stream().filter(this::hasSameName).collect(Collectors.toList());
+ this.waypointsToReach = waypointManager.getWaypoints().stream().filter(this::hasSameName)
+ .collect(Collectors.toList());
}
private boolean hasSameName(Waypoint waypoint) {
@@ -63,26 +63,25 @@ public Vector findNearestWaypoint() throws RPCException, IOException, Interrupte
double w2Distance = 0;
try {
w1Distance = Vector.distance(new Vector(getNaveAtual().position(orbitalReferenceFrame)),
- waypointPosOnSurface(w1)
- );
+ waypointPosOnSurface(w1));
w2Distance = Vector.distance(new Vector(getNaveAtual().position(orbitalReferenceFrame)),
- waypointPosOnSurface(w2)
- );
+ waypointPosOnSurface(w2));
} catch (RPCException e) {
}
return w1Distance > w2Distance ? 1 : -1;
}).collect(Collectors.toList());
waypointsToReach.forEach(System.out::println);
Waypoint currentWaypoint = waypointsToReach.get(0);
-// for (Waypoint waypoint : waypointsToReach) {
-// double waypointDistance = Vector.distance(new Vector(getNaveAtual().position(orbitalReferenceFrame)),
-// waypointPosOnSurface(waypoint)
-// );
-// if (currentDistance > waypointDistance) {
-// currentDistance = waypointDistance;
-// currentWaypoint = waypoint;
-// }
-// }
+ // for (Waypoint waypoint : waypointsToReach) {
+ // double waypointDistance = Vector.distance(new
+ // Vector(getNaveAtual().position(orbitalReferenceFrame)),
+ // waypointPosOnSurface(waypoint)
+ // );
+ // if (currentDistance > waypointDistance) {
+ // currentDistance = waypointDistance;
+ // currentWaypoint = waypoint;
+ // }
+ // }
return waypointPosOnSurface(currentWaypoint);
}
@@ -125,7 +124,8 @@ public void removeWaypointFromList() throws RPCException {
}
/**
- * Builds the path to the targetPosition, on the Celestial Body Reference ( Orbital Ref )
+ * Builds the path to the targetPosition, on the Celestial Body Reference (
+ * Orbital Ref )
*
* @param targetPosition the target pos to build the path to
* @throws IOException
@@ -133,10 +133,11 @@ public void removeWaypointFromList() throws RPCException {
* @throws InterruptedException
*/
public void buildPathToTarget(Vector targetPosition) throws IOException, RPCException, InterruptedException {
- // Get current rover Position on Orbital Ref, transform to Surf Ref and add 20 centimeters on height:
+ // Get current rover Position on Orbital Ref, transform to Surf Ref and add 20
+ // centimeters on height:
Vector roverHeight = new Vector(0.2, 0.0, 0.0);
- Vector currentRoverPos =
- transformSurfToOrb(new Vector(getNaveAtual().position(surfaceReferenceFrame)).sum(roverHeight));
+ Vector currentRoverPos = transformSurfToOrb(
+ new Vector(getNaveAtual().position(surfaceReferenceFrame)).sum(roverHeight));
// Calculate distance from rover to target on Orbital Ref:
double distanceToTarget = Vector.distance(currentRoverPos, targetPosition);
// Add rover pos as first point, on Orbital Ref
@@ -148,14 +149,12 @@ public void buildPathToTarget(Vector targetPosition) throws IOException, RPCExce
throw new InterruptedException();
}
Vector currentPoint = pathToTarget.get(index);
- Vector targetDirection =
- transformOrbToSurf(targetPosition).subtract(transformOrbToSurf(currentPoint)).normalize();
- Vector nextPoint =
- transformSurfToOrb(calculateNextPoint(transformOrbToSurf(currentPoint), targetDirection));
+ Vector targetDirection = transformOrbToSurf(targetPosition).subtract(transformOrbToSurf(currentPoint))
+ .normalize();
+ Vector nextPoint = transformSurfToOrb(calculateNextPoint(transformOrbToSurf(currentPoint), targetDirection));
pathToTarget.add(nextPoint);
index++;
- double distanceBetweenPoints =
- Vector.distance(transformOrbToSurf(currentPoint), transformOrbToSurf(nextPoint));
+ double distanceBetweenPoints = Vector.distance(transformOrbToSurf(currentPoint), transformOrbToSurf(nextPoint));
distanceToTarget -= distanceBetweenPoints;
}
pathToTarget.add(getPosOnSurface(targetPosition));
@@ -163,12 +162,11 @@ public void buildPathToTarget(Vector targetPosition) throws IOException, RPCExce
}
private void drawPathToTarget(List path) throws RPCException {
- Deque> drawablePath =
- path.stream().map(Vector::toTriplet).collect(Collectors.toCollection(ArrayDeque::new));
+ Deque> drawablePath = path.stream().map(Vector::toTriplet)
+ .collect(Collectors.toCollection(ArrayDeque::new));
drawablePath.offerFirst(new Triplet<>(0.0, 0.0, 0.0));
drawablePath.offerLast(new Triplet<>(0.0, 0.0, 0.0));
- polygonPath =
- drawing.addPolygon(drawablePath.stream().collect(Collectors.toList()), orbitalReferenceFrame, true);
+ polygonPath = drawing.addPolygon(drawablePath.stream().collect(Collectors.toList()), orbitalReferenceFrame, true);
polygonPath.setThickness(0.5f);
polygonPath.setColor(new Triplet<>(1.0, 0.5, 0.0));
}
@@ -184,25 +182,22 @@ private Vector calculateNextPoint(Vector currentPoint, Vector targetDirection) t
// PONTO REF SUPERFICIE: X = CIMA, Y = NORTE, Z = LESTE;
double stepDistance = 100.0;
// Calculate the next point position on surface:
- Vector nextPoint =
- getPosOnSurface(transformSurfToOrb(currentPoint.sum(targetDirection.multiply(stepDistance))));
+ Vector nextPoint = getPosOnSurface(transformSurfToOrb(currentPoint.sum(targetDirection.multiply(stepDistance))));
return transformOrbToSurf(nextPoint).sum(new Vector(0.2, 0.0, 0.0));
}
public double raycastDistance(Vector currentPoint, Vector targetDirection, SpaceCenter.ReferenceFrame reference,
- double searchDistance) throws RPCException {
+ double searchDistance) throws RPCException {
return Math.min(
getSpaceCenter().raycastDistance(currentPoint.toTriplet(), targetDirection.toTriplet(), reference),
- searchDistance
- );
+ searchDistance);
}
private Vector getPosOnSurface(Vector vector) throws RPCException {
return new Vector(
currentBody.surfacePosition(currentBody.latitudeAtPosition(vector.toTriplet(), orbitalReferenceFrame),
- currentBody.longitudeAtPosition(vector.toTriplet(), orbitalReferenceFrame),
- orbitalReferenceFrame
- ));
+ currentBody.longitudeAtPosition(vector.toTriplet(), orbitalReferenceFrame),
+ orbitalReferenceFrame));
}
private Vector transformSurfToOrb(Vector vector) throws IOException, RPCException {
diff --git a/src/com/pesterenan/utils/Telemetry.java b/src/main/java/com/pesterenan/utils/Telemetry.java
similarity index 100%
rename from src/com/pesterenan/utils/Telemetry.java
rename to src/main/java/com/pesterenan/utils/Telemetry.java
diff --git a/src/com/pesterenan/utils/Utilities.java b/src/main/java/com/pesterenan/utils/Utilities.java
similarity index 96%
rename from src/com/pesterenan/utils/Utilities.java
rename to src/main/java/com/pesterenan/utils/Utilities.java
index d3be012..86bdccc 100644
--- a/src/com/pesterenan/utils/Utilities.java
+++ b/src/main/java/com/pesterenan/utils/Utilities.java
@@ -27,7 +27,7 @@ public static Vector inverseLinearInterpolation(Vector start, Vector end, double
}
public static double remap(double inputMin, double inputMax, double outputMin, double outputMax, double value,
- boolean clampOutput) {
+ boolean clampOutput) {
double between = inverseLinearInterpolation(inputMin, inputMax, value);
double remappedOutput = linearInterpolation(outputMin, outputMax, between);
return clampOutput ? clamp(remappedOutput, outputMin, outputMax) : remappedOutput;
@@ -78,7 +78,6 @@ public String formatElapsedTime(Double totalSeconds) {
int minutes = (totalSeconds.intValue() % 3600) / 60;
int seconds = totalSeconds.intValue() % 60;
return String.format(Bundle.getString("pnl_tel_lbl_date_template"), years, days, hours, minutes,
- seconds
- ); //$NON-NLS-1$
+ seconds); // $NON-NLS-1$
}
}
diff --git a/src/com/pesterenan/utils/Vector.java b/src/main/java/com/pesterenan/utils/Vector.java
similarity index 93%
rename from src/com/pesterenan/utils/Vector.java
rename to src/main/java/com/pesterenan/utils/Vector.java
index c47661d..06c69e4 100644
--- a/src/com/pesterenan/utils/Vector.java
+++ b/src/main/java/com/pesterenan/utils/Vector.java
@@ -66,7 +66,7 @@ public static double distance(Vector start, Vector end) {
* @param start - Vetor contendo os componentes da posição do ponto de origem.
* @param end - Vetor contendo os componentes da posição do alvo.
* @return - Vetor com a soma dos valores do ponto de origem com os valores do
- * alvo.
+ * alvo.
*/
public static Vector targetDirection(Vector start, Vector end) {
return end.subtract(start).normalize();
@@ -78,7 +78,7 @@ public static Vector targetDirection(Vector start, Vector end) {
* @param start - Tupla contendo os componentes da posição do ponto de origem.
* @param end - Tupla contendo os componentes da posição do alvo.
* @return - Vetor inverso, com a soma dos valores do ponto de origem com o
- * negativo dos valores do alvo.
+ * negativo dos valores do alvo.
*/
public static Vector targetOppositeDirection(Vector start, Vector end) {
return end.subtract(start).multiply(-1).normalize();
@@ -151,12 +151,13 @@ public Vector normalize() {
* @param otherVector - Vetor para somar os componentes
* @return Novo vetor com a soma dos componentes dos dois
*/
- public double dotP(Vector otherVector) {
+
+ public double dotProduct(Vector otherVector) {
return (x * otherVector.x + y * otherVector.y + z * otherVector.z);
}
public double determinant(Vector otherVector) {
- return (x * otherVector.y - y * otherVector.x - z * otherVector.z);
+ return (x * otherVector.z - y * otherVector.y - z * otherVector.x);
}
/**
@@ -184,8 +185,8 @@ public Vector subtract(Vector otherVector) {
*
* @param scalar - Fator para multiplicar os componentes
* @return Novo vetor com os componentes multiplicados pela escalar. Caso a
- * escalar informada for 0, o Vetor retornado terá 0 como seus
- * componentes.
+ * escalar informada for 0, o Vetor retornado terá 0 como seus
+ * componentes.
*/
public Vector multiply(double scalar) {
if (scalar != 0) {
@@ -199,7 +200,7 @@ public Vector multiply(double scalar) {
*
* @param scalar - Fator para dividir os componentes
* @return Novo vetor com os componentes divididos pela escalar. Caso a escalar
- * informada for 0, o Vetor retornado terá 0 como seus componentes.
+ * informada for 0, o Vetor retornado terá 0 como seus componentes.
*/
public Vector divide(double scalar) {
if (scalar != 0) {
diff --git a/src/main/java/com/pesterenan/utils/VersionUtil.java b/src/main/java/com/pesterenan/utils/VersionUtil.java
new file mode 100644
index 0000000..a6084ca
--- /dev/null
+++ b/src/main/java/com/pesterenan/utils/VersionUtil.java
@@ -0,0 +1,32 @@
+package com.pesterenan.utils;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+
+public class VersionUtil {
+ public static String getVersion() {
+ String version = "N/A";
+ MavenXpp3Reader reader = new MavenXpp3Reader();
+ Model model;
+ try {
+ if ((new File("pom.xml")).exists()) {
+ model = reader.read(new FileReader("pom.xml"));
+ } else {
+ model = reader.read(
+ new InputStreamReader(
+ VersionUtil.class.getResourceAsStream(
+ "/META-INF/maven/com.pesterenan/MechPeste/pom.xml")));
+ }
+ version = model.getVersion();
+ return version;
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ return version;
+ }
+}
diff --git a/src/com/pesterenan/views/AboutJFrame.java b/src/main/java/com/pesterenan/views/AboutJFrame.java
similarity index 95%
rename from src/com/pesterenan/views/AboutJFrame.java
rename to src/main/java/com/pesterenan/views/AboutJFrame.java
index 7c3d2eb..e402033 100644
--- a/src/com/pesterenan/views/AboutJFrame.java
+++ b/src/main/java/com/pesterenan/views/AboutJFrame.java
@@ -9,6 +9,8 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
+import com.pesterenan.utils.VersionUtil;
+
import static com.pesterenan.views.MainGui.BTN_DIMENSION;
import static com.pesterenan.views.MainGui.centerDialogOnScreen;
import static com.pesterenan.views.MainGui.createMarginComponent;
@@ -28,7 +30,7 @@ public AboutJFrame() {
@Override
public void initComponents() {
// Labels:
- lblMechpeste = new JLabel("MechPeste - v.0.6.2");
+ lblMechpeste = new JLabel("MechPeste - v." + VersionUtil.getVersion());
lblAboutInfo = new JLabel(
"Esse app foi desenvolvido com o intuito de auxiliar o controle de naves
no game Kerbal Space Program.
"
+ "Não há garantias sobre o controle exato do app, portanto fique atento
"
diff --git a/src/com/pesterenan/views/ChangeVesselDialog.java b/src/main/java/com/pesterenan/views/ChangeVesselDialog.java
similarity index 99%
rename from src/com/pesterenan/views/ChangeVesselDialog.java
rename to src/main/java/com/pesterenan/views/ChangeVesselDialog.java
index 527b9ab..3702480 100644
--- a/src/com/pesterenan/views/ChangeVesselDialog.java
+++ b/src/main/java/com/pesterenan/views/ChangeVesselDialog.java
@@ -99,7 +99,6 @@ public void layoutComponents() {
pnlScroll.add(scrollPane);
pnlScroll.add(Box.createHorizontalStrut(190));
-
JPanel pnlOptionsAndList = new JPanel();
pnlOptionsAndList.setLayout(new BoxLayout(pnlOptionsAndList, BoxLayout.X_AXIS));
pnlOptions.setAlignmentY(TOP_ALIGNMENT);
diff --git a/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java b/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java
new file mode 100644
index 0000000..6c3a5ae
--- /dev/null
+++ b/src/main/java/com/pesterenan/views/CreateManeuverJPanel.java
@@ -0,0 +1,442 @@
+package com.pesterenan.views;
+
+import com.pesterenan.MechPeste;
+import com.pesterenan.resources.Bundle;
+import com.pesterenan.utils.ControlePID;
+
+import krpc.client.RPCException;
+import krpc.client.services.SpaceCenter.Node;
+import krpc.client.services.SpaceCenter.Orbit;
+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;
+ private static JButton btnCreateManeuver, btnDeleteManeuver, btnBack, btnAp, btnPe, btnAN, btnDN;
+ private static JButton btnIncrease, btnDecrease, btnNextOrbit, btnPrevOrbit;
+ private static JSlider sldScale;
+ private static JList listCurrentManeuvers;
+ private static int selectedManeuverIndex = 0;
+ private static JRadioButton rbPrograde, rbNormal, rbRadial, rbTime;
+ private static ButtonGroup bgManeuverType;
+ private static Map sliderValues = new HashMap<>();
+ private final ControlePID ctrlManeuver = new ControlePID();
+
+ public CreateManeuverJPanel() {
+ initComponents();
+ setupComponents();
+ layoutComponents();
+ }
+
+ @Override
+ public void initComponents() {
+ // Labels:
+ lblManeuverInfo = new JLabel("");
+
+ // Buttons:
+ btnCreateManeuver = new JButton("Criar");
+ btnDeleteManeuver = new JButton("Apagar");
+ btnAp = new JButton("AP");
+ btnPe = new JButton("PE");
+ btnAN = new JButton("NA");
+ btnDN = new JButton("ND");
+ btnBack = new JButton(Bundle.getString("pnl_mnv_btn_back"));
+ btnIncrease = new JButton("+");
+ btnDecrease = new JButton("-");
+ btnNextOrbit = new JButton(">");
+ btnPrevOrbit = new JButton("<");
+
+ // Radio buttons:
+ rbPrograde = new JRadioButton("Pro");
+ rbNormal = new JRadioButton("Nor");
+ rbRadial = new JRadioButton("Rad");
+ rbTime = new JRadioButton("Tmp");
+
+ // Misc:
+ listCurrentManeuvers = new JList<>();
+ sldScale = new JSlider(JSlider.VERTICAL, 0, 5, 2);
+ bgManeuverType = new ButtonGroup();
+ sliderValues.put(0, 0.01f);
+ sliderValues.put(1, 0.1f);
+ sliderValues.put(2, 1f);
+ sliderValues.put(3, 10f);
+ sliderValues.put(4, 100f);
+ sliderValues.put(5, 1000f);
+
+ ctrlManeuver.setOutput(-100, 100);
+ }
+
+ @Override
+ public void setupComponents() {
+ // Setting-up components:
+ btnCreateManeuver.addActionListener(this);
+ btnCreateManeuver.setMaximumSize(BTN_DIMENSION);
+ btnCreateManeuver.setPreferredSize(BTN_DIMENSION);
+ btnDeleteManeuver.addActionListener(this);
+ btnDeleteManeuver.setMaximumSize(BTN_DIMENSION);
+ btnDeleteManeuver.setPreferredSize(BTN_DIMENSION);
+ btnAp.addActionListener(this);
+ btnAp.setActionCommand("apoapsis");
+ btnPe.addActionListener(this);
+ btnPe.setActionCommand("periapsis");
+ btnAN.addActionListener(this);
+ btnAN.setActionCommand("ascending");
+ btnDN.addActionListener(this);
+ btnDN.setActionCommand("descending");
+ btnBack.addActionListener(this);
+ btnBack.setMaximumSize(BTN_DIMENSION);
+ btnBack.setPreferredSize(BTN_DIMENSION);
+ btnIncrease.setActionCommand("increase");
+ btnIncrease.addActionListener(this);
+ btnIncrease.addMouseWheelListener(e -> {
+ int rotation = e.getWheelRotation();
+ if (rotation > 0) {
+ changeManeuverDeltaV(btnDecrease.getActionCommand());
+ } else {
+ changeManeuverDeltaV(btnIncrease.getActionCommand());
+ }
+ });
+ btnIncrease.setMaximumSize(new Dimension(70, 26));
+ btnIncrease.setPreferredSize(new Dimension(70, 26));
+ btnIncrease.setMargin(new Insets(0, 0, 0, 0));
+ btnDecrease.setActionCommand("decrease");
+ btnDecrease.addActionListener(this);
+ btnDecrease.addMouseWheelListener(e -> {
+ int rotation = e.getWheelRotation();
+ if (rotation > 0) {
+ changeManeuverDeltaV(btnIncrease.getActionCommand());
+ } else {
+ changeManeuverDeltaV(btnDecrease.getActionCommand());
+ }
+ });
+ btnDecrease.setMaximumSize(new Dimension(70, 26));
+ btnDecrease.setPreferredSize(new Dimension(70, 26));
+ btnDecrease.setMargin(new Insets(0, 0, 0, 0));
+ btnNextOrbit.setActionCommand("next_orbit");
+ btnNextOrbit.addActionListener(this);
+ btnNextOrbit.setMaximumSize(new Dimension(35, 26));
+ btnNextOrbit.setPreferredSize(new Dimension(35, 26));
+ btnNextOrbit.setMargin(new Insets(0, 0, 0, 0));
+ btnPrevOrbit.setActionCommand("prev_orbit");
+ btnPrevOrbit.addActionListener(this);
+ btnPrevOrbit.setMaximumSize(new Dimension(35, 26));
+ btnPrevOrbit.setPreferredSize(new Dimension(35, 26));
+ btnPrevOrbit.setMargin(new Insets(0, 0, 0, 0));
+
+ rbPrograde.setActionCommand("prograde");
+ rbPrograde.addChangeListener(e -> handleChangeButtonText(sldScale.getValue()));
+ rbNormal.setActionCommand("normal");
+ rbNormal.addChangeListener(e -> handleChangeButtonText(sldScale.getValue()));
+ rbRadial.setActionCommand("radial");
+ rbRadial.addChangeListener(e -> handleChangeButtonText(sldScale.getValue()));
+ rbTime.setActionCommand("time");
+ rbTime.addChangeListener(e -> handleChangeButtonText(sldScale.getValue()));
+ bgManeuverType.add(rbPrograde);
+ bgManeuverType.add(rbNormal);
+ bgManeuverType.add(rbRadial);
+ bgManeuverType.add(rbTime);
+ bgManeuverType.setSelected(rbPrograde.getModel(), true);
+
+ listCurrentManeuvers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ listCurrentManeuvers.addListSelectionListener(e -> selectedManeuverIndex = e.getFirstIndex());
+
+ sldScale.setSnapToTicks(true);
+ sldScale.setPaintTicks(true);
+ sldScale.setMajorTickSpacing(1);
+ sldScale.setMinorTickSpacing(1);
+ sldScale.setPaintLabels(false);
+ sldScale.addChangeListener(e -> handleChangeButtonText(sldScale.getValue()));
+ sldScale.addMouseWheelListener(e -> {
+ int rotation = e.getWheelRotation();
+ if (rotation < 0) {
+ sldScale.setValue(sldScale.getValue() + sldScale.getMinorTickSpacing());
+ } else {
+ sldScale.setValue(sldScale.getValue() - sldScale.getMinorTickSpacing());
+ }
+ });
+ }
+
+ @Override
+ public void layoutComponents() {
+ // Main Panel layout:
+ setPreferredSize(PNL_DIMENSION);
+ setSize(PNL_DIMENSION);
+ setLayout(new BorderLayout());
+
+ JPanel pnlPositionManeuver = new JPanel();
+ pnlPositionManeuver.setLayout(new BoxLayout(pnlPositionManeuver, BoxLayout.X_AXIS));
+ pnlPositionManeuver.setBorder(new TitledBorder("Posicionar manobra no:"));
+ pnlPositionManeuver.add(Box.createHorizontalGlue());
+ pnlPositionManeuver.add(btnAp);
+ pnlPositionManeuver.add(btnPe);
+ pnlPositionManeuver.add(btnAN);
+ pnlPositionManeuver.add(btnDN);
+ pnlPositionManeuver.add(Box.createHorizontalGlue());
+
+ JPanel pnlRadioButtons = new JPanel(new GridLayout(4, 1));
+ pnlRadioButtons.setMaximumSize(new Dimension(50, 100));
+ pnlRadioButtons.add(rbPrograde);
+ pnlRadioButtons.add(rbNormal);
+ pnlRadioButtons.add(rbRadial);
+ pnlRadioButtons.add(rbTime);
+
+ JPanel pnlSlider = new JPanel();
+ pnlSlider.setLayout(new BoxLayout(pnlSlider, BoxLayout.Y_AXIS));
+ pnlSlider.setAlignmentX(Component.LEFT_ALIGNMENT);
+ pnlSlider.setBorder(new TitledBorder("Escala:"));
+ pnlSlider.add(sldScale);
+ pnlSlider.add(Box.createHorizontalStrut(40));
+
+ JPanel pnlOrbitControl = new JPanel();
+ pnlOrbitControl.setLayout(new BoxLayout(pnlOrbitControl, BoxLayout.X_AXIS));
+ pnlOrbitControl.setAlignmentX(Component.LEFT_ALIGNMENT);
+ pnlOrbitControl.add(btnPrevOrbit);
+ pnlOrbitControl.add(btnNextOrbit);
+
+ JPanel pnlManeuverButtons = new JPanel();
+ pnlManeuverButtons.setLayout(new BoxLayout(pnlManeuverButtons, BoxLayout.Y_AXIS));
+ pnlManeuverButtons.setAlignmentX(Component.LEFT_ALIGNMENT);
+ pnlManeuverButtons.add(btnIncrease);
+ pnlManeuverButtons.add(pnlOrbitControl);
+ pnlManeuverButtons.add(btnDecrease);
+
+ JPanel pnlManeuverController = new JPanel();
+ pnlManeuverController.setLayout(new BoxLayout(pnlManeuverController, BoxLayout.X_AXIS));
+ pnlManeuverController.setBorder(new TitledBorder("Controlador de Manobra:"));
+ pnlManeuverController.setMaximumSize(new Dimension(180, 300));
+ pnlManeuverController.add(pnlRadioButtons);
+ pnlManeuverController.add(pnlSlider);
+ pnlManeuverController.add(pnlManeuverButtons);
+
+ JPanel pnlManeuverInfo = new JPanel();
+ pnlManeuverInfo.setLayout(new BoxLayout(pnlManeuverInfo, BoxLayout.Y_AXIS));
+ pnlManeuverInfo.setBorder(new TitledBorder("Info. Manobra:"));
+ pnlManeuverInfo.setMaximumSize(new Dimension(300, 300));
+
+ JPanel pnlMCpnlAP = new JPanel();
+ pnlMCpnlAP.setLayout(new BoxLayout(pnlMCpnlAP, BoxLayout.X_AXIS));
+ pnlMCpnlAP.add(pnlManeuverController);
+ pnlMCpnlAP.add(pnlManeuverInfo);
+
+ JPanel pnlControls = new JPanel();
+ pnlControls.setLayout(new BoxLayout(pnlControls, BoxLayout.Y_AXIS));
+ pnlControls.add(pnlPositionManeuver);
+ pnlControls.add(pnlMCpnlAP);
+
+ JPanel pnlManeuverList = new JPanel();
+ pnlManeuverList.setLayout(new BoxLayout(pnlManeuverList, BoxLayout.Y_AXIS));
+ JScrollPane scrollPane = new JScrollPane();
+ scrollPane.setViewportView(listCurrentManeuvers);
+ pnlManeuverList.add(scrollPane);
+ pnlManeuverList.add(btnCreateManeuver);
+ pnlManeuverList.add(btnDeleteManeuver);
+
+ JPanel pnlOptions = new JPanel();
+ pnlOptions.setLayout(new BoxLayout(pnlOptions, BoxLayout.Y_AXIS));
+ pnlOptions.setBorder(new TitledBorder("Lista de Manobras:"));
+ pnlOptions.add(pnlManeuverList);
+ pnlOptions.setPreferredSize(new Dimension(110, 300));
+ pnlOptions.setMaximumSize(new Dimension(110, 300));
+
+ JPanel pnlOptionsAndList = new JPanel();
+ pnlOptionsAndList.setLayout(new BoxLayout(pnlOptionsAndList, BoxLayout.X_AXIS));
+ pnlControls.setAlignmentY(TOP_ALIGNMENT);
+ pnlOptions.setAlignmentY(TOP_ALIGNMENT);
+ pnlOptionsAndList.add(pnlOptions);
+ pnlOptionsAndList.add(Box.createHorizontalStrut(5));
+ pnlOptionsAndList.add(pnlControls);
+
+ JPanel pnlBackButton = new JPanel();
+ pnlBackButton.setLayout(new BoxLayout(pnlBackButton, BoxLayout.X_AXIS));
+ pnlBackButton.add(lblManeuverInfo);
+ pnlBackButton.add(Box.createHorizontalGlue());
+ pnlBackButton.add(btnBack);
+
+ JPanel pnlMain = new JPanel();
+ pnlMain.setLayout(new BoxLayout(pnlMain, BoxLayout.X_AXIS));
+ pnlMain.add(pnlOptionsAndList);
+
+ add(pnlMain, BorderLayout.CENTER);
+ add(pnlBackButton, BorderLayout.SOUTH);
+ }
+
+ public static void updatePanel(ListModel list) {
+ try {
+ boolean hasManeuverNodes = list.getSize() > 0;
+ boolean hasTargetVessel = MechPeste.getSpaceCenter().getTargetVessel() != null;
+ listCurrentManeuvers.setModel(list);
+ listCurrentManeuvers.setSelectedIndex(selectedManeuverIndex);
+ btnDeleteManeuver.setEnabled(hasManeuverNodes);
+ btnAp.setEnabled(hasManeuverNodes);
+ btnPe.setEnabled(hasManeuverNodes);
+ btnAN.setEnabled(hasManeuverNodes && hasTargetVessel);
+ btnDN.setEnabled(hasManeuverNodes && hasTargetVessel);
+ btnIncrease.setEnabled(hasManeuverNodes);
+ btnDecrease.setEnabled(hasManeuverNodes);
+ btnNextOrbit.setEnabled(hasManeuverNodes);
+ btnPrevOrbit.setEnabled(hasManeuverNodes);
+ lblManeuverInfo.setText(listCurrentManeuvers.getSelectedValue());
+ } catch (RPCException ignored) {
+ }
+ }
+
+ private static void handleChangeButtonText(int value) {
+ String decimalPlaces = value > 1 ? "%.0f" : "%.2f";
+ String formattedValue = String.format(Locale.ENGLISH, decimalPlaces, sliderValues.get(value));
+ String suffix = bgManeuverType.getSelection() == rbTime.getModel() ? " s" : "m/s";
+ btnIncrease.setText("+ " + formattedValue + suffix);
+ btnDecrease.setText("- " + formattedValue + suffix);
+ }
+
+ private void createManeuver() {
+ try {
+ createManeuver(MechPeste.getSpaceCenter().getUT() + 60);
+ } catch (RPCException e) {
+ }
+ }
+
+ private void createManeuver(double atFutureTime) {
+ try {
+ MechPeste.newInstance();
+ Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel();
+
+ if (vessel.getSituation() != VesselSituation.ORBITING) {
+ StatusJPanel.setStatusMessage("Não é possível criar a manobra fora de órbita.");
+ return;
+ }
+ vessel.getControl().addNode(atFutureTime, 0, 0, 0);
+ } catch (Exception e) {
+ }
+ }
+
+ private void deleteManeuver() {
+ try {
+ MechPeste.newInstance();
+ Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel();
+ Node currentManeuver = vessel.getControl().getNodes().get(selectedManeuverIndex);
+ currentManeuver.remove();
+ } catch (Exception e) {
+ }
+ }
+
+ private void positionManeuverAt(String node) {
+ try {
+ MechPeste.newInstance();
+ Vessel vessel = MechPeste.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();
+ break;
+ case "periapsis":
+ timeToNode = MechPeste.getSpaceCenter().getUT() + orbit.getTimeToPeriapsis();
+ break;
+ case "ascending":
+ double ascendingAnomaly = orbit
+ .trueAnomalyAtAN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit());
+ timeToNode = orbit.uTAtTrueAnomaly(ascendingAnomaly);
+ break;
+ case "descending":
+ double descendingAnomaly = orbit
+ .trueAnomalyAtDN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit());
+ timeToNode = orbit.uTAtTrueAnomaly(descendingAnomaly);
+ break;
+ }
+ currentManeuver.setUT(timeToNode);
+ // Print the maneuver node information
+ System.out.println("Maneuver Node updated:");
+ System.out.println(" Time to node: " + currentManeuver.getTimeTo() + " s");
+ } catch (Exception e) {
+ }
+ }
+
+ private void changeManeuverDeltaV(String command) {
+ try {
+ MechPeste.newInstance();
+ Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel();
+ Node currentManeuver = vessel.getControl().getNodes().get(selectedManeuverIndex);
+ String maneuverType = bgManeuverType.getSelection().getActionCommand();
+ float currentSliderValue = sliderValues.get(sldScale.getValue());
+ currentSliderValue = command == "decrease" ? -currentSliderValue : currentSliderValue;
+
+ switch (maneuverType) {
+ case "prograde":
+ currentManeuver.setPrograde(currentManeuver.getPrograde() + currentSliderValue);
+ break;
+ case "normal":
+ currentManeuver.setNormal(currentManeuver.getNormal() + currentSliderValue);
+ break;
+ case "radial":
+ currentManeuver.setRadial(currentManeuver.getRadial() + currentSliderValue);
+ break;
+ case "time":
+ currentManeuver.setUT(currentManeuver.getUT() + currentSliderValue);
+ break;
+ }
+ } catch (RPCException e) {
+ System.err.println("Erro RPC ao mudar o delta-V da manobra: " + e.getMessage());
+ } catch (Exception e) {
+ System.err.println("Erro ao mudar o delta-V da manobra: " + e.getMessage());
+ }
+
+ }
+
+ private void changeOrbit(String command) {
+ try {
+ MechPeste.newInstance();
+ Vessel vessel;
+ vessel = MechPeste.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;
+ currentManeuver.setUT(newUT);
+ }
+ } catch (RPCException ignored) {
+ }
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == btnCreateManeuver) {
+ createManeuver();
+ }
+ if (e.getSource() == btnDeleteManeuver) {
+ deleteManeuver();
+ }
+ if (e.getSource() == btnIncrease || e.getSource() == btnDecrease) {
+ changeManeuverDeltaV(e.getActionCommand());
+ }
+ if (e.getSource() == btnNextOrbit || e.getSource() == btnPrevOrbit) {
+ changeOrbit(e.getActionCommand());
+ }
+ if (e.getSource() == btnAp || e.getSource() == btnPe || e.getSource() == btnAN || e.getSource() == btnDN) {
+ positionManeuverAt(e.getActionCommand());
+ }
+ if (e.getSource() == btnBack) {
+ MainGui.backToTelemetry(e);
+ }
+ }
+}
diff --git a/src/main/java/com/pesterenan/views/DockingJPanel.java b/src/main/java/com/pesterenan/views/DockingJPanel.java
new file mode 100644
index 0000000..26edbb3
--- /dev/null
+++ b/src/main/java/com/pesterenan/views/DockingJPanel.java
@@ -0,0 +1,122 @@
+package com.pesterenan.views;
+
+import com.pesterenan.MechPeste;
+import com.pesterenan.resources.Bundle;
+import com.pesterenan.utils.Modulos;
+
+import javax.swing.*;
+import javax.swing.border.TitledBorder;
+import java.awt.*;
+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;
+
+public class DockingJPanel extends JPanel implements UIMethods {
+
+ private static final long serialVersionUID = 0L;
+
+ private JLabel lblMaxSpeed;
+ private JTextField txfMaxSpeed;
+ private JButton btnBack, btnStartDocking;
+
+ public DockingJPanel() {
+ initComponents();
+ setupComponents();
+ layoutComponents();
+ }
+
+ @Override
+ public void initComponents() {
+ // Labels:
+ lblMaxSpeed = new JLabel(Bundle.getString("pnl_rover_lbl_max_speed"));
+
+ // Textfields:
+ txfMaxSpeed = new JTextField("3");
+
+ // Buttons:
+ btnBack = new JButton(Bundle.getString("pnl_rover_btn_back"));
+ btnStartDocking = new JButton(Bundle.getString("pnl_rover_btn_docking"));
+ }
+
+ @Override
+ public void setupComponents() {
+ // Main Panel setup:
+ setBorder(new TitledBorder(null, Bundle.getString("btn_func_docking")));
+
+ // Setting-up components:
+ txfMaxSpeed.setHorizontalAlignment(SwingConstants.RIGHT);
+ txfMaxSpeed.setMaximumSize(BTN_DIMENSION);
+ txfMaxSpeed.setPreferredSize(BTN_DIMENSION);
+
+ btnBack.addActionListener(MainGui::backToTelemetry);
+ btnBack.setMaximumSize(BTN_DIMENSION);
+ btnBack.setPreferredSize(BTN_DIMENSION);
+ btnStartDocking.addActionListener(this::handleStartDocking);
+ btnStartDocking.setMaximumSize(BTN_DIMENSION);
+ btnStartDocking.setPreferredSize(BTN_DIMENSION);
+ }
+
+ @Override
+ public void layoutComponents() {
+ // Main Panel layout:
+ setPreferredSize(PNL_DIMENSION);
+ setSize(PNL_DIMENSION);
+ setLayout(new BorderLayout());
+
+ // Layout components:
+ JPanel pnlMaxSpeed = new JPanel();
+ pnlMaxSpeed.setLayout(new BoxLayout(pnlMaxSpeed, BoxLayout.X_AXIS));
+ pnlMaxSpeed.add(lblMaxSpeed);
+ pnlMaxSpeed.add(Box.createHorizontalGlue());
+ pnlMaxSpeed.add(txfMaxSpeed);
+
+ JPanel pnlRoverControls = new JPanel();
+ pnlRoverControls.setLayout(new BoxLayout(pnlRoverControls, BoxLayout.Y_AXIS));
+ pnlRoverControls.setBorder(MARGIN_BORDER_10_PX_LR);
+ pnlRoverControls.add(MainGui.createMarginComponent(0, 6));
+ pnlRoverControls.add(pnlMaxSpeed);
+ pnlRoverControls.add(Box.createVerticalGlue());
+
+ JPanel pnlButtons = new JPanel();
+ pnlButtons.setLayout(new BoxLayout(pnlButtons, BoxLayout.X_AXIS));
+ pnlButtons.add(btnStartDocking);
+ pnlButtons.add(Box.createHorizontalGlue());
+ pnlButtons.add(btnBack);
+
+ JPanel pnlMain = new JPanel();
+ pnlMain.setLayout(new BoxLayout(pnlMain, BoxLayout.X_AXIS));
+ pnlRoverControls.setAlignmentY(TOP_ALIGNMENT);
+ pnlMain.add(pnlRoverControls);
+
+ setLayout(new BorderLayout());
+ add(pnlMain, BorderLayout.CENTER);
+ add(pnlButtons, BorderLayout.SOUTH);
+ }
+
+ private void handleStartDocking(ActionEvent e) {
+ System.out.println("chamou startdocking");
+ Map commands = new HashMap<>();
+ commands.put(Modulos.MODULO.get(), Modulos.MODULO_DOCKING.get());
+ commands.put(Modulos.VELOCIDADE_MAX.get(), txfMaxSpeed.getText());
+ MechPeste.newInstance().startModule(commands);
+ }
+
+ private boolean validateTextFields() {
+ try {
+ if (Float.parseFloat(txfMaxSpeed.getText()) > 10) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException e) {
+ StatusJPanel.setStatusMessage(Bundle.getString("pnl_rover_max_speed_above_3"));
+ return false;
+ } catch (IllegalArgumentException e) {
+ StatusJPanel.setStatusMessage(Bundle.getString("pnl_rover_waypoint_name_not_empty"));
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/com/pesterenan/views/FunctionsAndTelemetryJPanel.java b/src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java
similarity index 88%
rename from src/com/pesterenan/views/FunctionsAndTelemetryJPanel.java
rename to src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java
index aadcb06..5a6dc03 100644
--- a/src/com/pesterenan/views/FunctionsAndTelemetryJPanel.java
+++ b/src/main/java/com/pesterenan/views/FunctionsAndTelemetryJPanel.java
@@ -21,7 +21,7 @@ public class FunctionsAndTelemetryJPanel extends JPanel implements UIMethods {
private static final long serialVersionUID = 0L;
private final Dimension btnFuncDimension = new Dimension(140, 25);
- private JButton btnLiftoff, btnLanding, btnExecManeuver, btnRover, btnCancel, btnCreateManeuver;
+ private JButton btnLiftoff, btnLanding, btnManeuvers, btnDocking, btnRover, btnCancel;
private static JLabel lblAltitude, lblSurfaceAlt, lblApoapsis, lblPeriapsis, lblVertSpeed, lblHorzSpeed;
private static JLabel lblAltitudeValue, lblSurfaceAltValue, lblApoapsisValue;
private static JLabel lblPeriapsisValue, lblVertSpeedValue, lblHorzSpeedValue;
@@ -51,9 +51,9 @@ public void initComponents() {
// Buttons:
btnLiftoff = new JButton(Bundle.getString("btn_func_liftoff"));
btnLanding = new JButton(Bundle.getString("btn_func_landing"));
- btnCreateManeuver = new JButton(Bundle.getString("btn_func_create_maneuver"));
- btnExecManeuver = new JButton(Bundle.getString("btn_func_exec_maneuver"));
+ btnManeuvers = new JButton(Bundle.getString("btn_func_maneuver"));
btnRover = new JButton(Bundle.getString("btn_func_rover"));
+ btnDocking = new JButton(Bundle.getString("btn_func_docking"));
btnCancel = new JButton(Bundle.getString("pnl_tel_btn_cancel"));
}
@@ -76,19 +76,18 @@ public void setupComponents() {
btnLiftoff.setActionCommand(Modulos.MODULO_DECOLAGEM.get());
btnLiftoff.setMaximumSize(btnFuncDimension);
btnLiftoff.setPreferredSize(btnFuncDimension);
- btnCreateManeuver.addActionListener(this::changeFunctionPanel);
- btnCreateManeuver.setActionCommand(Modulos.MODULO_CRIAR_MANOBRAS.get());
- btnCreateManeuver.setMaximumSize(btnFuncDimension);
- btnCreateManeuver.setPreferredSize(btnFuncDimension);
- btnCreateManeuver.setEnabled(false);
- btnExecManeuver.addActionListener(this::changeFunctionPanel);
- btnExecManeuver.setActionCommand(Modulos.MODULO_EXEC_MANOBRAS.get());
- btnExecManeuver.setMaximumSize(btnFuncDimension);
- btnExecManeuver.setPreferredSize(btnFuncDimension);
+ btnManeuvers.addActionListener(this::changeFunctionPanel);
+ btnManeuvers.setActionCommand(Modulos.MODULE_MANEUVER.get());
+ btnManeuvers.setMaximumSize(btnFuncDimension);
+ btnManeuvers.setPreferredSize(btnFuncDimension);
btnRover.addActionListener(this::changeFunctionPanel);
btnRover.setActionCommand(Modulos.MODULO_ROVER.get());
btnRover.setMaximumSize(btnFuncDimension);
btnRover.setPreferredSize(btnFuncDimension);
+ btnDocking.addActionListener(this::changeFunctionPanel);
+ btnDocking.setActionCommand(Modulos.MODULO_DOCKING.get());
+ btnDocking.setMaximumSize(btnFuncDimension);
+ btnDocking.setPreferredSize(btnFuncDimension);
}
@Override
@@ -100,9 +99,8 @@ public void layoutComponents() {
pnlFunctionControls.add(btnLiftoff);
pnlFunctionControls.add(btnLanding);
pnlFunctionControls.add(btnRover);
- pnlFunctionControls.add(MainGui.createMarginComponent(0, 20));
- pnlFunctionControls.add(btnCreateManeuver);
- pnlFunctionControls.add(btnExecManeuver);
+ pnlFunctionControls.add(btnDocking);
+ pnlFunctionControls.add(btnManeuvers);
pnlFunctionControls.add(Box.createVerticalGlue());
JPanel pnlLeftPanel = new JPanel();
diff --git a/src/main/java/com/pesterenan/views/InstallKrpcDialog.java b/src/main/java/com/pesterenan/views/InstallKrpcDialog.java
new file mode 100644
index 0000000..a9b0164
--- /dev/null
+++ b/src/main/java/com/pesterenan/views/InstallKrpcDialog.java
@@ -0,0 +1,200 @@
+package com.pesterenan.views;
+
+import com.pesterenan.resources.Bundle;
+import com.pesterenan.updater.KrpcInstaller;
+
+import javax.swing.*;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.border.BevelBorder;
+import javax.swing.border.TitledBorder;
+
+public class InstallKrpcDialog extends JDialog {
+ private static final long serialVersionUID = 1L;
+ private JLabel lblInstallerInfo;
+ private final JSeparator separator = new JSeparator();
+ private final JPanel pnlKspFolderPath = new JPanel();
+ private final JTextField txfPath = new JTextField();
+ private JButton btnBrowsePath;
+ private JButton btnDownloadInstall;
+ private JButton btnCancel;
+ private JPanel pnlStatus;
+ private static JLabel lblStatus;
+
+ public InstallKrpcDialog() {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ initComponents();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void initComponents() {
+ setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ setResizable(false);
+ setBounds(MainGui.centerDialogOnScreen());
+ setAlwaysOnTop(true);
+ setModalityType(ModalityType.APPLICATION_MODAL);
+ setTitle(Bundle.getString("installer_dialog_title")); //$NON-NLS-1$
+
+ lblInstallerInfo = new JLabel(Bundle.getString("installer_dialog_txt_info")); //$NON-NLS-1$
+
+ pnlKspFolderPath.setBorder(
+ new TitledBorder(null, Bundle.getString("installer_dialog_pnl_path"), TitledBorder.LEADING, // $NON
+ // -NLS-1$
+ TitledBorder.TOP, null, null));
+
+ btnDownloadInstall = new JButton(Bundle.getString("installer_dialog_btn_download")); // $NON
+ // -NLS-1$
+ btnDownloadInstall.addActionListener((e) -> KrpcInstaller.downloadAndInstallKrpc());
+ btnDownloadInstall.setEnabled(false);
+
+ btnCancel = new JButton(Bundle.getString("installer_dialog_btn_cancel")); //$NON-NLS-1$
+ btnCancel.addActionListener((e) -> this.dispose());
+
+ pnlStatus = new JPanel();
+ pnlStatus.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
+
+ GroupLayout groupLayout = new GroupLayout(getContentPane());
+ groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
+ .addGroup(groupLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(groupLayout.createParallelGroup(
+ Alignment.LEADING)
+ .addComponent(
+ pnlKspFolderPath,
+ GroupLayout.DEFAULT_SIZE,
+ 414,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblInstallerInfo,
+ Alignment.TRAILING,
+ GroupLayout.DEFAULT_SIZE,
+ 414,
+ Short.MAX_VALUE)
+ .addComponent(separator,
+ Alignment.TRAILING,
+ GroupLayout.DEFAULT_SIZE,
+ 414,
+ Short.MAX_VALUE)
+ .addGroup(
+ groupLayout.createSequentialGroup()
+ .addComponent(
+ btnDownloadInstall)
+ .addPreferredGap(
+ ComponentPlacement.RELATED,
+ 184,
+ Short.MAX_VALUE)
+ .addComponent(
+ btnCancel)))
+ .addGap(10))
+ .addComponent(pnlStatus, Alignment.LEADING, GroupLayout.DEFAULT_SIZE,
+ 434, Short.MAX_VALUE));
+ groupLayout.setVerticalGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+ .addGroup(groupLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblInstallerInfo,
+ GroupLayout.PREFERRED_SIZE, 60,
+ GroupLayout.PREFERRED_SIZE)
+ .addGap(2)
+ .addComponent(separator,
+ GroupLayout.PREFERRED_SIZE, 2,
+ GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addComponent(pnlKspFolderPath,
+ GroupLayout.PREFERRED_SIZE, 51,
+ GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(groupLayout.createParallelGroup(
+ Alignment.BASELINE)
+ .addComponent(
+ btnDownloadInstall)
+ .addComponent(btnCancel))
+ .addPreferredGap(ComponentPlacement.RELATED, 60,
+ Short.MAX_VALUE)
+ .addComponent(pnlStatus,
+ GroupLayout.PREFERRED_SIZE, 25,
+ GroupLayout.PREFERRED_SIZE)));
+
+ lblStatus = new JLabel();
+ GroupLayout glPnlStatus = new GroupLayout(pnlStatus);
+ glPnlStatus.setHorizontalGroup(glPnlStatus.createParallelGroup(Alignment.LEADING)
+ .addGroup(glPnlStatus.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblStatus)
+ .addContainerGap(389, Short.MAX_VALUE)));
+ glPnlStatus.setVerticalGroup(glPnlStatus.createParallelGroup(Alignment.TRAILING)
+ .addGroup(glPnlStatus.createSequentialGroup()
+ .addGap(2)
+ .addComponent(lblStatus, GroupLayout.DEFAULT_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addGap(0)));
+ pnlStatus.setLayout(glPnlStatus);
+
+ txfPath.setEditable(false);
+ txfPath.setColumns(10);
+
+ btnBrowsePath = new JButton(Bundle.getString("installer_dialog_btn_browse")); //$NON-NLS-1$
+ btnBrowsePath.addActionListener(e -> {
+ chooseKSPFolder();
+ txfPath.setText(KrpcInstaller.getKspFolder());
+ });
+ GroupLayout glPnlKspFolderPath = new GroupLayout(pnlKspFolderPath);
+ glPnlKspFolderPath.setHorizontalGroup(glPnlKspFolderPath.createParallelGroup(Alignment.LEADING)
+ .addGroup(Alignment.TRAILING,
+ glPnlKspFolderPath.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(txfPath,
+ GroupLayout.DEFAULT_SIZE,
+ 273,
+ Short.MAX_VALUE)
+ .addPreferredGap(
+ ComponentPlacement.RELATED)
+ .addComponent(btnBrowsePath,
+ GroupLayout.PREFERRED_SIZE,
+ 103,
+ GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()));
+ glPnlKspFolderPath.setVerticalGroup(glPnlKspFolderPath.createParallelGroup(Alignment.LEADING)
+ .addGroup(glPnlKspFolderPath.createSequentialGroup()
+ .addGroup(
+ glPnlKspFolderPath.createParallelGroup(
+ Alignment.BASELINE)
+ .addComponent(
+ txfPath,
+ GroupLayout.PREFERRED_SIZE,
+ 23,
+ GroupLayout.PREFERRED_SIZE)
+ .addComponent(
+ btnBrowsePath))
+ .addContainerGap(24,
+ Short.MAX_VALUE)));
+ pnlKspFolderPath.setLayout(glPnlKspFolderPath);
+ getContentPane().setLayout(groupLayout);
+
+ setVisible(true);
+ }
+
+ public void chooseKSPFolder() {
+ JFileChooser kspDir = new JFileChooser();
+ kspDir.setDialogTitle("Escolha a pasta do KSP na Steam");
+ kspDir.setMultiSelectionEnabled(false);
+ kspDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ int response = kspDir.showOpenDialog(this);
+ if (response == JFileChooser.APPROVE_OPTION) {
+ KrpcInstaller.setKspFolder(kspDir.getSelectedFile().getPath());
+ btnDownloadInstall.setEnabled(true);
+ setStatus("Pasta escolhida, pronto para instalar.");
+ } else {
+ KrpcInstaller.setKspFolder(null);
+ btnDownloadInstall.setEnabled(false);
+ setStatus("");
+ }
+ }
+
+ public static void setStatus(String status) {
+ lblStatus.setText(status);
+ }
+}
diff --git a/src/com/pesterenan/views/LandingJPanel.java b/src/main/java/com/pesterenan/views/LandingJPanel.java
similarity index 100%
rename from src/com/pesterenan/views/LandingJPanel.java
rename to src/main/java/com/pesterenan/views/LandingJPanel.java
diff --git a/src/com/pesterenan/views/LiftoffJPanel.java b/src/main/java/com/pesterenan/views/LiftoffJPanel.java
similarity index 100%
rename from src/com/pesterenan/views/LiftoffJPanel.java
rename to src/main/java/com/pesterenan/views/LiftoffJPanel.java
diff --git a/src/com/pesterenan/views/MainGui.java b/src/main/java/com/pesterenan/views/MainGui.java
similarity index 89%
rename from src/com/pesterenan/views/MainGui.java
rename to src/main/java/com/pesterenan/views/MainGui.java
index 04c903a..f824d7f 100644
--- a/src/com/pesterenan/views/MainGui.java
+++ b/src/main/java/com/pesterenan/views/MainGui.java
@@ -9,13 +9,11 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
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);
@@ -28,12 +26,14 @@ public class MainGui extends JFrame implements ActionListener, UIMethods {
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 ManeuverJPanel pnlManeuver;
+ private CreateManeuverJPanel pnlCreateManeuvers;
+ private RunManeuverJPanel pnlRunManeuvers;
private RoverJPanel pnlRover;
+ private DockingJPanel pnlDocking;
private MainGui() {
initComponents();
@@ -54,7 +54,7 @@ public void initComponents() {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ignored) {
}
-
+
// Menu bar
menuBar = new JMenuBar();
@@ -62,7 +62,7 @@ public void initComponents() {
mnFile = new JMenu(Bundle.getString("main_mn_file"));
mnOptions = new JMenu(Bundle.getString("main_mn_options"));
mnHelp = new JMenu(Bundle.getString("main_mn_help"));
-
+
// Menu Items
mntmInstallKrpc = new JMenuItem(Bundle.getString("main_mntm_install_krpc"));
mntmChangeVessels = new JMenuItem(Bundle.getString("main_mntm_change_vessels"));
@@ -73,8 +73,10 @@ public void initComponents() {
pnlFunctionsAndTelemetry = new FunctionsAndTelemetryJPanel();
pnlLiftoff = new LiftoffJPanel();
pnlLanding = new LandingJPanel();
- pnlManeuver = new ManeuverJPanel();
+ pnlCreateManeuvers = new CreateManeuverJPanel();
+ pnlRunManeuvers = new RunManeuverJPanel();
pnlRover = new RoverJPanel();
+ pnlDocking = new DockingJPanel();
pnlStatus = new StatusJPanel();
}
@@ -88,7 +90,7 @@ public void setupComponents() {
setLocation(100, 100);
setContentPane(ctpMainGui);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
+
// Setting-up components:
mntmAbout.addActionListener(this);
mntmChangeVessels.addActionListener(this);
@@ -98,7 +100,7 @@ public void setupComponents() {
cardJPanels.setPreferredSize(PNL_DIMENSION);
cardJPanels.setSize(PNL_DIMENSION);
}
-
+
@Override
public void layoutComponents() {
// Main Panel layout:
@@ -120,12 +122,17 @@ public void layoutComponents() {
menuBar.add(mnOptions);
menuBar.add(mnHelp);
+ JTabbedPane pnlManeuverJTabbedPane = new JTabbedPane();
+ pnlManeuverJTabbedPane.addTab("Criar Manobras", pnlCreateManeuvers);
+ pnlManeuverJTabbedPane.addTab("Executar Manobras", pnlRunManeuvers);
+
cardJPanels.setLayout(cardLayout);
cardJPanels.add(pnlFunctionsAndTelemetry, Modulos.MODULO_TELEMETRIA.get());
cardJPanels.add(pnlLiftoff, Modulos.MODULO_DECOLAGEM.get());
cardJPanels.add(pnlLanding, Modulos.MODULO_POUSO.get());
- cardJPanels.add(pnlManeuver, Modulos.MODULO_EXEC_MANOBRAS.get());
+ cardJPanels.add(pnlManeuverJTabbedPane, Modulos.MODULE_MANEUVER.get());
cardJPanels.add(pnlRover, Modulos.MODULO_ROVER.get());
+ cardJPanels.add(pnlDocking, Modulos.MODULO_DOCKING.get());
}
public void actionPerformed(ActionEvent e) {
@@ -172,7 +179,7 @@ public static JPanel getCardJPanels() {
public static void changeToPage(ActionEvent e) {
cardLayout.show(cardJPanels, e.getActionCommand());
}
-
+
public static void backToTelemetry(ActionEvent e) {
cardLayout.show(cardJPanels, Modulos.MODULO_TELEMETRIA.get());
}
diff --git a/src/com/pesterenan/views/RoverJPanel.java b/src/main/java/com/pesterenan/views/RoverJPanel.java
similarity index 99%
rename from src/com/pesterenan/views/RoverJPanel.java
rename to src/main/java/com/pesterenan/views/RoverJPanel.java
index d9b4d20..8590f82 100644
--- a/src/com/pesterenan/views/RoverJPanel.java
+++ b/src/main/java/com/pesterenan/views/RoverJPanel.java
@@ -169,4 +169,4 @@ private boolean validateTextFields() {
}
return true;
}
-}
\ No newline at end of file
+}
diff --git a/src/com/pesterenan/views/ManeuverJPanel.java b/src/main/java/com/pesterenan/views/RunManeuverJPanel.java
similarity index 59%
rename from src/com/pesterenan/views/ManeuverJPanel.java
rename to src/main/java/com/pesterenan/views/RunManeuverJPanel.java
index c0b80e9..037ecd8 100644
--- a/src/com/pesterenan/views/ManeuverJPanel.java
+++ b/src/main/java/com/pesterenan/views/RunManeuverJPanel.java
@@ -2,8 +2,15 @@
import com.pesterenan.MechPeste;
import com.pesterenan.resources.Bundle;
+import com.pesterenan.utils.ControlePID;
import com.pesterenan.utils.Modulos;
+import krpc.client.RPCException;
+import krpc.client.services.SpaceCenter.Node;
+import krpc.client.services.SpaceCenter.Orbit;
+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;
@@ -18,14 +25,15 @@
import static com.pesterenan.views.MainGui.MARGIN_BORDER_10_PX_LR;
import static com.pesterenan.views.MainGui.PNL_DIMENSION;
-public class ManeuverJPanel extends JPanel implements ActionListener, UIMethods {
+public class RunManeuverJPanel extends JPanel implements ActionListener, UIMethods {
private static final long serialVersionUID = 1L;
- private JLabel lblExecute, lblAdjustInc;
- private JButton btnLowerOrbit, btnApoapsis, btnPeriapsis, btnExecute, btnAdjustInc, btnBack;
+ private JLabel lblExecute;
+ private JButton btnLowerOrbit, btnApoapsis, btnPeriapsis, btnExecute, btnBack, btnAlignPlanes, btnRendezvous;
private JCheckBox chkFineAdjusment;
+ private final ControlePID ctrlManeuver = new ControlePID();
- public ManeuverJPanel() {
+ public RunManeuverJPanel() {
initComponents();
setupComponents();
layoutComponents();
@@ -33,35 +41,89 @@ public ManeuverJPanel() {
public void initComponents() {
// Labels:
- lblAdjustInc = new JLabel(Bundle.getString("pnl_mnv_lbl_adj_inc"));
lblExecute = new JLabel(Bundle.getString("pnl_mnv_lbl_exec_mnv"));
// Buttons:
- btnAdjustInc = new JButton(Bundle.getString("pnl_mnv_btn_adj_inc"));
btnApoapsis = new JButton(Bundle.getString("pnl_mnv_btn_apoapsis"));
btnBack = new JButton(Bundle.getString("pnl_mnv_btn_back"));
btnExecute = new JButton(Bundle.getString("pnl_mnv_btn_exec_mnv"));
btnLowerOrbit = new JButton(Bundle.getString("pnl_mnv_btn_lower_orbit"));
btnPeriapsis = new JButton(Bundle.getString("pnl_mnv_btn_periapsis"));
+ btnAlignPlanes = new JButton("Alinhar planos");
+ btnRendezvous = new JButton("Rendezvous");
// Misc:
chkFineAdjusment = new JCheckBox(Bundle.getString("pnl_mnv_chk_adj_mnv_rcs"));
}
- public void setupComponents() {
- // Main Panel setup:
- setBorder(new TitledBorder(null, Bundle.getString("pnl_mnv_border"), TitledBorder.LEADING, TitledBorder.TOP,
- null, null));
+ public static void createManeuver() {
+ System.out.println("Create maneuver");
+ try {
+ createManeuver(MechPeste.getSpaceCenter().getUT() + 60);
+ } catch (RPCException e) {
+ }
+ }
+
+ public static void createManeuver(double atFutureTime) {
+ System.out.println("Create maneuver overloaded");
+ try {
+ MechPeste.newInstance();
+ Vessel vessel = MechPeste.getSpaceCenter().getActiveVessel();
+ System.out.println("vessel: " + vessel);
+
+ if (vessel.getSituation() != VesselSituation.ORBITING) {
+ StatusJPanel.setStatusMessage("Não é possível criar a manobra fora de órbita.");
+ return;
+ }
+ vessel.getControl().addNode(atFutureTime, 0, 0, 0);
+ } catch (Exception e) {
+ }
+ }
+ public static void positionManeuverAt(String node) {
+ try {
+ MechPeste.newInstance();
+ Vessel vessel = MechPeste.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();
+ break;
+ case "periapsis":
+ timeToNode = MechPeste.getSpaceCenter().getUT() + orbit.getTimeToPeriapsis();
+ break;
+ case "ascending":
+ double ascendingAnomaly = orbit
+ .trueAnomalyAtAN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit());
+ timeToNode = orbit.uTAtTrueAnomaly(ascendingAnomaly);
+ break;
+ case "descending":
+ double descendingAnomaly = orbit
+ .trueAnomalyAtDN(MechPeste.getSpaceCenter().getTargetVessel().getOrbit());
+ timeToNode = orbit.uTAtTrueAnomaly(descendingAnomaly);
+ break;
+ }
+ currentManeuver.setUT(timeToNode);
+ // Print the maneuver node information
+ System.out.println("Maneuver Node updated:");
+ System.out.println(" Time to node: " + currentManeuver.getTimeTo() + " s");
+ } catch (Exception e) {
+ }
+ }
+
+ public void setupComponents() {
// Setting-up components:
- btnAdjustInc.addActionListener(this);
- btnAdjustInc.setActionCommand(Modulos.AJUSTAR.get());
- btnAdjustInc.setEnabled(false);
- btnAdjustInc.setMaximumSize(BTN_DIMENSION);
- btnAdjustInc.setPreferredSize(BTN_DIMENSION);
+ btnAlignPlanes.addActionListener(this);
+ btnAlignPlanes.setMaximumSize(BTN_DIMENSION);
+ btnAlignPlanes.setPreferredSize(BTN_DIMENSION);
+
+ btnRendezvous.addActionListener(this);
+ btnRendezvous.setMaximumSize(BTN_DIMENSION);
+ btnRendezvous.setPreferredSize(BTN_DIMENSION);
btnApoapsis.addActionListener(this);
- btnApoapsis.setActionCommand(Modulos.APOASTRO.get());
btnApoapsis.setMaximumSize(BTN_DIMENSION);
btnApoapsis.setPreferredSize(BTN_DIMENSION);
@@ -70,17 +132,14 @@ public void setupComponents() {
btnBack.setPreferredSize(BTN_DIMENSION);
btnExecute.addActionListener(this);
- btnExecute.setActionCommand(Modulos.EXECUTAR.get());
btnExecute.setMaximumSize(BTN_DIMENSION);
btnExecute.setPreferredSize(BTN_DIMENSION);
btnLowerOrbit.addActionListener(this);
- btnLowerOrbit.setActionCommand(Modulos.ORBITA_BAIXA.get());
btnLowerOrbit.setMaximumSize(BTN_DIMENSION);
btnLowerOrbit.setPreferredSize(BTN_DIMENSION);
btnPeriapsis.addActionListener(this);
- btnPeriapsis.setActionCommand(Modulos.PERIASTRO.get());
btnPeriapsis.setMaximumSize(BTN_DIMENSION);
btnPeriapsis.setPreferredSize(BTN_DIMENSION);
}
@@ -98,12 +157,11 @@ public void layoutComponents() {
pnlExecuteManeuver.add(MainGui.createMarginComponent(10, 0));
pnlExecuteManeuver.add(btnExecute);
- JPanel pnlAdjustInclination = new JPanel();
- pnlAdjustInclination.setLayout(new BoxLayout(pnlAdjustInclination, BoxLayout.X_AXIS));
- pnlAdjustInclination.setBorder(MARGIN_BORDER_10_PX_LR);
- pnlAdjustInclination.add(lblAdjustInc);
- pnlAdjustInclination.add(Box.createHorizontalGlue());
- pnlAdjustInclination.add(btnAdjustInc);
+ JPanel pnlAutoPosition = new JPanel();
+ pnlAutoPosition.setLayout(new BoxLayout(pnlAutoPosition, BoxLayout.X_AXIS));
+ pnlAutoPosition.setBorder(new TitledBorder("Auto posição:"));
+ pnlAutoPosition.add(btnAlignPlanes);
+ pnlAutoPosition.add(btnRendezvous);
JPanel pnlCircularize = new JPanel();
pnlCircularize.setLayout(new BoxLayout(pnlCircularize, BoxLayout.X_AXIS));
@@ -119,7 +177,7 @@ public void layoutComponents() {
JPanel pnlSetup = new JPanel();
pnlSetup.setLayout(new BoxLayout(pnlSetup, BoxLayout.Y_AXIS));
pnlSetup.add(pnlExecuteManeuver);
- pnlSetup.add(pnlAdjustInclination);
+ pnlSetup.add(pnlAutoPosition);
JPanel pnlOptions = new JPanel();
pnlOptions.setLayout(new BoxLayout(pnlOptions, BoxLayout.Y_AXIS));
@@ -161,9 +219,12 @@ public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnPeriapsis) {
handleManeuverFunction(Modulos.PERIASTRO.get());
}
- if (e.getSource() == btnAdjustInc) {
+ if (e.getSource() == btnAlignPlanes) {
handleManeuverFunction(Modulos.AJUSTAR.get());
}
+ if (e.getSource() == btnRendezvous) {
+ handleManeuverFunction(Modulos.RENDEZVOUS.get());
+ }
if (e.getSource() == btnBack) {
MainGui.backToTelemetry(e);
}
@@ -171,8 +232,8 @@ public void actionPerformed(ActionEvent e) {
protected void handleManeuverFunction(String maneuverFunction) {
Map commands = new HashMap<>();
- commands.put(Modulos.MODULO.get(), Modulos.MODULO_EXEC_MANOBRAS.get());
- commands.put(Modulos.FUNCAO.get(), maneuverFunction);
+ commands.put(Modulos.MODULO.get(), Modulos.MODULE_MANEUVER.get());
+ commands.put(Modulos.FUNCAO.get(), maneuverFunction.toString());
commands.put(Modulos.AJUSTE_FINO.get(), String.valueOf(chkFineAdjusment.isSelected()));
MechPeste.newInstance().startModule(commands);
}
diff --git a/src/com/pesterenan/views/StatusJPanel.java b/src/main/java/com/pesterenan/views/StatusJPanel.java
similarity index 100%
rename from src/com/pesterenan/views/StatusJPanel.java
rename to src/main/java/com/pesterenan/views/StatusJPanel.java
diff --git a/src/main/java/com/pesterenan/views/UIMethods.java b/src/main/java/com/pesterenan/views/UIMethods.java
new file mode 100644
index 0000000..5338fd0
--- /dev/null
+++ b/src/main/java/com/pesterenan/views/UIMethods.java
@@ -0,0 +1,10 @@
+package com.pesterenan.views;
+
+public interface UIMethods {
+
+ public void initComponents();
+
+ public void setupComponents();
+
+ public void layoutComponents();
+}
diff --git a/src/com/pesterenan/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF
similarity index 100%
rename from src/com/pesterenan/resources/META-INF/MANIFEST.MF
rename to src/main/resources/META-INF/MANIFEST.MF
diff --git a/src/com/pesterenan/resources/MechPesteBundle.properties b/src/main/resources/MechPesteBundle.properties
similarity index 94%
rename from src/com/pesterenan/resources/MechPesteBundle.properties
rename to src/main/resources/MechPesteBundle.properties
index ee168f7..03fcb5a 100644
--- a/src/com/pesterenan/resources/MechPesteBundle.properties
+++ b/src/main/resources/MechPesteBundle.properties
@@ -1,15 +1,16 @@
btn_func_landing = Auto Landing
btn_func_liftoff = Orbital Liftoff
btn_func_create_maneuver = Create Maneuvers
-btn_func_exec_maneuver = Exec. Maneuvers
+btn_func_maneuver = Maneuvers
btn_func_rover = Drive Rover
+btn_func_docking = Docking
btn_stat_connect = Connect
installer_dialog_btn_browse = Browse...
installer_dialog_btn_cancel = Cancel
installer_dialog_btn_download = Download file and install
installer_dialog_pnl_path = Path to KSP's folder\:
installer_dialog_title = KRPC Installer
-installer_dialog_txt_info = Here you can download the latest version of KRPC to use with MechPeste.
The app will connect and download the 0.5.1 version from the original KRPC's Github.
+installer_dialog_txt_info = Here you can download the latest version of KRPC to use with MechPeste.
The app will connect and download the 0.5.2 version from the original KRPC's Github.
lbl_stat_ready = Ready.
main_mn_file = File
main_mn_help = Help
@@ -34,8 +35,8 @@ pnl_land_pnl_hover_border = Hover the area\:
pnl_lift_btn_back = Back
pnl_lift_btn_liftoff = Lift-off
pnl_lift_cb_gravity_curve_tooltip = Choose the type of gravity curve to be performed. Goes from the softest (Sinosoidal) to the most exaggerated (Exponencial).
-pnl_lift_chk_open_panels = Open solar panels/radiators after getting to orbit
-pnl_lift_chk_open_panels_tooltip = After the circularizing maneuver, opens the solar panels and radiators.
+pnl_lift_chk_open_panels = Open solar panels/radiators/antennas after getting to orbit
+pnl_lift_chk_open_panels_tooltip = After the circularizing maneuver, opens the solar panels, radiators and deployable antennas.
pnl_lift_chk_options = Options\:
pnl_lift_chk_staging = Drop stages during liftoff
pnl_lift_chk_staging_tooltip = When the ship is going to orbit, if the stage doesn't have any more fuel, it will be staged.
@@ -62,6 +63,7 @@ pnl_mnv_lbl_exec_mnv = Execute next maneuver\:
pnl_rover_border = Drive Rover\:
pnl_rover_btn_back = Back
pnl_rover_btn_drive = Drive
+pnl_rover_btn_docking = Start Docking
pnl_rover_default_name = Target
pnl_rover_lbl_max_speed = Max Speed\:
pnl_rover_max_speed_above_3 = Max speed must be over 3m/s\u00B2
diff --git a/src/com/pesterenan/resources/MechPesteBundle_pt.properties b/src/main/resources/MechPesteBundle_pt.properties
similarity index 94%
rename from src/com/pesterenan/resources/MechPesteBundle_pt.properties
rename to src/main/resources/MechPesteBundle_pt.properties
index 9f3ffd3..36cb87a 100644
--- a/src/com/pesterenan/resources/MechPesteBundle_pt.properties
+++ b/src/main/resources/MechPesteBundle_pt.properties
@@ -1,15 +1,16 @@
btn_func_landing = Pouso Autom\u00E1tico
btn_func_liftoff = Decolagem Orbital
btn_func_create_maneuver = Criar Manobras
-btn_func_exec_maneuver = Exec. Manobras
+btn_func_maneuver = Manobras
btn_func_rover = Pilotar Rover
+btn_func_docking = Acoplagem
btn_stat_connect = Conectar
installer_dialog_btn_browse = Escolher...
installer_dialog_btn_cancel = Cancelar
installer_dialog_btn_download = Fazer download e instalar
installer_dialog_pnl_path = Caminho para a Pasta do KSP\:
installer_dialog_title = Instalador do KRPC
-installer_dialog_txt_info = Aqui voc\u00ea pode baixar a \u00faltima vers\u00e3o do KRPC para usar com o MechPeste.
O app ir\u00e1 se conectar e baixar a vers\u00e3o 0.5.1 do Github original do KRPC.
+installer_dialog_txt_info = Aqui voc\u00ea pode baixar a \u00faltima vers\u00e3o do KRPC para usar com o MechPeste.
O app ir\u00e1 se conectar e baixar a vers\u00e3o 0.5.2 do Github original do KRPC.
lbl_stat_ready = Pronto.
main_mn_file = Arquivo
main_mn_help = Ajuda
@@ -34,8 +35,8 @@ pnl_land_pnl_hover_border = Sobrevoar a \u00E1rea\:
pnl_lift_btn_back = Voltar
pnl_lift_btn_liftoff = Decolagem
pnl_lift_cb_gravity_curve_tooltip = Escolha o modelo da curva gravitacional a ser realizada.\rVai da mais leve (Sinusoidal) at\u00E9 a mais exagerada (Exponencial).
-pnl_lift_chk_open_panels = Abrir pain\u00E9is/radiadores
ap\u00F3s entrar em \u00F3rbita
-pnl_lift_chk_open_panels_tooltip = Ap\u00F3s a manobra de circulariza\u00E7\u00E3o, abre os pain\u00E9is e radiadores da nave.
+pnl_lift_chk_open_panels = Abrir pain\u00E9is/radiadores/antenas
ap\u00F3s entrar em \u00F3rbita
+pnl_lift_chk_open_panels_tooltip = Ap\u00F3s a manobra de circulariza\u00E7\u00E3o, abre os pain\u00E9is, radiadores e antenas dobr\u00e1veis da nave.
pnl_lift_chk_options = Op\u00e7\u00f5es\:
pnl_lift_chk_staging = Soltar est\u00E1gios e escudos
durante a decolagem
pnl_lift_chk_staging_tooltip = Enquanto a nave sobe pra \u00F3rbita, se o est\u00E1gio ficar sem combust\u00EDvel, ele ser\u00E1 descartado.
@@ -61,6 +62,7 @@ pnl_mnv_lbl_exec_mnv = Executar pr\u00F3xima
manobra\:
pnl_rover_border = Pilotar Rover\:
pnl_rover_btn_back = Voltar
pnl_rover_btn_drive = Pilotar
+pnl_rover_btn_docking = Iniciar Acoplagem
pnl_rover_default_name = Alvo
pnl_rover_lbl_max_speed = Velocidade m\u00E1xima:
pnl_rover_max_speed_above_3 = A velocidade m\u00E1xima tem que ser acima de 3m/s\u00b2
diff --git a/src/main/resources/krpc-java-0.5.2.jar b/src/main/resources/krpc-java-0.5.2.jar
new file mode 100644
index 0000000..a645a94
Binary files /dev/null and b/src/main/resources/krpc-java-0.5.2.jar differ