package jp.ac.fit.asura.nao.motion.motions; import java.util.List; import javax.vecmath.Vector3f; import jp.ac.fit.asura.nao.Joint; import jp.ac.fit.asura.nao.misc.Kinematics; import jp.ac.fit.asura.nao.misc.MatrixUtils; import jp.ac.fit.asura.nao.misc.SingularPostureException; import jp.ac.fit.asura.nao.motion.Motion; import jp.ac.fit.asura.nao.motion.MotionParam; import jp.ac.fit.asura.nao.physical.Robot; import jp.ac.fit.asura.nao.physical.Robot.Frames; import jp.ac.fit.asura.nao.sensation.FrameState; import jp.ac.fit.asura.nao.sensation.SomaticContext; import jp.ac.fit.asura.vecmathx.GfVector; import org.apache.log4j.Logger; /** * * @author sey * */ public class CartesianMotion extends Motion { private static final Logger log = Logger.getLogger(CartesianMotion.class); public static class DataFrame { public int time; public List<ChainFrame> chains; } public static class ChainFrame { public Frames chainId; public Vector3f position; public Vector3f postureYpr; public Vector3f positionWeight; public Vector3f postureWeight; } float[] frames; int[] times; int sequence; int sequenceStep; boolean isStarted; long startTime; int totalTimes; public CartesianMotion(Robot robot, List<DataFrame> args) throws SingularPostureException { int joints = Joint.values().length - 2; frames = new float[args.size() * joints]; int[] timesJointSpace = new int[args.size()]; SomaticContext sc = new SomaticContext(robot); for (int i = 0; i < args.size(); i++) { DataFrame d = args.get(i); log.trace("Frame " + i); // 前のフレームの値を引き継ぐ if (i != 0) System.arraycopy(frames, (i - 1) * joints, frames, i * joints, joints); // フレーム中のチェインの計算をする for (ChainFrame c : d.chains) { log.trace("Frame " + i + " Chain " + c.chainId + " pos:" + c.position + " ypr:" + c.postureYpr); // 逆運動学計算を実施 FrameState t = new FrameState(robot.get(c.chainId)); t.getBodyPosition().set(c.position); MatrixUtils.pyr2rot(c.postureYpr, t.getBodyRotation()); GfVector w = new GfVector(new float[] { c.positionWeight.x, c.positionWeight.y, c.positionWeight.z, c.postureWeight.x, c.postureWeight.y, c.postureWeight.z, }); Kinematics.calculateInverse(sc, Frames.Body, t, w); // 計算結果をモーションデータにセット Frames[] route = robot.findRoute(Frames.Body, c.chainId); for (Frames f : route) { if (f.isJoint()) { int idx = i * joints + f.toJoint().ordinal() - 2; frames[idx] = sc.get(f).getAngle(); } } } timesJointSpace[i] = d.time; } int time = 250; this.times = new int[timesJointSpace.length]; for (int i = 0; i < timesJointSpace.length; i++) { time += timesJointSpace[i]; this.times[i] = time; } totalTimes = time + 1000; log.debug("new CartesianMotion with matrix:" + frames.length + " totalTimes:" + totalTimes); log.trace("CartesianMotion created."); } @Override public void start(MotionParam param) throws IllegalArgumentException { isStarted = false; startTime = context.getTime(); log.debug("start" + startTime); } @Override public void stop() { log.debug("stop" + System.currentTimeMillis()); } @Override public void step() { if (isStarted) return; context.getRobotContext().getEffector().setBodyJoints(frames, times); isStarted = true; } @Override public boolean hasNextStep() { long current = context.getTime(); return current - startTime < totalTimes; } }