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

WIP : Penalty Improvements #133

Open
wants to merge 7 commits into
base: main
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
2 changes: 1 addition & 1 deletion roboteam_ai/include/roboteam_ai/utilities/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace rtt::ai::constants {
constexpr bool FEEDBACK_ENABLED = true; /**< Checks whether robot feedback is enabled */
// Kick and chip constants
constexpr double MAX_KICK_POWER = 6.5; /**< Maximum allowed kicking power */
constexpr double MIN_KICK_POWER = 3.0; /**< Minimum allowed kicking power */
constexpr double MIN_KICK_POWER = 0.1; /**< Minimum allowed kicking power */
constexpr double MAX_CHIP_POWER = 6.5; /**< Maximum allowed chipping power */
constexpr double MIN_CHIP_POWER = 4.5; /**< Minimum allowed chipping power */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ InterceptionInfo InterceptionComputations::calculateInterceptionInfo(const std::
auto futureBallPosition = ballPosition;
auto ballVelocity = world->getWorld()->getBall()->get()->velocity;
bool shouldReturn = false;
bool canIntercept = true;
interceptionInfo.interceptLocation = ballPosition;
const LineSegment ballTrajectory(world->getWorld()->getBall()->get()->position, world->getWorld()->getBall()->get()->expectedEndPosition);
auto interceptRobot = calculateTheirBallInterception(world, ballTrajectory);
Expand Down Expand Up @@ -103,7 +104,7 @@ InterceptionInfo InterceptionComputations::calculateInterceptionInfo(const std::
interceptionInfo.interceptId = robot->getId();
interceptionInfo.timeToIntercept = minTimeToTarget;
auto theirClosestToBall = world->getWorld()->getRobotClosestToBall(world::them);
if (!theirClosestToBall || (robot->getPos() - targetPosition).length() < (theirClosestToBall->get()->getPos() - targetPosition).length()) {
if (!theirClosestToBall || (robot->getPos() - targetPosition).length() < (theirClosestToBall->get()->getPos() - targetPosition).length() && canIntercept) {
interceptionInfo.isInterceptable = true;
}
}
Expand Down Expand Up @@ -146,6 +147,9 @@ InterceptionInfo InterceptionComputations::calculateInterceptionInfo(const std::
if (world->getField().value().playArea.contains(ballPosition, constants::BALL_RADIUS)) {
futureBallPosition =
FieldComputations::projectPointIntoFieldOnLine(world->getField().value(), futureBallPosition, ballPosition, futureBallPosition, constants::BALL_RADIUS);
auto robot = world->getWorld()->getRobotClosestToBall(world::us)->get();
auto trajectory = Trajectory2D(robot->getPos(), robot->getVel(), futureBallPosition, maxRobotVelocity, ai::constants::MAX_ACC);
if (trajectory.getTotalTime() > 0.1) canIntercept = false;
calculateIntercept(futureBallPosition);
} else {
calculateIntercept(ballPosition);
Expand Down
5 changes: 4 additions & 1 deletion roboteam_ai/src/stp/plays/offensive/Attack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ Attack::Attack() : Play() {

uint8_t Attack::score(const rtt::Field& field) noexcept {
// Score the position of the ball based on the odds of scoring
return PositionScoring::scorePosition(world->getWorld()->getBall().value()->position, gen::GoalShot, field, world).score * (rand() % (2) + 1);
// Multiply the score with a random value when the ball is on their side
double random_value = rand() % (2) + 1;
if (field.leftPlayArea.contains(world->getWorld()->getBall().value()->position)) random_value = 0.0;
return PositionScoring::scorePosition(world->getWorld()->getBall().value()->position, gen::GoalShot, field, world).score * random_value;
}

Dealer::FlagMap Attack::decideRoleFlags() const noexcept {
Expand Down
13 changes: 12 additions & 1 deletion roboteam_ai/src/stp/plays/referee_specific/PenaltyThem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,18 @@ Dealer::FlagMap PenaltyThem::decideRoleFlags() const noexcept {
return flagMap;
}

void PenaltyThem::calculateInfoForRoles() noexcept { stpInfos["keeper"].setPositionToMoveTo(field.leftGoalArea.rightLine().center()); }
void PenaltyThem::calculateInfoForRoles() noexcept {
if (stpInfos["keeper"].getRobot() && field.leftDefenseArea.rightLine().distanceToLine(world->getWorld()->getBall()->get()->position) < 0.8 &&
field.leftDefenseArea.rightLine().center().x < world->getWorld()->getBall()->get()->position.x &&
world->getWorld()->getBall()->get()->velocity.length() < constants::BALL_GOT_SHOT_LIMIT) {
// If the ball gets close to the goal, we want to get closer towards the ball to make it harder to score
auto targetPosition = world->getWorld()->getBall()->get()->position -
(world->getWorld()->getBall()->get()->position - field.leftGoalArea.rightLine().center()).stretchToLength(constants::ROBOT_RADIUS * 2.5);
stpInfos["keeper"].setPositionToMoveTo(targetPosition);
} else
// Just stand in the middle of the goal
stpInfos["keeper"].setPositionToMoveTo(field.leftGoalArea.rightLine().center());
}

const char* PenaltyThem::getName() const { return "Penalty Them"; }
} // namespace rtt::ai::stp::play
28 changes: 15 additions & 13 deletions roboteam_ai/src/stp/plays/referee_specific/PenaltyUs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,21 @@ Dealer::FlagMap PenaltyUs::decideRoleFlags() const noexcept {

void PenaltyUs::calculateInfoForRoles() noexcept {
auto positionTarget = PositionComputations::getPosition(std::nullopt, field.middleRightGrid, gen::GoalShot, field, world);
if (!RuntimeConfig::useReferee || GameStateManager::getCurrentGameState().timeLeft > 3.0) {
stpInfos["kicker"].setPositionToMoveTo(positionTarget);
} else {
stpInfos["kicker"].setPositionToMoveTo(stpInfos["kicker"].getRobot()->get()->getPos());
// set kick
stpInfos["kicker"].setKickOrChip(KickType::KICK);
}
auto goalTarget = computations::GoalComputations::calculateGoalTarget(world, field);
stpInfos["kicker"].setPositionToShootAt(goalTarget);
stpInfos["kicker"].setShotPower(ShotPower::MAX);
if (stpInfos["kicker"].getRobot().has_value() && stpInfos["kicker"].getRobot()->get()->hasBall()) {
stpInfos["kicker"].setMaxRobotVelocity((stpInfos["kicker"].getRobot()->get()->getPos() - positionTarget.position).length() * 4.8);
}
if (!RuntimeConfig::useReferee || GameStateManager::getCurrentGameState().timeLeft < 3.0 ||
(stpInfos["kicker"].getRobot() && (positionTarget.position - stpInfos["kicker"].getRobot()->get()->getPos()).length() < 1 ||
(positionTarget.position - world->getWorld()->getBall()->get()->position).length() < 2)) {
// Kick the ball at the goal if time is running out or if we are close enough
auto goalTarget = computations::GoalComputations::calculateGoalTarget(world, field);
stpInfos["kicker"].setPositionToShootAt(goalTarget);
stpInfos["kicker"].setShotPower(ShotPower::MAX);
} else if (stpInfos["kicker"].getRobot()) {
// Shoot the ball a bit ahead to cover ground towards the goal quickly
auto targetPosition = (positionTarget.position - stpInfos["kicker"].getRobot()->get()->getPos())
.stretchToLength((positionTarget.position - stpInfos["kicker"].getRobot()->get()->getPos()).length() / 1.7);
stpInfos["kicker"].setPositionToShootAt(targetPosition);
stpInfos["kicker"].setShotPower(ShotPower::TARGET);
} else
stpInfos["kicker"].setPositionToMoveTo(world->getWorld()->getBall()->get()->position);
}

} // namespace rtt::ai::stp::play
12 changes: 9 additions & 3 deletions roboteam_ai/src/stp/roles/PenaltyKeeper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <roboteam_utils/Print.h>

#include "stp/tactics/KeeperBlockBall.h"
#include "stp/tactics/active/GetBall.h"
#include "stp/tactics/passive/Formation.h"

namespace rtt::ai::stp::role {
Expand All @@ -14,12 +13,12 @@ namespace rtt::ai::stp::role {

PenaltyKeeper::PenaltyKeeper(std::string name) : Keeper(std::move(name)) {
// create state machine and initializes the first state
robotTactics = collections::state_machine<Tactic, Status, StpInfo>{tactic::Formation(), tactic::KeeperBlockBall()};
robotTactics = collections::state_machine<Tactic, Status, StpInfo>{tactic::Formation(), tactic::KeeperBlockBall(), tactic::Formation()};
}

Status PenaltyKeeper::update(StpInfo const& info) noexcept {
// Failure if the required data is not present
if (!info.getBall() || !info.getRobot() || !info.getField()) {
if (!info.getBall() || !info.getRobot() || !info.getField() || !info.getCurrentWorld()) {
RTT_WARNING("Required information missing in the tactic info for ", roleName)
return Status::Failure;
}
Expand All @@ -28,6 +27,13 @@ Status PenaltyKeeper::update(StpInfo const& info) noexcept {
if (robotTactics.current_num() == 0 && info.getBall().value()->velocity.length() > constants::BALL_STILL_VEL) {
forceNextTactic();
}
if (info.getField().value().leftDefenseArea.rightLine().distanceToLine(info.getBall().value()->position) < 0.8 &&
info.getField().value().leftDefenseArea.rightLine().center().x < info.getBall().value()->position.x &&
info.getBall().value()->velocity.length() < constants::BALL_GOT_SHOT_LIMIT) {
// If the ball is getting close to our goal, get out of the goal to increase our chances of saving it
forceLastTactic();
} else if (robotTactics.current_num() == 2)
reset();

return Role::update(info);
}
Expand Down
26 changes: 3 additions & 23 deletions roboteam_ai/src/stp/roles/active/PenaltyTaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,13 @@

namespace rtt::ai::stp::role {

PenaltyTaker::PenaltyTaker(std::string name) : Role(std::move(name)) {
robotTactics = collections::state_machine<Tactic, Status, StpInfo>{tactic::GetBall(), tactic::DriveWithBall(), tactic::OrbitKick()};
}
PenaltyTaker::PenaltyTaker(std::string name) : Role(std::move(name)) { robotTactics = collections::state_machine<Tactic, Status, StpInfo>{tactic::GetBall(), tactic::OrbitKick()}; }

[[nodiscard]] Status PenaltyTaker::update(StpInfo const& info) noexcept {
StpInfo infoCopy = info;
if (info.getRobot().has_value()) {
static double distanceDriven = 0.0;
static Vector2 lastPosition;
auto currentPos = info.getRobot()->get()->getPos();
auto currentVel = info.getRobot()->get()->getVel();
distanceDriven += (currentPos - lastPosition).length();
lastPosition = currentPos;
if (distanceDriven >= 0.5 && (info.getPositionToMoveTo().value() - currentPos).length() > 0.4) {
// set position to move to the current position
infoCopy.setPositionToMoveTo(currentPos - Vector2(0.1, 0));
if (currentVel.x < 0.1) {
infoCopy.setDribblerOn(false);
}
}
// if we don't have ball, reset the tactic
if (!info.getRobot()->get()->hasBall()) {
distanceDriven = 0.0;
reset();
}
if (!info.getRobot()->get()->hasBall()) {
reset();
}

return Role::update(infoCopy);
}
} // namespace rtt::ai::stp::role
2 changes: 1 addition & 1 deletion roboteam_ai/src/world/Ball.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ namespace rtt::world::ball {
Ball::Ball(const proto::WorldBall& copy, const World* data) : position{copy.pos().x(), copy.pos().y()}, velocity{copy.vel().x(), copy.vel().y()}, visible{copy.visible()} {
if (!visible || position == Vector2()) {
initBallAtExpectedPosition(data);
updateBallAtRobotPosition(data);
}
updateBallAtRobotPosition(data);
updateExpectedBallEndPosition();
}

Expand Down
Loading