Skip to content

Commit d61f70f

Browse files
authored
Improved HandleGetT accuracy
Also added the ground velocity output to TERR message so can handle landing on aircraft carrier (moving ground).
1 parent 377e19f commit d61f70f

1 file changed

Lines changed: 56 additions & 34 deletions

File tree

xpcPlugin/MessageHandlers.cpp

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -642,81 +642,103 @@ namespace XPC
642642
unsigned char aircraft = buffer[5];
643643
Log::FormatLine(LOG_TRACE, "GETT", "Getting terrain information for aircraft %u", aircraft);
644644

645-
double loc[3];
646-
double X;
647-
double Y;
648-
double Z;
649-
memcpy(loc, buffer + 6, 24);
645+
double pos[3];
646+
memcpy(pos, buffer + 6, 24);
650647

651-
if(loc[0] == -998 || loc[1] == -998 || loc[2] == -998)
648+
if(pos[0] == -998 || pos[1] == -998 || pos[2] == -998)
652649
{
653650
// get terrain properties at aircraft location
654-
// probe needs to be below terrain to work...
655-
X = DataManager::GetDouble(DREF_LocalX, aircraft);
656-
Z = DataManager::GetDouble(DREF_LocalZ, aircraft);
657-
Y = -100.0;
658-
}
659-
else
660-
{
661-
// terrain probe at specified location
662-
XPLMWorldToLocal(loc[0], loc[1], loc[2], &X, &Y, &Z);
651+
pos[0] = DataManager::GetDouble(DREF_Latitude, aircraft);
652+
pos[1] = DataManager::GetDouble(DREF_Longitude, aircraft);
653+
pos[2] = 0.0;
663654
}
655+
MessageHandlers::SendTerr(pos, aircraft);
656+
}
657+
658+
void MessageHandlers::SendTerr(double pos[3], char aircraft)
659+
{
660+
double lat, lon, alt, X, Y, Z;
664661

665662
// Init terrain probe (if required) and probe data struct
666-
XPLMProbeInfo_t probe_data;
663+
static XPLMProbeInfo_t probe_data;
667664
probe_data.structSize = sizeof(XPLMProbeInfo_t);
668665

669666
if(Terrain_probe == nullptr)
670667
{
671-
Log::FormatLine(LOG_TRACE, "GETT", "Create terrain probe for aircraft %u", aircraft);
668+
Log::FormatLine(LOG_TRACE, "TERR", "Create terrain probe for aircraft %u", aircraft);
672669
Terrain_probe = XPLMCreateProbe(0);
673670
}
674671

672+
// terrain probe at specified location
673+
// Follow the process in the following post to get accurate results
674+
// https://forums.x-plane.org/index.php?/forums/topic/38688-how-do-i-use-xplmprobeterrainxyz/&page=2
675+
676+
// transform probe location to local coordinates
677+
// Step 1. Convert initial lat/lon/alt to XYZ
678+
XPLMWorldToLocal(pos[0], pos[1], pos[2], &X, &Y, &Z);
679+
675680
// query probe
681+
// Step 2. Probe XYZ to get a new Y
676682
int rc = XPLMProbeTerrainXYZ(Terrain_probe, X, Y, Z, &probe_data);
677-
683+
if(rc > 0)
684+
{
685+
Log::FormatLine(LOG_ERROR, "TERR", "Probe failed. Return Value %u", rc);
686+
XPLMDestroyProbe(Terrain_probe);
687+
return;
688+
}
689+
678690
// transform probe location to world coordinates
679-
double lat;
680-
double lon;
681-
double alt;
682-
691+
// Step 3. Convert that new XYZ back to LLE
692+
XPLMLocalToWorld(probe_data.locationX, probe_data.locationY, probe_data.locationZ, &lat, &lon, &alt);
693+
Log::FormatLine(LOG_TRACE, "TERR", "Conv LLA=%f, %f, %f", lat, lon, alt);
694+
695+
// transform probe location to local coordinates
696+
// Step 4. NOW convert your origina lat/lon with the elevation from step 3 to XYZ
697+
XPLMWorldToLocal(pos[0], pos[1], alt, &X, &Y, &Z);
698+
699+
// query probe
700+
// Step 5. Re-probe with the NEW XYZ
701+
rc = XPLMProbeTerrainXYZ(Terrain_probe, X, Y, Z, &probe_data);
683702
if(rc == 0)
684703
{
704+
// transform probe location to world coordinates
705+
// Step 6. You now have a new Y, and your XYZ will be closer to correct for high elevations far from the origin.
685706
XPLMLocalToWorld(probe_data.locationX, probe_data.locationY, probe_data.locationZ, &lat, &lon, &alt);
686-
687-
Log::FormatLine(LOG_TRACE, "GETT", "Probe LLA %lf %lf %lf", lat, lon, alt);
707+
Log::FormatLine(LOG_TRACE, "TERR", "Probe LLA %lf %lf %lf", lat, lon, alt);
688708
}
689709
else
690710
{
691711
lat = -998;
692712
lon = -998;
693713
alt = -998;
694-
695-
Log::FormatLine(LOG_TRACE, "GETT", "Probe failed. Return Value %u", rc);
714+
Log::FormatLine(LOG_TRACE, "TERR", "Probe failed. Return Value %u", rc);
696715
}
697716

698717
// keep probe for next query
699-
// XPLMDestroyProbe(probe);
718+
// XPLMDestroyProbe(Terrain_probe);
700719

701720
// Assemble response message
702-
unsigned char response[50] = "TERR";
721+
unsigned char response[62] = "TERR";
703722
response[5] = aircraft;
704723
// terrain height over msl at lat/lon point
705724
memcpy(response + 6, &lat, 8);
706725
memcpy(response + 14, &lon, 8);
707726
memcpy(response + 22, &alt, 8);
708-
// terrain incidence
727+
// terrain normal vector
709728
memcpy(response + 30, &probe_data.normalX, 4);
710729
memcpy(response + 34, &probe_data.normalY, 4);
711730
memcpy(response + 38, &probe_data.normalZ, 4);
731+
// terrain velocity
732+
memcpy(response + 42, &probe_data.velocityX, 4);
733+
memcpy(response + 46, &probe_data.velocityY, 4);
734+
memcpy(response + 50, &probe_data.velocityZ, 4);
712735
// terrain type
713-
memcpy(response + 42, &probe_data.is_wet, 4);
736+
memcpy(response + 54, &probe_data.is_wet, 4);
714737
// probe status
715-
memcpy(response + 46, &rc, 4);
716-
717-
sock->SendTo(response, 50, &connection.addr);
718-
}
738+
memcpy(response + 58, &rc, 4);
719739

740+
sock->SendTo(response, 62, &connection.addr);
741+
}
720742

721743
void MessageHandlers::HandleSimu(const Message& msg)
722744
{

0 commit comments

Comments
 (0)