Merge branch 'master' into develop
# Conflicts: # xpcPlugin/XPlaneConnect/mac.xpl # xpcPlugin/xpcPlugin.xcodeproj/project.pbxproj
This commit is contained in:
1
Java/Examples/ContinuousOperation/.idea/.name
generated
Normal file
1
Java/Examples/ContinuousOperation/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
ContinuousOperation
|
||||
22
Java/Examples/ContinuousOperation/.idea/compiler.xml
generated
Normal file
22
Java/Examples/ContinuousOperation/.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
3
Java/Examples/ContinuousOperation/.idea/copyright/profiles_settings.xml
generated
Normal file
3
Java/Examples/ContinuousOperation/.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
9
Java/Examples/ContinuousOperation/.idea/libraries/XPlaneConnect.xml
generated
Normal file
9
Java/Examples/ContinuousOperation/.idea/libraries/XPlaneConnect.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="XPlaneConnect">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/libs/XPlaneConnect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
19
Java/Examples/ContinuousOperation/.idea/misc.xml
generated
Normal file
19
Java/Examples/ContinuousOperation/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
Java/Examples/ContinuousOperation/.idea/modules.xml
generated
Normal file
8
Java/Examples/ContinuousOperation/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/ContinuousOperation.iml" filepath="$PROJECT_DIR$/ContinuousOperation.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
Java/Examples/ContinuousOperation/.idea/vcs.xml
generated
Normal file
6
Java/Examples/ContinuousOperation/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
</project>
|
||||
12
Java/Examples/ContinuousOperation/ContinuousOperation.iml
Normal file
12
Java/Examples/ContinuousOperation/ContinuousOperation.iml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="XPlaneConnect" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
BIN
Java/Examples/ContinuousOperation/libs/XPlaneConnect.jar
Normal file
BIN
Java/Examples/ContinuousOperation/libs/XPlaneConnect.jar
Normal file
Binary file not shown.
47
Java/Examples/ContinuousOperation/src/Main.java
Normal file
47
Java/Examples/ContinuousOperation/src/Main.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package gov.nasa.xpc.ex;
|
||||
|
||||
import gov.nasa.xpc.XPlaneConnect;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An example program demonstrating the use of X-PlaneConnect in a continuous loop.
|
||||
*
|
||||
* @author Jason Watkins
|
||||
* @version 1.0
|
||||
* @since 2015-06-19
|
||||
*/
|
||||
public class Main
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try (XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
int aircraft = 0;
|
||||
while(true)
|
||||
{
|
||||
float[] posi = xpc.getPOSI(aircraft);
|
||||
float[] ctrl = xpc.getCTRL(aircraft);
|
||||
|
||||
System.out.format("Loc: (%4f, %4f, %4f) Aileron:%2f Elevator:%2f Rudder:%2f\n",
|
||||
posi[0], posi[1], posi[2], ctrl[1], ctrl[0], ctrl[2]);
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(100);
|
||||
}
|
||||
catch (InterruptedException ex) {}
|
||||
|
||||
if(System.in.available() > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(IOException ex)
|
||||
{
|
||||
System.out.println("Error:");
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Java/Examples/Playback/.idea/compiler.xml
generated
Normal file
22
Java/Examples/Playback/.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
3
Java/Examples/Playback/.idea/copyright/profiles_settings.xml
generated
Normal file
3
Java/Examples/Playback/.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
1
Java/Examples/Playback/.idea/description.html
generated
Normal file
1
Java/Examples/Playback/.idea/description.html
generated
Normal file
@@ -0,0 +1 @@
|
||||
<html>Simple <b>Java</b> application that includes a class with <code>main()</code> method</html>
|
||||
9
Java/Examples/Playback/.idea/libraries/XPlaneConnect.xml
generated
Normal file
9
Java/Examples/Playback/.idea/libraries/XPlaneConnect.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="XPlaneConnect">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../../out/artifacts/XPlaneConnect_jar/XPlaneConnect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
12
Java/Examples/Playback/.idea/misc.xml
generated
Normal file
12
Java/Examples/Playback/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectKey">
|
||||
<option name="state" value="project://e2804f05-5315-4fc6-a121-c522a6c26470" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
Java/Examples/Playback/.idea/modules.xml
generated
Normal file
8
Java/Examples/Playback/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/Playback.iml" filepath="$PROJECT_DIR$/Playback.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
3
Java/Examples/Playback/.idea/project-template.xml
generated
Normal file
3
Java/Examples/Playback/.idea/project-template.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<input-field default="com.company">IJ_BASE_PACKAGE</input-field>
|
||||
</template>
|
||||
6
Java/Examples/Playback/.idea/vcs.xml
generated
Normal file
6
Java/Examples/Playback/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
</project>
|
||||
12
Java/Examples/Playback/Playback.iml
Normal file
12
Java/Examples/Playback/Playback.iml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="XPlaneConnect" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
147
Java/Examples/Playback/src/gov/nasa/xpc/Main.java
Normal file
147
Java/Examples/Playback/src/gov/nasa/xpc/Main.java
Normal file
@@ -0,0 +1,147 @@
|
||||
package gov.nasa.xpc;
|
||||
|
||||
import com.sun.javafx.scene.EnteredExitedHandler;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main
|
||||
{
|
||||
|
||||
public static void main(String[] args) throws IOException
|
||||
{
|
||||
String[] mainOpts = new String[] { "Record X-Plane", "Playback File", "Exit" };
|
||||
|
||||
System.out.println("X-Plane Connect Playback Example [Version 1.2.0.0]");
|
||||
System.out.println("(c) 2013-2015 United States Government as represented by the Administrator");
|
||||
System.out.println("of the National Aeronautics and Space Administration. All Rights Reserved.");
|
||||
while(true)
|
||||
{
|
||||
int result = displayMenu("What would you like to do?", mainOpts);
|
||||
switch(result)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
String path = getString("Enter a save file path: ");
|
||||
int interval = getInt("Enter interval between frames (milliseconds): ");
|
||||
int duration = getInt("Enter duration to record for (seconds): ");
|
||||
|
||||
record(path, interval, duration);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
String path = getString("Enter path to saved playback file: ");
|
||||
int interval = getInt("Enter interval between frames (milliseconds): ");
|
||||
|
||||
playback(path, interval);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
System.out.println("Exiting.");
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
System.out.println("Unrecognized menu option.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int displayMenu(String title, String[] opts) throws IOException
|
||||
{
|
||||
System.out.println();
|
||||
System.out.println("+---------------------------------------------- +");
|
||||
System.out.println(String.format("| %1$-42s |", title));
|
||||
System.out.println("+---------------------------------------------- +");
|
||||
for(int i = 0; i < opts.length; ++i)
|
||||
{
|
||||
System.out.println(String.format("| %1$2d. %2$-40s |", i + 1, opts[i]));
|
||||
|
||||
}
|
||||
System.out.println("+---------------------------------------------- +");
|
||||
return getInt("Please select an option: ");
|
||||
}
|
||||
|
||||
private static String getString(String prompt) throws IOException
|
||||
{
|
||||
System.out.print(prompt);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
return reader.readLine();
|
||||
}
|
||||
|
||||
private static int getInt(String prompt) throws IOException
|
||||
{
|
||||
System.out.print(prompt);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
String result = reader.readLine();
|
||||
|
||||
return Integer.parseInt(result);
|
||||
}
|
||||
|
||||
public static void record(String path, int interval, int duration) throws IOException
|
||||
{
|
||||
int count = duration * 1000 / interval;
|
||||
if (count < 1)
|
||||
{
|
||||
throw new IllegalArgumentException("duration is less than one interval.");
|
||||
}
|
||||
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(path)))
|
||||
{
|
||||
System.out.println("Recording...");
|
||||
try (XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
float[] posi = xpc.getPOSI(0);
|
||||
writer.write(String.format("%1$f, %2$f, %3$f, %4$f, %5$f, %6$f, %7$f\n",
|
||||
posi[0], posi[1], posi[2], posi[3], posi[4], posi[5], posi[6]));
|
||||
try
|
||||
{
|
||||
Thread.sleep(interval);
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Recording Complete");
|
||||
}
|
||||
}
|
||||
|
||||
public static void playback(String path, int interval) throws IOException
|
||||
{
|
||||
try(Scanner reader = new Scanner(new FileReader(path)))
|
||||
{
|
||||
reader.useDelimiter("[\\s\\r\\n,]+");
|
||||
System.out.println("Starting playback...");
|
||||
try (XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
while(reader.hasNextLine())
|
||||
{
|
||||
float[] posi = new float[7];
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
String s = reader.next();
|
||||
posi[i] = Float.parseFloat(s);
|
||||
}
|
||||
reader.nextLine();
|
||||
xpc.sendPOSI(posi);
|
||||
try
|
||||
{
|
||||
Thread.sleep(interval);
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Java/src/ViewType.java
Normal file
60
Java/src/ViewType.java
Normal file
@@ -0,0 +1,60 @@
|
||||
//NOTICES:
|
||||
// Copyright <20> 2013-2015 United States Government as represented by the Administrator of the
|
||||
// National Aeronautics and Space Administration. All Rights Reserved.
|
||||
//
|
||||
// DISCLAIMERS
|
||||
// No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND,
|
||||
// EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE
|
||||
// SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT
|
||||
// SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO
|
||||
// THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY
|
||||
// GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE,
|
||||
// SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS RESULTING FROM USE OF THE SUBJECT SOFTWARE.
|
||||
// FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING THIRD-PARTY
|
||||
// SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT "AS IS."
|
||||
//
|
||||
// Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST THE UNITED STATES
|
||||
// GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF
|
||||
// RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES,
|
||||
// EXPENSES OR LOSSES ARISING FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR
|
||||
// RESULTING FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD
|
||||
// HARMLESS THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY
|
||||
// PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER
|
||||
// SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT.
|
||||
package gov.nasa.xpc;
|
||||
|
||||
/**
|
||||
* Represents a camera view in X-Plane
|
||||
*
|
||||
* @author Jason Watkins
|
||||
* @version 1.1
|
||||
* @since 2015-05-08
|
||||
*/
|
||||
public enum ViewType
|
||||
{
|
||||
Forwards(73),
|
||||
Down(74),
|
||||
Left(75),
|
||||
Right(76),
|
||||
Back(77),
|
||||
Tower(78),
|
||||
Runway(79),
|
||||
Chase(80),
|
||||
Follow(81),
|
||||
FollowWithPanel(82),
|
||||
Spot(83),
|
||||
FullscreenWithHud(84),
|
||||
FullscreenNoHud(85);
|
||||
|
||||
private final int value;
|
||||
private ViewType(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -331,46 +331,114 @@ public class XPlaneConnect implements AutoCloseable
|
||||
* @throws IOException If the command cannot be sent.
|
||||
*/
|
||||
public void sendDREF(String dref, float[] value) throws IOException
|
||||
{
|
||||
sendDREFs(new String[] {dref}, new float[][] {value});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to X-Plane that sets the given DREF.
|
||||
*
|
||||
* @param drefs The names of the X-Plane datarefs to set.
|
||||
* @param values A sequence of arrays of floating point values whose structure depends on the drefs specified.
|
||||
* @throws IOException If the command cannot be sent.
|
||||
*/
|
||||
public void sendDREFs(String[] drefs, float[][] values) throws IOException
|
||||
{
|
||||
//Preconditions
|
||||
if(dref == null)
|
||||
if(drefs == null || drefs.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("dref must be a valid string.");
|
||||
throw new IllegalArgumentException(("drefs must be non-empty."));
|
||||
}
|
||||
if(value == null || value.length == 0)
|
||||
if(values == null || values.length != drefs.length)
|
||||
{
|
||||
throw new IllegalArgumentException("value must be non-null and should contain at least one value.");
|
||||
throw new IllegalArgumentException("values must be of the same size as drefs.");
|
||||
}
|
||||
|
||||
//Convert drefs to bytes.
|
||||
byte[] drefBytes = dref.getBytes(StandardCharsets.UTF_8);
|
||||
if(drefBytes.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("DREF is an empty string!");
|
||||
}
|
||||
if(drefBytes.length > 255)
|
||||
{
|
||||
throw new IllegalArgumentException("dref must be less than 255 bytes in UTF-8. Are you sure this is a valid dref?");
|
||||
}
|
||||
|
||||
ByteBuffer bb = ByteBuffer.allocate(4 * value.length);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
for(int i = 0; i < value.length; ++i)
|
||||
{
|
||||
bb.putFloat(i * 4, value[i]);
|
||||
}
|
||||
|
||||
//Build and send message
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write("DREF".getBytes(StandardCharsets.UTF_8));
|
||||
os.write(0xFF); //Placeholder for message length
|
||||
os.write(drefBytes.length);
|
||||
os.write(drefBytes, 0, drefBytes.length);
|
||||
os.write(value.length);
|
||||
os.write(bb.array());
|
||||
for(int i = 0; i < drefs.length; ++i)
|
||||
{
|
||||
String dref = drefs[i];
|
||||
float[] value = values[i];
|
||||
|
||||
if (dref == null)
|
||||
{
|
||||
throw new IllegalArgumentException("dref must be a valid string.");
|
||||
}
|
||||
if (value == null || value.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("value must be non-null and should contain at least one value.");
|
||||
}
|
||||
|
||||
//Convert drefs to bytes.
|
||||
byte[] drefBytes = dref.getBytes(StandardCharsets.UTF_8);
|
||||
if (drefBytes.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("DREF is an empty string!");
|
||||
}
|
||||
if (drefBytes.length > 255)
|
||||
{
|
||||
throw new IllegalArgumentException("dref must be less than 255 bytes in UTF-8. Are you sure this is a valid dref?");
|
||||
}
|
||||
|
||||
ByteBuffer bb = ByteBuffer.allocate(4 * value.length);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
for (int j = 0; j < value.length; ++j)
|
||||
{
|
||||
bb.putFloat(j * 4, value[j]);
|
||||
}
|
||||
|
||||
//Build and send message
|
||||
os.write(drefBytes.length);
|
||||
os.write(drefBytes, 0, drefBytes.length);
|
||||
os.write(value.length);
|
||||
os.write(bb.array());
|
||||
}
|
||||
sendUDP(os.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the control surface information for the specified airplane.
|
||||
*
|
||||
* @param ac The aircraft to get control surface information for.
|
||||
* @return An array containing control surface data in the same format as {@code sendCTRL}.
|
||||
* @throws IOException If the command cannot be sent or a response cannot be read.
|
||||
*/
|
||||
public float[] getCTRL(int ac) throws IOException
|
||||
{
|
||||
// Send request
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write("GETC".getBytes(StandardCharsets.UTF_8));
|
||||
os.write(0xFF); //Placeholder for message length
|
||||
os.write(ac);
|
||||
sendUDP(os.toByteArray());
|
||||
|
||||
// Read response
|
||||
byte[] data = readUDP();
|
||||
if(data.length == 0)
|
||||
{
|
||||
throw new IOException("No response received.");
|
||||
}
|
||||
if(data.length < 31)
|
||||
{
|
||||
throw new IOException("Response too short");
|
||||
}
|
||||
|
||||
// Parse response
|
||||
float[] result = new float[7];
|
||||
ByteBuffer bb = ByteBuffer.wrap(data);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
result[0] = bb.getFloat(5);
|
||||
result[1] = bb.getFloat(9);
|
||||
result[2] = bb.getFloat(13);
|
||||
result[3] = bb.getFloat(17);
|
||||
result[4] = bb.get(21);
|
||||
result[5] = bb.getFloat(22);
|
||||
result[6] = bb.getFloat(27);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends command to X-Plane setting control surfaces on the player ac.
|
||||
*
|
||||
@@ -382,6 +450,7 @@ public class XPlaneConnect implements AutoCloseable
|
||||
* <li>Throttle [-1, 1]</li>
|
||||
* <li>Gear (0=up, 1=down)</li>
|
||||
* <li>Flaps [0, 1]</li>
|
||||
* <li>Speedbrakes [-0.5, 1.5]</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* If @{code ctrl} is less than 6 elements long, The missing elements will not be changed. To
|
||||
@@ -406,6 +475,7 @@ public class XPlaneConnect implements AutoCloseable
|
||||
* <li>Throttle [-1, 1]</li>
|
||||
* <li>Gear (0=up, 1=down)</li>
|
||||
* <li>Flaps [0, 1]</li>
|
||||
* <li>Speedbrakes [-0.5, 1.5]</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* If @{code ctrl} is less than 6 elements long, The missing elements will not be changed. To
|
||||
@@ -440,7 +510,14 @@ public class XPlaneConnect implements AutoCloseable
|
||||
{
|
||||
if(i == 4)
|
||||
{
|
||||
bb.put(cur, (byte) values[i]);
|
||||
if(i >= values.length)
|
||||
{
|
||||
bb.put(cur, (byte)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bb.put(cur, (byte)values[i]);
|
||||
}
|
||||
cur += 1;
|
||||
}
|
||||
else if (i >= values.length)
|
||||
@@ -465,6 +542,44 @@ public class XPlaneConnect implements AutoCloseable
|
||||
sendUDP(os.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets position information for the specified airplane.
|
||||
*
|
||||
* @param ac The aircraft to get position information for.
|
||||
* @return An array containing control surface data in the same format as {@code sendPOSI}.
|
||||
* @throws IOException If the command cannot be sent or a response cannot be read.
|
||||
*/
|
||||
public float[] getPOSI(int ac) throws IOException
|
||||
{
|
||||
// Send request
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write("GETP".getBytes(StandardCharsets.UTF_8));
|
||||
os.write(0xFF); //Placeholder for message length
|
||||
os.write(ac);
|
||||
sendUDP(os.toByteArray());
|
||||
|
||||
// Read response
|
||||
byte[] data = readUDP();
|
||||
if(data.length == 0)
|
||||
{
|
||||
throw new IOException("No response received.");
|
||||
}
|
||||
if(data.length < 34)
|
||||
{
|
||||
throw new IOException("Response too short");
|
||||
}
|
||||
|
||||
// Parse response
|
||||
float[] result = new float[7];
|
||||
ByteBuffer bb = ByteBuffer.wrap(data);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
for(int i = 0; i < 7; ++i)
|
||||
{
|
||||
result[i] = bb.getFloat(6 + 4 * i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the player ac.
|
||||
*
|
||||
@@ -693,6 +808,26 @@ public class XPlaneConnect implements AutoCloseable
|
||||
sendUDP(os.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera view in X-Plane.
|
||||
*
|
||||
* @param view The view to use.
|
||||
* @throws IOException If the command cannot be sent.
|
||||
*/
|
||||
public void sendVIEW(ViewType view) throws IOException
|
||||
{
|
||||
ByteBuffer bb = ByteBuffer.allocate(4);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
bb.putInt(view.getValue());
|
||||
|
||||
//Build and send message
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write("VIEW".getBytes(StandardCharsets.UTF_8));
|
||||
os.write(0xFF); //Placeholder for message length
|
||||
os.write(bb.array());
|
||||
sendUDP(os.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds, removes, or clears a set of waypoints. If the command is clear, the points are ignored
|
||||
* and all points are removed.
|
||||
|
||||
Reference in New Issue
Block a user