package org.openpnp.machine.reference.vision.wizards; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.border.TitledBorder; import org.openpnp.gui.MainFrame; import org.openpnp.gui.support.AbstractConfigurationWizard; import org.openpnp.machine.reference.vision.ReferenceBottomVision; import org.openpnp.machine.reference.vision.ReferenceBottomVision.PartSettings; import org.openpnp.model.LengthUnit; import org.openpnp.model.Location; import org.openpnp.model.Part; import org.openpnp.spi.Nozzle; import org.openpnp.spi.PartAlignment; import org.openpnp.util.UiUtils; import org.openpnp.util.VisionUtils; import org.openpnp.vision.pipeline.CvPipeline; import org.openpnp.vision.pipeline.ui.CvPipelineEditor; import com.jgoodies.forms.layout.ColumnSpec; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.layout.FormSpecs; import com.jgoodies.forms.layout.RowSpec; public class ReferenceBottomVisionPartConfigurationWizard extends AbstractConfigurationWizard { private final ReferenceBottomVision bottomVision; private final Part part; private final PartSettings partSettings; private JCheckBox enabledCheckbox; private JCheckBox chckbxCenterAfterTest; public ReferenceBottomVisionPartConfigurationWizard(ReferenceBottomVision bottomVision, Part part) { this.bottomVision = bottomVision; this.part = part; this.partSettings = bottomVision.getPartSettings(part); JPanel panel = new JPanel(); panel.setBorder(new TitledBorder(null, "General", TitledBorder.LEADING, TitledBorder.TOP, null, null)); contentPanel.add(panel); panel.setLayout(new FormLayout( new ColumnSpec[] {FormSpecs.RELATED_GAP_COLSPEC, ColumnSpec.decode("right:default"), FormSpecs.RELATED_GAP_COLSPEC, FormSpecs.DEFAULT_COLSPEC, FormSpecs.RELATED_GAP_COLSPEC, FormSpecs.DEFAULT_COLSPEC,}, new RowSpec[] {FormSpecs.RELATED_GAP_ROWSPEC, FormSpecs.DEFAULT_ROWSPEC, FormSpecs.RELATED_GAP_ROWSPEC, FormSpecs.DEFAULT_ROWSPEC, FormSpecs.RELATED_GAP_ROWSPEC, FormSpecs.DEFAULT_ROWSPEC,})); JLabel lblEnabled = new JLabel("Enabled?"); panel.add(lblEnabled, "2, 2"); enabledCheckbox = new JCheckBox(""); panel.add(enabledCheckbox, "4, 2"); JButton btnTestAlighment = new JButton("Test Alignment"); btnTestAlighment.addActionListener((e) -> { UiUtils.submitUiMachineTask(() -> { testAlignment(); }); }); JLabel lblTest = new JLabel("Test"); panel.add(lblTest, "2, 4"); panel.add(btnTestAlighment, "4, 4"); chckbxCenterAfterTest = new JCheckBox("Center After Test"); chckbxCenterAfterTest.setSelected(true); panel.add(chckbxCenterAfterTest, "6, 4"); JLabel lblPipeline = new JLabel("Pipeline"); panel.add(lblPipeline, "2, 6"); JButton editPipelineButton = new JButton("Edit"); editPipelineButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { UiUtils.messageBoxOnException(() -> { editPipeline(); }); } }); panel.add(editPipelineButton, "4, 6"); JButton btnLoadDefault = new JButton("Reset to Default"); btnLoadDefault.addActionListener((e) -> { int result = JOptionPane.showConfirmDialog(getTopLevelAncestor(), "This will replace the current part pipeline with the default pipeline. Are you sure?", null, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (result == JOptionPane.YES_OPTION) { UiUtils.messageBoxOnException(() -> { partSettings.setPipeline(bottomVision.getPipeline().clone()); editPipeline(); }); } }); panel.add(btnLoadDefault, "6, 6"); } private void testAlignment() throws Exception { Nozzle nozzle = MainFrame.get().getMachineControls().getSelectedNozzle(); // perform the alignment PartAlignment.PartAlignmentOffset alignmentOffset = bottomVision.findOffsets(part, null, null, nozzle); Location offsets = alignmentOffset.getLocation(); if (!chckbxCenterAfterTest.isSelected()) { return; } // position the part over camera center Location cameraLocation = VisionUtils.getBottomVisionCamera().getLocation(); // Rotate the point 0,0 using the bottom offsets as a center point by the angle // that is // the difference between the bottom vision angle and the calculated global // placement angle. Location location = new Location(LengthUnit.Millimeters).rotateXyCenterPoint(offsets, cameraLocation.getRotation() - offsets.getRotation()); // Set the angle to the difference mentioned above, aligning the part to the // same angle as // the placement. location = location.derive(null, null, null, cameraLocation.getRotation() - offsets.getRotation()); // Add the placement final location to move our local coordinate into global // space location = location.add(cameraLocation); // Subtract the bottom vision offsets to move the part to the final location, // instead of // the nozzle. location = location.subtract(offsets); nozzle.moveTo(location); } private void editPipeline() throws Exception { CvPipeline pipeline = partSettings.getPipeline(); pipeline.setCamera(VisionUtils.getBottomVisionCamera()); CvPipelineEditor editor = new CvPipelineEditor(pipeline); JDialog dialog = new JDialog(MainFrame.get(), "Bottom Vision Pipeline"); dialog.getContentPane().setLayout(new BorderLayout()); dialog.getContentPane().add(editor); dialog.setSize(1024, 768); dialog.setVisible(true); } @Override public void createBindings() { addWrappedBinding(partSettings, "enabled", enabledCheckbox, "selected"); } }