From 835f1e6527d360ea509f5b72961337b794b27eed Mon Sep 17 00:00:00 2001 From: Jason Watkins Date: Fri, 8 May 2015 09:03:23 -0700 Subject: [PATCH 1/5] Added support for the VIEW command to the plugin. - The VIEW command allows clients to change the camera position in X-Plane. --- xpcPlugin/MessageHandlers.cpp | 39 +++++++++++++++++++++++++++++++++-- xpcPlugin/MessageHandlers.h | 1 + 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/xpcPlugin/MessageHandlers.cpp b/xpcPlugin/MessageHandlers.cpp index 1a94bf3..37c7e71 100644 --- a/xpcPlugin/MessageHandlers.cpp +++ b/xpcPlugin/MessageHandlers.cpp @@ -1,10 +1,26 @@ //Copyright (c) 2013-2015 United States Government as represented by the Administrator of the //National Aeronautics and Space Administration. All Rights Reserved. +// +//X-Plane API +//Copyright(c) 2008, Sandy Barbour and Ben Supnik All rights reserved. +//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +//associated documentation files(the "Software"), to deal in the Software without restriction, +//including without limitation the rights to use, copy, modify, merge, publish, distribute, +//sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is +//furnished to do so, subject to the following conditions : +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Neither the names of the authors nor that of X - Plane or Laminar Research +// may be used to endorse or promote products derived from this software +// without specific prior written permission from the authors or +// Laminar Research, respectively. #include "MessageHandlers.h" #include "DataManager.h" #include "Drawing.h" #include "Log.h" +#include "XPLMUtilities.h" + #include #include @@ -36,8 +52,7 @@ namespace XPC handlers.insert(std::make_pair("SIMU", MessageHandlers::HandleSimu)); handlers.insert(std::make_pair("TEXT", MessageHandlers::HandleText)); handlers.insert(std::make_pair("WYPT", MessageHandlers::HandleWypt)); - // Not implemented messages - handlers.insert(std::make_pair("VIEW", MessageHandlers::HandleUnknown)); + handlers.insert(std::make_pair("VIEW", MessageHandlers::HandleView)); // X-Plane data messages handlers.insert(std::make_pair("DSEL", MessageHandlers::HandleXPlaneData)); handlers.insert(std::make_pair("USEL", MessageHandlers::HandleXPlaneData)); @@ -623,6 +638,26 @@ namespace XPC } } + void MessageHandlers::HandleView(Message& msg) + { + // Update Log +#if LOG_VERBOSITY > 0 + Log::FormatLine("[VIEW] Message Received (Conn %i)", connection.id); +#endif + + const std::size_t size = msg.GetSize(); + if (size != 9) + { +#if LOG_VERBOSITY > 1 + Log::FormatLine("[VIEW] Error: Unexpected length. Message was %d bytes, expected 9.", size); +#endif + return; + } + const unsigned char* buffer = msg.GetBuffer(); + int type = *((int*)(buffer + 5)); + XPLMCommandKeyStroke(type); + } + void MessageHandlers::HandleWypt(Message& msg) { // Update Log diff --git a/xpcPlugin/MessageHandlers.h b/xpcPlugin/MessageHandlers.h index b7cfd25..123c39a 100644 --- a/xpcPlugin/MessageHandlers.h +++ b/xpcPlugin/MessageHandlers.h @@ -46,6 +46,7 @@ namespace XPC static void HandleSimu(Message& msg); static void HandleText(Message& msg); static void HandleWypt(Message& msg); + static void HandleView(Message& msg); static void HandleXPlaneData(Message& msg); static void HandleUnknown(Message& msg); From 579cad0655c4ba47ab6d10040f741997ed66dd2d Mon Sep 17 00:00:00 2001 From: Jason Watkins Date: Fri, 8 May 2015 13:09:34 -0700 Subject: [PATCH 2/5] Added support for VIEW command to the C client. --- C/src/xplaneConnect.c | 31 +++++++++-- C/src/xplaneConnect.h | 24 +++++++++ TestScripts/C Tests.win/CTests.vcxproj | 1 + TestScripts/C Tests/ViewTests.h | 73 ++++++++++++++++++++++++++ TestScripts/C Tests/main.c | 5 ++ 5 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 TestScripts/C Tests/ViewTests.h diff --git a/C/src/xplaneConnect.c b/C/src/xplaneConnect.c index 74b098d..f6f0a5d 100755 --- a/C/src/xplaneConnect.c +++ b/C/src/xplaneConnect.c @@ -48,9 +48,6 @@ #include #include - - - void printError(char *functionName, char *format, ...) { va_list args; @@ -694,3 +691,31 @@ int sendWYPT(XPCSocket sock, WYPT_OP op, float points[], int count) /*****************************************************************************/ /**** End Drawing functions ****/ /*****************************************************************************/ + +/*****************************************************************************/ +/**** View functions ****/ +/*****************************************************************************/ +int sendVIEW(XPCSocket sock, VIEW_TYPE view) +{ + // Validate Input + if (view < XPC_VIEW_FORWARDS || view > XPC_VIEW_FULLSCREENNOHUD) + { + printError("sendVIEW", "Unrecognized view"); + return -1; + } + + // Setup Command + char buffer[9] = "VIEW"; + *((int*)(buffer + 5)) = view; + + // Send Command + if (sendUDP(sock, buffer, 9) < 0) + { + printError("sendVIEW", "Failed to send command"); + return -2; + } + return 0; +} +/*****************************************************************************/ +/**** End View functions ****/ +/*****************************************************************************/ \ No newline at end of file diff --git a/C/src/xplaneConnect.h b/C/src/xplaneConnect.h index 391ec54..3827a68 100644 --- a/C/src/xplaneConnect.h +++ b/C/src/xplaneConnect.h @@ -61,6 +61,23 @@ typedef enum XPC_WYPT_DEL = 2, XPC_WYPT_CLR = 3 } WYPT_OP; + +typedef enum +{ + XPC_VIEW_FORWARDS = 73, + XPC_VIEW_DOWN, + XPC_VIEW_LEFT, + XPC_VIEW_RIGHT, + XPC_VIEW_BACK, + XPC_VIEW_TOWER, + XPC_VIEW_RUNWAY, + XPC_VIEW_CHASE, + XPC_VIEW_FOLLOW, + XPC_VIEW_FOLLOWWITHPANEL, + XPC_VIEW_SPOT, + XPC_VIEW_FULLSCREENWITHHUD, + XPC_VIEW_FULLSCREENNOHUD, +} VIEW_TYPE; // Low Level UDP Functions @@ -214,6 +231,13 @@ int sendCTRL(XPCSocket sock, float values[], int size, char ac); /// \returns 0 if successful, otherwise a negative value. int sendTEXT(XPCSocket sock, char* msg, int x, int y); +/// Sets the camera view in X-Plane. +/// +/// \param sock The socket to use to send the command. +/// \param view The view to use. +/// \returns 0 if successful, otherwise a negative value. +int sendVIEW(XPCSocket sock, VIEW_TYPE view); + /// Adds, removes, or clears a set of waypoints. If the command is clear, the points are ignored /// and all points are removed. /// diff --git a/TestScripts/C Tests.win/CTests.vcxproj b/TestScripts/C Tests.win/CTests.vcxproj index b546a64..6c55744 100644 --- a/TestScripts/C Tests.win/CTests.vcxproj +++ b/TestScripts/C Tests.win/CTests.vcxproj @@ -33,6 +33,7 @@ + diff --git a/TestScripts/C Tests/ViewTests.h b/TestScripts/C Tests/ViewTests.h new file mode 100644 index 0000000..a25c14f --- /dev/null +++ b/TestScripts/C Tests/ViewTests.h @@ -0,0 +1,73 @@ +//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the +//National Aeronautics and Space Administration. All Rights Reserved. +#ifndef VIEWTESTS_H +#define VIEWTESTS_H + +#include "Test.h" +#include "xplaneConnect.h" + +typedef enum +{ + XPC_VDREF_FORWARDS = 1000, + XPC_VDREF_DOWN4 = 1001, + XPC_VDREF_DOWN8 = 1002, + XPC_VDREF_LEFT45 = 1004, + XPC_VDREF_RIGHT45 = 1005, + XPC_VDREF_LEFT90 = 1006, + XPC_VDREF_RIGHT90 = 1007, + XPC_VDREF_LEFT135 = 1008, + XPC_VDREF_RIGHT135 = 1009, + XPC_VDREF_BACKWARD = 1010, + XPC_VDREF_LEFTUP = 1011, + XPC_VDREF_RIGHTUP = 1012, + XPC_VDREF_AIRPORTBEACONTOWER = 1014, + XPC_VDREF_ONRUNWAY = 1015, + XPC_VDREF_CHASE = 1017, + XPC_VDREF_FOLLOW = 1018, + XPC_VDREF_FOLLOWWITHPANEL = 1019, + XPC_VDREF_SPOT = 1020, + XPC_VDREF_SPOTMOVING = 1021, + XPC_VDREF_FULLSCREENWITHHUD = 1023, + XPC_VDREF_FULLSCREENNOHUD = 1024, + XPC_VDREF_STRAIGHTDOWN = 1025, + XPC_VDREF_3DCOCKPIT = 1026 +} VIEW_DREF; + +int doViewTest(VIEW_TYPE viewCommand, VIEW_DREF viewResult) +{ + // Setup + char* dref = "sim/graphics/view/view_type"; + float value; + int size = 1; + + // Execute command + XPCSocket sock = openUDP(IP); + int result = sendVIEW(sock, viewCommand); + if (result >= 0) + { + result = getDREF(sock, dref, &value, &size); + } + closeUDP(sock); + if (result < 0) + { + return -1; + } + + if ((int)value != viewResult) + { + return -2; + } + return 0; +} + +int testView() +{ + int result = doViewTest(XPC_VIEW_FORWARDS, XPC_VDREF_FORWARDS); + if (result < 0) + { + return -1; + } + + return doViewTest(XPC_VIEW_CHASE, XPC_VDREF_CHASE); +} +#endif \ No newline at end of file diff --git a/TestScripts/C Tests/main.c b/TestScripts/C Tests/main.c index ae01451..0f5cdd9 100644 --- a/TestScripts/C Tests/main.c +++ b/TestScripts/C Tests/main.c @@ -8,6 +8,7 @@ #include "PosiTests.h" #include "DataTests.h" #include "TextTests.h" +#include "ViewTests.h" #include "WyptTests.h" int main(int argc, const char * argv[]) @@ -48,10 +49,14 @@ int main(int argc, const char * argv[]) runTest(testTEXT, "TEXT"); // Waypoints runTest(testWYPT, "WYPT"); + // View + runTest(testView, "VIEW"); // setConn runTest(testCONN, "CONN"); printf( "----------------\nTest Summary\n\tFailed: %i\n\tPassed: %i\n", testFailed, testPassed ); + printf("Press any key to exit."); + getchar(); return 0; } From 039c92b2f15ec5e94ec391aa68bcd7b454f260f3 Mon Sep 17 00:00:00 2001 From: Jason Watkins Date: Fri, 8 May 2015 13:34:32 -0700 Subject: [PATCH 3/5] Added support for VIEW command to Python client. --- Python/src/xpc.py | 32 +++++++++++++++++++++++++++++++ TestScripts/Python Tests/Tests.py | 16 ++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Python/src/xpc.py b/Python/src/xpc.py index 32b4d3c..c19bbdb 100644 --- a/Python/src/xpc.py +++ b/Python/src/xpc.py @@ -326,6 +326,23 @@ class XPlaneConnect(object): buffer = struct.pack("<4sxiiB" + str(msgLen) + "s", "TEXT", x, y, msgLen, msg) self.sendUDP(buffer) + def sendVIEW(self, view): + '''Sets the camera view in X-Plane + + Args: + view: The view to use. The ViewType class provides named constants + for known views. + ''' + # Preconditions + if view < ViewType.Forwards or view > ViewType.FullscreenNoHud: + raise ValueError("Unknown view command.") + + # Pack buffer + buffer = struct.pack("<4sxi", "VIEW", view) + + # Send message + self.sendUDP(buffer) + def sendWYPT(self, op, points): '''Adds, removes, or clears waypoints. Waypoints are three dimensional points on or above the Earth's surface that are represented visually in the simulator. Each @@ -350,3 +367,18 @@ class XPlaneConnect(object): else: buffer = struct.pack("<4sxBB" + str(len(points)) + "f", "WYPT", op, len(points), *points) self.sendUDP(buffer) + +class ViewType(object): + Forwards = 73 + Down = 74 + Left = 75 + Right = 76 + Back = 77 + Tower = 78 + Runway = 79 + Chase = 80 + Follow = 81 + FollowWithPanel = 82 + Spot = 83 + FullscreenWithHud = 84 + FullscreenNoHud = 85 diff --git a/TestScripts/Python Tests/Tests.py b/TestScripts/Python Tests/Tests.py index 558aa7c..2cdc825 100644 --- a/TestScripts/Python Tests/Tests.py +++ b/TestScripts/Python Tests/Tests.py @@ -319,6 +319,22 @@ class XPCTests(unittest.TestCase): # Cleanup client.close() + def test_sendView(self): + # Setup + dref = "sim/graphics/view/view_type" + fwd = 1000 + chase = 1017 + + #Execution + with xpc.XPlaneConnect() as client: + client.sendVIEW(xpc.ViewType.Forwards) + result = client.getDREF(dref) + self.assertAlmostEqual(fwd, result[0], 1e-4) + client.sendVIEW(xpc.ViewType.Chase) + result = client.getDREF(dref) + self.assertAlmostEqual(chase, result[0], 1e-4) + + def test_sendWYPT(self): # Setup client = xpc.XPlaneConnect() From 255877eee362675210a8df655706195d8edef483 Mon Sep 17 00:00:00 2001 From: Jason Watkins Date: Fri, 8 May 2015 13:57:16 -0700 Subject: [PATCH 4/5] Added support for VIEW command to Java client. --- Java/src/ViewType.java | 60 +++++++++++++++++++ Java/src/XPlaneConnect.java | 20 +++++++ TestScripts/Java Tests/XPlaneConnectTest.java | 21 +++++++ 3 files changed, 101 insertions(+) create mode 100644 Java/src/ViewType.java diff --git a/Java/src/ViewType.java b/Java/src/ViewType.java new file mode 100644 index 0000000..2f24c3d --- /dev/null +++ b/Java/src/ViewType.java @@ -0,0 +1,60 @@ +//NOTICES: +// Copyright ã 2013-2015 United States Government as represented by the Administrator of the +// National Aeronautics and Space Administration. All Rights Reserved. +// +// DISCLAIMERS +// No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND, +// EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE +// SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT +// SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO +// THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY +// GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, +// SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS RESULTING FROM USE OF THE SUBJECT SOFTWARE. +// FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING THIRD-PARTY +// SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT "AS IS." +// +// Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST THE UNITED STATES +// GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF +// RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, +// EXPENSES OR LOSSES ARISING FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR +// RESULTING FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD +// HARMLESS THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY +// PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER +// SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT. +package gov.nasa.xpc; + +/** + * Represents a camera view in X-Plane + * + * @author Jason Watkins + * @version 1.1 + * @since 2015-05-08 + */ +public enum ViewType +{ + Forwards(73), + Down(74), + Left(75), + Right(76), + Back(77), + Tower(78), + Runway(79), + Chase(80), + Follow(81), + FollowWithPanel(82), + Spot(83), + FullscreenWithHud(84), + FullscreenNoHud(85); + + private final int value; + private ViewType(int value) + { + this.value = value; + } + + public int getValue() + { + return value; + } +} diff --git a/Java/src/XPlaneConnect.java b/Java/src/XPlaneConnect.java index 2e1f336..ba545d5 100644 --- a/Java/src/XPlaneConnect.java +++ b/Java/src/XPlaneConnect.java @@ -720,6 +720,26 @@ public class XPlaneConnect implements AutoCloseable sendUDP(os.toByteArray()); } + /** + * Sets the camera view in X-Plane. + * + * @param view The view to use. + * @throws IOException If the command cannot be sent. + */ + public void sendVIEW(ViewType view) throws IOException + { + ByteBuffer bb = ByteBuffer.allocate(4); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.putInt(view.getValue()); + + //Build and send message + ByteArrayOutputStream os = new ByteArrayOutputStream(); + os.write("VIEW".getBytes(StandardCharsets.UTF_8)); + os.write(0xFF); //Placeholder for message length + os.write(bb.array()); + sendUDP(os.toByteArray()); + } + /** * Adds, removes, or clears a set of waypoints. If the command is clear, the points are ignored * and all points are removed. diff --git a/TestScripts/Java Tests/XPlaneConnectTest.java b/TestScripts/Java Tests/XPlaneConnectTest.java index e3caba5..fc7c76e 100644 --- a/TestScripts/Java Tests/XPlaneConnectTest.java +++ b/TestScripts/Java Tests/XPlaneConnectTest.java @@ -1,5 +1,6 @@ package gov.nasa.xpc.test; +import gov.nasa.xpc.ViewType; import gov.nasa.xpc.WaypointOp; import gov.nasa.xpc.XPlaneConnect; @@ -677,4 +678,24 @@ public class XPlaneConnectTest fail(); } } + + @Test + public void testSendView() throws IOException + { + String dref = "sim/graphics/view/view_type"; + float fwd = 1000; + float chase = 1017; + + try(XPlaneConnect xpc = new XPlaneConnect()) + { + xpc.sendVIEW(ViewType.Forwards); + float result = xpc.getDREF(dref)[0]; + assertEquals(fwd, result, 1e-4); + + xpc.sendVIEW(ViewType.Chase); + result = xpc.getDREF(dref)[0]; + assertEquals(chase, result, 1e-4); + } + + } } \ No newline at end of file From 60795b10a53077ad885d6e0715d8211d0acd5df7 Mon Sep 17 00:00:00 2001 From: Jason Watkins Date: Fri, 8 May 2015 14:37:58 -0700 Subject: [PATCH 5/5] Added support for VIEW command in MATLAB client. --- MATLAB/+XPlaneConnect/XPlaneConnect.jar | Bin 7035 -> 8294 bytes MATLAB/+XPlaneConnect/sendVIEW.m | 35 ++++++++++++++++++++++++ TestScripts/MATLAB Tests/sendVIEWTest.m | 26 ++++++++++++++++++ TestScripts/MATLAB Tests/tests.m | 1 + 4 files changed, 62 insertions(+) create mode 100644 MATLAB/+XPlaneConnect/sendVIEW.m create mode 100644 TestScripts/MATLAB Tests/sendVIEWTest.m diff --git a/MATLAB/+XPlaneConnect/XPlaneConnect.jar b/MATLAB/+XPlaneConnect/XPlaneConnect.jar index e4c0af51c2433fa6c376180c7268507b1f57c6bf..c7797111c75228c2b0d16de3685d4e7e92acf838 100644 GIT binary patch delta 7235 zcmY+JWmFVg*ME0VJfmTafN<5E#0Kj$vRF6c89`n4vpoM7l%imJUg21nI8t zdEOu2df&6pTK7J`&cA)mx~^N1tv7@^>R3wA3b!8-6pOJ9v$ z50xy>^QJSJGD=1Lb7A2dWPJL}uNTEOo(P*wc~smg(-kg{?3@9*g2(cHG19x~(#Gz? z59nOS^@#!W>0M8}#-Y0=gOH&$>6 zlXTeq16d7Yyo1ckem+^!et`FhQ-ow049T4yEhXp#KS6vD7SA``U zKn-PUE@gj#n-(?BTkX=QO^*6$c3H_<3ZbWmLBKSf>TFoO(8v1y8#?~LSyaf|>U}>{ zM8uKNuLHzbe^sla2)8$xRNt`#;AJ0g-2TjR@va$B5g?Mzu+hLtQmba>8&_I*#et<2 z^tbtCGOMqhgnM}jxv)YnM}XQd&WMQbtd#XMMtHRac?LJX4Zqui)5>3~)w`k_i2YGY z^NU{nq`I(O8f{@a{i2Z5{$cTA^D%04#K8>Z1SN$=YHRwg!EnTg-<_@8tkgHLiw^lI z$7TP68OE$T@fCK8Npdyt!F+8(sm-iq&9sMSPjYlr^K>~ay#_-{aRJG7`uZ#r4q7FL zqxp9|@d>4Gy9&CSpmM3y^jSvm-+NJ^k!QZGeFZRylCJJA5uDo;F&dPmz0 zUB^YXwCFdgK_VH?x0hDu%acVtm!B1Ks@I(5EEdX&R{6q3v0n6rXkBSsYupZB4c}y* ziEqMu792;nW5-NiCqkj`X@Bdp0_DjL*Rh>d4ZF<0b${W0q0v!w|lQ6Rk*=e(W zURIsXlD+}6nAX<&DSBL^Bu0i9UXqXxh{WUE*2==Kc3_pS?DHjdj9lt!YAn2p8(1t! zYE~59mII+ImHpoqbs%qcD+CxtQ|JtC(#cNpCf=%buoQT!@7feq4k3h+>2z=0sbOjM zMPRo3FH@WK69v_m+9yw&&)yn^Tka?cPbuc;5(d12yA;M0>XKWY(HN?JeS&$7jkiI| zsL(?7`X@B@#c#_+h8@dT0B^3eEHWjiS?s3*>yC!9Q+|n4`l-->t58pzbJ(Rbq@!Tq zKATbYXZM2&<$3h$b3(X!94w)Nje~Ug5l2TI2RFo+7k3y717jH*1EVT%0`uSTkfezv z2y?bJpH6ug4NhE6Vr2b7%Hrk5I_P0;6_$ipeG^tgPWcP3iWHUQ znFAwc_#D7}m$PslAbd|302DXAhrT0$<|-*`;#%Wj;(qp2A`lk9`b|>FB6HrQH!0E( zwUYXtMSqIVN&N%2KKJ5&nzJ5NClu+Ss*9n1{FPhqDiyg$Qf;3K8LPMd!qW3(3RZgF z1XceGNiJ7LLWcF-w#{GG+sk2`U)69w=a!<3SFE1nRktexaO=l;E1KrfrPM39l~orl zqyo%c+)X`(yrPS>q>W1Z)D#;BQz7PG8tm)RCBB~y|5W@|B*%@e+Eg&ts&0oy(gZCF~zi^0Ymg4H@OFfwhJ?28l4Y zfWn+djum1t_oIsz3R-T&^rtfSqc0Akihu7lNbU}t^-hLOY-Mk>FDM8B(b9ZB4TEot z{CXqo7)k!<<&z)LI*y8$F-TuDl(d%F;=IEebuoXvP}jgBv6{`_{A=9ZA?Q;9ums}r zOQ0+;-w{3}H1;&_1XOm$4r?3mRVovF64zObWm)w>Lkg*4?u|_dvy~zlLrvG`h5O^9 zG+Jd-X_>?4Nsqu2kSijB%>1#{PF>H@kG1J@zoyeP^wl}ZWBkD@jfSQLw%d>oB$5m! ze0$1$;|HV1;^OSJ;Mvu`OZ+ZwrS9z?b_z}A%hP6@3i&fbpoJhj*tP-qdh}e4E|@_A z@ujZkHif~_3GbXBK_whJ62tQ-9t+4R`Pa#k_&Hw{VOibLW8g?tHco0 z)t7plC(Zg#s)$kpTBlz3&jEKpEO=tZR2uM$=G-ANCQI!v%#mwvvGY|I6Yvj6LDEiY z=(8CQd%>ZbcT+7`qAhFiWt%`ZJ7e#8jMdV3ZP{DC2B=%_97)^(m>v)%PSPCL;Z&}w zVxa`gG7lPV^@^3qe~UE`$XH|FDO|B{^qxxRn2$OSA0S*PJ~s6#Vg6fDouN3>d^Y^z zjk!19H2E)D*ld}nMp%We7Cs|fLud4d&Wqdc))r!W&Bg8QCfc=?{L_MSW3|~amf!b^ zp8}~5i7JLEc@F6{9DlUft|qpKcTwh%WLO zw?=a==Pv7R)@NNk>~A$1YWpYY}4lteZzRLj-4SoM!rqI=m*2mujoQqmqX z4$K0C>GG{o8;8`MZvPKa01GLSO;Z}14?=S}Hr}4qnGu%C&k934K76<(%kh&FXNz6Z z9@><YJ2EGlJ;B$mqJWQHDj{jU5VPv9EmhrD86c3RER^>7Cr-v! zOofT0E@9rEEXvGeDB>8bCRmA?CyzgC!RWFctWl29WzF1zK%`*FR(<~K3tuy{otj+_e53_JF zaSTS}T3jXA2SDFR0UhJi{nyCts!>_5rs*{aJ}q&trQ&H-R_X>eeYrEln-U%>z&Fy7 z!J$}eN^1BGI@wFL3_dfk3Uj3$W)>~=pK@*;@@5YWwgodb$>udLw36{VTHy7Yr}N7_ zb{D)Z>kMPKRS4A5+% zx{r~xCla8^6*n1B_Bu-RV`fncq@b+UTPflRrKTU)Gc>6sjZHdOIBy(E0IO23?RB1B zQgXMt-uP%H^3K=#O^%gx(|8;=(lt3HUB+#GlsSuiuvNCF)1NS(JUdZ!i-UH0B`2C_ z=XFp>5Azaa9I?yIZdvy{J!9clhGnIA}>DWerR(x>NDDY_f4JjiO6v#(&^H4-vV z8eC$ZRb3Dg(p@)Ur=@iXf?ZZwwA@AyWr%1iZNVj)GqA#mHVex$r1_1pLs)2sg;+9y zNzpITzs>s_EUYcQ+e+5vKt``vK&_v=R1x?<)ESO3s)+wS4`6riFj>BGdwvI<0Cv8} z**-P~t_-(*P*pDcb3>svkGIsr!b6;^N9Ac#Gur)XnJ0Y4SawR$vabE(kj zw_K6oLzZx!y!0@2@rzE}D{+~qq1QUIbPbAS>2S>Ed#S?*IIO+nirb0hv>%QnoEZo#?Gy8Mh>6d6BHUGPxmQ$ zi(IGe^jk1-ITO#e*-1D-m1&=PZMn>ToNd{*RHUL!M9HCQ^75b&0SpR%dz+dH>+{`J~TePc|mTAGGcBYHkYxDNful)$qXt zD;4QX9D6>(1c3L38a=aoSdYou56G`vX)X|?TxzRnqyH60L-~k$jDw7asBDCeBeQ@v zRgKw{s$mxbxCRho?l>+hg( z<`E<&w$fWtm}C#Facbw)rDL(i^-fkV{$$S0RqY9*>Hcvb{&OlR_R`S!%2LXLpWAQK z$g5m$$R^otlNWftXrOsZi$0Z7J96i?nw!r#H7etrA_yBHaXGX5ZdqI9bJCWnFKJA1 zL)RcV@}vGjOWQ_2xTN7*QQM?(V_Vy#z%NPnnzo`ro+iB1ZI8g=KMR}{L{(NIc z&p+?gX_@8k`{)dDM9)dK~3{i)9 zOv0`{Wjqn_+Dh4Z+K~mvJi*ha6m zF{zR`gzJqi0#r(tes&+n%CWVp91E9SXKv-&<1cx**e*Uo{RoZxs)}Z=1IT@!dt|H(JtC-{bn?OofvdZ^1ySpv^koY>yX?_NVse}#$+35FiB*V9UdBeawC^9 z#v0RhxgGB-IQg{u7O@@-wohm?O$uI)Dc=vOT+uOY>tOrqPRs&Y<(S` z(=jEcFAlf+S8koY3K1hP2YQ;Y4SPi4xs}P76h+5W)XVCr?CNZMp8cn zrKbLB6wfNJ70E~OirxD*Y}evk@hwUM#inrE7eF-M@yB(9M@Fq zeyCj2P;^8Jy#BnaY}$1PVn;x=8;+9mgNb`icqkGl5j#PE$E|-p%%UWe21-(Kw-O^g zC4``*Mob=>7s>D-WG(|``ZEuw@^QhdnMTyDP_|#(u4f$H=I@-t2$)t)bkOR?ai9Bl z4S@Gqqt4%d_lvk-k43Ms8lj!_SpB6;9X=6Op*@UHiVx)p{rv}jHz2~|fFhb+Q^J82Q+4el zT*`#$1NLoy5$dwSa6_aZT2;Uk^EQGvk0&-lemh6E)BJe(>D`bp>BGLV?{dTgBKD-c zPVF7>4OsoGQQI|CMcdZd`|?fQ-z@ys6?VU4?<&UZ%Vq2F80t-sB8y{OFw&T3ldcF-G?Om_#7Lr_T~WE zI&lTRNm0T$zG^9aSfM}asASwy4WfU}1?`i6+c|b*-AL9J7ayG#pbJU99!i40#vV`V zq>5^bI&6-DS#4Xnpa!GFWA*z$SFQwqTTaW7DP7+bNpfh6N36OpY3onuwz|0c%GwD6w=D-aiKcU4%bL($f>m&Ve9QfhEjP^ssmZGuT zKztgLUV%VXhtf~^Xn+abh2*5Ae1QCHRo@itW%3?uB>g?((uX&NKO62m0<#W0sLBNN zea(2{qeHZq$pu|#t&J#ddqD!-ari+WQr2%v)6zT>@7_?g@lV#=k3`BBq?w?8vYk373)>D( z$#*TG^*B~Hn4}qDrq27V3=J8U(rWqK& z#%TQI=6kQ4=dmL@ULUF=w4dP+JG%7;uXK$WnP2}=~{7p>#r|&gd(`&Xbli^nhM43IUuXnLkenkch z71%l2AI4~xsfbx#a)qWu_g!+yZW#{o&!auQND0(82e?@9eAy9L&=aOW1mnXf)6QoE zE2i1I;bb>p`d^(n3GS-_TXi?Dw5w(K^iUZHf^sFkXE>82-VUNO$&e5T(};HcWEM$gXx0=)8}>g6O^Ey*e|MXD-it! zHIAqFigCggWF2$S)*`9}t_@qG=~bi>;pvU?QXTcfo4LWM>)M-p*Ny^uNri8dV=fH2 z%pU$gYz=?E$CaE>c0SQtP6q}o%WuPHCiP50F;y~F2GkOEeY^HTns@$=>I=zOWDV}aEjYp5Ebx_A7FSg(@)nyyIt zUm*%m!Q=E|WN*@vcA&p~H(!L;=+$B!Qc@XhYB`9gICx_*Pd-E0>Hzfk>d? zHadTVq=D4%vZvJm)~+5ID_!r%u%(_d5YuLagltouebAO73*{-ug)~SmRz&4+bxh5}s=B!&gYwv-+0A5BHXd2>?Zld?nEBp8*k8o(b zaSQR*zSqyXNI=_GC|WWq$GL-?G5k?4fY0DJL4&_2$j=IPa8bk85&80bmt`fla-DEi z_c9(Hb_n65FEvcC@g-)O;m03dqJM_?5|egfLM3aj6iWWA*LAqJ5|n+6t$FN2>v)IB zN(Igzzp`IWn>-iyn_b_&dd6~A4fI+S<;CfM5-xZ1TB=xdk{ddCQ~-_%7dJ3-mA9Kn z-o2w^gZRNzjCSMQ(4#IA51c)2=P9<=E)|e^;n>C`td&9ePqm7{N_oG%@_y$vUF?03 z&?7FdIbRawH+fLVZ4KY;eMemn>wCE#Vn9Q0o#I7?F1D6jk<{dE)}$Y`Cl1L1}2dHwcw_ zbb-%8Y5?0V!5KSB;q?v5SWYrhla91K77f|=sq6^}l{8X*<~fqR?BH#g&9-%io(+XZ zfERjR&u}WO#y$l!Sf2RjtmdbTHX%pFB3S;0$>(ulzt7>^ueJMLVw64N)OXs!H`c7_ z!)F-&7T42ZafEYf?i80|lWByR51kS6v}%R`RMQkcWA*W1%T{58B`QNbfiG=yO#oSA zGI8Ib!CvV*D1m*@j?pn`BX-k~4h7v=^>xud(ErQYle{l%m?$wYJh(A1bkv_<;$!^3 zpZgyb_Y~tPMv?-6@jooy86fnZ%ms*%{Oj!g8`#q%?E>hC{#Vo`4FfnZ;ZKvU0Gtf} ruzaQezLep=d>;meAx@G779)j@`m=x7KL!T&KNbB11EZJj-_!pANyYhn delta 6005 zcmV-*7mDcSK>IcgP)h>@3IG5I005VGr;!aK1DANGkuxL%mw2a zVh1ySd0<>sx&M84mV0M9X{TwYZJMN=?nx#~N!zrf(9%^RNm`n;B~+GaGEJtP%!HXq z+9FhzDk`GzP!W)VxZo2}@JYg>kfN4?Ad36rxuPhW=yO34fxh24_s(RJCdePT_slup zIp6mCmUHvOTMrHcSSBCzVIN-bqX;jm(Mv9W;N(dYFI)J7A0E7-CjaQipYVU`@n=7O z{>6_3{%YcHYS&-X^sC%;>=O0!?~33bYV?{50+{%xA0fQ1X8xr{Z}{;h-ZF8LKLnf> z;TAD0ahc*)Lysk1OH30t`NR^RA9KZT$|OG)Lqp*6+QsA zVoR1-QejD@B~^+hq8`=iQKJZJEvd6)sU@eWse1SEgIBp9T1(DS^y@5tS#QY(OEy}v$&$^A;$4=U?UyEbw7~^)`GLMf zG#Ojh)s+^^7$I!pLrumqnGve3sWgw9)E&!ii**jzzg!iSWT@bG{=*FF$%Cd zmTr&kPH?8UIn^0W?1-l0>bEoL&i2GJg0klB)IeP_nu*pO=!?5A(c$VI+bWe z@%?Kst4*OpDklijPGLkmn0 zsyLNObLmNCvPzwC&hT$K&>8E0%f?g5j44}b_%q_kcy^7p%??w}6`0w0Z!Fc%17?nM zev{V2d!X-Z&4UA5!CB+dYGO}kB9)<*W;zz_+P-nCvPR{u^#UVyKrnB_kG7-RZT5LN zDYSQY|DHWDYHX-&-oEIBSlOzVRx708pA1!U&BT&6S5L*R^-3PAFWR4fiM7Rhl_2M9 z3H1z-cs}jWo9X5*dSv6aO`D0c@r=BS3vL2#4^ML_Gs*_L#-mll66c0!I=zq#b}1#? ziCB_9j5r^%kAHh9hB}ewOdIDIhKyQWe=r*(g^}W8u1ytB)v4Ka>2&nqmi}yCf0kQf z(caZcM4E*LV`TIvvYIu2WifW|CUzX#IlI?u19OY3vp;R(ZWH%0F`2TB3MvCmY>Um> zfCJG)zcS$F@lmr&QyGf8FLxX@C>hUSyKG{wK9V4HJ0fgo-`1?1XfN}v(PczC9fGY} z+8EuILfJ;Gx2M83zKgcb>9MYTo!)GpVx?328H+kMaLDk;#1f2uXq$|@?5O3EGWxD2 z=alwM=e1K=qE`-biimOiqE~lzY~|{liqRQkXY^oSDxS=4>2s_hdz2sh6pSY#R9II- zTA@uNIlEy?Ypb$hsy!E^{~mIm_K6irbHsv z9ZjrDclY-)8|OoRPOz#eN&CmU!YW~fD|-7g+3@aIIGIY;B)KIUABcsc$*ypMIX9f` zi6+AhD^@IPsH_d(LpU5j8kBi^Kz87&fb5j>)bt_s_%H!7L52@VhnydfT{hwM0o*V? zwH@Q6k@p1T0=Y0C7h%AZivtoBB75$?$tP-KXF$5R5x3!gh@eVGe>kUOG^~*qjwh*D zES#pHV&Pp&tHbpd)Cz)Q@fyHg_@ZE$j@{9R(0ox9mEryIY)?3vrM045P9JiT>Np>rI zE0b(*-(0h*vNpVqavn_ehco?JU>>13I9eNGc$G zxG{kLz>Um$DK=ub1w+90_hHnM%C{8eKk9M8HxV96|thAF*el4{}VIwRDU9&gNZWtC%VF&sbn@vQ;!0S-p2j2v~S1prl4gM=eP6U zzj2>`I%jP_E|vENUTRV5c?qKar|_#LE@(`y6rKDk15YRvfoJf%7Jr84pHIFHP~4d?O#&bwpT{jpdw zyi~KLb(Hf|@d(J3!hon$RkOf@IUiMzK*NrIYo*aPmIj+P=eF2^XlFKYFnoGAo{jZp zYQu^q%zR%NkgMge0*bCKmFfJ}f6Kce@l2d;D7S`}al?{!hEH!ac`)p33Ac>Hsi9V3D!b0lBxYk)qNJ^gjr*9e!U4f4Yj0<&@8A~p zCZ;}F^{VA+G`>7`f26t|cJg^kclJcn8Rd*DBP^Qk+F<|Y=^n!JqE&=O^C`p*(Q3P; zb{eWV6%!L`*}T!dKFz&mVxym0BUdXcHND-kl}*`GlzD%ek?a^mD?BNi%9k{Ms=q%S z?bFTd`pOBq>f%w;Thh8r7d1Dvw>NLPXjALPrgiMcjt3zdN{%kQsq_ItSBHFopbg3X@%=F4%& z+1v#e>4Dj$x58Ii?EVajj>6MX>>Yx6tg7^WxbEYsOP^Rw)qp0dcMhh1qXi{s)u+#} zPjF6GqxVrw!4(|4VfcL>9$PvB&PEeESMyGo52| zhh3`=JLDXeRGRa>xM~Q0fvTe@>TnHV^8Jvi2QY;~R}}|oTjlZ6K};RtHJe;OaJcE- zAWxdf*>ZASL~bK0EzYa77$4EL9xcUnjuboSbLBICRivz3X;nN{s}IsBAJQjR*_8Q{ z{rIRhmKuGGJPbWjo^@$%Ud~+WnDBas-*r60!}pTB*5!`Yj<2eJ${ejj?s3$Hp#iNioFL|HgbA&HHLT|2~dS zXoYil@Q~`0G^09i22FW04#?+`*>y4o|S9y~7*a-rixl+B+;)drP%ddNWM-U2wZ@Xs@asLit#~{fPSh z7`6Bbmf@!bQZ3I*wH%+po#a1{a($Na*``_o<0K;5RJ73o7<|xp7@2XY85yHOF79u2 zR9MS=YL$9_KIf#gc-| zDEesEVqFX&?~R;*6&b$8vBo@QjmYp+oXpv0zCH7QFc!49)|5wv@5G+!@<@68*RXI9 zi`uHo>$!P>B0Y-59Ya`BTrr5s@rTnwK_nN=|jh-tQny^?2@}q-f|SRq^N7H zDPC$b8pLTeJYW#@HIZRHs~g=V?%@WHtHB%chCFv-UWq&8t#34IN=&uRmrIY99rp6T zUsjQS#d5lj>2HPJsx@xtC|)^)Rmb={=)KdKIbF>tjT;+1CGH2Xy3t$W{Tj{~#F;yT z-UidvV1=v_4=u5##KVz0WF9tU*+bqoSA#F)Q*-rPEY$=4_J+(stU33v=|1eED8D{z z@%c!J=iWS$Zef~$xZo2HrV+`d;=>{-LPREiW0?f8R;FSz6WJaKp-*Pwdd`1R%5X%= z@gt(%yAALQ(pbZ$6?3VfM= zs~&ul1@Rt^yt0K6`4x_QvVutdDo2(ATn?Zd-HZDO%7|=bLcN>7Jc3^^tumqERYLcE zRduM{1x&L;@KB!}cz~(aEA?!39^`qZj-Xwb;`2>?6Q+ryva0fRcvPA&bw+)Nb0!{E zD~y!au<#9(Gf7N6$r|PxO~K@Qo{3?9MfV0ue~-hrAuG zh35`p?U({C8xW9<1(~2IADTr@XsXdSXfb09n{PR6b~3?)pYgwR(C>JdZj1H>&+5-V|p@N zz$l1)8&5chUh7|DK1`bHg!)?re$7Ew6LdIguH7ZbLRAISM zhtiH5}Ybt92R<9u0>nFee99(wV9}JafhIZIVY z)z3Ba3cI?0#adHcP9qIsXM?+1U1E0zeUDOyMyE$~--$|BgBdb|zB^IESoGG1%<6L8 znz`KU;8+`UulSR~)~ueFN>v#>Ml<|I3j#(fW*A$r(AbJvV;fc(?bu{&$JrdWa<1Jt zPupS}#XHSO)F!VkHCk`4F6y}(;Wp>;85tQrLXsN(i$ZL{rfV6#h zw>-(?%-nr(SVh8lx@YmJR6Mq4`96N&nCvzuM;;qp-8(cc7e;g$ZK)m&%)P;duA|F7ddQUOR~Q>~t&3>sEO-r_GSJ=VE1e8|TW_&uLhH za-@-exZsp_zuLj_DfM_8Z~8F0;4}7Mnz0vU#y+|wfoda(dLxCEMjzH1X*{9x1-y*BmYfk5oYFX)RVVS4{!YcLk&ywkl#4UMw8)x zRyLYyHx{F#|C#)U#I#G3BEJ)?Mb;wwwdj?{@OqsmIW0tFTVNvgVo1)Hd-$B%PikSZ{GRF6Csqr+f zHojj_yAS8>aoDkk8vU>HweB!}ru`N~7C+Zt{;F`kQ@fk7s-SlJSeV~HsrvL%XwYBa zmySU%=P@cxAE_Sp_TB85uS;i%VQ-?qq%jTXY7OYt8pouk-0^3sJO0vDX3b20-l+H3 z8RUhWp-EfZJz{9LV`z6|5IuUJSn5Gdt~$EMH}$V*=4Ub0_$@*IJ1jC@M2+zhRv0fc z!@q*Z^2-l>(oR$^<052>608mQ-0tx^M000O80GD{DlhqzG1DANGlM5d-1DANG zlR_Ujlfxe#lb9b7leh#BEKo}U0u%rg00;;O0GD{DM%SdioR$^<052>603ZMW00000 j000000000$1CwzFB9l-c2o41R1pq+-001N!00000rJ2PM diff --git a/MATLAB/+XPlaneConnect/sendVIEW.m b/MATLAB/+XPlaneConnect/sendVIEW.m new file mode 100644 index 0000000..d95814c --- /dev/null +++ b/MATLAB/+XPlaneConnect/sendVIEW.m @@ -0,0 +1,35 @@ +function sendVIEW(view, socket) +% sendVIEW Sets the camera +% +%Inputs +% view: The view to use. +% socket (optional): The client to use when sending the command. +% +%Use +% 1. import XPlaneConnect.*; +% 2. sendView(Forwards); +% +% Contributors +% [JW] Jason Watkins + +import XPlaneConnect.* + +%% Get client +global clients; +if ~exist('socket', 'var') + assert(isequal(length(clients) < 2, 1), '[pauseSim] ERROR: Multiple clients open. You must specify which client to use.'); + if isempty(clients) + socket = openUDP(); + else + socket = clients(1); + end +end + +%% Validate input + + +%% Send command +socket.sendVIEW(view) + +end + diff --git a/TestScripts/MATLAB Tests/sendVIEWTest.m b/TestScripts/MATLAB Tests/sendVIEWTest.m new file mode 100644 index 0000000..4cfe29c --- /dev/null +++ b/TestScripts/MATLAB Tests/sendVIEWTest.m @@ -0,0 +1,26 @@ +function sendVIEWTest() +%% Setup +addpath('../../MATLAB') +import XPlaneConnect.* + +if ~exist('gov.nasa.xpc.ViewType', 'class') + [folder, ~, ~] = fileparts(which('XPlaneConnect.openUDP')); + javaaddpath(fullfile(folder, 'XPlaneConnect.jar')); +end + +dref = 'sim/graphics/view/view_type'; +fwd = 1000; +chase = 1017; + +%% Excecute +sendVIEW(gov.nasa.xpc.ViewType.Forwards); +result = getDREFs(dref); +assert(isequal(result, fwd)) + +sendVIEW(gov.nasa.xpc.ViewType.Chase); +result = getDREFs(dref); +assert(isequal(result, chase)) + + +end + diff --git a/TestScripts/MATLAB Tests/tests.m b/TestScripts/MATLAB Tests/tests.m index 6871686..11c8800 100644 --- a/TestScripts/MATLAB Tests/tests.m +++ b/TestScripts/MATLAB Tests/tests.m @@ -18,6 +18,7 @@ theTests = {{@openCloseTest, 'Open/Close Test', 0},... {@CTRLTest,'CTRL Test', 0},... {@POSITest,'POSI Test', 0},... {@sendWYPTTest,'WYPT Test', 0},... + {@sendVIEWTest,'VIEW Test', 0},... {@pauseTest,'Pause Test', 0},... {@setConnTest, 'setConn Test', 0}};