/* * 作成日: 2008/06/13 */ package jp.ac.fit.asura.nao.strategy.tactics; import static jp.ac.fit.asura.nao.motion.Motions.MOTION_LEFT_YY_TURN; import static jp.ac.fit.asura.nao.motion.Motions.MOTION_RIGHT_YY_TURN; import static jp.ac.fit.asura.nao.motion.Motions.BASIC_WALK; import static jp.ac.fit.asura.nao.motion.Motions.NAOJI_WALKER; import static jp.ac.fit.asura.nao.motion.Motions.NULL; import jp.ac.fit.asura.nao.RobotContext; import jp.ac.fit.asura.nao.localization.WorldObject; import jp.ac.fit.asura.nao.misc.MathUtils; import jp.ac.fit.asura.nao.strategy.StrategyContext; import jp.ac.fit.asura.nao.strategy.Task; import jp.ac.fit.asura.nao.strategy.permanent.BallTrackingTask; import jp.ac.fit.asura.nao.strategy.permanent.BallTrackingTask.Mode; import org.apache.log4j.Logger; /** * @author $Author: sey $ * * @version $Id: FindBallTask.java 709 2008-11-23 07:40:31Z sey $ * */ public class FindBallTask extends Task { private Logger log = Logger.getLogger(this.getClass()); private int step; private int lastTurnSide = 0; private enum FindState { PRE, TURN, FINDBALL } private FindState state; private BallTrackingTask tracking; private boolean balldataUsable; public String getName() { return "FindBallTask"; } public void init(RobotContext context) { tracking = (BallTrackingTask) context.getStrategy().getTaskManager() .find("BallTracking"); assert tracking != null; } public void enter(StrategyContext context) { context.getScheduler().setTTL(500); step = 0; state = FindState.PRE; log.debug("state = " + state); } public void continueTask(StrategyContext context) { if (context.getBall().getConfidence() > 0) { tracking.setMode(Mode.Cont); context.makemotion(NULL); context.getScheduler().abort(); return; } tracking.setMode(Mode.Cont); if (step == 180) { state = FindState.TURN; context.makemotion(NULL); step++; log.debug("state = " + state); return; } else if (step == 580) { state = FindState.FINDBALL; context.makemotion(NULL); step++; log.debug("state = " + state); return; } if (context.getBall().getDifftime() < 60000) { balldataUsable = true; } else { balldataUsable = false; } // state に応じた動作をする switch (state) { case PRE: tracking.setMode(Mode.Cont); if (context.getBall().getDistance() > 1500 && Math.abs(context.getBall().getHeading()) < 30.0f && balldataUsable) { /* * 最後に見た WorldObject: ball の距離が遠くて、 前方なら前進してみる */ int dist = (int) MathUtils.clipAbs(context.getBall() .getDistance(), 750); if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, dist * 0.5f / 1e3f, 0, 0); else context.makemotion(BASIC_WALK); } else { context.makemotion(NULL); } break; case TURN: if (balldataUsable) { /* * 最後に確認したballの位置が参考になりそうなら,その方向に回る */ if (context.getFrame() % 5 == 0) log.trace("from lastBallInfo."); if (context.getBall().getHeading() > 0) { if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, 0, 0, MathUtils .toRadians(40)); else context.makemotion(MOTION_LEFT_YY_TURN); } else { if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, 0, 0, MathUtils .toRadians(-40)); else context.makemotion(MOTION_RIGHT_YY_TURN); } } else if (lastTurnSide > 0) { if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, 0, 0, MathUtils .toRadians(40)); else context.makemotion(MOTION_LEFT_YY_TURN); } else { if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, 0, 0, MathUtils .toRadians(-40)); else context.makemotion(MOTION_RIGHT_YY_TURN); } break; case FINDBALL: // どうしても見つからないとき指定した場所に行く WorldObject self = context.getSelf(); int selfX = self.getX(); int selfY = self.getY(); int tx = 0; // 目標の位置 int ty = 0; // float deg = MathUtils.normalizeAngle180(MathUtils .toDegrees(MathUtils.atan2(tx - self.getX(), ty - self.getY())) - self.getYaw()); float dist = MathUtils.distance(tx, ty, self.getX(), self.getY()); if (Math.abs(selfX - tx) > 20 || Math.abs(selfY - ty) > 20) { // log.info(deg); deg = MathUtils.clipAbs(deg, 60); if (deg < -30) { if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, 0, 0, 0.85f * MathUtils.toRadians(deg)); else context.makemotion(MOTION_RIGHT_YY_TURN); lastTurnSide = -1; } else if (deg > 30) { if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, 0, 0, 0.85f * MathUtils.toRadians(deg)); else context.makemotion(MOTION_LEFT_YY_TURN); lastTurnSide = 1; } else { dist = MathUtils.clipAbs(dist, 750); if (context.hasMotion(NAOJI_WALKER)) context.makemotion(NAOJI_WALKER, dist * 0.5f / 1e3f, 0, 0); else context.makemotion(BASIC_WALK); } } else { step = 0; } break; default: assert false; } step++; } }