public void ItMasksEventNameWithTargetframeworkevalOnTargetFrameworkVersionUseWindowsFormsOrWPF() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = MSBuildLogger.TargetFrameworkTelemetryEventName, Properties = new Dictionary <string, string> { { MSBuildLogger.TargetFrameworkVersionTelemetryPropertyKey, ".NETStandard,Version=v2.0" }, { MSBuildLogger.UseWindowsFormsTelemetryPropertyKey, "true" }, { MSBuildLogger.UseWPFTelemetryPropertyKey, "AnyNonTrueValue" }, } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.EventName.Should().Be($"msbuild/{MSBuildLogger.TargetFrameworkTelemetryEventName}"); fakeTelemetry.LogEntry.Properties.Keys.Count.Should().Be(3); fakeTelemetry.LogEntry.Properties[MSBuildLogger.TargetFrameworkVersionTelemetryPropertyKey].Should().Be(Sha256Hasher.Hash(".NETSTANDARD,VERSION=V2.0")); fakeTelemetry.LogEntry.Properties[MSBuildLogger.UseWindowsFormsTelemetryPropertyKey].Should().Be("True"); fakeTelemetry.LogEntry.Properties[MSBuildLogger.UseWPFTelemetryPropertyKey] .Should().Be( "False", "sanitize to avoid user input, and since in SDK prop and target non 'true' is effectively false"); }
internal static void FormatAndSend(ITelemetry telemetry, TelemetryEventArgs args) { if (args.EventName == TargetFrameworkTelemetryEventName) { var newEventName = $"msbuild/{TargetFrameworkTelemetryEventName}"; Dictionary <string, string> maskedProperties = new Dictionary <string, string>(); foreach (var key in new[] { TargetFrameworkVersionTelemetryPropertyKey, RuntimeIdentifierTelemetryPropertyKey, SelfContainedTelemetryPropertyKey, UseApphostTelemetryPropertyKey, OutputTypeTelemetryPropertyKey }) { if (args.Properties.TryGetValue(key, out string value)) { maskedProperties.Add(key, Sha256Hasher.HashWithNormalizedCasing(value)); } } telemetry.TrackEvent(newEventName, maskedProperties, measurements: null); } var passthroughEvents = new string[] { SdkTaskBaseCatchExceptionTelemetryEventName, PublishPropertiesTelemetryEventName, ReadyToRunTelemetryEventName }; if (passthroughEvents.Contains(args.EventName)) { telemetry.TrackEvent(args.EventName, args.Properties, measurements: null); } }
/// <summary> /// Raises the a telemetry event to all registered loggers. /// </summary> private void RaiseTelemetryEvent(object sender, TelemetryEventArgs buildEvent) { if (TelemetryLogged != null) { try { TelemetryLogged(sender, buildEvent); } catch (LoggerException) { // if a logger has failed politely, abort immediately // first unregister all loggers, since other loggers may receive remaining events in unexpected orderings // if a fellow logger is throwing in an event handler. this.UnregisterAllEventHandlers(); throw; } catch (Exception exception) { // first unregister all loggers, since other loggers may receive remaining events in unexpected orderings // if a fellow logger is throwing in an event handler. this.UnregisterAllEventHandlers(); if (ExceptionHandling.IsCriticalException(exception)) { throw; } InternalLoggerException.Throw(exception, buildEvent, "FatalErrorWhileLogging", false); } } }
internal static void FormatAndSend(ITelemetry telemetry, TelemetryEventArgs args) { if (args.EventName == TargetFrameworkTelemetryEventName) { var newEventName = $"msbuild/{TargetFrameworkTelemetryEventName}"; Dictionary <string, string> maskedProperties = new Dictionary <string, string>(); if (args.Properties.TryGetValue(TargetFrameworkVersionTelemetryPropertyKey, out string targetFrameworkVersionValue)) { maskedProperties.Add(TargetFrameworkVersionTelemetryPropertyKey, Sha256Hasher.HashWithNormalizedCasing(targetFrameworkVersionValue)); } if (args.Properties.TryGetValue(UseWindowsFormsTelemetryPropertyKey, out string useWindowsFormsValue)) { maskedProperties.Add(UseWindowsFormsTelemetryPropertyKey, SanitizeToOnlyTrueFalseEmpty(useWindowsFormsValue)); } if (args.Properties.TryGetValue(UseWPFTelemetryPropertyKey, out string useWPFValue)) { maskedProperties.Add(UseWPFTelemetryPropertyKey, SanitizeToOnlyTrueFalseEmpty(useWPFValue)); } telemetry.TrackEvent(newEventName, maskedProperties, measurements: null); } if (args.EventName == SdkTaskBaseCatchExceptionTelemetryEventName) { telemetry.TrackEvent(args.EventName, args.Properties, measurements: null); } }
public void ItCanSendProperties() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = "targetframeworkeval", Properties = new Dictionary <string, string> { { "TargetFrameworkVersion", ".NETFramework,Version=v4.6" }, { "RuntimeIdentifier", "null" }, { "SelfContained", "null" }, { "UseApphost", "null" }, { "OutputType", "Library" }, } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.Properties.ShouldBeEquivalentTo(new Dictionary <string, string> { { "TargetFrameworkVersion", "9a871d7066260764d4cb5047e4b10570271d04bd1da275681a4b12bce0b27496" }, { "RuntimeIdentifier", "fb329000228cc5a24c264c57139de8bf854fc86fc18bf1c04ab61a2b5cb4b921" }, { "SelfContained", "fb329000228cc5a24c264c57139de8bf854fc86fc18bf1c04ab61a2b5cb4b921" }, { "UseApphost", "fb329000228cc5a24c264c57139de8bf854fc86fc18bf1c04ab61a2b5cb4b921" }, { "OutputType", "d77982267d9699c2a57bcab5bb975a1935f6427002f52fd4569762fd72db3a94" }, }); }
private async void DisplaySensorReadings(TelemetryEventArgs telemetryEventArgs) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { telemetryViewModel.Temperature = telemetryEventArgs.Temperature; telemetryViewModel.Humidity = telemetryEventArgs.Humidity; }); }
/// <summary> /// The thread funktion to poll the telemetry data and send TelemetryUpdated events. /// </summary> private void Run() { int _lastSessionTick = 0; iRacingSDK sdk = new iRacingSDK(); Session session = new Session(); Stopwatch sw = new Stopwatch(); sw.Start(); while (!isStopped) { try { // check if the SDK is connected if (sdk.IsConnected()) { IsConnected = true; // check if car is on track and if we got new data if ((bool)sdk.GetData("IsOnTrack") && _lastSessionTick != (int)sdk.GetData("SessionTick")) { IsRunning = true; _lastSessionTick = (int)sdk.GetData("SessionTick"); sw.Restart(); TelemetryEventArgs args = new TelemetryEventArgs(new iR60TelemetryInfo(sdk, session)); RaiseEvent(OnTelemetryUpdate, args); } else if (sw.ElapsedMilliseconds > 500) { IsRunning = false; } } else { sdk.Startup(); IsRunning = false; } Thread.Sleep(SamplePeriod); } catch (Exception e) { LogError("iR60TelemetryProvider Exception while processing data", e); IsConnected = false; IsRunning = false; Thread.Sleep(1000); } } sdk.Shutdown(); IsConnected = false; IsRunning = false; }
private async void DisplaySensorReadings(TelemetryEventArgs telemetryEventArgs) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { sensorsViewModel.SensorReadings.Temperature = telemetryEventArgs.Temperature; sensorsViewModel.SensorReadings.Humidity = telemetryEventArgs.Humidity; sensorsViewModel.SensorReadings.Pressure = telemetryEventArgs.Pressure; sensorsViewModel.SensorReadings.Accelerometer = telemetryEventArgs.LinearAcceleration; sensorsViewModel.SensorReadings.Gyroscope = telemetryEventArgs.AngularSpeed; sensorsViewModel.SensorReadings.Magnetometer = telemetryEventArgs.MagneticField; }); }
public void LogTelemetry(BuildEventContext buildEventContext, string eventName, IDictionary <string, string> properties) { ErrorUtilities.VerifyThrow(eventName != null, "eventName is null"); TelemetryEventArgs telemetryEvent = new TelemetryEventArgs { BuildEventContext = buildEventContext, EventName = eventName, Properties = properties == null ? new Dictionary <string, string>() : new Dictionary <string, string>(properties) }; ProcessLoggingEvent(telemetryEvent); }
internal static void FormatAndSend(ITelemetry telemetry, TelemetryEventArgs args) { if (args.EventName == TargetFrameworkTelemetryEventName) { var newEventName = $"msbuild/{TargetFrameworkTelemetryEventName}"; Dictionary <string, string> maskedProperties = new Dictionary <string, string>(); if (args.Properties.TryGetValue(TargetFrameworkVersionTelemetryPropertyKey, out string value)) { maskedProperties.Add(TargetFrameworkVersionTelemetryPropertyKey, Sha256Hasher.HashWithNormalizedCasing(value)); } telemetry.TrackEvent(newEventName, maskedProperties, measurements: null); } }
/// <summary> /// The thread funktion to poll the telemetry data and send TelemetryUpdated events. /// </summary> 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; }
private void Telemetry_DataReady(object sender, TelemetryEventArgs e) { DisplaySensorReadings(e); var telemetryData = new TelemetryData() { DeviceId = deviceId, Temperature = e.Temperature, Humidity = e.Humidity }; var telemetryMessage = MessageHelper.Serialize(telemetryData); deviceClient.SendEventAsync(telemetryMessage); }
public void ItBlocksTelemetryThatIsNotInTheList() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = "User Defined Event Name", Properties = new Dictionary <string, string> { { "User Defined Key", "User Defined Value" }, } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.Should().BeNull(); }
/// <summary> /// The thread funktion to poll the telemetry data and send TelemetryUpdated events. /// </summary> private void Run() { Shared telemetryData; Stopwatch sw = new Stopwatch(); sw.Start(); while (!isStopped) { try { telemetryData = (Shared)readSharedMemory(typeof(Shared), sharedMemoryFile); IsConnected = true; if (telemetryData.GamePaused != 1 && telemetryData.GameInMenus != 1 && telemetryData.Player.GameSimulationTicks != 0) { IsRunning = true; sw.Restart(); TelemetryEventArgs args = new TelemetryEventArgs( new r3eTelemetryInfo(telemetryData)); RaiseEvent(OnTelemetryUpdate, args); } else if (sw.ElapsedMilliseconds > 500) { IsRunning = false; } Thread.Sleep(SamplePeriod); } catch (Exception e) { LogDebug("RaceRoom Racing Experience (R3E) TelemetryProvider Exception while processing data", e); IsConnected = false; IsRunning = false; Thread.Sleep(1000); } } IsConnected = false; IsRunning = false; Log("polling stopped, RaceRoom Racing Experience (R3E) TelemetryProvider"); }
public void ItMasksEventNameWithTargetframeworkevalOnTargetFrameworkVersionUseWindowsFormsOrWPFWhenFieldIsEmpty() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = MSBuildLogger.TargetFrameworkTelemetryEventName, Properties = new Dictionary <string, string> { { MSBuildLogger.UseWindowsFormsTelemetryPropertyKey, "null" }, } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.Properties[MSBuildLogger.UseWindowsFormsTelemetryPropertyKey] .Should().Be( "null", "MSBuild will throw when the task param contain empty and if the field is empty json will emit the entry, so it still need to be set to something."); }
public void ItDoesNotMaskReadyToRunTelemetry() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = MSBuildLogger.ReadyToRunTelemetryEventName, Properties = new Dictionary <string, string> { { "PublishReadyToRunUseCrossgen2", "null" }, { "otherProperty", "otherProperty value" } } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.EventName.Should().Be(MSBuildLogger.ReadyToRunTelemetryEventName); fakeTelemetry.LogEntry.Properties.Keys.Count.Should().Be(2); fakeTelemetry.LogEntry.Properties["PublishReadyToRunUseCrossgen2"].Should().Be("null"); fakeTelemetry.LogEntry.Properties["otherProperty"].Should().Be("otherProperty value"); }
public void ItDoesNotMasksExceptionTelemetry() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = MSBuildLogger.SdkTaskBaseCatchExceptionTelemetryEventName, Properties = new Dictionary <string, string> { { "exceptionType", "System.Exception" }, { "detail", "Exception detail" } } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.EventName.Should().Be(MSBuildLogger.SdkTaskBaseCatchExceptionTelemetryEventName); fakeTelemetry.LogEntry.Properties.Keys.Count.Should().Be(2); fakeTelemetry.LogEntry.Properties["exceptionType"].Should().Be("System.Exception"); fakeTelemetry.LogEntry.Properties["detail"].Should().Be("Exception detail"); }
public void ItMasksTargetFrameworkEventname() { var fakeTelemetry = new FakeTelemetry(); var telemetryEventArgs = new TelemetryEventArgs { EventName = "targetframeworkeval", Properties = new Dictionary <string, string> { { "TargetFrameworkVersion", ".NETStandard,Version=v2.0" }, } }; MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); fakeTelemetry.LogEntry.EventName.Should().Be("msbuild/targetframeworkeval"); fakeTelemetry.LogEntry.Properties.Keys.Count.Should().Be(1); var expectedKey = "TargetFrameworkVersion"; fakeTelemetry.LogEntry.Properties.Should().ContainKey(expectedKey); fakeTelemetry.LogEntry.Properties[expectedKey].Should().Be(Sha256Hasher.Hash(".NETSTANDARD,VERSION=V2.0")); }
private void OnTelemetry(object sender, TelemetryEventArgs e) => _telemetry.SendTelemetry(e.value);
private void Run() { FH4Data data; Session session = new Session(); Stopwatch sw = new Stopwatch(); sw.Start(); UdpClient socket = new UdpClient(); socket.ExclusiveAddressUse = false; socket.Client.Bind(new IPEndPoint(IPAddress.Any, PORTNUM)); Log("Listener started (port: " + PORTNUM.ToString() + ") FH4TelemetryProvider.Thread"); while (!isStopped) { try { // get data from game, if (socket.Available == 0) { if (sw.ElapsedMilliseconds > 500) { IsRunning = false; IsConnected = false; Thread.Sleep(1000); } continue; } else { IsConnected = true; } Byte[] received = socket.Receive(ref _senderIP); data = new FH4Data(received); if (data.IsRaceOn == 1) { IsRunning = true; TelemetryEventArgs args = new TelemetryEventArgs( new FH4TelemetryInfo(data, session)); RaiseEvent(OnTelemetryUpdate, args); } else { IsRunning = false; } sw.Restart(); //Thread.Sleep(SamplePeriod); } catch (Exception) { IsConnected = false; IsRunning = false; Thread.Sleep(1000); } } socket.Close(); IsConnected = false; IsRunning = false; }
private void Run() { F12019NewTelemetryData data; // Exposes only data for interest to SimFeedback PacketMotionData packData; // Raw data as received from game Session session = new Session(); Stopwatch sw = new Stopwatch(); sw.Start(); UdpClient socket = new UdpClient(); socket.ExclusiveAddressUse = false; socket.Client.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), PORTNUM)); Log("Listener started (port: " + PORTNUM.ToString() + ") F12019NewTelemetryProvider.Thread"); while (!isStopped) { try { // get data from game, if (socket.Available == 0) { if (sw.ElapsedMilliseconds > 500) { IsRunning = false; IsConnected = false; Thread.Sleep(1000); } continue; } else { IsConnected = true; } Byte[] received = socket.Receive(ref _senderIP); LogDebug($"Packet size: '{received.Length}'"); if (received.Length == bytesInTelemetryPacket2019 || received.Length == bytesInTelemetryPacket2018) { // Unfortunately we need to "digest" the car telemetry data just to get the RPMs out of it. // Storing the RPMs in class variable for easier access when adding it to our SFB exposed telemetry data var telemData = new PacketCarTelemetryData(received); if (received.Length == bytesInTelemetryPacket2019) { lastRPMs = telemData.m_carTelemetryData2019[0].m_engineRPM; } else { lastRPMs = telemData.m_carTelemetryData2018[0].m_engineRPM; } LogDebug($"Got RPMs: '{lastRPMs}'"); } else if (received.Length == bytesInMotionPacket2019 || received.Length == bytesInMotionPacket2019 - 2) { packData = new PacketMotionData(received); if (packData.m_header.m_packetId == 0) // should always be the case if the # of bytes received match { data = new F12019NewTelemetryData(packData); LogDebug($"Got longitudal g force: '{data.gForceLongitudinal}'"); IsRunning = true; TelemetryEventArgs args = new TelemetryEventArgs( new F12019NewTelemetryInfo(data, session)); RaiseEvent(OnTelemetryUpdate, args); } else { LogDebug("Received packet has expected number of bytes but is not a motion packet. This should not happen."); IsRunning = false; lastRPMs = 0; } } else if (received.Length == bytesInParticipantPacket2019 || received.Length == bytesInParticipantPacket2018) { var participantData = new ParticpantData(received); LogDebug($"Got human driver index '{participantData.humanDriver}'"); humanDriver = participantData.humanDriver; } else if (received.Length == bytesInSessionData2019 || received.Length == bytesInSessionData2018) { var sessionData = new SessionData(received); LogDebug($"Got watched driver index '{sessionData.m_spectatorCarIndex}'"); spectatorCarIndex = sessionData.m_spectatorCarIndex; } sw.Restart(); //Thread.Sleep(SamplePeriod); } catch (Exception e) { IsConnected = false; IsRunning = false; lastRPMs = 0; LogDebug($"Caught Exception while unmarshalling data '{e.Message}'"); Thread.Sleep(1000); } } socket.Close(); IsConnected = false; IsRunning = false; }
public void Telemetry(TelemetryEventArgs e) => OnTelemetry?.Invoke(this, e);
private void OnTelemetryLogged(object sender, TelemetryEventArgs args) { _telemetry.TrackEvent(args.EventName, args.Properties, measurements: null); }
private void OnTelemetryLogged(object sender, TelemetryEventArgs args) { FormatAndSend(_telemetry, args); }
// ReSharper disable once UnusedMember.Local private void OnTelemetryLogged(TelemetryEventArgs e) { TelemetryLogged?.Invoke(this, e); }
/// <summary> /// The thread funktion to poll the telemetry data and send TelemetryUpdated events. /// </summary> private void Run() { SFUAPI lastTelemetryData = new SFUAPI(); lastTelemetryData.Reset(); Session session = new Session(); Stopwatch sw = new Stopwatch(); sw.Start(); UdpClient socket = new UdpClient(); socket.ExclusiveAddressUse = false; socket.Client.Bind(new IPEndPoint(IPAddress.Any, PORTNUM)); Log("Listener started (port: " + PORTNUM.ToString() + ") SFUTelemetryProvider.Thread"); while (!isStopped) { try { // get data from game, if (socket.Available == 0) { if (sw.ElapsedMilliseconds > 500) { IsRunning = false; IsConnected = false; Thread.Sleep(1000); } continue; } else { IsConnected = true; } Byte[] received = socket.Receive(ref _senderIP); var alloc = GCHandle.Alloc(received, GCHandleType.Pinned); SFUAPI telemetryData = (SFUAPI)Marshal.PtrToStructure(alloc.AddrOfPinnedObject(), typeof(SFUAPI)); // otherwise we are connected IsConnected = true; if (telemetryData.packetID != lastTelemetryData.packetID) { IsRunning = true; sw.Restart(); TelemetryEventArgs args = new TelemetryEventArgs( new SFUTelemetryInfo(telemetryData, lastTelemetryData)); RaiseEvent(OnTelemetryUpdate, args); lastTelemetryData = telemetryData; } else if (sw.ElapsedMilliseconds > 500) { IsRunning = false; } } catch (Exception e) { LogError("SFUTelemetryProvider Exception while processing data", e); IsConnected = false; IsRunning = false; Thread.Sleep(1000); } } socket.Close(); IsConnected = false; IsRunning = false; }
/// <summary> /// The thread funktion to poll the telemetry data and send TelemetryUpdated events. /// </summary> private void Run() { isStopped = false; WFSTAPI lastTelemetryData = new WFSTAPI(); lastTelemetryData.Reset(); Matrix4x4 lastTransform = Matrix4x4.Identity; bool lastFrameValid = false; Vector3 lastVelocity = Vector3.Zero; float lastYaw = 0.0f; Stopwatch sw = new Stopwatch(); sw.Start(); NestedSmooth accXSmooth = new NestedSmooth(3, 6, 0.5f); NestedSmooth accYSmooth = new NestedSmooth(3, 6, 0.5f); NestedSmooth accZSmooth = new NestedSmooth(3, 6, 0.5f); KalmanFilter velXFilter = new KalmanFilter(1, 1, 0.02f, 1, 0.02f, 0.0f); KalmanFilter velZFilter = new KalmanFilter(1, 1, 0.02f, 1, 0.02f, 0.0f); NoiseFilter velXSmooth = new NoiseFilter(6, 0.5f); NoiseFilter velZSmooth = new NoiseFilter(6, 0.5f); KalmanFilter yawRateFilter = new KalmanFilter(1, 1, 0.02f, 1, 0.02f, 0.0f); NoiseFilter yawRateSmooth = new NoiseFilter(6, 0.5f); NoiseFilter pitchFilter = new NoiseFilter(3); NoiseFilter rollFilter = new NoiseFilter(3); NoiseFilter yawFilter = new NoiseFilter(3); KalmanFilter posXFilter = new KalmanFilter(1, 1, 0.02f, 1, 0.1f, 0.0f); KalmanFilter posYFilter = new KalmanFilter(1, 1, 0.02f, 1, 0.1f, 0.0f); KalmanFilter posZFilter = new KalmanFilter(1, 1, 0.02f, 1, 0.1f, 0.0f); NestedSmooth posXSmooth = new NestedSmooth(12, 6, 0.5f); NestedSmooth posYSmooth = new NestedSmooth(12, 6, 0.5f); NestedSmooth posZSmooth = new NestedSmooth(12, 6, 0.5f); NoiseFilter slipAngleSmooth = new NoiseFilter(6, 0.25f); ProcessMemoryReader reader = new ProcessMemoryReader(); reader.ReadProcess = wfstProcess; uint readSize = 4 * 4 * 4; byte[] readBuffer = new byte[readSize]; reader.OpenProcess(); while (!isStopped) { try { float dt = (float)sw.ElapsedMilliseconds / 1000.0f; int byteReadSize; reader.ReadProcessMemory((IntPtr)memoryAddress, readSize, out byteReadSize, readBuffer); if (byteReadSize == 0) { continue; } float[] floats = new float[4 * 4]; Buffer.BlockCopy(readBuffer, 0, floats, 0, readBuffer.Length); Matrix4x4 transform = new Matrix4x4(floats[0], floats[1], floats[2], floats[3] , floats[4], floats[5], floats[6], floats[7] , floats[8], floats[9], floats[10], floats[11] , floats[12], floats[13], floats[14], floats[15]); Vector3 rht = new Vector3(transform.M11, transform.M12, transform.M13); Vector3 up = new Vector3(transform.M21, transform.M22, transform.M23); Vector3 fwd = new Vector3(transform.M31, transform.M32, transform.M33); float rhtMag = rht.Length(); float upMag = up.Length(); float fwdMag = fwd.Length(); //reading garbage if (rhtMag < 0.9f || upMag < 0.9f || fwdMag < 0.9f) { IsConnected = false; IsRunning = false; TelemetryLost(); break; } if (!lastFrameValid) { lastTransform = transform; lastFrameValid = true; lastVelocity = Vector3.Zero; lastYaw = 0.0f; continue; } WFSTAPI telemetryData = new WFSTAPI(); if (dt <= 0) { dt = 1.0f; } Vector3 worldVelocity = (transform.Translation - lastTransform.Translation) / dt; lastTransform = transform; Matrix4x4 rotation = new Matrix4x4(); rotation = transform; rotation.M41 = 0.0f; rotation.M42 = 0.0f; rotation.M43 = 0.0f; Matrix4x4 rotInv = new Matrix4x4(); Matrix4x4.Invert(rotation, out rotInv); Vector3 localVelocity = Vector3.Transform(worldVelocity, rotInv); telemetryData.velX = worldVelocity.X; telemetryData.velZ = worldVelocity.Z; Vector3 localAcceleration = localVelocity - lastVelocity; lastVelocity = localVelocity; telemetryData.accX = localAcceleration.X * 10.0f; telemetryData.accY = localAcceleration.Y * 100.0f; telemetryData.accZ = localAcceleration.Z * 10.0f; float pitch = (float)Math.Asin(-fwd.Y); float yaw = (float)Math.Atan2(fwd.X, fwd.Z); float roll = 0.0f; Vector3 rhtPlane = rht; rhtPlane.Y = 0; rhtPlane = Vector3.Normalize(rhtPlane); if (rhtPlane.Length() <= float.Epsilon) { roll = -(float)(Math.Sign(rht.Y) * Math.PI * 0.5f); } else { roll = -(float)Math.Asin(Vector3.Dot(up, rhtPlane)); } telemetryData.pitchPos = pitch; telemetryData.yawPos = yaw; telemetryData.rollPos = roll; telemetryData.yawRate = CalculateAngularChange(lastYaw, yaw) * (180.0f / (float)Math.PI); lastYaw = yaw; // otherwise we are connected IsConnected = true; if (IsConnected) { IsRunning = true; WFSTAPI telemetryToSend = new WFSTAPI(); telemetryToSend.Reset(); telemetryToSend.CopyFields(telemetryData); telemetryToSend.accX = accXSmooth.Filter(telemetryData.accX); telemetryToSend.accY = accYSmooth.Filter(telemetryData.accY); telemetryToSend.accZ = accZSmooth.Filter(telemetryData.accZ); telemetryToSend.pitchPos = pitchFilter.Filter(telemetryData.pitchPos); telemetryToSend.rollPos = rollFilter.Filter(telemetryData.rollPos); telemetryToSend.yawPos = yawFilter.Filter(telemetryData.yawPos); telemetryToSend.velX = velXSmooth.Filter(velXFilter.Filter(telemetryData.velX)); telemetryToSend.velZ = velZSmooth.Filter(velZFilter.Filter(telemetryData.velZ)); telemetryToSend.yawRate = yawRateSmooth.Filter(yawRateFilter.Filter(telemetryData.yawRate)); telemetryToSend.yawAcc = slipAngleSmooth.Filter(telemetryToSend.CalculateSlipAngle()); sw.Restart(); TelemetryEventArgs args = new TelemetryEventArgs( new WFSTTelemetryInfo(telemetryToSend, lastTelemetryData)); RaiseEvent(OnTelemetryUpdate, args); lastTelemetryData = telemetryToSend; Thread.Sleep(1000 / 100); } else if (sw.ElapsedMilliseconds > 500) { IsRunning = false; } } catch (Exception e) { LogError("WFSTTelemetryProvider Exception while processing data", e); IsConnected = false; IsRunning = false; Thread.Sleep(1000); } } IsConnected = false; IsRunning = false; reader.CloseHandle(); }
private void OnTelemetryLogged(object sender, TelemetryEventArgs args) { Console.WriteLine(JsonConvert.SerializeObject(args)); }
private void Run() { XP11Data data; Session session = new Session(); Stopwatch sw = new Stopwatch(); Stopwatch sSTimer = new Stopwatch(); //softStartTimer float sSMul = 0.0f; //softStartMultiplier (1.0f is the normal ratio for telemetry data), calculated with equation (sSTimer - sSWaitForALign)/sStime float sSTime = 5000f; //softStartTime, amount of milliseconds for the softstart to occur, starting after time sSWaitForAlign. //softStartWaitForAlign, the time it takes for the SFX-100 to elevate to neutral height. //Important: it takes about 3 seconds for the rig to start using telemetry data, if sSWaitForAlign is set below 3 seconds, //somehow the rig jumps directly to the telemetry position. I am not sure what is causing this....5 seconds seems like a secure value //So a total of 10 seconds until the rig is fully aligned to telemetry data. float sSWaitForAlign = 5000f; sw.Start(); UdpClient socket = new UdpClient(); socket.ExclusiveAddressUse = false; socket.Client.Bind(new IPEndPoint(IPAddress.Any, PORTNUM)); Log("Listener started (port: " + PORTNUM.ToString() + ") XP11TelemetryProvider.Thread"); sSTimer.Reset(); sSTimer.Start(); while (!isStopped) { try { // get data from game, if (socket.Available == 0) { if (sw.ElapsedMilliseconds > 500) { IsRunning = false; IsConnected = false; Thread.Sleep(1000); } continue; } else { IsConnected = true; } //Calculate the sofStartMultiplier from where when user presses start + sSWaitForAlign extra time for the SFX-100 to go to neutral position. //The time for the softstart alignment is sSTime. if (sSMul < 1.0f && sSTimer.ElapsedMilliseconds > sSWaitForAlign) { sSMul = (sSTimer.ElapsedMilliseconds - sSWaitForAlign) / sSTime; if (sSMul >= 1.0f) { sSMul = 1.0f; sSTimer.Stop(); } } Byte[] received = socket.Receive(ref _senderIP); data = new XP11Data(received, sSMul); if (data.IsRaceOn == 1) { IsRunning = true; TelemetryEventArgs args = new TelemetryEventArgs(new XP11TelemetryInfo(data, session)); RaiseEvent(OnTelemetryUpdate, args); } else { IsRunning = false; } sw.Restart(); } catch (Exception) { IsConnected = false; IsRunning = false; Thread.Sleep(1000); } } socket.Close(); IsConnected = false; IsRunning = false; }
private void OnTelemetryLogged(object sender, TelemetryEventArgs e) => TelemetryLogged?.Invoke(sender, e);