Skip to content

Commit

Permalink
Better comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
markmaker committed Aug 6, 2020
1 parent c8c0e7e commit ee29ca7
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,18 @@ public Wizard getConfigurationWizard() {
}

@Override
public LengthUnit getUnits() {
return LengthUnit.Millimeters;
public boolean coordinatesMatch(Length coordinateA, Length coordinateB) {
if (type == Axis.Type.Rotation) {
// Never convert rotation
return coordinatesMatch(
coordinateA.getValue(),
coordinateB.getValue());
}
else {
return coordinatesMatch(
coordinateA.convertToUnits(AxesLocation.getUnits()).getValue(),
coordinateB.convertToUnits(AxesLocation.getUnits()).getValue());
}
}

protected long getResolutionTicks(double coordinate) {
Expand Down
109 changes: 98 additions & 11 deletions src/main/java/org/openpnp/model/AxesLocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,43 +40,100 @@

/**
* Like the classic OpenPnP Location, the AxesLocation stores a set of coordinates. However AxesLocation
* can store an arbitrary number of axes and their coordinates including multiple times the same type.
* can store an arbitrary number of axes and their coordinates, including multiple times the same Axis.Type
* e.g. multiple Z or C axes.
*
* All coordinates are handled as Millimeters to speed up calculations and allow for multi-axis transforms
* across drivers with different units. This unit-less handling also avoids problems with rotational axis
* coordinates that should obviously never be length unit converted.
*
* Like Location, the AxesLoction is sometimes also used as a (relative) Vector. Furthermore, it is also used
* as an axis map, i.e. only the included axes are important, not the coordinates.
* Like Location, the AxesLoction is sometimes used as a Vector, thought as a distance to the origin.
* Furthermore, it is sometimes used as an axis map, i.e. only the included axes are important, not the
* coordinates.
*
* Coordinates of axes not present in the AxesLocation are sometimes treated as 0.0, in other cases however a
* missing axis means that it should not be included in an operation such as moveTo(), etc. Be careful to
* determine which meaning applies.
*
* AxesLocations preserve the order of the axes. In particular the Configuration order of axis definitions is
* sometimes used to treat axes in their "natural" order, where it may matter.
*
*/
public class AxesLocation {
final private LinkedHashMap<Axis, Double> location;
final public static AxesLocation zero = new AxesLocation();

/**
* All coordinates of AxesLoactions are handled as Millimeters to speed up calculations and allow for
* multi-axis transforms across drivers with different units and other universal vector math. This unit-less
* handling also avoids problems with rotational axis coordinates that should obviously never be length unit
* converted.
*
* @return
*/
final public static LengthUnit getUnits() {
return LengthUnit.Millimeters;
}

/**
* Create an empty AxesLocation. Because coordinates often default to 0.0, this can also be used as the
* origin or zero AxesLocation. See also org.openpnp.model.AxesLocation.zero.
*
*/
public AxesLocation() {
// Empty
// Empty.
location = new LinkedHashMap<>(0);
}
/**
* Create a single Axis/coordinate pair AxesLocation.
*
* @param axis
* @param coordinate
*/
public AxesLocation(Axis axis, double coordinate) {
location = new LinkedHashMap<>(1);
if (axis != null) {
location.put(axis, coordinate);
}
}
/**
* Create a single Axis/Length coordinate pair AxesLocation.
*
* @param axis
* @param coordinate
*/
public AxesLocation(Axis axis, Length coordinate) {
this(axis, coordinate
.convertToUnits(getUnits()).getValue());
}
/**
* Create an AxesLocation with the given CoordinateAxis argument list and initialize to the current
* coordinates (i.e. planned coordinates).
*
* @param axes
*/
public AxesLocation(CoordinateAxis... axis) {
location = new LinkedHashMap<>(axis.length);
for (CoordinateAxis oneAxis : axis) {
location.put(oneAxis, oneAxis.getLengthCoordinate().convertToUnits(getUnits()).getValue());
}
}
/**
* Create an AxesLocation with the given Axis List and initialize to the current
* coordinates (i.e. planned coordinates).
*
* @param axes
*/
public AxesLocation(List<CoordinateAxis> axes) {
this(axes, (axis) -> axis.getLengthCoordinate());
}
/**
* Create an AxesLocation with the given typed Axis Iterable and initialize coordinates with the given function.
*
* @param <T>
* @param axes
* @param initializer
*/
public <T extends Axis> AxesLocation(Iterable<T> axes, Function<T, Length> initializer) {
location = new LinkedHashMap<>();
for (T axis : axes) {
Expand All @@ -86,9 +143,22 @@ public <T extends Axis> AxesLocation(Iterable<T> axes, Function<T, Length> initi
}
}
}
/**
* Create an AxesLoaction over all the ControllerAxes of the machine and initialize to the current
* coordinates (i.e. planned coordinates).
*
* @param machine
*/
public AxesLocation(Machine machine) {
this(machine, (axis) -> (axis.getLengthCoordinate()));
}
/**
* Create an AxesLoaction over all the CoordinateAxes of the machine (in Machine Setup order).
* Apply the given function to initialize the coordinates.
*
* @param machine
* @param initializer
*/
public AxesLocation(Machine machine, Function<CoordinateAxis, Length> initializer) {
location = new LinkedHashMap<>();
for (Axis axis : machine.getAxes()) {
Expand All @@ -100,6 +170,14 @@ public AxesLocation(Machine machine, Function<CoordinateAxis, Length> initialize
}
}
}
/**
* Create an AxesLoaction over all the ControllerAxes of the machine (in Machine Setup order) and with the given driver.
* Apply the given function to initialize the coordinates.
*
* @param machine
* @param driver
* @param initializer
*/
public AxesLocation(Machine machine, Driver driver, Function<ControllerAxis, Length> initializer) {
location = new LinkedHashMap<>();
for (Axis axis : machine.getAxes()) {
Expand All @@ -113,6 +191,12 @@ public AxesLocation(Machine machine, Driver driver, Function<ControllerAxis, Len
}
}
}
/**
* Using the given binary function, aggregate the given axesLocation argument list.
*
* @param function
* @param axesLocation
*/
public AxesLocation(BiFunction<Double, Double, Double> function, AxesLocation... axesLocation) {
location = new LinkedHashMap<>();
for (AxesLocation oneAxesLocation : axesLocation) {
Expand All @@ -121,17 +205,19 @@ public AxesLocation(BiFunction<Double, Double, Double> function, AxesLocation...
}
}
}
/**
* Create a new AxesLocation with the given function applied to the coordinates of axesLocation.
*
* @param function
* @param axesLocation
*/
public AxesLocation(Function<Double, Double> function, AxesLocation axesLocation) {
location = new LinkedHashMap<>();
for (Axis axis : axesLocation.getAxes()) {
location.put(axis, function.apply(axesLocation.getCoordinate(axis)));
}
}

final public static LengthUnit getUnits() {
return LengthUnit.Millimeters;
}

public AxesLocation add(AxesLocation other) {
return new AxesLocation((a, b) -> (a + b), this, other);
}
Expand Down Expand Up @@ -159,7 +245,7 @@ public AxesLocation drivenBy(Driver driver) {
}

/**
* Filter those axes from the AxesLocation that have one of the given types.
* Filter those axes from the AxesLocation that have one of the given Axis.Types.
*
* @param types
* @return
Expand Down Expand Up @@ -329,7 +415,7 @@ public String toString() {
}

/**
* Based on the mapped axes in this, substitute coordinates by type to convert a Location to
* Based on the mapped axes in this, substitute coordinates by Axis.Type to convert a Location to
* an AxisLocation. Used together with org.openpnp.spi.MovableMountable.getMappedAxes(Machine).
*
* @param location
Expand Down Expand Up @@ -444,7 +530,8 @@ public AxesLocation motionSegmentTo(AxesLocation location1) {
}

/**
* Returns the Euclidean metric i.e. the distance in N-dimensional space of the AxesLocation from the origin.
* Returns the Euclidean metric i.e. the distance in N-dimensional space of the AxesLocation from the origin
* i.e. treated as a vector.
*
* @return
*/
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/org/openpnp/spi/Axis.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
package org.openpnp.spi;

import org.openpnp.model.Identifiable;
import org.openpnp.model.Location;
import org.openpnp.model.Named;

/**
* An Axis can be any coordinate dimension, either a raw machine controller axis or a
* a Cartesian-coordinate or rotary axis to be transformed into a raw axis.
* a Cartesian linear coordinate dimension or a rotary coordinate dimension to be transformed
* into a raw axis. Furthermore there are virtual axes to store coordinate states.
*
*/
public interface Axis extends Identifiable, Named, WizardConfigurable, PropertySheetHolder {
public enum Type {
Expand All @@ -40,6 +41,4 @@ public enum Type {
public Type getType();

public void setType(Type type);

double getLocationAxisCoordinate(Location location);
}
11 changes: 9 additions & 2 deletions src/main/java/org/openpnp/spi/ControllerAxis.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

/**
* A ControllerAxis is an axis coordinate dimension as exposed by the machine's controller/driver.
* These can already be Cartesian-coordinate or rotary axes, or raw actuator axes to be transformed by a TransformedAxis.
* These can already be Cartesian linear or rotary axed, or raw actuator axes to be transformed by a TransformedAxis.
*/
public interface ControllerAxis extends LinearInputAxis, CoordinateAxis {
/**
Expand All @@ -43,7 +43,14 @@ public interface ControllerAxis extends LinearInputAxis, CoordinateAxis {
public String getLetter();

public void setLetter(String designator);


public LengthUnit getUnits();

/**
* @return The driver coordinate in length units as determined by getUnits(). This is the coordinate
* that was last sent to the controller. It may not yet reflect the physical machine position. Only
* after a MotionController.waitForCompletion() can you be sure that the machine is in sync.
*/
double getDriverCoordinate();

void setDriverCoordinate(double coordinate);
Expand Down
36 changes: 32 additions & 4 deletions src/main/java/org/openpnp/spi/CoordinateAxis.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,54 @@
package org.openpnp.spi;

import org.openpnp.model.Length;
import org.openpnp.model.LengthUnit;
import org.openpnp.model.Location;

/**
* A CoordinateAxis is an axis which can store a coordinate either physically or virtually.
*/

public interface CoordinateAxis extends Axis {
public LengthUnit getUnits();

/**
* @return The coordinate that was last sent to the MotionPlanner either through a moveTo() or other
* operations, such as homing.
*
* This coordinate may not yet be sent to the driver and even less likely reflect the
* physical machine position. Only after a waitForCompletion() on the MotionPlanner, can you be sure that
* the coordinate is in sync with the machine.
*
* The coordinate is always in AxesLocation.getUnits() i.e. in Millimeters.
*/
public double getCoordinate();

/**
* @return The coordinate that was last sent to the MotionPlanner either through a moveTo() or other
* operations, such as homing.
*
* This coordinate may not yet be sent to the driver and even less likely reflect the
* physical machine position. Only after a waitForCompletion() on the MotionPlanner, can you be sure that
* the coordinate is in sync with the machine.
*
* The coordinate is always in AxesLocation.getUnits() i.e. in Millimeters.
*/
public Length getLengthCoordinate();

public void setCoordinate(double coordinate);

public void setLengthCoordinate(Length coordinate);

/**
* @param coordinateA
* @param coordinateB
* @return Whether the coordinates match in their native unit length and resolution as
* determined by the sub-class and possibly by a driver.
*/
boolean coordinatesMatch(Length coordinateA, Length coordinateB);

/**
* @param coordinateA
* @param coordinateB
* @return Whether the coordinates match in their native unit length and resolution as
* determined by the sub-class and possibly by a driver.
*/
boolean coordinatesMatch(double coordinateA, double coordinateB);

public Length getHomeCoordinate();
Expand Down
24 changes: 23 additions & 1 deletion src/main/java/org/openpnp/spi/LinearInputAxis.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
/*
* Copyright (C) 2020 <mark@makr.zone>
* inspired and based on work
* Copyright (C) 2011 Jason von Nieda <jason@vonnieda.org>
*
* This file is part of OpenPnP.
*
* OpenPnP is free software: you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* OpenPnP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with OpenPnP. If not, see
* <http://www.gnu.org/licenses/>.
*
* For more information about OpenPnP visit http://openpnp.org
*/

package org.openpnp.spi;

/**
* A LinearInputAxis is either directly a controller axis or something transformed by one
* of the "mechanical" transformations. This Interface serves as the distinction, so only
* one top level linear transformation can be set up.
* one level of linear transformation can be set up.
*/
public interface LinearInputAxis extends Axis {

}

0 comments on commit ee29ca7

Please sign in to comment.