Browse Source

Init

master
Apostolos Fanakis 7 years ago
commit
09b45b4620
  1. 6
      .classpath
  2. 17
      .project
  3. BIN
      bin/gr/auth/ee/computer_networks/Main$1.class
  4. BIN
      bin/gr/auth/ee/computer_networks/Main.class
  5. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/AudioIsAdaptivelyQuantisedListener.class
  6. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/AudioListener.class
  7. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/AudioRequestSpecificSampleListener.class
  8. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/CopterListener.class
  9. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/CopterSliderListener.class
  10. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/EchoListener.class
  11. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/GlobalSettingsListener.class
  12. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/ImageListener.class
  13. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/VehicleListener.class
  14. BIN
      bin/gr/auth/ee/computer_networks/actionListeners/VehicleUseUDPListener.class
  15. BIN
      bin/gr/auth/ee/computer_networks/helpers/MiniPID.class
  16. BIN
      bin/gr/auth/ee/computer_networks/helpers/TCPBundle.class
  17. BIN
      bin/gr/auth/ee/computer_networks/helpers/UDPBundle.class
  18. BIN
      bin/gr/auth/ee/computer_networks/networkTests/Audio$AudioStreamer.class
  19. BIN
      bin/gr/auth/ee/computer_networks/networkTests/Audio.class
  20. BIN
      bin/gr/auth/ee/computer_networks/networkTests/Copter.class
  21. BIN
      bin/gr/auth/ee/computer_networks/networkTests/Echo.class
  22. BIN
      bin/gr/auth/ee/computer_networks/networkTests/Image.class
  23. BIN
      bin/gr/auth/ee/computer_networks/networkTests/Vehicle.class
  24. BIN
      bin/org/eclipse/wb/swing/FocusTraversalOnArray.class
  25. 1
      output/audioDiff_A5723.csv
  26. 1
      output/audioDiff_A5723_1.csv
  27. 1
      output/audioDiff_A5723_2.csv
  28. 1
      output/audioDiff_A5723_3.csv
  29. 1
      output/audioDiff_A5723_4.csv
  30. 2
      output/audioParams_A5723.csv
  31. 1
      output/audio_A5723.csv
  32. 1
      output/audio_A5723_1.csv
  33. 0
      output/audio_A5723_2.csv
  34. 1
      output/audio_A5723_3.csv
  35. 0
      output/audio_A5723_4.csv
  36. 1
      output/echo_E7945.csv
  37. 1
      output/echo_E7945_1.csv
  38. BIN
      output/image_M6847FLOW=ONUDP=512 _0.jpg
  39. BIN
      output/image_M6847FLOW=ONUDP=512 _1.jpg
  40. BIN
      output/image_M6847UDP=1024 _0.jpg
  41. BIN
      output/image_M6847UDP=1024 _1.jpg
  42. BIN
      output/image_M6847UDP=1024 _2.jpg
  43. BIN
      output/image_M6847UDP=1024 _3.jpg
  44. 0
      output/vehicle_TCP.csv
  45. 0
      output/vehicle_TCP_1.csv
  46. 0
      output/vehicle_TCP_2.csv
  47. 0
      output/vehicle_TCP_3.csv
  48. 0
      output/vehicle_TCP_4.csv
  49. 6
      output/vehicle_TCP_5.csv
  50. 0
      output/vehicle_V0820.csv
  51. 6
      output/vehicle_V0820_1.csv
  52. 1559
      src/gr/auth/ee/computer_networks/Main.java
  53. 26
      src/gr/auth/ee/computer_networks/actionListeners/AudioIsAdaptivelyQuantisedListener.java
  54. 79
      src/gr/auth/ee/computer_networks/actionListeners/AudioListener.java
  55. 37
      src/gr/auth/ee/computer_networks/actionListeners/AudioRequestSpecificSampleListener.java
  56. 65
      src/gr/auth/ee/computer_networks/actionListeners/CopterListener.java
  57. 26
      src/gr/auth/ee/computer_networks/actionListeners/CopterSliderListener.java
  58. 51
      src/gr/auth/ee/computer_networks/actionListeners/EchoListener.java
  59. 41
      src/gr/auth/ee/computer_networks/actionListeners/GlobalSettingsListener.java
  60. 58
      src/gr/auth/ee/computer_networks/actionListeners/ImageListener.java
  61. 83
      src/gr/auth/ee/computer_networks/actionListeners/VehicleListener.java
  62. 26
      src/gr/auth/ee/computer_networks/actionListeners/VehicleUseUDPListener.java
  63. 572
      src/gr/auth/ee/computer_networks/helpers/MiniPID.java
  64. 64
      src/gr/auth/ee/computer_networks/helpers/TCPBundle.java
  65. 78
      src/gr/auth/ee/computer_networks/helpers/UDPBundle.java
  66. 380
      src/gr/auth/ee/computer_networks/networkTests/Audio.java
  67. 199
      src/gr/auth/ee/computer_networks/networkTests/Copter.java
  68. 226
      src/gr/auth/ee/computer_networks/networkTests/Echo.java
  69. 265
      src/gr/auth/ee/computer_networks/networkTests/Image.java
  70. 393
      src/gr/auth/ee/computer_networks/networkTests/Vehicle.java
  71. 105
      src/org/eclipse/wb/swing/FocusTraversalOnArray.java

6
.classpath

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

17
.project

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ComputerNetworksII</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

BIN
bin/gr/auth/ee/computer_networks/Main$1.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/Main.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/AudioIsAdaptivelyQuantisedListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/AudioListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/AudioRequestSpecificSampleListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/CopterListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/CopterSliderListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/EchoListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/GlobalSettingsListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/ImageListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/VehicleListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/actionListeners/VehicleUseUDPListener.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/helpers/MiniPID.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/helpers/TCPBundle.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/helpers/UDPBundle.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/networkTests/Audio$AudioStreamer.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/networkTests/Audio.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/networkTests/Copter.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/networkTests/Echo.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/networkTests/Image.class

Binary file not shown.

BIN
bin/gr/auth/ee/computer_networks/networkTests/Vehicle.class

Binary file not shown.

BIN
bin/org/eclipse/wb/swing/FocusTraversalOnArray.class

Binary file not shown.

1
output/audioDiff_A5723.csv

File diff suppressed because one or more lines are too long

1
output/audioDiff_A5723_1.csv

File diff suppressed because one or more lines are too long

1
output/audioDiff_A5723_2.csv

File diff suppressed because one or more lines are too long

1
output/audioDiff_A5723_3.csv

File diff suppressed because one or more lines are too long

1
output/audioDiff_A5723_4.csv

File diff suppressed because one or more lines are too long

2
output/audioParams_A5723.csv

@ -0,0 +1,2 @@
-18 10 15 34 -51 16 6 5 27 -73 57 -31 17 -15 -10 34 -122 101 -57 62 -13 -26 17 -4 -7 6 26 6 -13 17 -26 24 3 -51 13 -22 44 -2 3 8 -19 10 -7 4 -13 -4 9 -1 30 -12 -48 54 2 -25 3 20 -24 35 -52 88 -66 24 6 -35 10 27 -23 3 16 1 6 -21 -16 13 2 -26 61 -30 5 6 -16 -4 19 -16 43 -60 33 29 -33 -37 15 31 3 -56 28 47 -30 -16 2 -10 -8 30 -40 0 30 21 -22 4 3 -14 9 4 0 1 -9 11 -20 9 26 17 -41 4 -5 13 6 -29 21 7 -3 10 -28 1 -2 24 -29 15 -20 16 -7 -7 12 -19 38 9 -30 19 -11 5 -19 28 15 -35 13 -2 -5 5 -33 35 11 -24 -1 0 8 -2 -18 16 4 -73 85 -47 25 6 -13 -14 5 43 -19 5 -15 -3 23 -7 -23 12 -19 -14 46 -8 -11 13 -2 18 16 -51 52 -38 -13 16 -6 -10 4 2 8 -22 37 -24 14 -1 -17 2 30 -36 0 13 -4 4 -11 -14 -26 57 -14 39 -58 29 5 -18 14 -9 10 1 -4 18 -11 10 -26 -35 41 15 -8 -11 10 22 -33 1 10 -3 0 0 -2 -5 -7 32 -12 -22 23 -3 -5 13 16 -37 31 -25 0 10 -11 4 10 24 -42 27 -33 29 -18 14 -11 7 -15 0 -36 20 26 -23 48 -24 47 -63 41 -7 -1 -19 3 4 18 -24 13 -29 9 7 7 -11 10 13 -15 23 3 -16 1 -6 -3 14 -21 -5 6 10 -19 17 4 -3 13 -10
2315 2154 1759 1581 1236 1010 767 863 2122 2042 1467 1433 1348 1317 1202 1553 1790 2157 2142 2028 2503 1989 1673 1518 1335 1222 1111 1113 998 982 844 909 810 1901 2011 1350 1413 1392 1014 888 837 866 723 726 768 821 606 663 1030 1824 1557 1690 1822 1477 1674 1497 1259 1257 1702 2059 1929 1576 1392 1446 1158 1025 1348 2025 1775 1400 1220 1138 933 672 717 1951 2066 1710 1387 1078 996 948 1157 2020 3110 2514 2061 1883 1673 1626 1612 1426 1485 1304 1260 1209 1270 1081 1080 1013 2313 1965 1681 1344 1324 1109 1010 917 889 818 776 836 764 773 764 1323 1468 1355 1569 1560 1393 1243 1232 1212 1144 1078 1135 1008 898 832 798 762 862 1366 1824 1700 1458 1235 787 619 643 649 2148 1893 1495 1264 892 666 621 789 1768 2115 2073 1706 1591 1305 1286 1246 1142 1141 1084 1013 1050 1080 941 890 694 2112 1788 1442 1211 884 603 636 704 1257 1654 1640 1427 1196 644 629 977 1835 2437 2374 1949 1780 1529 1406 1322 1304 2343 2508 1779 1640 1571 1271 1103 1123 1387 2156 1659 1510 1214 1180 892 673 724 2232 2004 1496 1236 789 696 984 1173 2819 2006 2158 1709 1744 1700 1603 1572 1411 1496 1216 1146 1115 1022 942 933 984 1978 1782 1537 1220 1023 922 822 783 805 786 758 754 724 804 690 1314 1385 1343 1607 1399 1439 1279 1298 1194 1284 1176 1126 943 952 889 867 856 781 1691 2128 1725 1459 1349 1074 1027 819 719 2369 1836 1483 1395 1104 1104 1273 1339 2502 2274 2117 1786 1582 1477 1378 1224 1249 1078 1212 1116 987 999 930 859 730 2316 1810 1480 1243 1092 973 1006 737 775 722 793 769 694 678 688 1073 1945 1599 1578

1
output/audio_A5723.csv

File diff suppressed because one or more lines are too long

1
output/audio_A5723_1.csv

File diff suppressed because one or more lines are too long

0
output/audio_A5723_2.csv

1
output/audio_A5723_3.csv

File diff suppressed because one or more lines are too long

0
output/audio_A5723_4.csv

1
output/echo_E7945.csv

@ -0,0 +1 @@
1488 1551 1592 847 1469 1478 1011 1040 1187 1778

1
output/echo_E7945_1.csv

@ -0,0 +1 @@
62 62 53 59 58 62 69 72 62 75 71 76 80 81 86

BIN
output/image_M6847FLOW=ONUDP=512 _0.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
output/image_M6847FLOW=ONUDP=512 _1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
output/image_M6847UDP=1024 _0.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
output/image_M6847UDP=1024 _1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
output/image_M6847UDP=1024 _2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
output/image_M6847UDP=1024 _3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

0
output/vehicle_TCP.csv

0
output/vehicle_TCP_1.csv

0
output/vehicle_TCP_2.csv

0
output/vehicle_TCP_3.csv

0
output/vehicle_TCP_4.csv

6
output/vehicle_TCP_5.csv

@ -0,0 +1,6 @@
0 5 6 8 10 12 13 14 15 17 18 19 20 22 23 24
12 12 12 12 12 12 12 12 12 12 11 11 11 12 12 12
16.0 16.0 16.0 16.0 29.0 17.0 17.0 17.0 17.0 17.0 15.0 15.0 15.0 16.0 16.0 16.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1305.0 1132.0 1112.0 1110.0 1107.0 1129.0
0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0
10 10 10 10 11 10 10 11 10 10 10 10 10 11 11 10

0
output/vehicle_V0820.csv

6
output/vehicle_V0820_1.csv

@ -0,0 +1,6 @@
20 22 23 24 25 27 28 29 31 32 33 34 36 37 38 39
11 12 12 12 12 12 12 12 12 12 12 12 12 12 12 13
15.0 16.0 16.0 16.0 16.0 16.0 16.0 16.0 15.0 16.0 15.0 16.0 16.0 16.0 15.0 16.0
1112.0 1110.0 1107.0 1129.0 1134.0 1134.0 1107.0 1115.0 1115.0 1116.0 1123.0 1127.0 1124.0 1105.0 1122.0 1125.0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
10 10 11 11 10 10 11 11 11 11 11 11 11 11 12 11

1559
src/gr/auth/ee/computer_networks/Main.java

File diff suppressed because it is too large

26
src/gr/auth/ee/computer_networks/actionListeners/AudioIsAdaptivelyQuantisedListener.java

@ -0,0 +1,26 @@
package gr.auth.ee.computer_networks.actionListeners;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class AudioIsAdaptivelyQuantisedListener implements ChangeListener {
private final JFormattedTextField formatedTextFieldAudioBetaParameter;
@SuppressWarnings("unused")
private AudioIsAdaptivelyQuantisedListener() {
// Disable default constructor
formatedTextFieldAudioBetaParameter = null;
}
public AudioIsAdaptivelyQuantisedListener(JFormattedTextField formatedTextFieldAudioBetaParameter) {
this.formatedTextFieldAudioBetaParameter = formatedTextFieldAudioBetaParameter;
}
@Override
public void stateChanged(ChangeEvent e) {
this.formatedTextFieldAudioBetaParameter.setEnabled(!((JCheckBox) e.getSource()).isSelected());
}
}

79
src/gr/auth/ee/computer_networks/actionListeners/AudioListener.java

@ -0,0 +1,79 @@
package gr.auth.ee.computer_networks.actionListeners;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JProgressBar;
import javax.swing.JTextPane;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
import gr.auth.ee.computer_networks.networkTests.Audio;
public class AudioListener implements ActionListener {
private final JFormattedTextField formatedTextFieldAudioRequestCode, formatedTextFieldAudioRequestSpecificSample,
formatedTextFieldAudioNumberOfPackets, formatedTextFieldAudioBetaParameter;
private final JComboBox<String> comboBoxAudioPoolSelect;
private final JCheckBox checkBoxAudioRequestSpecificSample, checkBoxAudioAdaptiveQuantiser;
private final JComboBox<Integer> comboBoxAudioQParameter;
private final JTextPane textPaneAudioStatsOutput;
private final JProgressBar progressBarAudioStreamer, progressBarAudioPlayer;
private final UDPBundle UDPConnection;
@SuppressWarnings("unused")
private AudioListener() {
// Disable default constructor
this.formatedTextFieldAudioRequestCode = null;
this.checkBoxAudioRequestSpecificSample = null;
this.formatedTextFieldAudioRequestSpecificSample = null;
this.comboBoxAudioPoolSelect = null;
this.formatedTextFieldAudioNumberOfPackets = null;
this.checkBoxAudioAdaptiveQuantiser = null;
this.formatedTextFieldAudioBetaParameter = null;
this.comboBoxAudioQParameter = null;
this.textPaneAudioStatsOutput = null;
this.progressBarAudioStreamer = null;
this.progressBarAudioPlayer = null;
this.UDPConnection = null;
}
public AudioListener(JFormattedTextField formatedTextFieldAudioRequestCode,
JCheckBox checkBoxAudioRequestSpecificSample,
JFormattedTextField formatedTextFieldAudioRequestSpecificSample, JComboBox<String> comboBoxAudioPoolSelect,
JFormattedTextField formatedTextFieldAudioNumberOfPackets, JCheckBox checkBoxAudioAdaptiveQuantiser,
JFormattedTextField formatedTextFieldAudioBetaParameter, JComboBox<Integer> comboBoxAudioQParameter,
JTextPane textPaneAudioStatsOutput, JProgressBar progressBarAudioStreamer,
JProgressBar progressBarAudioPlayer, UDPBundle UDPConnection) {
this.formatedTextFieldAudioRequestCode = formatedTextFieldAudioRequestCode;
this.checkBoxAudioRequestSpecificSample = checkBoxAudioRequestSpecificSample;
this.formatedTextFieldAudioRequestSpecificSample = formatedTextFieldAudioRequestSpecificSample;
this.comboBoxAudioPoolSelect = comboBoxAudioPoolSelect;
this.formatedTextFieldAudioNumberOfPackets = formatedTextFieldAudioNumberOfPackets;
this.checkBoxAudioAdaptiveQuantiser = checkBoxAudioAdaptiveQuantiser;
this.formatedTextFieldAudioBetaParameter = formatedTextFieldAudioBetaParameter;
this.comboBoxAudioQParameter = comboBoxAudioQParameter;
this.textPaneAudioStatsOutput = textPaneAudioStatsOutput;
this.progressBarAudioStreamer = progressBarAudioStreamer;
this.progressBarAudioPlayer = progressBarAudioPlayer;
this.UDPConnection = UDPConnection;
}
@Override
public void actionPerformed(ActionEvent arg0) {
Main.setSubmitButtonsEnabled(false);
Main.setStatusLineText("Test running...", Main.STATUS_LINE_ACTION_RUNNING);
(new Audio(UDPConnection, formatedTextFieldAudioRequestCode.getText(),
checkBoxAudioRequestSpecificSample.isSelected(),
Integer.parseInt(formatedTextFieldAudioRequestSpecificSample.getText().substring(1)),
comboBoxAudioPoolSelect.getItemAt(comboBoxAudioPoolSelect.getSelectedIndex()),
Integer.parseInt(formatedTextFieldAudioNumberOfPackets.getText()),
checkBoxAudioAdaptiveQuantiser.isSelected(),
Integer.parseInt(formatedTextFieldAudioBetaParameter.getText()),
comboBoxAudioQParameter.getItemAt(comboBoxAudioQParameter.getSelectedIndex()), textPaneAudioStatsOutput,
progressBarAudioStreamer, progressBarAudioPlayer)).execute();
}
}

37
src/gr/auth/ee/computer_networks/actionListeners/AudioRequestSpecificSampleListener.java

@ -0,0 +1,37 @@
package gr.auth.ee.computer_networks.actionListeners;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class AudioRequestSpecificSampleListener implements ChangeListener {
private final JFormattedTextField formatedTextFieldAudioRequestSpecificSample;
private final JComboBox<String> comboBoxAudioPoolSelect;
@SuppressWarnings("unused")
private AudioRequestSpecificSampleListener() {
// Disable default constructor
formatedTextFieldAudioRequestSpecificSample = null;
comboBoxAudioPoolSelect = null;
}
public AudioRequestSpecificSampleListener(JFormattedTextField formatedTextFieldAudioRequestSpecificSample,
JComboBox<String> comboBoxAudioPoolSelect) {
this.formatedTextFieldAudioRequestSpecificSample = formatedTextFieldAudioRequestSpecificSample;
this.comboBoxAudioPoolSelect = comboBoxAudioPoolSelect;
}
@Override
public void stateChanged(ChangeEvent e) {
boolean isSpecificSampleRequestSelected = ((JCheckBox) e.getSource()).isSelected();
if (isSpecificSampleRequestSelected) {
this.comboBoxAudioPoolSelect.setSelectedItem(comboBoxAudioPoolSelect.getItemAt(1));
}
this.formatedTextFieldAudioRequestSpecificSample.setEnabled(isSpecificSampleRequestSelected);
this.comboBoxAudioPoolSelect.setEnabled(!isSpecificSampleRequestSelected);
}
}

65
src/gr/auth/ee/computer_networks/actionListeners/CopterListener.java

@ -0,0 +1,65 @@
package gr.auth.ee.computer_networks.actionListeners;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.TCPBundle;
import gr.auth.ee.computer_networks.networkTests.Copter;
public class CopterListener implements ActionListener {
private final JSlider sliderCopterFlightLevel;
private final JLabel lblCopterTemperatureOutput;
private final JLabel lblCopterPressureOutput;
private final JLabel lblCopterAltitudeOutput;
private final JLabel lblCopterLeftMotorOutput;
private final JLabel lblCopterRightMotorOutput;
private final JLabel lblCopterImageOutput;
private final JProgressBar progressBarCopterLeftMotorPower;
private final JProgressBar progressBarCopterRightMotorPower;
private final TCPBundle TCPConnection;
@SuppressWarnings("unused")
private CopterListener() {
// Disable default constructor
this.sliderCopterFlightLevel = null;
this.lblCopterTemperatureOutput = null;
this.lblCopterPressureOutput = null;
this.lblCopterAltitudeOutput = null;
this.lblCopterLeftMotorOutput = null;
this.lblCopterRightMotorOutput = null;
this.lblCopterImageOutput = null;
this.progressBarCopterLeftMotorPower = null;
this.progressBarCopterRightMotorPower = null;
this.TCPConnection = null;
}
public CopterListener(JSlider sliderCopterFlightLevel, JLabel lblCopterTemperatureOutput,
JLabel lblCopterPressureOutput, JLabel lblCopterAltitudeOutput, JLabel lblCopterLeftMotorOutput,
JLabel lblCopterRightMotorOutput, JLabel lblCopterImageOutput, JProgressBar progressBarCopterLeftMotorPower,
JProgressBar progressBarCopterRightMotorPower, TCPBundle TCPConnection) {
this.sliderCopterFlightLevel = sliderCopterFlightLevel;
this.lblCopterTemperatureOutput = lblCopterTemperatureOutput;
this.lblCopterPressureOutput = lblCopterPressureOutput;
this.lblCopterAltitudeOutput = lblCopterAltitudeOutput;
this.lblCopterLeftMotorOutput = lblCopterLeftMotorOutput;
this.lblCopterRightMotorOutput = lblCopterRightMotorOutput;
this.lblCopterImageOutput = lblCopterImageOutput;
this.progressBarCopterLeftMotorPower = progressBarCopterLeftMotorPower;
this.progressBarCopterRightMotorPower = progressBarCopterRightMotorPower;
this.TCPConnection = TCPConnection;
}
@Override
public void actionPerformed(ActionEvent e) {
Main.setSubmitButtonsEnabled(false);
Main.setStatusLineText("Test running...", Main.STATUS_LINE_ACTION_RUNNING);
(new Copter(TCPConnection, sliderCopterFlightLevel.getValue(), lblCopterTemperatureOutput,
lblCopterPressureOutput, lblCopterAltitudeOutput, lblCopterLeftMotorOutput, lblCopterRightMotorOutput,
lblCopterImageOutput, progressBarCopterLeftMotorPower, progressBarCopterRightMotorPower)).execute();
}
}

26
src/gr/auth/ee/computer_networks/actionListeners/CopterSliderListener.java

@ -0,0 +1,26 @@
package gr.auth.ee.computer_networks.actionListeners;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class CopterSliderListener implements ChangeListener {
private final JLabel lblCopterFlightLevel;
@SuppressWarnings("unused")
private CopterSliderListener() {
// Disable default constructor
lblCopterFlightLevel = null;
}
public CopterSliderListener(JLabel lblCopterFlightLevel) {
this.lblCopterFlightLevel = lblCopterFlightLevel;
}
@Override
public void stateChanged(ChangeEvent e) {
lblCopterFlightLevel.setText("Desired flight level:\t" + ((JSlider) e.getSource()).getValue());
}
}

51
src/gr/auth/ee/computer_networks/actionListeners/EchoListener.java

@ -0,0 +1,51 @@
package gr.auth.ee.computer_networks.actionListeners;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
import gr.auth.ee.computer_networks.networkTests.Echo;
public class EchoListener implements ActionListener {
private final JTextField textEchoRequestCode, textEchoDuration, textEchoNumberOfPackages;
private final JCheckBox checkBoxGetTemperature;
private final JTextPane runtimeOutput;
private final UDPBundle UDPConnection;
@SuppressWarnings("unused")
private EchoListener() {
// Disable default constructor
this.textEchoRequestCode = null;
this.textEchoDuration = null;
this.textEchoNumberOfPackages = null;
this.checkBoxGetTemperature = null;
this.runtimeOutput = null;
this.UDPConnection = null;
}
public EchoListener(JTextField textEchoRequestCode, JTextField textEchoDuration,
JTextField textEchoNumberOfPackages, JCheckBox checkBoxGetTemperature, JTextPane runtimeOutput,
UDPBundle UDPConnection) {
this.textEchoRequestCode = textEchoRequestCode;
this.textEchoDuration = textEchoDuration;
this.textEchoNumberOfPackages = textEchoNumberOfPackages;
this.checkBoxGetTemperature = checkBoxGetTemperature;
this.runtimeOutput = runtimeOutput;
this.UDPConnection = UDPConnection;
}
@Override
public void actionPerformed(ActionEvent arg0) {
Main.setSubmitButtonsEnabled(false);
Main.setStatusLineText("Test running...", Main.STATUS_LINE_ACTION_RUNNING);
(new Echo(UDPConnection, textEchoRequestCode.getText(), Integer.parseInt(textEchoDuration.getText()),
Integer.parseInt(textEchoNumberOfPackages.getText()), checkBoxGetTemperature.isSelected(),
runtimeOutput)).execute();
}
}

41
src/gr/auth/ee/computer_networks/actionListeners/GlobalSettingsListener.java

@ -0,0 +1,41 @@
package gr.auth.ee.computer_networks.actionListeners;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFormattedTextField;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
public class GlobalSettingsListener implements ActionListener {
private final JFormattedTextField formatedTextFieldServerPort, formatedTextFieldClientPort;
private final UDPBundle UDPConnection;
@SuppressWarnings("unused")
private GlobalSettingsListener() {
// Disable default constructor
this.formatedTextFieldServerPort = null;
this.formatedTextFieldClientPort = null;
UDPConnection = null;
}
public GlobalSettingsListener(JFormattedTextField formatedTextFieldServerPort,
JFormattedTextField formatedTextFieldClientPort, UDPBundle UDPConnection) {
this.formatedTextFieldServerPort = formatedTextFieldServerPort;
this.formatedTextFieldClientPort = formatedTextFieldClientPort;
this.UDPConnection = UDPConnection;
}
@Override
public void actionPerformed(ActionEvent arg0) {
Main.setSubmitButtonsEnabled(false);
int newLocalPort = Integer.parseInt(formatedTextFieldClientPort.getText());
int newServerPort = Integer.parseInt(formatedTextFieldServerPort.getText());
UDPConnection.setLocalPort(newLocalPort);
UDPConnection.setServerPort(newServerPort);
Main.setStatusLineText("Ports set.", Main.STATUS_LINE_ACTION_DONE);
Main.setSubmitButtonsEnabled(true);
}
}

58
src/gr/auth/ee/computer_networks/actionListeners/ImageListener.java

@ -0,0 +1,58 @@
package gr.auth.ee.computer_networks.actionListeners;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JTextPane;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
import gr.auth.ee.computer_networks.networkTests.Image;
public class ImageListener implements ActionListener {
private final JFormattedTextField formatedTextFieldImageRequestCode, formatedTextFieldImageDuration;
private final JCheckBox checkBoxImageControlFlow;
private final JComboBox<Integer> comboBoxImagePackageLength;
private final JTextPane runtimeStatsOutput;
private final JLabel runtimeImageOutput;
private final UDPBundle UDPConnection;
@SuppressWarnings("unused")
private ImageListener() {
// Disable default constructor
this.formatedTextFieldImageRequestCode = null;
this.checkBoxImageControlFlow = null;
this.comboBoxImagePackageLength = null;
this.formatedTextFieldImageDuration = null;
this.runtimeStatsOutput = null;
this.runtimeImageOutput = null;
this.UDPConnection = null;
}
public ImageListener(JFormattedTextField formatedTextFieldImageRequestCode, JCheckBox checkBoxImageControlFlow,
JComboBox<Integer> comboBoxImagePackageLength, JFormattedTextField formatedTextFieldImageDuration,
JTextPane runtimeStatsOutput, JLabel runtimeImageOutput, UDPBundle UDPConnection) {
this.formatedTextFieldImageRequestCode = formatedTextFieldImageRequestCode;
this.checkBoxImageControlFlow = checkBoxImageControlFlow;
this.comboBoxImagePackageLength = comboBoxImagePackageLength;
this.formatedTextFieldImageDuration = formatedTextFieldImageDuration;
this.runtimeStatsOutput = runtimeStatsOutput;
this.runtimeImageOutput = runtimeImageOutput;
this.UDPConnection = UDPConnection;
}
@Override
public void actionPerformed(ActionEvent arg0) {
Main.setSubmitButtonsEnabled(false);
Main.setStatusLineText("Test running...", Main.STATUS_LINE_ACTION_RUNNING);
(new Image(UDPConnection, formatedTextFieldImageRequestCode.getText(),
Integer.parseInt(formatedTextFieldImageDuration.getText()), checkBoxImageControlFlow.isSelected(),
comboBoxImagePackageLength.getItemAt(comboBoxImagePackageLength.getSelectedIndex()), runtimeStatsOutput,
runtimeImageOutput)).execute();
}
}

83
src/gr/auth/ee/computer_networks/actionListeners/VehicleListener.java

@ -0,0 +1,83 @@
package gr.auth.ee.computer_networks.actionListeners;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.TCPBundle;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
import gr.auth.ee.computer_networks.networkTests.Vehicle;
public class VehicleListener implements ActionListener {
private final JFormattedTextField formatedTextFieldVehicleRequestCode;
private final JCheckBox checkBoxVehicleUseUDP;
private final JFormattedTextField formatedTextFieldVehicleDuration;
private final JLabel lblVehicleEngineRunTimeOutput;
private final JLabel lblVehicleAirTempOutput;
private final JLabel lblVehicleThrottlePositionOutput;
private final JLabel lblVehicleEngineRPMOutput;
private final JLabel lblVehicleSpeedOutput;
private final JLabel lblVehicleCoolantTemperatureOutput;
private final JLabel lblVehiclePacketsTotalTimeOutput;
private final TCPBundle TCPConnection;
private final UDPBundle UDPConnection;
@SuppressWarnings("unused")
private VehicleListener() {
// Disable default constructor
this.formatedTextFieldVehicleRequestCode = null;
this.checkBoxVehicleUseUDP = null;
this.formatedTextFieldVehicleDuration = null;
this.lblVehicleEngineRunTimeOutput = null;
this.lblVehicleAirTempOutput = null;
this.lblVehicleThrottlePositionOutput = null;
this.lblVehicleEngineRPMOutput = null;
this.lblVehicleSpeedOutput = null;
this.lblVehicleCoolantTemperatureOutput = null;
this.lblVehiclePacketsTotalTimeOutput = null;
this.TCPConnection = null;
this.UDPConnection = null;
}
public VehicleListener(JFormattedTextField formatedTextFieldVehicleRequestCode, JCheckBox checkBoxVehicleUseUDP,
JFormattedTextField formatedTextFieldVehicleDuration, JLabel lblVehicleEngineRunTimeOutput,
JLabel lblVehicleAirTempOutput, JLabel lblVehicleThrottlePositionOutput, JLabel lblVehicleEngineRPMOutput,
JLabel lblVehicleSpeedOutput, JLabel lblVehicleCoolantTemperatureOutput,
JLabel lblVehiclePacketsTotalTimeOutput, TCPBundle TCPConnection, UDPBundle UDPConnection) {
this.formatedTextFieldVehicleRequestCode = formatedTextFieldVehicleRequestCode;
this.checkBoxVehicleUseUDP = checkBoxVehicleUseUDP;
this.formatedTextFieldVehicleDuration = formatedTextFieldVehicleDuration;
this.lblVehicleEngineRunTimeOutput = lblVehicleEngineRunTimeOutput;
this.lblVehicleAirTempOutput = lblVehicleAirTempOutput;
this.lblVehicleThrottlePositionOutput = lblVehicleThrottlePositionOutput;
this.lblVehicleEngineRPMOutput = lblVehicleEngineRPMOutput;
this.lblVehicleSpeedOutput = lblVehicleSpeedOutput;
this.lblVehicleCoolantTemperatureOutput = lblVehicleCoolantTemperatureOutput;
this.lblVehiclePacketsTotalTimeOutput = lblVehiclePacketsTotalTimeOutput;
this.TCPConnection = TCPConnection;
this.UDPConnection = UDPConnection;
}
@Override
public void actionPerformed(ActionEvent arg0) {
Main.setSubmitButtonsEnabled(false);
Main.setStatusLineText("Test running...", Main.STATUS_LINE_ACTION_RUNNING);
if (checkBoxVehicleUseUDP.isSelected()) {
new Vehicle(UDPConnection, formatedTextFieldVehicleRequestCode.getText(),
Integer.parseInt(formatedTextFieldVehicleDuration.getText()), lblVehicleEngineRunTimeOutput,
lblVehicleAirTempOutput, lblVehicleThrottlePositionOutput, lblVehicleEngineRPMOutput,
lblVehicleSpeedOutput, lblVehicleCoolantTemperatureOutput, lblVehiclePacketsTotalTimeOutput)
.execute();
} else {
new Vehicle(TCPConnection, formatedTextFieldVehicleRequestCode.getText(),
Integer.parseInt(formatedTextFieldVehicleDuration.getText()), lblVehicleEngineRunTimeOutput,
lblVehicleAirTempOutput, lblVehicleThrottlePositionOutput, lblVehicleEngineRPMOutput,
lblVehicleSpeedOutput, lblVehicleCoolantTemperatureOutput, lblVehiclePacketsTotalTimeOutput)
.execute();
}
}
}

26
src/gr/auth/ee/computer_networks/actionListeners/VehicleUseUDPListener.java

@ -0,0 +1,26 @@
package gr.auth.ee.computer_networks.actionListeners;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class VehicleUseUDPListener implements ChangeListener {
private final JFormattedTextField formatedTextFieldVehicleRequestCode;
@SuppressWarnings("unused")
private VehicleUseUDPListener() {
// Disable default constructor
this.formatedTextFieldVehicleRequestCode = null;
}
public VehicleUseUDPListener(JFormattedTextField formatedTextFieldVehicleRequestCode) {
// Disable default constructor
this.formatedTextFieldVehicleRequestCode = formatedTextFieldVehicleRequestCode;
}
@Override
public void stateChanged(ChangeEvent e) {
this.formatedTextFieldVehicleRequestCode.setEnabled(((JCheckBox) e.getSource()).isSelected());
}
}

572
src/gr/auth/ee/computer_networks/helpers/MiniPID.java

@ -0,0 +1,572 @@
package gr.auth.ee.computer_networks.helpers;
/**
* Small, easy to use PID implementation with advanced controller
* capability.<br>
* Minimal usage:<br>
* MiniPID pid = new MiniPID(p,i,d); <br>
* ...looping code...{ <br>
* output= pid.getOutput(sensorvalue,target); <br>
* }
*
* @see http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-direction/improving-the-beginners-pid-introduction
*/
public class MiniPID {
// **********************************
// Class private variables
// **********************************
private double P = 0;
private double I = 0;
private double D = 0;
private double F = 0;
private double maxIOutput = 0;
private double maxError = 0;
private double errorSum = 0;
private double maxOutput = 0;
private double minOutput = 0;
private double setpoint = 0;
private double lastActual = 0;
private boolean firstRun = true;
private boolean reversed = false;
private double outputRampRate = 0;
private double lastOutput = 0;
private double outputFilter = 0;
private double setpointRange = 0;
// **********************************
// Constructor functions
// **********************************
/**
* Create a MiniPID class object. See setP, setI, setD methods for more detailed
* parameters.
*
* @param p
* Proportional gain. Large if large difference between setpoint and
* target.
* @param i
* Integral gain. Becomes large if setpoint cannot reach target
* quickly.
* @param d
* Derivative gain. Responds quickly to large changes in error. Small
* values prevents P and I terms from causing overshoot.
*/
public MiniPID(double p, double i, double d) {
P = p;
I = i;
D = d;
checkSigns();
}
/**
* Create a MiniPID class object. See setP, setI, setD, setF methods for more
* detailed parameters.
*
* @param p
* Proportional gain. Large if large difference between setpoint and
* target.
* @param i
* Integral gain. Becomes large if setpoint cannot reach target
* quickly.
* @param d
* Derivative gain. Responds quickly to large changes in error. Small
* values prevents P and I terms from causing overshoot.
* @param f
* Feed-forward gain. Open loop "best guess" for the output should
* be. Only useful if setpoint represents a rate.
*/
public MiniPID(double p, double i, double d, double f) {
P = p;
I = i;
D = d;
F = f;
checkSigns();
}
// **********************************
// Configuration functions
// **********************************
/**
* Configure the Proportional gain parameter. <br>
* This responds quickly to changes in setpoint, and provides most of the
* initial driving force to make corrections. <br>
* Some systems can be used with only a P gain, and many can be operated with
* only PI.<br>
* For position based controllers, this is the first parameter to tune, with I
* second. <br>
* For rate controlled systems, this is often the second after F.
*
* @param p
* Proportional gain. Affects output according to
* <b>output+=P*(setpoint-current_value)</b>
*/
public void setP(double p) {
P = p;
checkSigns();
}
/**
* Changes the I parameter <br>
* This is used for overcoming disturbances, and ensuring that the controller
* always gets to the control mode. Typically tuned second for "Position" based
* modes, and third for "Rate" or continuous based modes. <br>
* Affects output through <b>output+=previous_errors*Igain
* ;previous_errors+=current_error</b>
*
* @see {@link #setMaxIOutput(double) setMaxIOutput} for how to restrict
*
* @param i
* New gain value for the Integral term
*/
public void setI(double i) {
if (I != 0) {
errorSum = errorSum * I / i;
}
if (maxIOutput != 0) {
maxError = maxIOutput / i;
}
I = i;
checkSigns();
// Implementation note:
// This Scales the accumulated error to avoid output errors.
// As an example doubling the I term cuts the accumulated error in half, which
// results in the
// output change due to the I term constant during the transition.
}
/**
* Changes the D parameter <br>
* This has two primary effects: <list>
* <li>Adds a "startup kick" and speeds up system response during setpoint
* changes
* <li>Adds "drag" and slows the system when moving toward the target </list> A
* small D value can be useful for both improving response times, and preventing
* overshoot. However, in many systems a large D value will cause significant
* instability, particularly for large setpoint changes. <br>
* Affects output through <b>output += -D*(current_input_value -
* last_input_value)</b>
*
* @param d
* New gain value for the Derivative term
*/
public void setD(double d) {
D = d;
checkSigns();
}
/**
* Configure the FeedForward parameter. <br>
* This is excellent for velocity, rate, and other continuous control modes
* where you can expect a rough output value based solely on the setpoint.<br>
* Should not be used in "position" based control modes.<br>
* Affects output according to <b>output+=F*Setpoint</b>. Note, that a F-only
* system is actually open loop.
*
* @param f
* Feed forward gain.
*/
public void setF(double f) {
F = f;
checkSigns();
}
/**
* Configure the PID object. See setP, setI, setD methods for more detailed
* parameters.
*
* @param p
* Proportional gain. Large if large difference between setpoint and
* target.
* @param i
* Integral gain. Becomes large if setpoint cannot reach target
* quickly.
* @param d
* Derivative gain. Responds quickly to large changes in error. Small
* values prevents P and I terms from causing overshoot.
*/
public void setPID(double p, double i, double d) {
P = p;
D = d;
// Note: the I term has additional calculations, so we need to use it's
// specific method for setting it.
setI(i);
checkSigns();
}
/**
* Configure the PID object. See setP, setI, setD, setF methods for more
* detailed parameters.
*
* @param p
* Proportional gain. Large if large difference between setpoint and
* target.
* @param i
* Integral gain. Becomes large if setpoint cannot reach target
* quickly.
* @param d
* Derivative gain. Responds quickly to large changes in error. Small
* values prevents P and I terms from causing overshoot.
* @param f
* Feed-forward gain. Open loop "best guess" for the output should
* be. Only useful if setpoint represents a rate.
*/
public void setPID(double p, double i, double d, double f) {
P = p;
D = d;
F = f;
// Note: the I term has additional calculations, so we need to use it's
// specific method for setting it.
setI(i);
checkSigns();
}
/**
* Set the maximum output value contributed by the I component of the system
* This can be used to prevent large windup issues and make tuning simpler
*
* @param maximum.
* Units are the same as the expected output value
*/
public void setMaxIOutput(double maximum) {
// Internally maxError and Izone are similar, but scaled for different purposes.
// The maxError is generated for simplifying math, since calculations against
// the max error are far more common than changing the I term or Izone.
maxIOutput = maximum;
if (I != 0) {
maxError = maxIOutput / I;
}
}
/**
* Specify a maximum output range. <br>
* When one input is specified, output range is configured to <b>[-output,
* output]</b>
*
* @param output
*/
public void setOutputLimits(double output) {
setOutputLimits(-output, output);
}
/**
* Specify a maximum output. When two inputs specified, output range is
* configured to <b>[minimum, maximum]</b>
*
* @param minimum
* possible output value
* @param maximum
* possible output value
*/
public void setOutputLimits(double minimum, double maximum) {
if (maximum < minimum)
return;
maxOutput = maximum;
minOutput = minimum;
// Ensure the bounds of the I term are within the bounds of the allowable output
// swing
if (maxIOutput == 0 || maxIOutput > (maximum - minimum)) {
setMaxIOutput(maximum - minimum);
}
}
/**
* Set the operating direction of the PID controller
*
* @param reversed
* Set true to reverse PID output
*/
public void setDirection(boolean reversed) {
this.reversed = reversed;
}
// **********************************
// Primary operating functions
// **********************************
/**
* Configure setpoint for the PID calculations<br>
* This represents the target for the PID system's, such as a position,
* velocity, or angle. <br>
*
* @see MiniPID#getOutput(actual) <br>
* @param setpoint
*/
public void setSetpoint(double setpoint) {
this.setpoint = setpoint;
}
/**
* Calculate the output value for the current PID cycle.<br>
*
* @param actual
* The monitored value, typically as a sensor input.
* @param setpoint
* The target value for the system
* @return calculated output value for driving the system
*/
public double getOutput(double actual, double setpoint) {
double output;
double Poutput;
double Ioutput;
double Doutput;
double Foutput;
this.setpoint = setpoint;
// Ramp the setpoint used for calculations if user has opted to do so
if (setpointRange != 0) {
setpoint = constrain(setpoint, actual - setpointRange, actual + setpointRange);
}
// Do the simple parts of the calculations
double error = setpoint - actual;
// Calculate F output. Notice, this depends only on the setpoint, and not the
// error.
Foutput = F * setpoint;
// Calculate P term
Poutput = P * error;
// If this is our first time running this, we don't actually _have_ a previous
// input or output.
// For sensor, sanely assume it was exactly where it is now.
// For last output, we can assume it's the current time-independent outputs.
if (firstRun) {
lastActual = actual;
lastOutput = Poutput + Foutput;
firstRun = false;
}
// Calculate D Term
// Note, this is negative. This actually "slows" the system if it's doing
// the correct thing, and small values helps prevent output spikes and overshoot
Doutput = -D * (actual - lastActual);
lastActual = actual;
// The Iterm is more complex. There's several things to factor in to make it
// easier to deal with.
// 1. maxIoutput restricts the amount of output contributed by the Iterm.
// 2. prevent windup by not increasing errorSum if we're already running against
// our max Ioutput
// 3. prevent windup by not increasing errorSum if output is output=maxOutput
Ioutput = I * errorSum;
if (maxIOutput != 0) {
Ioutput = constrain(Ioutput, -maxIOutput, maxIOutput);
}
// And, finally, we can just add the terms up
output = Foutput + Poutput + Ioutput + Doutput;
// Figure out what we're doing with the error.
if (minOutput != maxOutput && !bounded(output, minOutput, maxOutput)) {
errorSum = error;
// reset the error sum to a sane level
// Setting to current error ensures a smooth transition when the P term
// decreases enough for the I term to start acting upon the controller
// From that point the I term will build up as would be expected
} else if (outputRampRate != 0 && !bounded(output, lastOutput - outputRampRate, lastOutput + outputRampRate)) {
errorSum = error;
} else if (maxIOutput != 0) {
errorSum = constrain(errorSum + error, -maxError, maxError);
// In addition to output limiting directly, we also want to prevent I term
// buildup, so restrict the error directly
} else {
errorSum += error;
}
// Restrict output to our specified output and ramp limits
if (outputRampRate != 0) {
output = constrain(output, lastOutput - outputRampRate, lastOutput + outputRampRate);
}
if (minOutput != maxOutput) {
output = constrain(output, minOutput, maxOutput);
}
if (outputFilter != 0) {
output = lastOutput * outputFilter + output * (1 - outputFilter);
}
// Get a test printline with lots of details about the internal
// calculations. This can be useful for debugging.
// System.out.printf("Final output %5.2f [ %5.2f, %5.2f , %5.2f ], eSum
// %.2f\n",output,Poutput, Ioutput, Doutput,errorSum );
// System.out.printf("%5.2f\t%5.2f\t%5.2f\t%5.2f\n",output,Poutput, Ioutput,
// Doutput );
lastOutput = output;
return output;
}
/**
* Calculate the output value for the current PID cycle.<br>
* In no-parameter mode, this uses the last sensor value, and last setpoint
* value. <br>
* Not typically useful, and use of parameter modes is suggested. <br>
*
* @return calculated output value for driving the system
*/
public double getOutput() {
return getOutput(lastActual, setpoint);
}
/**
* Calculate the output value for the current PID cycle.<br>
* In one parameter mode, the last configured setpoint will be used.<br>
*
* @see MiniPID#setSetpoint()
* @param actual
* The monitored value, typically as a sensor input.
* @param setpoint
* The target value for the system
* @return calculated output value for driving the system
*/
public double getOutput(double actual) {
return getOutput(actual, setpoint);
}
/**
* Resets the controller. This erases the I term buildup, and removes D gain on
* the next loop.<br>
* This should be used any time the PID is disabled or inactive for extended
* duration, and the controlled portion of the system may have changed due to
* external forces.
*/
public void reset() {
firstRun = true;
errorSum = 0;
}
/**
* Set the maximum rate the output can increase per cycle.<br>
* This can prevent sharp jumps in output when changing setpoints or enabling a
* PID system, which might cause stress on physical or electrical systems. <br>
* Can be very useful for fast-reacting control loops, such as ones with large P
* or D values and feed-forward systems.
*
* @param rate,
* with units being the same as the output
*/
public void setOutputRampRate(double rate) {
outputRampRate = rate;
}
/**
* Set a limit on how far the setpoint can be from the current position <br>
* Can simplify tuning by helping tuning over a small range applies to a much
* larger range. <br>
* This limits the reactivity of P term, and restricts impact of large D term
* during large setpoint adjustments. Increases lag and I term if range is too
* small.
*
* @param range,
* with units being the same as the expected sensor range.
*/
public void setSetpointRange(double range) {
setpointRange = range;
}
/**
* Set a filter on the output to reduce sharp oscillations. <br>
* 0.1 is likely a sane starting value. Larger values use historical data more
* heavily, with low values weigh newer data. 0 will disable, filtering, and use
* only the most recent value. <br>
* Increasing the filter strength will P and D oscillations, but force larger I
* values and increase I term overshoot.<br>
* Uses an exponential wieghted rolling sum filter, according to a simple <br>
*
* <pre>
* output*(1-strength)*sum(0..n){output*strength^n}
* </pre>
*
* algorithm.
*
* @param output
* valid between [0..1), meaning [current output only.. historical
* output only)
*/
public void setOutputFilter(double strength) {
if (strength == 0 || bounded(strength, 0, 1)) {
outputFilter = strength;
}
}
// **************************************
// Helper functions
// **************************************
/**
* Forces a value into a specific range
*
* @param value
* input value
* @param min
* maximum returned value
* @param max
* minimum value in range
* @return Value if it's within provided range, min or max otherwise
*/
private double constrain(double value, double min, double max) {
if (value > max) {
return max;
}
if (value < min) {
return min;
}
return value;
}
/**
* Test if the value is within the min and max, inclusive
*
* @param value
* to test
* @param min
* Minimum value of range
* @param max
* Maximum value of range
* @return true if value is within range, false otherwise
*/
private boolean bounded(double value, double min, double max) {
// Note, this is an inclusive range. This is so tests like
// `bounded(constrain(0,0,1),0,1)` will return false.
// This is more helpful for determining edge-case behaviour
// than <= is.
return (min < value) && (value < max);
}
/**
* To operate correctly, all PID parameters require the same sign This should
* align with the {@literal}reversed value
*/
private void checkSigns() {
if (reversed) { // all values should be below zero
if (P > 0)
P *= -1;
if (I > 0)
I *= -1;
if (D > 0)
D *= -1;
if (F > 0)
F *= -1;
} else { // all values should be above zero
if (P < 0)
P *= -1;
if (I < 0)
I *= -1;
if (D < 0)
D *= -1;
if (F < 0)
F *= -1;
}
}
}

64
src/gr/auth/ee/computer_networks/helpers/TCPBundle.java

@ -0,0 +1,64 @@
package gr.auth.ee.computer_networks.helpers;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TCPBundle {
private static final int CONNECTION_TIME_OUT = 2000;
private String serverIp = "";
private int serverPort = 0;
private Socket connection = null;
private InetAddress hostAddress = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
@SuppressWarnings("unused")
private TCPBundle() {
// Disable default constructor
}
public TCPBundle(String serverIp, int serverPort) {
this.serverIp = serverIp;
this.serverPort = serverPort;
try {
String[] serverIPSplit = this.serverIp.split("\\.");
byte[] serverIPBytes = { (byte) Integer.parseInt(serverIPSplit[0]),
(byte) Integer.parseInt(serverIPSplit[1]), (byte) Integer.parseInt(serverIPSplit[2]),
(byte) Integer.parseInt(serverIPSplit[3]) };
hostAddress = InetAddress.getByAddress(serverIPBytes);
connection = new Socket(this.hostAddress, this.serverPort);
connection.setSoTimeout(CONNECTION_TIME_OUT);
inputStream = connection.getInputStream();
outputStream = connection.getOutputStream();
} catch (IOException exception) {
exception.printStackTrace();
}
}
public int getServerPort() {
return serverPort;
}
public Socket getConnection() {
return connection;
}
public InetAddress getHostAddress() {
return hostAddress;
}
public InputStream getInputStream() {
return inputStream;
}
public OutputStream getOutputStream() {
return outputStream;
}
}

78
src/gr/auth/ee/computer_networks/helpers/UDPBundle.java

@ -0,0 +1,78 @@
package gr.auth.ee.computer_networks.helpers;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UDPBundle {
private static final int CONNECTION_TIME_OUT = 10000;
private String serverIp = "";
private int serverPort = 0, localPort = 0;
private DatagramSocket connection = null;
private static InetAddress hostAddress;
@SuppressWarnings("unused")
private UDPBundle() {
// Disable default constructor
}
public UDPBundle(String serverIp, int serverPort, int localPort) {
this.serverIp = serverIp;
this.serverPort = serverPort;
this.localPort = localPort;
try {
connection = new DatagramSocket(this.localPort);
connection.setSoTimeout(CONNECTION_TIME_OUT);
String[] serverIPSplit = serverIp.split("\\.");
byte[] serverIPBytes = { (byte) Integer.parseInt(serverIPSplit[0]),
(byte) Integer.parseInt(serverIPSplit[1]), (byte) Integer.parseInt(serverIPSplit[2]),
(byte) Integer.parseInt(serverIPSplit[3]) };
hostAddress = InetAddress.getByAddress(serverIPBytes);
} catch (SocketException exception) {
exception.printStackTrace();
} catch (UnknownHostException exception) {
exception.printStackTrace();
}
}
public String getServerIp() {
return serverIp;
}
public int getServerPort() {
return serverPort;
}
public int getLocalPort() {
return localPort;
}
public DatagramSocket getConnection() {
return connection;
}
public static InetAddress getHostAddress() {
return hostAddress;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
public boolean setLocalPort(int localPort) {
if (this.localPort == localPort) {
return true;
}
try {
connection = new DatagramSocket(localPort);
this.localPort = localPort;
return true;
} catch (SocketException exception) {
exception.printStackTrace();
return false;
}
}
}

380
src/gr/auth/ee/computer_networks/networkTests/Audio.java

@ -0,0 +1,380 @@
package gr.auth.ee.computer_networks.networkTests;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JProgressBar;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
public class Audio extends SwingWorker<Void, Void> {
private static final int NON_ADAPTIVELY_QUANTISED_PACKET_LENGTH = 128;
private static final int ADAPTIVELY_QUANTISED_PACKET_LENGTH = 132;
private static final int SAMPLE_RATE = 8000;
private static final int NUMBER_OF_CHANNELS = 1;
private static final boolean IS_SIGNED = true;
private static final boolean IS_BIG_ENDIAN = false;
private static UDPBundle UDPConnection;
private String requestCode, audioPool;
private int specificSampleIndex, numberOfPacketsToRequest, betaParameter, qParameter;
private boolean isAdaptivelyQuantised, shouldRequestSpecificSample;
private static JTextPane runtimeStatsOutput;
private JProgressBar progressBarAudioStreamer, progressBarAudioPlayer;
private boolean testSuccess = false;
private String testStatusOutput = "undefined";
private int numberOfBytesWritenToBuffer = 0;
private int bytesPerPacket;
private float streamingProgress = 0;
private float streamingSpeed = 0;
private long playingProgress = 0;
@SuppressWarnings("unused")
private Audio() {
// Disable default constructor
}
public Audio(UDPBundle UDPConnection, String requestCode, boolean shouldRequestSpecificSample,
int specificSampleIndex, String audioPool, int numberOfPacketsToRequest, boolean isAdaptivelyQuantised,
int betaParameter, int qParameter, JTextPane runtimeStatsOutput, JProgressBar progressBarAudioStreamer,
JProgressBar progressBarAudioPlayer) {
Audio.UDPConnection = UDPConnection;
this.requestCode = requestCode;
this.shouldRequestSpecificSample = shouldRequestSpecificSample;
this.specificSampleIndex = specificSampleIndex;
this.audioPool = audioPool;
this.numberOfPacketsToRequest = numberOfPacketsToRequest;
this.isAdaptivelyQuantised = isAdaptivelyQuantised;
this.betaParameter = betaParameter;
this.qParameter = qParameter;
Audio.runtimeStatsOutput = runtimeStatsOutput;
this.progressBarAudioStreamer = progressBarAudioStreamer;
this.progressBarAudioPlayer = progressBarAudioPlayer;
if (!isAdaptivelyQuantised) {
bytesPerPacket = 128 * 2;
} else {
bytesPerPacket = 128 * 4;
}
}
@Override
protected Void doInBackground() {
int numberOfBytesPassedToLineOut = 0;
byte[] decodedDPCMBuffer = new byte[numberOfPacketsToRequest * bytesPerPacket];
AudioFormat linearPCM = new AudioFormat(SAMPLE_RATE, qParameter, NUMBER_OF_CHANNELS, IS_SIGNED, IS_BIG_ENDIAN);
AudioStreamer audioStreamer = new AudioStreamer(decodedDPCMBuffer);
Thread audioStreamerThread = new Thread(audioStreamer);
SourceDataLine lineOut;
audioStreamerThread.start();
while (numberOfBytesWritenToBuffer < ((8192 - 7500) * (numberOfPacketsToRequest / 32))) {
publish();
// wait a bit
}
playingProgress = 0;
try {
lineOut = AudioSystem.getSourceDataLine(linearPCM);
lineOut.open(linearPCM, 2560);
lineOut.start();
while (audioStreamerThread.isAlive() && playingProgress < numberOfPacketsToRequest * bytesPerPacket) {
playingProgress = lineOut.getLongFramePosition();
if (isAdaptivelyQuantised) {
playingProgress *= 2;
}
publish();
if (numberOfBytesPassedToLineOut != numberOfBytesWritenToBuffer) {
numberOfBytesPassedToLineOut += lineOut.write(decodedDPCMBuffer, numberOfBytesPassedToLineOut,
numberOfBytesWritenToBuffer - numberOfBytesPassedToLineOut);
}
}
lineOut.stop();
lineOut.close();
} catch (
LineUnavailableException exception) {
exception.printStackTrace();
}
streamingProgress = 100;
publish();
testSuccess = true;
testStatusOutput = "Test finished successfully.";
return null;
}
@Override
protected void process(List<Void> notInUse) {
runtimeStatsOutput.setText("" + streamingSpeed + "KB/s");
progressBarAudioStreamer.setValue((int) (streamingProgress + ((streamingProgress + 1) / 100)));
progressBarAudioPlayer
.setValue((int) (1000 * ((float) playingProgress / (numberOfPacketsToRequest * bytesPerPacket))));
}
@Override
protected void done() {
Main.setStatusLineText(testStatusOutput,
((testSuccess) ? Main.STATUS_LINE_ACTION_DONE : Main.STATUS_LINE_ACTION_ERROR));
Main.setSubmitButtonsEnabled(true);
}
class AudioStreamer implements Runnable {
private byte[] decodedDPCMBuffer;
private int[] meansArray = null, betasArray = null;
public AudioStreamer(byte[] decodedDPCMBuffer) {
this.decodedDPCMBuffer = decodedDPCMBuffer;
}
private void decodeDPCMPacket(byte[] packetBytes, byte[] decodedPacket, int beta, int packetIndex) {
for (int i = 0; i < packetBytes.length; i++) {
// Some noob code golf stuff here :P
decodedPacket[packetIndex * bytesPerPacket + 2 * i] = (byte) ((((packetBytes[i] >> 4) & 0x0F) - 8)
+ beta * ((packetIndex > 0) ? decodedPacket[packetIndex * bytesPerPacket + 2 * i - 1] : 0));
decodedPacket[packetIndex * bytesPerPacket + 2 * i + 1] = (byte) (((packetBytes[i] & 0x0F) - 8)
+ beta * decodedPacket[packetIndex * bytesPerPacket + 2 * i]);
}
}
private int decodeAQDPCMPacket(byte[] packetBytes, byte[] decodedPacket, int packetIndex, int previousNibble) {
int nibble = previousNibble, mean = 0, beta = 1;
{
byte[] tempByte = new byte[4];
byte meanSign = (byte) ((packetBytes[1] & 0x80) != 0 ? 0xff : 0x00);
tempByte[3] = meanSign;
tempByte[2] = meanSign;
tempByte[1] = packetBytes[1];
tempByte[0] = packetBytes[0];
mean = ByteBuffer.wrap(tempByte).order(ByteOrder.LITTLE_ENDIAN).getInt();
byte betaSign = (byte) ((packetBytes[3] & 0x80) != 0 ? 0xff : 0x00);
tempByte[3] = betaSign;
tempByte[2] = betaSign;
tempByte[1] = packetBytes[3];
tempByte[0] = packetBytes[2];
beta = ByteBuffer.wrap(tempByte).order(ByteOrder.LITTLE_ENDIAN).getInt();
meansArray[packetIndex] = mean;
betasArray[packetIndex] = beta;
}
for (int i = 4; i < 132; ++i) {
int upperDifference = (((packetBytes[i] >>> 4) & 0x0f) - 8) * beta,
lowerDifference = ((packetBytes[i] & 0x0f) - 8) * beta;
int firstSamplePair = upperDifference + nibble + mean;
int secondSamplePair = lowerDifference + upperDifference + mean;
nibble = lowerDifference;
decodedPacket[packetIndex * 512 + 4 * (i - 4)] = (byte) (firstSamplePair);
decodedPacket[packetIndex * 512 + 4 * (i - 4) + 1] = (byte) (firstSamplePair / 256 > 127 ? 127
: firstSamplePair / 256 < -128 ? -128 : firstSamplePair / 256);
decodedPacket[packetIndex * 512 + 4 * (i - 4) + 2] = (byte) (secondSamplePair);
decodedPacket[packetIndex * 512 + 4 * (i - 4) + 3] = (byte) (secondSamplePair / 256 > 127 ? 127
: secondSamplePair / 256 < -128 ? -128 : secondSamplePair / 256);
}
return nibble;
}
@Override
public void run() {
int numberOfPackets = 0, prevNibble = 0, audioOutputFileCounter = 0;
byte[] responseBuffer = null;
DatagramPacket audioRequestPacket = null, audioResponsePacket = null;
FileOutputStream audioDiffStream = null, audioOutputStream = null, audioParametersStream = null;
File audioDiffFile = null, audioOutputFile = null, audioParametersFile = null;
do {
audioDiffFile = new File("output/audioDiff_" + requestCode
+ (audioOutputFileCounter == 0 ? "" : "_" + audioOutputFileCounter) + ".csv");
audioOutputFile = new File("output/audio_" + requestCode
+ (audioOutputFileCounter == 0 ? "" : "_" + audioOutputFileCounter) + ".csv");
if (isAdaptivelyQuantised) {
audioParametersFile = new File("output/audioParams_" + requestCode
+ (audioOutputFileCounter == 0 ? "" : "_" + audioOutputFileCounter) + ".csv");
}
if (!audioDiffFile.isFile() && !audioOutputFile.isFile()
&& (!isAdaptivelyQuantised || !audioParametersFile.isFile())) {
break;
}
++audioOutputFileCounter;
} while (true);
try {
audioDiffStream = new FileOutputStream(audioDiffFile, false);
audioOutputStream = new FileOutputStream(audioOutputFile, false);
if (isAdaptivelyQuantised) {
audioParametersStream = new FileOutputStream(audioParametersFile, false);
}
} catch (FileNotFoundException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "File open failure!";
return;
}
if (!isAdaptivelyQuantised) {
responseBuffer = new byte[NON_ADAPTIVELY_QUANTISED_PACKET_LENGTH];
audioResponsePacket = new DatagramPacket(responseBuffer, NON_ADAPTIVELY_QUANTISED_PACKET_LENGTH);
} else {
meansArray = new int[numberOfPacketsToRequest];
betasArray = new int[numberOfPacketsToRequest];
responseBuffer = new byte[ADAPTIVELY_QUANTISED_PACKET_LENGTH];
requestCode = requestCode + "AQ";
audioResponsePacket = new DatagramPacket(responseBuffer, ADAPTIVELY_QUANTISED_PACKET_LENGTH);
}
if (shouldRequestSpecificSample) {
requestCode = requestCode + "L"
+ (specificSampleIndex < 10 ? "0" + specificSampleIndex : specificSampleIndex);
}
requestCode = requestCode + audioPool + (numberOfPacketsToRequest < 100
? "0" + (numberOfPacketsToRequest < 10 ? "0" + numberOfPacketsToRequest : numberOfPacketsToRequest)
: numberOfPacketsToRequest);
audioRequestPacket = new DatagramPacket(requestCode.getBytes(), requestCode.getBytes().length,
UDPBundle.getHostAddress(), UDPConnection.getServerPort());
try {
UDPConnection.getConnection().send(audioRequestPacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
audioDiffStream.close();
audioOutputStream.close();
if (isAdaptivelyQuantised) {
audioParametersStream.close();
}
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "File close failure, after request send failure!";
return;
}
testSuccess = false;
testStatusOutput = "Request send failure!";
return;
}
while (true) {
long packetDownloadTime = 0, packetStartTime = System.currentTimeMillis();
try {
UDPConnection.getConnection().receive(audioResponsePacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
audioDiffStream.close();
audioOutputStream.close();
if (isAdaptivelyQuantised) {
audioParametersStream.close();
}
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "File close failure, after response receive failure!";
return;
}
testSuccess = false;
testStatusOutput = "Response receive failure!";
return;
}
packetDownloadTime = System.currentTimeMillis() - packetStartTime;
for (byte audioSample : responseBuffer) {
try {
audioDiffStream.write((audioSample + "\t").getBytes(), 0,
(audioSample + "\t").getBytes().length);
} catch (IOException exception) {
exception.printStackTrace();
try {
audioDiffStream.close();
audioOutputStream.close();
if (isAdaptivelyQuantised) {
audioParametersStream.close();
}
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "File close failure, after buffer write failure!";
return;
}
testSuccess = false;
testStatusOutput = "Diff buffer write failure!";
return;
}
}
if (!isAdaptivelyQuantised) {
decodeDPCMPacket(responseBuffer, decodedDPCMBuffer, betaParameter, numberOfPackets);
} else {
prevNibble = decodeAQDPCMPacket(responseBuffer, decodedDPCMBuffer, numberOfPackets, prevNibble);
}
++numberOfPackets;
streamingProgress = ((float) numberOfPackets / (float) numberOfPacketsToRequest) * 100;
streamingSpeed = (float) (2 * responseBuffer.length) / (float) (packetDownloadTime);
numberOfBytesWritenToBuffer = numberOfPackets * bytesPerPacket;
if (numberOfPackets == numberOfPacketsToRequest) {
break;
}
}
try {
for (byte audioSample : decodedDPCMBuffer) {
audioOutputStream.write((audioSample + "\t").getBytes(), 0, (audioSample + "\t").getBytes().length);
}
if (isAdaptivelyQuantised) {
for (int mean : meansArray) {
audioParametersStream.write((mean + "\t").getBytes(), 0, (mean + "\t").getBytes().length);
}
audioParametersStream.write(("\n").getBytes(), 0, ("\n").getBytes().length);
for (int beta : betasArray) {
audioParametersStream.write((beta + "\t").getBytes(), 0, (beta + "\t").getBytes().length);
}
}
audioDiffStream.flush();
audioDiffStream.close();
audioOutputStream.flush();
audioOutputStream.close();
if (isAdaptivelyQuantised) {
audioParametersStream.flush();
audioParametersStream.close();
}
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Audio buffer write failure!";
return;
}
}
}
}

199
src/gr/auth/ee/computer_networks/networkTests/Copter.java

@ -0,0 +1,199 @@
package gr.auth.ee.computer_networks.networkTests;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.MiniPID;
import gr.auth.ee.computer_networks.helpers.TCPBundle;
public class Copter extends SwingWorker<Void, Void> {
private final static int PREAMPLE_RESPONSE_LENGTH = 429;
private final static String PREAMPLE_RESPONSE_STRING = "HTTP/1.1 200 OK\r\n"
+ "Server: Experimental Ithakicopter Java Server Version 0.4\r\n" + "Content-Type: text/html\r\n" + "\n"
+ "\n" + "\n" + "Ithakicopter remote control.<br>\r\n"
+ "Ready to enter a request-response control session.<br>\r\n" + "Request packet format :<br>\r\n"
+ "AUTO FLIGHTLEVEL=FFF LMOTOR=LLL RMOTOR=RRR PILOT <CR><LF><br>\r\n" + "Response packet format :<br>\r\n"
+ "ITHAKICOPTER LMOTOR=LLL RMOTOR=RRR ALTITUDE=AAA TEMPERATURE=TT.TT PRESSURE=PPPP.PP TELEMETRY <CR><LF><br>\r\n"
+ "<br>\r\n";
private final static int MAX_RESPONSE_LENGTH = 128;
public final static String IMAGE_OUTPUT_URL = "http://ithaki.eng.auth.gr:38098/ithakicopter.msp&m=62&x=0&z=0&d=396&v=quad";
public final static int IMAGE_OUTPUT_CROP_START_X = 4;
public final static int IMAGE_OUTPUT_CROP_START_Y = 2;
public final static int IMAGE_OUTPUT_CROP_WIDTH = 218;
public final static int IMAGE_OUTPUT_CROP_HEIGHT = 486;
private final TCPBundle TCPConnection;
private final int desiredAltitude;
private final JLabel lblCopterTemperatureOutput;
private final JLabel lblCopterPressureOutput;
private final JLabel lblCopterAltitudeOutput;
private final JLabel lblCopterLeftMotorOutput;
private final JLabel lblCopterRightMotorOutput;
private final JLabel lblCopterImageOutput;
private final JProgressBar progressBarCopterLeftMotorPower;
private final JProgressBar progressBarCopterRightMotorPower;
private boolean testSuccess = false;
private String testStatusOutput = "undefined";
private float copterOutputTemperature = 0, copterOutputPressure = 0;
private int copterOutputAltitude = 54;
private double copterOutputLeftMotor = 0, copterOutputRightMotor = 0;
private BufferedImage copterImageOutput = null;
@SuppressWarnings("unused")
private Copter() {
// Disable default constructor
this.TCPConnection = null;
this.desiredAltitude = 0;
this.lblCopterTemperatureOutput = null;
this.lblCopterPressureOutput = null;
this.lblCopterAltitudeOutput = null;
this.lblCopterLeftMotorOutput = null;
this.lblCopterRightMotorOutput = null;
this.lblCopterImageOutput = null;
this.progressBarCopterLeftMotorPower = null;
this.progressBarCopterRightMotorPower = null;
}
public Copter(TCPBundle TCPConnection, int desiredAltitude, JLabel lblCopterTemperatureOutput,
JLabel lblCopterPressureOutput, JLabel lblCopterAltitudeOutput, JLabel lblCopterLeftMotorOutput,
JLabel lblCopterRightMotorOutput, JLabel lblCopterImageOutput, JProgressBar progressBarCopterLeftMotorPower,
JProgressBar progressBarCopterRightMotorPower) {
this.TCPConnection = TCPConnection;
this.desiredAltitude = desiredAltitude;
this.lblCopterTemperatureOutput = lblCopterTemperatureOutput;
this.lblCopterPressureOutput = lblCopterPressureOutput;
this.lblCopterAltitudeOutput = lblCopterAltitudeOutput;
this.lblCopterLeftMotorOutput = lblCopterLeftMotorOutput;
this.lblCopterRightMotorOutput = lblCopterRightMotorOutput;
this.lblCopterImageOutput = lblCopterImageOutput;
this.progressBarCopterLeftMotorPower = progressBarCopterLeftMotorPower;
this.progressBarCopterRightMotorPower = progressBarCopterRightMotorPower;
}
@Override
protected Void doInBackground() {
byte[] responseBuffer = new byte[PREAMPLE_RESPONSE_LENGTH];
String requestCode = "GET /index.html HTTP/1.0\r\n\r\n", responseString = "";
URL copterImageOutputUrl;
try {
copterImageOutputUrl = new URL(IMAGE_OUTPUT_URL);
} catch (MalformedURLException exception) {
// This should never happen
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Malformed image URL error, this should never happen!";
return null;
}
MiniPID miniPID = new MiniPID(0.058, 0.012, 0.009);
miniPID.setOutputLimits(0, 105);
miniPID.setSetpoint(desiredAltitude);
try {
TCPConnection.getOutputStream().write(requestCode.getBytes());
TCPConnection.getInputStream().read(responseBuffer);
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Request send/response receive failure!";
return null;
}
for (byte responseByte : responseBuffer) {
responseString += (char) responseByte;
}
if (!responseString.isEmpty() && responseString.equals(PREAMPLE_RESPONSE_STRING)) {
responseBuffer = new byte[MAX_RESPONSE_LENGTH];
while (true) {
int numberOfBytesRead, motorsLevel;
responseString = "";
motorsLevel = 150 + (int) Math.floor(miniPID.getOutput(copterOutputAltitude));
requestCode = "AUTO FLIGHTLEVEL=" + desiredAltitude + " LMOTOR=" + motorsLevel + " RMOTOR="
+ motorsLevel + " PILOT \r\n";
try {
TCPConnection.getOutputStream().write(requestCode.getBytes());
numberOfBytesRead = TCPConnection.getInputStream().read(responseBuffer);
if (numberOfBytesRead == -1) {
testSuccess = false;
testStatusOutput = "Server closed the connection, try running the test again after restarting the app.";
return null;
}
} catch (SocketTimeoutException exception) {
testSuccess = false;
testStatusOutput = "Response timed out!";
return null;
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Request send/response receive failure!";
return null;
}
for (byte responseByte : responseBuffer) {
responseString += (char) responseByte;
}
copterOutputLeftMotor = Integer.parseInt(responseString.substring(20, 23)) / 2.55;
copterOutputRightMotor = Integer.parseInt(responseString.substring(31, 34)) / 2.55;
copterOutputAltitude = Integer.parseInt(responseString.substring(44, 47));
copterOutputTemperature = Float.parseFloat(responseString.substring(61, 66));
copterOutputPressure = Float.parseFloat(responseString.substring(76, 83));
try {
copterImageOutput = ImageIO.read(copterImageOutputUrl);
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image stream failure!";
return null;
}
copterImageOutput = copterImageOutput.getSubimage(IMAGE_OUTPUT_CROP_START_X, IMAGE_OUTPUT_CROP_START_Y,
IMAGE_OUTPUT_CROP_WIDTH, IMAGE_OUTPUT_CROP_HEIGHT);
publish();
}
}
testSuccess = true;
testStatusOutput = "Test finished successfully.";
return null;
}
@Override
protected void process(List<Void> notInUse) {
lblCopterTemperatureOutput.setText(copterOutputTemperature + " °C");
lblCopterPressureOutput.setText(copterOutputPressure + " mBar");
lblCopterAltitudeOutput.setText(copterOutputAltitude + " px above GND");
lblCopterLeftMotorOutput.setText((new DecimalFormat("#.###")).format(copterOutputLeftMotor) + " %");
lblCopterRightMotorOutput.setText((new DecimalFormat("#.###")).format(copterOutputRightMotor) + " %");
progressBarCopterLeftMotorPower.setValue((int) Math.floor(copterOutputLeftMotor));
progressBarCopterRightMotorPower.setValue((int) Math.floor(copterOutputRightMotor));
lblCopterImageOutput.setIcon(new ImageIcon(copterImageOutput));
}
@Override
protected void done() {
Main.setStatusLineText(testStatusOutput,
((testSuccess) ? Main.STATUS_LINE_ACTION_DONE : Main.STATUS_LINE_ACTION_ERROR));
Main.setSubmitButtonsEnabled(true);
}
}

226
src/gr/auth/ee/computer_networks/networkTests/Echo.java

@ -0,0 +1,226 @@
package gr.auth.ee.computer_networks.networkTests;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.util.List;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
public class Echo extends SwingWorker<Void, Long> {
private static final int MAX_RESPONSE_LENGTH = 2048;
private static UDPBundle UDPConnection;
private String requestCode;
private int duration, numberOfPackages;
private boolean getTemperature;
private static JTextPane runtimeOutput;
private boolean testSuccess = false;
private String testStatusOutput = "undefined";
@SuppressWarnings("unused")
private Echo() {
// Disable default constructor
}
public Echo(UDPBundle UDPConnection, String requestCode, int duration, int numberOfPackages, boolean getTemperature,
JTextPane runtimeOutput) {
Echo.UDPConnection = UDPConnection;
this.requestCode = requestCode;
this.duration = duration;
this.numberOfPackages = numberOfPackages;
this.getTemperature = getTemperature;
Echo.runtimeOutput = runtimeOutput;
}
@Override
protected Void doInBackground() {
int currentPackageNumber = 0, echoOutputFileCounter = 0;
boolean monitorNumberOfPackages = !(numberOfPackages == 0), monitorDuration = !(duration == 0);
byte responseBuffer[] = new byte[MAX_RESPONSE_LENGTH];
DatagramPacket echoRequestPacket = null,
echoResponsePacket = new DatagramPacket(responseBuffer, MAX_RESPONSE_LENGTH);
long startTime = System.currentTimeMillis(), packageStartTime = 0, packageEndTime, runningTime = 0;
String temperatureString = null;
FileOutputStream echoOutputStream = null;
File echoOutputFile = null;
do {
echoOutputFile = new File("output/echo_" + requestCode
+ (echoOutputFileCounter == 0 ? "" : "_" + echoOutputFileCounter) + ".csv");
if (!echoOutputFile.isFile()) {
break;
}
++echoOutputFileCounter;
} while (true);
try {
echoOutputStream = new FileOutputStream(echoOutputFile, false);
} catch (FileNotFoundException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file open failure!";
return null;
}
if (getTemperature) {
requestCode = requestCode + "T00";
}
requestCode = requestCode + "\r";
echoRequestPacket = new DatagramPacket(requestCode.getBytes(), requestCode.getBytes().length,
UDPBundle.getHostAddress(), UDPConnection.getServerPort());
while (true) {
currentPackageNumber++;
try {
UDPConnection.getConnection().send(echoRequestPacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
echoOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file close failure, after request send failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Request send failure!";
return null;
}
try {
packageStartTime = System.currentTimeMillis();
UDPConnection.getConnection().receive(echoResponsePacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
echoOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file close failure, after response receive failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Response receive failure!";
return null;
}
String responseString = new String(responseBuffer);
if (!responseString.contains("PSTART") || !responseString.contains("PSTOP")) {
try {
echoOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file close failure, after malformed response receive!";
return null;
}
testSuccess = false;
testStatusOutput = "Malformed response!";
return null;
} else {
packageEndTime = System.currentTimeMillis();
long packageTime = packageEndTime - packageStartTime;
runningTime += packageTime;
try {
echoOutputStream.write((packageTime + "\t").getBytes(), 0, (packageTime + "\t").getBytes().length);
} catch (IOException exception) {
exception.printStackTrace();
try {
echoOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file close failure, after buffer write failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Echo file buffer write failure!";
return null;
}
if (getTemperature) {
if (currentPackageNumber == 1) {
if (responseString.contains("+")) {
temperatureString = responseString.substring(responseString.indexOf("+"),
responseString.indexOf(" C"));
} else {
temperatureString = responseString.substring(responseString.indexOf("-"),
responseString.indexOf(" C"));
}
}
publish(packageTime, runningTime / currentPackageNumber, Long.parseLong(temperatureString));
} else {
publish(packageTime, runningTime / currentPackageNumber, null);
}
}
if (monitorNumberOfPackages) {
if (numberOfPackages == currentPackageNumber) {
try {
echoOutputStream.flush();
echoOutputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file buffer flush/close failure!";
return null;
}
testSuccess = true;
testStatusOutput = "Test finished successfully.";
return null;
}
}
if (monitorDuration) {
if ((packageEndTime - startTime) >= (duration * 1000)) {
try {
echoOutputStream.flush();
echoOutputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file buffer flush/close failure!";
return null;
}
testSuccess = true;
testStatusOutput = "Test finished successfully.";
return null;
}
}
}
}
@Override
protected void process(List<Long> pingValues) {
if (pingValues.size() != 3) {
return;
} else {
if (pingValues.get(2) == null) {
runtimeOutput.setText("Last packet ping time:\t" + pingValues.get(0)
+ " ms\nAverage packet ping time:\t" + pingValues.get(1) + " ms\nTemperature = NaN");
} else {
runtimeOutput
.setText("Last packet ping time:\t" + pingValues.get(0) + " ms\nAverage packet ping time:\t"
+ pingValues.get(1) + " ms\nTemperature = " + pingValues.get(2) + " °C");
}
}
}
@Override
protected void done() {
Main.setStatusLineText(testStatusOutput,
((testSuccess) ? Main.STATUS_LINE_ACTION_DONE : Main.STATUS_LINE_ACTION_ERROR));
Main.setSubmitButtonsEnabled(true);
}
}

265
src/gr/auth/ee/computer_networks/networkTests/Image.java

@ -0,0 +1,265 @@
package gr.auth.ee.computer_networks.networkTests;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
public class Image extends SwingWorker<Void, Boolean> {
private static final int IMAGE_WIDTH = 320;
private static final int IMAGE_HEIGHT = 240;
private static UDPBundle UDPConnection;
private String requestCode;
private int duration, packageLength;
private boolean flowControl;
private static JTextPane runtimeStatsOutput;
private static JLabel runtimeImageOutput;
private ArrayList<Byte> dispImageBytesList;
private boolean testSuccess = false;
private String testStatusOutput = "undefined";
private long currentImageTimeElapsed = 0;
private int currentImageNumberOfPackages = 0;
private float averageImageTimeElapsed = 0, averageImageNumberOfPackages = 0, currentImageSize = 0,
averageImageSize = 0, fps = 0;
@SuppressWarnings("unused")
private Image() {
// Disable default constructor
}
public Image(UDPBundle UDPConnection, String requestCode, int duration, boolean flowControl, int packageLength,
JTextPane runtimeStatsOutput, JLabel runtimeImageOutput) {
Image.UDPConnection = UDPConnection;
this.requestCode = requestCode;
this.duration = duration;
this.packageLength = packageLength;
this.flowControl = flowControl;
Image.runtimeStatsOutput = runtimeStatsOutput;
Image.runtimeImageOutput = runtimeImageOutput;
}
@Override
protected Void doInBackground() {
boolean monitorDuration = !(duration == 0);
byte responseBuffer[] = new byte[packageLength];
DatagramPacket imageRequestPacket = null,
imageResponsePacket = new DatagramPacket(responseBuffer, packageLength), imageNextPacket = null;
long startTime = System.currentTimeMillis(), totalImagesTimeElapsed = 0;
int numberOfImages = 0, totalImagesNumberOfPackages = 0, totalImagesSize = 0;
averageImageTimeElapsed = 0;
averageImageNumberOfPackages = 0;
averageImageSize = 0;
fps = 0;
if (flowControl) {
requestCode = requestCode + "FLOW=ON";
imageNextPacket = new DatagramPacket("NEXT".getBytes(), "NEXT".getBytes().length,
UDPBundle.getHostAddress(), UDPConnection.getServerPort());
}
if (packageLength != 128) {
requestCode = requestCode + "UDP=" + packageLength;
}
requestCode = requestCode + "\r";
imageRequestPacket = new DatagramPacket(requestCode.getBytes(), requestCode.getBytes().length,
UDPBundle.getHostAddress(), UDPConnection.getServerPort());
while (true) {
ArrayList<Byte> loadingImageBytesList = new ArrayList<Byte>();
FileOutputStream imageOutputStream = null;
try {
imageOutputStream = new FileOutputStream("output/image_" + requestCode + "_" + numberOfImages + ".jpg",
false);
} catch (FileNotFoundException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image file open failure!";
return null;
}
boolean shouldBreak = false;
currentImageNumberOfPackages = 0;
currentImageTimeElapsed = 0;
currentImageSize = 0;
try {
UDPConnection.getConnection().send(imageRequestPacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
imageOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image file close failure, after request send failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Request send failure!";
return null;
}
long currentImageTimeStart = System.currentTimeMillis();
while (true) {
try {
UDPConnection.getConnection().receive(imageResponsePacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
imageOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image file close failure, after response receive failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Response receive failure!";
return null;
}
++currentImageNumberOfPackages;
try {
imageOutputStream.write(responseBuffer, 0, responseBuffer.length);
} catch (IOException exception) {
exception.printStackTrace();
try {
imageOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image file close failure, after buffer write failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Image file buffer write failure!";
return null;
}
for (int i = 0; i < packageLength; ++i) {
loadingImageBytesList.add(responseBuffer[i]);
if (responseBuffer[i] != 0) {
if ((i < packageLength - 1) && (responseBuffer[i] == (byte) 255)
&& (responseBuffer[i + 1] == (byte) 217)) {
shouldBreak = true;
}
responseBuffer[i] = 0;
}
}
if (currentImageNumberOfPackages % 20 == 0) {
currentImageSize = (float) ((loadingImageBytesList.size()) / 1000.0);
currentImageTimeElapsed = System.currentTimeMillis() - currentImageTimeStart;
publish(false);
}
if (shouldBreak) {
currentImageTimeElapsed = System.currentTimeMillis() - currentImageTimeStart;
break;
}
if (flowControl) {
try {
UDPConnection.getConnection().send(imageNextPacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
imageOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image file close failure, after request send failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Request send failure!";
return null;
}
}
}
try {
imageOutputStream.flush();
imageOutputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Image file buffer flush/close failure!";
return null;
}
++numberOfImages;
totalImagesTimeElapsed += currentImageTimeElapsed;
averageImageTimeElapsed = (float) totalImagesTimeElapsed / (float) numberOfImages;
totalImagesNumberOfPackages += currentImageNumberOfPackages;
averageImageNumberOfPackages = (float) totalImagesNumberOfPackages / (float) numberOfImages;
totalImagesSize += currentImageSize;
averageImageSize = totalImagesSize / (float) numberOfImages;
dispImageBytesList = loadingImageBytesList;
fps = (float) ((numberOfImages) / (totalImagesTimeElapsed / 1000.0));
publish(true);
if (monitorDuration) {
if ((System.currentTimeMillis() - startTime) >= (duration * 1000)) {
break;
}
}
}
testSuccess = true;
testStatusOutput = "Test finished successfully.";
return null;
}
@Override
protected void process(List<Boolean> shouldRefreshImage) {
runtimeStatsOutput.setText("Current Image" + "\t" + "\t" + "Average" + "\n" + "Time elapsed = "
+ currentImageTimeElapsed + " ms\t" + "Average image time = " + averageImageTimeElapsed + " ms\n"
+ "Number of packages = " + currentImageNumberOfPackages + "\t" + "Average number of packages = "
+ averageImageNumberOfPackages + "\n" + "Image size = " + currentImageSize + " KB\t"
+ "Average image size = " + averageImageSize + " KB\n" + "\n" + "FPS = " + fps);
if (shouldRefreshImage.get(0)) {
byte[] imageBytes = new byte[dispImageBytesList.size()];
for (int i = 0; i < dispImageBytesList.size(); ++i) {
imageBytes[i] = dispImageBytesList.get(i);
}
ImageIcon image = new ImageIcon(imageBytes);
BufferedImage resizedImg = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(image.getImage(), 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
g2.dispose();
image = new ImageIcon(resizedImg);
runtimeImageOutput.setIcon(image);
}
}
@Override
protected void done() {
Main.setStatusLineText(testStatusOutput,
((testSuccess) ? Main.STATUS_LINE_ACTION_DONE : Main.STATUS_LINE_ACTION_ERROR));
Main.setSubmitButtonsEnabled(true);
}
}

393
src/gr/auth/ee/computer_networks/networkTests/Vehicle.java

@ -0,0 +1,393 @@
package gr.auth.ee.computer_networks.networkTests;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import gr.auth.ee.computer_networks.Main;
import gr.auth.ee.computer_networks.helpers.TCPBundle;
import gr.auth.ee.computer_networks.helpers.UDPBundle;
public class Vehicle extends SwingWorker<Void, Void> {
private static final int MAX_RESPONSE_LENGTH = 12;
private static final String[] OBD_UDP_REQUEST_CODES = new String[] { "01 1F", "01 0F", "01 11", "01 0C", "01 0D",
"01 05" };
private static final int ENGINE_RUN_TIME = 0;
private static final int INTAKE_AIR_TEMPERATURE = 1;
private static final int THROTTLE_POSITION = 2;
private static final int ENGINE_RPM = 3;
private static final int VEHICLE_SPEED = 4;
private static final int COOLANT_TEMPERATURE = 5;
private final TCPBundle TCPConnection;
private final UDPBundle UDPConnection;
private String requestCode;
private final boolean useUDP;
private final int duration;
private final JLabel lblVehicleEngineRunTimeOutput;
private final JLabel lblVehicleAirTempOutput;
private final JLabel lblVehicleThrottlePositionOutput;
private final JLabel lblVehicleEngineRPMOutput;
private final JLabel lblVehicleSpeedOutput;
private final JLabel lblVehicleCoolantTemperatureOutput;
private final JLabel lblVehiclePacketsTotalTimeOutput;
private boolean testSuccess = false;
private String testStatusOutput = "undefined";
private String[] outputData = new String[7];
private ArrayList<Integer> engineRunTimeValues = new ArrayList<>(), intakeAirTemperatureValues = new ArrayList<>(),
vehicleSpeedValues = new ArrayList<>(), coolantTemperatureValues = new ArrayList<>();
private ArrayList<Float> throttlePositionValues = new ArrayList<>(), engineRPMValues = new ArrayList<>();
@SuppressWarnings("unused")
private Vehicle() {
// Disable default constructor
this.TCPConnection = null;
this.UDPConnection = null;
this.useUDP = false;
this.duration = 0;
this.lblVehicleEngineRunTimeOutput = null;
this.lblVehicleAirTempOutput = null;
this.lblVehicleThrottlePositionOutput = null;
this.lblVehicleEngineRPMOutput = null;
this.lblVehicleSpeedOutput = null;
this.lblVehicleCoolantTemperatureOutput = null;
this.lblVehiclePacketsTotalTimeOutput = null;
}
public Vehicle(UDPBundle UDPConnection, String requestCode, int duration, JLabel lblVehicleEngineRunTimeOutput,
JLabel lblVehicleAirTempOutput, JLabel lblVehicleThrottlePositionOutput, JLabel lblVehicleEngineRPMOutput,
JLabel lblVehicleSpeedOutput, JLabel lblVehicleCoolantTemperatureOutput,
JLabel lblVehiclePacketsTotalTimeOutput) {
this.TCPConnection = null;
this.UDPConnection = UDPConnection;
this.requestCode = requestCode;
this.useUDP = true;
this.duration = duration;
this.lblVehicleEngineRunTimeOutput = lblVehicleEngineRunTimeOutput;
this.lblVehicleAirTempOutput = lblVehicleAirTempOutput;
this.lblVehicleThrottlePositionOutput = lblVehicleThrottlePositionOutput;
this.lblVehicleEngineRPMOutput = lblVehicleEngineRPMOutput;
this.lblVehicleSpeedOutput = lblVehicleSpeedOutput;
this.lblVehicleCoolantTemperatureOutput = lblVehicleCoolantTemperatureOutput;
this.lblVehiclePacketsTotalTimeOutput = lblVehiclePacketsTotalTimeOutput;
}
public Vehicle(TCPBundle TCPConnection, String requestCode, int duration, JLabel lblVehicleEngineRunTimeOutput,
JLabel lblVehicleAirTempOutput, JLabel lblVehicleThrottlePositionOutput, JLabel lblVehicleEngineRPMOutput,
JLabel lblVehicleSpeedOutput, JLabel lblVehicleCoolantTemperatureOutput,
JLabel lblVehiclePacketsTotalTimeOutput) {
this.TCPConnection = TCPConnection;
this.UDPConnection = null;
this.requestCode = requestCode;
this.useUDP = false;
this.duration = duration;
this.lblVehicleEngineRunTimeOutput = lblVehicleEngineRunTimeOutput;
this.lblVehicleAirTempOutput = lblVehicleAirTempOutput;
this.lblVehicleThrottlePositionOutput = lblVehicleThrottlePositionOutput;
this.lblVehicleEngineRPMOutput = lblVehicleEngineRPMOutput;
this.lblVehicleSpeedOutput = lblVehicleSpeedOutput;
this.lblVehicleCoolantTemperatureOutput = lblVehicleCoolantTemperatureOutput;
this.lblVehiclePacketsTotalTimeOutput = lblVehiclePacketsTotalTimeOutput;
}
private String getValueFromResponse(byte[] response, int bytesReturned, int loopIndex) {
int returnValueXX = 0, returnValueYY = 0;
String value = "";
if (bytesReturned == 9) {
String hexValueXX = "" + (char) response[6] + (char) response[7];
returnValueXX = Integer.parseInt(hexValueXX, 16);
} else if (bytesReturned == 12) {
String hexValueXX = "" + (char) response[6] + (char) response[7];
String hexValueYY = "" + (char) response[9] + (char) response[10];
returnValueXX = Integer.parseInt(hexValueXX, 16);
returnValueYY = Integer.parseInt(hexValueYY, 16);
} else {
// Shouldn't happen
return null;
}
switch (loopIndex) {
case ENGINE_RUN_TIME:
value = "" + 256 * returnValueXX + returnValueYY;
engineRunTimeValues.add(256 * returnValueXX + returnValueYY);
break;
case INTAKE_AIR_TEMPERATURE:
value = "" + (returnValueXX - 40);
intakeAirTemperatureValues.add(returnValueXX - 40);
break;
case THROTTLE_POSITION:
value = "" + (100 * returnValueXX / 255);
throttlePositionValues.add((float) (100 * returnValueXX / 255));
break;
case ENGINE_RPM:
value = "" + ((256 * returnValueXX + returnValueYY) / 4);
engineRPMValues.add((float) ((256 * returnValueXX + returnValueYY) / 4));
break;
case VEHICLE_SPEED:
value = "" + returnValueXX;
vehicleSpeedValues.add(returnValueXX);
break;
case COOLANT_TEMPERATURE:
value = "" + (returnValueXX - 40);
coolantTemperatureValues.add(returnValueXX - 40);
break;
default:
break;
}
return value;
}
@Override
protected Void doInBackground() {
int vehicleOutputFileCounter = 0;
byte responseBuffer[] = new byte[MAX_RESPONSE_LENGTH];
long totalTimeElapsed = 0, OBDPacketStart = 0;
FileOutputStream vehicleOutputStream = null;
File vehicleOutputFile = null;
do {
vehicleOutputFile = new File("output/vehicle_" + (useUDP ? requestCode : "TCP")
+ (vehicleOutputFileCounter == 0 ? "" : "_" + vehicleOutputFileCounter) + ".csv");
if (!vehicleOutputFile.isFile()) {
break;
}
++vehicleOutputFileCounter;
} while (true);
try {
vehicleOutputStream = new FileOutputStream(vehicleOutputFile, false);
} catch (FileNotFoundException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Echo file open failure!";
return null;
}
if (useUDP) {
DatagramPacket OBDRequestPacket = null,
OBDResponsePacket = new DatagramPacket(responseBuffer, MAX_RESPONSE_LENGTH);
while (totalTimeElapsed < duration * 1000) {
for (int i = 0; i < OBD_UDP_REQUEST_CODES.length; ++i) {
int bytesReturned = MAX_RESPONSE_LENGTH;
String OBDRequestCode = requestCode + "OBD=" + OBD_UDP_REQUEST_CODES[i];
OBDRequestPacket = new DatagramPacket(OBDRequestCode.getBytes(), OBDRequestCode.getBytes().length,
UDPBundle.getHostAddress(), UDPConnection.getServerPort());
try {
UDPConnection.getConnection().send(OBDRequestPacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after request send failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Request send failure!";
return null;
}
OBDPacketStart = System.currentTimeMillis();
try {
UDPConnection.getConnection().receive(OBDResponsePacket);
} catch (IOException exception) {
exception.printStackTrace();
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after response receive failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Response receive failure!";
return null;
}
totalTimeElapsed += System.currentTimeMillis() - OBDPacketStart;
for (int j = MAX_RESPONSE_LENGTH - 1; j > 0; --j) {
if (responseBuffer[j] == 0) {
--bytesReturned;
}
}
outputData[i] = getValueFromResponse(responseBuffer, bytesReturned + 1, i);
for (int j = 0; j < MAX_RESPONSE_LENGTH; ++j) {
responseBuffer[j] = 0;
}
}
outputData[6] = "" + totalTimeElapsed;
publish();
}
} else {
while (totalTimeElapsed < duration * 1000) {
for (int i = 0; i < OBD_UDP_REQUEST_CODES.length; ++i) {
int bytesReturned = 0;
try {
TCPConnection.getOutputStream().write((OBD_UDP_REQUEST_CODES[i] + (char) 13).getBytes());
} catch (IOException exception) {
exception.printStackTrace();
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after request send failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Request send failure!";
return null;
}
OBDPacketStart = System.currentTimeMillis();
try {
bytesReturned = TCPConnection.getInputStream().read(responseBuffer);
} catch (IOException exception) {
exception.printStackTrace();
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after response receive failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Response receive failure!";
return null;
}
totalTimeElapsed += System.currentTimeMillis() - OBDPacketStart;
if (bytesReturned == -1) {
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after connection failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Server closed the connection, try running the test again after restarting the app.";
return null;
} else if (bytesReturned != 9 && bytesReturned != 12) {
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after malformed response failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Malformed response.";
return null;
}
outputData[i] = getValueFromResponse(responseBuffer, bytesReturned, i);
}
outputData[6] = "" + totalTimeElapsed;
publish();
}
}
try {
for (Integer engineRunTime : engineRunTimeValues) {
vehicleOutputStream.write((engineRunTime + "\t").getBytes(), 0,
(engineRunTime + "\t").getBytes().length);
}
vehicleOutputStream.write(("\n").getBytes(), 0, ("\n").getBytes().length);
for (Integer intakeAirTemperatureValues : intakeAirTemperatureValues) {
vehicleOutputStream.write((intakeAirTemperatureValues + "\t").getBytes(), 0,
(intakeAirTemperatureValues + "\t").getBytes().length);
}
vehicleOutputStream.write(("\n").getBytes(), 0, ("\n").getBytes().length);
for (Float throttlePositionValues : throttlePositionValues) {
vehicleOutputStream.write((throttlePositionValues + "\t").getBytes(), 0,
(throttlePositionValues + "\t").getBytes().length);
}
vehicleOutputStream.write(("\n").getBytes(), 0, ("\n").getBytes().length);
for (Float engineRPMValues : engineRPMValues) {
vehicleOutputStream.write((engineRPMValues + "\t").getBytes(), 0,
(engineRPMValues + "\t").getBytes().length);
}
vehicleOutputStream.write(("\n").getBytes(), 0, ("\n").getBytes().length);
for (Integer vehicleSpeedValues : vehicleSpeedValues) {
vehicleOutputStream.write((vehicleSpeedValues + "\t").getBytes(), 0,
(vehicleSpeedValues + "\t").getBytes().length);
}
vehicleOutputStream.write(("\n").getBytes(), 0, ("\n").getBytes().length);
for (Integer coolantTemperatureValues : coolantTemperatureValues) {
vehicleOutputStream.write((coolantTemperatureValues + "\t").getBytes(), 0,
(coolantTemperatureValues + "\t").getBytes().length);
}
} catch (IOException exception) {
exception.printStackTrace();
try {
vehicleOutputStream.close();
} catch (IOException inception) {
inception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file close failure, after buffer write failure!";
return null;
}
testSuccess = false;
testStatusOutput = "Vehicle file buffer write failure!";
return null;
}
try {
vehicleOutputStream.flush();
vehicleOutputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
testSuccess = false;
testStatusOutput = "Vehicle file buffer flush/close failure!";
return null;
}
testSuccess = true;
testStatusOutput = "Test finished successfully.";
return null;
}
@Override
protected void process(List<Void> notInUse) {
lblVehicleEngineRunTimeOutput.setText(outputData[0] + " s");
lblVehicleAirTempOutput.setText(outputData[1] + " °C");
lblVehicleThrottlePositionOutput.setText(outputData[2] + " %");
lblVehicleEngineRPMOutput.setText(outputData[3] + " RPM");
lblVehicleSpeedOutput.setText(outputData[4] + " Km/h");
lblVehicleCoolantTemperatureOutput.setText(outputData[5] + " °C");
lblVehiclePacketsTotalTimeOutput.setText(outputData[6] + " ms");
}
@Override
protected void done() {
Main.setStatusLineText(testStatusOutput,
((testSuccess) ? Main.STATUS_LINE_ACTION_DONE : Main.STATUS_LINE_ACTION_ERROR));
Main.setSubmitButtonsEnabled(true);
}
}

105
src/org/eclipse/wb/swing/FocusTraversalOnArray.java

@ -0,0 +1,105 @@
/*******************************************************************************
* Copyright (c) 2011 Google, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.wb.swing;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
/**
* Cyclic focus traversal policy based on array of components.
* <p>
* This class may be freely distributed as part of any application or plugin.
*
* @author scheglov_ke
*/
public class FocusTraversalOnArray extends FocusTraversalPolicy {
private final Component m_Components[];
////////////////////////////////////////////////////////////////////////////
//
// Constructor
//
////////////////////////////////////////////////////////////////////////////
public FocusTraversalOnArray(Component components[]) {
m_Components = components;
}
////////////////////////////////////////////////////////////////////////////
//
// Utilities
//
////////////////////////////////////////////////////////////////////////////
private int indexCycle(int index, int delta) {
int size = m_Components.length;
int next = (index + delta + size) % size;
return next;
}
private Component cycle(Component currentComponent, int delta) {
int index = -1;
loop: for (int i = 0; i < m_Components.length; i++) {
Component component = m_Components[i];
for (Component c = currentComponent; c != null; c = c.getParent()) {
if (component == c) {
index = i;
break loop;
}
}
}
// try to find enabled component in "delta" direction
int initialIndex = index;
while (true) {
int newIndex = indexCycle(index, delta);
if (newIndex == initialIndex) {
break;
}
index = newIndex;
//
Component component = m_Components[newIndex];
if (component.isEnabled() && component.isVisible() && component.isFocusable()) {
return component;
}
}
// not found
return currentComponent;
}
////////////////////////////////////////////////////////////////////////////
//
// FocusTraversalPolicy
//
////////////////////////////////////////////////////////////////////////////
@Override
public Component getComponentAfter(Container container, Component component) {
return cycle(component, 1);
}
@Override
public Component getComponentBefore(Container container, Component component) {
return cycle(component, -1);
}
@Override
public Component getFirstComponent(Container container) {
return m_Components[0];
}
@Override
public Component getLastComponent(Container container) {
return m_Components[m_Components.length - 1];
}
@Override
public Component getDefaultComponent(Container container) {
return getFirstComponent(container);
}
}
Loading…
Cancel
Save