update
This commit is contained in:
parent
305735c92c
commit
952d0db0d1
@ -5,10 +5,13 @@ import static java.util.Objects.requireNonNull;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import jakarta.inject.Inject;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -17,8 +20,15 @@ import org.opentcs.common.LoopbackAdapterConstants;
|
||||
import org.opentcs.communication.http.enums.Actions;
|
||||
import org.opentcs.communication.http.service.ExecuteAction;
|
||||
import org.opentcs.communication.http.service.ExecuteMove;
|
||||
import org.opentcs.communication.http.service.ExecuteOperation;
|
||||
import org.opentcs.components.kernel.services.TCSObjectService;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
import org.opentcs.customizations.kernel.KernelExecutor;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Path;
|
||||
import org.opentcs.data.model.Point;
|
||||
import org.opentcs.data.model.Pose;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.model.Triple;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.Route.Step;
|
||||
@ -33,7 +43,6 @@ import org.opentcs.drivers.vehicle.management.VehicleProcessModelTO;
|
||||
import org.opentcs.manage.entity.AgvActionStatus;
|
||||
import org.opentcs.manage.entity.AgvInfo;
|
||||
import org.opentcs.manage.entity.AgvInfoParams;
|
||||
import org.opentcs.manage.entity.AgvStatus;
|
||||
import org.opentcs.util.ExplainedBoolean;
|
||||
import org.opentcs.virtualvehicle.VelocityController.WayEntry;
|
||||
import org.slf4j.Logger;
|
||||
@ -108,9 +117,27 @@ public class LoopbackCommunicationAdapter
|
||||
*/
|
||||
private static String CURRENT_POS;
|
||||
/**
|
||||
* 订单任务key
|
||||
* 订单任务key:记录当前订单执行的任务key
|
||||
*/
|
||||
private int TASK_KEY = 1;
|
||||
// private int TASK_KEY;
|
||||
/**
|
||||
* 记录最后经过点
|
||||
* 防止意外重启后,AGV控制器上报最终经过点为0无法执行任务
|
||||
*/
|
||||
private String LAST_PASSED_POINT;
|
||||
/**
|
||||
* 记录车辆最后的姿态
|
||||
* 防止车辆重启后,AGV控制器上报最终经过点为0无法进行交管
|
||||
*/
|
||||
private Pose LAST_POSE;
|
||||
/**
|
||||
* 车辆服务对象
|
||||
*/
|
||||
private final VehicleService vehicleService;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private final TCSObjectService objectService;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
@ -125,7 +152,9 @@ public class LoopbackCommunicationAdapter
|
||||
@Assisted
|
||||
Vehicle vehicle,
|
||||
@KernelExecutor
|
||||
ScheduledExecutorService kernelExecutor
|
||||
ScheduledExecutorService kernelExecutor,
|
||||
TCSObjectService objectService, // 注入对象服务
|
||||
VehicleService vehicleService
|
||||
) {
|
||||
super(
|
||||
new LoopbackVehicleModel(vehicle),
|
||||
@ -135,6 +164,8 @@ public class LoopbackCommunicationAdapter
|
||||
);
|
||||
this.vehicle = requireNonNull(vehicle, "vehicle");
|
||||
this.configuration = requireNonNull(configuration, "configuration");
|
||||
this.objectService = requireNonNull(objectService, "objectService");
|
||||
this.vehicleService = requireNonNull(vehicleService, "vehicleService");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -228,6 +259,15 @@ public class LoopbackCommunicationAdapter
|
||||
}
|
||||
LOG.info("Loopback comm adapter is being disable: {}", getName());
|
||||
super.disable();
|
||||
|
||||
//关闭连接后,更新车辆等级为不处理订单,但占用资源。
|
||||
getProcessModel().integrationLevelChangeRequested(Vehicle.IntegrationLevel.TO_BE_RESPECTED);
|
||||
if (LAST_PASSED_POINT != null) {
|
||||
getProcessModel().setPosition(LAST_PASSED_POINT);
|
||||
}
|
||||
if (LAST_POSE != null) {
|
||||
getProcessModel().setPose(LAST_POSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -257,8 +297,8 @@ public class LoopbackCommunicationAdapter
|
||||
ORDER_NAME = cmd.getTransportOrder().getName();
|
||||
//下发起点
|
||||
CURRENT_POS = sourcePoint;
|
||||
//当前执行taskKey
|
||||
TASK_KEY = 1;
|
||||
// //当前执行taskKey
|
||||
// TASK_KEY = 1;
|
||||
|
||||
// The command is added to the sent queue after this method returns. Therefore
|
||||
// we have to explicitly start the simulation like this.
|
||||
@ -293,6 +333,7 @@ public class LoopbackCommunicationAdapter
|
||||
|
||||
@Override
|
||||
public synchronized void initVehiclePosition(String newPos) {
|
||||
LAST_PASSED_POINT = newPos;
|
||||
((ExecutorService) getExecutor()).submit(() -> getProcessModel().setPosition(newPos));
|
||||
}
|
||||
|
||||
@ -398,11 +439,33 @@ public class LoopbackCommunicationAdapter
|
||||
getProcessModel().setState(Vehicle.State.EXECUTING);
|
||||
Step step = command.getStep();
|
||||
|
||||
Vehicle newVehicle = vehicleService.fetchObject(Vehicle.class, getProcessModel().getName());
|
||||
List<Set<TCSResourceReference<?>>> allocatedResources = newVehicle.getAllocatedResources();
|
||||
|
||||
//使用副本更新车辆模型,防止异常情况
|
||||
List<Set<TCSResourceReference<?>>> copiedResources = new ArrayList<>(allocatedResources);
|
||||
copiedResources.clear();
|
||||
|
||||
if (step.getSourcePoint() != null) {
|
||||
//下发起点不为空
|
||||
Point point = objectService.fetchObject(Point.class, step.getSourcePoint().getName());
|
||||
Set<TCSResourceReference<?>> resource = new HashSet<>();
|
||||
resource.add(point.getReference());
|
||||
copiedResources.add(resource);
|
||||
}
|
||||
if (step.getPath() != null) {
|
||||
Path path = objectService.fetchObject(Path.class, step.getPath().getName());
|
||||
Set<TCSResourceReference<?>> resource = new HashSet<>();
|
||||
resource.add(path.getReference());
|
||||
copiedResources.add(resource);
|
||||
}
|
||||
newVehicle.withAllocatedResources(copiedResources);
|
||||
|
||||
if (step.getPath() == null) {
|
||||
actionExec(command);
|
||||
} else {
|
||||
ExecuteMove.setExecTaskKey(getProcessModel().getName(), TASK_KEY);
|
||||
TASK_KEY++;
|
||||
// ExecuteOperation.setExecTaskKey(getProcessModel().getName(), TASK_KEY);
|
||||
// TASK_KEY++;
|
||||
//todo 移动
|
||||
movementExec(command);
|
||||
}
|
||||
@ -432,9 +495,6 @@ public class LoopbackCommunicationAdapter
|
||||
//下发动作
|
||||
ExecuteAction.sendCmd(getProcessModel().getName(), command.getOperation(), getSerialNum());
|
||||
|
||||
// 结束动作
|
||||
finishCmd(command);
|
||||
|
||||
//进入阻塞
|
||||
while (ACTION_STATUS) {
|
||||
try {
|
||||
@ -444,6 +504,8 @@ public class LoopbackCommunicationAdapter
|
||||
}
|
||||
}
|
||||
|
||||
// 结束动作
|
||||
finishCmd(command);
|
||||
//继续执行动作
|
||||
nextCmd();
|
||||
}
|
||||
@ -778,13 +840,19 @@ public class LoopbackCommunicationAdapter
|
||||
|
||||
//更新车辆姿态
|
||||
if (params.getPoint() != 0) {
|
||||
LAST_PASSED_POINT = params.getPoint().toString(); //记录最终经过点
|
||||
if (!Objects.equals(getProcessModel().getPosition(), params.getPoint().toString())) {
|
||||
getProcessModel().setPosition(params.getPoint().toString()); //更新最终经过点
|
||||
}
|
||||
getProcessModel().setPose(new Pose(new Triple(Math.round(params.getX() * 1000), Math.round(params.getY() * 1000), 0), params.getAngle()));
|
||||
|
||||
LAST_POSE = new Pose(new Triple(Math.round(params.getX() * 1000), Math.round(params.getY() * 1000), 0), params.getAngle());
|
||||
getProcessModel().setPose(LAST_POSE);
|
||||
} else {
|
||||
//最后经过点为0,应该是车辆重启过。车辆关机时应该正常对点位进行交管,防止车辆碰撞。
|
||||
//todo 可能需要实现原点自动定位,暂时不做处理
|
||||
//最后经过点为0,应该是车辆丢失定位或重启过。todo 可能需要自动找点
|
||||
}
|
||||
|
||||
if (ACTION_STATUS) {
|
||||
vehicleState = Vehicle.State.EXECUTING;
|
||||
}
|
||||
|
||||
//更新电量
|
||||
|
@ -53,5 +53,8 @@ public interface LoopbackAdapterConstants {
|
||||
* AGV 端口
|
||||
*/
|
||||
String AGV_PORT = "AGV:PORT";
|
||||
|
||||
/**
|
||||
* 对应路线车辆行驶姿态:0=正走,1=到走
|
||||
*/
|
||||
String AGV_DRIVE_POSE = "PATH:DRIVE_POSE";
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.opentcs.communication.http.dto.BaseRequestTo;
|
||||
import org.opentcs.communication.http.dto.kc.move.Path;
|
||||
import org.opentcs.communication.http.dto.kc.move.Point;
|
||||
import org.opentcs.communication.http.dto.kc.move.RequestAe;
|
||||
import org.opentcs.communication.http.service.ExecuteOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -55,7 +56,23 @@ public class HttpClient {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
HttpClient httpClient = new HttpClient();
|
||||
|
||||
ExecuteOperation executeOperation = new ExecuteOperation();
|
||||
|
||||
{ //暂停订单
|
||||
ExecuteOperation.pauseOrder("v1", 1);
|
||||
}
|
||||
|
||||
{ //继续执行订单
|
||||
ExecuteOperation.continueOrder("v1", 1);
|
||||
}
|
||||
|
||||
{ //撤销订单
|
||||
ExecuteOperation.cancelOrder("v1");
|
||||
}
|
||||
|
||||
|
||||
// HttpClient httpClient = new HttpClient();
|
||||
|
||||
// { //0x02
|
||||
// //变量成员
|
||||
@ -171,49 +188,49 @@ public class HttpClient {
|
||||
// httpClient.sendCommand(baseRequestTo);
|
||||
// }
|
||||
|
||||
{ //0xAE
|
||||
RequestAe ae = new RequestAe();
|
||||
ae.setWms_order_id(1);
|
||||
ae.setOrder_id(1);
|
||||
ae.setTask_key(1);
|
||||
ae.setPoint_size(2);
|
||||
ae.setPath_size(1);
|
||||
|
||||
ArrayList<Point> pointList = new ArrayList<>();
|
||||
for (int i = 0; i < ae.getPoint_size(); i++) {
|
||||
Point point = new Point();
|
||||
|
||||
if (i == 0) {
|
||||
point.setPoint_id(1);
|
||||
point.setPoint_serial(0);
|
||||
} else {
|
||||
point.setPoint_id(2);
|
||||
point.setPoint_serial(2);
|
||||
}
|
||||
point.setPoint_angle(0);
|
||||
|
||||
pointList.add(point);
|
||||
}
|
||||
ae.setPoint_info(pointList);
|
||||
|
||||
ArrayList<Path> pathList = new ArrayList<>();
|
||||
for (int i = 0; i < ae.getPath_size(); i++) {
|
||||
Path path = new Path();
|
||||
|
||||
path.setPath_id(12);
|
||||
path.setPath_serial(1);
|
||||
path.setPath_angle(0);
|
||||
path.setDriver_pose(1);
|
||||
path.setMax_speed(1);
|
||||
path.setMax_angle_speed(1);
|
||||
|
||||
pathList.add(path);
|
||||
}
|
||||
ae.setPath_info(pathList);
|
||||
|
||||
BaseRequestTo baseRequestTo = new BaseRequestTo(2, "OPENTCS", "KC-CTRL", 1, "2025-6-6 10:00:00", ae);
|
||||
|
||||
httpClient.sendCommand("http://192.168.124.121:2005", baseRequestTo);
|
||||
}
|
||||
// { //0xAE
|
||||
// RequestAe ae = new RequestAe();
|
||||
// ae.setWms_order_id(1);
|
||||
// ae.setOrder_id(1);
|
||||
// ae.setTask_key(1);
|
||||
// ae.setPoint_size(2);
|
||||
// ae.setPath_size(1);
|
||||
//
|
||||
// ArrayList<Point> pointList = new ArrayList<>();
|
||||
// for (int i = 0; i < ae.getPoint_size(); i++) {
|
||||
// Point point = new Point();
|
||||
//
|
||||
// if (i == 0) {
|
||||
// point.setPoint_id(1);
|
||||
// point.setPoint_serial(0);
|
||||
// } else {
|
||||
// point.setPoint_id(2);
|
||||
// point.setPoint_serial(2);
|
||||
// }
|
||||
// point.setPoint_angle(0);
|
||||
//
|
||||
// pointList.add(point);
|
||||
// }
|
||||
// ae.setPoint_info(pointList);
|
||||
//
|
||||
// ArrayList<Path> pathList = new ArrayList<>();
|
||||
// for (int i = 0; i < ae.getPath_size(); i++) {
|
||||
// Path path = new Path();
|
||||
//
|
||||
// path.setPath_id(12);
|
||||
// path.setPath_serial(1);
|
||||
// path.setPath_angle(0);
|
||||
// path.setDriver_pose(1);
|
||||
// path.setMax_speed(1);
|
||||
// path.setMax_angle_speed(1);
|
||||
//
|
||||
// pathList.add(path);
|
||||
// }
|
||||
// ae.setPath_info(pathList);
|
||||
//
|
||||
// BaseRequestTo baseRequestTo = new BaseRequestTo(2, "OPENTCS", "KC-CTRL", 1, "2025-6-6 10:00:00", ae);
|
||||
//
|
||||
// httpClient.sendCommand("http://192.168.124.121:2005", baseRequestTo);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,34 @@
|
||||
package org.opentcs.communication.http.service;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.opentcs.communication.http.enums.VehicleEnums;
|
||||
|
||||
public class BaseService {
|
||||
|
||||
// 随机初始化起点,减少重复概率
|
||||
private static final AtomicInteger counter = new AtomicInteger(
|
||||
ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE / 2)
|
||||
);
|
||||
|
||||
public static String getUrl(String vehicleName) {
|
||||
VehicleEnums vehicleEnums = VehicleEnums.valueOf(vehicleName);
|
||||
return "http://" + vehicleEnums.getIp() + ":" + vehicleEnums.getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成进程内唯一的int型ID
|
||||
* 优点:简单高效
|
||||
* 限制:
|
||||
* - 重启后可能重复
|
||||
* - 超过21亿后会回绕(正常应用很难达到)
|
||||
*/
|
||||
public static int generate() {
|
||||
int id = counter.getAndIncrement();
|
||||
// 处理溢出(当接近int上限时重置为随机值)
|
||||
return (id < 0) ? counter.getAndSet(
|
||||
ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE / 2)
|
||||
) : id;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import org.opentcs.common.LoopbackAdapterConstants;
|
||||
import org.opentcs.communication.http.HttpClient;
|
||||
import org.opentcs.communication.http.dto.BaseRequestTo;
|
||||
import org.opentcs.communication.http.dto.kc.move.Path;
|
||||
@ -12,17 +13,19 @@ import org.opentcs.communication.http.dto.kc.move.Point;
|
||||
import org.opentcs.communication.http.dto.kc.move.RequestAe;
|
||||
import org.opentcs.communication.http.entity.OrderInfo;
|
||||
import org.opentcs.drivers.vehicle.MovementCommand;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ExecuteMove extends BaseService {
|
||||
|
||||
/**
|
||||
* LOG
|
||||
*/
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ExecuteMove.class);
|
||||
/**
|
||||
* 订单名映射int类型数据.
|
||||
*/
|
||||
private static final HashMap<String, OrderInfo> orderInfoMap = new HashMap<>();
|
||||
/**
|
||||
* 通讯适配器当前执行taskkey
|
||||
*/
|
||||
private static HashMap<String, Integer> execTaskKeyMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 发送移动指令
|
||||
@ -79,6 +82,8 @@ public class ExecuteMove extends BaseService {
|
||||
}
|
||||
maxVelocity = 5;
|
||||
|
||||
Integer drivePose = getDrivePose(pathInfo); //行驶姿态
|
||||
|
||||
RequestAe ae = new RequestAe();
|
||||
ae.setWms_order_id(1); //todo 测试填写
|
||||
ae.setOrder_id(orderID);
|
||||
@ -112,7 +117,7 @@ public class ExecuteMove extends BaseService {
|
||||
path.setPath_id(pathID);
|
||||
path.setPath_serial(orderInfo.getPathSerialNum());
|
||||
path.setPath_angle(0);
|
||||
path.setDriver_pose(0);
|
||||
path.setDriver_pose(drivePose);
|
||||
path.setMax_speed(maxVelocity);
|
||||
path.setMax_angle_speed(maxVelocity);
|
||||
|
||||
@ -138,13 +143,8 @@ public class ExecuteMove extends BaseService {
|
||||
//当前车辆已存在集合中
|
||||
OrderInfo orderInfo = orderInfoMap.get(vehicleName);
|
||||
|
||||
if (!Objects.equals(orderName, orderInfo.getName())) {
|
||||
//订单名称不相等为执行下一个订单,初始化订单对应参数
|
||||
orderInfoMap.remove(vehicleName);
|
||||
|
||||
Integer currentOrderId = orderInfo.getId() + 1;
|
||||
|
||||
orderInfo.setId(currentOrderId);
|
||||
if (!Objects.equals(orderName, orderInfo.getName()) && orderInfoMap.containsKey(vehicleName)) {
|
||||
orderInfo.setId(generate());
|
||||
orderInfo.setName(orderName);
|
||||
orderInfo.setState(1);
|
||||
orderInfo.setTaskKey(1);
|
||||
@ -154,7 +154,7 @@ public class ExecuteMove extends BaseService {
|
||||
} else {
|
||||
//车辆不在集合中
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
orderInfo.setId(1); //todo 测试修改,正式上线应该为1
|
||||
orderInfo.setId(generate());
|
||||
orderInfo.setName(orderName);
|
||||
orderInfo.setState(1);
|
||||
orderInfo.setTaskKey(1);
|
||||
@ -165,28 +165,33 @@ public class ExecuteMove extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前执行任务key
|
||||
*/
|
||||
public static void setExecTaskKey(String vehicleName, Integer taskKey) {
|
||||
if (execTaskKeyMap.containsKey(vehicleName)) {
|
||||
execTaskKeyMap.put(vehicleName, taskKey);
|
||||
} else {
|
||||
execTaskKeyMap.put(vehicleName, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务key
|
||||
*/
|
||||
public static Integer getTaskKey(String vehicleName) {
|
||||
return execTaskKeyMap.get(vehicleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前订单ID
|
||||
*/
|
||||
public static Integer getOrderID(String vehicleName) {
|
||||
return orderInfoMap.get(vehicleName).getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回行驶姿态
|
||||
*/
|
||||
private static Integer getDrivePose(org.opentcs.data.model.Path path) {
|
||||
String drivePost = path.getProperties().get(LoopbackAdapterConstants.AGV_DRIVE_POSE);
|
||||
System.out.println("getDrivePose drivePost: " + drivePost);
|
||||
|
||||
int pose = 0;
|
||||
if (drivePost == null) {
|
||||
return pose;
|
||||
}
|
||||
|
||||
switch (drivePost) {
|
||||
case "1" -> pose = 1;
|
||||
default -> {
|
||||
LOG.error("getDrivePose UNKNOWN DRIVE POSE: {}", drivePost);
|
||||
throw new IllegalArgumentException("UNKNOWN DRIVE POSE: " + drivePost);
|
||||
}
|
||||
}
|
||||
|
||||
return pose;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.opentcs.communication.http.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import org.opentcs.communication.http.HttpClient;
|
||||
import org.opentcs.communication.http.dto.BaseRequestTo;
|
||||
import org.opentcs.communication.http.dto.kc.operation.Action01;
|
||||
@ -18,6 +19,14 @@ public class ExecuteOperation extends BaseService{
|
||||
* This class's Logger.
|
||||
*/
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ExecuteOperation.class);
|
||||
/**
|
||||
* 通讯适配器当前执行taskkey
|
||||
*/
|
||||
private static HashMap<String, Integer> execTaskKeyMap = new HashMap<>();
|
||||
/**
|
||||
* 序列号
|
||||
*/
|
||||
private static Integer serialNum = 0;
|
||||
|
||||
/**
|
||||
* 暂停执行订单
|
||||
@ -32,7 +41,7 @@ public class ExecuteOperation extends BaseService{
|
||||
b2.setParam_size(4);
|
||||
|
||||
Action01 action01 = new Action01();
|
||||
action01.setIsStopImmediately(1);
|
||||
action01.setIsStopImmediately(0);
|
||||
|
||||
b2.setParam_data(action01);
|
||||
|
||||
@ -49,7 +58,7 @@ public class ExecuteOperation extends BaseService{
|
||||
Integer orderId = ExecuteMove.getOrderID(vehicleName);
|
||||
|
||||
//获取任务key
|
||||
Integer taskKey = ExecuteMove.getTaskKey(vehicleName);
|
||||
Integer taskKey = getTaskKey(vehicleName);
|
||||
|
||||
RequestB2 b2 = new RequestB2();
|
||||
|
||||
@ -69,9 +78,8 @@ public class ExecuteOperation extends BaseService{
|
||||
/**
|
||||
* 撤销订单
|
||||
* @param vehicleName 车辆名称
|
||||
* @param serialNum 序列号
|
||||
*/
|
||||
public static void cancelOrder(String vehicleName, Integer serialNum) {
|
||||
public static void cancelOrder(String vehicleName) {
|
||||
|
||||
//获取订单ID
|
||||
Integer orderId = ExecuteMove.getOrderID(vehicleName);
|
||||
@ -84,11 +92,11 @@ public class ExecuteOperation extends BaseService{
|
||||
|
||||
Action03 action03 = new Action03();
|
||||
action03.setOrderId(orderId);
|
||||
action03.setIsStopImmediately(1);
|
||||
action03.setIsStopImmediately(0);
|
||||
|
||||
b2.setParam_data(action03);
|
||||
|
||||
sendCmd(vehicleName, b2, serialNum);
|
||||
sendCmd(vehicleName, b2, getSerialNum());
|
||||
}
|
||||
|
||||
public static void sendCmd(String vehicleName, Object data, Integer serialNum)
|
||||
@ -107,4 +115,26 @@ public class ExecuteOperation extends BaseService{
|
||||
httpClient.sendCommand(url, baseRequestTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前执行任务key
|
||||
*/
|
||||
public static void setExecTaskKey(String vehicleName, Integer taskKey) {
|
||||
if (execTaskKeyMap.containsKey(vehicleName)) {
|
||||
execTaskKeyMap.put(vehicleName, taskKey);
|
||||
} else {
|
||||
execTaskKeyMap.put(vehicleName, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务key
|
||||
*/
|
||||
public static Integer getTaskKey(String vehicleName) {
|
||||
return execTaskKeyMap.get(vehicleName);
|
||||
}
|
||||
|
||||
private static int getSerialNum() {
|
||||
return serialNum++;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
package org.opentcs.communication.mqtt.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.opentcs.communication.mqtt.entity.BaseRequestTo;
|
||||
import org.opentcs.communication.mqtt.entity.kc.action.RequestAction;
|
||||
|
||||
public class ExecuteAction {
|
||||
|
||||
/**
|
||||
* 下发动作到平台
|
||||
* @param action 动作
|
||||
*/
|
||||
public static void sendCmd(String action, Integer serialNum) {
|
||||
|
||||
// 获取当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
String time = now.format(formatter);
|
||||
|
||||
RequestAction requestAction = new RequestAction();
|
||||
requestAction.setAction(action);
|
||||
|
||||
BaseRequestTo baseRequestTo = new BaseRequestTo(
|
||||
4,
|
||||
"OPENTCS",
|
||||
"KC-CTRL",
|
||||
serialNum,
|
||||
time,
|
||||
requestAction
|
||||
);
|
||||
|
||||
//发送mqtt消息
|
||||
}
|
||||
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
package org.opentcs.communication.mqtt.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import org.opentcs.communication.mqtt.entity.BaseRequestTo;
|
||||
import org.opentcs.communication.mqtt.entity.kc.move.Path;
|
||||
import org.opentcs.communication.mqtt.entity.kc.move.Point;
|
||||
import org.opentcs.communication.mqtt.entity.kc.move.RequestAe;
|
||||
import org.opentcs.drivers.vehicle.MovementCommand;
|
||||
|
||||
public class ExecuteMove {
|
||||
|
||||
/**
|
||||
* 订单名映射int类型数据.
|
||||
*/
|
||||
private static final HashMap<String, Integer> orderNameMap = new HashMap<>();
|
||||
/**
|
||||
* 记录上次下发订单名称
|
||||
*/
|
||||
private static String oldOrderName;
|
||||
/**
|
||||
* 当前订单名称对应唯一整数ID
|
||||
*/
|
||||
private static Integer currentOrderId = 0;
|
||||
/**
|
||||
* 任务ID
|
||||
* 任务的唯一标识。与订单ID绑定,从1开始,当同一订单下发新的资源时加1;订单ID发生改变,任务KEY需要重新计数。
|
||||
*/
|
||||
private static Integer taskKey;
|
||||
/**
|
||||
* 序列号
|
||||
* 用于定位点在整个任务中的位置。目的是区分同一个点ID是否在一个任务中出现多次。从0开始偶数递增,例如:0->2->4->6……
|
||||
*/
|
||||
private static Integer pointSerialNum = 0;
|
||||
/**
|
||||
* 用于定位段在整个任务中的位置。目的是区分同一个段ID是否在一个任务中出现多次。从1开始奇数递增,例如:1->3->5->7……
|
||||
*/
|
||||
private static Integer pathSerialNum = 1;
|
||||
|
||||
public static void sendCmd(MovementCommand cmd, Integer serialNum)
|
||||
{
|
||||
// 获取当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
String time = now.format(formatter);
|
||||
|
||||
RequestAe ae = buildCommand(cmd);
|
||||
BaseRequestTo baseRequestTo = new BaseRequestTo(2, "OPENTCS", "KC-CTRL", serialNum, time, ae);
|
||||
|
||||
// HttpClient httpClient = new HttpClient();
|
||||
// httpClient.sendCommand(baseRequestTo);
|
||||
}
|
||||
|
||||
private static RequestAe buildCommand(MovementCommand cmd)
|
||||
{
|
||||
//订单ID
|
||||
int orderID = getUniqueOrderID(cmd.getTransportOrder().getName());
|
||||
//下发起点
|
||||
String sourcePoint = cmd.getStep().getSourcePoint().getName();
|
||||
int newSourcePoint = Integer.parseInt(sourcePoint);
|
||||
//下发终点
|
||||
String destinationPoint = cmd.getStep().getDestinationPoint().getName();
|
||||
int newDestination = Integer.parseInt(destinationPoint);
|
||||
|
||||
//获取路径ID
|
||||
int pathID;
|
||||
if (newSourcePoint < newDestination) {
|
||||
pathID = Integer.parseInt(sourcePoint + destinationPoint);
|
||||
} else {
|
||||
pathID = Integer.parseInt(destinationPoint + sourcePoint);
|
||||
}
|
||||
|
||||
org.opentcs.data.model.Path pathInfo = cmd.getStep().getPath();
|
||||
int maxVelocity = 1; //获取最大速度
|
||||
int maxReverseVelocity = 1; //获取最大反向速度
|
||||
if (pathInfo != null) {
|
||||
maxVelocity = pathInfo.getMaxVelocity(); //获取设置速度
|
||||
maxReverseVelocity = pathInfo.getMaxReverseVelocity();
|
||||
}
|
||||
|
||||
RequestAe ae = new RequestAe();
|
||||
ae.setOrderId(orderID);
|
||||
ae.setTaskKey(taskKey);
|
||||
ae.setPointSize(2);
|
||||
ae.setPathSize(1);
|
||||
|
||||
ArrayList<Point> pointList = new ArrayList<>();
|
||||
for (int i = 0; i < ae.getPointSize(); i++) {
|
||||
Point point = new Point();
|
||||
|
||||
if (i == 0) {
|
||||
point.setPoint_id(newSourcePoint);
|
||||
} else {
|
||||
point.setPoint_id(newDestination);
|
||||
}
|
||||
point.setPoint_serial(pointSerialNum);
|
||||
point.setPoint_angle(0);
|
||||
|
||||
pointSerialNum = pointSerialNum + 2;
|
||||
|
||||
pointList.add(point);
|
||||
}
|
||||
ae.setPoint(pointList);
|
||||
|
||||
ArrayList<Path> pathList = new ArrayList<>();
|
||||
for (int i = 0; i < ae.getPathSize(); i++) {
|
||||
Path path = new Path();
|
||||
|
||||
path.setPath_id(pathID);
|
||||
path.setPath_serial(pathSerialNum);
|
||||
path.setPath_angle(0);
|
||||
path.setDrive_pose(1);
|
||||
path.setMax_speed(maxVelocity);
|
||||
path.setMax_angle_speed(maxVelocity);
|
||||
|
||||
pathSerialNum = pathSerialNum + 2;
|
||||
|
||||
pathList.add(path);
|
||||
}
|
||||
ae.setPath(pathList);
|
||||
|
||||
return ae;
|
||||
}
|
||||
|
||||
/**
|
||||
* 维护订单名对应int类型唯一ID--------todo 待优化:如果调度重启,控制器也需要重启。否则0xAE指令会因为重置订单ID和任务key下发失败。应改成wms数据库ID交互
|
||||
* @param orderName 订单名
|
||||
* @return Integer
|
||||
*/
|
||||
private static int getUniqueOrderID(String orderName){
|
||||
|
||||
Integer orderId;
|
||||
|
||||
if (orderNameMap.containsKey(orderName)) {
|
||||
//订单名已存在
|
||||
orderId = orderNameMap.get(orderName);
|
||||
} else { //订单名不存在
|
||||
//初始化参数
|
||||
initParams();
|
||||
|
||||
if (oldOrderName != null) {
|
||||
//删除上次订单映射唯一ID
|
||||
orderNameMap.remove(oldOrderName);
|
||||
}
|
||||
|
||||
//更新记录订单名称
|
||||
oldOrderName = orderName;
|
||||
|
||||
// 创建对应映射
|
||||
orderId = currentOrderId;
|
||||
currentOrderId++;
|
||||
orderNameMap.put(orderName, orderId);
|
||||
}
|
||||
|
||||
return orderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化参数
|
||||
*/
|
||||
private static void initParams() {
|
||||
taskKey = 1;
|
||||
pointSerialNum = 0;
|
||||
pathSerialNum = 1;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package org.opentcs.communication.mqtt.service;
|
||||
|
||||
public class ExecuteOperation {
|
||||
|
||||
|
||||
|
||||
}
|
@ -7,11 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.opentcs.access.KernelServicePortal;
|
||||
import org.opentcs.access.rmi.KernelServicePortalBuilder;
|
||||
import org.opentcs.common.GuestUserCredentials;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.manage.entity.AgvInfo;
|
||||
import org.opentcs.manage.entity.AgvInfoParams;
|
||||
import org.opentcs.manage.entity.AgvStatus;
|
||||
@ -45,15 +41,6 @@ public class AdapterManage {
|
||||
* 设置自动关闭适配器时间阈值,单位:毫秒
|
||||
*/
|
||||
private static final Long AUTO_CLOSE_TIME = 2000L;
|
||||
/**
|
||||
* 记录通讯适配器数据,实现异步不阻塞更新车辆模型
|
||||
* 基于线程安全HASHMAP
|
||||
*/
|
||||
// private static final ConcurrentHashMap<String, AgvInfo> adapterDataMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 内核状态
|
||||
*/
|
||||
// public static Boolean kernelStatus = false;
|
||||
|
||||
//开启通讯信息
|
||||
private static final String USER = GuestUserCredentials.USER;
|
||||
@ -63,7 +50,7 @@ public class AdapterManage {
|
||||
|
||||
//开启定时任务
|
||||
public void START() {
|
||||
scheduler.scheduleWithFixedDelay(task, 5000, 500, TimeUnit.MILLISECONDS);
|
||||
scheduler.scheduleWithFixedDelay(task, 5000, 1000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
//关闭定时任务
|
||||
@ -87,9 +74,9 @@ public class AdapterManage {
|
||||
Date date = new Date();
|
||||
long currentTime = date.getTime();
|
||||
|
||||
System.out.println("autoManageAdapterStatus sout: " + adapterStatusMap);
|
||||
// System.out.println("autoManageAdapterStatus sout: " + adapterStatusMap);
|
||||
adapterStatusMap.forEach((key, value) -> {
|
||||
LOG.info("adapterStatusMap starts name: {}", key);
|
||||
// LOG.info("adapterStatusMap starts name: {}", key);
|
||||
|
||||
AgvStatus agvStatus = new AgvStatus();
|
||||
agvStatus.setTime(value.getTime());
|
||||
@ -108,8 +95,7 @@ public class AdapterManage {
|
||||
|
||||
//更新记录数据
|
||||
adapterStatusMap.put(key, agvStatus);
|
||||
|
||||
LOG.info("adapterStatusMap end name: {}", key);
|
||||
// LOG.info("adapterStatusMap end name: {}", key);
|
||||
});
|
||||
}
|
||||
|
||||
@ -151,7 +137,6 @@ public class AdapterManage {
|
||||
agvInfo.setTime(jsonObject.getString("time"));
|
||||
agvInfo.setParams(getAgvInfoParams(jsonObject.getString("params")));
|
||||
|
||||
// adapterDataMap.put(name, agvInfo);
|
||||
return agvInfo;
|
||||
}
|
||||
|
||||
@ -181,44 +166,4 @@ public class AdapterManage {
|
||||
Boolean ENABLE = true;
|
||||
Boolean DISABLE = false;
|
||||
}
|
||||
|
||||
// private void testSendMessage() {
|
||||
// System.out.println("test");
|
||||
// AgvInfoParams agvInfoParams = new AgvInfoParams();
|
||||
// agvInfoParams.setX(0.5f);
|
||||
// agvInfoParams.setY(0.5f);
|
||||
// agvInfoParams.setAngle(0.5f);
|
||||
// agvInfoParams.setPoint(12);
|
||||
// agvInfoParams.setPower(0.52f);
|
||||
// agvInfoParams.setAgv_status(0);
|
||||
// agvInfoParams.setCargo_status(0);
|
||||
// agvInfoParams.setAgv_model(0);
|
||||
// agvInfoParams.setCharge_status(0);
|
||||
// agvInfoParams.setAction_status(1);
|
||||
//
|
||||
// AgvInfo agvInfo = new AgvInfo();
|
||||
// agvInfo.setReceiver("OPENTCS");
|
||||
// agvInfo.setSender("KC-CTRL");
|
||||
// agvInfo.setSerial_num(1);
|
||||
// agvInfo.setType(1);
|
||||
// agvInfo.setTime("2020-07-07 09:09:09");
|
||||
// agvInfo.setVehicle_name("v2");
|
||||
// agvInfo.setParams(agvInfoParams);
|
||||
//
|
||||
// System.out.println("testSendMessage agvInfo: " + agvInfo);
|
||||
//
|
||||
// KernelServicePortal servicePortal = new KernelServicePortalBuilder(USER, PASSWORD).build();
|
||||
// servicePortal.login(IP, PORT);
|
||||
// VehicleService vehicleService = servicePortal.getVehicleService();
|
||||
// Vehicle vehicle = vehicleService.fetchObject(Vehicle.class, "v2");
|
||||
//
|
||||
// if (vehicle != null) {
|
||||
// System.out.println("send success");
|
||||
// vehicleService.sendCommAdapterMessage(vehicle.getReference(), agvInfo);
|
||||
// } else {
|
||||
// System.out.println("send not fund");
|
||||
// }
|
||||
//
|
||||
//// kernel.sendToAdapter("v2", agvInfo);
|
||||
// }
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package org.opentcs.traffic.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import org.opentcs.traffic.entity.VehicleAttr;
|
||||
import java.awt.geom.Point2D;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -30,9 +31,19 @@ public class ContourAlgorithm {
|
||||
*
|
||||
* @return true,可通过,false,不通过
|
||||
*/
|
||||
public boolean interferenceDetection() {
|
||||
public boolean interferenceDetection(Point2D.Double center) {
|
||||
|
||||
// center.setLocation(0.0, 0.0);
|
||||
|
||||
GeometryFactory geometryFactory = new GeometryFactory();
|
||||
Coordinate[] coords = {
|
||||
|
||||
};
|
||||
|
||||
|
||||
// new BezierCurve()
|
||||
|
||||
|
||||
//
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -15,9 +15,6 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.opentcs.access.KernelServicePortal;
|
||||
import org.opentcs.access.rmi.KernelServicePortalBuilder;
|
||||
import org.opentcs.common.GuestUserCredentials;
|
||||
import org.opentcs.components.kernel.services.RouterService;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
@ -74,8 +71,12 @@ public class VehicleHandler {
|
||||
System.out.println("jsonObject-----ssss: " + data.toString());
|
||||
|
||||
//截取平台响应的字符串
|
||||
String jsonStr = data.toString().split("=", 2)[1];
|
||||
// String jsonStr = data.toString();
|
||||
String jsonStr;
|
||||
try {
|
||||
jsonStr = data.toString().split("=", 2)[1];
|
||||
} catch (Exception e) {
|
||||
jsonStr = data.toString();
|
||||
}
|
||||
JSONObject jsonObject = JSON.parseObject(jsonStr);
|
||||
String name = jsonObject.getString("vehicle_name");
|
||||
Integer type = jsonObject.getInteger("type");
|
||||
|
@ -42,6 +42,7 @@ public class DefaultPropertySuggestions
|
||||
keySuggestions.add(LoopbackAdapterConstants.AGV_AUTHORIZE_CODE);
|
||||
keySuggestions.add(LoopbackAdapterConstants.AGV_IP);
|
||||
keySuggestions.add(LoopbackAdapterConstants.AGV_PORT);
|
||||
keySuggestions.add(LoopbackAdapterConstants.AGV_DRIVE_POSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,6 +10,7 @@ import jakarta.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.opentcs.communication.http.service.ExecuteOperation;
|
||||
import org.opentcs.components.Lifecycle;
|
||||
import org.opentcs.components.kernel.Router;
|
||||
import org.opentcs.components.kernel.services.InternalTransportOrderService;
|
||||
@ -355,6 +356,9 @@ public class TransportOrderUtil
|
||||
// vehicle reports the remaining movements as finished.
|
||||
updateTransportOrderState(order.getReference(), TransportOrder.State.WITHDRAWN);
|
||||
|
||||
//撤销订单
|
||||
ExecuteOperation.cancelOrder(vehicle.getName());
|
||||
|
||||
VehicleController vehicleController
|
||||
= vehicleControllerPool.getVehicleController(vehicle.getName());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user