Actually send all information
This commit is contained in:
parent
5e07bfa54a
commit
2d157a0048
3 changed files with 78 additions and 168 deletions
26
.vscode/settings.json
vendored
26
.vscode/settings.json
vendored
|
@ -18,6 +18,30 @@
|
|||
"xstddef": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xstring": "cpp"
|
||||
"xstring": "cpp",
|
||||
"atomic": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"ctime": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xmemory": "cpp"
|
||||
}
|
||||
}
|
|
@ -74,6 +74,11 @@ public:
|
|||
|
||||
void send(std::string msg)
|
||||
{
|
||||
if (!has_end_point())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.length() > 1024)
|
||||
{
|
||||
throw std::runtime_error("msg is too long: " + msg.length());
|
||||
|
@ -87,6 +92,10 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool has_end_point()
|
||||
{
|
||||
return SenderAddr.sin_port != 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _SOCKET_HPP_
|
|
@ -18,8 +18,17 @@ extern "C" __declspec(dllexport)
|
|||
|
||||
extern "C" __declspec(dllexport) void __cdecl DestroyPluginObject(PluginObject *obj) { delete ((RFServerPlugin *)obj); }
|
||||
|
||||
// RFServerPlugin class
|
||||
std::string format_float(double d, int precision)
|
||||
{
|
||||
std::stringstream sstream;
|
||||
|
||||
sstream << d;
|
||||
sstream.precision(precision);
|
||||
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
// RFServerPlugin class
|
||||
RFServerPlugin::RFServerPlugin()
|
||||
{
|
||||
socket = new Socket(6262);
|
||||
|
@ -56,183 +65,51 @@ void RFServerPlugin::ExitRealtime()
|
|||
|
||||
void RFServerPlugin::UpdateTelemetry(const TelemInfoV01 &info)
|
||||
{
|
||||
// Use the incoming data, for now I'll just write some of it to a file to a) make sure it
|
||||
// is working, and b) explain the coordinate system a little bit (see header for more info)
|
||||
FILE *fo = fopen("ExampleInternalsTelemetryOutput.txt", "a");
|
||||
if (fo != NULL)
|
||||
{
|
||||
// Delta time is variable, as we send out the info once per frame
|
||||
fprintf(fo, "DT=%.4f ET=%.4f\n", info.mDeltaTime, info.mElapsedTime);
|
||||
fprintf(fo, "Lap=%d StartET=%.3f\n", info.mLapNumber, info.mLapStartET);
|
||||
fprintf(fo, "Vehicle=%s\n", info.mVehicleName);
|
||||
fprintf(fo, "Track=%s\n", info.mTrackName);
|
||||
fprintf(fo, "Pos=(%.3f,%.3f,%.3f)\n", info.mPos.x, info.mPos.y, info.mPos.z);
|
||||
std::string msg = "[TELEMETRY;";
|
||||
msg += format_float(info.mElapsedTime, 3) + ";";
|
||||
msg += format_float(info.mLapStartET, 3) + ";";
|
||||
msg += info.mLapNumber + ";";
|
||||
msg += format_float(100.0 * info.mFilteredThrottle, 1) + ";";
|
||||
msg += format_float(100.0 * info.mFilteredBrake, 1) + ";";
|
||||
msg += format_float(info.mFuel, 1) + ";";
|
||||
msg += info.mScheduledStops;
|
||||
msg += "]";
|
||||
|
||||
// Forward is roughly in the -z direction (although current pitch of car may cause some y-direction velocity)
|
||||
fprintf(fo, "LocalVel=(%.2f,%.2f,%.2f)\n", info.mLocalVel.x, info.mLocalVel.y, info.mLocalVel.z);
|
||||
fprintf(fo, "LocalAccel=(%.1f,%.1f,%.1f)\n", info.mLocalAccel.x, info.mLocalAccel.y, info.mLocalAccel.z);
|
||||
|
||||
// Orientation matrix is left-handed
|
||||
fprintf(fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[0].x, info.mOri[0].y, info.mOri[0].z);
|
||||
fprintf(fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[1].x, info.mOri[1].y, info.mOri[1].z);
|
||||
fprintf(fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[2].x, info.mOri[2].y, info.mOri[2].z);
|
||||
fprintf(fo, "LocalRot=(%.3f,%.3f,%.3f)\n", info.mLocalRot.x, info.mLocalRot.y, info.mLocalRot.z);
|
||||
fprintf(fo, "LocalRotAccel=(%.2f,%.2f,%.2f)\n", info.mLocalRotAccel.x, info.mLocalRotAccel.y, info.mLocalRotAccel.z);
|
||||
|
||||
// Vehicle status
|
||||
fprintf(fo, "Gear=%d RPM=%.1f RevLimit=%.1f\n", info.mGear, info.mEngineRPM, info.mEngineMaxRPM);
|
||||
fprintf(fo, "Water=%.1f Oil=%.1f\n", info.mEngineWaterTemp, info.mEngineOilTemp);
|
||||
fprintf(fo, "ClutchRPM=%.1f\n", info.mClutchRPM);
|
||||
|
||||
// Driver input
|
||||
fprintf(fo, "UnfilteredThrottle=%.1f%%\n", 100.0 * info.mUnfilteredThrottle);
|
||||
fprintf(fo, "UnfilteredBrake=%.1f%%\n", 100.0 * info.mUnfilteredBrake);
|
||||
fprintf(fo, "UnfilteredSteering=%.1f%%\n", 100.0 * info.mUnfilteredSteering);
|
||||
fprintf(fo, "UnfilteredClutch=%.1f%%\n", 100.0 * info.mUnfilteredClutch);
|
||||
|
||||
// Filtered input
|
||||
fprintf(fo, "FilteredThrottle=%.1f%%\n", 100.0 * info.mFilteredThrottle);
|
||||
fprintf(fo, "FilteredBrake=%.1f%%\n", 100.0 * info.mFilteredBrake);
|
||||
fprintf(fo, "FilteredSteering=%.1f%%\n", 100.0 * info.mFilteredSteering);
|
||||
fprintf(fo, "FilteredClutch=%.1f%%\n", 100.0 * info.mFilteredClutch);
|
||||
|
||||
// Misc
|
||||
fprintf(fo, "SteeringShaftTorque=%.1f\n", info.mSteeringShaftTorque);
|
||||
fprintf(fo, "Front3rdDeflection=%.3f Rear3rdDeflection=%.3f\n", info.mFront3rdDeflection, info.mRear3rdDeflection);
|
||||
|
||||
// Aerodynamics
|
||||
fprintf(fo, "FrontWingHeight=%.3f FrontRideHeight=%.3f RearRideHeight=%.3f\n", info.mFrontWingHeight, info.mFrontRideHeight, info.mRearRideHeight);
|
||||
fprintf(fo, "Drag=%.1f FrontDownforce=%.1f RearDownforce=%.1f\n", info.mDrag, info.mFrontDownforce, info.mRearDownforce);
|
||||
|
||||
// Other
|
||||
fprintf(fo, "Fuel=%.1f ScheduledStops=%d Overheating=%d Detached=%d\n", info.mFuel, info.mScheduledStops, info.mOverheating, info.mDetached);
|
||||
fprintf(fo, "Dents=(%d,%d,%d,%d,%d,%d,%d,%d)\n", info.mDentSeverity[0], info.mDentSeverity[1], info.mDentSeverity[2], info.mDentSeverity[3],
|
||||
info.mDentSeverity[4], info.mDentSeverity[5], info.mDentSeverity[6], info.mDentSeverity[7]);
|
||||
fprintf(fo, "LastImpactET=%.1f Mag=%.1f, Pos=(%.1f,%.1f,%.1f)\n", info.mLastImpactET, info.mLastImpactMagnitude,
|
||||
info.mLastImpactPos.x, info.mLastImpactPos.y, info.mLastImpactPos.z);
|
||||
|
||||
// Wheels
|
||||
for (long i = 0; i < 4; ++i)
|
||||
{
|
||||
const TelemWheelV01 &wheel = info.mWheel[i];
|
||||
fprintf(fo, "Wheel=%s\n", (i == 0) ? "FrontLeft" : (i == 1) ? "FrontRight"
|
||||
: (i == 2) ? "RearLeft"
|
||||
: "RearRight");
|
||||
fprintf(fo, " SuspensionDeflection=%.3f RideHeight=%.3f\n", wheel.mSuspensionDeflection, wheel.mRideHeight);
|
||||
fprintf(fo, " SuspForce=%.1f BrakeTemp=%.1f BrakePressure=%.3f\n", wheel.mSuspForce, wheel.mBrakeTemp, wheel.mBrakePressure);
|
||||
fprintf(fo, " ForwardRotation=%.1f Camber=%.3f\n", -wheel.mRotation, wheel.mCamber);
|
||||
fprintf(fo, " LateralPatchVel=%.2f LongitudinalPatchVel=%.2f\n", wheel.mLateralPatchVel, wheel.mLongitudinalPatchVel);
|
||||
fprintf(fo, " LateralGroundVel=%.2f LongitudinalGroundVel=%.2f\n", wheel.mLateralGroundVel, wheel.mLongitudinalGroundVel);
|
||||
fprintf(fo, " LateralForce=%.1f LongitudinalForce=%.1f\n", wheel.mLateralForce, wheel.mLongitudinalForce);
|
||||
fprintf(fo, " TireLoad=%.1f GripFract=%.3f TirePressure=%.1f\n", wheel.mTireLoad, wheel.mGripFract, wheel.mPressure);
|
||||
fprintf(fo, " TireTemp(l/c/r)=%.1f/%.1f/%.1f\n", wheel.mTemperature[0], wheel.mTemperature[1], wheel.mTemperature[2]);
|
||||
fprintf(fo, " Wear=%.3f TerrainName=%s SurfaceType=%d\n", wheel.mWear, wheel.mTerrainName, wheel.mSurfaceType);
|
||||
fprintf(fo, " Flat=%d Detached=%d\n", wheel.mFlat, wheel.mDetached);
|
||||
}
|
||||
|
||||
// Compute some auxiliary info based on the above
|
||||
TelemVect3 forwardVector = {-info.mOri[0].z, -info.mOri[1].z, -info.mOri[2].z};
|
||||
TelemVect3 leftVector = {info.mOri[0].x, info.mOri[1].x, info.mOri[2].x};
|
||||
|
||||
// These are normalized vectors, and remember that our world Y coordinate is up. So you can
|
||||
// determine the current pitch and roll (w.r.t. the world x-z plane) as follows:
|
||||
const double pitch = atan2(forwardVector.y, sqrt((forwardVector.x * forwardVector.x) + (forwardVector.z * forwardVector.z)));
|
||||
const double roll = atan2(leftVector.y, sqrt((leftVector.x * leftVector.x) + (leftVector.z * leftVector.z)));
|
||||
const double radsToDeg = 57.296;
|
||||
fprintf(fo, "Pitch = %.1f deg, Roll = %.1f deg\n", pitch * radsToDeg, roll * radsToDeg);
|
||||
|
||||
const double metersPerSec = sqrt((info.mLocalVel.x * info.mLocalVel.x) +
|
||||
(info.mLocalVel.y * info.mLocalVel.y) +
|
||||
(info.mLocalVel.z * info.mLocalVel.z));
|
||||
fprintf(fo, "Speed = %.1f KPH, %.1f MPH\n\n", metersPerSec * 3.6, metersPerSec * 2.237);
|
||||
|
||||
// Close file
|
||||
fclose(fo);
|
||||
}
|
||||
}
|
||||
|
||||
std::string format_float(double d, int precision)
|
||||
{
|
||||
std::stringstream sstream;
|
||||
|
||||
sstream << d;
|
||||
sstream.precision(precision);
|
||||
|
||||
return sstream.str();
|
||||
this->socket->send(msg);
|
||||
}
|
||||
|
||||
void RFServerPlugin::UpdateScoring(const ScoringInfoV01 &info)
|
||||
{
|
||||
std::string msg = "[";
|
||||
std::string msg = "[SCORE;";
|
||||
msg += info.mMaxLaps + ";";
|
||||
msg += format_float(info.mLapDist, 1) + ";";
|
||||
msg +=
|
||||
msg += format_float(info.mDarkCloud, 2) + ";";
|
||||
msg += format_float(info.mRaining, 2) + ";";
|
||||
msg += format_float(info.mAmbientTemp, 1) + ";";
|
||||
msg += format_float(info.mTrackTemp, 1) + ";";
|
||||
msg += format_float(info.mMinPathWetness, 2) + ";";
|
||||
msg += format_float(info.mMaxPathWetness, 2) + ";";
|
||||
msg += info.mNumVehicles + ";";
|
||||
msg += info.mYellowFlagState + ";";
|
||||
msg += info.mSectorFlag[0] + ";";
|
||||
msg += info.mSectorFlag[1] + ";";
|
||||
msg += info.mSectorFlag[2];
|
||||
msg += "]";
|
||||
|
||||
// Note: function is called twice per second now (instead of once per second in previous versions)
|
||||
FILE *fo = fopen("ExampleInternalsScoringOutput.txt", "a");
|
||||
if (fo != NULL)
|
||||
{
|
||||
// Print general scoring info
|
||||
fprintf(fo, "TrackName=%s\n", info.mTrackName);
|
||||
fprintf(fo, "Session=%d NumVehicles=%d CurET=%.3f\n", info.mSession, info.mNumVehicles, info.mCurrentET);
|
||||
fprintf(fo, "EndET=%.3f MaxLaps=%d LapDist=%.1f\n", info.mEndET, info.mMaxLaps, info.mLapDist);
|
||||
|
||||
// Note that only one plugin can use the stream (by enabling scoring updates) ... sorry if any clashes result
|
||||
fprintf(fo, "START STREAM\n");
|
||||
const char *ptr = info.mResultsStream;
|
||||
while (*ptr != NULL)
|
||||
fputc(*ptr++, fo);
|
||||
fprintf(fo, "END STREAM\n");
|
||||
|
||||
// New version 2 stuff
|
||||
fprintf(fo, "GamePhase=%d YellowFlagState=%d SectorFlags=(%d,%d,%d)\n", info.mGamePhase, info.mYellowFlagState,
|
||||
info.mSectorFlag[0], info.mSectorFlag[1], info.mSectorFlag[2]);
|
||||
fprintf(fo, "InRealtime=%d StartLight=%d NumRedLights=%d\n", info.mInRealtime, info.mStartLight, info.mNumRedLights);
|
||||
fprintf(fo, "PlayerName=%s PlrFileName=%s\n", info.mPlayerName, info.mPlrFileName);
|
||||
fprintf(fo, "DarkCloud=%.2f Raining=%.2f AmbientTemp=%.1f TrackTemp=%.1f\n", info.mDarkCloud, info.mRaining, info.mAmbientTemp, info.mTrackTemp);
|
||||
fprintf(fo, "Wind=(%.1f,%.1f,%.1f) MinPathWetness=%.2f MaxPathWetness=%.2f\n", info.mWind.x, info.mWind.y, info.mWind.z, info.mMinPathWetness, info.mMaxPathWetness);
|
||||
|
||||
// Print vehicle info
|
||||
for (long i = 0; i < info.mNumVehicles; ++i)
|
||||
{
|
||||
VehicleScoringInfoV01 &vinfo = info.mVehicle[i];
|
||||
fprintf(fo, "Driver %d: %s\n", i, vinfo.mDriverName);
|
||||
fprintf(fo, " ID=%d Vehicle=%s\n", vinfo.mID, vinfo.mVehicleName);
|
||||
fprintf(fo, " Laps=%d Sector=%d FinishStatus=%d\n", vinfo.mTotalLaps, vinfo.mSector, vinfo.mFinishStatus);
|
||||
fprintf(fo, " LapDist=%.1f PathLat=%.2f RelevantTrackEdge=%.2f\n", vinfo.mLapDist, vinfo.mPathLateral, vinfo.mTrackEdge);
|
||||
fprintf(fo, " Best=(%.3f, %.3f, %.3f)\n", vinfo.mBestSector1, vinfo.mBestSector2, vinfo.mBestLapTime);
|
||||
fprintf(fo, " Last=(%.3f, %.3f, %.3f)\n", vinfo.mLastSector1, vinfo.mLastSector2, vinfo.mLastLapTime);
|
||||
fprintf(fo, " Current Sector 1 = %.3f, Current Sector 2 = %.3f\n", vinfo.mCurSector1, vinfo.mCurSector2);
|
||||
fprintf(fo, " Pitstops=%d, Penalties=%d\n", vinfo.mNumPitstops, vinfo.mNumPenalties);
|
||||
|
||||
// New version 2 stuff
|
||||
fprintf(fo, " IsPlayer=%d Control=%d InPits=%d LapStartET=%.3f\n", vinfo.mIsPlayer, vinfo.mControl, vinfo.mInPits, vinfo.mLapStartET);
|
||||
fprintf(fo, " Place=%d VehicleClass=%s\n", vinfo.mPlace, vinfo.mVehicleClass);
|
||||
fprintf(fo, " TimeBehindNext=%.3f LapsBehindNext=%d\n", vinfo.mTimeBehindNext, vinfo.mLapsBehindNext);
|
||||
fprintf(fo, " TimeBehindLeader=%.3f LapsBehindLeader=%d\n", vinfo.mTimeBehindLeader, vinfo.mLapsBehindLeader);
|
||||
fprintf(fo, " Pos=(%.3f,%.3f,%.3f)\n", vinfo.mPos.x, vinfo.mPos.y, vinfo.mPos.z);
|
||||
|
||||
// Forward is roughly in the -z direction (although current pitch of car may cause some y-direction velocity)
|
||||
fprintf(fo, " LocalVel=(%.2f,%.2f,%.2f)\n", vinfo.mLocalVel.x, vinfo.mLocalVel.y, vinfo.mLocalVel.z);
|
||||
fprintf(fo, " LocalAccel=(%.1f,%.1f,%.1f)\n", vinfo.mLocalAccel.x, vinfo.mLocalAccel.y, vinfo.mLocalAccel.z);
|
||||
|
||||
// Orientation matrix is left-handed
|
||||
fprintf(fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[0].x, vinfo.mOri[0].y, vinfo.mOri[0].z);
|
||||
fprintf(fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[1].x, vinfo.mOri[1].y, vinfo.mOri[1].z);
|
||||
fprintf(fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[2].x, vinfo.mOri[2].y, vinfo.mOri[2].z);
|
||||
fprintf(fo, " LocalRot=(%.3f,%.3f,%.3f)\n", vinfo.mLocalRot.x, vinfo.mLocalRot.y, vinfo.mLocalRot.z);
|
||||
fprintf(fo, " LocalRotAccel=(%.2f,%.2f,%.2f)\n", vinfo.mLocalRotAccel.x, vinfo.mLocalRotAccel.y, vinfo.mLocalRotAccel.z);
|
||||
}
|
||||
|
||||
// Delimit sections
|
||||
fprintf(fo, "\n");
|
||||
|
||||
// Close file
|
||||
fclose(fo);
|
||||
}
|
||||
this->socket->send(msg);
|
||||
}
|
||||
|
||||
bool RFServerPlugin::AccessPitMenu(PitMenuV01 &info)
|
||||
{
|
||||
std::string msg = "[PIT;";
|
||||
msg += info.mCategoryIndex + ";";
|
||||
msg += std::string(info.mCategoryName) + ";";
|
||||
msg += info.mChoiceIndex + ";";
|
||||
msg += std::string(info.mChoiceString) + ";";
|
||||
msg += info.mNumChoices;
|
||||
msg += "]";
|
||||
|
||||
this->socket->send(msg);
|
||||
|
||||
return false;
|
||||
}
|
Loading…
Reference in a new issue