Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing replay mode compatibility by adding telemetry stream state detection #2

Closed
wants to merge 3 commits into from

Conversation

Nathaniel-Wu
Copy link

An attempt to restore the capability to use the tool with the replay mode. Based on the discovery I posted here.

The only thing this fix does is determine what the player is doing based on the context of the telemetry stream, and force the GTData.in_race field to be True if we find that the player is in replay mode. The rest of the code base is untouched. Hopefully nothing is broken.

Some constants might need a bit of tweaking down the line, but it should work most of the time, with two caveats:

  1. If you start the software while already in replay mode, it can't tell whether you are in the pre-race menu or a replay.
  2. It determines that you're exiting a replay by detecting a large delta in engine RPM or car speed, so it might prematurely determine that you've exited the replay if you skip or rewind the replay.

In both cases, just quit and restart the replay.

return True
return False

def check_for_replay_end(self, data_history):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain what the logic behind this function and the function below is? Some magic numbers and logic that will be hard to maintain in the future.

I would prefer a manual approach of recording and not recording laps.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I only just saw your comment.
data_history is a FIFO queue of GTData packets to help determine whether the replay has started or ended.
At replay start, total_laps will quickly flip to -1 for a fraction of a second, it usually lasts 3 packets, but just for safety, I assumed it could last a bit longer. check_for_replay_start() just implements this logic, it just looks for this pattern … >=0, -1, >=0 …. It starts by scanning the latest and its previous 5 packets, when total_laps is no less than 0, and its previous total_laps is -1, replay has probably started; then we scan further back, and look for a total_laps value no less than 0, within 5 packets or 5 frames worth of packets, whichever is less; if we found one, then we can determine that replay has started; lastly we discard all packets before the replay start and returning True.
At replay end, we look for an abrupt change in engine RPM. In check_for_replay_end(), if rpm changed more than 10% within 1/30 of a second, we determine that the replay has ended, then discard all packets before the replay end. Admittedly, this is not reliable if you have pitted during a race, but I didn't quite figure out the pattern of a pit stop, the RPM and speed changes are quite random.
There are magic numbers, but they can be easily extracted and renamed.

@snipem
Copy link
Owner

snipem commented Feb 25, 2023

It seems like your changes interfere with some basic functionality. For example: Last Lap time, Max Speed, Min Body Height are not longer logged correctly. This is what I saw when I was racing with your branch yesterday.

@snipem
Copy link
Owner

snipem commented Mar 17, 2023

I have added a manual recording switch for replays with #6

@Nathaniel-Wu
Copy link
Author

Nathaniel-Wu commented Mar 18, 2023

It seems like your changes interfere with some basic functionality. For example: Last Lap time, Max Speed, Min Body Height are not longer logged correctly. This is what I saw when I was racing with your branch yesterday.

I'm not sure why it does that, I only added a recvtime field to GTData, and other parts of run() is stateless, all my changes do is determine whether the in_race field should actually be True when the raw value is False, it should not affect other parts of your program. The only possibility I can think of is that you used some fields of GTData not by field identifier but by bytes offsets or typecasted it to something else (I don't even know if you can do these things in python), and my added recvtime field interferes that.

@snipem snipem closed this Jun 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants