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 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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;

// 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();
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
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