This commit is contained in:
xuzhiheng 2025-06-24 09:59:47 +08:00
parent 2be7b938c2
commit 6d96ea6891
5 changed files with 198 additions and 8 deletions

View File

@ -32,6 +32,7 @@ import org.opentcs.kernel.extensions.servicewebapi.KernelExecutorWrapper;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetOrderSequenceResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetOrderSequenceResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetTransportOrderResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetTransportOrderResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostOrderSequenceRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostOrderSequenceRequestTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTransportOrderInfoRequestTo;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTransportOrderRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTransportOrderRequestTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.posttransportorder.Destination; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.posttransportorder.Destination;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.shared.Property; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.shared.Property;
@ -59,6 +60,52 @@ public class TransportOrderHandler {
this.executorWrapper = requireNonNull(executorWrapper, "executorWrapper"); this.executorWrapper = requireNonNull(executorWrapper, "executorWrapper");
} }
/**
* 根据WMS任务创建订单序列和运输订单
* @param sequenceName 序列名称
* @param vehicleName 车辆名称
* @param type 订单类型
* @param destinations 位置信息
* @return 创建的订单
*/
public List<TransportOrder> createWmsTask(String sequenceName, String vehicleName, String type, List<PostTransportOrderInfoRequestTo> destinations){
//构建订单序列对象
PostOrderSequenceRequestTO postOrderSequenceRequestTO = new PostOrderSequenceRequestTO();
postOrderSequenceRequestTO.setIncompleteName(false);
postOrderSequenceRequestTO.setType(type);
postOrderSequenceRequestTO.setIntendedVehicle(vehicleName);
postOrderSequenceRequestTO.setFailureFatal(true);
//根据传入name创建订单序列
this.createOrderSequence(sequenceName, postOrderSequenceRequestTO);
//构建订单对象
PostTransportOrderRequestTO postTransportOrderRequestTO = new PostTransportOrderRequestTO();
postTransportOrderRequestTO.setIncompleteName(true);
postTransportOrderRequestTO.setDispensable(false);
postTransportOrderRequestTO.setDeadline(Instant.now());
postTransportOrderRequestTO.setIntendedVehicle(vehicleName);
// postTransportOrderRequestTO.setPeripheralReservationToken("");
postTransportOrderRequestTO.setWrappingSequence(sequenceName);
postTransportOrderRequestTO.setType(type);
List<TransportOrder> orders = new ArrayList<>();
//根据传入点位创建订单
for (PostTransportOrderInfoRequestTo destination : destinations) {
List<Destination> destinationsList = new ArrayList<>();
Destination newDestination = new Destination();
newDestination.setLocationName(destination.getLocationName());
newDestination.setOperation(destination.getOperation());
destinationsList.add(newDestination);
postTransportOrderRequestTO.setDestinations(destinationsList);
TransportOrder order = this.createOrder("", postTransportOrderRequestTO);
orders.add(order);
}
return orders;
}
public TransportOrder createOrder(String name, PostTransportOrderRequestTO order) public TransportOrder createOrder(String name, PostTransportOrderRequestTO order)
throws ObjectUnknownException, throws ObjectUnknownException,
ObjectExistsException, ObjectExistsException,

View File

@ -4,6 +4,7 @@ package org.opentcs.kernel.extensions.servicewebapi.v1;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.alibaba.fastjson.JSON;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -16,13 +17,12 @@ import org.opentcs.kernel.extensions.servicewebapi.RequestHandler;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetOrderSequenceResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetOrderSequenceResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetPeripheralAttachmentInfoResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetPeripheralAttachmentInfoResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetPeripheralJobResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetPeripheralJobResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetTransportOrderResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetVehicleAttachmentInfoResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetVehicleAttachmentInfoResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PlantModelTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PlantModelTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostOrderSequenceRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostOrderSequenceRequestTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostPeripheralJobRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostPeripheralJobRequestTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTopologyUpdateRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTopologyUpdateRequestTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTransportOrderRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostTransportOrderInfoRequestTo;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostVehicleRoutesRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostVehicleRoutesRequestTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostVehicleRoutesResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostVehicleRoutesResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PutVehicleAllowedOrderTypesTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PutVehicleAllowedOrderTypesTO;
@ -370,14 +370,44 @@ public class V1RequestHandler
IllegalArgumentException, IllegalArgumentException,
IllegalStateException { IllegalStateException {
response.type(HttpConstants.CONTENT_TYPE_APPLICATION_JSON_UTF8); response.type(HttpConstants.CONTENT_TYPE_APPLICATION_JSON_UTF8);
//解析data
String type = JSON.parseObject(request.body()).getString("type");
String destinations = JSON.parseObject(request.body()).getString("destinations");
List<PostTransportOrderInfoRequestTo> dataList = JSON.parseArray(destinations, PostTransportOrderInfoRequestTo.class);
//获取路由成本最低的车辆
String executeVehicle = vehicleHandler.getExecuteVehicle(dataList.getFirst().getPoint(), dataList.getLast().getPoint());
System.out.println("handlePostTransportOrder: " + executeVehicle);
//定制逻辑
return jsonBinder.toJson( return jsonBinder.toJson(
GetTransportOrderResponseTO.fromTransportOrder( transportOrderHandler.createWmsTask(
transportOrderHandler.createOrder( request.params(":NAME"),
request.params(":NAME"), executeVehicle,
jsonBinder.fromJson(request.body(), PostTransportOrderRequestTO.class) type,
) dataList
) )
); );
// return jsonBinder.toJson(
// transportOrderHandler.getTransportOrders(
// transportOrderHandler.createWmsTask(
// request.params(":NAME"),
// executeVehicle,
// type,
// dataList
// )
// )
// );
// return jsonBinder.toJson(
// GetTransportOrderResponseTO.fromTransportOrder(
// transportOrderHandler.createOrder(
// request.params(":NAME"),
// jsonBinder.fromJson(request.body(), PostTransportOrderRequestTO.class)
// )
// )
// );
} }
private Object handlePutTransportOrderIntendedVehicle(Request request, Response response) private Object handlePutTransportOrderIntendedVehicle(Request request, Response response)

View File

@ -28,6 +28,7 @@ import org.opentcs.data.model.Vehicle.EnergyLevelThresholdSet;
import org.opentcs.data.order.Route; import org.opentcs.data.order.Route;
import org.opentcs.drivers.vehicle.VehicleCommAdapterDescription; import org.opentcs.drivers.vehicle.VehicleCommAdapterDescription;
import org.opentcs.drivers.vehicle.management.VehicleAttachmentInformation; import org.opentcs.drivers.vehicle.management.VehicleAttachmentInformation;
import org.opentcs.drivers.vehicle.management.VehicleProcessModelTO;
import org.opentcs.kernel.extensions.servicewebapi.KernelExecutorWrapper; import org.opentcs.kernel.extensions.servicewebapi.KernelExecutorWrapper;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetVehicleResponseTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.GetVehicleResponseTO;
import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostVehicleRoutesRequestTO; import org.opentcs.kernel.extensions.servicewebapi.v1.binding.PostVehicleRoutesRequestTO;
@ -111,6 +112,77 @@ public class VehicleHandler {
} }
} }
/**
* 获取执行成本最低车辆
* @param sourcePoint 起点
* @param destinationPoint 目标点
* @return 车辆名称
*/
public String getExecuteVehicle(String sourcePoint, String destinationPoint) {
// System.out.println("sourcePoint: " + sourcePoint + " destinationPoint: " + destinationPoint);
//获取所有车辆
Set<Vehicle> vehicles = vehicleService.fetchObjects(Vehicle.class);
//设置终点
List<String> destinationPointList = List.of(destinationPoint);
//记录最低路由成本
long costs = 0;
//返回的车辆名称
String vehicleName = null;
for (Vehicle vehicle : vehicles) {
VehicleProcessModelTO vehicleProcessModelTO = vehicleService.fetchProcessModel(vehicle.getReference());
boolean commAdapterEnabled = vehicleProcessModelTO.isCommAdapterEnabled();
//校验车辆通讯适配器状态集成级别 todo 可能需要改,无空闲车辆可能也要分配车辆
if (
!commAdapterEnabled ||
vehicle.getState() != Vehicle.State.IDLE ||
vehicle.getIntegrationLevel() != Vehicle.IntegrationLevel.TO_BE_UTILIZED
) {
//车辆不能执行任务直接获取下台车辆
continue;
}
PostVehicleRoutesRequestTO postVehicleRoutesRequestTO = new PostVehicleRoutesRequestTO(destinationPointList);
postVehicleRoutesRequestTO.setSourcePoint(sourcePoint);
Map<TCSObjectReference<Point>, Route> vehicleRoutes = this.getVehicleRoutes(vehicle.getName(), postVehicleRoutesRequestTO);
// System.out.println("getExecuteVehicle vehicleRoutes: " + vehicleRoutes);
for (Map.Entry<TCSObjectReference<Point>, Route> entry : vehicleRoutes.entrySet()) {
TCSObjectReference<Point> key = entry.getKey();
Route value = entry.getValue();
// System.out.println("getExecuteVehicle point: " + key);
// System.out.println("getExecuteVehicle route: " + value);
// System.out.println("getExecuteVehicle route costs: " + value.getCosts());
//判断成本值是否合规(为空或小于0不合规)
if (value == null || value.getCosts() < 0) {
continue;
}
//比较成本取成本低车辆名称
if (vehicleName == null || costs > value.getCosts()) {
//记录数据
costs = value.getCosts();
vehicleName = vehicle.getName();
}
}
}
if (vehicleName == null) {
throw new IllegalArgumentException("无可用车辆");
// throw new IllegalArgumentException("No vehicle available.");
}
//todo 无空闲车辆可能需要创建一个无车辆订单序列
return vehicleName;
}
/** /**
* Find all vehicles orders and filters depending on the given parameters. * Find all vehicles orders and filters depending on the given parameters.
* *

View File

@ -1,4 +1,43 @@
package org.opentcs.kernel.extensions.servicewebapi.v1.binding; package org.opentcs.kernel.extensions.servicewebapi.v1.binding;
public class PostTransportOrderInfoRequestTo { public class PostTransportOrderInfoRequestTo {
private String locationName;
private String point;
private String operation;
public String getLocationName() {
return locationName;
}
public void setLocationName(String locationName) {
this.locationName = locationName;
}
public String getPoint() {
return point;
}
public void setPoint(String point) {
this.point = point;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
@Override
public String toString() {
return "PostTransportOrderInfoRequestTo{" +
"locationName='" + locationName + '\'' +
", point='" + point + '\'' +
", operation='" + operation + '\'' +
'}';
}
} }

View File

@ -1052,11 +1052,13 @@ public class DefaultVehicleController
case LENGTH_RESPECTED: case LENGTH_RESPECTED:
// Free resources allocated for executed commands, but keep as many as needed for the // Free resources allocated for executed commands, but keep as many as needed for the
// vehicle's current length. // vehicle's current length.
long vehicleLeghtRadius = 3700 / 2; //车辆长度半径
BoundingBox boundingBox = commAdapter.getProcessModel().getBoundingBox().withLength(vehicleLeghtRadius); //长度有问题
int freeableResourceSetCount int freeableResourceSetCount
= ResourceMath.freeableResourceSetCount( = ResourceMath.freeableResourceSetCount(
SplitResources.from(allocatedResources, Set.of(currentVehiclePosition)) SplitResources.from(allocatedResources, Set.of(currentVehiclePosition))
.getResourcesPassed(), .getResourcesPassed(),
commAdapter.getProcessModel().getBoundingBox().getLength() boundingBox.getLength()
); );
for (int i = 0; i < freeableResourceSetCount; i++) { for (int i = 0; i < freeableResourceSetCount; i++) {
Set<TCSResource<?>> oldResources = allocatedResources.poll(); Set<TCSResource<?>> oldResources = allocatedResources.poll();