From 1fd6400a98a2840b05bde7574a278739c95672e8 Mon Sep 17 00:00:00 2001 From: Kai Lehmkuehler Date: Wed, 6 Nov 2019 17:45:54 +0100 Subject: [PATCH] Terrain height probe (#186) * ignore binaries * Add terrain probe * requested changes part 1 * try mac os build check * Revert "try mac os build check" This reverts commit 46fa8adde4f825c3a7f2a8bea7f543ad55a79765. * update debug message label --- .gitignore | 3 +- xpcPlugin/Message.cpp | 2 +- xpcPlugin/MessageHandlers.cpp | 116 ++++++++++++++++-- xpcPlugin/MessageHandlers.h | 1 + xpcPlugin/xpcPlugin.xcodeproj/project.pbxproj | 8 ++ 5 files changed, 116 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index d77d831..8c184fe 100644 --- a/.gitignore +++ b/.gitignore @@ -92,4 +92,5 @@ out/ # Internal Docs # ################# -Docs/~$Capability Matrix.xlsx \ No newline at end of file +Docs/~$Capability Matrix.xlsx +*.xpl diff --git a/xpcPlugin/Message.cpp b/xpcPlugin/Message.cpp index eb28fe4..c1eb448 100644 --- a/xpcPlugin/Message.cpp +++ b/xpcPlugin/Message.cpp @@ -121,7 +121,7 @@ namespace XPC } Log::WriteLine(LOG_DEBUG, "DBUG", ss.str()); } - else if (head == "GETC" || head == "GETP") + else if (head == "GETC" || head == "GETP" || head == "GETT") { ss << " Aircraft:" << (int)buffer[5]; Log::WriteLine(LOG_DEBUG, "DBUG", ss.str()); diff --git a/xpcPlugin/MessageHandlers.cpp b/xpcPlugin/MessageHandlers.cpp index dc386fd..c6e7053 100644 --- a/xpcPlugin/MessageHandlers.cpp +++ b/xpcPlugin/MessageHandlers.cpp @@ -8,21 +8,21 @@ // 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. +// * 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 "XPLMScenery.h" #include "XPLMGraphics.h" - #include #include #include @@ -41,6 +41,9 @@ namespace XPC UDPSocket* MessageHandlers::sock; static sockaddr multicast_address = UDPSocket::GetAddr(MULTICAST_GROUP, MULITCAST_PORT); + + // define a static terrain probe handler (do not re-create probe for each query) + XPLMProbeRef Terrain_probe = nullptr; void MessageHandlers::SetSocket(UDPSocket* socket) { @@ -66,6 +69,7 @@ namespace XPC handlers.insert(std::make_pair("VIEW", MessageHandlers::HandleView)); handlers.insert(std::make_pair("GETC", MessageHandlers::HandleGetC)); handlers.insert(std::make_pair("GETP", MessageHandlers::HandleGetP)); + handlers.insert(std::make_pair("GETT", MessageHandlers::HandleGetT)); // X-Plane data messages handlers.insert(std::make_pair("DSEL", MessageHandlers::HandleXPlaneData)); handlers.insert(std::make_pair("USEL", MessageHandlers::HandleXPlaneData)); @@ -626,6 +630,94 @@ namespace XPC } } } + + void MessageHandlers::HandleGetT(const Message& msg) + { + const unsigned char* buffer = msg.GetBuffer(); + std::size_t size = msg.GetSize(); + if (size != 30) + { + Log::FormatLine(LOG_ERROR, "GETT", "Unexpected message length: %u", size); + return; + } + unsigned char aircraft = buffer[5]; + Log::FormatLine(LOG_TRACE, "GETT", "Getting terrain information for aircraft %u", aircraft); + + double loc[3]; + double X; + double Y; + double Z; + memcpy(loc, buffer + 6, 24); + + if(loc[0] == -998 || loc[1] == -998 || loc[2] == -998) + { + // get terrain properties at aircraft location + // probe needs to be below terrain to work... + X = DataManager::GetDouble(DREF_LocalX, aircraft); + Z = DataManager::GetDouble(DREF_LocalZ, aircraft); + Y = -100.0; + } + else + { + // terrain probe at specified location + XPLMWorldToLocal(loc[0], loc[1], loc[2], &X, &Y, &Z); + } + + // Init terrain probe (if required) and probe data struct + XPLMProbeInfo_t probe_data; + probe_data.structSize = sizeof(XPLMProbeInfo_t); + + if(Terrain_probe == nullptr) + { + Log::FormatLine(LOG_TRACE, "GETT", "Create terrain probe for aircraft %u", aircraft); + Terrain_probe = XPLMCreateProbe(0); + } + + // query probe + int rc = XPLMProbeTerrainXYZ(Terrain_probe, X, Y, Z, &probe_data); + + // transform probe location to world coordinates + double lat; + double lon; + double alt; + + if(rc == 0) + { + XPLMLocalToWorld(probe_data.locationX, probe_data.locationY, probe_data.locationZ, &lat, &lon, &alt); + + Log::FormatLine(LOG_TRACE, "GETT", "Probe LLA %lf %lf %lf", lat, lon, alt); + } + else + { + lat = -998; + lon = -998; + alt = -998; + + Log::FormatLine(LOG_TRACE, "GETT", "Probe failed. Return Value %u", rc); + } + + // keep probe for next query + // XPLMDestroyProbe(probe); + + // Assemble response message + unsigned char response[50] = "TERR"; + response[5] = aircraft; + // terrain height over msl at lat/lon point + memcpy(response + 6, &lat, 8); + memcpy(response + 14, &lon, 8); + memcpy(response + 22, &alt, 8); + // terrain incidence + memcpy(response + 30, &probe_data.normalX, 4); + memcpy(response + 34, &probe_data.normalY, 4); + memcpy(response + 38, &probe_data.normalZ, 4); + // terrain type + memcpy(response + 42, &probe_data.is_wet, 4); + // probe status + memcpy(response + 46, &rc, 4); + + sock->SendTo(response, 50, &connection.addr); + } + void MessageHandlers::HandleSimu(const Message& msg) { @@ -798,7 +890,7 @@ namespace XPC double dy = y - cY; double dz = z - cZ; -// Log::FormatLine(LOG_TRACE, "CAM", "Cam vect %f %f %f", dx, dy, dz); +// Log::FormatLine(LOG_TRACE, "CAM", "Cam vect %f %f %f", dx, dy, dz); double pi = 3.141592653589793; @@ -811,15 +903,15 @@ namespace XPC outCameraPosition->heading = 90 + angle; // rel to north -// Log::FormatLine(LOG_TRACE, "CAM", "Cam p %f hdg %f ", outCameraPosition->pitch, outCameraPosition->heading); +// Log::FormatLine(LOG_TRACE, "CAM", "Cam p %f hdg %f ", outCameraPosition->pitch, outCameraPosition->heading); outCameraPosition->roll = 0; } else { - outCameraPosition->roll = campos->direction[0]; - outCameraPosition->pitch = campos->direction[1]; - outCameraPosition->heading = campos->direction[2]; + outCameraPosition->roll = campos->direction[0]; + outCameraPosition->pitch = campos->direction[1]; + outCameraPosition->heading = campos->direction[2]; } outCameraPosition->zoom = campos->zoom; diff --git a/xpcPlugin/MessageHandlers.h b/xpcPlugin/MessageHandlers.h index a065c96..8753d00 100644 --- a/xpcPlugin/MessageHandlers.h +++ b/xpcPlugin/MessageHandlers.h @@ -56,6 +56,7 @@ namespace XPC static void HandleText(const Message& msg); static void HandleWypt(const Message& msg); static void HandleView(const Message& msg); + static void HandleGetT(const Message& msg); static void HandleXPlaneData(const Message& msg); static void HandleUnknown(const Message& msg); diff --git a/xpcPlugin/xpcPlugin.xcodeproj/project.pbxproj b/xpcPlugin/xpcPlugin.xcodeproj/project.pbxproj index 4a4fe23..a888911 100755 --- a/xpcPlugin/xpcPlugin.xcodeproj/project.pbxproj +++ b/xpcPlugin/xpcPlugin.xcodeproj/project.pbxproj @@ -230,6 +230,10 @@ MACH_O_TYPE = mh_bundle; MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DXPLM200", + ); OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS)", "-Wl,-exported_symbol", @@ -278,6 +282,10 @@ ); MACH_O_TYPE = mh_bundle; MACOSX_DEPLOYMENT_TARGET = 10.7; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DXPLM200", + ); OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS)", "-Wl,-exported_symbol",