Merge pull request #47 from jason-watkins/feature/waypoints
Add support for rendering waypoints in the world
This commit is contained in:
@@ -434,6 +434,32 @@ short sendTEXT(struct xpcSocket sendfd, char* msg, int x, int y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendWYPT(struct xpcSocket sendfd, WYPT_OP op, float points[], int numPoints)
|
||||
{
|
||||
char buf[255] = "WYPT";
|
||||
//Preconditions
|
||||
//Validate operation
|
||||
if (op < xpc_WYPT_ADD || op > xpc_WYPT_CLR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
//Validate number of points
|
||||
else if (numPoints > 19)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
//Everything checks out; send the message
|
||||
else
|
||||
{
|
||||
buf[5] = op;
|
||||
buf[6] = numPoints;
|
||||
size_t len = sizeof(float) * 3 * numPoints;
|
||||
memcpy(buf + 7, points, len);
|
||||
sendUDP(sendfd, buf, len + 7);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//READ
|
||||
//----------------------------------------
|
||||
short readUDP(struct xpcSocket recfd, char *dataRef, struct sockaddr *recvaddr)
|
||||
@@ -669,3 +695,40 @@ xpcCtrl parseCTRL(const char data[])
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
xpcWypt parseWYPT(const char data[])
|
||||
{
|
||||
xpcWypt result;
|
||||
unsigned char len = data[4];
|
||||
//Preconditions
|
||||
//Validate message prefix to ensure we are looking at the right kind of packet.
|
||||
if (strncmp(data, "WYPT", 4) != 0)
|
||||
{
|
||||
result.op = -1;
|
||||
}
|
||||
//Validate operation
|
||||
else if (data[5] < xpc_WYPT_ADD || data[5] > xpc_WYPT_CLR)
|
||||
{
|
||||
result.op = -1;
|
||||
}
|
||||
//Validate number of points
|
||||
else if (data[6] > 19)
|
||||
{
|
||||
result.op = -2;
|
||||
}
|
||||
//Everything checks out; copy the points into result
|
||||
else
|
||||
{
|
||||
result.op = data[5];
|
||||
result.numPoints = data[6];
|
||||
char* ptr = data + 7;
|
||||
for (size_t i = 0; i < result.numPoints; ++i)
|
||||
{
|
||||
result.points[i].latitude = *((float*)ptr);
|
||||
result.points[i].longitude = *((float*)(ptr + 4));
|
||||
result.points[i].altitude = *((float*)(ptr + 8));
|
||||
ptr += 12;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,27 @@
|
||||
float flaps;
|
||||
char aircraft;
|
||||
} xpcCtrl;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double latitude;
|
||||
double longitude;
|
||||
double altitude;
|
||||
} Waypoint;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
xpc_WYPT_ADD = 1,
|
||||
xpc_WYPT_DEL = 2,
|
||||
xpc_WYPT_CLR = 3
|
||||
} WYPT_OP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WYPT_OP op;
|
||||
Waypoint points[20];
|
||||
size_t numPoints;
|
||||
} xpcWypt;
|
||||
|
||||
// Basic Functions
|
||||
struct xpcSocket openUDP(unsigned short port, const char *xpIP, unsigned short xpPort);
|
||||
@@ -83,6 +104,10 @@
|
||||
short parseRequest(const char my_message[], float *resultArray[], short arraySizes[]);
|
||||
short readRequest(struct xpcSocket recfd, float *dataRef[], short arraySizes[], struct sockaddr *recvaddr);
|
||||
|
||||
// Waypoints
|
||||
xpcWypt parseWYPT(const char data[]);
|
||||
short sendWYPT(struct xpcSocket sendfd, WYPT_OP op, float points[], int numPoints);
|
||||
|
||||
// Screen Text
|
||||
short sendTEXT(struct xpcSocket sendfd, char* msg, int x, int y);
|
||||
|
||||
|
||||
Binary file not shown.
50
Java/src/WaypointOp.java
Normal file
50
Java/src/WaypointOp.java
Normal file
@@ -0,0 +1,50 @@
|
||||
//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 operations that can be performed by the WYPT command.
|
||||
*
|
||||
* @author Jason Watkins
|
||||
* @version 1.0
|
||||
* @since 2015-04-09
|
||||
*/
|
||||
public enum WaypointOp
|
||||
{
|
||||
Add(1),
|
||||
Del(2),
|
||||
Clr(3);
|
||||
|
||||
private final int value;
|
||||
private WaypointOp(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,50 @@
|
||||
//NOTICES:
|
||||
// Copyright ã 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.
|
||||
//
|
||||
// X-Plane API
|
||||
// Copyright (c) 2008, Sandy Barbour and Ben Supnik All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
// and associated documentation files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
// * Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
// * Neither the names of the authors nor that of X-Plane or Laminar Research may be used to
|
||||
// endorse or promote products derived from this software without specific prior written
|
||||
// permission from the authors or Laminar Research, respectively.
|
||||
//
|
||||
// X-Plane API SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
package gov.nasa.xpc;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -15,23 +62,6 @@ import java.util.Arrays;
|
||||
* @author Jason Watkins
|
||||
* @version 0.1
|
||||
* @since 2015-03-31
|
||||
|
||||
NOTICES:
|
||||
Copyright ã 2013-2014 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.
|
||||
|
||||
X-Plane API
|
||||
Copyright (c) 2008, Sandy Barbour and Ben Supnik All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Neither the names of the authors nor that of X-Plane or Laminar Research may be used to endorse or promote products derived from this software without specific prior written permission from the authors or Laminar Research, respectively.
|
||||
|
||||
X-Plane API SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
public class XPlaneConnect implements AutoCloseable
|
||||
{
|
||||
@@ -635,6 +665,32 @@ public class XPlaneConnect implements AutoCloseable
|
||||
sendUDP(os.toByteArray());
|
||||
}
|
||||
|
||||
public void sendWYPT(WaypointOp op, float[] points) throws IOException
|
||||
{
|
||||
//Preconditions
|
||||
if(points.length % 3 != 0)
|
||||
{
|
||||
throw new IllegalArgumentException("points.length should be divisible by 3.");
|
||||
}
|
||||
|
||||
//Convert points to bytes
|
||||
ByteBuffer bb = ByteBuffer.allocate(4 * points.length);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
for(float f : points)
|
||||
{
|
||||
bb.putFloat(f);
|
||||
}
|
||||
|
||||
//Build and send message
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write("WYPT".getBytes(StandardCharsets.UTF_8));
|
||||
os.write(0xFF); //Placeholder for message length
|
||||
os.write(op.getValue());
|
||||
os.write(points.length / 3);
|
||||
os.write(bb.array());
|
||||
sendUDP(os.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the port on which the client will receive data from X-Plane.
|
||||
*
|
||||
|
||||
53
MATLAB/+XPlaneConnect/sendWYPT.m
Normal file
53
MATLAB/+XPlaneConnect/sendWYPT.m
Normal file
@@ -0,0 +1,53 @@
|
||||
function [ status ] = sendWYPT( op, points, varargin )
|
||||
% sendWYPT Adds, removes, or clears a set of waypoints to be rendered in
|
||||
% the simulator.
|
||||
%
|
||||
% Inputs
|
||||
% msg: The string to be displayed
|
||||
% x (optional): The distance from the left edge of the screen to display the message.
|
||||
% y (optional): The distance from the bottom edge of the screen to display the message.
|
||||
% IP Address (optional): IP Address of the machine that will receive the data as a character array. Default is '127.0.0.1' (local machine)
|
||||
% port (optional): Port on the receiving machine where the data will be sent. Default is 49009 (XPlaneConnect). In general use 49009 to send to the plugin and 49005 to send to the x-plane udp
|
||||
%
|
||||
% Outputs
|
||||
% status: 0 if successful, otherwise a negative value.
|
||||
%
|
||||
% Use
|
||||
% 1. import XPlaneConnect.*;
|
||||
% 2. #Set a message to be displayed near the top middle of the screen.
|
||||
% 3. status = sendTEXT('Some text', 512, 600);
|
||||
%
|
||||
% Contributors
|
||||
% Jason Watkins
|
||||
% jason.w.watkins@nasa.gov
|
||||
%
|
||||
% To Do
|
||||
%
|
||||
% BEGIN CODE
|
||||
|
||||
import XPlaneConnect.*
|
||||
%% Handle Input
|
||||
p = inputParser;
|
||||
addRequired(p,'op');
|
||||
addRequired(p,'points');
|
||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
||||
addOptional(p,'port',49009,@isnumeric);
|
||||
parse(p,op,points,varargin{:});
|
||||
|
||||
%% Validate Input
|
||||
len = uint32(length(points));
|
||||
assert(op > 0 && op < 4);
|
||||
assert(mod(len, 3) == 0);
|
||||
assert(len / 3 < 20);
|
||||
|
||||
%% Body
|
||||
header = ['WYPT'-0,0];
|
||||
dataStream = [header,...
|
||||
uint8(op),...
|
||||
uint8(len / 3),...
|
||||
typecast(single(points), 'uint8')];
|
||||
|
||||
% Send TEXT
|
||||
status = sendUDP(dataStream, p.Results.IP, p.Results.port);
|
||||
end
|
||||
|
||||
@@ -435,6 +435,39 @@ short sendPOSITest() // sendPOSI test
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendWYPTTest()
|
||||
{
|
||||
printf("sendWYPT - ");
|
||||
|
||||
// Setup
|
||||
struct xpcSocket sendPort = openUDP(49064, "127.0.0.1", 49009);
|
||||
float points[] =
|
||||
{
|
||||
37.5245, -122.06899, 2500,
|
||||
37.455397, -122.050037, 2500,
|
||||
37.469567, -122.051411, 2500,
|
||||
37.479376, -122.060509, 2300,
|
||||
37.482237, -122.076130, 2100,
|
||||
37.474881, -122.087288, 1900,
|
||||
37.467660, -122.079391, 1700,
|
||||
37.466298, -122.090549, 1500,
|
||||
37.362562, -122.039223, 1000,
|
||||
37.361448, -122.034416, 1000,
|
||||
37.361994, -122.026348, 1000,
|
||||
37.365541, -122.022572, 1000,
|
||||
37.373727, -122.024803, 1000,
|
||||
37.403869, -122.041283, 50,
|
||||
37.418544, -122.049222, 6
|
||||
};
|
||||
|
||||
// Test
|
||||
sendWYPT(sendPort, xpc_WYPT_ADD, points, 15);
|
||||
|
||||
// Cleanup
|
||||
closeUDP(sendPort);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short pauseTest() // pauseSim test
|
||||
{
|
||||
printf("pauseSim - ");
|
||||
@@ -560,16 +593,17 @@ int main(int argc, const char * argv[])
|
||||
printf("(Linux) \n");
|
||||
#endif
|
||||
|
||||
runTest(openTest);
|
||||
runTest(closeTest);
|
||||
runTest(openTest);
|
||||
runTest(closeTest);
|
||||
runTest(sendReadTest);
|
||||
runTest(sendTEXTTest);
|
||||
runTest(requestDREFTest);
|
||||
runTest(sendDREFTest);
|
||||
runTest(requestDREFTest);
|
||||
runTest(sendDREFTest);
|
||||
runTest(sendDATATest);
|
||||
runTest(sendCTRLTest);
|
||||
runTest(sendpCTRLTest);
|
||||
runTest(sendPOSITest);
|
||||
runTest(sendPOSITest);
|
||||
runTest(sendWYPTTest);
|
||||
runTest(pauseTest);
|
||||
runTest(connTest);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package gov.nasa.xpc.test;
|
||||
|
||||
import gov.nasa.xpc.WaypointOp;
|
||||
import gov.nasa.xpc.XPlaneConnect;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -247,6 +248,57 @@ public class XPlaneConnectTest
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendWYPT_Add() throws IOException
|
||||
{
|
||||
float points[] =
|
||||
{
|
||||
37.455397F, -122.050037F, 2500F,
|
||||
37.469567F, -122.051411F, 2500F,
|
||||
37.479376F, -122.060509F, 2300F,
|
||||
37.482237F, -122.076130F, 2100F,
|
||||
37.474881F, -122.087288F, 1900F,
|
||||
37.467660F, -122.079391F, 1700F,
|
||||
37.466298F, -122.090549F, 1500F,
|
||||
37.362562F, -122.039223F, 1000F,
|
||||
37.361448F, -122.034416F, 1000F,
|
||||
37.361994F, -122.026348F, 1000F,
|
||||
37.365541F, -122.022572F, 1000F,
|
||||
37.373727F, -122.024803F, 1000F,
|
||||
37.403869F, -122.041283F, 50F,
|
||||
37.418544F, -122.049222F, 6F
|
||||
};
|
||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
xpc.sendWYPT(WaypointOp.Add, points);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendWYPT_Delete() throws IOException
|
||||
{
|
||||
float points[] =
|
||||
{
|
||||
37.361448F, -122.034416F, 1000F,
|
||||
37.361994F, -122.026348F, 1000F,
|
||||
37.365541F, -122.022572F, 1000F,
|
||||
37.373727F, -122.024803F, 1000F,
|
||||
};
|
||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
xpc.sendWYPT(WaypointOp.Del, points);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendWYPT_Clear() throws IOException
|
||||
{
|
||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||
{
|
||||
xpc.sendWYPT(WaypointOp.Clr, new float[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendDREF() throws IOException
|
||||
{
|
||||
|
||||
26
TestScripts/MATLAB Tests/sendWYPTTest.m
Normal file
26
TestScripts/MATLAB Tests/sendWYPTTest.m
Normal file
@@ -0,0 +1,26 @@
|
||||
function sendWYPTTest()
|
||||
%% Setup
|
||||
addpath('../../MATLAB')
|
||||
import XPlaneConnect.*
|
||||
|
||||
points = [37.5245, -122.06899, 2500,...
|
||||
37.455397, -122.050037, 2500,...
|
||||
37.469567, -122.051411, 2500,...
|
||||
37.479376, -122.060509, 2300,...
|
||||
37.482237, -122.076130, 2100,...
|
||||
37.474881, -122.087288, 1900,...
|
||||
37.467660, -122.079391, 1700,...
|
||||
37.466298, -122.090549, 1500,...
|
||||
37.362562, -122.039223, 1000,...
|
||||
37.361448, -122.034416, 1000,...
|
||||
37.361994, -122.026348, 1000,...
|
||||
37.365541, -122.022572, 1000,...
|
||||
37.373727, -122.024803, 1000,...
|
||||
37.403869, -122.041283, 50,...
|
||||
37.418544, -122.049222, 6];
|
||||
|
||||
%% Test
|
||||
sendWYPT(1, points);
|
||||
|
||||
|
||||
end
|
||||
@@ -18,6 +18,7 @@ theTests = {{@openCloseTest, 'Open/Close Test', 0},...
|
||||
{@DATATest,'DATA Test', 0},...
|
||||
{@CTRLTest,'CTRL Test', 0},...
|
||||
{@POSITest,'POSI Test', 0},...
|
||||
{@sendWYPTTest,'WYPT Test', 0},...
|
||||
{@pauseTest,'Pause Test', 0},...
|
||||
{@struTest,'Struct Test', 0},...
|
||||
{@setConnTest, 'setConn Test', 0}};
|
||||
|
||||
@@ -120,7 +120,7 @@ int handleSIMU(char buf[]);
|
||||
int handleCONN(char buf[]);
|
||||
int handlePOSI(char buf[]);
|
||||
int handleCTRL(char buf[]);
|
||||
int handleWYPT();
|
||||
int handleWYPT(char buf[], int len);
|
||||
int handleGETD(char *buf);
|
||||
int handleDREF(char *buf);
|
||||
int handleVIEW();
|
||||
@@ -355,7 +355,7 @@ short handleInput(struct XPCMessage * theMessage)
|
||||
}
|
||||
else if (strncmp(theMessage->head,"WYPT",4)==0) // Header = WYPT (Waypoint Draw)
|
||||
{
|
||||
handleWYPT();
|
||||
handleWYPT(theMessage->msg, theMessage->msglen);
|
||||
}
|
||||
else if (strncmp(theMessage->head,"GETD",4)==0) // Header = GETD (Data Request)
|
||||
{
|
||||
@@ -828,14 +828,40 @@ int handleCTRL(char buf[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handleWYPT()
|
||||
int handleWYPT(char buf[], int len)
|
||||
{
|
||||
char logmsg[100];
|
||||
|
||||
// UPDATE LOG
|
||||
sprintf(logmsg,"[WYPT] Message Received (Conn %i)- WAYPOINT DRAWING FEATURE UNDER CONSTRUCTION", current_connection+1);
|
||||
char logmsg[100];
|
||||
sprintf(logmsg,"[WYPT] Message Received (Conn %i)", current_connection+1);
|
||||
updateLog(logmsg, strlen(logmsg));
|
||||
|
||||
|
||||
xpcWypt wypt = parseWYPT(buf);
|
||||
if (wypt.op < 0)
|
||||
{
|
||||
sprintf(logmsg, "[WYPT] Failed to parse command. ERR:%i", wypt.op);
|
||||
updateLog(logmsg, strlen(logmsg));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(logmsg, "[WYPT] Performing operation %i", wypt.op);
|
||||
updateLog(logmsg, strlen(logmsg));
|
||||
}
|
||||
|
||||
switch (wypt.op)
|
||||
{
|
||||
case xpc_WYPT_ADD:
|
||||
XPCAddWaypoints(wypt.points, wypt.numPoints);
|
||||
break;
|
||||
case xpc_WYPT_DEL:
|
||||
XPCRemoveWaypoints(wypt.points, wypt.numPoints);
|
||||
break;
|
||||
case xpc_WYPT_CLR:
|
||||
XPCClearWaypoints();
|
||||
break;
|
||||
default: //If parseWYPT is doing its job, we shouldn't ever hit this.
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,19 +1,93 @@
|
||||
#include "xpcDrawing.h"
|
||||
#include "XPLMDisplay.h"
|
||||
#include "XPLMGraphics.h"
|
||||
#include <stdlib.h>
|
||||
#include "XPLMDataAccess.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
//OpenGL includes
|
||||
#if IBM
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#if __GNUC__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
//Internal Structures
|
||||
typedef struct
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} LocalPoint;
|
||||
|
||||
//Internal Memory
|
||||
static const size_t MSG_MAX = 1024;
|
||||
static const size_t MSG_LINE_MAX = MSG_MAX / 16;
|
||||
static bool msgEnabled = false;
|
||||
static int msgX = -1;
|
||||
static int msgY = -1;
|
||||
static char msgVal[256] = { 0 };
|
||||
static char msgVal[MSG_MAX] = { 0 };
|
||||
static size_t newLineCount = 0;
|
||||
static size_t newLines[64] = { 0 };
|
||||
static size_t newLines[MSG_LINE_MAX] = { 0 };
|
||||
static float rgb[3] = { 0.25F, 1.0F, 0.25F };
|
||||
|
||||
static const size_t WAYPOINT_MAX = 128;
|
||||
static bool routeEnabled = false;
|
||||
static size_t numWaypoints = 0;
|
||||
static Waypoint waypoints[WAYPOINT_MAX];
|
||||
static LocalPoint localPoints[WAYPOINT_MAX];
|
||||
|
||||
XPLMDataRef planeXref;
|
||||
XPLMDataRef planeYref;
|
||||
XPLMDataRef planeZref;
|
||||
|
||||
//Internal Functions
|
||||
int cmp(const void * a, const void * b)
|
||||
{
|
||||
return (*(size_t*)a - *(size_t*)b);
|
||||
}
|
||||
|
||||
static void gl_drawCube(float x, float y, float z, float d)
|
||||
{
|
||||
//tan(0.25) degrees. Should scale all markers to appear about the same size
|
||||
const float TAN = 0.00436335082070156648652885284203;
|
||||
float h = d * TAN;
|
||||
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
//Top
|
||||
glVertex3f(x - h, y + h, z - h);
|
||||
glVertex3f(x + h, y + h, z - h);
|
||||
glVertex3f(x - h, y + h, z + h);
|
||||
glVertex3f(x + h, y + h, z + h);
|
||||
//Front
|
||||
glVertex3f(x - h, y - h, z + h);
|
||||
glVertex3f(x + h, y - h, z + h);
|
||||
//Bottom
|
||||
glVertex3f(x - h, y - h, z - h);
|
||||
glVertex3f(x + h, y - h, z - h);
|
||||
//Back
|
||||
glVertex3f(x - h, y + h, z - h);
|
||||
glVertex3f(x + h, y + h, z - h);
|
||||
|
||||
glEnd();
|
||||
glBegin(GL_QUADS);
|
||||
//Left
|
||||
glVertex3f(x - h, y + h, z - h);
|
||||
glVertex3f(x - h, y + h, z + h);
|
||||
glVertex3f(x - h, y - h, z + h);
|
||||
glVertex3f(x - h, y - h, z - h);
|
||||
//Right
|
||||
glVertex3f(x + h, y + h, z + h);
|
||||
glVertex3f(x + h, y + h, z - h);
|
||||
glVertex3f(x + h, y - h, z - h);
|
||||
glVertex3f(x + h, y - h, z + h);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static int MessageDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon)
|
||||
{
|
||||
XPLMDrawString(rgb, msgX, msgY, msgVal, NULL, xplmFont_Basic);
|
||||
@@ -26,6 +100,59 @@ static int MessageDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void *
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int RouteDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon)
|
||||
{
|
||||
float px = XPLMGetDataf(planeXref);
|
||||
float py = XPLMGetDataf(planeYref);
|
||||
float pz = XPLMGetDataf(planeZref);
|
||||
|
||||
Waypoint* g;
|
||||
LocalPoint* l;
|
||||
//Convert to local
|
||||
for (size_t i = 0; i < numWaypoints; ++i)
|
||||
{
|
||||
g = &waypoints[i];
|
||||
l = &localPoints[i];
|
||||
XPLMWorldToLocal(g->latitude, g->longitude, g->altitude,
|
||||
&l->x, &l->y, &l->z);
|
||||
}
|
||||
|
||||
|
||||
//Draw posts
|
||||
glColor3f(1.0F, 1.0F, 1.0F);
|
||||
glBegin(GL_LINES);
|
||||
for (size_t i = 0; i < numWaypoints; ++i)
|
||||
{
|
||||
l = &localPoints[i];
|
||||
glVertex3f((float)l->x, (float)l->y, (float)l->z);
|
||||
glVertex3f((float)l->x, -1000.0F, (float)l->z);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
//Draw route
|
||||
glColor3f(1.0F, 0.0F, 0.0F);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (size_t i = 0; i < numWaypoints; ++i)
|
||||
{
|
||||
l = &localPoints[i];
|
||||
glVertex3f((float)l->x, (float)l->y, (float)l->z);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
//Draw markers
|
||||
glColor3f(1.0F, 1.0F, 1.0F);
|
||||
for (size_t i = 0; i < numWaypoints; ++i)
|
||||
{
|
||||
l = &localPoints[i];
|
||||
float xoff = (float)l->x - px;
|
||||
float yoff = (float)l->y - py;
|
||||
float zoff = (float)l->z - pz;
|
||||
float d = sqrtf(xoff*xoff + yoff*yoff + zoff*zoff);
|
||||
gl_drawCube((float)l->x, (float)l->y, (float)l->z, d);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Public Functions
|
||||
void XPCClearMessage()
|
||||
{
|
||||
@@ -37,7 +164,7 @@ void XPCSetMessage(int x, int y, char* msg)
|
||||
{
|
||||
//Determine size of message and clear instead if the message string
|
||||
//is empty.
|
||||
size_t len = strnlen(msg, 255);
|
||||
size_t len = strnlen(msg, MSG_MAX);
|
||||
if (len == 0)
|
||||
{
|
||||
XPCClearMessage();
|
||||
@@ -47,7 +174,7 @@ void XPCSetMessage(int x, int y, char* msg)
|
||||
//Set the message, location, and mark new lines.
|
||||
strncpy(msgVal, msg, len);
|
||||
newLineCount = 0;
|
||||
for (size_t i = 0; i < len && newLineCount < 64; ++i)
|
||||
for (size_t i = 0; i < len && newLineCount < MSG_LINE_MAX; ++i)
|
||||
{
|
||||
if (msgVal[i] == '\n' || msgVal[i] == '\r')
|
||||
{
|
||||
@@ -64,4 +191,78 @@ void XPCSetMessage(int x, int y, char* msg)
|
||||
XPLMRegisterDrawCallback(MessageDrawCallback, xplm_Phase_LastCockpit, 0, NULL);
|
||||
msgEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void XPCClearWaypoints()
|
||||
{
|
||||
numWaypoints = 0;
|
||||
if (routeEnabled)
|
||||
{
|
||||
XPLMUnregisterDrawCallback(RouteDrawCallback, xplm_Phase_Objects, 0, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XPCAddWaypoints(Waypoint points[], size_t numPoints)
|
||||
{
|
||||
if (numWaypoints + numPoints > WAYPOINT_MAX)
|
||||
{
|
||||
numPoints = WAYPOINT_MAX - numWaypoints;
|
||||
}
|
||||
size_t finalNumWaypoints = numPoints + numWaypoints;
|
||||
for (size_t i = 0; i < numPoints; ++i)
|
||||
{
|
||||
waypoints[numWaypoints + i] = points[i];
|
||||
}
|
||||
numWaypoints = finalNumWaypoints;
|
||||
|
||||
if (!routeEnabled)
|
||||
{
|
||||
XPLMRegisterDrawCallback(RouteDrawCallback, xplm_Phase_Objects, 0, NULL);
|
||||
}
|
||||
if (!planeXref)
|
||||
{
|
||||
planeXref = XPLMFindDataRef("sim/flightmodel/position/local_x");
|
||||
planeYref = XPLMFindDataRef("sim/flightmodel/position/local_y");
|
||||
planeZref = XPLMFindDataRef("sim/flightmodel/position/local_z");
|
||||
}
|
||||
}
|
||||
|
||||
void XPCRemoveWaypoints(Waypoint points[], size_t numPoints)
|
||||
{
|
||||
//Build a list of indices of waypoints we should delete.
|
||||
size_t delPoints[WAYPOINT_MAX];
|
||||
size_t delPointsCur = 0;
|
||||
for (size_t i = 0; i < numPoints; ++i)
|
||||
{
|
||||
Waypoint p = points[i];
|
||||
for (size_t j = 0; j < numWaypoints; ++j)
|
||||
{
|
||||
Waypoint q = waypoints[j];
|
||||
if (p.latitude == q.latitude &&
|
||||
p.longitude == q.longitude &&
|
||||
p.altitude == q.altitude)
|
||||
{
|
||||
delPoints[delPointsCur++] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Sort the indices so that we only have to iterate them once
|
||||
qsort(delPoints, delPointsCur, sizeof(size_t), cmp);
|
||||
|
||||
//Copy the new array on top of the old array
|
||||
size_t copyCur = 0;
|
||||
size_t count = delPointsCur;
|
||||
delPointsCur = 0;
|
||||
for (size_t i = 0; i < numWaypoints; ++i)
|
||||
{
|
||||
if (i == delPoints[delPointsCur])
|
||||
{
|
||||
++delPointsCur;
|
||||
continue;
|
||||
}
|
||||
waypoints[copyCur++] = waypoints[i];
|
||||
}
|
||||
numWaypoints -= count;
|
||||
}
|
||||
@@ -1,8 +1,17 @@
|
||||
#ifndef xpcDrawing_h
|
||||
#define xpcDrawing_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
void XPCClearMessage();
|
||||
|
||||
void XPCSetMessage(int x, int y, char* msg);
|
||||
|
||||
void XPCClearWaypoints();
|
||||
|
||||
void XPCAddWaypoints(Waypoint points[], size_t numPoints);
|
||||
|
||||
void XPCRemoveWaypoints(Waypoint points[], size_t numPoints);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -93,6 +94,7 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user