-
Notifications
You must be signed in to change notification settings - Fork 110
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
Remove all instances of MessageToDict #3405
base: master
Are you sure you want to change the base?
Conversation
""" | ||
tactic_assignments = play_info_dict["robotTacticAssignment"] | ||
tactic_assignments = play_info.robotTacticAssignment() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't quite work. The correct way access the robot tactic assignment field is: play_info.robot_tactic_assignment()
.
This will return a MessageMapContainer
which has this API: https://googleapis.dev/python/protobuf/3.17.0/google/protobuf/internal/containers.html#google.protobuf.internal.containers.MessageMap
The function call will match the field from the definition of the proto parameters:
Software/src/proto/play_info_msg.proto
Line 18 in 10bded3
map<uint32, Tactic> robot_tactic_assignment = 1; |
@@ -38,20 +36,17 @@ def __init__(self, name: str, buffer_size: int = 5) -> None: | |||
def refresh_graphics(self) -> None: | |||
"""Update graphics in this layer""" | |||
self.cached_world = self.world_buffer.get(block=False) | |||
play_info = self.play_info_buffer.get(block=False) | |||
play_info_dict = MessageToDict(play_info) | |||
play_info = self.play_info_buffer.get(block=False).GetOptions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need to call GetOptions()
here. I believe you'll only need this if you define specific bounds for the proto definitions (like if you defined this proto:
Software/src/proto/parameters.proto
Line 61 in 10bded3
required double ball_is_kicked_m_per_s_threshold = 1 |
playinfo = self.playinfo_buffer.get(block=False, return_cached=False) | ||
playinfo = self.playinfo_buffer.get( | ||
block=False, return_cached=False | ||
).GetOptions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need to call GetOptions
here
robot_ids = [] | ||
tactic_fsm_states = [] | ||
tactic_names = [] | ||
play_name = [] | ||
|
||
if "robotTacticAssignment" not in play_info_dict: | ||
if "robotTacticAssignment" not in playinfo: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you can do if not playinfo.robot_tactic_assignment()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe try if not playinfo.robot_tactic_assignment
if that doesn't work. I may be wrong, but I feel like robot_tactic_assignment
would return a type of dict
which is not callable?
len(playinfo.robotTacticAssignment()), | ||
len(playinfo.play.playState()), | ||
) | ||
|
||
# setting table size dynamically | ||
self.play_table.setRowCount(num_rows) | ||
|
||
for state in play_info_dict["play"]["playState"]: | ||
for state in playinfo.play().playstate(): | ||
play_name.append(state) | ||
|
||
for robot_id in sorted(play_info_dict["robotTacticAssignment"]): | ||
for robot_id in sorted(playinfo.robotTacticAssignment()): | ||
robot_ids.append(robot_id) | ||
tactic_fsm_states.append( | ||
play_info_dict["robotTacticAssignment"][robot_id]["tacticFsmState"] | ||
playinfo.robotTacticAssignment().robot_id().tacticFsmState() | ||
) | ||
tactic_names.append( | ||
play_info_dict["robotTacticAssignment"][robot_id]["tacticName"] | ||
playinfo.robotTacticAssignment().robot_id().tacticName() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these function calls should be updated. The field names should match the proto field names.
You should take a look at the proto definition:
message PlayInfo |
And take a look at the Python generated code reference guide: https://protobuf.dev/reference/python/python-generated/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for your reference, it should be something like this:
for robot_id in sorted(playinfo.robot_tactic_assignment):
robot_ids.append(robot_id)
tactic_fsm_states.append(
playinfo.robot_tactic_assignment[robot_id].tactic_fsm_state
)
tactic_names.append(
playinfo.robot_tactic_assignment[robot_id].tactic_name
)
playinfo
has type is a google protobuf type. playinfo.robot_tactic_assignment
returns a dictionary. So to access this we need an id like robot_id
. playinfo.robot_tactic_assignment[robot_id]
is this type:
Software/src/proto/play_info_msg.proto
Lines 12 to 16 in 10bded3
message Tactic | |
{ | |
string tactic_name = 1; | |
string tactic_fsm_state = 2; | |
} |
To get the tactic_name we do playinfo.robot_tactic_assignment[robot_id].tactic_name
@@ -36,15 +35,13 @@ def __init__(self, buffer_size: int = 1) -> None: | |||
|
|||
def refresh(self) -> None: | |||
"""Update the referee info widget with new referee information""" | |||
referee = self.referee_buffer.get(block=False, return_cached=False) | |||
referee = self.referee_buffer.get(block=False, return_cached=False).GetOptions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need to call GetOptions
here
|
||
if not referee_msg_dict: | ||
if not referee: | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this check is duplicated above, you can delete this now
referee_msg_dict = MessageToDict(referee) | ||
|
||
if not referee_msg_dict: | ||
if not referee: | ||
return | ||
|
||
stage_time_left_s = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to update:
referee_msg_dict["stageTimeLeft"]
referee_msg_dict["packetTimestamp"]
blue.append(referee_msg_dict["blue"][info]) | ||
yellow.append(referee_msg_dict["yellow"][info]) | ||
blue.append(referee.blue().info()) | ||
yellow.append(referee.yellow().info()) | ||
|
||
set_table_data( | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you also need to update the implementation of parse_yellow_card_times
I believe for the team_info object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start. I recommend running ./tbots.py run thunderscope_main --enable_autoref
and check the console to see if errors are being spammed. If everything is working properly, you should see the "Play Info" and "Referee Info" widget constantly update.
return | ||
|
||
num_rows = max( | ||
len(play_info_dict["robotTacticAssignment"]), | ||
len(play_info_dict["play"]["playState"]), | ||
len(playinfo.robotTacticAssignment()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you meant len(playinfo.robot_tactic_assignment)
len(play_info_dict["robotTacticAssignment"]), | ||
len(play_info_dict["play"]["playState"]), | ||
len(playinfo.robotTacticAssignment()), | ||
len(playinfo.play.playState()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be len(playinfo.play.play_state)
, you should check these two comments.
@@ -54,27 +51,27 @@ def refresh(self) -> None: | |||
f"Packet Timestamp: {round(float(referee_msg_dict['packetTimestamp']) * SECONDS_PER_MICROSECOND, 3)}\n" | |||
+ f"Stage Time Left: {int(stage_time_left_s / SECONDS_PER_MINUTE):02d}" | |||
+ f":{int(stage_time_left_s % SECONDS_PER_MINUTE):02d}\n" | |||
+ f"Stage: {referee_msg_dict['stage']}\n" | |||
+ f"Stage: {referee.stage()}\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need a ()
, so just referee.stage
+ "Command: " | ||
+ referee_msg_dict["command"] | ||
+ referee.command() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
+ "\n" | ||
+ f"Blue Team on Positive Half: {referee_msg_dict['blueTeamOnPositiveHalf']}\n" | ||
+ f"Blue Team on Positive Half: {referee.blueTeamOnPositiveHalf()}\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here as well
if info == "yellowCardTimes": | ||
blue.append(self.parse_yellow_card_times(referee_msg_dict["blue"])) | ||
yellow.append(self.parse_yellow_card_times(referee_msg_dict["yellow"])) | ||
blue.append(self.parse_yellow_card_times(referee.blue())) | ||
yellow.append(self.parse_yellow_card_times(referee.yellow())) | ||
elif info == "remainingTimeouts": | ||
blue.append(referee_msg_dict["blue"]["timeouts"]) | ||
yellow.append(referee_msg_dict["yellow"]["timeouts"]) | ||
blue.append(referee.blue().timeouts()) | ||
yellow.append(referee.yellow().timeouts()) | ||
elif info == "goalkeeperID": | ||
blue.append(referee_msg_dict["blue"]["goalkeeper"]) | ||
yellow.append(referee_msg_dict["yellow"]["goalkeeper"]) | ||
blue.append(referee.blue().goalkeepers()) | ||
yellow.append(referee.yellow().goalkeeper()) | ||
else: | ||
blue.append(referee_msg_dict["blue"][info]) | ||
yellow.append(referee_msg_dict["yellow"][info]) | ||
blue.append(referee.blue().info()) | ||
yellow.append(referee.yellow().info()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you actually don't need the ()
here.
from thefuzz import fuzz | ||
from proto.import_all_protos import * | ||
|
||
|
||
def __create_int_parameter_writable(key, value, descriptor): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be nice to add type annotation
def __create_int_parameter_writable(key, value, descriptor):
to def __create_int_parameter_writable(key:str, value:int, descriptor:FieldDescriptor):
Also, FieldDescriptor
could be found here: from google.protobuf.descriptor import FieldDescriptor
looking good. just need some final touches. |
FYI: Say we have the following protobuf file
We use a protobuf compiler, called protoc, to generate the python file. This would then be turned into some python file under some black magic process. To set the field, we do something like this;
To access the field, we do something like this:
Since from the
This would imply that see here for the entire code: https://github.com/Mr-Anyone/Thunderbot_Software/tree/proto_example/src/proto_example You might have to do:
|
Please fill out the following before requesting review on this PR
Description
Testing Done
n/a
Resolved Issues
#3341
Review Checklist
It is the reviewers responsibility to also make sure every item here has been covered
.h
file) should have a javadoc style comment at the start of them. For examples, see the functions defined inthunderbots/software/geom
. Similarly, all classes should have an associated Javadoc comment explaining the purpose of the class.TODO
(or similar) statements should either be completed or associated with a github issue