org.opentcs.util.persistence.v6.V6TOMapper Maven / Gradle / Ivy
The newest version!
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.util.persistence.v6;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.opentcs.access.to.model.BlockCreationTO;
import org.opentcs.access.to.model.BoundingBoxCreationTO;
import org.opentcs.access.to.model.CoupleCreationTO;
import org.opentcs.access.to.model.LocationCreationTO;
import org.opentcs.access.to.model.LocationTypeCreationTO;
import org.opentcs.access.to.model.PathCreationTO;
import org.opentcs.access.to.model.PlantModelCreationTO;
import org.opentcs.access.to.model.PointCreationTO;
import org.opentcs.access.to.model.VehicleCreationTO;
import org.opentcs.access.to.model.VisualLayoutCreationTO;
import org.opentcs.access.to.peripherals.PeripheralOperationCreationTO;
import org.opentcs.data.model.Block;
import org.opentcs.data.model.Couple;
import org.opentcs.data.model.Envelope;
import org.opentcs.data.model.Path;
import org.opentcs.data.model.Point;
import org.opentcs.data.model.Pose;
import org.opentcs.data.model.Triple;
import org.opentcs.data.model.visualization.Layer;
import org.opentcs.data.model.visualization.LayerGroup;
import org.opentcs.data.model.visualization.LocationRepresentation;
import org.opentcs.data.peripherals.PeripheralOperation;
import org.opentcs.util.Colors;
/**
* Provides methods for mapping {@link PlantModelCreationTO} to {@link V6PlantModelTO} and
* vice versa.
*/
public class V6TOMapper {
/**
* Creates a new instance.
*/
public V6TOMapper() {
}
/**
* Maps the given model to a {@link PlantModelCreationTO} instance.
*
* @param model The model to map.
* @return The mapped {@link PlantModelCreationTO} instance.
*/
public PlantModelCreationTO map(V6PlantModelTO model) {
return new PlantModelCreationTO(model.getName())
.withPoints(toPointCreationTO(model.getPoints()))
.withVehicles(toVehicleCreationTO(model.getVehicles()))
.withPaths(toPathCreationTO(model.getPaths()))
.withLocationTypes(toLocationTypeCreationTO(model.getLocationTypes()))
.withLocations(toLocationCreationTO(model.getLocations()))
.withBlocks(toBlockCreationTO(model.getBlocks()))
.withVisualLayout(toVisualLayoutCreationTO(model.getVisualLayout()))
.withProperties(convertProperties(model.getProperties()));
}
/**
* Maps the given model to a {@link V6PlantModelTO} instance.
*
* @param model The model to map.
* @return The mapped {@link V6PlantModelTO} instance.
*/
public V6PlantModelTO map(PlantModelCreationTO model) {
V6PlantModelTO result = new V6PlantModelTO();
result.setName(model.getName());
result.setVersion(V6PlantModelTO.VERSION_STRING);
result.getPoints().addAll(toPointTO(model.getPoints(), model.getPaths()));
result.getVehicles().addAll(toVehicleTO(model.getVehicles()));
result.getPaths().addAll(toPathTO(model.getPaths()));
result.getLocationTypes().addAll(toLocationTypeTO(model.getLocationTypes()));
result.getLocations().addAll(toLocationTO(model.getLocations()));
result.getBlocks().addAll(toBlockTO(model.getBlocks()));
result.setVisualLayout(toVisualLayoutTO(model.getVisualLayout()));
result.getProperties().addAll(convertProperties(model.getProperties()));
return result;
}
//Methods for mapping from PlantModelElementTO to CreationTO start here.
private List toPointCreationTO(List points) {
List result = new ArrayList<>();
for (PointTO point : points) {
result.add(
new PointCreationTO(point.getName())
.withPose(
new Pose(
new Triple(point.getPositionX(), point.getPositionY(), point.getPositionZ()),
point.getVehicleOrientationAngle().doubleValue()
)
)
.withType(Point.Type.valueOf(point.getType()))
.withVehicleEnvelopes(toEnvelopeMap(point.getVehicleEnvelopes()))
.withMaxVehicleBoundingBox(toBoundingBoxCreationTO(point.getMaxVehicleBoundingBox()))
.withProperties(convertProperties(point.getProperties()))
.withLayout(
new PointCreationTO.Layout(
new Couple(
point.getPointLayout().getPositionX(),
point.getPointLayout().getPositionY()
),
new Couple(
point.getPointLayout().getLabelOffsetX(),
point.getPointLayout().getLabelOffsetY()
),
point.getPointLayout().getLayerId()
)
)
);
}
return result;
}
private List toVehicleCreationTO(List vehicles) {
List result = new ArrayList<>();
for (VehicleTO vehicle : vehicles) {
result.add(
new VehicleCreationTO(vehicle.getName())
.withBoundingBox(toBoundingBoxCreationTO(vehicle.getBoundingBox()))
.withEnergyLevelThresholdSet(toEnergyLevelThresholdSetCreationTO(vehicle))
.withMaxReverseVelocity(vehicle.getMaxReverseVelocity())
.withMaxVelocity(vehicle.getMaxVelocity())
.withEnvelopeKey(vehicle.getEnvelopeKey())
.withProperties(convertProperties(vehicle.getProperties()))
.withLayout(
new VehicleCreationTO.Layout(
Colors.decodeFromHexRGB(vehicle.getVehicleLayout().getColor())
)
)
);
}
return result;
}
private List toPathCreationTO(List paths) {
List result = new ArrayList<>();
for (PathTO path : paths) {
result.add(
new PathCreationTO(
path.getName(),
path.getSourcePoint(),
path.getDestinationPoint()
)
.withLength(path.getLength())
.withLocked(path.isLocked())
.withMaxVelocity(path.getMaxVelocity().intValue())
.withMaxReverseVelocity(path.getMaxReverseVelocity().intValue())
.withPeripheralOperations(
toPeripheralOperationCreationTOs(path.getPeripheralOperations())
)
.withVehicleEnvelopes(toEnvelopeMap(path.getVehicleEnvelopes()))
.withProperties(convertProperties(path.getProperties()))
.withLayout(
new PathCreationTO.Layout(
Path.Layout.ConnectionType.valueOf(path.getPathLayout().getConnectionType()),
path.getPathLayout().getControlPoints().stream()
.map(controlPoint -> new Couple(controlPoint.getX(), controlPoint.getY()))
.toList(),
path.getPathLayout().getLayerId()
)
)
);
}
return result;
}
private List toPeripheralOperationCreationTOs(
List tos
) {
return tos.stream()
.map(
to -> new PeripheralOperationCreationTO(to.getName(), to.getLocationName())
.withExecutionTrigger(
PeripheralOperation.ExecutionTrigger.valueOf(to.getExecutionTrigger())
)
.withCompletionRequired(to.isCompletionRequired())
)
.toList();
}
private List toLocationTypeCreationTO(
List locationTypes
) {
List result = new ArrayList<>();
for (LocationTypeTO locationType : locationTypes) {
result.add(
new LocationTypeCreationTO(locationType.getName())
.withAllowedOperations(getOperationNames(locationType.getAllowedOperations()))
.withAllowedPeripheralOperations(
getPeripheralOperationNames(
locationType.getAllowedPeripheralOperations()
)
)
.withProperties(convertProperties(locationType.getProperties()))
.withLayout(
new LocationTypeCreationTO.Layout(
LocationRepresentation.valueOf(
locationType.getLocationTypeLayout().getLocationRepresentation()
)
)
)
);
}
return result;
}
private List toLocationCreationTO(List locations) {
List result = new ArrayList<>();
for (LocationTO location : locations) {
result.add(
new LocationCreationTO(
location.getName(),
location.getType(),
new Triple(
location.getPositionX(),
location.getPositionY(),
location.getPositionZ()
)
)
.withLinks(getLinks(location))
.withLocked(location.isLocked())
.withProperties(convertProperties(location.getProperties()))
.withLayout(
new LocationCreationTO.Layout(
new Couple(
location.getLocationLayout().getPositionX(),
location.getLocationLayout().getPositionY()
),
new Couple(
location.getLocationLayout().getLabelOffsetX(),
location.getLocationLayout().getLabelOffsetY()
),
LocationRepresentation.valueOf(
location.getLocationLayout().getLocationRepresentation()
),
location.getLocationLayout().getLayerId()
)
)
);
}
return result;
}
private List toBlockCreationTO(List blocks) {
List result = new ArrayList<>();
for (BlockTO block : blocks) {
result.add(
new BlockCreationTO(block.getName())
.withType(Block.Type.valueOf(block.getType()))
.withMemberNames(
block.getMembers().stream()
.map(member -> member.getName())
.collect(Collectors.toSet())
)
.withProperties(convertProperties(block.getProperties()))
.withLayout(
new BlockCreationTO.Layout(
Colors.decodeFromHexRGB(block.getBlockLayout().getColor())
)
)
);
}
return result;
}
private VisualLayoutCreationTO toVisualLayoutCreationTO(VisualLayoutTO visualLayout) {
return new VisualLayoutCreationTO(visualLayout.getName())
.withScaleX(visualLayout.getScaleX())
.withScaleY(visualLayout.getScaleY())
.withLayers(convertLayers(visualLayout.getLayers()))
.withLayerGroups(convertLayerGroups(visualLayout.getLayerGroups()))
.withProperties(convertProperties(visualLayout.getProperties()));
}
private List convertLayers(List layers) {
List result = new ArrayList<>();
for (VisualLayoutTO.Layer layer : layers) {
result.add(
new Layer(
layer.getId(),
layer.getOrdinal(),
layer.isVisible(),
layer.getName(),
layer.getGroupId()
)
);
}
return result;
}
private List convertLayerGroups(List layerGroups) {
List result = new ArrayList<>();
for (VisualLayoutTO.LayerGroup layerGroup : layerGroups) {
result.add(
new LayerGroup(
layerGroup.getId(),
layerGroup.getName(),
layerGroup.isVisible()
)
);
}
return result;
}
private Map convertProperties(List propsList) {
Map result = new HashMap<>();
for (PropertyTO property : propsList) {
String propName
= isNullOrEmpty(property.getName()) ? "Property unknown" : property.getName();
String propValue
= isNullOrEmpty(property.getValue()) ? "Value unknown" : property.getValue();
result.put(propName, propValue);
}
return result;
}
private List getOperationNames(List ops) {
List result = new ArrayList<>(ops.size());
for (AllowedOperationTO operation : ops) {
result.add(operation.getName());
}
return result;
}
private List getPeripheralOperationNames(List ops) {
List result = new ArrayList<>(ops.size());
for (AllowedPeripheralOperationTO operation : ops) {
result.add(operation.getName());
}
return result;
}
private Map> getLinks(LocationTO to) {
Map> result = new HashMap<>();
for (LocationTO.Link linkTO : to.getLinks()) {
result.put(
linkTO.getPoint(),
new HashSet<>(getOperationNames(linkTO.getAllowedOperations()))
);
}
return result;
}
//Methods for mapping from CreationTO to PlantModelElementTO start here.
private List toPointTO(List points, List paths) {
List result = new ArrayList<>();
for (PointCreationTO point : points) {
PointTO pointTO = new PointTO();
pointTO.setName(point.getName());
pointTO.setPositionX(point.getPose().getPosition().getX())
.setPositionY(point.getPose().getPosition().getY())
.setVehicleOrientationAngle((float) point.getPose().getOrientationAngle())
.setType(point.getType().name())
.setOutgoingPaths(getOutgoingPaths(point, paths))
.setVehicleEnvelopes(toVehicleEnvelopeTOs(point.getVehicleEnvelopes()))
.setMaxVehicleBoundingBox(toBoundingBoxTO(point.getMaxVehicleBoundingBox()))
.setPointLayout(
new PointTO.PointLayout()
.setPositionX(point.getLayout().getPosition().getX())
.setPositionY(point.getLayout().getPosition().getY())
.setLabelOffsetX(point.getLayout().getLabelOffset().getX())
.setLabelOffsetY(point.getLayout().getLabelOffset().getY())
.setLayerId(point.getLayout().getLayerId())
)
.setProperties(convertProperties(point.getProperties()));
result.add(pointTO);
}
Collections.sort(result, Comparators.elementsByName());
return result;
}
private List toVehicleTO(List vehicles) {
List result = new ArrayList<>();
for (VehicleCreationTO vehicle : vehicles) {
VehicleTO vehicleTO = new VehicleTO();
vehicleTO.setName(vehicle.getName());
vehicleTO.setBoundingBox(toBoundingBoxTO(vehicle.getBoundingBox()))
.setMaxVelocity(vehicle.getMaxVelocity())
.setMaxReverseVelocity(vehicle.getMaxReverseVelocity())
.setEnergyLevelGood((long) vehicle.getEnergyLevelThresholdSet().getEnergyLevelGood())
.setEnergyLevelCritical(
(long) vehicle.getEnergyLevelThresholdSet().getEnergyLevelCritical()
)
.setEnergyLevelFullyRecharged(
(long) vehicle.getEnergyLevelThresholdSet().getEnergyLevelFullyRecharged()
)
.setEnergyLevelSufficientlyRecharged(
(long) vehicle.getEnergyLevelThresholdSet().getEnergyLevelSufficientlyRecharged()
)
.setEnvelopeKey(vehicle.getEnvelopeKey())
.setVehicleLayout(
new VehicleTO.VehicleLayout()
.setColor(Colors.encodeToHexRGB(vehicle.getLayout().getRouteColor()))
)
.setProperties(convertProperties(vehicle.getProperties()));
result.add(vehicleTO);
}
Collections.sort(result, Comparators.elementsByName());
return result;
}
private List toPathTO(List paths) {
List result = new ArrayList<>();
for (PathCreationTO path : paths) {
PathTO pathTO = new PathTO();
pathTO.setName(path.getName());
pathTO.setSourcePoint(path.getSrcPointName())
.setDestinationPoint(path.getDestPointName())
.setLength(path.getLength())
.setMaxVelocity((long) path.getMaxVelocity())
.setMaxReverseVelocity((long) path.getMaxReverseVelocity())
.setPeripheralOperations(toPeripheralOperationTOs(path.getPeripheralOperations()))
.setLocked(path.isLocked())
.setVehicleEnvelopes(toVehicleEnvelopeTOs(path.getVehicleEnvelopes()))
.setPathLayout(
new PathTO.PathLayout()
.setConnectionType(path.getLayout().getConnectionType().name())
.setControlPoints(
path.getLayout().getControlPoints().stream()
.map(controlPoint -> {
return new PathTO.ControlPoint()
.setX(controlPoint.getX())
.setY(controlPoint.getY());
})
.toList()
)
.setLayerId(path.getLayout().getLayerId())
)
.setProperties(convertProperties(path.getProperties()));
result.add(pathTO);
}
Collections.sort(result, Comparators.elementsByName());
return result;
}
private List toPeripheralOperationTOs(
List tos
) {
return tos.stream()
.map(
to -> (PeripheralOperationTO) new PeripheralOperationTO()
.setLocationName(to.getLocationName())
.setExecutionTrigger(to.getExecutionTrigger().name())
.setCompletionRequired(to.isCompletionRequired())
.setName(to.getOperation())
)
.toList();
}
private List toLocationTypeTO(
List locationTypes
) {
List result = new ArrayList<>();
for (LocationTypeCreationTO locationType : locationTypes) {
LocationTypeTO locationTypeTO = new LocationTypeTO();
locationTypeTO.setName(locationType.getName());
locationTypeTO.setAllowedOperations(
toAllowedOperationTOs(locationType.getAllowedOperations())
)
.setAllowedPeripheralOperations(
toAllowedPeripheralOperationTOs(locationType.getAllowedPeripheralOperations())
)
.setLocationTypeLayout(
new LocationTypeTO.LocationTypeLayout()
.setLocationRepresentation(
locationType.getLayout().getLocationRepresentation().name()
)
)
.setProperties(convertProperties(locationType.getProperties()));
result.add(locationTypeTO);
}
Collections.sort(result, Comparators.elementsByName());
return result;
}
private List toLocationTO(List locations) {
List result = new ArrayList<>();
for (LocationCreationTO location : locations) {
LocationTO locationTO = new LocationTO();
locationTO.setName(location.getName());
locationTO.setPositionX(location.getPosition().getX())
.setPositionY(location.getPosition().getY())
.setType(location.getTypeName())
.setLinks(toLocationTOLinks(location.getLinks()))
.setLocked(location.isLocked())
.setLocationLayout(
new LocationTO.LocationLayout()
.setPositionX(location.getLayout().getPosition().getX())
.setPositionY(location.getLayout().getPosition().getY())
.setLabelOffsetX(location.getLayout().getLabelOffset().getX())
.setLabelOffsetY(location.getLayout().getLabelOffset().getY())
.setLocationRepresentation(
location.getLayout().getLocationRepresentation().name()
)
.setLayerId(location.getLayout().getLayerId())
)
.setProperties(convertProperties(location.getProperties()));
result.add(locationTO);
}
Collections.sort(result, Comparators.elementsByName());
return result;
}
private List toBlockTO(List blocks) {
List result = new ArrayList<>();
for (BlockCreationTO block : blocks) {
BlockTO blockTO = new BlockTO();
blockTO.setName(block.getName());
blockTO.setType(block.getType().name())
.setMembers(toMemberTOs(block.getMemberNames()))
.setBlockLayout(
new BlockTO.BlockLayout()
.setColor(Colors.encodeToHexRGB(block.getLayout().getColor()))
)
.setProperties(convertProperties(block.getProperties()));
result.add(blockTO);
}
Collections.sort(result, Comparators.elementsByName());
return result;
}
private VisualLayoutTO toVisualLayoutTO(VisualLayoutCreationTO layout) {
VisualLayoutTO result = new VisualLayoutTO();
result.setName(layout.getName())
.setProperties(convertProperties(layout.getProperties()));
result.setScaleX((float) layout.getScaleX())
.setScaleY((float) layout.getScaleY())
.setLayers(toLayerTOs(layout.getLayers()))
.setLayerGroups(toLayerGroupTOs(layout.getLayerGroups()));
return result;
}
private List toLayerTOs(List layers) {
List result = new ArrayList<>();
for (Layer layer : layers) {
result.add(
new VisualLayoutTO.Layer()
.setId(layer.getId())
.setOrdinal(layer.getOrdinal())
.setVisible(layer.isVisible())
.setName(layer.getName())
.setGroupId(layer.getGroupId())
);
}
return result;
}
private List toLayerGroupTOs(List layerGroups) {
List result = new ArrayList<>();
for (LayerGroup layerGroup : layerGroups) {
result.add(
new VisualLayoutTO.LayerGroup()
.setId(layerGroup.getId())
.setName(layerGroup.getName())
.setVisible(layerGroup.isVisible())
);
}
return result;
}
private List getOutgoingPaths(
PointCreationTO point,
List paths
) {
List result = new ArrayList<>();
for (PathCreationTO path : paths) {
if (Objects.equals(path.getSrcPointName(), point.getName())) {
result.add(new PointTO.OutgoingPath().setName(path.getName()));
}
}
Collections.sort(result, Comparators.outgoingPathsByName());
return result;
}
private List toAllowedOperationTOs(Collection allowedOperations) {
return allowedOperations.stream()
.sorted()
.map(allowedOperation -> {
return (AllowedOperationTO) new AllowedOperationTO().setName(allowedOperation);
})
.toList();
}
private List toAllowedPeripheralOperationTOs(
Collection allowedOperations
) {
return allowedOperations.stream()
.sorted()
.map(allowedOperation -> {
return (AllowedPeripheralOperationTO) new AllowedPeripheralOperationTO()
.setName(allowedOperation);
})
.toList();
}
private List toLocationTOLinks(Map> links) {
List result = new ArrayList<>();
links.forEach((key, value) -> {
result.add(
new LocationTO.Link()
.setPoint(key)
.setAllowedOperations(toAllowedOperationTOs(value))
);
});
Collections.sort(result, Comparators.linksByPointName());
return result;
}
private List toMemberTOs(Collection members) {
return members.stream()
.map(member -> (MemberTO) new MemberTO().setName(member))
.sorted(Comparators.elementsByName())
.toList();
}
private List convertProperties(Map properties) {
List result = new ArrayList<>();
properties.forEach((key, value) -> {
result.add(new PropertyTO().setName(key).setValue(value));
});
Collections.sort(result, Comparators.propertiesByName());
return result;
}
private boolean isNullOrEmpty(String s) {
return s == null || s.isEmpty();
}
private Map toEnvelopeMap(List envelopeTOs) {
return envelopeTOs.stream()
.collect(
Collectors.toMap(
VehicleEnvelopeTO::getKey,
vehicleEnvelopeTO -> toEnvelope(vehicleEnvelopeTO)
)
);
}
private Envelope toEnvelope(VehicleEnvelopeTO vehicleEnvelopeTO) {
return new Envelope(
vehicleEnvelopeTO.getVertices().stream()
.map(coupleTO -> new Couple(coupleTO.getX(), coupleTO.getY()))
.toList()
);
}
private List toVehicleEnvelopeTOs(Map envelopeMap) {
return envelopeMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.map(
entry -> new VehicleEnvelopeTO()
.setKey(entry.getKey())
.setVertices(toCoupleTOs(entry.getValue().getVertices()))
)
.toList();
}
private List toCoupleTOs(List couples) {
return couples.stream()
.map(
couple -> new CoupleTO()
.setX(couple.getX())
.setY(couple.getY())
)
.toList();
}
private BoundingBoxCreationTO toBoundingBoxCreationTO(BoundingBoxTO boundingBox) {
return new BoundingBoxCreationTO(
boundingBox.getLength(),
boundingBox.getWidth(),
boundingBox.getHeight()
)
.withReferenceOffset(
new CoupleCreationTO(
boundingBox.getReferenceOffsetX(),
boundingBox.getReferenceOffsetY()
)
);
}
private VehicleCreationTO.EnergyLevelThresholdSet toEnergyLevelThresholdSetCreationTO(
VehicleTO vehicle
) {
return new VehicleCreationTO.EnergyLevelThresholdSet(
vehicle.getEnergyLevelCritical().intValue(),
vehicle.getEnergyLevelGood().intValue(),
vehicle.getEnergyLevelSufficientlyRecharged().intValue(),
vehicle.getEnergyLevelFullyRecharged().intValue()
);
}
private BoundingBoxTO toBoundingBoxTO(BoundingBoxCreationTO boundingBox) {
return new BoundingBoxTO()
.setLength(boundingBox.getLength())
.setWidth(boundingBox.getWidth())
.setHeight(boundingBox.getHeight())
.setReferenceOffsetX(boundingBox.getReferenceOffset().getX())
.setReferenceOffsetY(boundingBox.getReferenceOffset().getY());
}
}