Merge pull request #78 from nasa/release-1.2.0

Release 1.2.0
This commit is contained in:
Christopher Teubert
2015-08-27 13:34:52 -07:00
69 changed files with 1929 additions and 69 deletions

101
C/monitorExample/main.c Normal file
View File

@@ -0,0 +1,101 @@
// Copyright (c) 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.
#include "../src/xplaneConnect.h"
#include <sys/time.h>
#include "stdio.h"
#ifdef WIN32
HANDLE hStdIn = NULL;
INPUT_RECORD buffer;
int waitForInput()
{
if (hStdIn == NULL)
{
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
}
FlushConsoleInputBuffer(hStdIn);
DWORD result = WaitForSingleObject(hStdIn, 100);
if (result == WAIT_OBJECT_0)
{
DWORD eventsRead;
PeekConsoleInput(hStdIn, &buffer, 1, &eventsRead);
if (eventsRead > 0)
{
return buffer.EventType == KEY_EVENT;
}
}
return FALSE;
}
#else
int fdstdin = 0;
fd_set fds;
struct timeval tv;
int waitForInput()
{
FD_ZERO(&fds);
FD_SET(fdstdin, &fds);
select(1, &fds, NULL, NULL, &tv);
return FD_ISSET(fdstdin, &fds);
}
#endif
int main(void)
{
XPCSocket client = openUDP("127.0.0.1");
const int aircraftNum = 0;
tv.tv_usec = 100 * 1000;
while (1)
{
float posi[7];
int result = getPOSI(client, posi, aircraftNum);
if (result < 0) // Error in getPOSI
{
break;
}
float ctrl[7];
result = getCTRL(client, ctrl, aircraftNum);
if (result < 0) // Error in getCTRL
{
break;
}
printf("Loc: (%4f, %4f, %4f) Aileron:%2f Elevator:%2f Rudder:%2f\n",
posi[0], posi[1], posi[2], ctrl[1], ctrl[0], ctrl[2]);
// Check if any key has been pressed and break
if (waitForInput())
{
break;
}
}
printf("\n\nPress Any Key to exit...");
getchar();
return 0;
}

View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "monitorExample", "monitorExample.vcxproj", "{0F45204B-6910-46C7-BECD-273985390F75}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0F45204B-6910-46C7-BECD-273985390F75}.Debug|Win32.ActiveCfg = Debug|Win32
{0F45204B-6910-46C7-BECD-273985390F75}.Debug|Win32.Build.0 = Debug|Win32
{0F45204B-6910-46C7-BECD-273985390F75}.Release|Win32.ActiveCfg = Release|Win32
{0F45204B-6910-46C7-BECD-273985390F75}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0F45204B-6910-46C7-BECD-273985390F75}</ProjectGuid>
<RootNamespace>monitorExample</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>../src;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>../src;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\xplaneConnect.c" />
<ClCompile Include="main.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\xplaneConnect.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,71 @@
//Copyright (c) 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.
#include "chrome.h"
#include <stdio.h>
void displayStart(char* version)
{
printf("X-Plane Connect Playback Example [Version %s]\n", version);
printf("(c) 2013-2015 United States Government as represented by the Administrator\n");
printf("of the National Aeronautics and Space Administration. All Rights Reserved.\n");
}
int displayMenu(char* title, char* opts[], size_t count)
{
printf("\n");
printf("+---------------------------------------------- +\n");
printf("| %-42s |\n", title);
printf("+---------------------------------------------- +\n");
for (size_t i = 0; i < count; i++)
{
printf("| %2u. %-40s |\n", i + 1, opts[i]);
}
printf("+---------------------------------------------- +\n");
printf("Please select an option: ");
int opt;
scanf("%d", &opt);
return opt;
}
void displayMsg(char* msg)
{
printf("%s\n", msg);
}
void getString(char* prompt, char buffer[255])
{
printf("%s: ", prompt);
scanf("%255s", buffer);
}
int getInt(char* prompt)
{
printf("%s: ", prompt);
int result;
scanf("%d", &result);
return result;
}

View File

@@ -0,0 +1,40 @@
//Copyright (c) 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.
#ifndef XPC_PLAYBACKEX_CHROME_H_
#define XPC_PLAYBACKEX_CHROME_H_
#include <stdlib.h>
void displayStart(char* version);
int displayMenu(char* title, char* opts[], size_t count);
void displayMsg(char* msg);
void getString(char* prompt, char buffer[255]);
int getInt(char* prompt);
#endif

View File

@@ -0,0 +1,70 @@
//Copyright (c) 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.
#include "chrome.h"
#include "playback.h"
int main(void)
{
char* mainOpts[3] =
{
"Record X-Plane",
"Playback File",
"Exit"
};
char path[256] = { 0 };
displayStart("1.2.0.0");
while (1)
{
switch (displayMenu("What would you like to do?", mainOpts, 3))
{
case 1:
{
getString("Enter save file path", path);
int interval = getInt("Enter interval between frames (milliseconds)");
int duration = getInt("Enter duration to record for (seconds)");
record(path, interval, duration);
break;
}
case 2:
{
getString("Enter path to saved playback file", path);
int interval = getInt("Enter interval between frames (milliseconds)");
playback(path, interval);
break;
}
case 3:
displayMsg("Exiting.");
return 0;
default:
displayMsg("Unrecognized option.");
break;
}
}
return 0;
}

View File

@@ -0,0 +1,106 @@
//Copyright (c) 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.
#include "playback.h"
#include "chrome.h"
#include "xplaneConnect.h"
#include <stdio.h>
#include <time.h>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
void playbackSleep(int ms)
{
#ifdef WIN32
Sleep(ms);
#else
usleep(ms * 1000);
#endif
}
void record(char* path, int interval, int duration)
{
FILE* fd = fopen(path, "w");
int count = duration * 1000 / interval;
if (!fd)
{
displayMsg("Unable to open output file.");
return;
}
if (count < 1)
{
displayMsg("Duration is less than one iteration.");
return;
}
displayMsg("Recording...");
XPCSocket sock = openUDP("127.0.0.1");
for (int i = 0; i < count; ++i)
{
float posi[7];
int result = getPOSI(sock, posi, 0);
playbackSleep(interval);
if (result < 0)
{
continue;
}
fprintf(fd, "%f, %f, %f, %f, %f, %f, %f\n", posi[0], posi[1], posi[2], posi[3], posi[4], posi[5], posi[6]);
}
closeUDP(sock);
displayMsg("Recording Complete");
}
void playback(char* path, int interval)
{
FILE* fd = fopen(path, "r");
if (!fd)
{
displayMsg("Unable to open output file.");
return;
}
displayMsg("Starting Playback...");
XPCSocket sock = openUDP("127.0.0.1");
float posi[7];
while (!feof(fd) && !ferror(fd))
{
int result = fscanf(fd, "%f, %f, %f, %f, %f, %f, %f\n",
&posi[0], &posi[1], &posi[2], &posi[3], &posi[4], &posi[5], &posi[6]);
playbackSleep(interval);
if (result != 7)
{
continue;
}
sendPOSI(sock, posi, 7, 0);
}
closeUDP(sock);
displayMsg("Playback Complete");
}

View 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.
//
//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.
#ifndef XPC_PLAYBACKEX_PLAYBACK_H_
#define XPC_PLAYBACKEX_PLAYBACK_H_
void record(char* path, int interval, int duration);
void playback(char* path, int interval);
#endif

View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playbackExample", "playbackExample.vcxproj", "{40781C32-3EE6-4B3C-A94F-E128BD41E21C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{40781C32-3EE6-4B3C-A94F-E128BD41E21C}.Debug|Win32.ActiveCfg = Debug|Win32
{40781C32-3EE6-4B3C-A94F-E128BD41E21C}.Debug|Win32.Build.0 = Debug|Win32
{40781C32-3EE6-4B3C-A94F-E128BD41E21C}.Release|Win32.ActiveCfg = Release|Win32
{40781C32-3EE6-4B3C-A94F-E128BD41E21C}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{40781C32-3EE6-4B3C-A94F-E128BD41E21C}</ProjectGuid>
<RootNamespace>playbackExample</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>../../src;../src;$(IncludePath)</IncludePath>
<SourcePath>../../src;../src;$(SourcePath)</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>../../src;../src;$(IncludePath)</IncludePath>
<SourcePath>../../src;../src;$(SourcePath)</SourcePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="../src/chrome.h" />
<ClInclude Include="../src/playback.h" />
<ClInclude Include="..\..\src\xplaneConnect.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="../src/chrome.c" />
<ClCompile Include="../src/main.c" />
<ClCompile Include="../src/playback.c" />
<ClCompile Include="..\..\src\xplaneConnect.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="../src/chrome.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="../src/playback.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\xplaneConnect.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="../src/chrome.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="../src/main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="../src/playback.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\xplaneConnect.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -116,7 +116,7 @@ XPCSocket aopenUDP(const char *xpIP, unsigned short xpPort, unsigned short port)
#else
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
timeout.tv_usec = 250000;
#endif
if (setsockopt(sock.sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0)
{
@@ -521,6 +521,38 @@ int getDREFs(XPCSocket sock, const char* drefs[], float* values[], unsigned char
/*****************************************************************************/
/**** POSI functions ****/
/*****************************************************************************/
int getPOSI(XPCSocket sock, float values[7], char ac)
{
// Setup send command
unsigned char buffer[6] = "GETP";
buffer[5] = ac;
// Send command
if (sendUDP(sock, buffer, 6) < 0)
{
printError("getPOSI", "Failed to send command.");
return -1;
}
// Get response
unsigned char readBuffer[34];
int readResult = readUDP(sock, readBuffer, 34);
if (readResult < 0)
{
printError("getPOSI", "Failed to read response.");
return -2;
}
if (readResult != 34)
{
printError("getPOSI", "Unexpected response length.");
return -3;
}
// Copy response into values
memcpy(values, readBuffer + 6, 7 * sizeof(float));
return 0;
}
int sendPOSI(XPCSocket sock, float values[], int size, char ac)
{
// Validate input
@@ -565,6 +597,41 @@ int sendPOSI(XPCSocket sock, float values[], int size, char ac)
/*****************************************************************************/
/**** CTRL functions ****/
/*****************************************************************************/
int getCTRL(XPCSocket sock, float values[7], char ac)
{
// Setup send command
unsigned char buffer[6] = "GETC";
buffer[5] = ac;
// Send command
if (sendUDP(sock, buffer, 6) < 0)
{
printError("getCTRL", "Failed to send command.");
return -1;
}
// Get response
unsigned char readBuffer[31];
int readResult = readUDP(sock, readBuffer, 31);
if (readResult < 0)
{
printError("getCTRL", "Failed to read response.");
return -2;
}
if (readResult != 31)
{
printError("getCTRL", "Unexpected response length.");
return -3;
}
// Copy response into values
memcpy(values, readBuffer + 5, 4 * sizeof(float));
values[4] = readBuffer[21];
values[5] = *((float*)(readBuffer + 22));
values[6] = *((float*)(readBuffer + 27));
return 0;
}
int sendCTRL(XPCSocket sock, float values[], int size, char ac)
{
// Validate input

View File

@@ -196,6 +196,14 @@ int getDREFs(XPCSocket sock, const char* drefs[], float* values[], unsigned char
// Position
/// Gets the position and orientation of the specified aircraft.
///
/// \param sock The socket used to send the command and receive the response.
/// \param values An array to store the position information returned by the
/// plugin. The format of values is [Lat, Lon, Alt, Pitch, Roll, Yaw, Gear]
/// \returns 0 if successful, otherwise a negative value.
int getPOSI(XPCSocket sock, float values[7], char ac);
/// Sets the position and orientation of the specified aircraft.
///
/// \param sock The socket to use to send the command.
@@ -209,6 +217,16 @@ int sendPOSI(XPCSocket sock, float values[], int size, char ac);
// Controls
/// Gets the control surface information for the specified aircraft.
///
/// \param sock The socket used to send the command and receive the response.
/// \param values An array to store the position information returned by the
/// plugin. The format of values is [Elevator, Aileron, Rudder,
/// Throttle, Gear, Flaps, Speed Brakes]
/// \param ac The aircraft to set the control surfaces of. 0 is the main/player aircraft.
/// \returns 0 if successful, otherwise a negative value.
int getCTRL(XPCSocket sock, float values[7], char ac);
/// Sets the control surfaces of the specified aircraft.
///
/// \param sock The socket to use to send the command.

View File

@@ -0,0 +1 @@
ContinuousOperation

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@@ -0,0 +1,3 @@
<component name="CopyrightManager">
<settings default="" />
</component>

View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="XPlaneConnect">
<CLASSES>
<root url="jar://$PROJECT_DIR$/libs/XPlaneConnect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/ContinuousOperation.iml" filepath="$PROJECT_DIR$/ContinuousOperation.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="XPlaneConnect" level="project" />
</component>
</module>

View File

@@ -0,0 +1,47 @@
package gov.nasa.xpc.ex;
import gov.nasa.xpc.XPlaneConnect;
import java.io.IOException;
/**
* An example program demonstrating the use of X-PlaneConnect in a continuous loop.
*
* @author Jason Watkins
* @version 1.0
* @since 2015-06-19
*/
public class Main
{
public static void main(String[] args)
{
try (XPlaneConnect xpc = new XPlaneConnect())
{
int aircraft = 0;
while(true)
{
float[] posi = xpc.getPOSI(aircraft);
float[] ctrl = xpc.getCTRL(aircraft);
System.out.format("Loc: (%4f, %4f, %4f) Aileron:%2f Elevator:%2f Rudder:%2f\n",
posi[0], posi[1], posi[2], ctrl[1], ctrl[0], ctrl[2]);
try
{
Thread.sleep(100);
}
catch (InterruptedException ex) {}
if(System.in.available() > 0)
{
break;
}
}
}
catch(IOException ex)
{
System.out.println("Error:");
System.out.println(ex.getMessage());
}
}
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@@ -0,0 +1,3 @@
<component name="CopyrightManager">
<settings default="" />
</component>

View File

@@ -0,0 +1 @@
<html>Simple <b>Java</b> application that includes a class with <code>main()</code> method</html>

View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="XPlaneConnect">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../../out/artifacts/XPlaneConnect_jar/XPlaneConnect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

12
Java/Examples/Playback/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectKey">
<option name="state" value="project://e2804f05-5315-4fc6-a121-c522a6c26470" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Playback.iml" filepath="$PROJECT_DIR$/Playback.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,3 @@
<template>
<input-field default="com.company">IJ_BASE_PACKAGE</input-field>
</template>

6
Java/Examples/Playback/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="XPlaneConnect" level="project" />
</component>
</module>

View File

@@ -0,0 +1,147 @@
package gov.nasa.xpc;
import com.sun.javafx.scene.EnteredExitedHandler;
import java.io.*;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws IOException
{
String[] mainOpts = new String[] { "Record X-Plane", "Playback File", "Exit" };
System.out.println("X-Plane Connect Playback Example [Version 1.2.0.0]");
System.out.println("(c) 2013-2015 United States Government as represented by the Administrator");
System.out.println("of the National Aeronautics and Space Administration. All Rights Reserved.");
while(true)
{
int result = displayMenu("What would you like to do?", mainOpts);
switch(result)
{
case 1:
{
String path = getString("Enter a save file path: ");
int interval = getInt("Enter interval between frames (milliseconds): ");
int duration = getInt("Enter duration to record for (seconds): ");
record(path, interval, duration);
break;
}
case 2:
{
String path = getString("Enter path to saved playback file: ");
int interval = getInt("Enter interval between frames (milliseconds): ");
playback(path, interval);
break;
}
case 3:
{
System.out.println("Exiting.");
return;
}
default:
{
System.out.println("Unrecognized menu option.");
break;
}
}
}
}
private static int displayMenu(String title, String[] opts) throws IOException
{
System.out.println();
System.out.println("+---------------------------------------------- +");
System.out.println(String.format("| %1$-42s |", title));
System.out.println("+---------------------------------------------- +");
for(int i = 0; i < opts.length; ++i)
{
System.out.println(String.format("| %1$2d. %2$-40s |", i + 1, opts[i]));
}
System.out.println("+---------------------------------------------- +");
return getInt("Please select an option: ");
}
private static String getString(String prompt) throws IOException
{
System.out.print(prompt);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
}
private static int getInt(String prompt) throws IOException
{
System.out.print(prompt);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String result = reader.readLine();
return Integer.parseInt(result);
}
public static void record(String path, int interval, int duration) throws IOException
{
int count = duration * 1000 / interval;
if (count < 1)
{
throw new IllegalArgumentException("duration is less than one interval.");
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(path)))
{
System.out.println("Recording...");
try (XPlaneConnect xpc = new XPlaneConnect())
{
for (int i = 0; i < count; ++i)
{
float[] posi = xpc.getPOSI(0);
writer.write(String.format("%1$f, %2$f, %3$f, %4$f, %5$f, %6$f, %7$f\n",
posi[0], posi[1], posi[2], posi[3], posi[4], posi[5], posi[6]));
try
{
Thread.sleep(interval);
}
catch (InterruptedException ex)
{
}
}
}
System.out.println("Recording Complete");
}
}
public static void playback(String path, int interval) throws IOException
{
try(Scanner reader = new Scanner(new FileReader(path)))
{
reader.useDelimiter("[\\s\\r\\n,]+");
System.out.println("Starting playback...");
try (XPlaneConnect xpc = new XPlaneConnect())
{
while(reader.hasNextLine())
{
float[] posi = new float[7];
for (int i = 0; i < 7; ++i)
{
String s = reader.next();
posi[i] = Float.parseFloat(s);
}
reader.nextLine();
xpc.sendPOSI(posi);
try
{
Thread.sleep(interval);
}
catch (InterruptedException ex)
{
}
}
}
}
}
}

View File

@@ -398,6 +398,47 @@ public class XPlaneConnect implements AutoCloseable
sendUDP(os.toByteArray());
}
/**
* Gets the control surface information for the specified airplane.
*
* @param ac The aircraft to get control surface information for.
* @return An array containing control surface data in the same format as {@code sendCTRL}.
* @throws IOException If the command cannot be sent or a response cannot be read.
*/
public float[] getCTRL(int ac) throws IOException
{
// Send request
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write("GETC".getBytes(StandardCharsets.UTF_8));
os.write(0xFF); //Placeholder for message length
os.write(ac);
sendUDP(os.toByteArray());
// Read response
byte[] data = readUDP();
if(data.length == 0)
{
throw new IOException("No response received.");
}
if(data.length < 31)
{
throw new IOException("Response too short");
}
// Parse response
float[] result = new float[7];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.order(ByteOrder.LITTLE_ENDIAN);
result[0] = bb.getFloat(5);
result[1] = bb.getFloat(9);
result[2] = bb.getFloat(13);
result[3] = bb.getFloat(17);
result[4] = bb.get(21);
result[5] = bb.getFloat(22);
result[6] = bb.getFloat(27);
return result;
}
/**
* Sends command to X-Plane setting control surfaces on the player ac.
*
@@ -409,6 +450,7 @@ public class XPlaneConnect implements AutoCloseable
* <li>Throttle [-1, 1]</li>
* <li>Gear (0=up, 1=down)</li>
* <li>Flaps [0, 1]</li>
* <li>Speedbrakes [-0.5, 1.5]</li>
* </ol>
* <p>
* If @{code ctrl} is less than 6 elements long, The missing elements will not be changed. To
@@ -433,6 +475,7 @@ public class XPlaneConnect implements AutoCloseable
* <li>Throttle [-1, 1]</li>
* <li>Gear (0=up, 1=down)</li>
* <li>Flaps [0, 1]</li>
* <li>Speedbrakes [-0.5, 1.5]</li>
* </ol>
* <p>
* If @{code ctrl} is less than 6 elements long, The missing elements will not be changed. To
@@ -499,6 +542,44 @@ public class XPlaneConnect implements AutoCloseable
sendUDP(os.toByteArray());
}
/**
* Gets position information for the specified airplane.
*
* @param ac The aircraft to get position information for.
* @return An array containing control surface data in the same format as {@code sendPOSI}.
* @throws IOException If the command cannot be sent or a response cannot be read.
*/
public float[] getPOSI(int ac) throws IOException
{
// Send request
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write("GETP".getBytes(StandardCharsets.UTF_8));
os.write(0xFF); //Placeholder for message length
os.write(ac);
sendUDP(os.toByteArray());
// Read response
byte[] data = readUDP();
if(data.length == 0)
{
throw new IOException("No response received.");
}
if(data.length < 34)
{
throw new IOException("Response too short");
}
// Parse response
float[] result = new float[7];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.order(ByteOrder.LITTLE_ENDIAN);
for(int i = 0; i < 7; ++i)
{
result[i] = bb.getFloat(6 + 4 * i);
}
return result;
}
/**
* Sets the position of the player ac.
*

View File

@@ -0,0 +1,29 @@
function ctrl = getCTRL(ac, socket)
% getCTRL Gets control surface information for the specified aircraft
%
% Inputs
% ac: The aircraft number to get control surface data for.
% Outputs
% posi: An array of values matching the the format used by sendCTRL
import XPlaneConnect.*
%% Get client
global clients;
if ~exist('socket', 'var')
assert(isequal(length(clients) < 2, 1), '[getCTRL] ERROR: Multiple clients open. You must specify which client to use.');
if isempty(clients)
socket = openUDP();
else
socket = clients(1);
end
end
%% Validate input
ac = int32(ac);
%% Send command
ctrl = socket.getCTRL(ac);
end

View File

@@ -0,0 +1,29 @@
function posi = getPOSI(ac, socket)
% getPOSI Gets position information for the specified aircraft
%
% Inputs
% ac: The aircraft number to get position data for.
% Outputs
% posi: An array of values matching the the format used by sendPOSI
import XPlaneConnect.*
%% Get client
global clients;
if ~exist('socket', 'var')
assert(isequal(length(clients) < 2, 1), '[getPOSI] ERROR: Multiple clients open. You must specify which client to use.');
if isempty(clients)
socket = openUDP();
else
socket = clients(1);
end
end
%% Validate input
ac = int32(ac);
%% Send command
posi = socket.getPOSI(ac);
end

View File

@@ -0,0 +1,19 @@
%% X-Plane Connect MATLAB Example Script
% This script demonstrates how to read and write data to the XPC plugin.
% Before running this script, ensure that the XPC plugin is installed and
% X-Plane is running.
%% Import XPC
clear all
addpath('../')
import XPlaneConnect.*
Socket = openUDP();
while 1
posi = getPOSI(0, Socket);
ctrl = getCTRL(0, Socket);
fprintf('Loc: (%4f, %4f, %4f) Aileron:%2f Elevator:%2f Rudder:%2f\n', ...
posi(1), posi(2), posi(3), ctrl(2), ctrl(1), ctrl(3));
pause(0.1);
end
closeUDP(Socket);

View File

@@ -0,0 +1,100 @@
37.184181, -120.793640, 3904.040771, 1.856917, 0.001644, 116.058609, 0.000000
37.184143, -120.793541, 3903.825928, 2.172139, -0.034512, 115.875587, 0.000000
37.184090, -120.793404, 3903.511719, 2.425995, -0.111958, 115.577911, 0.000000
37.184040, -120.793282, 3903.230225, 2.497653, -0.205506, 115.289268, 0.000000
37.183994, -120.793167, 3902.961914, 2.478850, -0.315117, 115.006279, 0.000000
37.183949, -120.793053, 3902.683838, 2.412536, -0.447890, 114.716370, 0.000000
37.183910, -120.792953, 3902.452881, 2.344441, -0.570747, 114.485756, 0.000000
37.183857, -120.792824, 3902.137939, 2.253826, -0.752984, 114.194984, 0.000000
37.183807, -120.792702, 3901.830566, 2.178489, -0.942979, 113.943779, 0.000000
37.183765, -120.792595, 3901.561279, 2.125190, -1.116157, 113.754135, 0.000000
37.183735, -120.792511, 3901.342773, 2.089507, -1.260052, 113.621834, 0.000000
37.183693, -120.792404, 3901.058350, 2.051378, -1.449701, 113.479713, 0.000000
37.183628, -120.792244, 3900.620361, 2.004393, -1.742637, 113.320374, 0.000000
37.183571, -120.792107, 3900.232178, 1.969860, -1.999084, 113.234406, 0.000000
37.183529, -120.791992, 3899.922852, 1.945357, -2.199157, 113.199463, 0.000000
37.183487, -120.791885, 3899.607666, 1.922479, -2.397843, 113.190887, 0.000000
37.183441, -120.791771, 3899.279297, 1.738008, -2.604320, 113.214371, 0.000000
37.183395, -120.791649, 3898.942383, 1.172052, -2.819112, 113.280800, 0.000000
37.183342, -120.791512, 3898.525879, 0.437769, -3.059577, 113.392952, 0.000000
37.183292, -120.791389, 3898.116943, -0.110597, -3.260861, 113.510010, 0.000000
37.183247, -120.791275, 3897.675293, -0.458939, -3.399007, 113.635101, 0.000000
37.183220, -120.791206, 3897.409668, -0.495934, -3.425584, 113.706985, 0.000000
37.183182, -120.791107, 3896.976318, -0.338542, -3.312644, 113.832870, 0.000000
37.183128, -120.790962, 3896.313965, 0.088305, -2.812056, 114.069130, 0.000000
37.183083, -120.790848, 3895.734863, 0.355302, -2.143086, 114.327766, 0.000000
37.183033, -120.790718, 3895.112061, 0.345563, -1.171917, 114.668144, 0.000000
37.182987, -120.790604, 3894.519043, 0.034761, -0.025642, 115.037415, 0.000000
37.182941, -120.790489, 3893.926270, -0.549108, 1.265883, 115.421654, 0.000000
37.182888, -120.790344, 3893.151611, -1.627703, 3.039703, 115.896240, 0.000000
37.182831, -120.790199, 3892.313477, -2.879907, 4.868656, 116.325722, 0.000000
37.182785, -120.790077, 3891.557129, -3.883288, 6.350969, 116.633751, 0.000000
37.182743, -120.789970, 3890.766602, -4.752331, 7.729563, 116.888329, 0.000000
37.182705, -120.789871, 3889.997314, -5.439554, 8.871016, 117.077042, 0.000000
37.182659, -120.789749, 3888.965820, -6.164141, 10.014505, 117.239494, 0.000000
37.182610, -120.789627, 3887.832031, -6.734039, 10.811956, 117.319382, 0.000000
37.182560, -120.789505, 3886.558594, -7.134449, 11.245357, 117.313339, 0.000000
37.182514, -120.789383, 3885.197510, -7.320403, 11.326477, 117.228592, 0.000000
37.182465, -120.789261, 3883.700439, -7.264509, 11.086659, 117.071564, 0.000000
37.182415, -120.789131, 3882.124023, -7.020517, 10.579235, 116.843575, 0.000000
37.182365, -120.789009, 3880.477295, -6.698184, 9.864036, 116.538239, 0.000000
37.182316, -120.788887, 3878.771973, -6.407937, 8.986709, 116.154274, 0.000000
37.182266, -120.788765, 3877.028076, -6.217397, 7.992366, 115.705994, 0.000000
37.182217, -120.788643, 3875.249023, -6.173934, 6.988136, 115.220467, 0.000000
37.182167, -120.788521, 3873.432617, -6.285208, 6.050294, 114.729034, 0.000000
37.182117, -120.788399, 3871.583496, -6.453388, 5.213163, 114.269440, 0.000000
37.182068, -120.788269, 3869.689209, -6.484870, 4.480176, 113.873062, 0.000000
37.182014, -120.788147, 3867.766357, -6.310386, 3.856612, 113.555290, 0.000000
37.181965, -120.788025, 3865.820801, -6.021461, 3.327790, 113.311180, 0.000000
37.181915, -120.787903, 3863.870361, -5.728759, 2.874094, 113.135651, 0.000000
37.181866, -120.787781, 3861.910156, -5.480271, 2.475115, 113.025513, 0.000000
37.181816, -120.787651, 3859.973145, -5.302026, 2.122235, 112.979225, 0.000000
37.181767, -120.787529, 3858.042969, -5.182843, 1.808723, 112.993736, 0.000000
37.181717, -120.787407, 3856.119629, -5.038956, 1.552066, 113.070557, 0.000000
37.181667, -120.787285, 3854.215088, -4.828547, 1.368155, 113.206085, 0.000000
37.181614, -120.787148, 3852.185059, -4.515563, 1.254129, 113.410904, 0.000000
37.181557, -120.787010, 3850.030762, -4.132499, 1.210060, 113.681358, 0.000000
37.181507, -120.786888, 3848.263916, -3.831450, 1.225745, 113.935280, 0.000000
37.181458, -120.786766, 3846.475342, -3.528734, 1.284648, 114.214294, 0.000000
37.181408, -120.786644, 3844.712158, -3.243377, 1.382594, 114.502975, 0.000000
37.181358, -120.786522, 3842.987549, -2.982575, 1.515415, 114.790489, 0.000000
37.181309, -120.786392, 3841.302246, -2.688687, 1.679037, 115.070442, 0.000000
37.181259, -120.786270, 3839.659424, -2.305070, 1.869125, 115.338135, 0.000000
37.181210, -120.786148, 3838.070068, -1.827937, 2.080883, 115.588036, 0.000000
37.181156, -120.786018, 3836.515137, -1.326015, 2.315055, 115.817902, 0.000000
37.181107, -120.785889, 3835.020508, -0.858468, 2.566000, 116.019691, 0.000000
37.181053, -120.785767, 3833.605713, -0.446646, 2.827466, 116.188957, 0.000000
37.181004, -120.785637, 3832.263672, -0.082390, 3.097450, 116.326546, 0.000000
37.180950, -120.785515, 3830.996094, 0.248427, 3.372406, 116.433670, 0.000000
37.180901, -120.785385, 3829.802734, 0.561189, 3.648955, 116.513596, 0.000000
37.180847, -120.785263, 3828.686279, 0.901348, 3.909596, 116.570610, 0.000000
37.180798, -120.785133, 3827.642090, 1.422296, 4.101938, 116.610832, 0.000000
37.180744, -120.785011, 3826.675537, 2.124010, 4.216800, 116.636208, 0.000000
37.180691, -120.784889, 3825.800049, 2.895841, 4.268193, 116.644135, 0.000000
37.180641, -120.784767, 3825.024658, 3.647615, 4.264566, 116.632553, 0.000000
37.180588, -120.784637, 3824.355469, 4.389325, 4.198403, 116.604164, 0.000000
37.180538, -120.784523, 3823.797119, 5.116096, 4.063403, 116.559959, 0.000000
37.180489, -120.784401, 3823.351562, 5.802851, 3.858843, 116.500069, 0.000000
37.180435, -120.784279, 3823.021240, 6.434232, 3.583184, 116.425621, 0.000000
37.180386, -120.784164, 3822.803223, 7.040646, 3.237821, 116.340439, 0.000000
37.180336, -120.784042, 3822.697021, 7.629384, 2.839028, 116.249237, 0.000000
37.180286, -120.783928, 3822.700195, 8.181519, 2.404881, 116.155312, 0.000000
37.180244, -120.783821, 3822.798828, 8.596326, 1.981372, 116.066658, 0.000000
37.180183, -120.783684, 3823.074219, 9.020256, 1.372200, 115.947289, 0.000000
37.180126, -120.783554, 3823.453369, 9.331639, 0.798377, 115.847244, 0.000000
37.180073, -120.783424, 3823.932129, 9.642418, 0.224538, 115.759720, 0.000000
37.180019, -120.783302, 3824.521729, 9.962214, -0.365530, 115.680557, 0.000000
37.179970, -120.783188, 3825.146240, 10.216949, -0.901261, 115.617035, 0.000000
37.179928, -120.783081, 3825.777100, 10.420901, -1.378152, 115.566948, 0.000000
37.179871, -120.782951, 3826.665283, 10.683296, -1.973540, 115.510689, 0.000000
37.179817, -120.782829, 3827.599854, 10.932059, -2.526971, 115.463028, 0.000000
37.179764, -120.782700, 3828.676758, 11.182608, -3.091355, 115.418022, 0.000000
37.179710, -120.782570, 3829.791748, 11.405788, -3.608584, 115.379250, 0.000000
37.179657, -120.782448, 3830.954102, 11.541166, -4.084742, 115.349564, 0.000000
37.179604, -120.782326, 3832.230469, 11.431418, -4.526593, 115.343117, 0.000000
37.179554, -120.782204, 3833.525391, 11.053594, -4.891589, 115.367775, 0.000000
37.179501, -120.782082, 3834.855957, 10.596283, -5.199400, 115.407677, 0.000000
37.179451, -120.781960, 3836.201660, 10.188977, -5.458726, 115.448441, 0.000000
37.179401, -120.781837, 3837.573486, 9.879080, -5.681745, 115.481895, 0.000000
37.179348, -120.781715, 3838.972656, 9.667299, -5.869191, 115.505310, 0.000000
37.179298, -120.781593, 3840.342529, 9.507944, -5.992330, 115.524872, 0.000000

View File

@@ -0,0 +1,36 @@
%% X-Plane Connect MATLAB Playback Example Script
% This script demonstrates how to playback recorded data from X-Plane.
% (See Record.m)
% Before running this script, ensure that the XPC plugin is installed and
% X-Plane is running.
%% Import XPC
addpath('../')
import XPlaneConnect.*
%% Setup
% Create variables and open connection to X-Plane
path = 'MyRecording.txt'; % File containing stored data
interval = 0.1; % Time between snapshots in seconds
duration = 10;
Socket = openUDP(); % Open connection to X-Plane
fd = fopen(path, 'r'); % Open file
disp('X-Plane Connect Playback Example Script');
fprintf('Playing back ''%s'' in %fs increments.\n', path, interval);
%% Start Playback
count = floor(duration / interval);
pauseSim(1);
for i = 1:count
line = fgetl(fd);
posi = sscanf(line, '%f, %f, %f, %f, %f, %f, %f\n');
sendPOSI(posi);
pause(interval);
end
%% Close connection and file
pauseSim(0);
closeUDP(Socket);
fclose(fd);
disp('Playback complete.');

View File

@@ -0,0 +1,34 @@
%% X-Plane Connect MATLAB Recording Example Script
% This script demonstrates how to record data from X-Plane that can later
% be played back. (See Playback.m)
% Before running this script, ensure that the XPC plugin is installed and
% X-Plane is running.
%% Import XPC
addpath('../')
import XPlaneConnect.*
%% Setup
% Create variables and open connection to X-Plane
path = 'MyRecording.txt'; % File to save the data in
interval = 0.1; % Time between snapshots in seconds
duration = 10; % Time to record for in seconds
Socket = openUDP(); % Open connection to X-Plane
fd = fopen(path, 'w'); % Open file
disp('X-Plane Connect Recording Example Script');
fprintf('Recording to ''%s'' for %f seconds in %fs increments.\n', path, duration, interval);
%% Start Recording
count = floor(duration / interval);
for i = 1:count
posi = getPOSI(0, Socket);
fprintf(fd, '%f, %f, %f, %f, %f, %f, %f\n', ...
posi(1), posi(2), posi(3), posi(4), posi(5), posi(6), posi(7));
pause(interval);
end
%% Close connection and file
closeUDP(Socket);
fclose(fd);
disp('Recording complete.');

View File

@@ -0,0 +1,16 @@
import sys
import xpc
def monitor():
with xpc.XPlaneConnect() as client:
while True:
posi = client.getPOSI();
ctrl = client.getCTRL();
print "Loc: (%4f, %4f, %4f) Aileron:%2f Elevator:%2f Rudder:%2f\n"\
% (posi[0], posi[1], posi[2], ctrl[1], ctrl[0], ctrl[2])
if __name__ == "__main__":
monitor()

View File

@@ -0,0 +1,82 @@
from time import sleep
import xpc
def record(path, interval = 0.1, duration = 60):
try:
fd = open(path, "w")
except:
print "Unable to open file."
return
count = int(duration / interval)
if count < 1:
print "duration is less than a single frame."
return
with xpc.XPlaneConnect("localhost", 49009, 0, 1000) as client:
print "Recording..."
for i in range(0, count):
try:
posi = client.getPOSI()
fd.write("{0}, {1}, {2}, {3}, {4}, {5}, {6}\n".format(*posi))
except:
print "Error reading position"
continue
sleep(interval);
print "Recording Complete"
fd.close()
def playback(path, interval):
try:
fd = open(path, "r")
except:
print "Unable to open file."
return
with xpc.XPlaneConnect("localhost", 49009, 0, 1000) as client:
print "Starting Playback..."
for line in fd:
try:
posi = [ float(x) for x in line.split(',') ]
posi = client.sendPOSI(posi)
except:
print "Error sending position"
continue
sleep(interval);
print "Playback Complete"
fd.close()
def printMenu(title, opts):
print "\n+---------------------------------------------- +"
print "| {0:42} |\n".format(title)
print "+---------------------------------------------- +"
for i in range(0,len(opts)):
print "| {0:2}. {1:40} |".format(i + 1, opts[i])
print "+---------------------------------------------- +"
return int(raw_input("Please select and option: "))
def ex():
print "X-Plane Connect Playback Example [Version 1.2.0]"
print "(c) 2013-2015 United States Government as represented by the Administrator"
print "of the National Aeronautics and Space Administration. All Rights Reserved."
mainOpts = [ "Record X-Plane", "Playback File", "Exit" ]
while True:
opt = printMenu("What would you like to do?", mainOpts)
if opt == 1:
path = raw_input("Enter save file path: ")
interval = float(raw_input("Enter interval between frames (seconds): "))
duration = float(raw_input("Enter duration to record for (seconds): "))
record(path, interval, duration)
elif opt == 2:
path = raw_input("Enter save file path: ")
interval = float(raw_input("Enter interval between frames (seconds): "))
playback(path, interval)
elif opt == 3:
return;
else:
print "Unrecognized option."
if __name__ == "__main__":
ex()

View File

@@ -144,6 +144,28 @@ class XPlaneConnect(object):
self.sendUDP(buffer)
# Position
def getPOSI(self, ac = 0):
'''Gets position information for the specified aircraft.
Args:
ac: The aircraft to set the control surfaces of. 0 is the main/player aircraft.
'''
# Send request
buffer = struct.pack("<4sxB", "GETP", ac)
self.sendUDP(buffer)
# Read response
resultBuf = self.readUDP()
if len(resultBuf) != 34:
raise ValueError("Unexpected response length.")
result = struct.unpack("<4sxBfffffff", resultBuf)
if result[0] != "POSI":
raise ValueError("Unexpected header: " + result[0])
# Drop the header & ac from the return value
return result[2:]
def sendPOSI(self, values, ac = 0):
'''Sets position information on the specified aircraft.
@@ -155,8 +177,8 @@ class XPlaneConnect(object):
* Latitude (deg)
* Longitude (deg)
* Altitude (m above MSL)
* Roll (deg)
* Pitch (deg)
* Roll (deg)
* True Heading (deg)
* Gear (0=up, 1=down)
ac: The aircraft to set the control surfaces of. 0 is the main/player aircraft.
@@ -179,6 +201,29 @@ class XPlaneConnect(object):
self.sendUDP(buffer)
# Controls
def getCTRL(self, ac = 0):
'''Gets the control surface information for the specified aircraft.
Args:
ac: The aircraft to set the control surfaces of. 0 is the main/player aircraft.
'''
# Send request
buffer = struct.pack("<4sxB", "GETC", ac)
self.sendUDP(buffer)
# Read response
resultBuf = self.readUDP()
if len(resultBuf) != 31:
raise ValueError("Unexpected response length.")
result = struct.unpack("<4sxffffbfBf", resultBuf)
if result[0] != "CTRL":
raise ValueError("Unexpected header: " + result[0])
# Drop the header from the return value
result =result[1:7] + result[8:]
return result
def sendCTRL(self, values, ac = 0):
'''Sets control surface information on the specified aircraft.

View File

@@ -5,7 +5,7 @@
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>3c7a940d-17c8-4e91-882f-9bc8b1d2f54b</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>src\example.py</StartupFile>
<StartupFile>src\basicExample.py</StartupFile>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
@@ -24,8 +24,14 @@
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<ItemGroup>
<Compile Include="src\playbackExample.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="src\monitorExample.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="src\xpc.py" />
<Compile Include="src\example.py">
<Compile Include="src\basicExample.py">
<SubType>Code</SubType>
</Compile>
</ItemGroup>

View File

@@ -38,6 +38,33 @@ int doCTRLTest(char* drefs[7], float values[], int size, int ac, float expected[
return compareArray(expected, actual, 7);
}
int doGETCTest(float values[7], int ac, float expected[7])
{
// Execute Test
float actual[7];
XPCSocket sock = openUDP(IP);
int result = sendCTRL(sock, values, 7, ac);
if (result >= 0)
{
result = getCTRL(sock, actual, ac);
}
closeUDP(sock);
if (result < 0)
{
return -1;
}
// Test values
for (int i = 0; i < 7; ++i)
{
if (fabs(expected[i] - actual[i]) > 1e-4)
{
return -10 - i;
}
}
return 0;
}
int basicCTRLTest(char** drefs, int ac)
{
// Set control surfaces to known state.
@@ -146,4 +173,16 @@ int testCTRL_Speedbrakes()
}
return 0;
}
int testGETC()
{
float CTRL[7] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F, -1.5F };
return doGETCTest(CTRL, 0, CTRL);
}
int testGETC_NonPlayer()
{
float CTRL[7] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F, -1.5F };
return doGETCTest(CTRL, 2, CTRL);
}
#endif

View File

@@ -40,6 +40,33 @@ int doPOSITest(char* drefs[7], float values[], int size, int ac, float expected[
return compareArray(expected, actual, 7);
}
int doGETPTest(float values[7], int ac, float expected[7])
{
// Execute Test
float actual[7];
XPCSocket sock = openUDP(IP);
int result = sendPOSI(sock, values, 7, ac);
if (result >= 0)
{
result = getPOSI(sock, actual, ac);
}
closeUDP(sock);
if (result < 0)
{
return -1;
}
// Test values
for (int i = 0; i < 7; ++i)
{
if (fabs(expected[i] - actual[i]) > 1e-4)
{
return -10 - i;
}
}
return 0;
}
int basicPOSITest(char** drefs, int ac)
{
// Set psoition and initial orientation
@@ -116,6 +143,16 @@ int testPOSI_NonPlayer()
return basicPOSITest(drefs, 1);
}
int testGetPOSI_Player()
{
float POSI[7] = { 37.524F, -122.06899F, 2500, 0, 0, 0, 1 };
return doGETPTest(POSI, 0, POSI);
}
int testGetPOSI_NonPlayer()
{
float POSI[7] = { 37.624F, -122.06899F, 1500, 0, 0, 0, 1 };
return doGETPTest(POSI, 3, POSI);
}
#endif

View File

@@ -40,9 +40,13 @@ int main(int argc, const char * argv[])
runTest(testCTRL_Player, "CTRL (player)");
runTest(testCTRL_NonPlayer, "CTRL (non-player)");
runTest(testCTRL_Speedbrakes, "CTRL (speedbrakes)");
runTest(testGETC, "GETC (player)");
runTest(testGETC_NonPlayer, "GETC (Non-player)");
// POSI
runTest(testPOSI_Player, "POSI (player)");
runTest(testPOSI_NonPlayer, "POSI (non-player)");
runTest(testGetPOSI_Player, "GETP (player)");
runTest(testGetPOSI_NonPlayer, "GETP (non-player)");
// Data
runTest(testDATA, "DATA");
// Text

View File

@@ -698,4 +698,31 @@ public class XPlaneConnectTest
}
}
@Test
public void testGetPOSI() throws IOException
{
float[] values = { 37.524F, -122.06899F, 2500.0F, 45.0F, -45.0F, 15.0F, 1.0F };
try(XPlaneConnect xpc = new XPlaneConnect())
{
xpc.pauseSim(true);
xpc.sendPOSI(values);
float[] actual = xpc.getPOSI(0);
assertArrayEquals(values, actual, 1e-4F);
}
}
@Test
public void testGetCTRL() throws IOException
{
float[] values = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F, -1.5F };
try(XPlaneConnect xpc = new XPlaneConnect())
{
xpc.sendCTRL(values);
float[] actual = xpc.getCTRL(0);
assertArrayEquals(values, actual, 1e-4F);
}
}
}

View File

@@ -0,0 +1,15 @@
function getCTRLTest()
%GETCTRLTEST Summary of this function goes here
% Detailed explanation goes here
addpath('../../MATLAB')
import XPlaneConnect.*
values = [10.0, 5.0, -5.0, 0.8, 1.0, 0.5, -1.5];
sendCTRL(values, 0);
actual = getCTRL(0);
assert(isequal(length(actual), length(values)));
for i = 1:length(actual)
assert(abs(actual(i) - values(i)) <1e-4)
end
end

View File

@@ -0,0 +1,17 @@
function getPOSITest()
%GETCTRLTEST Summary of this function goes here
% Detailed explanation goes here
addpath('../../MATLAB')
import XPlaneConnect.*
values = [ 37.524, -122.06899, 2500, 45, -45, 15, 1 ];
pauseSim(1);
sendPOSI(values, 0);
actual = getPOSI(0);
pauseSim(0);
assert(isequal(length(actual), length(values)));
for i = 1:length(actual)
assert(abs(actual(i) - values(i)) <1e-4)
end
end

View File

@@ -1,4 +1,4 @@
function CTRLTest( )
function sendCTRLTest( )
%CTRLTest Summary of this function goes here
% Detailed explanation goes here
%% Test player aircraft

View File

@@ -1,4 +1,4 @@
function POSITest( )
function sendPOSITest( )
%POSITest Summary of this function goes here
% Detailed explanation goes here
addpath('../../MATLAB')

View File

@@ -18,8 +18,10 @@ theTests = {{@openCloseTest, 'Open/Close Test', 0},...
{@getDREFsTest,'Request DREF Test', 0},...
{@sendDREFTest,'Send DREF Test', 0},...
{@DATATest,'DATA Test', 0},...
{@CTRLTest,'CTRL Test', 0},...
{@POSITest,'POSI Test', 0},...
{@sendCTRLTest,'sendCTRL Test', 0},...
{@getCTRLTest,'getCTRL Test', 0},...
{@sendPOSITest,'sendPOSI Test', 0},...
{@getPOSITest,'getPOSI Test', 0},...
{@sendWYPTTest,'WYPT Test', 0},...
{@sendVIEWTest,'VIEW Test', 0},...
{@pauseTest,'Pause Test', 0},...

View File

@@ -3,7 +3,7 @@ import unittest
import imp
import time
import xpc
xpc = imp.load_source('xpc', '../../Python/src/xpc.py')
class XPCTests(unittest.TestCase):
"""Tests the functionality of the XPlaneConnect class."""
@@ -202,6 +202,29 @@ class XPCTests(unittest.TestCase):
expected = 0.0
do_test()
def test_getCTRL(self):
values = None
ac = 0
expected = None
def do_test():
with xpc.XPlaneConnect() as client:
# Execute
client.sendCTRL(values, ac)
result = client.getCTRL(ac)
# Test
self.assertEqual(len(result), len(expected))
for a, e in zip(result, expected):
self.assertAlmostEqual(a, e, 4)
values = [0.0, 0.0, 0.0, 0.8, 1.0, 0.5, -1.5]
expected = values
ac = 0
do_test()
ac = 3
do_test()
def test_sendCTRL(self):
# Setup
@@ -270,6 +293,31 @@ class XPCTests(unittest.TestCase):
ctrl[6] = 0.0
do_test()
def test_getPOSI(self):
values = None
ac = 0
expected = None
def do_test():
with xpc.XPlaneConnect() as client:
# Execute
client.pauseSim(True)
client.sendPOSI(values, ac)
result = client.getPOSI(ac)
client.pauseSim(False)
# Test
self.assertEqual(len(result), len(expected))
for a, e in zip(result, expected):
self.assertAlmostEqual(a, e, 4)
values = [ 37.524, -122.06899, 2500, 45, -45, 15, 1 ]
expected = values
ac = 0
do_test()
ac = 3
do_test()
def test_sendPOSI(self):
# Setup
drefs = ["sim/flightmodel/position/latitude",\

View File

@@ -13,7 +13,6 @@ SET(CMAKE_CXX_COMPILER g++)
add_library(xpc64 SHARED XPCPlugin.cpp
DataManager.cpp
DataMaps.cpp
Drawing.cpp
Log.cpp
Message.cpp
@@ -24,7 +23,6 @@ set_target_properties(xpc64 PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-shared
add_library(xpc32 SHARED XPCPlugin.cpp
DataManager.cpp
DataMaps.cpp
Drawing.cpp
Log.cpp
Message.cpp

View File

@@ -169,8 +169,8 @@ namespace XPC
sprintf(multi, "sim/multiplayer/position/plane%i_gear_deploy", i);
mdrefs[i][DREF_GearDeploy] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_flap_ratio", i);
mdrefs[i][DREF_FlapSetting] = XPLMFindDataRef(multi); // Can't set the actual flap setting on npc aircraft
mdrefs[i][DREF_FlapActual] = XPLMFindDataRef(multi);
mdrefs[i][DREF_FlapSetting] = mdrefs[i][DREF_FlapActual]; // Can't set the actual flap setting on npc aircraft
sprintf(multi, "sim/multiplayer/position/plane%i_flap_ratio2", i);
mdrefs[i][DREF_FlapActual2] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_spoiler_ratio", i);
@@ -183,6 +183,7 @@ namespace XPC
mdrefs[i][DREF_Sweep] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_throttle", i);
mdrefs[i][DREF_ThrottleActual] = XPLMFindDataRef(multi);
mdrefs[i][DREF_ThrottleSet] = mdrefs[i][DREF_ThrottleActual]; // No throttle set for multiplayer planes.
sprintf(multi, "sim/multiplayer/position/plane%i_yolk_pitch", i);
mdrefs[i][DREF_YokePitch] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_yolk_roll", i);
@@ -528,7 +529,7 @@ namespace XPC
}
XPLMDataTypeID dataType = XPLMGetDataRefTypes(xdref);
Log::FormatLine(LOG_INFO, "DMAN", "Setting DREF %s (x:%X) Type: %i", xdref, dataType);
Log::FormatLine(LOG_INFO, "DMAN", "Setting DREF %s (x:%X) Type: %i", dref.c_str(), xdref, dataType);
if ((dataType & 2) == 2) // Float
{
XPLMSetDataf(xdref, values[0]);
@@ -729,13 +730,13 @@ namespace XPC
// http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf
float q[4];
float halfRad = 0.00872664625997F;
orient[2] = halfRad * orient[2];
orient[0] = halfRad * orient[0];
orient[1] = halfRad * orient[1];
q[0] = cos(orient[2]) * cos(orient[0]) * cos(orient[1]) + sin(orient[2]) * sin(orient[0]) * sin(orient[1]);
q[1] = cos(orient[2]) * cos(orient[0]) * sin(orient[1]) - sin(orient[2]) * sin(orient[0]) * cos(orient[1]);
q[2] = cos(orient[2]) * sin(orient[0]) * cos(orient[1]) + sin(orient[2]) * cos(orient[0]) * sin(orient[1]);
q[3] = sin(orient[2]) * cos(orient[0]) * cos(orient[1]) - cos(orient[2]) * sin(orient[0]) * sin(orient[1]);
float theta = halfRad * orient[0];
float phi = halfRad * orient[1];
float psi = halfRad * orient[2];
q[0] = cos(phi) * cos(theta) * cos(psi) + sin(phi) * sin(theta) * sin(psi);
q[1] = sin(phi) * cos(theta) * cos(psi) - cos(phi) * sin(theta) * sin(psi);
q[2] = cos(phi) * sin(theta) * cos(psi) + sin(phi) * cos(theta) * sin(psi);
q[3] = cos(phi) * cos(theta) * sin(psi) - sin(phi) * sin(theta) * cos(psi);
// If the sim is un-paused, this will overwrite the pitch/roll/yaw
// values set above.

View File

@@ -57,7 +57,7 @@ namespace XPC
static void WriteLevel(FILE* fd, int level)
{
char* str;
const char* str;
switch (level)
{
case LOG_OFF:

View File

@@ -25,12 +25,6 @@ namespace XPC
return m;
}
unsigned long Message::GetMagicNumber() const
{
unsigned long val = size < 4 ? 0 : *((unsigned long*)buffer);
return val;
}
std::string Message::GetHead() const
{
std::string val = size < 4 ? "" : std::string((char*)buffer, 4);
@@ -59,25 +53,21 @@ namespace XPC
stringstream ss;
// Dump raw bytes to string
ss << hex << setfill('0');
ss << std::hex << setfill('0');
for (int i = 0; i < size; ++i)
{
ss << ' ' << setw(2) << static_cast<unsigned>(buffer[i]);
}
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
Log::WriteLine(LOG_TRACE, "DBUG", ss.str());
std::string head = GetHead();
ss.str("");
ss << "Head: " << GetHead() << "(0x" << setw(8) << GetMagicNumber() << ")" << dec << " Size: " << GetSize();
switch (GetMagicNumber()) // Binary version of head
{
case 0x4E4EF443: // CONN
case 0x54505957: // WYPT
case 0x54584554: // TEXT
ss << "Head: " << head << std::dec << " Size: " << GetSize();
if (head == "CONN" || head == "WYPT" || head == "TEXT")
{
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
break;
}
case 0x4C525443: // CTRL
else if (head == "CTRL")
{
// Parse message data
float pitch = *((float*)(buffer + 5));
@@ -94,9 +84,8 @@ namespace XPC
ss << " Attitude:(" << pitch << " " << roll << " " << yaw << ")";
ss << " Thr:" << thr << " Gear:" << (int)gear << " Flaps:" << flaps;
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
break;
}
case 0x41544144: // DATA
else if (head == "DATA")
{
size_t numCols = (size - 5) / 36;
float values[32][9];
@@ -117,9 +106,8 @@ namespace XPC
}
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
break;
}
case 0x46455244: // DREF
else if (head == "DREF")
{
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
string dref((char*)buffer + 6, buffer[5]);
@@ -132,9 +120,13 @@ namespace XPC
ss << " " << *((float*)(buffer + values + 1 + sizeof(float) * i));
}
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
break;
}
case 0x44544547: // GETD
else if (head == "GETC" || head == "GETP")
{
ss << " Aircraft:" << (int)buffer[5];
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
else if (head == "GETD")
{
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
int cur = 6;
@@ -145,9 +137,8 @@ namespace XPC
i + 1, buffer[5], dref.length(), dref.c_str());
cur += 1 + buffer[cur];
}
break;
}
case 0x49534F50: // POSI
else if (head == "POSI")
{
char aircraft = buffer[5];
float gear = *((float*)(buffer + 30));
@@ -160,20 +151,21 @@ namespace XPC
ss << orient[3] << ' ' << orient[4] << ' ' << orient[5] << ") Gear:";
ss << gear;
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
break;
}
case 0x554D4953: // SIMU
else if (head == "SIMU")
{
ss << ' ' << (int)buffer[5];
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
break;
}
default:
else if (head == "VIEW")
{
ss << "Type:" << *((unsigned long*)(buffer + 5));
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
else
{
ss << " UNKNOWN HEADER ";
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
break;
}
}
}
}

View File

@@ -55,6 +55,8 @@ namespace XPC
handlers.insert(std::make_pair("TEXT", MessageHandlers::HandleText));
handlers.insert(std::make_pair("WYPT", MessageHandlers::HandleWypt));
handlers.insert(std::make_pair("VIEW", MessageHandlers::HandleView));
handlers.insert(std::make_pair("GETC", MessageHandlers::HandleGetC));
handlers.insert(std::make_pair("GETP", MessageHandlers::HandleGetP));
// X-Plane data messages
handlers.insert(std::make_pair("DSEL", MessageHandlers::HandleXPlaneData));
handlers.insert(std::make_pair("USEL", MessageHandlers::HandleXPlaneData));
@@ -425,6 +427,43 @@ namespace XPC
}
}
void MessageHandlers::HandleGetC(const Message& msg)
{
const unsigned char* buffer = msg.GetBuffer();
std::size_t size = msg.GetSize();
if (size != 6)
{
Log::FormatLine(LOG_ERROR, "GCTL", "Unexpected message length: %u", size);
return;
}
unsigned char aircraft = buffer[5];
// TODO(jason-watkins): Get proper printf specifier for unsigned char
Log::FormatLine(LOG_TRACE, "GCTL", "Getting control information for aircraft %u", aircraft);
float throttle[8];
unsigned char response[31] = "CTRL";
*((float*)(response + 5)) = DataManager::GetFloat(DREF_Elevator, aircraft);
*((float*)(response + 9)) = DataManager::GetFloat(DREF_Aileron, aircraft);
*((float*)(response + 13)) = DataManager::GetFloat(DREF_Rudder, aircraft);
DataManager::GetFloatArray(DREF_ThrottleSet, throttle, 8, aircraft);
*((float*)(response + 17)) = throttle[0];
if (aircraft == 0)
{
response[21] = (char)DataManager::GetInt(DREF_GearHandle, aircraft);
}
else
{
float mpGear[10];
DataManager::GetFloatArray(DREF_GearDeploy, mpGear, 10, aircraft);
response[21] = mpGear[0] > 0.5 ? 1 : 0;
}
*((float*)(response + 22)) = DataManager::GetFloat(DREF_FlapSetting, aircraft);
response[26] = aircraft;
*((float*)(response + 27)) = DataManager::GetFloat(DREF_SpeedBrakeSet, aircraft);
sock->SendTo(response, 31, &connection.addr);
}
void MessageHandlers::HandleGetD(const Message& msg)
{
const unsigned char* buffer = msg.GetBuffer();
@@ -471,6 +510,34 @@ namespace XPC
sock->SendTo(response, cur, &connection.addr);
}
void MessageHandlers::HandleGetP(const Message& msg)
{
const unsigned char* buffer = msg.GetBuffer();
std::size_t size = msg.GetSize();
if (size != 6)
{
Log::FormatLine(LOG_ERROR, "GPOS", "Unexpected message length: %u", size);
return;
}
unsigned char aircraft = buffer[5];
Log::FormatLine(LOG_TRACE, "GPOS", "Getting position information for aircraft %u", aircraft);
unsigned char response[34] = "POSI";
response[5] = (char)DataManager::GetInt(DREF_GearHandle, aircraft);
*((float*)(response + 6)) = (float)DataManager::GetDouble(DREF_Latitude, aircraft);
*((float*)(response + 10)) = (float)DataManager::GetDouble(DREF_Longitude, aircraft);
*((float*)(response + 14)) = (float)DataManager::GetDouble(DREF_Elevation, aircraft);
*((float*)(response + 18)) = DataManager::GetFloat(DREF_Pitch, aircraft);
*((float*)(response + 22)) = DataManager::GetFloat(DREF_Roll, aircraft);
*((float*)(response + 26)) = DataManager::GetFloat(DREF_HeadingTrue, aircraft);
float gear[10];
DataManager::GetFloatArray(DREF_GearDeploy, gear, 10, aircraft);
*((float*)(response + 30)) = gear[0];
sock->SendTo(response, 34, &connection.addr);
}
void MessageHandlers::HandlePosi(const Message& msg)
{
// Update log

View File

@@ -43,7 +43,9 @@ namespace XPC
static void HandleCtrl(const Message& msg);
static void HandleData(const Message& msg);
static void HandleDref(const Message& msg);
static void HandleGetC(const Message& msg);
static void HandleGetD(const Message& msg);
static void HandleGetP(const Message& msg);
static void HandlePosi(const Message& msg);
static void HandleSimu(const Message& msg);
static void HandleText(const Message& msg);

View File

@@ -135,7 +135,7 @@ namespace XPC
}
else
{
Log::FormatLine(LOG_INFO, tag, "Send failed. (remote: %s)", GetHost(remote).c_str());
Log::FormatLine(LOG_INFO, tag, "Send succeeded. (remote: %s)", GetHost(remote).c_str());
}
}

View File

@@ -91,7 +91,7 @@ static float XPCFlightLoopCallback(float inElapsedSinceLastCall, float inElapsed
PLUGIN_API int XPluginStart(char* outName, char* outSig, char* outDesc)
{
strcpy(outName, "X-Plane Connect [Version 1.0.1]");
strcpy(outName, "X-Plane Connect [Version 1.2.0]");
strcpy(outSig, "NASA.XPlaneConnect");
strcpy(outDesc, "X Plane Communications Toolbox\nCopyright (c) 2013-2015 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved.");
@@ -105,7 +105,7 @@ PLUGIN_API int XPluginStart(char* outName, char* outSig, char* outDesc)
1000000000.0;
}
#endif
XPC::Log::Initialize("1.1.0");
XPC::Log::Initialize("1.1.1");
XPC::Log::WriteLine(LOG_INFO, "EXEC", "Plugin Start");
XPC::DataManager::Initialize();

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.