/* * 作成日: 2008/06/15 */ package jp.ac.fit.asura.nao.strategy.permanent; import jp.ac.fit.asura.nao.RobotContext; import jp.ac.fit.asura.nao.SensorContext; import jp.ac.fit.asura.nao.motion.Motions; import jp.ac.fit.asura.nao.strategy.GameState; import jp.ac.fit.asura.nao.strategy.StrategyContext; import jp.ac.fit.asura.nao.strategy.Task; import jscheme.SchemeException; import org.apache.log4j.Logger; /** * @author $Author: sey $ * * @version $Id: GetUpTask.java 717 2008-12-31 18:16:20Z sey $ * */ public class GetUpTask extends Task { private Logger log = Logger.getLogger(GetUpTask.class); private boolean doStandup; private boolean active; private int fallDownCount; // falseにすれば起き上がりモーションを発動しなくなります. private boolean useGetup; public void init(RobotContext context) { active = false; useGetup = true; } public boolean canExecute(StrategyContext context) { return true; } public void after(StrategyContext context) { if (active) return; SensorContext sensor = context.getSensorContext(); float ax = sensor.getAccelX(); float ay = sensor.getAccelY(); float az = sensor.getAccelZ(); if (ay < 4.0 && (Math.abs(ax) > 8.0 || Math.abs(az) > 8.0)) { fallDownCount++; if (context.getGameState() == GameState.INITIAL) { // Initial状態では起き上がり禁止. // FIXME ペナライズ状態でも禁止にする. return; } if (fallDownCount > 5) { log.info("Fall down state detected." + " x:" + ax + " y:" + ay + " z:" + az); context.getScheduler().preempt(this); } } else { fallDownCount = 0; } } public void continueTask(StrategyContext context) { context.getScheduler().setTTL(10); SensorContext sensor = context.getSensorContext(); float ax = sensor.getAccelX(); float ay = sensor.getAccelY(); float az = sensor.getAccelZ(); if (ay > 9.0f) { // 重力が下にかかるようになったら抜ける // context.getSuperContext().getEffector().setPower(0.5f); context.makemotion(Motions.NULL); context.makemotion_head(0.0f, 0.0f); if (context.getSuperContext().getMotor().getCurrentMotion() == null) { // 起き上がりが終わったら終了 context.getScheduler().setTTL(0); } return; } // 起き上がり中は頭を動かさない context.makemotion_head(0.0f, 0.0f); // if (context.hasMotion(Motions.NAOJI_WALKER)) // context.getSuperContext().getEffector().setPower(0.125f); int motion = -1; // TODO WebotsでもCHORE_FROM_BACKでもいいかも? // 逆さになってる if (!useGetup) { log.info("We don't get up."); motion = Motions.NULL; } else if (ay < -6.0f) { log.info("Getup from ???"); if (!context.hasMotion(Motions.NAOJI_WALKER)) motion = Motions.MOTION_W_GETUP_BACK; else motion = Motions.CHORE_FROM_BACK; } else if (az > 5.0f) { log.info("Getup from face-up"); // 顔が上 if (!context.hasMotion(Motions.NAOJI_WALKER)) motion = Motions.MOTION_W_GETUP_BACK; else motion = Motions.CHORE_FROM_BACK; } else if (az < -5.0f) { log.info("Getup from face-down"); // 背中側が上 if (!context.hasMotion(Motions.NAOJI_WALKER)) motion = Motions.MOTION_W_GETUP; else motion = Motions.CHORE_FROM_FRONT; } else if (Math.abs(ax) > 5.0f) { log.info("Getup from face sideways. ax:" + ax); // 横? if (!context.hasMotion(Motions.NAOJI_WALKER)) motion = Motions.MOTION_W_GETUP; } if (motion != -1 && doStandup) context.makemotion(motion); } public void enter(StrategyContext context) { context.getScheduler().setTTL(20); active = true; try { Object v = context.getSuperContext().getGlue().getValue( "ss-getup-standup"); doStandup = (v != null && Boolean.TRUE == v); } catch (SchemeException e) { doStandup = false; } context.getSuperContext().getEffector().say("Oh my god!"); } public String getName() { return "GetUpTask"; } public void leave(StrategyContext context) { active = false; fallDownCount = 0; } }