Refactored MATLAB client to use the Java client internally.
- Still need to implement selectDATA for all languages.
This commit is contained in:
BIN
MATLAB/+XPlaneConnect/XPlaneConnect.jar
Normal file
BIN
MATLAB/+XPlaneConnect/XPlaneConnect.jar
Normal file
Binary file not shown.
@@ -1,33 +0,0 @@
|
|||||||
function socket = clearUDPBuffer(socket,varargin)
|
|
||||||
% clearUDPBuffer Script that clears an UDP Socket Buffer by closing and
|
|
||||||
% reopening the socket
|
|
||||||
%
|
|
||||||
% Inputs
|
|
||||||
% Socket: UDP Socket to be cleared
|
|
||||||
%
|
|
||||||
% Outputs
|
|
||||||
% Socket: UDP Socket
|
|
||||||
%
|
|
||||||
% Use
|
|
||||||
% 1. import XPlaneConnect.*;
|
|
||||||
% 2. Socket = openUDP(49005);
|
|
||||||
% 3. Socket = clearUDPBuffer(Socket);
|
|
||||||
%
|
|
||||||
% Contributors
|
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
|
||||||
% christopher.a.teubert@nasa.gov
|
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
|
||||||
|
|
||||||
%% Close and reopen socket
|
|
||||||
if ~socket.isClosed()
|
|
||||||
port = socket.getLocalPort(); %get port of socket
|
|
||||||
socket.close; %Close Socket
|
|
||||||
socket = openUDP(port,varargin); %open new socket
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,28 +1,27 @@
|
|||||||
function [socket] = closeUDP(socket)
|
function closeUDP(socket)
|
||||||
% closeUDP Script that closes a UDP Socket
|
% closeUDP Closes the specified connection and releases resources associated with it.
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% Socket: UDP Socket to be closed
|
% socket: An XPC client to close
|
||||||
%
|
|
||||||
% Outputs
|
|
||||||
% Socket: Closed Socket
|
|
||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
% 2. Socket = openUDP(49005);
|
% 2. socket = openUDP();
|
||||||
% 3. Status = closeUDP(Socket);
|
% 3. closeUDP(socket);
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% [CT] Christopher Teubert (SGT, Inc.)
|
||||||
% christopher.a.teubert@nasa.gov
|
% christopher.a.teubert@nasa.gov
|
||||||
%
|
% [JW] Jason Watkins
|
||||||
% To Do
|
% jason.w.watkins@nasa.gov
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
|
%% Close the socket
|
||||||
|
assert(isequal(class(socket), 'gov.nasa.xpc.XPlaneConnect'),...
|
||||||
|
'[closeUDP] ERROR: socket was not an XPC client.');
|
||||||
socket.close;
|
socket.close;
|
||||||
|
|
||||||
assert(isequal(socket.isClosed(),1),'closeUDP: Error- Could not close socket');
|
%% Track open clients
|
||||||
|
global clients;
|
||||||
|
%TODO: Remove stale clients
|
||||||
|
|
||||||
end
|
end
|
||||||
37
MATLAB/+XPlaneConnect/getDREFs.m
Normal file
37
MATLAB/+XPlaneConnect/getDREFs.m
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
function result = requestDREFs( drefs, socket )
|
||||||
|
%requestDREF request the value of a specific DataRef from X-Plane over UDP
|
||||||
|
%
|
||||||
|
%Inputs
|
||||||
|
% drefs: Cell Array of DataRefs to be requested
|
||||||
|
% socket (optional): The client to use when sending the command.
|
||||||
|
%Outputs
|
||||||
|
% result: cell array of resulting data.
|
||||||
|
%
|
||||||
|
%Use
|
||||||
|
% 1. import XPlaneConnect.*;
|
||||||
|
% 2. socket = opendUDP();
|
||||||
|
% 3. drefs = {'sim/cockpit2/controls/yoke_heading_ratio','sim/cockpit2/controls/yoke_roll_ratio'};
|
||||||
|
% 4. result = requestDREF(drefs, socket);
|
||||||
|
%
|
||||||
|
% Contributors
|
||||||
|
% [CT] Christopher Teubert (SGT, Inc.)
|
||||||
|
% christopher.a.teubert@nasa.gov
|
||||||
|
% [JW] Jason Watkins
|
||||||
|
% jason.w.watkins@nasa.gov
|
||||||
|
|
||||||
|
import XPlaneConnect.*
|
||||||
|
|
||||||
|
%% Get client
|
||||||
|
global clients;
|
||||||
|
if ~exist('socket', 'var')
|
||||||
|
assert(istrue(length(clients) < 2), '[getDREFs] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
|
if isempty(clients)
|
||||||
|
openUDP();
|
||||||
|
end
|
||||||
|
socket = clients(1);
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Send command
|
||||||
|
result = socket.getDREF(drefs);
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,41 +1,40 @@
|
|||||||
function [socket] = openUDP(port, varargin)
|
function [ socket ] = openUDP(varargin)
|
||||||
%openUDP Script that opens an UDP Socket
|
%openUDP Initializes a new instance of the XPC client and returns it.
|
||||||
%
|
%
|
||||||
%Inputs
|
%Inputs
|
||||||
% port: UDP Port for socket
|
% xpHost: The network host on which X-Plane is running.
|
||||||
|
% xpPort: The port on which the X-Plane Connect plugin is listening.
|
||||||
|
% port: The local port to use when sending and receiving data from XPC.
|
||||||
% timeout (optional): Optional parameter for time to UDP timeout (in ms)
|
% timeout (optional): Optional parameter for time to UDP timeout (in ms)
|
||||||
%Outputs
|
%Outputs
|
||||||
% Socket: UDP Socket
|
% socket: An instance of the XPC client.
|
||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
% 2. Socket = openUDP(49005); %Open socket at port 49005 with timeout=0.1 sec
|
% 2. socket = openUDP(); % Open a socket using the default settings
|
||||||
% or
|
% or
|
||||||
% 2. Socket = openUDP(49005); %Open socket at port 49005 with timeout=0.2 sec
|
% 2. Socket = openUDP('127.0.0.1', 49008, 49005); % Open a socket to connect to X-Plane on the local machine and receive data on port 49005
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% [CT] Christopher Teubert (SGT, Inc.)
|
||||||
% christopher.a.teubert@nasa.gov
|
% christopher.a.teubert@nasa.gov
|
||||||
%
|
% [JW] Jason Watkins
|
||||||
% To Do
|
% jason.w.watkins@nasa.gov
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import java.net.DatagramSocket
|
%% Handle input
|
||||||
|
p = inputParser;
|
||||||
|
addOptional(p,'xpHost','127.0.0.1',@ischar);
|
||||||
|
addOptional(p,'xpPort',49009,@isnumeric);
|
||||||
|
addOptional(p,'port',0,@isnumeric);
|
||||||
|
parse(p,varargin{:});
|
||||||
|
|
||||||
%% create socket
|
%% Create client
|
||||||
socket = DatagramSocket(port);
|
javaaddpath('XPlaneConnect.jar');
|
||||||
socket.setSoTimeout(100);
|
import gov.nasa.xpc.*;
|
||||||
socket.setReceiveBufferSize(2000);
|
socket = XPlaneConnect(p.Results.xpHost, p.Results.xpPort, p.Results.port);
|
||||||
|
|
||||||
%% interpret input
|
%% Track open clients
|
||||||
if ~isempty(varargin)
|
global clients;
|
||||||
if isnumeric(varargin(1))
|
clients = [clients, socket];
|
||||||
socket.setSoTimeout(varargin(1));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert(isequal(socket.isClosed(),0),'openUDP: Error- Could not open port');
|
end
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
function status = pauseSim( pause, varargin )
|
function pauseSim( pause, socket )
|
||||||
%pauseSim pause Simulation
|
%pauseSim Pauses or unpauses X-Plane.
|
||||||
%
|
%
|
||||||
%Inputs
|
%Inputs
|
||||||
% Pause: binary value 0=run, 1=pause
|
% pause: binary value 0=run, 1=pause
|
||||||
% 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)
|
% socket (optional): The client to use when sending the command.
|
||||||
% 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
|
|
||||||
%
|
|
||||||
%Outputs
|
|
||||||
% status: If there was an error. Status<0 means there was an error.
|
|
||||||
%
|
%
|
||||||
%Use
|
%Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
@@ -16,29 +12,25 @@ function status = pauseSim( pause, varargin )
|
|||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% [CT] Christopher Teubert (SGT, Inc.)
|
||||||
% christopher.a.teubert@nasa.gov
|
% christopher.a.teubert@nasa.gov
|
||||||
%
|
% [JW] Jason Watkins
|
||||||
% To Do
|
% jason.w.watkins@nasa.gov
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
%BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
import XPlaneConnect.*
|
||||||
|
|
||||||
%% Handle Input
|
%% Get client
|
||||||
% Optional parameters
|
global clients;
|
||||||
p = inputParser;
|
if ~exist('socket', 'var')
|
||||||
addRequired(p,'pause',@isnumeric);
|
assert(istrue(length(clients) < 2), '[pauseSim] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
if isempty(clients)
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
openUDP();
|
||||||
parse(p,pause,varargin{:});
|
end
|
||||||
|
socket = clients(1);
|
||||||
|
end
|
||||||
|
|
||||||
% Check format of input-TODO
|
%% Validate input
|
||||||
|
pause = logical(pause);
|
||||||
|
|
||||||
%% BODY
|
%% Send command
|
||||||
message = zeros(1,6);
|
socket.pauseSim(pause);
|
||||||
|
|
||||||
message(1:4) = 'SIMU'-0;
|
|
||||||
message(6) = uint8(p.Results.pause);
|
|
||||||
|
|
||||||
status = sendUDP(message, p.Results.IP, p.Results.port);
|
|
||||||
end
|
end
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
function [ sensor ] = readDATA( socket )
|
function [ result ] = readDATA( socket )
|
||||||
% readDATA Reads UDP Socket and interprets data
|
% readDATA Reads UDP Socket and interprets data
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% location: Either an opened UDP Socket or integer port number
|
% socket (optional): The client to read from.
|
||||||
%
|
|
||||||
% Outputs
|
% Outputs
|
||||||
% If data is X-Plane data format:
|
% If data is X-Plane data format:
|
||||||
% data: Matlab X-Plane DATA Structure
|
% data: Matlab X-Plane DATA Structure
|
||||||
@@ -30,62 +29,20 @@ function [ sensor ] = readDATA( socket )
|
|||||||
% NOTE: sending in a port number instead of an opened socket clears the UDP buffer. This only works if the data is being sent at a fast rate. Sending in a UDP Socket reads the first packet in the buffer.
|
% NOTE: sending in a port number instead of an opened socket clears the UDP buffer. This only works if the data is being sent at a fast rate. Sending in a UDP Socket reads the first packet in the buffer.
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% Christopher Teubert (SGT, Inc.) <christopher.a.teubert@nasa.gov>
|
||||||
% christopher.a.teubert@nasa.gov
|
% Jason Watkins <jason.w.watkins@nasa.gov>
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
import XPlaneConnect.*
|
||||||
|
|
||||||
%% Read UDP Socket
|
%% Get client
|
||||||
[ sensor.raw] = readUDP(socket);
|
global clients;
|
||||||
|
if ~exist('socket', 'var')
|
||||||
%% Interpret Input
|
assert(istrue(length(clients) < 2), '[sendDATA] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
bits = size(sensor.raw);
|
if isempty(clients)
|
||||||
if sensor.raw ~= -998 %If the signal exists
|
openUDP();
|
||||||
header = char(sensor.raw(1:4)');
|
|
||||||
if strcmp(header,'DATA') %DATA signal type
|
|
||||||
Values = floor((bits-5)/36);
|
|
||||||
sensor.d = [];
|
|
||||||
sensor.h = zeros(Values(1),1);
|
|
||||||
for i=1:Values(1)
|
|
||||||
sensor.h(i) = sensor.raw(6+(i-1)*36);
|
|
||||||
sensor.d = [sensor.d; typecast(uint8(sensor.raw(10+(i-1)*36:5+i*36))','single')];
|
|
||||||
end
|
|
||||||
elseif strcmp(header,'STRU') %STRU signal type
|
|
||||||
a = 6;
|
|
||||||
while a<length(sensor.raw)
|
|
||||||
strdim = sensor.raw(a);
|
|
||||||
if strdim == 0
|
|
||||||
break
|
|
||||||
end
|
|
||||||
fieldName = char(sensor.raw(a+1:a+strdim)');
|
|
||||||
a = a+strdim+1;
|
|
||||||
dim1 = sensor.raw(a);
|
|
||||||
dim2 = sensor.raw(a+1);
|
|
||||||
if dim1 == 0 %String
|
|
||||||
value = char(sensor.raw(a+2:a+1+dim2))';
|
|
||||||
a = a + dim2 + 2;
|
|
||||||
else
|
|
||||||
value = [];
|
|
||||||
for i=1:dim1
|
|
||||||
value(i,:) = typecast(uint8(sensor.raw(a+2+(i-1)*dim2*4:a+1+i*dim2*4))','single');
|
|
||||||
end
|
|
||||||
a = a + dim1*dim2*4+2;
|
|
||||||
end
|
|
||||||
sensor.(fieldName) = value;
|
|
||||||
end
|
|
||||||
elseif strcmp(header,'OTHR')
|
|
||||||
sensor.d = sensor.raw(6:end);
|
|
||||||
else %Other signal type
|
|
||||||
sensor.d = sensor.raw;
|
|
||||||
end
|
|
||||||
else %No Signal
|
|
||||||
sensor.d = -998;
|
|
||||||
end
|
end
|
||||||
|
socket = clients(1);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% Get data
|
||||||
|
result.raw = socket.readDATA();
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
function [ data ] = readUDP( varargin )
|
|
||||||
%readUDP Read Array from UDP Socket
|
|
||||||
%
|
|
||||||
% Inputs
|
|
||||||
% input: Either an opened UDP Socket or integer port number
|
|
||||||
%
|
|
||||||
% Outputs
|
|
||||||
% data: UDP uint8 Array. Equal to -998 in the case of an error
|
|
||||||
%
|
|
||||||
% Use
|
|
||||||
% 1. import XPlaneConnect.*;
|
|
||||||
% 2. socket = openUDP(49005);
|
|
||||||
% 3. data = readUDP(socket);
|
|
||||||
% 4. status = closeUDP(socket);
|
|
||||||
%
|
|
||||||
% or
|
|
||||||
%
|
|
||||||
% 1. import XPlaneConnect.*;
|
|
||||||
% 2. data = readUDP(49005);
|
|
||||||
%
|
|
||||||
% NOTE: sending in a port number instead of an opened socket clears the
|
|
||||||
%UDP buffer. This only works if the data is being sent at a fast rate.
|
|
||||||
%Sending in a UDP Socket reads the first packet in the buffer.
|
|
||||||
%
|
|
||||||
% Contributors
|
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
|
||||||
% christopher.a.teubert@nasa.gov
|
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
|
||||||
import java.net.DatagramPacket
|
|
||||||
bits = 2000;
|
|
||||||
|
|
||||||
%% Interpret Input
|
|
||||||
global udpReadPort;
|
|
||||||
if isempty(varargin)
|
|
||||||
if isempty(udpReadPort)
|
|
||||||
udpReadPort = 49008;
|
|
||||||
end
|
|
||||||
socket = openUDP(udpReadPort);
|
|
||||||
ownSocket = 1;
|
|
||||||
else
|
|
||||||
socket = varargin{1};
|
|
||||||
ownSocket = 0;
|
|
||||||
if isnumeric(varargin{1})
|
|
||||||
socket=openUDP(varargin{1});
|
|
||||||
ownSocket = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
%% Try reading packet
|
|
||||||
try
|
|
||||||
packet = DatagramPacket(zeros(1,bits,'int8'),bits);
|
|
||||||
socket.receive(packet)
|
|
||||||
data = packet.getData;
|
|
||||||
|
|
||||||
data = int16(data);
|
|
||||||
data(data(:)<0) = uint8(data(data(:)<0) + 256); %fix signed issue
|
|
||||||
size = int16(data(5)); %size of data stream
|
|
||||||
|
|
||||||
%% trim trailing data
|
|
||||||
for i=1:floor(length(data)/256)+1
|
|
||||||
if data(size+1:end)==0
|
|
||||||
break
|
|
||||||
end
|
|
||||||
size = size + 256;
|
|
||||||
end
|
|
||||||
data = data(1:size);
|
|
||||||
|
|
||||||
catch err %Read Unsuccessful
|
|
||||||
data = -998;
|
|
||||||
end
|
|
||||||
|
|
||||||
%% Close Port (if opened in code)
|
|
||||||
if ownSocket
|
|
||||||
socket.close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
function result = requestDREF( DREFArray, varargin )
|
|
||||||
%requestDREF request the value of a specific DataRef from X-Plane over UDP
|
|
||||||
%
|
|
||||||
%Inputs
|
|
||||||
% DREFArray: Cell Array of DataRefs to be requested
|
|
||||||
% 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
|
|
||||||
%
|
|
||||||
%Outputs
|
|
||||||
% result: cell array of resulting data where
|
|
||||||
%
|
|
||||||
%Use
|
|
||||||
% 1. import XPlaneConnect.*;
|
|
||||||
% 2. DREFArray = {'sim/cockpit2/controls/yoke_heading_ratio','sim/cockpit2/controls/yoke_roll_ratio'};
|
|
||||||
% 3. result = requestDREF( DREFArray, '172.0.100.54' );
|
|
||||||
%
|
|
||||||
% Contributors
|
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
|
||||||
% christopher.a.teubert@nasa.gov
|
|
||||||
%
|
|
||||||
%BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
|
||||||
|
|
||||||
message = zeros(1,6);
|
|
||||||
len = 7;
|
|
||||||
status = -1; %#ok<NASGU> % no data
|
|
||||||
|
|
||||||
%% Handle Input
|
|
||||||
p = inputParser;
|
|
||||||
addRequired(p,'DREFArray');
|
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
|
||||||
parse(p,DREFArray,varargin{:});
|
|
||||||
|
|
||||||
%% BODY
|
|
||||||
% Header
|
|
||||||
message(1:4) = 'GETD'-0;
|
|
||||||
message(6) = length(p.Results.DREFArray);
|
|
||||||
|
|
||||||
% DREFS
|
|
||||||
for i=1:length(p.Results.DREFArray)
|
|
||||||
message(len) = length(p.Results.DREFArray{i});
|
|
||||||
message(len+1:len+message(len)) = p.Results.DREFArray{i};
|
|
||||||
len = len+1+message(len);
|
|
||||||
end
|
|
||||||
|
|
||||||
% Send UDP
|
|
||||||
status = sendUDP(message, p.Results.IP, p.Results.port);
|
|
||||||
|
|
||||||
% Look for response
|
|
||||||
for i=1:40
|
|
||||||
data = readUDP();
|
|
||||||
if length(data) > 1 % Received Data
|
|
||||||
status = 0;
|
|
||||||
counter = 7;
|
|
||||||
nArrays = data(6);
|
|
||||||
result = cell(nArrays,1);
|
|
||||||
for j=1:nArrays
|
|
||||||
sizeArray = data(counter);
|
|
||||||
result{j} = typecast(uint8(data(counter+1:counter+sizeArray*4))','single');
|
|
||||||
counter = counter + 1 + sizeArray * 4;
|
|
||||||
end
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
result = cell(0,1);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
function [ status ] = sendCTRL( ctrl, acft, IP, port )
|
function sendCTRL( ctrl, ac, socket )
|
||||||
% sendCTRL Send X-Plane Aircraft Control Commands over UDP
|
% sendCTRL Sends command to X-Plane setting control surfaces on the specified aircraft.
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% ctrl: control array where the elements are as follows:
|
% ctrl: control array where the elements are as follows:
|
||||||
@@ -9,56 +9,44 @@ function [ status ] = sendCTRL( ctrl, acft, IP, port )
|
|||||||
% 4. Throttle [-1, 1]
|
% 4. Throttle [-1, 1]
|
||||||
% 5. Gear (0=up, 1=down)
|
% 5. Gear (0=up, 1=down)
|
||||||
% 6. Flaps [0, 1]
|
% 6. Flaps [0, 1]
|
||||||
% acft (optional): Aircraft # (default is 0; 0 = own aircraft)
|
% ac (optional): The aircraft to set. 0 for the player aircraft.
|
||||||
% 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)
|
% socket (optional): The client to use when sending the command.
|
||||||
% 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
|
% Outputs
|
||||||
% status: If there was an error. Status<0 means there was an error.
|
% status: If there was an error. Status<0 means there was an error.
|
||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
% 2. #Send the data array to port 49009 on the computer at IP address 172.0.100.54.
|
% 2. socket = openUDP();
|
||||||
% 3. status = sendCTRL([0, 0, 0, 0.8, 0, 1], 1, '172.0.100.54',49009);
|
% 3. status = sendCTRL([0, 0, 0, 0.8, 0, 1], 0, socket); % Set throttle and flaps on the player aircraft.
|
||||||
%
|
%
|
||||||
% Note: send the value -998 to not overwrite that parameter. That is, if -998 is sent, the parameter will stay at the current X-Plane value
|
% Note: send the value -998 to not overwrite that parameter. That is, if
|
||||||
|
% -998 is sent, the parameter will stay at the current X-Plane value.
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% Christopher Teubert (SGT, Inc.) <christopher.a.teubert@nasa.gov>
|
||||||
% christopher.a.teubert@nasa.gov
|
% Jason Watkins <jason.w.watkins@nasa.gov>
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
import XPlaneConnect.*
|
||||||
|
|
||||||
%% Handle Input
|
%% Get client
|
||||||
% Optional parameters
|
global clients;
|
||||||
if ~exist('IP','var'), IP = '127.0.0.1'; end
|
if ~exist('socket', 'var')
|
||||||
if ~exist('port','var'), port = 49009; end
|
assert(istrue(length(clients) < 2), '[sendCTRL] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
if ~exist('acft','var'), acft = 0; end
|
if isempty(clients)
|
||||||
|
openUDP();
|
||||||
% Check format of input-TODO
|
|
||||||
|
|
||||||
%%BODY
|
|
||||||
header = ['CTRL'-0,0];
|
|
||||||
dataStream = header; %TODO-ADD ACFT
|
|
||||||
|
|
||||||
% Deal with position update
|
|
||||||
control = [-998.5, -998.5, -998.5, -998.5, -998.5, -998.5];
|
|
||||||
|
|
||||||
for i=1:min(length(ctrl),length(control))
|
|
||||||
control(i) = ctrl(i);
|
|
||||||
end
|
end
|
||||||
dataStream = [dataStream, typecast(single(control(1:4)),'uint8')];
|
socket = clients(1);
|
||||||
dataStream = [dataStream, uint8(control(5))];
|
|
||||||
dataStream = [dataStream, typecast(single(control(6)),'uint8')];
|
|
||||||
dataStream = [dataStream, uint8(acft)];
|
|
||||||
|
|
||||||
% Send DATA
|
|
||||||
status = sendUDP(dataStream, IP, port);
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% Validate input
|
||||||
|
ctrl = single(ctrl);
|
||||||
|
if ~exist('ac', 'var')
|
||||||
|
ac = 0;
|
||||||
|
end
|
||||||
|
ac = logical(ac);
|
||||||
|
|
||||||
|
%% Send command
|
||||||
|
socket.sendCTRL(ctrl, ac);
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
function [ status ] = sendDATA(data, varargin)
|
function sendDATA(data, socket)
|
||||||
% sendDATA Send X-Plane formatted DATA over UDP
|
% sendDATA Send X-Plane formatted DATA over UDP
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% data: X-Plane formatted data. Is a matlab structure with the following fields:
|
% data: X-Plane formatted data. Is a matlab structure with the following fields:
|
||||||
% .h: Header array containing header numbers corresponding to values in the X-Plane UDP Data screen.
|
% .h: Header array containing header numbers corresponding to values in the X-Plane UDP Data screen.
|
||||||
% .d: 2-D Data array. Each row contains eight values corresponding to the header value (.h(1) corresponds to .d(1,:))
|
% .d: 2-D Data array. Each row contains eight values corresponding to the header value (.h(1) corresponds to .d(1,:))
|
||||||
% 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)
|
% socket (optional): The client to use when sending the command.
|
||||||
% 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 interface.
|
|
||||||
%
|
|
||||||
% Outputs
|
|
||||||
% status: 0: no error, <0: error
|
|
||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
@@ -29,29 +25,22 @@ function [ status ] = sendDATA(data, varargin)
|
|||||||
|
|
||||||
import XPlaneConnect.*
|
import XPlaneConnect.*
|
||||||
|
|
||||||
%% Handle Input
|
%% Get client
|
||||||
p = inputParser;
|
global clients;
|
||||||
addRequired(p,'data');
|
if ~exist('socket', 'var')
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
assert(istrue(length(clients) < 2), '[sendDATA] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
if isempty(clients)
|
||||||
parse(p,data,varargin{:});
|
openUDP();
|
||||||
|
|
||||||
%% BODY
|
|
||||||
|
|
||||||
header = ['DATA'-0,0];
|
|
||||||
dataStream = header;
|
|
||||||
|
|
||||||
for i=1:length(p.Results.data.h)
|
|
||||||
dataStream = [dataStream, p.Results.data.h(i), 0, 0, 0, typecast(single(p.Results.data.d(i,1:8)),'uint8')]; %#ok<AGROW>
|
|
||||||
end
|
end
|
||||||
|
socket = clients(1);
|
||||||
% Send DATA
|
|
||||||
if length(dataStream) > 5
|
|
||||||
status = sendUDP(dataStream, p.Results.IP, p.Results.port);
|
|
||||||
else
|
|
||||||
disp('Warning in sendDATA: Sending empty dataStream')
|
|
||||||
status = -2;
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% Validate input
|
||||||
|
javaData = [];
|
||||||
|
for i = 1:length(data.h);
|
||||||
|
javaData = [javaData; data.h(i) data.d(i, 1:8)];
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Send command
|
||||||
|
socket.sendDATA(javaData);
|
||||||
|
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
function status = sendDREF( dataRef, Value, varargin )
|
|
||||||
% sendDREF Send a command to change any DataRef in X-Plane over UDP. This requires the X-Plane Connect Plugin to be running
|
|
||||||
%
|
|
||||||
% Inputs
|
|
||||||
% dataRef: The X-Plane Dataref that will be chaged
|
|
||||||
% Value: The value that the above dataref is set to
|
|
||||||
% 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: If there was an error. status<0 means there was an error.
|
|
||||||
%
|
|
||||||
% Use
|
|
||||||
% 1. import XPlaneConnect.*
|
|
||||||
% 2. dataRef = 'sim/aircraft/parts/acf_gear_deploy'; // Landing Gear
|
|
||||||
% 3. Value = 0;
|
|
||||||
% 4. status = sendDREF(dataRef, Value);
|
|
||||||
%
|
|
||||||
% Contributors
|
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
|
||||||
% christopher.a.teubert@nasa.gov
|
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
|
||||||
|
|
||||||
status = 0;
|
|
||||||
|
|
||||||
%% Handle Input
|
|
||||||
p = inputParser;
|
|
||||||
addRequired(p,'dataRef');
|
|
||||||
addRequired(p,'Value');
|
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
|
||||||
parse(p,dataRef, Value ,varargin{:});
|
|
||||||
|
|
||||||
%% BODY
|
|
||||||
dataStream = zeros(1,7+length(p.Results.dataRef)+length(p.Results.Value)*4);
|
|
||||||
% Build Header
|
|
||||||
dataStream(1:4) = 'DREF'-0;
|
|
||||||
|
|
||||||
% Add DREF
|
|
||||||
dataStream(6) = uint8(length(p.Results.dataRef));
|
|
||||||
len = 6+length(p.Results.dataRef);
|
|
||||||
dataStream(7:len)=p.Results.dataRef-0;
|
|
||||||
|
|
||||||
% Add Value
|
|
||||||
dataStream(len+1) =uint8(length(p.Results.Value));
|
|
||||||
dataStream(len+2:end)=typecast(single(p.Results.Value),'uint8');
|
|
||||||
|
|
||||||
% Send DREF
|
|
||||||
if length(dataStream) > 5
|
|
||||||
status = sendUDP(dataStream, p.Results.IP, p.Results.port);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
function [ status ] = sendPOSI( posi, varargin )
|
function sendPOSI( posi, ac, socket )
|
||||||
% sendPOSI Send X-Plane Aircraft Position over UDP
|
% sendPOSI Sets the position of the specified aircraft.
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% posi: Position array where the elements are as follows:
|
% posi: Position array where the elements are as follows:
|
||||||
@@ -10,52 +10,42 @@ function [ status ] = sendPOSI( posi, varargin )
|
|||||||
% 5. Pitch (deg)
|
% 5. Pitch (deg)
|
||||||
% 6. True Heading (deg)
|
% 6. True Heading (deg)
|
||||||
% 7. Gear (0=up, 1=down)
|
% 7. Gear (0=up, 1=down)
|
||||||
% acft (optional): Aircraft # (default is 0; 0 = own aircraft)
|
% acft (optional): The aircraft to set. 0 for the player aircraft.
|
||||||
% 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)
|
% socket (optional): The client to use when sending the command.
|
||||||
% 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: If there was an error. Status<0 means there was an error.
|
|
||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
% 2. #Send the data array to port 49009 on the computer at IP address 172.0.100.54.
|
% 2. sendPOSI([37.5242422, -122.06899, 2500, 0, 0, 0, 1], 1);
|
||||||
% 3. status = sendPOSI([37.5242422, -122.06899, 2500, 0, 0, 0, 1], 1, '172.0.100.54');
|
|
||||||
%
|
%
|
||||||
% Note: send the value -998 to not overwrite that parameter. That is, if -998 is sent, the parameter will stay at the current X-Plane value
|
% Note: send the value -998 to not overwrite that parameter. That is, if
|
||||||
|
% -998 is sent, the parameter will stay at the current X-Plane value.
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% [CT] Christopher Teubert (SGT, Inc.)
|
||||||
% christopher.a.teubert@nasa.gov
|
% christopher.a.teubert@nasa.gov
|
||||||
%
|
% [JW] Jason Watkins
|
||||||
% To Do
|
% jason.w.watkins@nasa.gov
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
import XPlaneConnect.*
|
||||||
|
|
||||||
%% Handle Input
|
%% Get client
|
||||||
p = inputParser;
|
global clients;
|
||||||
addRequired(p,'posi');
|
if ~exist('socket', 'var')
|
||||||
addOptional(p,'acft',0,@isnumeric);
|
assert(istrue(length(clients) < 2), '[pauseSim] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
if isempty(clients)
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
openUDP();
|
||||||
parse(p,posi,varargin{:});
|
|
||||||
|
|
||||||
%% BODY
|
|
||||||
header = ['POSI'-0,0];
|
|
||||||
dataStream = [header, p.Results.acft];
|
|
||||||
|
|
||||||
% Deal with position update
|
|
||||||
position = [37.4185718,-121.935565,500,0,0,0, 0];
|
|
||||||
|
|
||||||
for i=1:min(length(position),length(p.Results.posi))
|
|
||||||
position(i) = p.Results.posi(i);
|
|
||||||
end
|
end
|
||||||
dataStream = [dataStream, typecast(single(position),'uint8')];
|
socket = clients(1);
|
||||||
|
|
||||||
% Send POSI
|
|
||||||
status = sendUDP(dataStream, p.Results.IP, p.Results.port);
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% Validate input
|
||||||
|
posi = single(posi);
|
||||||
|
if ~exist('ac', 'var')
|
||||||
|
ac = 0;
|
||||||
|
end
|
||||||
|
ac = logical(ac);
|
||||||
|
|
||||||
|
%% Send command
|
||||||
|
socket.sendCTRL(ctrl, ac);
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
function [ status ] = sendSTRU( STRU, varargin )
|
|
||||||
%sendSTRU Send a MATLAB structure over UDP
|
|
||||||
%
|
|
||||||
%Inputs
|
|
||||||
% stru: A MATLAB structure
|
|
||||||
% 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
|
|
||||||
%
|
|
||||||
%Outputs
|
|
||||||
% status: If there was an error. Status<0 means there was an error.
|
|
||||||
%
|
|
||||||
%Use
|
|
||||||
% 1. import XPlaneConnect.*;
|
|
||||||
% 2. data = struct('a',[1:20],'b',1.853,'name','Example Structure');
|
|
||||||
% 3. #Send the data structure to port 49005 on the computer at IP address 172.0.100.54
|
|
||||||
% 4. status = sendUDP( data, '172.0.100.54', 49005 );
|
|
||||||
%
|
|
||||||
% Contributors
|
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
|
||||||
% christopher.a.teubert@nasa.gov
|
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
%
|
|
||||||
%BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
|
||||||
|
|
||||||
%% Handle Input
|
|
||||||
p = inputParser;
|
|
||||||
addRequired(p,'STRU');
|
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
|
||||||
parse(p,STRU,varargin{:});
|
|
||||||
|
|
||||||
%% Form Data Array representing the structure
|
|
||||||
DATA = ['STRU'-0,0]; %array header
|
|
||||||
fieldName = fieldnames(p.Results.STRU); %all Struct fields
|
|
||||||
for i=1:length(fieldName) %for each field
|
|
||||||
field = getfield(p.Results.STRU,fieldName{i}); %get field
|
|
||||||
if ischar(field) %String
|
|
||||||
dim1 = 0; %Indicates string
|
|
||||||
dim2 = length(field); %length
|
|
||||||
data = field-0; %data
|
|
||||||
else %Numeric
|
|
||||||
dim1 = size(field,1); %Array Dim1
|
|
||||||
dim2 = size(field,2); %Array Dim2
|
|
||||||
data = typecast(single(reshape(field',1,dim1*dim2)),'uint8'); %Data
|
|
||||||
end
|
|
||||||
|
|
||||||
DATA = [DATA,length(fieldName{i}),fieldName{i}-0,dim1,dim2,data]; %add to array
|
|
||||||
end
|
|
||||||
|
|
||||||
%% Send Array
|
|
||||||
status = sendUDP(DATA, p.Results.IP, p.Results.port);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
function [ status ] = sendTEXT( msg, varargin )
|
function sendTEXT( msg, x, y, socket )
|
||||||
% sendTEXT Sends a string to be displayed in X-Plane.
|
% sendTEXT Sends a string to be displayed in X-Plane.
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
@@ -13,35 +13,34 @@ function [ status ] = sendTEXT( msg, varargin )
|
|||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
% 2. #Set a message to be displayed near the top middle of the screen.
|
% 2. % Set a message to be displayed near the top middle of the screen.
|
||||||
% 3. status = sendTEXT('Some text', 512, 600);
|
% 3. status = sendTEXT('Some text', 512, 600);
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% Jason Watkins
|
% Jason Watkins (jason.w.watkins@nasa.gov)
|
||||||
% jason.w.watkins@nasa.gov
|
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
|
|
||||||
import XPlaneConnect.*
|
import XPlaneConnect.*
|
||||||
%% Handle Input
|
|
||||||
p = inputParser;
|
|
||||||
addRequired(p,'msg');
|
|
||||||
addOptional(p,'x',-1,@isnumeric);
|
|
||||||
addOptional(p,'y',-1,@isnumeric);
|
|
||||||
addOptional(p,'IP','127.0.0.1',@ischar);
|
|
||||||
addOptional(p,'port',49009,@isnumeric);
|
|
||||||
parse(p,msg,varargin{:});
|
|
||||||
|
|
||||||
%% Body
|
%% Get client
|
||||||
header = ['TEXT'-0,0];
|
global clients;
|
||||||
dataStream = [header,...
|
if ~exist('socket', 'var')
|
||||||
typecast(uint32(p.Results.x), 'uint8'),...
|
assert(istrue(length(clients) < 2), '[sendCTRL] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
typecast(uint32(p.Results.y), 'uint8'),...
|
if isempty(clients)
|
||||||
uint8(length(msg)), msg-0];
|
openUDP();
|
||||||
|
end
|
||||||
% Send TEXT
|
socket = clients(1);
|
||||||
status = sendUDP(dataStream, p.Results.IP, p.Results.port);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% Validate input
|
||||||
|
if ~exist('x', 'var')
|
||||||
|
x = -1;
|
||||||
|
end
|
||||||
|
if ~exist('y', 'var')
|
||||||
|
y = -1;
|
||||||
|
end
|
||||||
|
x = int32(x);
|
||||||
|
y = int32(y);
|
||||||
|
|
||||||
|
%% Send command
|
||||||
|
socket.sendTEXT(msg, x, y);
|
||||||
|
end
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
function [ status ] = sendUDP( data, IP, port )
|
|
||||||
%sendUDP Send an one dimensional array of type uint8 data over an UDP connection using a java DatagramSocket
|
|
||||||
%
|
|
||||||
%Inputs
|
|
||||||
% Data: 1-D array of type uint8 data to be sent
|
|
||||||
% 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
|
|
||||||
%
|
|
||||||
%Outputs
|
|
||||||
% status: If there was an error. Status<0 means there was an error.
|
|
||||||
%
|
|
||||||
%Use
|
|
||||||
% 1. import XPlaneConnect.*;
|
|
||||||
% 2. data = uint8([1:20]);
|
|
||||||
% 3. #Send the data array to port 49005 on the computer at IP address 172.0.100.54.
|
|
||||||
% 4. status = sendUDP( data, '172.0.100.54', 49005 );
|
|
||||||
%
|
|
||||||
% Contributors
|
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
|
||||||
% christopher.a.teubert@nasa.gov
|
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
%BEGIN CODE
|
|
||||||
|
|
||||||
import java.net.DatagramSocket
|
|
||||||
import java.net.DatagramPacket
|
|
||||||
import java.net.InetAddress
|
|
||||||
|
|
||||||
data(5) = length(data);
|
|
||||||
status = 0;
|
|
||||||
|
|
||||||
%% Send array
|
|
||||||
persistent socket
|
|
||||||
if isempty(socket)
|
|
||||||
try
|
|
||||||
socket = DatagramSocket;
|
|
||||||
catch err
|
|
||||||
status = 1;
|
|
||||||
disp(err)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
IP = InetAddress.getByName(IP);
|
|
||||||
packet = DatagramPacket(data, length(data), IP, port); %create packet
|
|
||||||
socket.send(packet);
|
|
||||||
end
|
|
||||||
|
|
||||||
@@ -1,53 +1,43 @@
|
|||||||
function [ status ] = sendWYPT( op, points, varargin )
|
function sendWYPT( op, points, socket )
|
||||||
% sendWYPT Adds, removes, or clears a set of waypoints to be rendered in
|
% sendWYPT Adds, removes, or clears a set of waypoints to be rendered in
|
||||||
% the simulator.
|
% the simulator.
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% msg: The string to be displayed
|
% op: The operation to perform. 1=add, 2=remove, 3=clear.
|
||||||
% x (optional): The distance from the left edge of the screen to display the message.
|
% points: An array of values representing points. Each triplet in the
|
||||||
% y (optional): The distance from the bottom edge of the screen to display the message.
|
% array will be interpreted as a (Lat, Lon, Alt) point.
|
||||||
% 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)
|
% socket (optional): The client to use when sending the command.
|
||||||
% 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
|
% Use
|
||||||
% 1. import XPlaneConnect.*;
|
% 1. import XPlaneConnect.*;
|
||||||
% 2. #Set a message to be displayed near the top middle of the screen.
|
% 2. %Set a message to be displayed near the top middle of the screen.
|
||||||
% 3. status = sendTEXT('Some text', 512, 600);
|
% 3. status = sendTEXT('Some text', 512, 600);
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% Jason Watkins
|
% Jason Watkins (jason.w.watkins@nasa.gov)
|
||||||
% jason.w.watkins@nasa.gov
|
|
||||||
%
|
%
|
||||||
% To Do
|
% To Do
|
||||||
%
|
%
|
||||||
% BEGIN CODE
|
% BEGIN CODE
|
||||||
|
|
||||||
import XPlaneConnect.*
|
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
|
%% Get client
|
||||||
|
global clients;
|
||||||
|
if ~exist('socket', 'var')
|
||||||
|
assert(istrue(length(clients) < 2), '[sendCTRL] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
|
if isempty(clients)
|
||||||
|
openUDP();
|
||||||
|
end
|
||||||
|
socket = clients(1);
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Validate input
|
||||||
len = uint32(length(points));
|
len = uint32(length(points));
|
||||||
assert(op > 0 && op < 4);
|
assert(op > 0 && op < 4);
|
||||||
assert(mod(len, 3) == 0);
|
assert(mod(len, 3) == 0);
|
||||||
assert(len / 3 < 20);
|
|
||||||
|
|
||||||
%% Body
|
%% Send command
|
||||||
header = ['WYPT'-0,0];
|
socket.sendCTRL(ctrl, ac);
|
||||||
dataStream = [header,...
|
|
||||||
uint8(op),...
|
|
||||||
uint8(len / 3),...
|
|
||||||
typecast(single(points), 'uint8')];
|
|
||||||
|
|
||||||
% Send TEXT
|
|
||||||
status = sendUDP(dataStream, p.Results.IP, p.Results.port);
|
|
||||||
end
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,51 +1,35 @@
|
|||||||
function status = setConn( recvPort, IP, port )
|
function setConn(port, socket)
|
||||||
% setConn Send a command to set up the port where you will receive data on
|
% setConn Send a command to set up the port where you will receive data on
|
||||||
% this computer.
|
% this computer.
|
||||||
%
|
%
|
||||||
% Inputs
|
% Inputs
|
||||||
% Receiving Port: Port that data will be sent to in the future for this connection
|
% port: Port that data will be sent to in the future for this connection.
|
||||||
% 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)
|
% socket (optional): The client to use when sending the command.
|
||||||
% 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: If there was an error. status<0 means there was an error.
|
|
||||||
%
|
%
|
||||||
% Use
|
% Use
|
||||||
% 1. import XPlaneConnect.*
|
% 1. import XPlaneConnect.*
|
||||||
% 2. status = setConn(49011);
|
% 2. status = setConn(49011);
|
||||||
%
|
%
|
||||||
% Contributors
|
% Contributors
|
||||||
% [CT] Christopher Teubert (SGT, Inc.)
|
% Christopher Teubert (SGT, Inc.) <christopher.a.teubert@nasa.gov>
|
||||||
% christopher.a.teubert@nasa.gov
|
% Jason Watkins <jason.w.watkins@nasa.gov>
|
||||||
%
|
|
||||||
% To Do
|
|
||||||
% 1. Verify Input
|
|
||||||
%
|
|
||||||
% BEGIN CODE
|
|
||||||
import XPlaneConnect.*
|
|
||||||
|
|
||||||
status = 0;
|
import XPlaneConnect.*
|
||||||
message = zeros(1,7);
|
|
||||||
|
|
||||||
%% Handle Input
|
|
||||||
% Optional parameters
|
|
||||||
if ~exist('IP','var'), IP = '127.0.0.1'; end
|
|
||||||
if ~exist('port','var'), port = 49009; end
|
|
||||||
|
|
||||||
% Check format of input-TODO
|
%% Get client
|
||||||
|
global clients;
|
||||||
|
if ~exist('socket', 'var')
|
||||||
|
assert(istrue(length(clients) < 2), '[sendCTRL] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
|
if isempty(clients)
|
||||||
|
openUDP();
|
||||||
|
end
|
||||||
|
socket = clients(1);
|
||||||
|
end
|
||||||
|
|
||||||
%% BODY
|
%% Validate input
|
||||||
% Header
|
port = int32(port);
|
||||||
message(1:4) = 'CONN'-0;
|
|
||||||
|
%% Send command
|
||||||
% RecvPort
|
socket.setCONN(port);
|
||||||
message(6:7) = typecast(uint16(recvPort),'uint8');
|
|
||||||
|
|
||||||
% Send
|
|
||||||
sendUDP(message,IP,port);
|
|
||||||
|
|
||||||
global udpReadPort;
|
|
||||||
udpReadPort = recvPort;
|
|
||||||
readUDP(); % Read and discard CONF message
|
|
||||||
|
|
||||||
end
|
end
|
||||||
37
MATLAB/+XPlaneConnect/setDREF.m
Normal file
37
MATLAB/+XPlaneConnect/setDREF.m
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
function setDREF( dref, value, socket )
|
||||||
|
% sendDREF Sends a command to X-Plane that sets the given DREF.
|
||||||
|
%
|
||||||
|
% 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
|
||||||
|
% [JW] Jason Watkins
|
||||||
|
% jason.w.watkins@nasa.gov
|
||||||
|
|
||||||
|
import XPlaneConnect.*
|
||||||
|
|
||||||
|
%% Get client
|
||||||
|
global clients;
|
||||||
|
if ~exist('socket', 'var')
|
||||||
|
assert(istrue(length(clients) < 2), '[setDREF] ERROR: Multiple clients open. You must specify which client to use.');
|
||||||
|
if isempty(clients)
|
||||||
|
openUDP();
|
||||||
|
end
|
||||||
|
socket = clients(1);
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Validate input
|
||||||
|
value = single(value);
|
||||||
|
|
||||||
|
%%Send command
|
||||||
|
socket.setDREF(dref, value);
|
||||||
@@ -123,7 +123,7 @@ public class XPlaneConnectTest
|
|||||||
String dref = "sim/cockpit/switches/gear_handle_status";
|
String dref = "sim/cockpit/switches/gear_handle_status";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
float[] result = xpc.requestDREF(dref);
|
float[] result = xpc.getDREF(dref);
|
||||||
assertEquals(1, result.length);
|
assertEquals(1, result.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ public class XPlaneConnectTest
|
|||||||
};
|
};
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
float[][] result = xpc.requestDREFs(drefs);
|
float[][] result = xpc.getDREFs(drefs);
|
||||||
assertEquals(2, result.length);
|
assertEquals(2, result.length);
|
||||||
assertEquals(1, result[0].length);
|
assertEquals(1, result[0].length);
|
||||||
assertEquals(4, result[1].length);
|
assertEquals(4, result[1].length);
|
||||||
@@ -150,7 +150,7 @@ public class XPlaneConnectTest
|
|||||||
{
|
{
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.requestDREFs(null);
|
xpc.getDREFs(null);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ public class XPlaneConnectTest
|
|||||||
String[] drefs = new String[0];
|
String[] drefs = new String[0];
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.requestDREFs(drefs);
|
xpc.getDREFs(drefs);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ public class XPlaneConnectTest
|
|||||||
String[] drefs = new String[300];
|
String[] drefs = new String[300];
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.requestDREFs(drefs);
|
xpc.getDREFs(drefs);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ public class XPlaneConnectTest
|
|||||||
String[] drefs = new String[]{longDREF};
|
String[] drefs = new String[]{longDREF};
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.requestDREFs(drefs);
|
xpc.getDREFs(drefs);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ public class XPlaneConnectTest
|
|||||||
String dref = "";
|
String dref = "";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.requestDREF(dref);
|
xpc.getDREF(dref);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,12 +207,12 @@ public class XPlaneConnectTest
|
|||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.pauseSim(true);
|
xpc.pauseSim(true);
|
||||||
float[] result = xpc.requestDREF(dref);
|
float[] result = xpc.getDREF(dref);
|
||||||
//assertEquals(1, result.length); //TODO: Why is this result 20 elements long in Java? (It's only one in MATLAB)
|
//assertEquals(1, result.length); //TODO: Why is this result 20 elements long in Java? (It's only one in MATLAB)
|
||||||
assertEquals(1, result[0], 1e-4);
|
assertEquals(1, result[0], 1e-4);
|
||||||
|
|
||||||
xpc.pauseSim(false);
|
xpc.pauseSim(false);
|
||||||
result = xpc.requestDREF(dref);
|
result = xpc.getDREF(dref);
|
||||||
//assertEquals(1, result.length);
|
//assertEquals(1, result.length);
|
||||||
assertEquals(0, result[0], 1e-4);
|
assertEquals(0, result[0], 1e-4);
|
||||||
}
|
}
|
||||||
@@ -305,12 +305,12 @@ public class XPlaneConnectTest
|
|||||||
String dref = "sim/cockpit/switches/gear_handle_status";
|
String dref = "sim/cockpit/switches/gear_handle_status";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
float gearHandle = xpc.requestDREF(dref)[0];
|
float gearHandle = xpc.getDREF(dref)[0];
|
||||||
|
|
||||||
float value = gearHandle > 0.5 ? 0 : 1;
|
float value = gearHandle > 0.5 ? 0 : 1;
|
||||||
xpc.sendDREF(dref, value);
|
xpc.setDREF(dref, value);
|
||||||
|
|
||||||
float result = xpc.requestDREF(dref)[0];
|
float result = xpc.getDREF(dref)[0];
|
||||||
assertEquals(value, result, 1e-4);
|
assertEquals(value, result, 1e-4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,7 @@ public class XPlaneConnectTest
|
|||||||
{
|
{
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDREF(null, 0);
|
xpc.setDREF(null, 0);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,7 +332,7 @@ public class XPlaneConnectTest
|
|||||||
|
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDREF(dref, null);
|
xpc.setDREF(dref, null);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ public class XPlaneConnectTest
|
|||||||
String dref = "sim/cockpit/switches/gear_handle_status";
|
String dref = "sim/cockpit/switches/gear_handle_status";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDREF(dref, new float[0]);
|
xpc.setDREF(dref, new float[0]);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ public class XPlaneConnectTest
|
|||||||
String dref = "sim/cockpit/switches/gear_handle_status";
|
String dref = "sim/cockpit/switches/gear_handle_status";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDREF(dref, new float[200]);
|
xpc.setDREF(dref, new float[200]);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -365,7 +365,7 @@ public class XPlaneConnectTest
|
|||||||
String dref = "sim/cockpit/switches/i/am/a/very/long/fake/dref/that/is/over/255/characters/./which/means/that/my/length/cant/be/encoded/in/the/single/byte/allocated/by/the/message/format/,/so/i/should/cause/an/exception/instead/./i/am/still/not/long/enough/./almost/there";
|
String dref = "sim/cockpit/switches/i/am/a/very/long/fake/dref/that/is/over/255/characters/./which/means/that/my/length/cant/be/encoded/in/the/single/byte/allocated/by/the/message/format/,/so/i/should/cause/an/exception/instead/./i/am/still/not/long/enough/./almost/there";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDREF(dref, 0);
|
xpc.setDREF(dref, 0);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,7 +376,7 @@ public class XPlaneConnectTest
|
|||||||
String dref = "";
|
String dref = "";
|
||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDREF(dref, 0);
|
xpc.setDREF(dref, 0);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +396,7 @@ public class XPlaneConnectTest
|
|||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendCTRL(ctrl);
|
xpc.sendCTRL(ctrl);
|
||||||
float[][] result = xpc.requestDREFs(drefs);
|
float[][] result = xpc.getDREFs(drefs);
|
||||||
if(result.length < ctrl.length)
|
if(result.length < ctrl.length)
|
||||||
{
|
{
|
||||||
fail();
|
fail();
|
||||||
@@ -425,8 +425,8 @@ public class XPlaneConnectTest
|
|||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendCTRL(ctrl, 1);
|
xpc.sendCTRL(ctrl, 1);
|
||||||
float[][] result1 = xpc.requestDREFs(drefs1);
|
float[][] result1 = xpc.getDREFs(drefs1);
|
||||||
float[][] result2 = xpc.requestDREFs(drefs2);
|
float[][] result2 = xpc.getDREFs(drefs2);
|
||||||
if(result1.length != 4 || result2.length != 2)
|
if(result1.length != 4 || result2.length != 2)
|
||||||
{
|
{
|
||||||
fail();
|
fail();
|
||||||
@@ -480,7 +480,7 @@ public class XPlaneConnectTest
|
|||||||
xpc.sendPOSI(posi);
|
xpc.sendPOSI(posi);
|
||||||
//TODO: It seems that these calls are a bit too fast. The dref request often gets stale data, causing the test to fail incorrectly.
|
//TODO: It seems that these calls are a bit too fast. The dref request often gets stale data, causing the test to fail incorrectly.
|
||||||
try {Thread.sleep(100);}catch(InterruptedException ex){}
|
try {Thread.sleep(100);}catch(InterruptedException ex){}
|
||||||
float[][] result = xpc.requestDREFs(drefs);
|
float[][] result = xpc.getDREFs(drefs);
|
||||||
xpc.pauseSim(false);
|
xpc.pauseSim(false);
|
||||||
if(result.length < posi.length)
|
if(result.length < posi.length)
|
||||||
{
|
{
|
||||||
@@ -543,7 +543,7 @@ public class XPlaneConnectTest
|
|||||||
try(XPlaneConnect xpc = new XPlaneConnect())
|
try(XPlaneConnect xpc = new XPlaneConnect())
|
||||||
{
|
{
|
||||||
xpc.sendDATA(data);
|
xpc.sendDATA(data);
|
||||||
float[] result = xpc.requestDREF(dref);
|
float[] result = xpc.getDREF(dref);
|
||||||
assertEquals(data[0][1], result[0], 1e-4);
|
assertEquals(data[0][1], result[0], 1e-4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,7 +577,7 @@ public class XPlaneConnectTest
|
|||||||
{
|
{
|
||||||
xpc.setCONN(49055);
|
xpc.setCONN(49055);
|
||||||
assertEquals(49055, xpc.getRecvPort());
|
assertEquals(49055, xpc.getRecvPort());
|
||||||
float[] result = xpc.requestDREF(dref);
|
float[] result = xpc.getDREF(dref);
|
||||||
assertEquals(1, result.length);
|
assertEquals(1, result.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user