org.opentcs.data.model.Path Maven / Gradle / Ivy
/**
* Copyright (c) The openTCS Authors.
*
* This program is free software and subject to the MIT license. (For details,
* see the licensing information (LICENSE.txt) you should have received with
* this copy of the software.)
*/
package org.opentcs.data.model;
import static java.util.Objects.requireNonNull;
import static org.opentcs.util.Assertions.checkInRange;
import jakarta.annotation.Nonnull;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.opentcs.data.ObjectHistory;
import org.opentcs.data.TCSObject;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.peripherals.PeripheralOperation;
/**
* Describes a connection between two {@link Point}s which a {@link Vehicle} may traverse.
*/
public class Path
extends
TCSResource
implements
Serializable {
/**
* A reference to the point which this point originates in.
*/
private final TCSObjectReference sourcePoint;
/**
* A reference to the point which this point ends in.
*/
private final TCSObjectReference destinationPoint;
/**
* The length of this path (in mm).
*/
private final long length;
/**
* The absolute maximum allowed forward velocity on this path (in mm/s).
* A value of 0 (default) means forward movement is not allowed on this path.
*/
private final int maxVelocity;
/**
* The absolute maximum allowed reverse velocity on this path (in mm/s).
* A value of 0 (default) means reverse movement is not allowed on this path.
*/
private final int maxReverseVelocity;
/**
* The peripheral operations to be performed when a vehicle travels along this path.
*/
private final List peripheralOperations;
/**
* A flag for marking this path as locked (i.e. to prevent vehicles from using it).
*/
private final boolean locked;
/**
* A map of envelope keys to envelopes that vehicles traversing this path may occupy.
*/
private final Map vehicleEnvelopes;
/**
* The information regarding the grahical representation of this path.
*/
private final Layout layout;
/**
* Creates a new Path.
*
* @param name The new path's name.
* @param sourcePoint A reference to this path's starting point.
* @param destinationPoint A reference to this path's destination point.
*/
public Path(
String name,
TCSObjectReference sourcePoint,
TCSObjectReference destinationPoint
) {
super(name);
this.sourcePoint = requireNonNull(sourcePoint, "sourcePoint");
this.destinationPoint = requireNonNull(destinationPoint, "destinationPoint");
this.length = 1;
this.maxVelocity = 1000;
this.maxReverseVelocity = 1000;
this.peripheralOperations = List.of();
this.locked = false;
this.vehicleEnvelopes = Map.of();
this.layout = new Layout();
}
private Path(
String name,
Map properties,
ObjectHistory history,
TCSObjectReference sourcePoint,
TCSObjectReference destinationPoint,
long length,
int maxVelocity,
int maxReverseVelocity,
List peripheralOperations,
boolean locked,
Map vehicleEnvelopes,
Layout layout
) {
super(name, properties, history);
this.sourcePoint = requireNonNull(sourcePoint, "sourcePoint");
this.destinationPoint = requireNonNull(destinationPoint, "destinationPoint");
this.length = checkInRange(length, 1, Long.MAX_VALUE, "length");
this.maxVelocity = checkInRange(maxVelocity, 0, Integer.MAX_VALUE, "maxVelocity");
this.maxReverseVelocity = checkInRange(
maxReverseVelocity,
0,
Integer.MAX_VALUE,
"maxReverseVelocity"
);
this.peripheralOperations = new ArrayList<>(
requireNonNull(
peripheralOperations,
"peripheralOperations"
)
);
this.locked = locked;
this.vehicleEnvelopes = requireNonNull(vehicleEnvelopes, "vehicleEnvelopes");
this.layout = requireNonNull(layout, "layout");
}
@Override
public Path withProperty(String key, String value) {
return new Path(
getName(),
propertiesWith(key, value),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
@Override
public Path withProperties(Map properties) {
return new Path(
getName(),
properties,
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
@Override
public TCSObject withHistoryEntry(ObjectHistory.Entry entry) {
return new Path(
getName(),
getProperties(),
getHistory().withEntryAppended(entry),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
@Override
public TCSObject withHistory(ObjectHistory history) {
return new Path(
getName(),
getProperties(),
history,
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Return the length of this path (in mm).
*
* @return The length of this path (in mm).
*/
public long getLength() {
return length;
}
/**
* Creates a copy of this object, with the given length.
*
* @param length The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withLength(long length) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Returns a reference to the point which this path originates in.
*
* @return A reference to the point which this path originates in.
*/
public TCSObjectReference getSourcePoint() {
return sourcePoint;
}
/**
* Returns a reference to the point which this path ends in.
*
* @return A reference to the point which this path ends in.
*/
public TCSObjectReference getDestinationPoint() {
return destinationPoint;
}
/**
* Return the maximum allowed forward velocity (in mm/s) for this path.
*
* @return The maximum allowed forward velocity (in mm/s). A value of 0 means
* forward movement is not allowed on this path.
*/
public int getMaxVelocity() {
return maxVelocity;
}
/**
* Creates a copy of this object, with the given maximum velocity.
*
* @param maxVelocity The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withMaxVelocity(int maxVelocity) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Return the maximum allowed reverse velocity (in mm/s) for this path.
*
* @return The maximum allowed reverse velocity (in mm/s). A value of 0 means
* reverse movement is not allowed on this path.
*/
public int getMaxReverseVelocity() {
return maxReverseVelocity;
}
/**
* Creates a copy of this object, with the given maximum reverse velocity.
*
* @param maxReverseVelocity The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withMaxReverseVelocity(int maxReverseVelocity) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Returns the peripheral operations to be performed when a vehicle travels along this path.
*
* @return The peripheral operations to be performed when a vehicle travels along this path.
*/
public List getPeripheralOperations() {
return Collections.unmodifiableList(peripheralOperations);
}
/**
* Creates a copy of this object, with the given peripheral operations.
*
* @param peripheralOperations The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withPeripheralOperations(
@Nonnull
List peripheralOperations
) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Return the lock status of this path (i.e. whether this path my be used by
* vehicles or not).
*
* @return true
if this path is currently locked (i.e. it may not
* be used by vehicles), else false
.
*/
public boolean isLocked() {
return locked;
}
/**
* Creates a copy of this object, with the given locked flag.
*
* @param locked The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withLocked(boolean locked) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Returns a map of envelope keys to envelopes that vehicles traversing this path may occupy.
*
* @return A map of envelope keys to envelopes that vehicles traversing this path may occupy.
*/
public Map getVehicleEnvelopes() {
return vehicleEnvelopes;
}
/**
*
* Creates a copy of this object, with the given vehicle envelopes.
*
* @param vehicleEnvelopes The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withVehicleEnvelopes(Map vehicleEnvelopes) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Returns the information regarding the grahical representation of this path.
*
* @return The information regarding the grahical representation of this path.
*/
public Layout getLayout() {
return layout;
}
/**
* Creates a copy of this object, with the given layout.
*
* @param layout The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Path withLayout(Layout layout) {
return new Path(
getName(),
getProperties(),
getHistory(),
sourcePoint,
destinationPoint,
length,
maxVelocity,
maxReverseVelocity,
peripheralOperations,
locked,
vehicleEnvelopes,
layout
);
}
/**
* Checks whether this path is navigable in forward direction.
*
* @return true
if, and only if, this path is not locked and its
* maximum forward velocity is not zero.
*/
public boolean isNavigableForward() {
return !locked && maxVelocity != 0;
}
/**
* Checks whether this path is navigable in backward/reverse direction.
*
* @return true
if, and only if, this path is not locked and its
* maximum reverse velocity is not zero.
*/
public boolean isNavigableReverse() {
return !locked && maxReverseVelocity != 0;
}
/**
* Checks whether this path is navigable towards the given point.
*
* @param navPoint The point.
* @return If navPoint
is this path's destination point, returns
* isNavigableForward()
; if navPoint
is this path's
* source point, returns isNavigableReverse()
.
* @throws IllegalArgumentException If the given point is neither the source
* point nor the destination point of this path.
*/
public boolean isNavigableTo(TCSObjectReference navPoint)
throws IllegalArgumentException {
if (Objects.equals(navPoint, destinationPoint)) {
return isNavigableForward();
}
else if (Objects.equals(navPoint, sourcePoint)) {
return isNavigableReverse();
}
else {
throw new IllegalArgumentException(navPoint + " is not an end point of " + this);
}
}
/**
* Contains information regarding the grahical representation of a path.
*/
public static class Layout
implements
Serializable {
/**
* The connection type the path is represented as.
*/
private final ConnectionType connectionType;
/**
* Control points describing the way the path is drawn (if the connection type
* is {@link ConnectionType#BEZIER}, {@link ConnectionType#BEZIER_3}
* or {@link ConnectionType#POLYPATH}).
*/
private final List controlPoints;
/**
* The ID of the layer on which the path is to be drawn.
*/
private final int layerId;
/**
* Creates a new instance.
*/
public Layout() {
this(ConnectionType.DIRECT, new ArrayList<>(), 0);
}
/**
* Creates a new instance.
*
* @param connectionType The connection type a path is represented as.
* @param controlPoints Control points describing the way the path is drawn.
* @param layerId The ID of the layer on which the path is to be drawn.
*/
public Layout(ConnectionType connectionType, List controlPoints, int layerId) {
this.connectionType = connectionType;
this.controlPoints = requireNonNull(controlPoints, "controlPoints");
this.layerId = layerId;
}
/**
* Returns the connection type the path is represented as.
*
* @return The connection type the path is represented as.
*/
public ConnectionType getConnectionType() {
return connectionType;
}
/**
* Creates a copy of this object, with the given connection type.
*
* @param connectionType The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Layout withConnectionType(ConnectionType connectionType) {
return new Layout(connectionType, controlPoints, layerId);
}
/**
* Returns the control points describing the way the path is drawn.
* Returns an empty list if connection type is not {@link ConnectionType#BEZIER},
* {@link ConnectionType#BEZIER_3} or {@link ConnectionType#POLYPATH}.
*
* @return The control points describing the way the path is drawn.
*/
public List getControlPoints() {
return Collections.unmodifiableList(controlPoints);
}
/**
* Creates a copy of this object, with the given control points.
*
* @param controlPoints The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Layout withControlPoints(List controlPoints) {
return new Layout(connectionType, controlPoints, layerId);
}
/**
* Returns the ID of the layer on which the path is to be drawn.
*
* @return The layer ID.
*/
public int getLayerId() {
return layerId;
}
/**
* Creates a copy of this object, with the given layer ID.
*
* @param layerId The value to be set in the copy.
* @return A copy of this object, differing in the given value.
*/
public Layout withLayer(int layerId) {
return new Layout(connectionType, controlPoints, layerId);
}
/**
* The connection type a path is represented as.
*/
public enum ConnectionType {
/**
* A direct connection.
*/
DIRECT,
/**
* An elbow connection.
*/
ELBOW,
/**
* A slanted connection.
*/
SLANTED,
/**
* A polygon path with any number of vertecies.
*/
POLYPATH,
/**
* A bezier curve with 2 control points.
*/
BEZIER,
/**
* A bezier curve with 3 control points.
*/
BEZIER_3;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy