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);
+ }
+
+ }
+}