private Point GetGoalSpeed(AHEntities.Action direction, double x, double y, Point Pg) { Point Vg; Random random = new Random(); switch (direction) { case AHEntities.Action.ATTACK_LEFT: Vg = new Point(random.Next(400, 600), -random.Next(200, 300)); break; case AHEntities.Action.ATTACK_RIGHT: Vg = new Point(random.Next(400, 600), random.Next(200, 300)); break; case AHEntities.Action.ATTACK_MIDDLE: int Vx = random.Next(500, 700); double t = (1180.0 - x) / Vx; int Vy = -Convert.ToInt32(t * y); Vg = new Point(Vx, Vy); break; default: Vg = new Point(); break; } return(Vg); }
public SimpleLinesActionPlanningStrategy(WorldModel WM) { worldModel = WM; mLogger = Logger.Logger.Instance; random = new Random(); lastPlan = null; lastAction = AHEntities.Action.LEAVE; }
private PointParams CalculateDirectedAttack(AHEntities.Action direction, Point puckP, Point puckV, double puckR, double xline, int tableW, int tableH) { PointParams finalConditions = new PointParams(); double[] crossParamsAttack = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, puckR, xline, tableW, tableH); Point XYi = GetCollissionPoint(puckV.X, puckV.Y, xline, crossParamsAttack[0], direction); // Detemine speeds at the goal. Point Pg = new Point(1180, 0); Point speedG = GetGoalSpeed(direction, xline, crossParamsAttack[0], Pg); double thetaG = -speedG.X / rp; // constrain on the angle speed at the goal double vG = speedG.Norm(); double vPS; Point speedPS; double thetaPS, thetaPSdot; if (direction != AHEntities.Action.ATTACK_MIDDLE) { // calculating angles double alpha = CalculateAlpha(speedG, AHEntities.Action.ATTACK_RIGHT); double beta = CalculateBeta(direction, xline, crossParamsAttack[0], tableH, Pg, alpha); // calculating post strike prameters vPS = -vG / e * Math.Sin(alpha) / Math.Sin(beta); speedPS = new Point(vPS * Math.Cos(beta), vPS * Math.Sin(beta)); thetaPS = Math.Atan2(speedPS.Y, speedPS.X); thetaPSdot = 2 * vG / (rp * e) * Math.Sin(alpha) / Math.Tan(beta) - 3 * vG / rp * Math.Cos(alpha); } else // direction == MIDDLE { // calculating post strike prameters vPS = 0; speedPS = new Point(); thetaPS = 0; thetaPSdot = 0; } // calculating frames rotation angle double thetaP = Math.Atan2(puckV.Y, puckV.X); double thetaC = CalculateRotationAngle(thetaPS, thetaPSdot, thetaP, puckR, vPS, puckV.Norm()); // transform puck and ps velocities to impact frame Point impactVps = TransformFrames(thetaC, speedPS, true); Point impactVp = TransformFrames(thetaC, puckV, true); // calculate control velocities Point impactVm = CalculateImpactVelocities(impactVp, impactVps, thetaP, thetaPS, rp); // transform to XY Point vM = TransformFrames(thetaC, impactVm, false); // create finalConditions. Point target = CalculateTargetPoint(XYi, new Point(AHEntities.EstimateLineCrossing.attackLine, crossParamsAttack[0])); finalConditions.AddParameters(target); finalConditions.AddParameters(vM); finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(crossParamsAttack[1]); return(finalConditions); }
private double CalculateAlpha(Point SpeedGoal, AHEntities.Action direction) { if (direction == AHEntities.Action.ATTACK_LEFT) { return(Math.Atan2(-SpeedGoal.Y, SpeedGoal.X)); } else { return(Math.Atan2(SpeedGoal.Y, SpeedGoal.X)); } }
private PointParams CalculateNaiveDirectedAttack(AHEntities.Action direction, Point puckPline, double time, double xline, double puckRadius, double malletRadius, int tableW, int tableH, double velocity) { PointParams finalConditions = new PointParams(); Point collisionPoint, targetPoint, targetVelocity; collisionPoint = GetNaiveCollisionPoint(direction, puckPline, puckRadius - 2, tableW, tableH); targetPoint = GetNaiveTargetPoint(puckPline, collisionPoint, malletRadius - 2); targetVelocity = GetNaiveTargetVelocity(collisionPoint, targetPoint, velocity); finalConditions.AddParameters(targetPoint); finalConditions.AddParameters(targetVelocity); finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(time); return(finalConditions); }
private double CalculateBeta(AHEntities.Action direction, double x, double y, double tableY, Point Pg, double alpha) { double yp, a1; if (direction == AHEntities.Action.ATTACK_LEFT) { a1 = tableY / 2 - Pg.Y; yp = tableY / 2 - y; } else // ATTACK_RIGHT { a1 = Pg.Y - tableY / 2; yp = tableY / 2 - y; } double b1 = a1 / Math.Tan(alpha); double b2 = (Pg.X - x) - b1; double beta = Math.Atan2(yp, b2); return(beta); }
private Point GetNaiveCollisionPoint(AHEntities.Action direction, Point puckPline, double puckRadius, int tableW, int tableH) { Point attackVector = new Point(); Point collisionPoint = null; Point wallCollision = null; double ratio = 0; switch (direction) { case AHEntities.Action.ATTACK_RIGHT: ratio = Math.Abs(puckPline.Y - (-tableH / 2)) / (tableH / 2); wallCollision = new Point(Math.Abs(tableW / 2 - puckPline.X) / (1 + ratio) + puckPline.X, -tableH / 2); attackVector = (wallCollision - puckPline).Normalize(); attackVector.Set(attackVector.X * puckRadius, attackVector.Y * puckRadius); collisionPoint = puckPline - attackVector; break; case AHEntities.Action.ATTACK_MIDDLE: attackVector.X = tableW / 2 - puckPline.X; attackVector.Y = -puckPline.Y; attackVector = attackVector.Normalize(); attackVector.Set(attackVector.X * puckRadius, attackVector.Y * puckRadius); collisionPoint = puckPline - attackVector; break; case AHEntities.Action.ATTACK_LEFT: ratio = Math.Abs(puckPline.Y - tableH / 2) / (tableH / 2); wallCollision = new Point(Math.Abs(tableW / 2 - puckPline.X) / (1 + ratio) + puckPline.X, tableH / 2); attackVector = (wallCollision - puckPline).Normalize(); attackVector.Set(attackVector.X * puckRadius, attackVector.Y * puckRadius); collisionPoint = puckPline - attackVector; break; default: collisionPoint = null; break; } return(collisionPoint); }
public override AHEntities.ActionDirective SelectAction(SenseEventType planReason) { Dictionary <string, double> physicalState = WM.GetPhysicalState(); double[] crossParamsGoal, crossParamsAttack, crossParamsDefense; bool isThreat = false; double time2goal = 0; double time2attack = 0; double time2defense = 0; AHEntities.ActionDirective action = new ActionDirective(); action.TimeStamp = DateTime.Now; #region stuck events handling if (planReason == SenseEventType.StuckPlayer) { action.Action = AHEntities.Action.PREPARE; action.Duration = TimeSpan.FromSeconds(1); return(action); } if (planReason == SenseEventType.StuckAgent) { action.Action = AHEntities.Action.STUCK_ATTACK; action.Duration = TimeSpan.FromSeconds(0.3); return(action); } #endregion stuck events handling #region Crossing calculations Point puckP = new Point(physicalState["PuckX"], physicalState["PuckY"]); Point puckV = new Point(physicalState["PuckVx"], physicalState["PuckVy"]); try { // (y, T) crossParamsGoal = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, 32, AHEntities.EstimateLineCrossing.goalLine, (int)global["Tablewidth"], (int)global["Tableheight"]); crossParamsDefense = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, 32, AHEntities.EstimateLineCrossing.defenseAttackLine, (int)global["Tablewidth"], (int)global["Tableheight"]); crossParamsAttack = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, 32, AHEntities.EstimateLineCrossing.attackLine, (int)global["Tablewidth"], (int)global["Tableheight"]); } catch (Exception) { action.Action = AHEntities.Action.LEAVE; action.Duration = TimeSpan.FromSeconds(0); return(action); } #endregion Crossing calculations // not directed to the goal if (crossParamsGoal == null) { action.Action = AHEntities.Action.PREPARE; action.Duration = TimeSpan.FromSeconds(1); return(action); } // is directed to the goal if ((crossParamsGoal[0] < 220) && (crossParamsGoal[0] > -220)) { isThreat = true; } // time to reach the goal and attack lines time2goal = crossParamsGoal[1]; time2defense = crossParamsDefense[1]; time2attack = crossParamsAttack[1]; #region emergency Block/Leave // puck is too fast, immidiate BLOCK or LEAVE if (time2goal < 0.2) { if (isThreat) { action.Action = AHEntities.Action.BLOCK; action.Duration = TimeSpan.FromSeconds(time2goal); return(action); } else { action.Action = AHEntities.Action.LEAVE; action.Duration = TimeSpan.FromSeconds(0); return(action); } } #endregion emergency Block/Leave if (time2attack < 0.5) // defense attack (no time to calcualte elaborated attack { action.Action = AHEntities.Action.DEFENSE_ATTACK; action.Duration = TimeSpan.FromSeconds(time2defense); return(action); } else // Directed attack { int height = (int)global["Tableheight"] / 2; double rim = height * 0.95; action.Duration = TimeSpan.FromSeconds(time2attack); // puck is crossing on the rim of the table if (Math.Abs(crossParamsAttack[0]) > rim) { action.Action = AHEntities.Action.DEFENSE_ATTACK; action.Duration = TimeSpan.FromSeconds(time2defense); return(action); } else // crossing on the inside of the table { Random random = new Random(); AHEntities.Action[] attacks; double outerTable = height * 0.65; if (Math.Abs(crossParamsAttack[0]) > outerTable) // outer part { if (crossParamsAttack[2] > height - outerTable) // Agent's left part { attacks = new AHEntities.Action[] { AHEntities.Action.ATTACK_RIGHT, AHEntities.Action.ATTACK_MIDDLE }; } else // Agent's right part { attacks = new AHEntities.Action[] { AHEntities.Action.ATTACK_LEFT, AHEntities.Action.ATTACK_MIDDLE }; } } else // inner part { attacks = new AHEntities.Action[] { AHEntities.Action.ATTACK_LEFT, AHEntities.Action.ATTACK_MIDDLE, AHEntities.Action.ATTACK_RIGHT }; } action.Action = attacks[random.Next(attacks.Length)]; return(action); } } }
public override PointParams ActionPlanning(AHEntities.ActionDirective action, bool isNewPlaning) { AHEntities.Action A = action.Action; PointParams finalConditions = null; Random random = new Random(); Point puckP, puckV; physicalState = worldModel.GetPhysicalState(); puckP = new Point(physicalState["PuckX"], physicalState["PuckY"]); puckV = new Point(physicalState["PuckVx"], physicalState["PuckVy"]); global = worldModel.GetSize(); Point crossing; double[] crossParams; switch (A) { case AHEntities.Action.BLOCK: #region BLOCK crossParams = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, rp, AHEntities.EstimateLineCrossing.blockLine, global[0], global[1]); crossing = new Point(AHEntities.EstimateLineCrossing.blockLine, crossParams[0]); Point defendPoint = AHEntities.EstimateLineCrossing.CalculateActionPoint(crossing, new Point(crossParams[2], crossParams[3]), rp, rm); mLogger.AddLogMessage("LowLevel Planning BLOCK: estimated collission: mallet: " + defendPoint.ToString() + ", puck: " + crossing.ToString()); finalConditions = new PointParams(); finalConditions.AddParameters(defendPoint); finalConditions.AddParameters(new Point(0, 0)); finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(crossParams[1]); break; #endregion BLOCK case AHEntities.Action.LEAVE: #region LEAVE finalConditions = null; break; #endregion LEAVE case AHEntities.Action.ATTACK_RIGHT: #region ATTACK_RIGHT //finalConditions = CalculateDirectedAttack(AHEntities.Action.ATTACK_RIGHT, puckP, puckV, physicalState["PuckR"], // AHEntities.EstimateLineCrossing.attackLine, global[0], global[1]); //break; #endregion ATTACK_RIGHT case AHEntities.Action.ATTACK_LEFT: #region ATTACK_LEFT //finalConditions = CalculateDirectedAttack(AHEntities.Action.ATTACK_LEFT, puckP, puckV, physicalState["PuckR"], // AHEntities.EstimateLineCrossing.attackLine, global[0], global[1]); //break; #endregion ATTACK_LEFT case AHEntities.Action.ATTACK_MIDDLE: #region ATTACK_MIDDLE crossParams = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, rp, AHEntities.EstimateLineCrossing.attackLine, global[0], global[1]); mLogger.AddLogMessage("LowLevel: Puck Estimated at: (" + AHEntities.EstimateLineCrossing.attackLine.ToString() + "," + crossParams[0].ToString() + ") in " + crossParams[1].ToString() + " seconds"); Point puckPline = new Point(AHEntities.EstimateLineCrossing.attackLine, crossParams[0]); double velocity = 1000; finalConditions = CalculateNaiveDirectedAttack(A, puckPline, crossParams[1], AHEntities.EstimateLineCrossing.attackLine, rp, rm, global[0], global[1], velocity); break; #endregion ATTACK_MIDDLE case AHEntities.Action.DEFENSE_ATTACK: #region DEFENSE_ATTACK if (Math.Abs(puckV.X) < 0.01) { break; } crossParams = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, rp, AHEntities.EstimateLineCrossing.defenseAttackLine, global[0], global[1]); if (crossParams == null) { finalConditions = null; break; } crossing = new Point(AHEntities.EstimateLineCrossing.defenseAttackLine, crossParams[0]); Point attackPoint = AHEntities.EstimateLineCrossing.CalculateActionPoint(new Point(AHEntities.EstimateLineCrossing.defenseAttackLine, crossParams[0]), new Point(crossParams[2], crossParams[3]), rp, rm); mLogger.AddLogMessage("LowLevel Planning DEFENSE_ATTACK: estimated collission: mallet: " + attackPoint.ToString() + ", puck estimated at: " + crossing.ToString()); finalConditions = new PointParams(); finalConditions.AddParameters(attackPoint); double yvel = (attackPoint.Y > 0) ? (yvel = -200) : (yvel = 200); finalConditions.AddParameters(new Point(500, yvel)); finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(crossParams[1]); break; #endregion DEFENSE_ATTACK case AHEntities.Action.PREPARE: #region PREPARE finalConditions = new PointParams(); finalConditions.AddParameters(new Point(-1000, 0)); finalConditions.AddParameters(new Point(0, 0)); finalConditions.T = action.TimeStamp + TimeSpan.FromSeconds(0.5); break; #endregion PREPARE case AHEntities.Action.STUCK_ATTACK: #region STUCK_ATTACK double stuckTime; stuckTime = (action.Duration - (DateTime.Now - action.TimeStamp)).TotalSeconds; Point stuckAttackPoint = AHEntities.EstimateLineCrossing.EstimateStuck(puckP, puckV, rp, global[0], global[1], stuckTime, rm); if (stuckAttackPoint == null) { finalConditions = null; break; } mLogger.AddLogMessage("LowLevel Planning STUCK_ATTACK: estimated collission: mallet: " + stuckAttackPoint.ToString()); finalConditions = new PointParams(); finalConditions.AddParameters(stuckAttackPoint); finalConditions.AddParameters(new Point(0, 0)); finalConditions.T = action.TimeStamp + TimeSpan.FromSeconds(stuckTime); break; #endregion STUCK_ATTACK default: #region default finalConditions = null; break; #endregion default } //saving current planning (action and parameters) lastAction = A; if (finalConditions != null) { if (lastPlan == null) { lastPlan = new PointParams(); } lastPlan.Clear(); lastPlan.AddParameters(finalConditions.GetParamsByIndex(1)); lastPlan.AddParameters(finalConditions.GetParamsByIndex(2)); lastPlan.T = finalConditions.T; } else { lastPlan = null; } return(finalConditions); }
private Point GetCollissionPoint(double PuckVx, double PuckVy, double xLine, double y, AHEntities.Action attackDirection) { Point XYi = new Point(); Random random = new Random(); int a, b; switch (attackDirection) { case AHEntities.Action.ATTACK_LEFT: if (PuckVy > 0) { a = random.Next(5); b = (int)Math.Round(Math.Sqrt(rp * rp - a * a)); XYi.Y = y + a; XYi.X = xLine - b; } else { a = random.Next(10); b = (int)Math.Round(Math.Sqrt(rp * rp - a * a)); XYi.Y = y - a; XYi.X = xLine - b; } break; case AHEntities.Action.ATTACK_MIDDLE: if (PuckVy > 0) { a = random.Next(3); b = (int)Math.Round(Math.Sqrt(rp * rp - a * a)); XYi.Y = y + a; XYi.X = xLine - b; } else { a = random.Next(3); b = (int)Math.Round(Math.Sqrt(rp * rp - a * a)); XYi.Y = y - a; XYi.X = xLine - b; } break; case AHEntities.Action.ATTACK_RIGHT: if (PuckVy > 0) { a = random.Next(10); b = (int)Math.Round(Math.Sqrt(rp * rp - a * a)); XYi.Y = y + a; XYi.X = xLine - b; } else { a = random.Next(5); b = (int)Math.Round(Math.Sqrt(rp * rp - a * a)); XYi.Y = y - a; XYi.X = xLine - b; } break; } return(XYi); }