diff --git a/Src/ACTelemetryProvider/.gitattributes b/Src/ACTelemetryProvider/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/Src/ACTelemetryProvider/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/Src/ACTelemetryProvider/.gitignore b/Src/ACTelemetryProvider/.gitignore new file mode 100644 index 0000000..615d1ec --- /dev/null +++ b/Src/ACTelemetryProvider/.gitignore @@ -0,0 +1,193 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates +*.licenseheader +*.sln +.vs/ + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +x64/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +## TODO: Comment the next line if you want to checkin your +## web deploy settings but do note that will include unencrypted +## passwords +#*.pubxml + +# NuGet Packages Directory +packages/* +## TODO: If the tool you use requires repositories.config +## uncomment the next line +#!packages/repositories.config + +# Enable "build/" folder in the NuGet Packages folder since +# NuGet packages use it for MSBuild targets. +# This line needs to be after the ignore of the build folder +# (and the packages folder if the line above has been uncommented) +!packages/build/ + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml \ No newline at end of file diff --git a/Src/ACTelemetryProvider/ACTelemetryProvider.csproj b/Src/ACTelemetryProvider/ACTelemetryProvider.csproj new file mode 100644 index 0000000..2aacc4b --- /dev/null +++ b/Src/ACTelemetryProvider/ACTelemetryProvider.csproj @@ -0,0 +1,62 @@ + + + + + Debug + AnyCPU + {AADB7AD3-25BE-435A-BDED-259F2E55ACE5} + Library + Properties + SimFeedback.telemetry.ac + ACTelemetryProvider + v4.6 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + + + + + + + + + + + + + + + + + + {a43fc598-5e10-4730-83f8-ca0f6164c988} + SimFeedbackTelemetryProvider + + + + + + + \ No newline at end of file diff --git a/Src/ACTelemetryProvider/Properties/AssemblyInfo.cs b/Src/ACTelemetryProvider/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..980d901 --- /dev/null +++ b/Src/ACTelemetryProvider/Properties/AssemblyInfo.cs @@ -0,0 +1,58 @@ +// +// Copyright (c) 2018 Rausch IT +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("ACTelemetryProvider")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ACTelemetryProvider")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly +// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("aadb7ad3-25be-435a-bded-259f2e55ace5")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, +// indem Sie "*" wie unten gezeigt eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Src/ACTelemetryProvider/ac/ACAPI.cs b/Src/ACTelemetryProvider/ac/ACAPI.cs new file mode 100644 index 0000000..a4dea56 --- /dev/null +++ b/Src/ACTelemetryProvider/ac/ACAPI.cs @@ -0,0 +1,351 @@ +// +// Copyright (c) 2018 Rausch IT +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// +using System; +using System.Runtime.InteropServices; + +namespace SimFeedback.telemetry.ac +{ + /// + /// Helper struct to name the array positions + /// + [StructLayout(LayoutKind.Sequential)] + public struct Coordinates + { + public float X; + public float Y; + public float Z; + } + + /// + /// The struct of the shared memory file + some named properties + /// for human friendly mapping and stateless calculations + /// + [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] + public struct ACAPI + { + #region Fields + + public int PacketId; + public float Gas; + public float Brake; + public float Fuel; + public int Gear; + public int Rpms; + public float SteerAngle; + public float SpeedKmh; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public float[] Velocity; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public float[] AccG; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] WheelSlip; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] WheelLoad; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] WheelsPressure; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] WheelAngularSpeed; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] TyreWear; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] TyreDirtyLevel; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] TyreCoreTemperature; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] CamberRad; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] SuspensionTravel; + + public float Drs; + public float TC; + public float Heading; + public float Pitch; + public float Roll; + public float CgHeight; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public float[] CarDamage; + + public int NumberOfTyresOut; + public int PitLimiterOn; + public float Abs; + + public float KersCharge; + public float KersInput; + public int AutoShifterOn; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public float[] RideHeight; + + // since 1.5 + public float TurboBoost; + public float Ballast; + public float AirDensity; + + // since 1.6 + public float AirTemp; + public float RoadTemp; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public float[] LocalAngularVelocity; + public float FinalFF; + + // since 1.7 + public float PerformanceMeter; + public int EngineBrake; + public int ErsRecoveryLevel; + public int ErsPowerLevel; + public int ErsHeatCharging; + public int ErsisCharging; + public float KersCurrentKJ; + public int DrsAvailable; + public int DrsEnabled; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] BrakeTemp; + + // since 1.10 + public float Clutch; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] TyreTempI; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] TyreTempM; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] TyreTempO; + + // since 1.10.2 + public int IsAIControlled; + + // since 1.11 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public Coordinates[] TyreContactPoint; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public Coordinates[] TyreContactNormal; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public Coordinates[] TyreContactHeading; + public float BrakeBias; + + // since 1.12 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public float[] LocalVelocity; + + #endregion + + #region Properties + // Properties + + + + public float Heave + { + get + { + return AccG[1]; + } + } + + public float Sway + { + get + { + return AccG[0]; + } + } + + public float Surge + { + get + { + return AccG[2]; + } + } + + public float PitchDeg + { + get + { + return Pitch * (float)(180 / Math.PI); + } + } + public float RollDeg + { + get + { + return Roll * (float)(180 / Math.PI); + } + } + + public float Yaw + { + get + { + return Heading; + } + } + + public float Speed + { + get + { + return SpeedKmh; + } + } + + public float SlipAngle + { + get + { + float slipAngle = 0.0f; + if (SpeedKmh > 5) + { + // Porsche GT3 Cup + // Fahrzeug Länge: 4.564 + // Radstand: 1.980 x 2.456 + slipAngle = (float)(Math.Atan( + (LocalVelocity[0] - LocalAngularVelocityY * (1.980f / 2)) + / + (LocalVelocity[2] - LocalAngularVelocityY * (2.456f / 2)) + ) * 180 / Math.PI); + } + return slipAngle; + } + } + + + public float SlipAngle2 + { + get + { + float slipAngle = 0.0f; + double Vx = AccG[2] + LocalAngularVelocity[1] * LocalVelocity[0]; + double Vy = AccG[0] + LocalAngularVelocity[1] * LocalVelocity[2]; + slipAngle = (float)(Math.Atan(Vy / Vx) * 180 / Math.PI); + return slipAngle; + } + } + + /// + /// Placeholder for the stateful property. + /// This will propergate the Name list for available Telemetry Keys. + /// + /// + public float Rumble + { + get { return 0; } + } + + + + public float SuspensionTravelAll + { + get + { + return + Math.Abs(SuspensionTravel[0]) + + Math.Abs(SuspensionTravel[1])+ + Math.Abs(SuspensionTravel[2])+ + Math.Abs(SuspensionTravel[3]) / 4; + } + } + + + public float SuspensionTravelFL { + get + { + return SuspensionTravel[0]; + } + } + + public float SuspensionTravelFR + { + get + { + return SuspensionTravel[1]; + } + } + + public float SuspensionTravelRL + { + get + { + return SuspensionTravel[2]; + } + } + + public float SuspensionTravelRR + { + get + { + return SuspensionTravel[3]; + } + } + + public float VelocityX + { + get { + return LocalVelocity[0]; + } + } + public float VelocityY + { + get + { + return LocalVelocity[1]; + } + } + public float VelocityZ + { + get + { + return LocalVelocity[2]; + } + } + + public float LocalAngularVelocityX + { + get + { + return LocalAngularVelocity[0]; + } + } + + public float LocalAngularVelocityY + { + get + { + return LocalAngularVelocity[1]; + } + } + + public float LocalAngularVelocityZ + { + get + { + return LocalAngularVelocity[2]; + } + } + + #endregion + + } + +} diff --git a/Src/ACTelemetryProvider/ac/ACTelemetryInfo.cs b/Src/ACTelemetryProvider/ac/ACTelemetryInfo.cs new file mode 100644 index 0000000..38c2d16 --- /dev/null +++ b/Src/ACTelemetryProvider/ac/ACTelemetryInfo.cs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2018 Rausch IT +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// +using System; +using System.Reflection; +using System.Linq; + +namespace SimFeedback.telemetry.ac +{ + /// + /// This class provides the telemetry data by looking up the value from the data struct + /// and does some stateful calculations where more than one data sample is required. + /// + public sealed class ACTelemetryInfo : EventArgs, TelemetryInfo + { + private readonly ACAPI _telemetryData; + private readonly ACAPI _lastTelemetryData; + + public ACTelemetryInfo(ACAPI telemetryData, ACAPI lastTelemetryData) + { + _telemetryData = telemetryData; + _lastTelemetryData = lastTelemetryData; + } + + private float Rumble + { + get + { + if (_lastTelemetryData.SuspensionTravel == null) return 0; + + const float x = 1000.0f; + float[] data = + { + _telemetryData.SuspensionTravel[0] - _lastTelemetryData.SuspensionTravel[0], + _telemetryData.SuspensionTravel[1] - _lastTelemetryData.SuspensionTravel[1], + _telemetryData.SuspensionTravel[2] - _lastTelemetryData.SuspensionTravel[2], + _telemetryData.SuspensionTravel[3] - _lastTelemetryData.SuspensionTravel[3] + }; + return data.Max() * x; + } + } + + public TelemetryValue TelemetryValueByName(string name) + { + object data; + + TelemetryValue tv; + switch (name) + { + case "Rumble": + data = Rumble; + break; + + default: + int arrayIndexPos = -1; + int squareBracketPos = name.IndexOf('['); + if (squareBracketPos != -1) + { + int.TryParse(name.Substring(squareBracketPos+1, 1), out arrayIndexPos); + name = name.Substring(0, squareBracketPos); + } + Type eleDataType = typeof(ACAPI); + PropertyInfo propertyInfo; + FieldInfo fieldInfo = eleDataType.GetField(name); + if (fieldInfo != null) + { + data = fieldInfo.GetValue(_telemetryData); + if (arrayIndexPos != -1 && data.GetType().IsArray) + { + float[] array = (float[])data; + data = array[arrayIndexPos]; + } + + } + else if ((propertyInfo = eleDataType.GetProperty(name)) != null) + { + data = propertyInfo.GetValue(_telemetryData, null); + } + else + { + throw new UnknownTelemetryValueException(name); + } + break; + } + + tv = new ACTelemetryValue(name, data); + object value = tv.Value; + if (value == null) + { + throw new UnknownTelemetryValueException(name); + } + return tv; + } + } +} diff --git a/Src/ACTelemetryProvider/ac/ACTelemetryProvider.cs b/Src/ACTelemetryProvider/ac/ACTelemetryProvider.cs new file mode 100644 index 0000000..0a538ec --- /dev/null +++ b/Src/ACTelemetryProvider/ac/ACTelemetryProvider.cs @@ -0,0 +1,151 @@ +// +// Copyright (c) 2018 Rausch IT +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// +using SimFeedback.log; +using System; +using System.Diagnostics; +using System.Threading; + +namespace SimFeedback.telemetry.ac +{ + /// + /// Assetto Corsa Telemetry Provider + /// + public sealed class ACTelemetryProvider : AbstractTelemetryProvider + { + private const string sharedMemoryFile = @"Local\acpmf_physics"; // the name of the shared memory file + private bool isStopped = true; // flag to control the polling thread + private Thread t; // the polling thread, reads telemetry data and sends TelemetryUpdated events + + /// + /// Default constructor. + /// Every TelemetryProvider needs a default constructor for dynamic loading. + /// Make sure to call the underlying abstract class in the constructor. + /// + public ACTelemetryProvider() : base() + { + Author = "saxxon66"; + Version = "v1.1"; + BannerImage = @"img\banner_ac.png"; // Image shown on top of the profiles tab + IconImage = @"img\ac.jpg"; // Icon used in the tree view for the profile + TelemetryUpdateFrequency = 100; // the update frequency in samples per second + } + + /// + /// Name of this TelemetryProvider. + /// Used for dynamic loading and linking to the profile configuration. + /// + public override string Name { get { return "ac"; } } + + public override void Init(ILogger logger) + { + base.Init(logger); + Log("Initializing ACTelemetryProvider"); + } + + /// + /// A list of all telemetry names of this provider. + /// + /// List of all telemetry names + public override string[] GetValueList() + { + return GetValueListByReflection(typeof(ACAPI)); + } + + /// + /// Start the polling thread + /// + public override void Start() + { + if (isStopped) + { + LogDebug("Starting ACTelemetryProvider"); + isStopped = false; + t = new Thread(Run); + t.Start(); + } + } + + /// + /// Stop the polling thread + /// + public override void Stop() + { + LogDebug("Stopping ACTelemetryProvider"); + isStopped = true; + if(t != null)t.Join(); + } + + /// + /// The thread funktion to poll the telemetry data and send TelemetryUpdated events. + /// + private void Run() + { + ACAPI lastTelemetryData = new ACAPI(); + Stopwatch sw = new Stopwatch(); + sw.Start(); + + while (!isStopped) + { + try + { + // get data from game, + // if an exception will be thrown, we could not retrieve the data because the game + // is not running or something went wrong + ACAPI telemetryData = (ACAPI)readSharedMemory(typeof(ACAPI), sharedMemoryFile); + // otherwise we are connected + IsConnected = true; + + if (telemetryData.PacketId != lastTelemetryData.PacketId) + { + IsRunning = true; + + sw.Restart(); + + TelemetryEventArgs args = new TelemetryEventArgs( + new ACTelemetryInfo(telemetryData, lastTelemetryData)); + RaiseEvent(OnTelemetryUpdate, args); + + lastTelemetryData = telemetryData; + } + else if(sw.ElapsedMilliseconds > 500) + { + IsRunning = false; + } + + Thread.Sleep(SamplePeriod); + } + catch (Exception e) + { + LogError("ACTelemetryProvider Exception while processing data", e); + IsConnected = false; + IsRunning = false; + Thread.Sleep(1000); + } + } + + IsConnected = false; + IsRunning = false; + } + + } +} diff --git a/Src/ACTelemetryProvider/ac/ACTelemetryValue.cs b/Src/ACTelemetryProvider/ac/ACTelemetryValue.cs new file mode 100644 index 0000000..d5fcf51 --- /dev/null +++ b/Src/ACTelemetryProvider/ac/ACTelemetryValue.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) 2018 Rausch IT +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// +namespace SimFeedback.telemetry.ac +{ + public sealed class ACTelemetryValue : AbstractTelemetryValue + { + + public ACTelemetryValue(string name, object value) + : base() + { + Name = name; + Value = value; + } + + public override object Value { get; set; } + + public override string ToString() + { + return string.Format("{0} {1}", this.Value, this.Unit); + } + + } +}