@@ -366,32 +366,46 @@ int readDATA(XPCSocket sock, float data[][9], int rows)
|
||||
/*****************************************************************************/
|
||||
int sendDREF(XPCSocket sock, const char* dref, float value[], int size)
|
||||
{
|
||||
// Setup command
|
||||
// 5 byte header + max 255 char dref name + max 255 values * 4 bytes per value = 1279
|
||||
unsigned char buffer[1279] = "DREF";
|
||||
int drefLen = strnlen(dref, 256);
|
||||
if (drefLen > 255)
|
||||
{
|
||||
printError("setDREF", "dref length is too long. Must be less than 256 characters.");
|
||||
return -1;
|
||||
}
|
||||
if (size > 255)
|
||||
{
|
||||
printError("setDREF", "size is too big. Must be less than 256.");
|
||||
return -2;
|
||||
}
|
||||
int len = 7 + drefLen + size * sizeof(float);
|
||||
|
||||
// Copy dref to buffer
|
||||
buffer[5] = (unsigned char)drefLen;
|
||||
memcpy(buffer + 6, dref, drefLen);
|
||||
return sendDREFs(sock, &dref, &value, &size, 1);
|
||||
}
|
||||
|
||||
// Copy values to buffer
|
||||
buffer[6 + drefLen] = (unsigned char)size;
|
||||
memcpy(buffer + 7 + drefLen, value, size * sizeof(float));
|
||||
int sendDREFs(XPCSocket sock, const char* drefs[], float* values[], int sizes[], int count)
|
||||
{
|
||||
// Setup command
|
||||
// Max size is technically unlimited.
|
||||
unsigned char buffer[65536] = "DREF";
|
||||
int pos = 5;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
int drefLen = strnlen(drefs[i], 256);
|
||||
if (pos + drefLen + sizes[i] * 4 + 2 > 65536)
|
||||
{
|
||||
printError("sendDREF", "About to overrun the send buffer!");
|
||||
return -4;
|
||||
}
|
||||
if (drefLen > 255)
|
||||
{
|
||||
printError("sendDREF", "dref %d is too long. Must be less than 256 characters.", i);
|
||||
return -1;
|
||||
}
|
||||
if (sizes[i] > 255)
|
||||
{
|
||||
printError("sendDREF", "size %d is too big. Must be less than 256.", i);
|
||||
return -2;
|
||||
}
|
||||
// Copy dref to buffer
|
||||
buffer[pos++] = (unsigned char)drefLen;
|
||||
memcpy(buffer + pos, drefs[i], drefLen);
|
||||
pos += drefLen;
|
||||
|
||||
// Copy values to buffer
|
||||
buffer[pos++] = (unsigned char)sizes[i];
|
||||
memcpy(buffer + pos, values[i], sizes[i] * sizeof(float));
|
||||
pos += sizes[i] * sizeof(float);
|
||||
}
|
||||
|
||||
// Send command
|
||||
if (sendUDP(sock, buffer, len) < 0)
|
||||
if (sendUDP(sock, buffer, pos) < 0)
|
||||
{
|
||||
printError("setDREF", "Failed to send command");
|
||||
return -3;
|
||||
|
||||
@@ -127,13 +127,27 @@ int sendDATA(XPCSocket sock, float data[][9], int rows);
|
||||
/// http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html. The size of values should match
|
||||
/// the size given on that page. XPC currently sends all values as floats regardless of
|
||||
/// the type described on the wiki. This doesn't cause any data loss for most datarefs.
|
||||
/// \param sock The socket to use to send the command.
|
||||
/// \param dref The name of the dataref to set.
|
||||
/// \param values An array of values representing the data to set.
|
||||
/// \param size The number of elements in values.
|
||||
/// \returns 0 if successful, otherwise a negative value.
|
||||
/// \param sock The socket to use to send the command.
|
||||
/// \param dref The name of the dataref to set.
|
||||
/// \param value An array of values representing the data to set.
|
||||
/// \param size The number of elements in values.
|
||||
/// \returns 0 if successful, otherwise a negative value.
|
||||
int sendDREF(XPCSocket sock, const char* dref, float value[], int size);
|
||||
|
||||
/// Sets the specified datarefs to the specified values.
|
||||
///
|
||||
/// \details dref names and their associated data types can be found on the XPSDK wiki at
|
||||
/// http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html. The size of values should match
|
||||
/// the size given on that page. XPC currently sends all values as floats regardless of
|
||||
/// the type described on the wiki. This doesn't cause any data loss for most datarefs.
|
||||
/// \param sock The socket to use to send the command.
|
||||
/// \param drefs The names of the datarefs to set.
|
||||
/// \param values A multidimensional array containing the values for each dataref to set.
|
||||
/// \param sizes The number of elements in each array in values
|
||||
/// \param count The number of datarefs being set.
|
||||
/// \returns 0 if successful, otherwise a negative value.
|
||||
int sendDREFs(XPCSocket sock, const char* drefs[], float* values[], int sizes[], int count);
|
||||
|
||||
/// Gets the value of the specified dataref.
|
||||
///
|
||||
/// \details dref names and their associated data types can be found on the XPSDK wiki at
|
||||
|
||||
@@ -331,43 +331,70 @@ 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());
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,17 +1,8 @@
|
||||
function sendDREF( dref, value, socket )
|
||||
% sendDREF Sends a command to X-Plane that sets the given DREF.
|
||||
% sendDREFs Sends a command to X-Plane that sets the given DREF. This
|
||||
% function is now an alias to sendDREFs. It is kept only for backwards
|
||||
% compatibility.
|
||||
%
|
||||
% Inputs
|
||||
% dref: The name of the X-Plane dataref to set.
|
||||
% Value: An array of floating point values whose structure depends on the dref specified.
|
||||
% socket (optional): The client to use when sending the command.
|
||||
%
|
||||
% Use
|
||||
% 1. import XPlaneConnect.*
|
||||
% 2. dataRef = 'sim/aircraft/parts/acf_gear_deploy'; // Landing Gear
|
||||
% 3. Value = 0;
|
||||
% 4. status = setDREF(dataRef, Value);
|
||||
%
|
||||
% Contributors
|
||||
% [CT] Christopher Teubert (SGT, Inc.)
|
||||
% christopher.a.teubert@nasa.gov
|
||||
@@ -20,19 +11,8 @@ function sendDREF( dref, value, socket )
|
||||
|
||||
import XPlaneConnect.*
|
||||
|
||||
%% Get client
|
||||
global clients;
|
||||
if ~exist('socket', 'var')
|
||||
assert(isequal(length(clients) < 2, 1), '[setDREF] ERROR: Multiple clients open. You must specify which client to use.');
|
||||
if isempty(clients)
|
||||
socket = openUDP();
|
||||
else
|
||||
socket = clients(1);
|
||||
end
|
||||
end
|
||||
|
||||
%% Validate input
|
||||
value = single(value);
|
||||
|
||||
%%Send command
|
||||
socket.sendDREF(dref, value);
|
||||
sendDREFs(dref, value)
|
||||
else
|
||||
sendDREFs(dref, value, socket)
|
||||
end
|
||||
37
MATLAB/+XPlaneConnect/sendDREFs.m
Normal file
37
MATLAB/+XPlaneConnect/sendDREFs.m
Normal file
@@ -0,0 +1,37 @@
|
||||
function sendDREFs( drefs, values, socket )
|
||||
% sendDREFs Sends a command to X-Plane that sets the given DREF(s).
|
||||
%
|
||||
% Inputs
|
||||
% dref: The name or names of the X-Plane dataref(s) to set.
|
||||
% Value: An array or an multidimensional array of floating point values
|
||||
% whose structure depends on the dref specified.
|
||||
% socket (optional): The client to use when sending the command.
|
||||
%
|
||||
% Use
|
||||
% 1. import XPlaneConnect.*
|
||||
% 2. dataRef = 'sim/aircraft/parts/acf_gear_deploy'; // Landing Gear
|
||||
% 3. Value = 0;
|
||||
% 4. status = setDREF(dataRef, Value);
|
||||
%
|
||||
% Contributors
|
||||
% [JW] Jason Watkins
|
||||
% jason.w.watkins@nasa.gov
|
||||
|
||||
import XPlaneConnect.*
|
||||
|
||||
%% Get client
|
||||
global clients;
|
||||
if ~exist('socket', 'var')
|
||||
assert(isequal(length(clients) < 2, 1), '[setDREF] ERROR: Multiple clients open. You must specify which client to use.');
|
||||
if isempty(clients)
|
||||
socket = openUDP();
|
||||
else
|
||||
socket = clients(1);
|
||||
end
|
||||
end
|
||||
|
||||
%% Validate input
|
||||
values = single(values);
|
||||
|
||||
%%Send command
|
||||
socket.sendDREFs(drefs, values);
|
||||
@@ -79,8 +79,20 @@ class XPlaneConnect(object):
|
||||
if port < 0 or port > 65535:
|
||||
raise ValueError("The specified port is not a valid port number.")
|
||||
|
||||
#Send command
|
||||
buffer = struct.pack("<4sxH", "CONN", port)
|
||||
self.sendUDP(buffer)
|
||||
|
||||
#Rebind socket
|
||||
clientAddr = ("0.0.0.0", port)
|
||||
timeout = self.socket.gettimeout();
|
||||
self.socket.close();
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
||||
self.socket.bind(clientAddr)
|
||||
self.socket.settimeout(timeout)
|
||||
|
||||
#Read response
|
||||
buffer = self.socket.recv(1024)
|
||||
|
||||
def pauseSim(self, pause):
|
||||
'''Pauses or un-pauses the physics simulation engine in X-Plane.
|
||||
@@ -208,31 +220,45 @@ class XPlaneConnect(object):
|
||||
# Send
|
||||
self.sendUDP(buffer)
|
||||
|
||||
# DREF Manipulation
|
||||
# DREF Manipulation
|
||||
def sendDREF(self, dref, values):
|
||||
'''Sets the specified dataref to the specified value.
|
||||
|
||||
Args:
|
||||
dref: The name of the dataref to set.
|
||||
dref: The name of the datarefs to set.
|
||||
values: Either a scalar value or a sequence of values.
|
||||
'''
|
||||
# Preconditions
|
||||
if len(dref) == 0 or len(dref) > 255:
|
||||
raise ValueError("dref must be a non-empty string less than 256 characters.")
|
||||
if values == None:
|
||||
raise ValueError("values must be a scalar or sequence of floats.")
|
||||
self.sendDREFs([dref], [values])
|
||||
|
||||
def sendDREFs(self, drefs, values):
|
||||
'''Sets the specified datarefs to the specified values.
|
||||
|
||||
Args:
|
||||
drefs: A list of names of the datarefs to set.
|
||||
values: A list of scalar or vector values to set.
|
||||
'''
|
||||
if len(drefs) != len(values):
|
||||
raise ValueError("drefs and values must have the same number of elements.")
|
||||
|
||||
buffer = struct.pack("<4sx", "DREF")
|
||||
for i in range(len(drefs)):
|
||||
dref = drefs[i]
|
||||
value = values[i]
|
||||
# Preconditions
|
||||
if len(dref) == 0 or len(dref) > 255:
|
||||
raise ValueError("dref must be a non-empty string less than 256 characters.")
|
||||
if value == None:
|
||||
raise ValueError("value must be a scalar or sequence of floats.")
|
||||
|
||||
# Pack message
|
||||
fmt = ""
|
||||
buffer = None
|
||||
if hasattr(values, "__len__"):
|
||||
if len(values) > 255:
|
||||
raise ValueError("values must have less than 256 items.")
|
||||
fmt = "<4sxB{0:d}sB{1:d}f".format(len(dref), len(values))
|
||||
buffer = struct.pack(fmt, "DREF", len(dref), dref, len(values), values)
|
||||
else:
|
||||
fmt = "<4sxB{0:d}sBf".format(len(dref))
|
||||
buffer = struct.pack(fmt, "DREF", len(dref), dref, 1, values)
|
||||
# Pack message
|
||||
if hasattr(value, "__len__"):
|
||||
if len(value) > 255:
|
||||
raise ValueError("value must have less than 256 items.")
|
||||
fmt = "<B{0:d}sB{1:d}f".format(len(dref), len(value))
|
||||
buffer += struct.pack(fmt, len(dref), dref, len(value), value)
|
||||
else:
|
||||
fmt = "<B{0:d}sBf".format(len(dref))
|
||||
buffer += struct.pack(fmt, len(dref), dref, 1, value)
|
||||
|
||||
# Send
|
||||
self.sendUDP(buffer)
|
||||
|
||||
@@ -21,9 +21,19 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\C\src\xplaneConnect.c" />
|
||||
<ClCompile Include="..\C Tests\main.c" />
|
||||
<ClCompile Include="..\C Tests\Test.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\C\src\xplaneConnect.h" />
|
||||
<ClInclude Include="..\C Tests\CtrlTests.h" />
|
||||
<ClInclude Include="..\C Tests\DataTests.h" />
|
||||
<ClInclude Include="..\C Tests\DrefTests.h" />
|
||||
<ClInclude Include="..\C Tests\PosiTests.h" />
|
||||
<ClInclude Include="..\C Tests\SimuTests.h" />
|
||||
<ClInclude Include="..\C Tests\Test.h" />
|
||||
<ClInclude Include="..\C Tests\TextTests.h" />
|
||||
<ClInclude Include="..\C Tests\UDPTests.h" />
|
||||
<ClInclude Include="..\C Tests\WyptTests.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BC701AF4-552C-4C9D-82A1-B352542783A4}</ProjectGuid>
|
||||
|
||||
@@ -21,10 +21,40 @@
|
||||
<ClCompile Include="..\..\C\src\xplaneConnect.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\C Tests\Test.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\C\src\xplaneConnect.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\UDPTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\DrefTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\TextTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\SimuTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\CtrlTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\DataTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\PosiTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\WyptTests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\C Tests\Test.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
147
TestScripts/C Tests/CtrlTests.h
Normal file
147
TestScripts/C Tests/CtrlTests.h
Normal file
@@ -0,0 +1,147 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef CTRLTESTS_H
|
||||
#define CTRLTESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int doCTRLTest(char* drefs[7], float values[], int size, int ac, float expected[7])
|
||||
{
|
||||
float* data[7];
|
||||
int sizes[7];
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
data[i] = (float*)malloc(sizeof(float) * 16);
|
||||
sizes[i] = 16;
|
||||
}
|
||||
|
||||
// Execute command
|
||||
XPCSocket sock = openUDP(IP);
|
||||
int result = sendCTRL(sock, values, size, ac);
|
||||
if (result >= 0)
|
||||
{
|
||||
result = getDREFs(sock, drefs, data, 7, sizes);
|
||||
}
|
||||
closeUDP(sock);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Test values
|
||||
float actual[7];
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
actual[i] = data[i][0];
|
||||
}
|
||||
return compareArray(expected, actual, 7);
|
||||
}
|
||||
|
||||
int basicCTRLTest(char** drefs, int ac)
|
||||
{
|
||||
// Set control surfaces to known state.
|
||||
float CTRL[6] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F };
|
||||
float expected[7] = { 0.0F, 0.0F, 0.0F, NAN, NAN, NAN, NAN };
|
||||
int result = doCTRLTest(drefs, CTRL, 3, ac, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -10000 + result;
|
||||
}
|
||||
|
||||
// Test control surfaces and set other values to known state.
|
||||
expected[0] = CTRL[0] = 0.2F;
|
||||
expected[1] = CTRL[1] = 0.1F;
|
||||
expected[2] = CTRL[2] = 0.1F;
|
||||
expected[3] = 0.8F;
|
||||
expected[4] = 1.0F;
|
||||
expected[5] = 0.5F;
|
||||
result = doCTRLTest(drefs, CTRL, 6, ac, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -20000 + result;
|
||||
}
|
||||
|
||||
// Test other values and verify control surfaces unchanged.
|
||||
CTRL[0] = -998;
|
||||
CTRL[1] = -998;
|
||||
CTRL[2] = -998;
|
||||
expected[3] = CTRL[3] = 0.9F;
|
||||
expected[4] = CTRL[4] = 0.0F;
|
||||
expected[5] = CTRL[5] = 0.75F;
|
||||
result = doCTRLTest(drefs, CTRL, 6, ac, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -30000 + result;
|
||||
}
|
||||
}
|
||||
|
||||
int testCTRL_Player()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/cockpit2/controls/yoke_pitch_ratio",
|
||||
"sim/cockpit2/controls/yoke_roll_ratio",
|
||||
"sim/cockpit2/controls/yoke_heading_ratio",
|
||||
"sim/flightmodel/engine/ENGN_thro",
|
||||
"sim/cockpit/switches/gear_handle_status",
|
||||
"sim/flightmodel/controls/flaprqst",
|
||||
"sim/flightmodel/controls/sbrkrqst"
|
||||
};
|
||||
return basicCTRLTest(drefs, 0);
|
||||
}
|
||||
|
||||
int testCTRL_NonPlayer()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/multiplayer/position/plane1_yolk_pitch",
|
||||
"sim/multiplayer/position/plane1_yolk_roll",
|
||||
"sim/multiplayer/position/plane1_yolk_yaw",
|
||||
"sim/multiplayer/position/plane1_throttle",
|
||||
"sim/multiplayer/position/plane1_gear_deploy",
|
||||
"sim/multiplayer/position/plane1_flap_ratio",
|
||||
"sim/multiplayer/position/plane1_sbrkrqst"
|
||||
};
|
||||
return basicCTRLTest(drefs, 1);
|
||||
}
|
||||
|
||||
int testCTRL_Speedbrakes()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/cockpit2/controls/yoke_pitch_ratio",
|
||||
"sim/cockpit2/controls/yoke_roll_ratio",
|
||||
"sim/cockpit2/controls/yoke_heading_ratio",
|
||||
"sim/flightmodel/engine/ENGN_thro",
|
||||
"sim/cockpit/switches/gear_handle_status",
|
||||
"sim/flightmodel/controls/flaprqst",
|
||||
"sim/flightmodel/controls/sbrkrqst"
|
||||
};
|
||||
|
||||
// Arm
|
||||
float CTRL[7] = { -998, -998, -998, -998, -998, -998, -0.5F };
|
||||
float expected[7] = { NAN, NAN, NAN, NAN, NAN, NAN, -0.5F };
|
||||
int result = doCTRLTest(drefs, CTRL, 7, 0, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -10000 + result;
|
||||
}
|
||||
|
||||
// Set to full
|
||||
expected[6] = CTRL[6] = 1.5F;
|
||||
result = doCTRLTest(drefs, CTRL, 7, 0, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -20000 + result;
|
||||
}
|
||||
|
||||
// Retract
|
||||
expected[6] = CTRL[6] = 0.0F;
|
||||
result = doCTRLTest(drefs, CTRL, 7, 0, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -30000 + result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
62
TestScripts/C Tests/DataTests.h
Normal file
62
TestScripts/C Tests/DataTests.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef DATATESTS_H
|
||||
#define DATATESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int testDATA()
|
||||
{
|
||||
// Initialize
|
||||
int i, j; // Iterator
|
||||
char* drefs[100] =
|
||||
{
|
||||
"sim/aircraft/parts/acf_gear_deploy"
|
||||
};
|
||||
float* data[100]; // array for result of getDREFs
|
||||
int sizes[100];
|
||||
float DATA[4][9]; // Array for sendDATA
|
||||
XPCSocket sock = openUDP(IP);
|
||||
|
||||
// Setup
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
data[i] = (float*)malloc(40 * sizeof(float));
|
||||
sizes[i] = 40;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j = 0; j < 9; j++)
|
||||
{
|
||||
data[i][j] = -998;
|
||||
}
|
||||
}
|
||||
DATA[0][0] = 14; // Gear
|
||||
DATA[0][1] = 1;
|
||||
DATA[0][2] = 0;
|
||||
|
||||
// Execution
|
||||
sendDATA(sock, DATA, 1);
|
||||
int result = getDREFs(sock, drefs, data, 1, sizes);
|
||||
|
||||
// Close
|
||||
closeUDP(sock);
|
||||
|
||||
// Tests
|
||||
if (result < 0)// Request 1 value
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (sizes[0] != 10)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
if (*data[0] != data[0][1])
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
247
TestScripts/C Tests/DrefTests.h
Normal file
247
TestScripts/C Tests/DrefTests.h
Normal file
@@ -0,0 +1,247 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef DREFTESTS_H
|
||||
#define DREFTESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int doGETDTest(char* drefs[], float* expected[], int count, int sizes[])
|
||||
{
|
||||
// Setup memory
|
||||
int* asizes = (int*)malloc(sizeof(int) * count);
|
||||
float** actual = (float**)malloc(sizeof(float*) * count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
asizes[i] = sizes[i];
|
||||
actual[i] = (float*)malloc(sizeof(float) * sizes[i]);
|
||||
}
|
||||
|
||||
// Execute command
|
||||
XPCSocket sock = openUDP(IP);
|
||||
int result = getDREFs(sock, drefs, actual, count, asizes);
|
||||
closeUDP(sock);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Test sizes and values
|
||||
result = compareArrays(expected, sizes, actual, asizes, count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
free(actual[i]);
|
||||
}
|
||||
free(actual);
|
||||
free(asizes);
|
||||
return result;
|
||||
}
|
||||
|
||||
int doDREFTest(char* drefs[], float* values[], float* expected[], int count, int sizes[])
|
||||
{
|
||||
// Setup memory
|
||||
int* asizes = (int*)malloc(sizeof(int) * count);
|
||||
float** actual = (float**)malloc(sizeof(float*) * count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
asizes[i] = sizes[i];
|
||||
actual[i] = (float*)malloc(sizeof(float) * sizes[i]);
|
||||
}
|
||||
|
||||
// Execute command
|
||||
XPCSocket sock = openUDP(IP);
|
||||
int result = sendDREFs(sock, drefs, values, sizes, count);
|
||||
if (result >= 0)
|
||||
{
|
||||
result = getDREFs(sock, drefs, actual, count, asizes);
|
||||
}
|
||||
closeUDP(sock);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Test sizes and values
|
||||
result = compareArrays(expected, sizes, actual, asizes, count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
free(actual[i]);
|
||||
}
|
||||
free(actual);
|
||||
free(asizes);
|
||||
return result;
|
||||
}
|
||||
|
||||
int testGETD_Basic()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/cockpit/switches/gear_handle_status", //int
|
||||
"sim/cockpit/autopilot/altitude", //float
|
||||
"sim/aircraft/prop/acf_prop_type", //int[8]
|
||||
"sim/cockpit2/switches/panel_brightness_ratio", //float[4]
|
||||
"sim/aircraft/view/acf_tailnum", //byte[40]
|
||||
"sim/flightmodel/position/elevation" //double
|
||||
};
|
||||
int sizes[] = { 1, 1, 8, 4, 40, 1 };
|
||||
float* expected[6];
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
expected[i] = (float*)malloc(sizeof(float) * sizes[i]);
|
||||
for (int j = 0; j < sizes[i]; ++j)
|
||||
{
|
||||
expected[i][j] = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
return doGETDTest(drefs, expected, 6, sizes);
|
||||
}
|
||||
|
||||
int testGETD_TestFloat()
|
||||
{
|
||||
char* dref = "sim/test/test_float";
|
||||
int size = 1;
|
||||
float* expected[1];
|
||||
expected[0] = (float*)malloc(sizeof(float));
|
||||
expected[0][0] = 0.0F;
|
||||
|
||||
int result = doGETDTest(&dref, &expected, 1, &size);
|
||||
free(expected[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
int testGETD_Types()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/cockpit/switches/gear_handle_status", //int
|
||||
"sim/cockpit/autopilot/altitude", //float
|
||||
"sim/aircraft/prop/acf_prop_type", //int[8]
|
||||
"sim/cockpit2/switches/panel_brightness_ratio", //float[4]
|
||||
"sim/aircraft/view/acf_tailnum", //byte[40]
|
||||
"sim/flightmodel/position/elevation" //double
|
||||
};
|
||||
int sizes[] = { 1, 1, 8, 4, 40, 1 };
|
||||
float* data[6];
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
data[i] = (float*)malloc(sizeof(float) * sizes[i]);
|
||||
}
|
||||
|
||||
// Execute command
|
||||
XPCSocket sock = openUDP(IP);
|
||||
int result = getDREFs(sock, drefs, data, 6, sizes);
|
||||
closeUDP(sock);
|
||||
|
||||
// Tests
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// Verify sizes
|
||||
if (sizes[0] != 1 || sizes[1] != 1 || sizes[2] != 8
|
||||
|| sizes[3] != 4 || sizes[4] != 40 || sizes[5] != 1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
// Verify integer drefs are integers
|
||||
if ((float)((int)data[0][0]) != data[0][0])
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if ((float)((int)data[2][i]) != data[2][i])
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 40; ++i)
|
||||
{
|
||||
if ((float)((char)data[4][i]) != data[4][i])
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
// Verify tail number has at least one valid character
|
||||
if (data[4][0] <= 0 || data[4][0] > 127)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDREF()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/cockpit/switches/gear_handle_status", //int
|
||||
"sim/cockpit/autopilot/altitude", //float
|
||||
"sim/aircraft/prop/acf_prop_type", //int[8]
|
||||
"sim/cockpit2/switches/panel_brightness_ratio", //float[4]
|
||||
"sim/aircraft/view/acf_tailnum", //byte[40]
|
||||
"sim/flightmodel/position/elevation" //double - Read only
|
||||
};
|
||||
float* values[6];
|
||||
float* expected[6];
|
||||
int sizes[6];
|
||||
|
||||
// Setup
|
||||
sizes[0] = 1;
|
||||
values[0] = (float*)malloc(sizes[0] * sizeof(float));
|
||||
expected[0] = values[0];
|
||||
values[0][0] = 1;
|
||||
|
||||
sizes[1] = 1;
|
||||
values[1] = (float*)malloc(sizes[1] * sizeof(float));
|
||||
expected[1] = values[1];
|
||||
values[1][0] = 4000.0F;
|
||||
|
||||
sizes[2] = 8;
|
||||
values[2] = (float*)malloc(sizes[2] * sizeof(float));
|
||||
expected[2] = values[2];
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
values[2][i] = 0;
|
||||
}
|
||||
|
||||
sizes[3] = 4;
|
||||
values[3] = (float*)malloc(sizes[3] * sizeof(float));
|
||||
expected[3] = values[3];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
values[3][i] = 0.25F;
|
||||
}
|
||||
|
||||
sizes[4] = 40;
|
||||
values[4] = (float*)malloc(sizes[4] * sizeof(float));
|
||||
expected[4] = (float*)malloc(sizes[4] * sizeof(float));
|
||||
memset(values[4], 0, sizes[4] * sizeof(float));
|
||||
values[4][0] = 78.0F; //N
|
||||
values[4][1] = 55.0F; //7
|
||||
values[4][2] = 52.0F; //4
|
||||
values[4][3] = 56.0F; //8
|
||||
values[4][4] = 53.0F; //5
|
||||
values[4][5] = 89.0F; //Y
|
||||
|
||||
expected[4][0] = 78.0F; //N
|
||||
expected[4][1] = 55.0F; //7
|
||||
expected[4][2] = 52.0F; //4
|
||||
expected[4][3] = 56.0F; //8
|
||||
expected[4][4] = 53.0F; //5
|
||||
expected[4][5] = 89.0F; //Y
|
||||
for (int i = 6; i < sizes[4]; ++i)
|
||||
{
|
||||
expected[4][i] = NAN;
|
||||
}
|
||||
|
||||
sizes[5] = 1;
|
||||
values[5] = (float*)malloc(sizes[5] * sizeof(float));
|
||||
expected[5] = (float*)malloc(sizes[5] * sizeof(float));
|
||||
values[5][0] = 5000.0F;
|
||||
expected[5][0] = NAN;
|
||||
|
||||
return doDREFTest(drefs, values, expected, 6, sizes);
|
||||
}
|
||||
|
||||
#endif
|
||||
120
TestScripts/C Tests/PosiTests.h
Normal file
120
TestScripts/C Tests/PosiTests.h
Normal file
@@ -0,0 +1,120 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef POSITESTS_H
|
||||
#define POSITESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int doPOSITest(char* drefs[7], float values[], int size, int ac, float expected[7])
|
||||
{
|
||||
float* data[7];
|
||||
int sizes[7];
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
data[i] = (float*)malloc(sizeof(float) * 10);
|
||||
sizes[i] = 10;
|
||||
}
|
||||
|
||||
// Execute command
|
||||
XPCSocket sock = openUDP(IP);
|
||||
pauseSim(sock, 1);
|
||||
int result = sendPOSI(sock, values, size, ac);
|
||||
if (result >= 0)
|
||||
{
|
||||
result = getDREFs(sock, drefs, data, 7, sizes);
|
||||
}
|
||||
pauseSim(sock, 0);
|
||||
closeUDP(sock);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Test values
|
||||
float actual[7];
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
actual[i] = data[i][0];
|
||||
}
|
||||
return compareArray(expected, actual, 7);
|
||||
}
|
||||
|
||||
int basicPOSITest(char** drefs, int ac)
|
||||
{
|
||||
// Set psoition and initial orientation
|
||||
float POSI[7] = { 37.524F, -122.06899F, 2500, 0, 0, 0, 1 };
|
||||
float expected[7] = { 37.524F, -122.06899F, 2500, 0, 0, 0, 1 };
|
||||
int result = doPOSITest(drefs, POSI, 7, ac, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -10000 + result;
|
||||
}
|
||||
|
||||
// Set orientation
|
||||
POSI[0] = -998.0F;
|
||||
POSI[1] = -998.0F;
|
||||
POSI[2] = -998.0F;
|
||||
POSI[3] = 5.0F;
|
||||
POSI[4] = -5.0F;
|
||||
POSI[5] = 10.0F;
|
||||
POSI[6] = 0;
|
||||
|
||||
float *loc[3];
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
loc[i] = (float*)malloc(sizeof(float));
|
||||
}
|
||||
int sizes[3] = { 1, 1, 1 };
|
||||
XPCSocket sock = openUDP(IP);
|
||||
pauseSim(sock, 1);
|
||||
getDREFs(sock, drefs, loc, 3, sizes);
|
||||
closeUDP(sock);
|
||||
|
||||
expected[0] = loc[0][0];
|
||||
expected[1] = loc[1][0];
|
||||
expected[2] = loc[2][0];
|
||||
expected[3] = 5.0F;
|
||||
expected[4] = -5.0F;
|
||||
expected[5] = 10.0F;
|
||||
expected[6] = 0.0F;
|
||||
result = doPOSITest(drefs, POSI, 7, ac, expected);
|
||||
if (result < 0)
|
||||
{
|
||||
return -20000 + result;
|
||||
}
|
||||
}
|
||||
|
||||
int testPOSI_Player()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/flightmodel/position/latitude",
|
||||
"sim/flightmodel/position/longitude",
|
||||
"sim/flightmodel/position/elevation",
|
||||
"sim/flightmodel/position/theta",
|
||||
"sim/flightmodel/position/phi",
|
||||
"sim/flightmodel/position/psi",
|
||||
"sim/cockpit/switches/gear_handle_status"
|
||||
};
|
||||
return basicPOSITest(drefs, 0);
|
||||
}
|
||||
|
||||
int testPOSI_NonPlayer()
|
||||
{
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/multiplayer/position/plane1_lat",
|
||||
"sim/multiplayer/position/plane1_lon",
|
||||
"sim/multiplayer/position/plane1_el",
|
||||
"sim/multiplayer/position/plane1_the",
|
||||
"sim/multiplayer/position/plane1_phi",
|
||||
"sim/multiplayer/position/plane1_psi",
|
||||
"sim/multiplayer/position/plane1_gear_deploy"
|
||||
};
|
||||
return basicPOSITest(drefs, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
80
TestScripts/C Tests/SimuTests.h
Normal file
80
TestScripts/C Tests/SimuTests.h
Normal file
@@ -0,0 +1,80 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef SIMUTESTS_H
|
||||
#define SIMIUTESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int doSIMUTest(int value, float expected)
|
||||
{
|
||||
int size = 20;
|
||||
float actual[20];
|
||||
char* dref = "sim/operation/override/override_planepath";
|
||||
|
||||
XPCSocket sock = openUDP(IP);
|
||||
int result = pauseSim(sock, value);
|
||||
if (result >= 0)
|
||||
{
|
||||
result = getDREF(sock, dref, &actual, &size);
|
||||
}
|
||||
closeUDP(sock);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
if (!feq(actual[i], expected) && !isnan(expected))
|
||||
{
|
||||
return -100 - i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int testSIMU_Basic()
|
||||
{
|
||||
int result = doSIMUTest(0, 0);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = doSIMUTest(1, 1);
|
||||
if (result < 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
result = doSIMUTest(0, 0);
|
||||
if (result < 0)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSIMU_Toggle()
|
||||
{
|
||||
int result = doSIMUTest(0, 0);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = doSIMUTest(2, 1);
|
||||
if (result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = doSIMUTest(2, 0);
|
||||
if (result < 0)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
51
TestScripts/C Tests/Test.c
Normal file
51
TestScripts/C Tests/Test.c
Normal file
@@ -0,0 +1,51 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#include "Test.h"
|
||||
|
||||
int testFailed = 0;
|
||||
int testPassed = 0;
|
||||
|
||||
void runTest(int(*test)(), char* name)
|
||||
{
|
||||
printf("Running test %s... ", name);
|
||||
int result = test(); // Run Test
|
||||
if (result == 0)
|
||||
{
|
||||
printf("PASSED\n");
|
||||
testPassed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Test %s - FAILED\n\tError: %i\n", name, result);
|
||||
testFailed++;
|
||||
}
|
||||
}
|
||||
|
||||
int compareFloat(float expected, float actual)
|
||||
{
|
||||
return feq(expected, actual) || isnan(expected) ? 0 : -1;
|
||||
}
|
||||
|
||||
int compareArray(float expected[], float actual[], int size)
|
||||
{
|
||||
return compareArrays(&expected, &size, &actual, &size, 1);
|
||||
}
|
||||
|
||||
int compareArrays(float* expected[], int esizes[], float* actual[], int asizes[], int count)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (esizes[i] != asizes[i])
|
||||
{
|
||||
return -100 - i;
|
||||
}
|
||||
for (int j = 0; j < esizes[i]; ++j)
|
||||
{
|
||||
if (!feq(actual[i][j], expected[i][j]) && !isnan(expected[i][j]))
|
||||
{
|
||||
return -1000 - i * 100 - j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
25
TestScripts/C Tests/Test.h
Normal file
25
TestScripts/C Tests/Test.h
Normal file
@@ -0,0 +1,25 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef TESTRUNNER_H
|
||||
#define TESTRUNNER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define feq(x, y) (fabs(x - y) < 1e-4)
|
||||
|
||||
#define IP "127.0.0.1"
|
||||
|
||||
extern int testFailed;
|
||||
extern int testPassed;
|
||||
|
||||
void runTest(int(*test)(), char* name);
|
||||
|
||||
int compareFloat(float expected, float actual);
|
||||
int compareArray(float expected[], float actual[], int size);
|
||||
int compareArrays(float* expected[], int esizes[], float* actual[], int asizes[], int count);
|
||||
|
||||
#endif
|
||||
32
TestScripts/C Tests/TextTests.h
Normal file
32
TestScripts/C Tests/TextTests.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef TEXTTESTS_H
|
||||
#define TEXTTESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int testTEXT()
|
||||
{
|
||||
// Setup
|
||||
XPCSocket sendPort = openUDP(IP);
|
||||
int x = 100;
|
||||
int y = 700;
|
||||
char* msg = "This is an X-Plane Connect test message.\nThis should be a new line.\r\nThat will be parsed as two line breaks.";
|
||||
|
||||
// Test
|
||||
sendTEXT(sendPort, msg, x, y);
|
||||
// NOTE: Manually verify that msg appears on the screen in X-Plane!
|
||||
|
||||
sendTEXT(sendPort, "Another test message", x, y);
|
||||
// NOTE: Manually verify that msg appears on the screen and that no part of the previous
|
||||
// message is visible.
|
||||
|
||||
sendTEXT(sendPort, NULL, -1, -1);
|
||||
|
||||
// Cleanup
|
||||
closeUDP(sendPort);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
55
TestScripts/C Tests/UDPTests.h
Normal file
55
TestScripts/C Tests/UDPTests.h
Normal file
@@ -0,0 +1,55 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef UDPTESTS_H
|
||||
#define UDPTESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int testOpen()
|
||||
{
|
||||
XPCSocket sock = openUDP("localhost");
|
||||
int result = strncmp(sock.xpIP, "127.0.0.1", 16);
|
||||
closeUDP(sock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int testClose()
|
||||
{
|
||||
XPCSocket sendPort = aopenUDP(IP, 49009, 49063);
|
||||
closeUDP(sendPort);
|
||||
sendPort = aopenUDP(IP, 49009, 49063);
|
||||
closeUDP(sendPort);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCONN()
|
||||
{
|
||||
// Initialize
|
||||
char* drefs[] =
|
||||
{
|
||||
"sim/cockpit/switches/gear_handle_status"
|
||||
};
|
||||
float data[1];
|
||||
int size = 1;
|
||||
XPCSocket sock = openUDP(IP);
|
||||
#if (__APPLE__ || __linux)
|
||||
usleep(0);
|
||||
#endif
|
||||
|
||||
// Execution
|
||||
setCONN(&sock, 49055);
|
||||
int result = getDREF(sock, drefs[0], data, &size);
|
||||
|
||||
// Close
|
||||
closeUDP(sock);
|
||||
|
||||
// Test
|
||||
if (result < 0)// No data received
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
42
TestScripts/C Tests/WyptTests.h
Normal file
42
TestScripts/C Tests/WyptTests.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||
#ifndef WYPTTESTS_H
|
||||
#define WYPTTESTS_H
|
||||
|
||||
#include "Test.h"
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int testWYPT()
|
||||
{
|
||||
// Setup
|
||||
XPCSocket sock = openUDP(IP);
|
||||
float points[] =
|
||||
{
|
||||
37.5245F, -122.06899F, 2500,
|
||||
37.455397F, -122.050037F, 2500,
|
||||
37.469567F, -122.051411F, 2500,
|
||||
37.479376F, -122.060509F, 2300,
|
||||
37.482237F, -122.076130F, 2100,
|
||||
37.474881F, -122.087288F, 1900,
|
||||
37.467660F, -122.079391F, 1700,
|
||||
37.466298F, -122.090549F, 1500,
|
||||
37.362562F, -122.039223F, 1000,
|
||||
37.361448F, -122.034416F, 1000,
|
||||
37.361994F, -122.026348F, 1000,
|
||||
37.365541F, -122.022572F, 1000,
|
||||
37.373727F, -122.024803F, 1000,
|
||||
37.403869F, -122.041283F, 50,
|
||||
37.418544F, -122.049222F, 6
|
||||
};
|
||||
|
||||
// Test
|
||||
sendWYPT(sock, XPC_WYPT_CLR, NULL, 0);
|
||||
sendWYPT(sock, XPC_WYPT_ADD, points, 15);
|
||||
// NOTE: Visually ensure waypoints are added in the sim
|
||||
|
||||
// Cleanup
|
||||
closeUDP(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -333,6 +333,33 @@ public class XPlaneConnectTest
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendDREFs() throws IOException
|
||||
{
|
||||
String[] drefs =
|
||||
{
|
||||
"sim/cockpit/switches/gear_handle_status",
|
||||
"sim/cockpit/autopilot/altitude"
|
||||
};
|
||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
float[][] values = {{1}, {2000}};
|
||||
xpc.sendDREFs(drefs, values);
|
||||
|
||||
float[][] result = xpc.getDREFs(drefs);
|
||||
assertEquals(values[0][0], result[0][0], 1e-4);
|
||||
assertEquals(values[1][0], result[1][0], 1e-4);
|
||||
|
||||
values[0][0] = 0;
|
||||
values[1][0] = 4000;
|
||||
xpc.sendDREFs(drefs, values);
|
||||
|
||||
result = xpc.getDREFs(drefs);
|
||||
assertEquals(values[0][0], result[0][0], 1e-4);
|
||||
assertEquals(values[1][0], result[1][0], 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSendDREF_NullDREF() throws IOException
|
||||
{
|
||||
|
||||
@@ -117,6 +117,37 @@ class XPCTests(unittest.TestCase):
|
||||
value = 0
|
||||
do_test()
|
||||
|
||||
def test_sendDREFs(self):
|
||||
drefs = [\
|
||||
"sim/cockpit/switches/gear_handle_status",\
|
||||
"sim/cockpit/autopilot/altitude"]
|
||||
values = None
|
||||
def do_test():
|
||||
# Setup
|
||||
client = xpc.XPlaneConnect()
|
||||
|
||||
# Execute
|
||||
client.sendDREFs(drefs, values)
|
||||
result = client.getDREFs(drefs)
|
||||
|
||||
# Cleanup
|
||||
client.close()
|
||||
|
||||
# Tests
|
||||
self.assertEqual(2, len(result))
|
||||
self.assertEqual(1, len(result[0]))
|
||||
self.assertEqual(values[0], result[0][0])
|
||||
self.assertEqual(1, len(result[1]))
|
||||
self.assertEqual(values[1], result[1][0])
|
||||
|
||||
# Test 1
|
||||
values = [1, 2000]
|
||||
do_test()
|
||||
|
||||
# Test 2
|
||||
values = [0, 4000]
|
||||
do_test()
|
||||
|
||||
def test_sendDATA(self):
|
||||
# Setup
|
||||
dref = "sim/aircraft/parts/acf_gear_deploy"
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
// As a result, these log messages may be the only indication of failure.
|
||||
// 2: All errors. Any time something unexpected happens, log it.
|
||||
// 3: Significant actions. Any time something happens outside of normal
|
||||
// command processing, log it.
|
||||
// command processing, log it. Will also log when commands are received.
|
||||
// 4: Detailed actions. Log aditional information as commands are processed.
|
||||
// 5: Everything. Log nearly every single action the plugin takes. This may
|
||||
// have a detrimental impact on X-Plane performance.
|
||||
#define LOG_VERBOSITY 2
|
||||
#define LOG_VERBOSITY 3
|
||||
|
||||
namespace XPC
|
||||
{
|
||||
|
||||
@@ -402,18 +402,41 @@ namespace XPC
|
||||
|
||||
void MessageHandlers::HandleDref(Message& msg)
|
||||
{
|
||||
const unsigned char* buffer = msg.GetBuffer();
|
||||
unsigned char len = buffer[5];
|
||||
std::string dref = std::string((char*)buffer + 6, len);
|
||||
|
||||
unsigned char valueCount = buffer[6 + len];
|
||||
float* values = (float*)(buffer + 7 + len);
|
||||
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::FormatLine("[DREF] Request to set DREF value received (Conn %i): %s", connection.id, dref.c_str());
|
||||
#if LOG_VERBOSITY >= 3
|
||||
Log::FormatLine("[DREF] Request to set DREF value received (Conn %i)", connection.id);
|
||||
#endif
|
||||
const unsigned char* buffer = msg.GetBuffer();
|
||||
std::size_t size = msg.GetSize();
|
||||
std::size_t pos = 5;
|
||||
while (pos < size)
|
||||
{
|
||||
unsigned char len = buffer[pos++];
|
||||
if (pos + len > size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
std::string dref = std::string((char*)buffer + pos, len);
|
||||
pos += len;
|
||||
|
||||
DataManager::Set(dref, values, valueCount);
|
||||
unsigned char valueCount = buffer[pos++];
|
||||
if (pos + 4 * valueCount > size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
float* values = (float*)(buffer + pos);
|
||||
pos += 4 * valueCount;
|
||||
|
||||
DataManager::Set(dref, values, valueCount);
|
||||
#if LOG_VERBOSITY >= 4
|
||||
Log::FormatLine("[DREF] Set %d values for %s", valueCount, dref.c_str());
|
||||
#endif
|
||||
}
|
||||
#if LOG_VERBOSITY >= 2
|
||||
if (pos != size)
|
||||
{
|
||||
Log::WriteLine("[DREF] Error: Command did not terminate at the expected position.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MessageHandlers::HandleGetD(Message& msg)
|
||||
|
||||
Reference in New Issue
Block a user