Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live recordings #229

Merged
merged 5 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.marginallyclever</groupId>
<artifactId>RobotOverlord</artifactId>
<version>2.99.0</version>
<version>2.100.0</version>
<name>Robot Overlord</name>
<description>A friendly 3D user interface for controlling robots.</description>
<url>https://www.marginallyclever.com/</url>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.marginallyclever.convenience.swing;

import javax.swing.text.NumberFormatter;
import java.text.NumberFormat;

public class NumberFormatHelper {
static public NumberFormatter getNumberFormatter() {
NumberFormat format = NumberFormat.getNumberInstance();
NumberFormatter formatter = new NumberFormatter(format);
formatter.setValueClass(Double.class);
formatter.setAllowsInvalid(true);
formatter.setCommitsOnValidEdit(true);
return formatter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@ public void actionPerformed(ActionEvent e) {
String message = getLineAtCaret();
if(!message.trim().isEmpty()) {
arm.sendGCode(message);
// move down one line in the file.
int caretPosition = text.getCaretPosition();
Element root = text.getDocument().getDefaultRootElement();
int lineNumber = root.getElementIndex(caretPosition);
Element lineElement = root.getElement(lineNumber);
int end = lineElement.getEndOffset();
try {
text.setCaretPosition(Math.min(end, text.getDocument().getLength()));
} catch (Exception exception) {
logger.error("Failed to move caret.",exception);
}
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/com/marginallyclever/ro3/node/nodes/Camera.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.marginallyclever.ro3.node.nodes;

import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.Registry;
import com.marginallyclever.ro3.apps.render.Viewport;

Expand Down Expand Up @@ -95,11 +96,7 @@ public void getComponents(List<JPanel> list) {
}

private void addLookAtComponents(JPanel pane) {
NumberFormat format = NumberFormat.getNumberInstance();
NumberFormatter formatter = new NumberFormatter(format);
formatter.setValueClass(Double.class);
formatter.setAllowsInvalid(true);
formatter.setCommitsOnValidEdit(true);
var formatter = NumberFormatHelper.getNumberFormatter();

JFormattedTextField tx = new JFormattedTextField(formatter); tx.setValue(0);
JFormattedTextField ty = new JFormattedTextField(formatter); ty.setValue(0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.marginallyclever.ro3.node.nodes;

import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.node.Node;
import org.json.JSONObject;
import org.slf4j.Logger;
Expand Down Expand Up @@ -119,11 +120,7 @@ public void getComponents(List<JPanel> list) {
JButton toPose = new JButton("To Pose");
toPose.addActionListener(e -> toPoseAndAdjustMeshes());

NumberFormat format = NumberFormat.getNumberInstance();
NumberFormatter formatter = new NumberFormatter(format);
formatter.setValueClass(Double.class);
formatter.setAllowsInvalid(true);
formatter.setCommitsOnValidEdit(true);
var formatter = NumberFormatHelper.getNumberFormatter();

JFormattedTextField dh_d = new JFormattedTextField(formatter); dh_d.setValue(d);
JFormattedTextField dh_r = new JFormattedTextField(formatter); dh_r.setValue(r);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.marginallyclever.ro3.node.nodes;

import com.marginallyclever.convenience.PathCalculator;
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.apps.nodeselector.NodeSelector;
import com.marginallyclever.ro3.node.NodePath;
Expand Down Expand Up @@ -39,11 +40,7 @@ public void getComponents(List<JPanel> list) {
list.add(pane);
pane.setName(HingeJoint.class.getSimpleName());

NumberFormat format = NumberFormat.getNumberInstance();
NumberFormatter formatter = new NumberFormatter(format);
formatter.setValueClass(Double.class);
formatter.setAllowsInvalid(true);
formatter.setCommitsOnValidEdit(true);
NumberFormatter formatter = NumberFormatHelper.getNumberFormatter();

JFormattedTextField angleField = new JFormattedTextField(formatter);
angleField.setValue(angle);
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/com/marginallyclever/ro3/node/nodes/Pose.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.marginallyclever.ro3.node.nodes;

import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.node.Node;
import org.json.JSONArray;
import org.json.JSONObject;
Expand Down Expand Up @@ -68,12 +69,7 @@ public void getComponents(List<JPanel> list) {
list.add(pane);
pane.setName(Pose.class.getSimpleName());

NumberFormat format = NumberFormat.getNumberInstance();
NumberFormatter formatter = new NumberFormatter(format);
formatter.setValueClass(Double.class);
formatter.setAllowsInvalid(true);
formatter.setCommitsOnValidEdit(true);

var formatter = NumberFormatHelper.getNumberFormatter();
addTranslationComponents(pane,formatter);
addRotationComponents(pane,formatter);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.StringHelper;
import com.marginallyclever.convenience.swing.Dial;
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.apps.nodedetailview.CollapsiblePanel;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.NodePath;
Expand All @@ -20,6 +21,8 @@
import javax.vecmath.Vector3d;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -136,41 +139,152 @@ public void getComponents(List<JPanel> list) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx=0;
gbc.gridy=0;
gbc.fill = GridBagConstraints.BOTH;

gbc.gridx=0;
gbc.gridy=0;
gbc.gridwidth=2;
pane.add(addMotorPanel(),gbc);
pane.add(createVelocitySlider(),gbc);

gbc.gridy++;
gbc.gridwidth=1;

addMoveTargetToEndEffector(pane,gbc);

JButton M114 = new JButton("M114");
M114.addActionListener(e-> sendGCode("M114"));
addLabelAndComponent(pane, "Get state", M114,gbc);

gbc.gridwidth=1;
gbc.gridy++;

// add a selector for the end effector
NodeSelector<Pose> endEffectorSelector = new NodeSelector<>(Pose.class, endEffector.getSubject());
endEffectorSelector.addPropertyChangeListener("subject",(e)-> {
endEffector.setRelativePath(this, (Pose)e.getNewValue());
});
addLabelAndComponent(pane, "End Effector", endEffectorSelector,gbc);
addNodeSelector(pane, "End Effector", endEffector, Pose.class, gbc);
addNodeSelector(pane, "Target", target, Pose.class, gbc);
addNodeSelector(pane, "Gripper motor", gripperMotor, Motor.class, gbc);

// add a selector for the target
NodeSelector<Pose> targetSelector = new NodeSelector<>(Pose.class, target.getSubject());
targetSelector.addPropertyChangeListener("subject",(e)-> {
target.setRelativePath(this, (Pose)e.getNewValue());
});
addLabelAndComponent(pane, "Target", targetSelector,gbc);
gbc.gridx=0;
gbc.gridwidth=2;
pane.add(getReceiver(),gbc);
gbc.gridy++;
pane.add(getSender(),gbc);
gbc.gridy++;
pane.add(createReportInterval(),gbc);
gbc.gridy++;
pane.add(createEasyFK(),gbc);
gbc.gridy++;

// add a selector for the gripper
NodeSelector<Motor> gripperMotorSelector = new NodeSelector<>(Motor.class, gripperMotor.getSubject());
gripperMotorSelector.addPropertyChangeListener("subject",(e)-> {
gripperMotor.setRelativePath(this, (Motor)e.getNewValue());
});
addLabelAndComponent(pane, "Gripper motor", gripperMotorSelector,gbc);
gbc.gridwidth=2;
pane.add(addMotorPanel(),gbc);

super.getComponents(list);
}

private JComponent createVelocitySlider() {
JPanel container = new JPanel(new BorderLayout());
// add a slider to control linear velocity
JSlider slider = new JSlider(0,20,(int)linearVelocity);
slider.addChangeListener(e-> linearVelocity = slider.getValue());
addLabelAndComponent(pane, "Linear Vel", slider,gbc);

// Make the slider fill the available horizontal space
slider.setMaximumSize(new Dimension(Integer.MAX_VALUE, slider.getPreferredSize().height));

container.add(new JLabel("Linear Vel"), BorderLayout.LINE_START);
container.add(slider, BorderLayout.CENTER); // Add slider to the center of the container


return container;
}

private double reportInterval=1.0;

private JComponent createReportInterval() {
var containerPanel = new CollapsiblePanel("Report");
var outerPanel = containerPanel.getContentPane();
outerPanel.setLayout(new GridBagLayout());

var label = new JLabel("interval (s)");
// here i need an input - time interval (positive float, seconds)
var formatter = NumberFormatHelper.getNumberFormatter();
var secondsField = new JFormattedTextField(formatter);
secondsField.setValue(getReportInterval());

// then a toggle to turn it on and off.
JToggleButton toggle = new JToggleButton("Start");
toggle.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/com/marginallyclever/ro3/apps/icons8-stopwatch-16.png"))));
JProgressBar progressBar = new JProgressBar();
progressBar.setMaximum((int) (getReportInterval() * 1000)); // Assuming interval is in seconds

Timer timer = new Timer(100, null);
ActionListener timerAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int value = progressBar.getValue() + 100;
if (value >= progressBar.getMaximum()) {
value = 0;
sendGCode("G0"); // Send G0 command when progress bar is full
}
progressBar.setValue(value);
}
};

toggle.addActionListener(e -> {
if (toggle.isSelected()) {
toggle.setText("Stop");
timer.addActionListener(timerAction);
timer.start();
} else {
toggle.setText("Start");
progressBar.setValue(0); // Reset progress bar when toggle is off
timer.stop();
timer.removeActionListener(timerAction);
}
});

toggle.addHierarchyListener(e -> {
if ((HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags()) !=0
&& !toggle.isShowing()) {
timer.stop();
timer.removeActionListener(timerAction);
}
});

// Add components to the panel
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx=0;
gbc.gridy=0;
gbc.fill = GridBagConstraints.BOTH;

outerPanel.add(label, gbc);
gbc.gridx++;
outerPanel.add(secondsField, gbc);
gbc.gridy++;
gbc.gridx=0;
outerPanel.add(toggle, gbc);
gbc.gridx++;
outerPanel.add(progressBar, gbc);
gbc.gridy++;

return containerPanel;
}

private double getReportInterval() {
return reportInterval;
}

private void setReportInterval(double seconds) {
reportInterval = Math.max(0.1,seconds);
}


private <T extends Node> void addNodeSelector(JPanel pane, String label, NodePath<T> nodePath, Class<T> clazz, GridBagConstraints gbc) {
NodeSelector<T> selector = new NodeSelector<>(clazz, nodePath.getSubject());
selector.addPropertyChangeListener("subject", (e) -> nodePath.setRelativePath(this, (T) e.getNewValue()));
addLabelAndComponent(pane, label, selector, gbc);
}

private void addMoveTargetToEndEffector(JPanel pane,GridBagConstraints gbc) {
// move target to end effector
JButton targetToEE = new JButton(new AbstractAction() {
{
Expand All @@ -185,22 +299,6 @@ public void actionPerformed(ActionEvent e) {
}
});
addLabelAndComponent(pane, "Target to EE", targetToEE,gbc);

JButton M114 = new JButton("M114");
M114.addActionListener(e-> sendGCode("M114"));
addLabelAndComponent(pane, "Get state", M114,gbc);

gbc.gridx=0;
gbc.gridwidth=2;
pane.add(getReceiver(),gbc);
gbc.gridy++;
pane.add(getSender(),gbc);
gbc.gridy++;
pane.add(new JSeparator(),gbc);
gbc.gridy++;
pane.add(createEasyFK(),gbc);

super.getComponents(list);
}

private void setTargetToEndEffector() {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.