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

Add referee display layer #3337

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4d608ca
Add new layer
Lmh-java Oct 4, 2024
de95603
Update format
Lmh-java Oct 4, 2024
07f17cb
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 4, 2024
b369777
Fix typo
Lmh-java Oct 5, 2024
8f58631
Add ball placement vis?
Lmh-java Oct 5, 2024
878112a
Migrate ball placement
Lmh-java Oct 5, 2024
160d347
Add ball placement visuals
Lmh-java Oct 6, 2024
ef0a030
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 6, 2024
f39a399
Refactor code
Lmh-java Oct 19, 2024
0d242ce
Fix refactor
Lmh-java Oct 19, 2024
db3f208
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 19, 2024
709db29
Rename methods
Lmh-java Oct 19, 2024
ecd314d
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 19, 2024
b7642cf
Merge branch 'master' into HEAD
Lmh-java Oct 25, 2024
4f3d93c
replace auto with optional
Lmh-java Oct 26, 2024
947428d
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 26, 2024
70ea39f
partially introduce constexpr
Lmh-java Oct 26, 2024
63ff6ed
use cpp library calls
Lmh-java Nov 9, 2024
494b833
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Nov 9, 2024
f403762
nit
Lmh-java Nov 16, 2024
e08edd0
replace all font name with constant
Lmh-java Nov 16, 2024
8b1a616
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Nov 16, 2024
2daae4f
update flag logic
Lmh-java Nov 23, 2024
207eae2
Merge branch 'minghao/referee-layer' of github.com:Lmh-java/Software …
Lmh-java Nov 23, 2024
4f94227
update flag logic
Lmh-java Nov 23, 2024
7368f8c
Merge branch 'master' into minghao/referee-layer
Lmh-java Nov 23, 2024
7f097b0
Merge branch 'master' into minghao/referee-layer
Lmh-java Jan 19, 2025
afaf9a9
remove font name instance
Lmh-java Jan 19, 2025
6b4fb32
fix
Lmh-java Jan 19, 2025
1f91332
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Jan 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/proto/visualization.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ message AttackerVisualization
optional Point chip_target = 4;
}

message BallPlacementVisualization
{
Point ball_placement_point = 1;
}

message CostVisualization
{
uint32 num_rows = 1;
Expand Down
8 changes: 8 additions & 0 deletions src/shared/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ static const double BALL_MAX_RADIUS_METERS = 0.0215;
// cover more than 20% of the ball
static const double MAX_FRACTION_OF_BALL_COVERED_BY_ROBOT = 0.2;

// The radius of a circle region where ball placement is acceptable (in meters).
static const double BALL_PLACEMENT_TOLERANCE_RADIUS_METERS = 0.15;
// The radius of the outer region where robots are not allowed to be during ball
// placement (in meters)
static const double BALL_PLACEMENT_ROBOT_AVOID_RADIUS_METERS = 0.5;
// The time limit for ball placement in seconds
static const int BALL_PLACEMENT_TIME_LIMIT_S = 30;
Copy link
Contributor

Choose a reason for hiding this comment

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

Interestingly enough, it seems that our constants.h file is wildly inconsistent with its use of static const vs constexpr. From my knowledge, there is no real performance difference here aside from constexpr potentially preventing others in the future from assigning a non-compile time constant value to these variables.

TLDR: ask the others about as I am not sure why this is the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As the info I have learned just then, constexpr might be used in this case, but I will confirm with others.

static const seems to be used more in class-level constants. If we use constexpr, it allows complie-time optimization.

If confirmed and refactor needed, do you mind if I do this refactor in a separate ticket, so we don't mess up other features.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, sounds good.

IMO constexpr and static const in this case should not technically have a difference in optimization in this case as most of the static const values we have can be determined at compile-time which results in the optimization process being carried through anyways (to my understanding). This would mean the main advantage of switching would purely be to deter others in the future from using non-compile time derivable values (as constexpr would throw an error). You may want to refer to the link below for a clearer explanation:

https://stackoverflow.com/questions/41125651/constexpr-vs-static-const-which-one-to-prefer

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, we could open a new issue to make all these constants constexpr. The main benefit would be so that we can use these constants in other constexpr variables and use them in template args, array declarations, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, fixed all 3 constants included in this PR with constexpr. Will send another PR on refactoring others after this is merged.


// The mass of a standard golf ball, as defined by https://en.wikipedia.org/wiki/Golf_ball
constexpr double BALL_MASS_KG = 0.004593;
// The max allowed speed of the robot when the stop command is issued, in meters per
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "software/ai/hl/stp/play/ball_placement/ball_placement_play.h"

#include "proto/message_translation/tbots_geometry.h"
#include "software/util/generic_factory/generic_factory.h"


Expand All @@ -17,7 +18,18 @@ void BallPlacementPlay::getNextTactics(TacticCoroutine::push_type &yield,

void BallPlacementPlay::updateTactics(const PlayUpdate &play_update)
{
fsm.process_event(BallPlacementPlayFSM::Update(control_params, play_update));
auto event = BallPlacementPlayFSM::Update(control_params, play_update);
fsm.process_event(event);

auto placement_point = event.common.world_ptr->gameState().getBallPlacementPoint();
Lmh-java marked this conversation as resolved.
Show resolved Hide resolved
if (placement_point.has_value())
{
TbotsProto::BallPlacementVisualization ball_placement_vis_msg;
*(ball_placement_vis_msg.mutable_ball_placement_point()) =
*createPointProto(placement_point.value());

LOG(VISUALIZE) << ball_placement_vis_msg;
}
}

std::vector<std::string> BallPlacementPlay::getState()
Expand Down
5 changes: 5 additions & 0 deletions src/software/py_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ PYBIND11_MODULE(py_constants, m)
m.attr("BALL_MAX_RADIUS_METERS") = BALL_MAX_RADIUS_METERS;
m.attr("BALL_MAX_RADIUS_MILLIMETERS") =
BALL_MAX_RADIUS_METERS * MILLIMETERS_PER_METER;
m.attr("BALL_PLACEMENT_TOLERANCE_RADIUS_METERS") =
BALL_PLACEMENT_TOLERANCE_RADIUS_METERS;
m.attr("BALL_PLACEMENT_ROBOT_AVOID_RADIUS_METERS") =
BALL_PLACEMENT_ROBOT_AVOID_RADIUS_METERS;
m.attr("BALL_PLACEMENT_TIME_LIMIT_S") = BALL_PLACEMENT_TIME_LIMIT_S;

m.attr("MAX_FRACTION_OF_BALL_COVERED_BY_ROBOT") =
MAX_FRACTION_OF_BALL_COVERED_BY_ROBOT;
Expand Down
1 change: 1 addition & 0 deletions src/software/thunderscope/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ py_library(
"//software/thunderscope/gl/layers:gl_obstacle_layer",
"//software/thunderscope/gl/layers:gl_passing_layer",
"//software/thunderscope/gl/layers:gl_path_layer",
"//software/thunderscope/gl/layers:gl_referee_info_layer",
"//software/thunderscope/gl/layers:gl_sandbox_world_layer",
"//software/thunderscope/gl/layers:gl_simulator_layer",
"//software/thunderscope/gl/layers:gl_tactic_layer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ def setup_proto_unix_io(self, proto_unix_io: ProtoUnixIO) -> None:
PlayInfo,
ObstacleList,
DebugShapes,
BallPlacementVisualization,
]:
proto_unix_io.attach_unix_receiver(
runtime_dir=self.full_system_runtime_dir,
Expand Down
1 change: 1 addition & 0 deletions src/software/thunderscope/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ class Colors:
ROBOT_MIDDLE_BLUE = QtGui.QColor(0, 0, 255, 255)
PINK = QtGui.QColor(255, 0, 255)
GREEN = QtGui.QColor(0, 255, 0)
RED = QtGui.QColor(255, 0, 0, 255)

# Creates a default vision pattern lookup with the actual colors used on the robots
VISION_PATTERN_LOOKUP = create_vision_pattern_lookup(PINK, GREEN)
Expand Down
9 changes: 9 additions & 0 deletions src/software/thunderscope/gl/graphics/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,12 @@ py_library(
":gl_shape",
],
)

py_library(
name = "gl_label",
srcs = ["gl_label.py"],
deps = [
requirement("pyqtgraph"),
":gl_shape",
],
)
78 changes: 78 additions & 0 deletions src/software/thunderscope/gl/graphics/gl_label.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from PyQt6.QtGui import QFont, QColor
from pyqtgraph.opengl.GLGraphicsItem import GLGraphicsItem
from pyqtgraph.Qt import QtCore, QtGui

from typing import Optional

from software.thunderscope.gl.graphics.gl_painter import GLPainter
from software.thunderscope.constants import Colors


class GLLabel(GLPainter):
"""Displays a 2D text label on the viewport"""

def __init__(
self,
parent_item: Optional[GLGraphicsItem] = None,
font: QFont = QFont("Roboto", 8),
text_color: QColor = Colors.PRIMARY_TEXT_COLOR,
offset: tuple[int, int] = (0, 0),
text: str = "",
) -> None:
"""Initialize the GLLabel

:param parent_item: The parent item of the graphic
:param font: The font using to render the text
:param text_color: The color for rendering the text.
:param offset: The offset (x, y) from the viewport left and top edge
to use when positioning the label.
If x is negative then the x offset is |x| pixels from
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: is this necessary? feels like its a bit clearer to just require the offsets to be positive numbers always. from the perspective of someone using this method in the future, the sign flipping feels a bit roundabout

Copy link
Contributor

Choose a reason for hiding this comment

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

not a huge deal tho

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lol I followed the design of other components on the same level for consistency. But sure, I will clean this up to make it more understandable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After some testing here, I found out that the easier way to place the label on the top right corner is just to keep this wired sign flipping, because it takes some code to fetch the width of the viewport before passing into this function. Instead, we can get viewport by whatever calls this function, so we probably need to use a negative sign to denote starting from the right side.

the viewport right edge.
If y is negative then the y offset is |y| pixels from
the viewport bottom edge.
:param text: The optional title to display above the legend
"""
super().__init__(parent_item=parent_item)

self.text_pen = QtGui.QPen(text_color)
self.font = font
self.offset = offset
self.text = text

self.add_draw_function(self.draw_label)

def draw_label(self, painter: QtGui.QPainter, viewport_rect: QtCore.QRect) -> None:
"""Draw the label

:param painter: The QPainter to perform drawing operations with
:param viewport_rect: The QRect indicating the viewport dimensions
"""
# calculate width and height of the label
painter.setFont(self.font)
bounds = painter.boundingRect(
QtCore.QRectF(0, 0, 0, 0),
QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter,
str(self.text),
)

width = round(bounds.width())
height = round(bounds.height())

# Determine x and y coordinates of the label
if self.offset[0] < 0:
x = viewport_rect.right() + self.offset[0] - width
else:
x = viewport_rect.left() + self.offset[0]
if self.offset[1] < 0:
y = viewport_rect.bottom() + self.offset[1] - height
else:
y = viewport_rect.top() + self.offset[1]

if self.text:
painter.drawText(QtCore.QPoint(x, y), self.text)

def set_text(self, new_text: str) -> None:
"""Update the text being displayed
:param new_text: new text being displayed
"""
self.text = new_text
10 changes: 10 additions & 0 deletions src/software/thunderscope/gl/layers/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,13 @@ py_library(
requirement("pyqtgraph"),
],
)

py_library(
name = "gl_referee_info_layer",
srcs = ["gl_referee_info_layer.py"],
deps = [
":gl_layer",
"//software/thunderscope/gl/graphics:gl_label",
requirement("pyqtgraph"),
],
)
Loading
Loading