/** * */ package jp.ac.fit.asura.nao.misc; import java.awt.Container; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.text.NumberFormat; import java.util.ArrayList; import java.util.List; import java.util.Vector; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; import javax.vecmath.Vector3f; import jp.ac.fit.asura.nao.physical.RobotTest; 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; /** * @author sey * */ public class KinematicsFrame extends JFrame { private SomaticContext sc; public KinematicsFrame() { valuePanel = new ValuePanel(); controlPanel = new ControlPanel(); textArea = new JTextArea(); try { sc = new SomaticContext(RobotTest.createRobot()); } catch (IOException e) { e.printStackTrace(); return; } Kinematics.calculateForward(sc); valuePanel.addChain(sc.get(Frames.HeadPitch)); valuePanel.addChain(sc.get(Frames.LElbowRoll)); // valuePanel.addChain(sc.get(Frames.LAnkleRoll)); // valuePanel.addChain(sc.get(Frames.RAnkleRoll)); valuePanel.addChain(sc.get(Frames.LSole)); valuePanel.addChain(sc.get(Frames.RSole)); valuePanel.addChain(sc.get(Frames.RElbowRoll)); for (Frames f : Frames.values()) valuePanel.addFrame(sc.get(f)); Container cpane = this.getContentPane(); BoxLayout layout = new BoxLayout(cpane, BoxLayout.Y_AXIS); cpane.setLayout(layout); cpane.add(valuePanel); cpane.add(controlPanel); cpane.add(textArea); setPreferredSize(layout.preferredLayoutSize(this.getContentPane())); pack(); Kinematics.SCALE = 0.125f; Kinematics.LANGLE = MathUtils.PIf / 16; } private ValuePanel valuePanel; private ControlPanel controlPanel; private JTextArea textArea; class ValuePanel extends JPanel { private JTable chainTable; private JTable frameTable; protected DefaultTableModel chainModel; protected DefaultTableModel frameModel; private List<Frames> chains; private List<Frames> frames; public ValuePanel() { chains = new ArrayList<Frames>(); chainModel = new DefaultTableModel(0, 6); String[] labels = { "Name", "x", "y", "z", "Pitch", "Yaw", "Roll" }; chainModel.setColumnIdentifiers(labels); chainTable = new JTable(chainModel); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); JScrollPane chainScroll = new JScrollPane(chainTable); add(chainScroll); frames = new ArrayList<Frames>(); frameModel = new DefaultTableModel(0, 6); String[] labels2 = { "Name", "min θ", "θ[deg]", "max θ", "x", "y", "z", "Pitch", "Yaw", "Roll" }; frameModel.setColumnIdentifiers(labels2); frameTable = new JTable(frameModel); JScrollPane scroll2 = new JScrollPane(frameTable); add(scroll2); setPreferredSize(new Dimension(640, 640)); } public void addChain(FrameState fs) { NumberFormat format = NumberFormat.getInstance(); format.setMaximumFractionDigits(2); Vector<Object> row = new Vector<Object>(); row.add(fs.getId().name()); row.add(format.format(fs.getBodyPosition().x)); row.add(format.format(fs.getBodyPosition().y)); row.add(format.format(fs.getBodyPosition().z)); Vector3f vec = new Vector3f(); MatrixUtils.rot2pyr(fs.getBodyRotation(), vec); row.add(format.format(MathUtils.toDegrees(vec.x))); row.add(format.format(MathUtils.toDegrees(vec.y))); row.add(format.format(MathUtils.toDegrees(vec.z))); chainModel.addRow(row); chains.add(fs.getId()); } public void addFrame(FrameState fs) { NumberFormat format = NumberFormat.getInstance(); format.setMaximumFractionDigits(2); Vector<Object> row = new Vector<Object>(); row.add(fs.getId().name()); row.add(format.format(fs.getFrame().getMinAngleDeg())); row.add(format.format(MathUtils.toDegrees(fs.getAngle()))); row.add(format.format(fs.getFrame().getMaxAngleDeg())); row.add(format.format(fs.getBodyPosition().x)); row.add(format.format(fs.getBodyPosition().y)); row.add(format.format(fs.getBodyPosition().z)); Vector3f vec = new Vector3f(); MatrixUtils.rot2pyr(fs.getBodyRotation(), vec); row.add(format.format(MathUtils.toDegrees(vec.x))); row.add(format.format(MathUtils.toDegrees(vec.y))); row.add(format.format(MathUtils.toDegrees(vec.z))); frameModel.addRow(row); frames.add(fs.getId()); } public void setFrame(FrameState fs) { int i = frames.indexOf(fs.getId()); NumberFormat format = NumberFormat.getInstance(); format.setMaximumFractionDigits(2); int j = 1; frameModel.setValueAt( format.format(fs.getFrame().getMinAngleDeg()), i, j++); frameModel.setValueAt(format.format(MathUtils.toDegrees(fs .getAngle())), i, j++); frameModel.setValueAt( format.format(fs.getFrame().getMaxAngleDeg()), i, j++); frameModel .setValueAt(format.format(fs.getBodyPosition().x), i, j++); frameModel .setValueAt(format.format(fs.getBodyPosition().y), i, j++); frameModel .setValueAt(format.format(fs.getBodyPosition().z), i, j++); Vector3f vec = new Vector3f(); MatrixUtils.rot2pyr(fs.getBodyRotation(), vec); frameModel.setValueAt(format.format(MathUtils.toDegrees(vec.x)), i, j++); frameModel.setValueAt(format.format(MathUtils.toDegrees(vec.y)), i, j++); frameModel.setValueAt(format.format(MathUtils.toDegrees(vec.z)), i, j++); } } class ControlPanel extends JPanel { public ControlPanel() { BoxLayout layout = new BoxLayout(this, BoxLayout.X_AXIS); setLayout(layout); JButton forwardButton = new JButton("ForwardK"); forwardButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // 現在位置を取得 for (Frames frame : valuePanel.frames) { DefaultTableModel model = valuePanel.frameModel; int i = valuePanel.frames.indexOf(frame); sc.get(frame).setAngle( MathUtils.toRadians(Float.parseFloat(model .getValueAt(i, 2).toString()))); } Kinematics.calculateForward(sc); for (Frames frame : valuePanel.frames) { valuePanel.setFrame(sc.get(frame)); } printScheme(); } }); add(forwardButton); final JTextField weightsField = new JTextField("1 1 1 1 1 1"); JButton invButton = new JButton("InverseK"); invButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // 現在位置を取得 Kinematics.calculateForward(sc); SomaticContext sc2 = new SomaticContext(sc); // 最初に取得した値を目標に逆運動学計算 for (Frames chain : valuePanel.chains) { FrameState fs = sc2.get(chain).clone(); DefaultTableModel model = valuePanel.chainModel; int i = valuePanel.chains.indexOf(chain); int j = 1; fs.getBodyPosition().x = Float.parseFloat(model .getValueAt(i, j++).toString()); fs.getBodyPosition().y = Float.parseFloat(model .getValueAt(i, j++).toString()); fs.getBodyPosition().z = Float.parseFloat(model .getValueAt(i, j++).toString()); float wx = MathUtils.toRadians(Float.parseFloat(model .getValueAt(i, j++).toString())); float wy = MathUtils.toRadians(Float.parseFloat(model .getValueAt(i, j++).toString())); float wz = MathUtils.toRadians(Float.parseFloat(model .getValueAt(i, j++).toString())); MatrixUtils.pyr2rot(new Vector3f(wx, wy, wz), fs .getBodyRotation()); try { // float err = Kinematics.calculateInverse(sc2, fs); String[] weights = weightsField.getText().split( "[ \t]+"); GfVector weightsVec = new GfVector(6); for (int k = 0; k < 6; k++) try { weightsVec.setElement(k, Float .valueOf(weights[k])); } catch (NumberFormatException e) { weightsVec.setElement(k, 0); e.printStackTrace(); } float err = Kinematics.calculateInverse(sc2, Frames.Body, fs, weightsVec); System.out.println("err:" + err); } catch (Exception e) { textArea.setText("Error! " + e.getMessage()); return; } } sc = sc2; for (Frames frame : valuePanel.frames) { valuePanel.setFrame(sc.get(frame)); } printScheme(); } }); add(invButton); add(weightsField); setMaximumSize(layout.preferredLayoutSize(this)); } private void printScheme() { StringBuilder text = new StringBuilder(); text.append("#("); NumberFormat format = NumberFormat.getInstance(); format.setMaximumFractionDigits(3); for (Frames f : Frames.values()) { if (f.isJoint() && f != Frames.HeadPitch && f != Frames.HeadYaw) { text.append(format.format(MathUtils.toDegrees(sc.get(f) .getAngle()))); text.append(" "); } } text.append(")"); textArea.setText(text.toString()); } } /** * @param args */ public static void main(String[] args) { KinematicsFrame main = new KinematicsFrame(); main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); main.pack(); main.setVisible(true); } }