Skip to content

[Thunderscope] Remove Extra Robots and Add Missing Robots during Simulator + Fixes #3454

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

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

Andrewyx
Copy link
Contributor

@Andrewyx Andrewyx commented Mar 30, 2025

Please fill out the following before requesting review on this PR

Description

This PR provides support for dynamic robot removal & re-addition during simulation per acquired cards during play. Addition is then called after cards expire (yellow), and robots are placed back onto the field along the field margin along the halfway line (per RoboCup rules).
Also addresses the following:

  • Introduces a new ThreadSafeCircularBuffer for more efficient proto handling
  • this ticket also resolves a few other Thunderscope bugs. See below.

Testing Done

Modifying GC during sims works.

Screencast.from.2025-03-30.13-19-52.webm

Resolved Issues

Resolves #3116

Extras:

Length Justification and Key Files to Review

Review Checklist

It is the reviewers responsibility to also make sure every item here has been covered

  • Function & Class comments: All function definitions (usually in the .h file) should have a javadoc style comment at the start of them. For examples, see the functions defined in thunderbots/software/geom. Similarly, all classes should have an associated Javadoc comment explaining the purpose of the class.
  • Remove all commented out code
  • Remove extra print statements: for example, those just used for testing
  • Resolve all TODO's: All TODO (or similar) statements should either be completed or associated with a github issue

@itsarune itsarune requested review from Copilot, a team, DimitriK24, someone2060 and AmyKawa and removed request for a team April 18, 2025 07:54
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances the Thunderscope simulator by supporting dynamic robot removal and re-addition during simulation, while also refactoring buffer implementations and updating referee-related commands and tests. Key changes include:

  • Updating the Gamecontroller to pass in a simulator-specific proto IO and introducing a ThreadSafeCircularBuffer.
  • Refactoring various modules to replace direct queue access with uniform buffer get/size methods.
  • Updating test cases and referee command mappings from indirect to direct commands.

Reviewed Changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/software/thunderscope/thunderscope_main.py Updated Gamecontroller instantiation to include simulator_proto_unix_io.
src/software/thunderscope/thread_safe_buffer.py Replaced direct queue usage with a new buffer attribute and updated exception handling.
src/software/thunderscope/log/g3log_widget.py Modified log retrieval to use the buffer's get method.
src/software/thunderscope/gl/layers/* Refactored graphics layers to use buffer.size() and get methods instead of direct queue access.
src/software/thunderscope/common/thread_safe_circular_buffer.py Added a new circular buffer for improved proto handling.
src/software/thunderscope/common/proto_plotter.py Adjusted buffer iteration to use the new size() method.
src/software/thunderscope/binary_context_managers/game_controller.py Enhanced robot count updating and integrated new referee handling.
src/software/sensor_fusion/sensor_fusion_test.cpp Updated tests to use direct referee commands instead of indirect ones.
src/proto/message_translation/* Updated deprecated referee commands and removed indirect command tuples.
Files not reviewed (2)
  • src/software/thunderscope/binary_context_managers/BUILD: Language not supported
  • src/software/thunderscope/common/BUILD: Language not supported
Comments suppressed due to low confidence (1)

src/software/thunderscope/common/thread_safe_circular_buffer.py:53

  • MIN_DROPPED_BEFORE_LOG is referenced but not defined in this class; consider defining it as a class-level constant if it is not inherited from the parent class.
and self.protos_dropped > self.MIN_DROPPED_BEFORE_LOG

Comment on lines +71 to +72
{tactic_assignments[robot.id].tactic_name} -
{tactic_assignments[robot.id].tactic_fsm_state}
Copy link
Preview

Copilot AI Apr 18, 2025

Choose a reason for hiding this comment

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

The earlier version accessed tactic assignments using string keys via a function call, but the updated code uses robot.id directly; ensure that the key types are consistent (e.g., converting robot.id to string if required) to avoid potential mismatches.

Suggested change
{tactic_assignments[robot.id].tactic_name} -
{tactic_assignments[robot.id].tactic_fsm_state}
{tactic_assignments[str(robot.id)].tactic_name} -
{tactic_assignments[str(robot.id)].tactic_fsm_state}

Copilot uses AI. Check for mistakes.

Copy link
Contributor

Choose a reason for hiding this comment

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

probably a bad take here

@@ -62,6 +70,8 @@ const static std::unordered_map<SSLProto::Referee::Command, RefereeCommand>
RefereeCommand createRefereeCommand(const SSLProto::Referee &packet,
TeamColour team_colour)
{
if (deprecated_commands.contains(packet.command()))
Copy link
Contributor

Choose a reason for hiding this comment

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

didn't we notice the gamecontroller randomly generate these? couldn't this cause our robots to randomly halt during the game (which is bad).

@@ -124,17 +124,6 @@ INSTANTIATE_TEST_CASE_P(
std::make_tuple(RefereeCommand::DIRECT_FREE_THEM,
SSLProto::Referee_Command_DIRECT_FREE_YELLOW, TeamColour::BLUE),

// indirect free
Copy link
Contributor

Choose a reason for hiding this comment

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

depending on above comment, you might need to change this

self,
suppress_logs: bool = False,
use_conventional_port: bool = False,
simulator_proto_unix_io: ProtoUnixIO = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

simulated_proto_unix_io needs docs

Copy link
Contributor

Choose a reason for hiding this comment

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

also you can probably pass this in via setup_proto_unix_io

return
for _ in range(robots_diff):
try:
robot_states[removed_robot_ids.get_nowait()].CopyFrom(place_state)
Copy link
Contributor

Choose a reason for hiding this comment

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

do multiple robots being spawned in the same location cause any issues?

except queue.Empty:
return

def handle_referee(self, referee: Referee) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

handle_referee is not a clear enough name here. I suggest handle_fouls

@@ -168,6 +281,7 @@ def __send_referee_command(data: Referee) -> None:

:param data: The referee command to send
"""
self.handle_referee(data)
Copy link
Contributor

Choose a reason for hiding this comment

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

you can probably move this down to the if autoref_proto_unix_io is not None check below.

Copy link
Contributor

Choose a reason for hiding this comment

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

or you should probably have a new argument for this class called enable_auto_remove_robots that will enable this feature

@@ -187,6 +301,9 @@ def __send_referee_command(data: Referee) -> None:
yellow_full_system_proto_unix_io.register_observer(
ManualGCCommand, self.command_override_buffer
)
blue_full_system_proto_unix_io.register_observer(
Copy link
Contributor

Choose a reason for hiding this comment

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

why only register the World for blue?

from typing import override


class ThreadSafeCircularBuffer(ThreadSafeBuffer):
Copy link
Contributor

Choose a reason for hiding this comment

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

make an issue to collapse both ThreadSafeBufer and ThreadSafeCircularBuffer into better OOP-style

Copy link
Contributor

Choose a reason for hiding this comment

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

or we could completely replace ThreadSafeBuffer into a deque implementation which I think will work

cost_vis = self.cost_visualization_buffer.queue.get_nowait()
except queue.Empty:
cost_vis = None
cost_vis = self.cost_visualization_buffer.get(block=False, return_cached=False)
Copy link
Contributor

Choose a reason for hiding this comment

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

does it not raise a queue.Empty error anymore?

pass_vis = self.pass_visualization_buffer.queue.get_nowait()
except queue.Empty:
pass_vis = None
pass_vis = self.pass_visualization_buffer.get(block=False, return_cached=False)
Copy link
Contributor

Choose a reason for hiding this comment

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

does it not raise a queue.Empty error anymore?

log = self.log_buffer.queue.get_nowait()
except queue.Empty:

log = self.log_buffer.get(block=False, return_cached=False)
Copy link
Contributor

Choose a reason for hiding this comment

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

no queue.Empty exception?

@@ -168,6 +281,7 @@ def __send_referee_command(data: Referee) -> None:

:param data: The referee command to send
"""
self.handle_referee(data)
Copy link
Contributor

Choose a reason for hiding this comment

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

pass in simulator_proto_unix_io as an argument to this setup_proto_unix_io function and then you can call self.handle_data(simulator_proto_unix_io and avoid modifying the constructor

Copy link
Contributor

@itsarune itsarune left a comment

Choose a reason for hiding this comment

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

great work! this will help us loads in figuring out gameplay issues before robocup!

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.

Extra robots should be removed from AI vs AI when a team receives a foul
2 participants