Skip to content

Commit

Permalink
Feature / Global Axes and Framework for Enhanced Motion Control (open…
Browse files Browse the repository at this point in the history
…pnp#1035)

* First implementation round. GCodeDriver Axis management is still redundantly in there.

* Reworked Drivers to flat list.

* Machine Setup Panel Tabs per class restoring and out of bounds bugfix.

* Work in progress, backup commit.

* Add

* Axes and Transformations' Wizards implemented. Reorganized into own axis package. Wrestle with WindowBuilder.

* First time tests run successful. GcodeDriver still partially running on its own (redundant) Axis mapping.

* Testing and refining migration with examples.

* Resolved openpnp#998 merging issues.

* Cosmetics.

* Created new AxesLocation for Controller side. Reworked all Transformations.

* Made tests run with AxesLocation.

* Testing: First steps towards "simulated imperfection".

* Tested using NullDriver.
* Added simulated Homing Error corrected by Visual Homing
* Added simulated non-squareness corrected by Linear Axis Non-Squareness Transformation
* Added simulated vibration to test Camera Settle
* Added simulated camera noise to test Camera Settle
* Added simulated nozzle runout to test Runout Compensation
No Unit yet.

* Restrict image transfer to the area of the source image, to fix some wrapping-around when going beyond the image margin.

* Backup commit.

* Factored OpenCvUtils.createFootprintTemplate() out for use outside of stages.

* SimulationModeMachine can now check pick and place Locations by inspecting the ImageCamera view at the location.

* Sub-pixel rendering etc.

* Refined the NullMotionPlanner and various stuff.

* Fix the camera view rotation jog to work with and respect mapped axes.

* MotionPlanner first implementation. Before MappedAxes refactoring.

* Reworked: no MappedAxes. Axis limits. Rotation wrap-around.

* Added solver.

* Better description and simpler formula. Getting the hang of this.

* More cosmetics

* Backup commit.

* Backup commit.

* Added motion solver test. Does not work (yet).

* Backup commit

* Backup commit before solver remove.

* Removed tnc solver. Almost completed profile solver cases.

* Backup commit

* Changed profile solver to rudimentary secant method.

* Solver seems to work now.

* Backup commit

* New region solver.

* Tests augmented.

* Before reworking path solver.

* Backup before reworking path solving/half sided profiles.

* Finish without trying to implement advanced motion planning. Cleanup and better comments.

* Better comments.

* Removed unnecessary (whitespace) changes etc. Better comments.

* Self code review bugfixes.

* Constant acceleration profiles.
Optionally test an imperfect machine in the SampleJobTest.

* Simplify Motion and MotionOption.
Implement analytical constant acceleration profile solving for symmetric cases.
Lots of cosmetics.

* Testing on the machine with GcodeDriver: refinements and bugfixes.

* Test bugfix.

(cherry picked from commit f6713b6)

Fix/global axes bugfixes 1 (openpnp#1038)

* Squashed commit of the following:

commit a252f08
Author: markmaker <mark@makr.zone>

    Own Machine testing bug-fixes. Proper X, Y filtering of Visual Homing axes by the Camera that is used (mapped axes only). Also found logic inversion error in ReferenceHead.isInsideSoftLimits(HeadMountable, Location).
    Testing this with multiple Heads and no camera on second head required changing Park Location interpretation to any HeadMountable.

commit c765eaf
Author: markmaker <mark@makr.zone>

    Initial user group machine testing bugfixes. Thank you Duncan, Bill, Marmalade, Mike!
    Removed obsolete openpnp\src\main\java\org\openpnp\machine\reference\driver\wizards\AbstractTcpDriverConfigurationWizard.java

commit 190b34b
Author: markmaker <mark@makr.zone>

    Test bugfix.

commit 3a94e82
Author: markmaker <mark@makr.zone>

    Testing on the machine with GcodeDriver: refinements and bugfixes.

commit 1f52b1c
Author: markmaker <mark@makr.zone>

    Simplify Motion and MotionOption.
    Implement analytical constant acceleration profile solving for symmetric cases.
    Lots of cosmetics.

commit 38aae5d
Author: markmaker <mark@makr.zone>

    Constant acceleration profiles.
    Optionally test an imperfect machine in the SampleJobTest.

commit e38384a
Author: markmaker <mark@makr.zone>

    Self code review bugfixes.

commit c4f87b7
Merge: cd6b55f edbca39
Author: markmaker <mark@makr.zone>

    Merge branch 'develop' into feature/global-axes

    Conflicts resolved:
    *	src/test/java/VisionUtilsTest.java

commit cd6b55f
Author: markmaker <mark@makr.zone>

    Removed unnecessary (whitespace) changes etc. Better comments.

commit ee29ca7
Author: markmaker <mark@makr.zone>

    Better comments.

commit c8c0e7e
Merge: ef152b6 10b0095
Author: markmaker <mark@makr.zone>

    Merge branch 'develop' into feature/global-axes

    Resolved Conflicts:
    *	src/main/java/org/openpnp/machine/reference/ReferenceMachine.java

commit ef152b6
Author: markmaker <mark@makr.zone>

    Finish without trying to implement advanced motion planning. Cleanup and better comments.

commit 2e1a0ee
Author: markmaker <mark@makr.zone>

    Backup before reworking path solving/half sided profiles.

commit fb92b4d
Author: markmaker <mark@makr.zone>

    Before reworking path solver.

commit 9443afb
Merge: 9aed71f 5280aa8
Author: markmaker <mark@makr.zone>

    Merge branch 'develop' into feature/global-axes

    Conflicts resolved:
    *	src/main/java/org/openpnp/machine/reference/ReferenceMachine.java
    *	src/main/java/org/openpnp/machine/reference/ReferenceNozzleTipCalibration.java
    *	src/main/java/org/openpnp/machine/reference/driver/GcodeDriver.java

commit 9aed71f
Author: markmaker <mark@makr.zone>

    Tests augmented.

commit 777ed4a
Author: markmaker <mark@makr.zone>

    New region solver.

commit 2511dcf
Author: markmaker <mark@makr.zone>

    Backup commit

commit 273474c
Author: markmaker <mark@makr.zone>

    Solver seems to work now.

commit 4cd7f6d
Author: markmaker <mark@makr.zone>

    Changed profile solver to rudimentary secant method.

commit aaa832f
Author: markmaker <mark@makr.zone>

    Backup commit

commit 512ce63
Author: markmaker <mark@makr.zone>

    Removed tnc solver. Almost completed profile solver cases.

commit 15996c6
Author: markmaker <mark@makr.zone>

    Backup commit before solver remove.

commit 019436b
Author: markmaker <mark@makr.zone>

    Backup commit

commit 46a3be1
Author: markmaker <mark@makr.zone>

    Added motion solver test. Does not work (yet).

commit b8a5780
Author: markmaker <mark@makr.zone>

    Backup commit.

commit 4a5f01f
Author: markmaker <mark@makr.zone>

    Backup commit.

commit 5de4b1c
Author: markmaker <mark@makr.zone>

    More cosmetics

commit 557c005
Author: markmaker <mark@makr.zone>

    Better description and simpler formula. Getting the hang of this.

commit 4b8f935
Author: markmaker <mark@makr.zone>

    Added solver.

commit e3a14a2
Author: markmaker <mark@makr.zone>

    Reworked: no MappedAxes. Axis limits. Rotation wrap-around.

commit f8301ba
Author: markmaker <mark@makr.zone>

    MotionPlanner first implementation. Before MappedAxes refactoring.

commit 71c672d
Author: markmaker <mark@makr.zone>

    Fix the camera view rotation jog to work with and respect mapped axes.

commit 0dbdf0b
Author: markmaker <mark@makr.zone>

    Refined the NullMotionPlanner and various stuff.

commit 2234e45
Author: markmaker <mark@makr.zone>

    Sub-pixel rendering etc.

commit 7e98c23
Author: markmaker <mark@makr.zone>

    SimulationModeMachine can now check pick and place Locations by inspecting the ImageCamera view at the location.

commit ba10f8c
Author: markmaker <mark@makr.zone>

    Factored OpenCvUtils.createFootprintTemplate() out for use outside of stages.

commit 02bcfa5
Author: markmaker <mark@makr.zone>

    Backup commit.

commit 3d2409a
Author: markmaker <mark@makr.zone>

    Restrict image transfer to the area of the source image, to fix some wrapping-around when going beyond the image margin.

commit 0be6a0e
Merge: 4b389c7 b4310b6
Author: markmaker <mark@makr.zone>

    Merge branch 'develop' into feature/global-axes

commit 4b389c7
Author: markmaker <mark@makr.zone>

    Tested using NullDriver.
    * Added simulated Homing Error corrected by Visual Homing
    * Added simulated non-squareness corrected by Linear Axis Non-Squareness Transformation
    * Added simulated vibration to test Camera Settle
    * Added simulated camera noise to test Camera Settle
    * Added simulated nozzle runout to test Runout Compensation
    No Unit yet.

commit c08725c
Author: markmaker <mark@makr.zone>

    Testing: First steps towards "simulated imperfection".

commit 3e72d57
Author: markmaker <mark@makr.zone>

    Made tests run with AxesLocation.

commit 4dd295d
Merge: 19f2505 b8548f9
Author: markmaker <mark@makr.zone>

    Merge branch 'develop' into feature/global-axes

commit 19f2505
Author: markmaker <mark@makr.zone>

    Created new AxesLocation for Controller side. Reworked all Transformations.

commit 80117eb
Author: markmaker <mark@makr.zone>

    Cosmetics.

commit b36f6e9
Author: markmaker <mark@makr.zone>

    Resolved openpnp#998 merging issues.

commit 0139331
Merge: 8b266b2 19e2925
Author: markmaker <mark@makr.zone>

    Merge branch 'develop' into feature/global-axes

    # Conflicts resolved:
    *	src/main/java/org/openpnp/machine/marek/MarekNozzle.java
    *	src/main/java/org/openpnp/machine/neoden4/NeoDen4Driver.java
    *	src/main/java/org/openpnp/machine/reference/ReferenceActuator.java
    *	src/main/java/org/openpnp/machine/reference/ReferenceCamera.java
    *	src/main/java/org/openpnp/machine/reference/ReferenceDriver.java
    *	src/main/java/org/openpnp/machine/reference/ReferenceHead.java
    *	src/main/java/org/openpnp/machine/reference/ReferenceNozzle.java
    *	src/main/java/org/openpnp/machine/reference/driver/GcodeDriver.java
    *	src/main/java/org/openpnp/machine/reference/driver/NullDriver.java
    *	src/main/java/org/openpnp/spi/Movable.java
    *	src/main/java/org/openpnp/spi/base/AbstractActuator.java
    *	src/main/java/org/openpnp/spi/base/AbstractCamera.java
    *	src/test/java/BasicJobTest.java
    *	src/test/java/VisionUtilsTest.java
    *	src/test/java/org/openpnp/machine/reference/driver/test/TestDriver.java

commit 8b266b2
Author: markmaker <mark@makr.zone>

    Testing and refining migration with examples.

commit 1dc16ec
Author: markmaker <mark@makr.zone>

    First time tests run successful. GcodeDriver still partially running on its own (redundant) Axis mapping.

commit b12c661
Author: markmaker <mark@makr.zone>

    Axes and Transformations' Wizards implemented. Reorganized into own axis package. Wrestle with WindowBuilder.

commit daa9eee
Author: markmaker <mark@makr.zone>

    Add

commit ce3f543
Author: markmaker <mark@makr.zone>

    Work in progress, backup commit.

commit 53e7875
Author: markmaker <mark@makr.zone>

    Machine Setup Panel Tabs per class restoring and out of bounds bugfix.

commit e61af78
Author: markmaker <mark@makr.zone>

    Reworked Drivers to flat list.

commit 51ea613
Author: markmaker <mark@makr.zone>

    First implementation round. GCodeDriver Axis management is still redundantly in there.

Conflicts resolved:
*	src/main/java/org/openpnp/machine/reference/ReferenceHead.java
*	src/main/java/org/openpnp/machine/reference/axis/ReferenceControllerAxis.java
*	src/main/java/org/openpnp/machine/reference/axis/ReferenceMappedAxis.java
*	src/main/java/org/openpnp/machine/reference/axis/wizards/ReferenceControllerAxisConfigurationWizard.java
*	src/main/java/org/openpnp/machine/reference/driver/AbstractMotionPlanner.java
*	src/main/java/org/openpnp/machine/reference/driver/GcodeDriver.java
*	src/main/java/org/openpnp/model/AxesLocation.java
*	src/main/java/org/openpnp/model/Motion.java
*	src/main/java/org/openpnp/spi/ControllerAxis.java
*	src/main/java/org/openpnp/spi/base/AbstractControllerAxis.java

* Initial user group machine testing bugfixes. Thank you Duncan, Bill, Marmalade, Mike!
Removed obsolete openpnp\src\main\java\org\openpnp\machine\reference\driver\wizards\AbstractTcpDriverConfigurationWizard.java

* Cosmetics.

(cherry picked from commit d46cfb3)

Fix/Global Axes Enhancements and Bug-Fixes 2 (openpnp#1042)

* Integrated GcodeServer into SimulationMode.

* Added MotionControlType to Driver. Implemented simplified S-Curves as in TinyG and Marlin. Bugfixes.

* Tests with Null Machine. New reset button for default GcodeDriver commands. Bug-fixes.

(cherry picked from commit c144c75)

Feature/Better Backlash Compensation (openpnp#1047)

* Removed backlash compensation from GcodeDriver and added it to the Motion Planner.
* A new BacklashCompensationMethod can now be selected on the axis.
* Added optimized one-sided backlash compensation that only adds an extra move, if on the wrong side.
* Added directional backlash compensation that works without extra moves.

(cherry picked from commit 58a54a7)

Feature/Advanced Motion Control (openpnp#1061)

* Make Directional Backlash Compensation one sided too for better compatibility.

* Asynchronous GcodeDriver first steps.

* * Implemented GcodeAsyncDriver.
* Fixed some Backlash Compensation bugs for the new Directional method.
* Hide deprecated Gcode commands in the Combobox, if they are not set to a value already.

* * Adding the GcodeAsyncDriver class to the Machine so it can be instantiated.
* Some bug-fixes.

* Bugfixes, testing with controller.

* First trials with interpolation.

* Fixed Logger thread safety.

* * New GcodeAsyncDriverSettings Wizard.
* Interpolation settings moved to the GcodeAsyncDriver where they belong, getters return defaults in GcodeDriver.
* timeoutMilliseconds is stretched to the inverse of the Machine Speed where it matters. So tests with very small speed factors won't timeout.
* Added ModeratedConstantAcceleration motion control type.
* Bug-fixes from testing with controller/stepper attached.

* * MotionPlanner class can now be selected in the Machine Wizard.
* ReferenceAdvancedMotionPlannerConfigurationWizard added, exposing the MotionPlanner as a Wizard page of the machine.
* Refactored actuator sub-class Wizards to use base class AbstractActuatorConfigurationWizard for common stuff (in preparation to add more common stuff).
* extracted public method to allow (re-) selection of current object in the Machine Setup Tree, therefore allow loading Wizards with changing set of tabs.
* moved getMotionPlanner() to Machine interface.

* * Actuator, machine & motion coordination

* * CameraView Zoom increment clipped to >= 1.0 if best scale quality is selected

* * Remodeled ReferenceDriver interface into spi Driver interface and class hierarchy similar to other machine objects.
* Made interpolation a task of the MotionPlanner, drivers now only execute single moveTo commands.

* * Backlash compensation more robust when settings change during session
* First steps towards advanced motion planner
* Support profiles with fused reversing ramps i.e. acceleration != 0 in mid segment
* Test case reworked

* * Path solver progress.

* * Refactored overshoot control

* * Good working order.

* * Refactored AbstractMotionPath out of MotionProfile to separate path solving from profile solving.
* Simplified "PnP class" path solver heuristics completed.

* * Controller axes get Safe Zone

* * Implemented Axis centric Safe (Z) Zone
* Migrate Safe Z.
* BasicJobTest with proper working Z below Safe Z
* ReferenceAdvancedMotionPlanner performs uncoordinated moves in Safe Zone

* * Machine testing.

* * First steps towards better interpolation.

* * Reverted Momentaries.
* New interpolation method.

* * More testing.

* * Diagnostic Graphics
* Bugfixing

* * Finished graphical diagnostics.
* Better uncoordinated motion synchronization, tries to approximate coordinated.
* Bugfixing.

* * Interpolation intervals snap to the special points in time (extremes in the profile).
* Testing on machine.

* * Proper diagnostics for all MotionControlType variants.
* Added Test Motion.
* Time measurements in diagnostics.
* Interpolation failure status.

* * C axis in Test motionGraph
* Retiming optionFlags
* Fine tuning.
* More tests on Smoothie.

* * extensive testing on machine

* * Extensive code review, last fixes and final touches.
* Redesigned ugly axis limit icons.

* * Solved position reporting dilemma.
* Made "infinite" timeouts into 5 minutes to (eventually) resolve hard-to-diagnose hangs.
* Added after actuate machine coordination back, needed for contact probing.
* Added Safe Z handling for virtual axes (takes home coordinate).

(cherry picked from commit 52f2756)

* Conflicts resolved:
   * src/main/java/org/openpnp/machine/reference/driver/GcodeDriver.java

Merge pull request openpnp#1065 from markmaker/feature/advanced-motion-control--update

Feature/Advanced Motion Control - Various Improvments

Merging this myself, in the testing branch regime.

(cherry picked from commit b5a53eb)

Merge pull request openpnp#1066 from markmaker/feature/advanced-motion-control--update-2

Feature/Advanced Motion Control  - Update 2

(cherry picked from commit 75bda17)

Merge pull request openpnp#1071 from markmaker/feature/advanced-motion-control--3

Feature / Advanced Motion Control - Update 3

(cherry picked from commit 4a96553)

Merge pull request openpnp#1072 from markmaker/feature/advanced-motion-control--4

Feature/Advanced Motion Control - Update 4

(cherry picked from commit dfba626)

Merge pull request openpnp#1073 from markmaker/feature/advanced-motion-control--5

Feature / Advanced Motion Control - Update 5

(cherry picked from commit 56eae4d)

Merge pull request openpnp#1074 from markmaker/feature/advanced-motion-control--6

Feature / Advanced Motion Control - Update 6

(cherry picked from commit e5b521c)

Merge pull request openpnp#1082 from markmaker/feature/advanced-motion-control--7

Feature / Advanced Motion Control - Update 7

(cherry picked from commit e12b91a)

* Better TinyG SET_GLOBAL_OFFSETS_COMMAND suggestion.

(cherry picked from commit 2bcaff3151ba7d8516c16551d5a74202d57c9c74)

* Cherry Pick artifact?
  • Loading branch information
markmaker committed Dec 12, 2020
1 parent 6382e82 commit 2fa440c
Show file tree
Hide file tree
Showing 147 changed files with 23,993 additions and 2,989 deletions.
21 changes: 21 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
This file lists major or notable changes to OpenPnP in chronological order. This is not
a complete change list, only those that may directly interest or affect users.

# 2020-12-12

## Advanced Motion Control

- Simpler all-GUI setup of machine axes, axis transformations and their assignment to Nozzles,
Cameras etc. (no more machine.xml hacking).
- Making features such as Axis Mapping, Backlash Compensation, Visual Homing, Non-Squareness
Compensation etc. available for all types of drivers (formerly just the GcodeDriver).
- Allowing multiple drivers of mixed types.
- Better control of speed factors: properly control the average speed, including
acceleration/deceleration phases. A move at 50% takes exactly twice as long, regardles of
how short or long the move is.
- Simulated Jerk Control to reduce vibrations, prevent slipping of parts on nozzles, etc.
- Experimental: Motion Blending.
- Asynchronous communication between OpenPnP and (multiple) controllers. Decoupled and
paralellized operation.
- Graphical diagnostics for Motion Planning as a basis for fact based machine optimization.
- Issues & Solutions system to automatically solve machine specific setup and migration
issues, enable advanced features, generate firmware-adapted Gcode commands and regular
expressions.

# 2020-06-23

## Actuator API Change (Non-Breaking)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/openpnp/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public void run() {
try {
MainFrame frame = new MainFrame(configuration);
frame.setVisible(true);
Logger.debug(String.format("Bienvenue, Bienvenido, Willkommen, Hello, Namaskar, Welkom, Bonjour to OpenPnP version %s.", Main.getVersion()));
Logger.info(String.format("Bienvenue, Bienvenido, Willkommen, Hello, Namaskar, Welkom, Bonjour to OpenPnP version %s.", Main.getVersion()));
configuration.getScripting().on("Startup", null);
}
catch (Exception e) {
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/org/openpnp/gui/JogControlsPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.openpnp.model.Length;
import org.openpnp.model.LengthUnit;
import org.openpnp.model.Location;
import org.openpnp.model.Motion.MotionOption;
import org.openpnp.spi.Actuator;
import org.openpnp.spi.Head;
import org.openpnp.spi.HeadMountable;
Expand Down Expand Up @@ -228,7 +229,8 @@ else if (c < 0) {
}
}

tool.moveTo(targetLocation);
tool.moveTo(targetLocation, MotionOption.JogMotion);
// to test without backlash comp for continous jogging: add MotionOption.SpeedOverPrecision
}

private boolean nozzleLocationIsSafe(Location origin, Location dimension, Location nozzle,
Expand Down Expand Up @@ -566,7 +568,14 @@ public void actionPerformed(ActionEvent arg0) {
public void actionPerformed(ActionEvent arg0) {
UiUtils.submitUiMachineTask(() -> {
HeadMountable hm = machineControlsPanel.getSelectedTool();
hm.moveToSafeZ();
// Note, we don't just moveToSafeZ(), because this will just sit still, if we're anywhere in the Safe Z Zone.
// instead we explicitly move to the Safe Z coordinate i.e. the lower bound of the Safe Z Zone, applicable
// for this hm.
Location location = hm.getLocation();
Length safeZLength = hm.getSafeZ();
double safeZ = (safeZLength != null ? safeZLength.convertToUnits(location.getUnits()).getValue() : Double.NaN);
location = location.derive(null, null, safeZ, null);
hm.moveTo(location);
});
}
};
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/org/openpnp/gui/LogPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@

import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;

import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

Expand All @@ -42,6 +47,8 @@ public class LogPanel extends JPanel {
private LogEntryListModel.LogEntryFilter searchBarFilter = new LogEntryListModel.LogEntryFilter();
private LogEntryListModel.LogEntryFilter systemOutFilter = new LogEntryListModel.LogEntryFilter();

private ScheduledExecutorService scheduledExecutor;

public LogPanel() {

loadLoggingPreferences();
Expand Down Expand Up @@ -134,6 +141,21 @@ public void actionPerformed(ActionEvent e) {
copyStringToClipboard(sb.toString());
}
});

scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
scheduledExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
refreshLogIfOnTop();
}
}, 0, 500, TimeUnit.MILLISECONDS);

MainFrame.get().getTabs().addChangeListener(new ChangeListener() {

@Override
public void stateChanged(ChangeEvent e) {
refreshLogIfOnTop();
}
});
}

private JCheckBox createSystemOutputCheckbox() {
Expand Down Expand Up @@ -186,9 +208,11 @@ private JPanel createSearchFieldPanel() {
searchTextField.getDocument().addDocumentListener(new DocumentListener() {

private void updateSearchBarFilter() {
LogEntry entry = getSelectedEntry();
String searchText = searchTextField.getText();
searchBarFilter.setFilter((logEntry -> logEntry.getRenderedLogEntry().toLowerCase().contains(searchText.toLowerCase())));
logEntries.filter();
setSelectedEntry(entry);
}

@Override
Expand Down Expand Up @@ -218,9 +242,11 @@ private JPanel createFilterLogLevelPanel() {
JComboBox<Level> logLevelFilterComboBox = new JComboBox<>(Level.values());
logLevelFilterComboBox.setSelectedItem(filterLogLevel);
logLevelFilterComboBox.addActionListener(e -> {
LogEntry entry = getSelectedEntry();
Level logLevel = (Level) logLevelFilterComboBox.getSelectedItem();
logLevelFilter.setFilter(logEntry -> logEntry.getLevel().compareTo(logLevel) >= 0);
logEntries.filter();
setSelectedEntry(entry);
});
filterLogLevelPanel.add(logLevelFilterComboBox);
return filterLogLevelPanel;
Expand Down Expand Up @@ -249,4 +275,29 @@ private void copyStringToClipboard(String s) {
clipboard.setContents(selection, selection);
}

protected void refreshLogIfOnTop() {
if (MainFrame.get().getTabs().getSelectedComponent() == LogPanel.this) {
if (logEntries.isRefreshNeeded()) {
logEntries.refresh();
}
}
}

protected LogEntry getSelectedEntry() {
int index = logEntryJList.getSelectedIndex();
if (index >= 0) {
return logEntries.getElementAt(index);
}
return null;
}

protected void setSelectedEntry(LogEntry entry) {
if (entry != null) {
int index = logEntries.getFilteredLogEntries().indexOf(entry);
if (index >= 0) {
logEntryJList.setSelectedIndex(index);
}
}
}

}
15 changes: 8 additions & 7 deletions src/main/java/org/openpnp/gui/MachineControlsPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,14 @@ public void actionPerformed(ActionEvent arg0) {
Machine machine = Configuration.get().getMachine();
boolean enable = !machine.isEnabled();
try {
Configuration.get().getMachine().setEnabled(enable);
// TODO STOPSHIP move setEnabled into a binding.
setEnabled(true);
if (machine.getHomeAfterEnabled() && machine.isEnabled()) {
// TODO STOPSHIP should not be in the UI
machine.home();
}
Configuration.get().getMachine().setEnabled(enable);
// TODO STOPSHIP move setEnabled into a binding.
setEnabled(true);
if (machine.getHomeAfterEnabled() && machine.isEnabled()) {
UiUtils.submitUiMachineTask(() -> {
machine.home();
});
}
}
catch (Exception t1) {
MessageBoxes.errorBox(MachineControlsPanel.this, "Enable Failure", //$NON-NLS-1$
Expand Down
112 changes: 58 additions & 54 deletions src/main/java/org/openpnp/gui/MachineSetupPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,60 +172,7 @@ public void stateChanged(ChangeEvent e) {
tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
disableLastSelectedListener = true;
tabbedPane.removeAll();
toolBar.removeAll();

TreePath path = tree.getSelectionPath();
if (path != null) {
List<Object> pathsReverse = Arrays.asList(path.getPath());
Collections.reverse(pathsReverse);
for (Object o : pathsReverse) {
PropertySheetHolderTreeNode node = (PropertySheetHolderTreeNode) o;
Action[] actions = node.obj.getPropertySheetHolderActions();
if (actions != null) {
for (Action action : actions) {
toolBar.add(action);
}
}
}

PropertySheetHolderTreeNode node =
(PropertySheetHolderTreeNode) path.getLastPathComponent();
if (node != null) {
PropertySheet[] propertySheets = node.obj.getPropertySheets();
if (propertySheets != null) {
for (PropertySheet propertySheet : propertySheets) {
String title = propertySheet.getPropertySheetTitle();
JPanel panel = propertySheet.getPropertySheetPanel();
if (title == null) {
title = "Configuration";
}
if (panel != null) {
tabbedPane.add(title, panel);
}
}

if (node.obj != null) {
if (lastSelectedTabIndex.get(node.obj.getClass()) != null) {
// Sometimes when clicking around quickly, the lastSelectedTabIndex update seems to be wrong,
// resulting in an IndexOutOfBoundsException. Therefore we check the tab count too. This covers variable per class Wizards too.
tabbedPane.setSelectedIndex(Math.min(tabbedPane.getTabCount()-1, lastSelectedTabIndex.get(node.obj.getClass())));
}
}

lastSelectedNode = node.obj;
}
else {
lastSelectedNode = null;
}
}
}

disableLastSelectedListener = false;

revalidate();
repaint();
selectCurrentTreePath();
}
});

Expand Down Expand Up @@ -257,6 +204,63 @@ public void wizardCompleted(Wizard wizard) {}
@Override
public void wizardCancelled(Wizard wizard) {}

public void selectCurrentTreePath() {
disableLastSelectedListener = true;
tabbedPane.removeAll();
toolBar.removeAll();

TreePath path = tree.getSelectionPath();
if (path != null) {
List<Object> pathsReverse = Arrays.asList(path.getPath());
Collections.reverse(pathsReverse);
for (Object o : pathsReverse) {
PropertySheetHolderTreeNode node = (PropertySheetHolderTreeNode) o;
Action[] actions = node.obj.getPropertySheetHolderActions();
if (actions != null) {
for (Action action : actions) {
toolBar.add(action);
}
}
}

PropertySheetHolderTreeNode node =
(PropertySheetHolderTreeNode) path.getLastPathComponent();
if (node != null) {
PropertySheet[] propertySheets = node.obj.getPropertySheets();
if (propertySheets != null) {
for (PropertySheet propertySheet : propertySheets) {
String title = propertySheet.getPropertySheetTitle();
JPanel panel = propertySheet.getPropertySheetPanel();
if (title == null) {
title = "Configuration";
}
if (panel != null) {
tabbedPane.add(title, panel);
}
}

if (node.obj != null) {
if (lastSelectedTabIndex.get(node.obj.getClass()) != null) {
// Sometimes when clicking around quickly, the lastSelectedTabIndex update seems to be wrong,
// resulting in an IndexOutOfBoundsException. Therefore we check the tab count too. This covers variable per class Wizards too.
tabbedPane.setSelectedIndex(Math.min(tabbedPane.getTabCount()-1, lastSelectedTabIndex.get(node.obj.getClass())));
}
}

lastSelectedNode = node.obj;
}
else {
lastSelectedNode = null;
}
}
}

disableLastSelectedListener = false;

revalidate();
repaint();
}

public class PropertySheetHolderTreeNode implements TreeNode {
private final PropertySheetHolder obj;
private final TreeNode parent;
Expand Down

0 comments on commit 2fa440c

Please sign in to comment.