sendPOSI command change (double for lat/lon/h) (#111)

* Updated POSI to use doubles for lat/lon/alt, as step size for floats was unacceptably large at high longitudes.
This commit is contained in:
Jan Zwiener
2017-06-28 21:04:59 +02:00
committed by Jason Watkins
parent 48656f2b4c
commit 0e493920fa
27 changed files with 201 additions and 143 deletions

View File

@@ -658,7 +658,7 @@ namespace XPC
}
}
void DataManager::SetPosition(float pos[3], char aircraft)
void DataManager::SetPosition(double pos[3], char aircraft)
{
Log::FormatLine(LOG_INFO, "DMAN", "Setting position (%f, %f, %f) for aircraft %i",
pos[0], pos[1], pos[2], aircraft);
@@ -670,15 +670,15 @@ namespace XPC
if (IsDefault(pos[0]))
{
pos[0] = (float)GetDouble(DREF_Latitude, aircraft);
pos[0] = GetDouble(DREF_Latitude, aircraft);
}
if (IsDefault(pos[1]))
{
pos[1] = (float)GetDouble(DREF_Longitude, aircraft);
pos[1] = GetDouble(DREF_Longitude, aircraft);
}
if (IsDefault(pos[2]))
{
pos[2] = (float)GetDouble(DREF_Elevation, aircraft);
pos[2] = GetDouble(DREF_Elevation, aircraft);
}
// See: http://www.xsquawkbox.net/xpsdk/mediawiki/MovingThePlane
@@ -700,9 +700,9 @@ namespace XPC
Set(DREF_LocalY, local[1], aircraft);
Set(DREF_LocalZ, local[2], aircraft);
// If the sim is unpaused, this will override the above settings.
Set(DREF_Latitude, (double)pos[0], aircraft);
Set(DREF_Longitude, (double)pos[1], aircraft);
Set(DREF_Elevation, (double)pos[2], aircraft);
Set(DREF_Latitude, pos[0], aircraft);
Set(DREF_Longitude, pos[1], aircraft);
Set(DREF_Elevation, pos[2], aircraft);
// Now reset orientation to update q
SetOrientation(orient, aircraft);
@@ -785,7 +785,7 @@ namespace XPC
return -998.0F;
}
bool DataManager::IsDefault(float value)
bool DataManager::IsDefault(double value)
{
return value < -997.9 && value > -999.1;
}

View File

@@ -396,7 +396,7 @@ namespace XPC
/// \param pos An array containing latitude, longitude and altitude in
/// fractional degrees and meters above sea level.
/// \param aircraft The aircraft to set the position of.
static void SetPosition(float pos[3], char aircraft = 0);
static void SetPosition(double pos[3], char aircraft = 0);
/// Sets the orientation of the specified aircraft.
///
@@ -417,7 +417,7 @@ namespace XPC
///
/// \param value The value to check.
/// \returns true if value is a default value; otherwise false.
static bool IsDefault(float value);
static bool IsDefault(double value);
};
}
#endif

View File

@@ -342,10 +342,11 @@ namespace XPC
}
case 20: // Position
{
float pos[3];
pos[0] = values[i][2];
pos[1] = values[i][3];
pos[2] = values[i][4];
// TODO: loss of precision here
double pos[3];
pos[0] = (double)values[i][2];
pos[1] = (double)values[i][3];
pos[2] = (double)values[i][4];
DataManager::SetPosition(pos);
break;
}
@@ -439,7 +440,7 @@ namespace XPC
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);
@@ -524,13 +525,14 @@ namespace XPC
unsigned char response[34] = "POSI";
response[5] = (char)DataManager::GetInt(DREF_GearHandle, aircraft);
// TODO change lat/lon/h to double?
*((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];
@@ -545,18 +547,29 @@ namespace XPC
const unsigned char* buffer = msg.GetBuffer();
const std::size_t size = msg.GetSize();
if (size < 34)
{
Log::FormatLine(LOG_ERROR, "POSI", "ERROR: Unexpected size: %i (Expected at least 34)", size);
return;
}
char aircraftNumber = buffer[5];
float gear = *((float*)(buffer + 30));
float pos[3];
float gear = *((float*)(buffer + 42));
double posd[3];
float orient[3];
memcpy(pos, buffer + 6, 12);
memcpy(orient, buffer + 18, 12);
if (size == 34) /* lat/lon/h as 32-bit float */
{
posd[0] = *((float*)&buffer[6]);
posd[1] = *((float*)&buffer[10]);
posd[2] = *((float*)&buffer[14]);
memcpy(orient, buffer + 18, 12);
}
else if (size == 46) /* lat/lon/h as 64-bit double */
{
memcpy(posd, buffer + 6, 3*8);
memcpy(orient, buffer + 30, 12);
}
else
{
Log::FormatLine(LOG_ERROR, "POSI", "ERROR: Unexpected size: %i (Expected 34 or 46)", size);
return;
}
if (aircraftNumber > 0)
{
@@ -570,7 +583,8 @@ namespace XPC
}
}
DataManager::SetPosition(pos, aircraftNumber);
/* convert float to double */
DataManager::SetPosition(posd, aircraftNumber);
DataManager::SetOrientation(orient, aircraftNumber);
if (gear >= 0)
{
@@ -589,7 +603,7 @@ namespace XPC
Log::FormatLine(LOG_ERROR, "SIMU", "ERROR: Invalid argument: %i", v);
return;
}
int value[20];
if (v == 2)
{