diff --git a/roboteam_ai/CMakeLists.txt b/roboteam_ai/CMakeLists.txt index 10fcb077b..2e7ec3337 100644 --- a/roboteam_ai/CMakeLists.txt +++ b/roboteam_ai/CMakeLists.txt @@ -141,6 +141,7 @@ target_link_libraries(roboteam_ai_computation PRIVATE roboteam_networking PRIVATE roboteam_utils PRIVATE roboteam_ai_evaluation + PRIVATE ixwebsocket ) target_compile_options(roboteam_ai_computation PRIVATE "${COMPILER_FLAGS}") diff --git a/roboteam_ai/include/roboteam_ai/stp/computations/PositionComputations.h b/roboteam_ai/include/roboteam_ai/stp/computations/PositionComputations.h index ab19a6bff..2c53b96e5 100644 --- a/roboteam_ai/include/roboteam_ai/stp/computations/PositionComputations.h +++ b/roboteam_ai/include/roboteam_ai/stp/computations/PositionComputations.h @@ -170,6 +170,17 @@ class PositionComputations { * @return A position that is outside the given shape */ static Vector2 calculatePositionOutsideOfShape(Vector2 targetPosition, const Field &field, const std::unique_ptr &avoidShape, const AvoidObjects &avoidObj); + + /** + * @brief Gets a specific grid (the type) from the field based on a grid number we input (1-9) + * @param field The field containing the grid positions + * @param gridNumber Number identifying which grid to return (1-9): + * 1: top left 2: top middle 3: top right + * 4: middle left 5: middle middle 6: middle right + * 7: bottom left 8: bottom middle 9: bottom right + * @return The requested grid if the number is valid (1-9), std::nullopt otherwise + */ + static std::optional getGridFromNumber(const Field& field, int gridNumber); }; } // namespace rtt::ai::stp #endif // RTT_POSITIONCOMPUTATIONS_H diff --git a/roboteam_ai/src/STPManager.cpp b/roboteam_ai/src/STPManager.cpp index 05abe1027..55187cfd4 100644 --- a/roboteam_ai/src/STPManager.cpp +++ b/roboteam_ai/src/STPManager.cpp @@ -245,6 +245,17 @@ STPManager::STPManager(std::shared_ptr interface interfaceGateway(std::move(interfaceGateway)), rlInterface() { instance = this; + + // Set initial grid positions + std::array defaultGrid = { + false, false, true, // top row + false, true, true, // middle row + false, false, true // bottom row + }; + rlInterface.setBinaryOccupancyGrid(defaultGrid); + + // Set initial attacker number + rlInterface.setNumAttackers(2); } } // namespace rtt diff --git a/roboteam_ai/src/rl/test.cpp b/roboteam_ai/src/rl/test.cpp index 44d8b0465..61a516ca7 100644 --- a/roboteam_ai/src/rl/test.cpp +++ b/roboteam_ai/src/rl/test.cpp @@ -1,51 +1,51 @@ -#include -#include -#include -#include -#include +// #include +// #include +// #include +// #include +// #include -int main() -{ - using namespace std::chrono_literals; +// int main() +// { +// using namespace std::chrono_literals; - std::cout << "Starting server..." << std::endl; +// std::cout << "Starting server..." << std::endl; - // initialize the zmq context with a single IO thread - zmq::context_t context{1}; +// // initialize the zmq context with a single IO thread +// zmqpp::context context; - // construct a REP (reply) socket and bind to interface - zmq::socket_t socket{context, zmq::socket_type::rep}; - socket.bind("tcp://*:5555"); +// // construct a REP (reply) socket and bind to interface +// zmqpp::socket_t socket{context, zmqpp::socket_type::rep}; +// socket.bind("tcp://*:5555"); - std::cout << "Server is running on port 5555..." << std::endl; +// std::cout << "Server is running on port 5555..." << std::endl; - // prepare some static data for responses - const std::string data{"World"}; +// // prepare some static data for responses +// const std::string data{"World"}; - for (;;) - { - zmq::message_t request; +// for (;;) +// { +// zmqpp::message_t request; - std::cout << "Waiting for messages..." << std::endl; +// std::cout << "Waiting for messages..." << std::endl; - // After (warning fixed): - if (!socket.recv(request, zmq::recv_flags::none)) { - std::cerr << "Failed to receive message" << std::endl; - continue; - } - std::cout << "Received " << request.to_string() << std::endl; - - // simulate work - std::this_thread::sleep_for(1s); - - // send the reply to the client - auto res = socket.send(zmq::buffer(data), zmq::send_flags::none); - if (!res) { - std::cerr << "Failed to send response" << std::endl; - continue; - } - std::cout << "Sent response: " << data << std::endl; - } - - return 0; -} \ No newline at end of file +// // After (warning fixed): +// if (!socket.recv(request, zmqpp::recv_flags::none)) { +// std::cerr << "Failed to receive message" << std::endl; +// continue; +// } +// std::cout << "Received " << request.to_string() << std::endl; + +// // simulate work +// std::this_thread::sleep_for(1s); + +// // send the reply to the client +// auto res = socket.send(zmqpp::buffer(data), zmqpp::send_flags::none); +// if (!res) { +// std::cerr << "Failed to send response" << std::endl; +// continue; +// } +// std::cout << "Sent response: " << data << std::endl; +// } + +// return 0; +// } \ No newline at end of file diff --git a/roboteam_ai/src/rl/zmq_PUB.py b/roboteam_ai/src/rl/zmq_PUB.py index c4e767ee0..72beae803 100644 --- a/roboteam_ai/src/rl/zmq_PUB.py +++ b/roboteam_ai/src/rl/zmq_PUB.py @@ -21,7 +21,7 @@ def create_publisher(): def publish_messages(socket, topic="updates"): # Array of integers to send - numbers = [2, 7, 9] + numbers = [3, 7, 9, 8] while True: # Convert numbers to strings diff --git a/roboteam_ai/src/rl/zmq_client.py b/roboteam_ai/src/rl/zmq_client.py deleted file mode 100644 index 3efd9e4fc..000000000 --- a/roboteam_ai/src/rl/zmq_client.py +++ /dev/null @@ -1,10 +0,0 @@ -import zmq - -context = zmq.Context() -socket = context.socket(zmq.PULL) -socket.bind("tcp://*:5555") - -print("Waiting for messages...") -while True: - message = socket.recv_string() - print(f"Received: {message}") \ No newline at end of file diff --git a/roboteam_ai/src/stp/Role.cpp b/roboteam_ai/src/stp/Role.cpp index 7dc50947a..41627b12d 100644 --- a/roboteam_ai/src/stp/Role.cpp +++ b/roboteam_ai/src/stp/Role.cpp @@ -16,7 +16,7 @@ Status Role::update(StpInfo const& info) noexcept { // Success if the tactic returned success and if all tactics are done if (status == Status::Success && robotTactics.finished()) { - RTT_INFO("ROLE SUCCESSFUL for ", info.getRobot()->get()->getId()) + // RTT_INFO("ROLE SUCCESSFUL for ", info.getRobot()->get()->getId()) return Status::Success; } diff --git a/roboteam_ai/src/stp/computations/PositionComputations.cpp b/roboteam_ai/src/stp/computations/PositionComputations.cpp index 1ab2d1628..14d859bcf 100644 --- a/roboteam_ai/src/stp/computations/PositionComputations.cpp +++ b/roboteam_ai/src/stp/computations/PositionComputations.cpp @@ -13,6 +13,8 @@ #include "stp/computations/PositionScoring.h" #include "utilities/Constants.h" #include "world/World.hpp" +#include "rl/RLInterface.hpp" +#include "STPManager.h" namespace rtt::ai::stp { int PositionComputations::amountOfWallers = 4; @@ -473,34 +475,79 @@ void PositionComputations::calculateInfoForDefendersAndWallers(std::unordered_ma void PositionComputations::calculateInfoForAttackers(std::unordered_map &stpInfos, std::array, constants::MAX_ROBOT_COUNT> &roles, const Field &field, world::World *world) noexcept { - // List of all active attackers + // Get list of attackers auto attackerNames = std::vector{}; for (size_t i = 0; i < world->getWorld()->getUs().size(); i++) { if (roles[i]->getName().find("attacker") != std::string::npos) { attackerNames.emplace_back(roles[i]->getName()); } } - if (attackerNames.size() == 0) - ; // Do nothing - else if (attackerNames.size() == 1) { - stpInfos["attacker_0"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.middleRightGrid, gen::AttackingPass, field, world)); - } else if (attackerNames.size() == 2) { - stpInfos["attacker_0"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.topRightGrid, gen::AttackingPass, field, world)); - stpInfos["attacker_1"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.bottomRightGrid, gen::AttackingPass, field, world)); - } else if (attackerNames.size() >= 3) { - stpInfos["attacker_0"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.topRightGrid, gen::SafePass, field, world)); - stpInfos["attacker_1"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.middleRightGrid, gen::AttackingPass, field, world)); - stpInfos["attacker_2"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.bottomRightGrid, gen::SafePass, field, world)); - } - if (attackerNames.size() == 4) { - stpInfos["attacker_3"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.middleMidGrid, gen::AttackingPass, field, world)); - } else if (attackerNames.size() == 5) { - stpInfos["attacker_3"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.topMidGrid, gen::AttackingPass, field, world)); - stpInfos["attacker_4"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.bottomMidGrid, gen::AttackingPass, field, world)); - } else if (attackerNames.size() >= 6) { - stpInfos["attacker_3"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.topMidGrid, gen::AttackingPass, field, world)); - stpInfos["attacker_4"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.middleMidGrid, gen::SafePass, field, world)); - stpInfos["attacker_5"].setPositionToMoveTo(PositionComputations::getPosition(std::nullopt, field.bottomMidGrid, gen::AttackingPass, field, world)); + + // If no attackers, nothing to do + if (attackerNames.empty()) return; + + // Get grid array + std::array gridArray = STPManager::getRLInterface().getBinaryOccupancyGrid(); + + // Just print first 9 values directly + RTT_INFO("First 9 grid values:"); + RTT_INFO("0: " + std::to_string(gridArray[0])); + RTT_INFO("1: " + std::to_string(gridArray[1])); + RTT_INFO("2: " + std::to_string(gridArray[2])); + RTT_INFO("3: " + std::to_string(gridArray[3])); + RTT_INFO("4: " + std::to_string(gridArray[4])); + RTT_INFO("5: " + std::to_string(gridArray[5])); + RTT_INFO("6: " + std::to_string(gridArray[6])); + RTT_INFO("7: " + std::to_string(gridArray[7])); + RTT_INFO("8: " + std::to_string(gridArray[8])); + + // Number of attackers + //RTT_INFO("Number of attackers: " + std::to_string(attackerNames.size())); + + // Assign attackers to positions where gridArray is true + size_t currentAttacker = 0; + for (int i = 0; i < 9 && currentAttacker < attackerNames.size(); i++) { + if (gridArray[i]) { + if (auto grid = PositionComputations::getGridFromNumber(field, i + 1)) { + stpInfos[attackerNames[currentAttacker]].setPositionToMoveTo( + PositionComputations::getPosition(std::nullopt, *grid, gen::SafePass, field, world)); + currentAttacker++; + } + } + } +} + +std::optional PositionComputations::getGridFromNumber(const Field& field, int gridNumber){ + if (gridNumber == 1){ + return field.topLeftGrid; + } + if (gridNumber == 2){ + return field.topMidGrid; + } + if (gridNumber == 3){ + return field.topRightGrid; + } + if (gridNumber == 4){ + return field.middleLeftGrid; + } + if (gridNumber == 5){ + return field.middleMidGrid; + } + if (gridNumber == 6){ + return field.middleRightGrid; + } + if (gridNumber == 7){ + return field.bottomLeftGrid; + } + if (gridNumber == 8){ + return field.bottomMidGrid; + } + if (gridNumber == 9){ + return field.bottomRightGrid; + } + else{ + RTT_WARNING("Invalid grid number"); + return std::nullopt; } } diff --git a/roboteam_ai/src/stp/plays/offensive/Attack.cpp b/roboteam_ai/src/stp/plays/offensive/Attack.cpp index d03f527d5..bdd967875 100644 --- a/roboteam_ai/src/stp/plays/offensive/Attack.cpp +++ b/roboteam_ai/src/stp/plays/offensive/Attack.cpp @@ -44,7 +44,7 @@ Attack::Attack() : Play() { std::make_unique("waller_1"), std::make_unique("attacker_1"), std::make_unique("defender_3"), - std::make_unique("attacker_2"), + std::make_unique("defender_4"), }; } @@ -67,9 +67,9 @@ Dealer::FlagMap Attack::decideRoleFlags() const noexcept { flagMap.insert({"defender_1", {DealerFlagPriority::MEDIUM_PRIORITY, {}}}); flagMap.insert({"defender_2", {DealerFlagPriority::MEDIUM_PRIORITY, {}}}); flagMap.insert({"defender_3", {DealerFlagPriority::MEDIUM_PRIORITY, {}}}); + flagMap.insert({"defender_4", {DealerFlagPriority::MEDIUM_PRIORITY, {}}}); flagMap.insert({"attacker_0", {DealerFlagPriority::LOW_PRIORITY, {}}}); flagMap.insert({"attacker_1", {DealerFlagPriority::LOW_PRIORITY, {}}}); - flagMap.insert({"attacker_2", {DealerFlagPriority::LOW_PRIORITY, {}}}); return flagMap; } diff --git a/roboteam_ai/src/utilities/Settings.cpp b/roboteam_ai/src/utilities/Settings.cpp index b51f7b849..ffff940eb 100644 --- a/roboteam_ai/src/utilities/Settings.cpp +++ b/roboteam_ai/src/utilities/Settings.cpp @@ -43,7 +43,7 @@ void GameSettings::setLeft(bool _left) { return; } - RTT_INFO("This secondary AI can not alter settings") + //RTT_INFO("This secondary AI can not alter settings") } net::RobotHubMode GameSettings::getRobotHubMode() { return robotHubMode; } @@ -55,7 +55,7 @@ bool GameSettings::setRobotHubMode(net::RobotHubMode mode) { return true; } - RTT_INFO("This secondary AI can not alter settings") + //RTT_INFO("This secondary AI can not alter settings") return false; } diff --git a/roboteam_ai/src/world/Robot.cpp b/roboteam_ai/src/world/Robot.cpp index 8e5c3ad2e..d3bf59372 100644 --- a/roboteam_ai/src/world/Robot.cpp +++ b/roboteam_ai/src/world/Robot.cpp @@ -63,8 +63,8 @@ void Robot::setWorkingBallSensor(bool _workingBallSensor) noexcept { Robot::work void Robot::setBallSensorSeesBall(bool _seesBall) noexcept { ballSensorSeesBall = _seesBall; } void Robot::setDribblerSeesBall(bool _seesBall) noexcept { - if (_seesBall) RTT_INFO("Robot " + std::to_string(id) + " has ball") - dribblerSeesBall = _seesBall; + // if (_seesBall) RTT_INFO("Robot " + std::to_string(id) + " has ball") + // dribblerSeesBall = _seesBall; } void Robot::setHasBall(bool _hasBall) noexcept { Robot::robotHasBall = _hasBall; }