SHWotever / SimHub

Multi sim dashboard, bass shaker driver, ....
http://www.simhubdash.com/
799 stars 98 forks source link

iRacing: Wrong opponents in HEAT race format #580

Open hieblmedia opened 4 years ago

hieblmedia commented 4 years ago

iRacing has an Heat Racing format for Ralllycross. But can also used in hosted session etc.

SimHub contains all opponents instead of only active drivers of the current head/consulation races. This results in wrong positions, gaps etc for the leaderboard.

Not 100% sure, but looks like following filters out these drivers. Tested it on some different replay data and it looks good. bool hasData = gameData.GameNewData.Raw.Telemetry.HasData((int) driver.CarIdx);

ReplayData: https://www.dropbox.com/s/5tyijpykz11nnmo/IRacing_Replay_HEAT_Format.zip?dl=1

SHWotever commented 4 years ago

Ah the unbelieavble Iracing complexity ! Thanks for the replay ! I take a look !

hieblmedia commented 4 years ago

Telemetry.HasData() returns false if a user is disconnected. Some Telemetry Data are -1 like PositionCarIdx. May this helps in combination.

hieblmedia commented 4 years ago

Looks like HasData or ResultPosition?.Position>0 have to be checked. Something like this. Hope it helps a bit.

iRacingSDK.SessionData._SessionInfo._Sessions._ResultsPositions driverSessionInfo = null;
if (currentSession.ResultsPositions != null)
{
  driverSessionInfo = currentSession.ResultsPositions.Where(x => x.CarIdx == [carIdx]).FirstOrDefault();
}
var hasData = gameData.GameNewData.Raw.Telemetry.HasData([carIdx]);

if ((hasData == true || (driverSessionInfo != null && driverSessionInfo.Position > 0)))
{
  // valid driver
}
SHWotever commented 4 years ago

Your initial pointer seems to have done the trick : image

Based on your replay it correctly removes the ghosts players

hieblmedia commented 4 years ago

Nice. But you have to check if drivers are still on the list if they are disconnected. Then HasData is false, i just noticed . Therefore, you have to check for a valid ResultsPositions.Position in > 0 i think. Means current Session.ResultsPositions must be equal the opponent list. But ResultsPositions is only avaiable after the Race starts for example. So the HasData check is necessary also.

If you need a Replay to check disconnected drivers will stay in the list just let me know.

SHWotever commented 4 years ago

Uh uh :D You are right ! I will check that tomorrow.

hieblmedia commented 4 years ago

Thanks. I tried to take a closer look again. HasData has to be true OR just have to exist in Screenshot_3

Then it is fine i think.

SHWotever commented 4 years ago

Ah I see the logic, they must be classified or connected, so somebody who leaves there server without a result has to disappear.

hieblmedia commented 4 years ago

Just a little reminder :D

Here the complete logik split into parts. Tested in some normal races and in heat format.

iRacingSDK.SessionData._SessionInfo._Sessions currentSession;
iRacingSDK.SessionData._SessionInfo._Sessions._ResultsPositions driverSessionInfo;
currentSession = ((IEnumerable<iRacingSDK.SessionData._SessionInfo._Sessions>)gameData.GameNewData.Raw.SessionData.SessionInfo.Sessions).SingleOrDefault(s => s.SessionNum == gameData.GameNewData.Raw.Telemetry.SessionNum);
driverSessionInfo = currentSession?.ResultsPositions?.Where(x => x.CarIdx == opponent.CarIdx).FirstOrDefault();

var hasData = gameData.GameNewData.Raw.Telemetry.HasData((int)opponent.CarIdx);
var hasValidDriverData = (hasData == true || driverSessionInfo != null);
if (hasValidDriverData)
{
    // valid driver data
}
Romainrob commented 4 years ago

Hi. I just noticed with 7.0.5 the position returned by my plugin position are wrong. So I checked with the the built-in leader board feature and the positions are also wrong. It looks like the disconnected people are not taken into account at all anymore (even the ones with a recorded time) and people at the bottom of the leader board see their position improve when someone disconnect.

hieblmedia commented 4 years ago

Yes positions are not correct in some situations. The iRacing SDK Wrapper has not mapped all data. So we need to take this from Raw.Sessions.Directory manually. For example in Grid phase or Formation lap the qualifing result has to be used for correct position values. There are two different ways (depending on the race format) to get these. Currently i fix this on my own plugin.

Don't know how deep will @SHWotever go into this. It is not absolutely necessary. But would provide more accurate data for leaderboard. I could outsource the necessary adjustments to an extra plugin and give you @SHWotever. Would that be an idea?

SHWotever commented 4 years ago

I/Sorry for the delay ;) I've prepared the fix, I'm just a preparing my moving and it's hard to keep up all fronts at the same time :D.

By taking both the results and online status I got a good result I think.

If you have some additional data processing that is interesting indeed.. I may not retain all of them as I'm not trying to make simhub specific to a single game. But if I can make life easier I will do my best ;)

SHWotever commented 4 years ago

I've built a small beta with the fix ;) https://www.simhubdash.com/unofficial/SimHub.7.00.6b1.zip

hieblmedia commented 4 years ago

Thanks! Looks fine for me.

Here a plugin with some improvements/fixes. I hope you can do something with it.

  1. Methods to get positions in grid and formations lap.
  2. In generell some gaps/deltas are wrong or just null. Only set GatoLeader temporary because i dont know how you handle this internally. I already created a ticket for a while for this :D - https://github.com/SHWotever/SimHub/issues/366
  3. Lap/Trackpostions corrections.

OverTheClockFix580.Plugin.zip

As I said, this is not absolutely necessary, but would be nice this works out of the box. For any questions you can just ask me in Discord. I'm OverTheClock.

hieblmedia commented 4 years ago

FYI @SHWotever. Dont know exactly which IRacingSDK you use. but looks like the IRacingSDK has some updates recently after 4 years. https://github.com/vipoo/iRacingSDK.Net/issues/9 https://www.nuget.org/packages/iRacingSDK/

SHWotever commented 4 years ago

Thanks for the plugin I will look to see what I can reuse from it ! About the sdk I'm already running a patched version of it ,Iracing regular changes have been a real killer on it over time and I've simplified it a bit to be less suffering of monthly breaks (reduce unused processed yaml to object data and store them dynamically as a simple key/value dictionary so I'm not bound to fixed data types (so it won't break anymore when numbers are transformed into strings, strings are transformed into integers, integers are transformed to doubles .... and all the fun changes I had to face over time) By looking at the issue discussion, not sure if it will lead to active maintenance, but If it does I will try to switch back to "non patched" version.

SHWotever commented 4 years ago

About the gap/delta #366 i think I fixed this particular one recently :https://github.com/SHWotever/SimHub/issues/546 But I'm not certain it was the same issue,

hieblmedia commented 4 years ago

Ok then it might be better if you maintain it in your own. I try to explain/summary the open things as clearly as possible :)

Gaps/Deltas: Ahh! - looks like these are only set if you an active driver. But on team racing or just watching as spectator the data are null. Hope you can remove this restriction?

Track Position CurrentLapHighPrecision is also null. But CurrentLap ans TrackPositionPercent is set. Maybe CurrentLapHighPrecision is an deprecated property or just the same with Gaps/Deltas?

First Laps and CurrentLap CurrentLap jumps from 1 to 2 and few seconds back to 1 after green when passing start/finish line. Maybe this is an Telemetry issue of iRacing or wrong implmented in the IRacingSDK. I dont know.

Grid Positions: This is really a bit involved. But confusing if you actively use the leaderboard.

  1. Check SessionData.Dictonary.QualifyResultsInfo.Results
  2. If not available check SessionData.Dictonary.SessionInfo.Sessions[current].QualifyPositions
  3. All where not listed has no qualy time and needed to fill up grouped by CarClass in order to CarClassRelSpeed. Fill up positions are must be taken from ResultsPositions of SessionData.SessionInfo.Sessions[type *= quali].First
hieblmedia commented 3 years ago

About the opponent filtering.

I watched this now an long time and they are some small problems with filtering the opponents in the current way. One simple example - On driver swap in team races and some other cases (like netcode things) the opponent temorary disappear unlucky. And also bounded/extended data to the opponents on 3rd party plugins can be lost which of course is unfavorable.

Because this heat races are a very special case, we should only enable this filtering only if the heat raceformat is active.

So the general HasData(CarIdx) || resultsPosition != null check should be changed in something like this.

bool isHeatRacing = GameData.GameNewData.Raw.SessionDataDict["WeekendInfo.HeatRacing"] == "1";
if (
    !isHeatRacing || /* normal case */
    (isHeatRacing && (GameData.GameNewData.Raw.Telemetry.CarIdxLap[CarIdx] >= 0 || GameData.GameNewData.Raw.Telemetry.HasData(CarIdx))) /* heat reacing is active - filter opponents */
    )
{
    // Valid Opponent
}
hieblmedia commented 3 years ago

@SHWotever would be nice if you can take look at the last post 😄.

Also have some new replays with Heat Racing where all opponents with data must be visible in all sessions. Heat racing is just used here to start with reversed grid on race 2. https://www.dropbox.com/s/317e2eubhei3ukj/IRacing_Heat_Racing2.zip?dl=1

And in the old replay where only 8 opponents have to be visible because drivers spllited depending on past qualy/race results. https://www.dropbox.com/s/5tyijpykz11nnmo/IRacing_Replay_HEAT_Format.zip?dl=1

SHWotever commented 3 years ago

Hi ! I tried to adapt your suggested code but it looks like that it does not changes a thing, or even makes it worse for all the replays you gave (thanks a lot for that ! ).

I ran it with all the replays and each time a player was supposed to be included with your version he was already with the simpler "hasdata or sessionresult" code.

In the second (2011341) replay I spotted a temporary vanishing of 'Rafael Muenzer" (#007) for 3 or 4 data frames but unfortunately when he disappears all the related data does it too (CarIdxLap, hasdata) it seems that the code adaptation makes it even worse as my old code would keep him because he still have session results.

I'm not sure what to search for :D

hieblmedia commented 3 years ago

Hi, it try to explain all of it :D Unfortunately, iRacing itself does not offer any possibility to filter this cleanly.

The isHeatRacing check should be clear?  All this special filtering must be only active if HeatRacing is really active. On normal races all opponents must be visible all the time as it is supplied. So for normal races all issues are solved. Nothing special to care about.

The problems that remains is only in HeatRacing now because the isHeatRacing exclude the normal races. The resultposition check is also necessary because there is a difference between an iRacing replay and the live session for CarIdxLap. Sorry i missed this to check.

Here all the cases to cover for the HeatRacing.

In summary:

I have no replay for the netcode and driver swaps atm here. Hard to made one. Sorry. Can only explain it atm. Hope it helps.