From 99cf1db440ff1865c01b34b790aae29ca7ddc482 Mon Sep 17 00:00:00 2001 From: Alexsandro Francisco Date: Fri, 8 Mar 2019 04:10:57 -0300 Subject: [PATCH] Add midfielder --- lib/Coach.js | 96 +++++++++++++++++------- players/Attacker.js | 2 +- players/experimental/AttackerFoward.js | 2 +- players/experimental/MidFieldAttacker.js | 57 ++++++++++++++ players/experimental/MidFieldDefender.js | 71 ++++++++++++++++++ server.js | 8 +- 6 files changed, 203 insertions(+), 33 deletions(-) create mode 100644 players/experimental/MidFieldAttacker.js create mode 100644 players/experimental/MidFieldDefender.js diff --git a/lib/Coach.js b/lib/Coach.js index e8e44ca..90701ff 100644 --- a/lib/Coach.js +++ b/lib/Coach.js @@ -6,15 +6,21 @@ const GoalKeeperPush = require('../players/experimental/GoalkeeperPush') const FieldConstraints = require('../entities/FieldConstraints') const Attacker = require('../players/experimental/Attacker') const AttackerFoward = require('../players/experimental/AttackerFoward') -const Vector = require('../lib/Vector') const AttackerSides = require('../players/experimental/AttackerSides') const AttackerAvoidSides = require('../players/experimental/AttackerAvoidSides') +const midfielderAttacker = require('../players/experimental/MidFieldAttacker') +const midfielderDefender = require('../players/experimental/MidFieldDefender') +const RulesPlay = require('../players/experimental/RulePlays') + +const Vector = require('../lib/Vector') module.exports = class Coach { constructor(dependencies) { this.match = dependencies.match this.robotsProperties = this.match.robotsProperties + this.currentOrder = {} + this.init() } @@ -26,18 +32,31 @@ module.exports = class Coach { this.attackerId = null this.midfieldId = null + this.attackerRobot = null + + this.Rules = new RulesPlay(0, this.match, null), + this.goalkeeper = { main: new GoalKeeper(0, this.match, null), push: new GoalKeeperPush(0, this.match, null), side: new GoalKeeperSides(0, this.match, null) } - this.attacker = { - main: new Attacker(0, this.match, null), - foward: new AttackerFoward(0, this.match, null), - sides: new AttackerSides(0, this.match, null), - avoidSides: new AttackerAvoidSides(0, this.match, null) - } + this.attacker = { + main: new Attacker(0, this.match, null), + foward: new AttackerFoward(0, this.match, null), + sides: new AttackerSides(0, this.match, null), + avoidSides: new AttackerAvoidSides(0, this.match, null) + } + + this.midfielder = { + inAttack: new midfielderAttacker(0, this.match, null), + inDefense: new midfielderDefender(0, this.match, null), + sides: new AttackerSides(0, this.match, null), + avoidSides: new AttackerAvoidSides(0, this.match, null) + } + + } @@ -65,13 +84,15 @@ module.exports = class Coach { // id let distFromBallCandidateGK = 100000 - + if (!this.goalkeeperId) { _.values(robots).map(robot => { - const distToGoalCenter = Vector.distBetween({x: -700, y: 0}, robot.robots.self.position) - if (distFromBallCandidateGK > distToGoalCenter) { - this.goalkeeperId = robot.radioId - distFromBallCandidateGK = distToGoalCenter + if(robot.robots.self.position) { + const distToGoalCenter = Vector.distBetween({x: -700, y: 0}, robot.robots.self.position) + if (distFromBallCandidateGK > distToGoalCenter) { + this.goalkeeperId = robot.radioId + distFromBallCandidateGK = distToGoalCenter + } } }) } @@ -82,13 +103,15 @@ module.exports = class Coach { _.values(robots).map(robot => { if (robot.radioId != this.goalkeeperId) { - if (!ball){ - this.attackerId = robot.radioId - }else { - const distToBall = Vector.distBetween(ball, robot.robots.self.position) - if (distToBallCandidateATK > distToBall) { + if(robot.robots.self.position) { + if (!ball){ this.attackerId = robot.radioId - distToBallCandidateATK = distToBall + } else { + const distToBall = Vector.distBetween(ball, robot.robots.self.position) + if (distToBallCandidateATK > distToBall) { + this.attackerId = robot.radioId + distToBallCandidateATK = distToBall + } } } } @@ -96,49 +119,70 @@ module.exports = class Coach { _.values(robots).map(robot => { if(robot.radioId == this.goalkeeperId) { - if (!ball) robot.runningPlay = this.goalkeeper.main + if (!ball) { + robot.runningPlay = this.goalkeeper.main + this.goalkeeper.main.setRobot(robot) + } if (this.insideFieldConstraint(FieldConstraints.SMALL_AREA_CENTER, ball)) { robot.runningPlay = this.goalkeeper.push this.goalkeeper.push.setRobot(robot) + } else if (this.insideFieldConstraint(FieldConstraints.SMALL_AREA_LEFT, ball) || this.insideFieldConstraint(FieldConstraints.SMALL_AREA_RIGHT, ball)) { robot.runningPlay = this.goalkeeper.side this.goalkeeper.side.setRobot(robot) + } else { robot.runningPlay = this.goalkeeper.main this.goalkeeper.main.setRobot(robot) } } - if(robot.radioId == this.attackerId) { + else if(robot.radioId == this.attackerId) { + this.attackerRobot = robot let robotPos = robot.robots.self.position let ball = {x: this.match.dataManager.ball.x, y: this.match.dataManager.ball.y} let ballToCenterGoal = Vector.sub({x: 700, y: 0}, ball) let robotToBall = Vector.sub(ball, robotPos) let angle = Vector.toDegrees(Vector.angleBetween(ballToCenterGoal, robotToBall)) if (Math.abs(ball.y) > 500 && Math.abs(robotPos.y) > 500) { - if (robotPos.x < ball.x) { robot.runningPlay = this.attacker.sides this.attacker.sides.setRobot(robot) - console.log('laterais') + } else { robot.runningPlay = this.attacker.avoidSides this.attacker.avoidSides.setRobot(robot) - console.log('laterais atras') + } - } else if(Math.abs(angle) < 10) { + } else if(Math.abs(angle) < 25) { robot.runningPlay = this.attacker.foward this.attacker.foward.setRobot(robot) - console.log('atacando') } else { robot.runningPlay = this.attacker.main this.attacker.main.setRobot(robot) - console.log('padrão') } } else { // MEIO CAMPISTA + let robotPos = robot.robots.self.position + if (ball.x > 0 || robotPos == null) { + robot.runningPlay = this.midfielder.inAttack + this.midfielder.inAttack.setRobot(robot) + } else { + if (Math.abs(ball.y) > 500 && Math.abs(robotPos.y) > 500) { + if (robotPos.x < ball.x) { + robot.runningPlay = this.midfielder.sides + this.midfielder.sides.setRobot(robot) + } else { + robot.runningPlay = this.midfielder.avoidSides + this.midfielder.avoidSides.setRobot(robot) + } + }else{ + robot.runningPlay = this.midfielder.inDefense + this.midfielder.inDefense.setRobot(robot) + } + } } }) diff --git a/players/Attacker.js b/players/Attacker.js index f45188a..b971cc3 100644 --- a/players/Attacker.js +++ b/players/Attacker.js @@ -227,7 +227,7 @@ module.exports = class Attacker extends IntentionPlayer { } - loop(){ + loop () { let toBall = Vector.sub({x: this.ball.x, y: this.ball.y}, this.position) let toBallDist = Vector.size(toBall) let toBallAngle = Vector.toDegrees(Vector.angle(toBall)) diff --git a/players/experimental/AttackerFoward.js b/players/experimental/AttackerFoward.js index 2b5ae16..916827a 100644 --- a/players/experimental/AttackerFoward.js +++ b/players/experimental/AttackerFoward.js @@ -30,7 +30,7 @@ module.exports = class AttackerForward extends RulePlays { let ballSpeedBasedMultiplier = () => { let ballSpeed = Vector.size(this.match.dataManager.ball.speed) - let multiplier = Math.max(Math.min(ballSpeed + 35, 80), 60) + let multiplier = Math.max(Math.min(ballSpeed + 25, 80), 25) return multiplier } diff --git a/players/experimental/MidFieldAttacker.js b/players/experimental/MidFieldAttacker.js new file mode 100644 index 0000000..5226e44 --- /dev/null +++ b/players/experimental/MidFieldAttacker.js @@ -0,0 +1,57 @@ +const IntentionPlayer = require('../IntentionPlayer') +const TensorMath = require('../../lib/TensorMath') +const Intention = require('../../Intention') +const LineIntention = require('../../Intention/LineIntention') +const PointIntention = require('../../Intention/PointIntention') +const LookAtIntention = require('../../Intention/LookAtIntention') +const Vector = require('../../lib/Vector') +const RulePlays = require('./RulePlays') + +const BASE_SPEED = 50 + +module.exports = class Midfielder extends RulePlays { + setup(){ + super.setup() + let ball = () => { + let ball = {x: this.match.dataManager.ball.x, y: this.match.dataManager.ball.y} + return ball + } + + let followAttackerShadow = () => { + let pos = this.match.gameManager.coach.attackerRobot.robots.self.position + /* + A projeção não é usada nos casos onde: + - Não existe vetor projeção (ocorre no primeiro frame de execução) + - Velocidade da bola inferior a 1.2 cm/s (praticamente parada) + - Quando a bola ira bater longe do gol (acima de 30 cm em relação ao centro do gol) + */ + return {x: -250, y: -pos.y/2} + } + + this.addIntetion(new LineIntention('KeepGoalLine', { + target: {x: -250, y: 0}, + theta: Vector.direction("up"), + lineSize: 1700, + lineDist: 260, + decay: TensorMath.new.finish, + multiplier: BASE_SPEED + })) + + this.addIntetion(new LineIntention('followAttackerShadow', { + target: followAttackerShadow, + theta: Vector.direction("left"), + lineSize: 1700, + lineDist: 250, + decay: TensorMath.new.finish, + multiplier: BASE_SPEED + })) + + this.addIntetion(new LookAtIntention('LookAtBall', { + target: ball, + decay: TensorMath.new.constant(1).finish, + multiplier: 100 + })) + } + loop(){ + } +} diff --git a/players/experimental/MidFieldDefender.js b/players/experimental/MidFieldDefender.js new file mode 100644 index 0000000..741d0a3 --- /dev/null +++ b/players/experimental/MidFieldDefender.js @@ -0,0 +1,71 @@ +const IntentionPlayer = require('../IntentionPlayer') +const TensorMath = require('../../lib/TensorMath') +const Intention = require('../../Intention') +const LineIntention = require('../../Intention/LineIntention') +const PointIntention = require('../../Intention/PointIntention') +const LookAtIntention = require('../../Intention/LookAtIntention') +const OrbitalIntention = require('../../Intention/OrbitalIntention') +const Vector = require('../../lib/Vector') +const RulePlays = require('./RulePlays') + +const BASE_SPEED = 65 + +module.exports = class MidfieldDefender extends RulePlays { + setup () { + super.setup() + let ballAntecipation = () => { + let ball = {x: this.match.dataManager.ball.x, y: this.match.dataManager.ball.y} + let ballToCenterGoal = Vector.sub({x: 700, y: 0}, ball) + let ballToCenterGoalNorm = Vector.norm(ballToCenterGoal) + let antecipation = { + x: ballToCenterGoalNorm.x * 130, + y: ballToCenterGoalNorm.y * 130 + } + antecipation = {x: ball.x - antecipation.x, y: ball.y - antecipation.y} + return antecipation + } + + let ball = () => { + let ball = {x: this.match.dataManager.ball.x, y: this.match.dataManager.ball.y} + return ball + } + + let ballSpeedBasedMultiplier = () => { + let ballSpeed = Vector.size(this.match.dataManager.ball.speed) + let multiplier = Math.max(Math.min(ballSpeed + 30, 80), 55) + return multiplier + } + + this.addIntetion(new PointIntention('goBall', { + target: ballAntecipation, + radius: 50, + decay: TensorMath.new.finish, + multiplier: ballSpeedBasedMultiplier, + })) + + this.addIntetion(new LineIntention('avoidBallOwnGoal', { + target: ball, + theta: Vector.direction("down"), + lineSize: 50, // Largura do segmento de reta + lineDist: 180, // Tamanho da repelência + lineDistMax: 200, // Tamanho da repelência + lineDistSingleSide: true, + decay: TensorMath.new.mult(-1).finish, + multiplier: 55, + })) + + this.addIntetion(new LineIntention('avoidBallOwnGoallateral', { + target: ball, + theta: Vector.direction("right"), + lineSize: 400, // Largura do segmento de reta + lineDist: 120, // Tamanho da repelência + lineDistMax: 130, // Tamanho da repelência + lineSizeSingleSide: true, + decay: TensorMath.new.constant(1).mult(-1).finish, + multiplier: 50, + })) + + } + loop(){ + } +} diff --git a/server.js b/server.js index 3e9f413..42f4c5e 100644 --- a/server.js +++ b/server.js @@ -34,9 +34,6 @@ async function startup(){ let MatchClass = Match let CoachClass = require('./lib/Coach') - let vision = null - let driver = null - switch (run_mode) { case 1: visionImpl = 'ssl-vision' @@ -67,8 +64,9 @@ async function startup(){ driver: {impl: driverImpl, params: config[driverImpl]}, coach: CoachClass, robotsProperties: { - robot_1: {vision_id: 9, radio_id:1}, - robot_2: {vision_id: 1, radio_id:2} + robot_1: {vision_id: 9, radio_id: 1}, + robot_2: {vision_id: 1, radio_id: 2}, + robot_3: {vision_id: 3, radio_id: 3} }, })