This commit is contained in:
xuzhiheng 2025-06-13 15:49:32 +08:00
parent 305735c92c
commit 952d0db0d1
14 changed files with 272 additions and 376 deletions

View File

@ -5,10 +5,13 @@ import static java.util.Objects.requireNonNull;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; 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.enums.Actions;
import org.opentcs.communication.http.service.ExecuteAction; import org.opentcs.communication.http.service.ExecuteAction;
import org.opentcs.communication.http.service.ExecuteMove; 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.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.Pose;
import org.opentcs.data.model.TCSResourceReference;
import org.opentcs.data.model.Triple; import org.opentcs.data.model.Triple;
import org.opentcs.data.model.Vehicle; import org.opentcs.data.model.Vehicle;
import org.opentcs.data.order.Route.Step; 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.AgvActionStatus;
import org.opentcs.manage.entity.AgvInfo; import org.opentcs.manage.entity.AgvInfo;
import org.opentcs.manage.entity.AgvInfoParams; import org.opentcs.manage.entity.AgvInfoParams;
import org.opentcs.manage.entity.AgvStatus;
import org.opentcs.util.ExplainedBoolean; import org.opentcs.util.ExplainedBoolean;
import org.opentcs.virtualvehicle.VelocityController.WayEntry; import org.opentcs.virtualvehicle.VelocityController.WayEntry;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -108,9 +117,27 @@ public class LoopbackCommunicationAdapter
*/ */
private static String CURRENT_POS; 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. * Creates a new instance.
@ -125,7 +152,9 @@ public class LoopbackCommunicationAdapter
@Assisted @Assisted
Vehicle vehicle, Vehicle vehicle,
@KernelExecutor @KernelExecutor
ScheduledExecutorService kernelExecutor ScheduledExecutorService kernelExecutor,
TCSObjectService objectService, // 注入对象服务
VehicleService vehicleService
) { ) {
super( super(
new LoopbackVehicleModel(vehicle), new LoopbackVehicleModel(vehicle),
@ -135,6 +164,8 @@ public class LoopbackCommunicationAdapter
); );
this.vehicle = requireNonNull(vehicle, "vehicle"); this.vehicle = requireNonNull(vehicle, "vehicle");
this.configuration = requireNonNull(configuration, "configuration"); this.configuration = requireNonNull(configuration, "configuration");
this.objectService = requireNonNull(objectService, "objectService");
this.vehicleService = requireNonNull(vehicleService, "vehicleService");
} }
@Override @Override
@ -228,6 +259,15 @@ public class LoopbackCommunicationAdapter
} }
LOG.info("Loopback comm adapter is being disable: {}", getName()); LOG.info("Loopback comm adapter is being disable: {}", getName());
super.disable(); 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 @Override
@ -257,8 +297,8 @@ public class LoopbackCommunicationAdapter
ORDER_NAME = cmd.getTransportOrder().getName(); ORDER_NAME = cmd.getTransportOrder().getName();
//下发起点 //下发起点
CURRENT_POS = sourcePoint; CURRENT_POS = sourcePoint;
//当前执行taskKey // //当前执行taskKey
TASK_KEY = 1; // TASK_KEY = 1;
// The command is added to the sent queue after this method returns. Therefore // The command is added to the sent queue after this method returns. Therefore
// we have to explicitly start the simulation like this. // we have to explicitly start the simulation like this.
@ -293,6 +333,7 @@ public class LoopbackCommunicationAdapter
@Override @Override
public synchronized void initVehiclePosition(String newPos) { public synchronized void initVehiclePosition(String newPos) {
LAST_PASSED_POINT = newPos;
((ExecutorService) getExecutor()).submit(() -> getProcessModel().setPosition(newPos)); ((ExecutorService) getExecutor()).submit(() -> getProcessModel().setPosition(newPos));
} }
@ -398,11 +439,33 @@ public class LoopbackCommunicationAdapter
getProcessModel().setState(Vehicle.State.EXECUTING); getProcessModel().setState(Vehicle.State.EXECUTING);
Step step = command.getStep(); 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) { if (step.getPath() == null) {
actionExec(command); actionExec(command);
} else { } else {
ExecuteMove.setExecTaskKey(getProcessModel().getName(), TASK_KEY); // ExecuteOperation.setExecTaskKey(getProcessModel().getName(), TASK_KEY);
TASK_KEY++; // TASK_KEY++;
//todo 移动 //todo 移动
movementExec(command); movementExec(command);
} }
@ -432,9 +495,6 @@ public class LoopbackCommunicationAdapter
//下发动作 //下发动作
ExecuteAction.sendCmd(getProcessModel().getName(), command.getOperation(), getSerialNum()); ExecuteAction.sendCmd(getProcessModel().getName(), command.getOperation(), getSerialNum());
// 结束动作
finishCmd(command);
//进入阻塞 //进入阻塞
while (ACTION_STATUS) { while (ACTION_STATUS) {
try { try {
@ -444,6 +504,8 @@ public class LoopbackCommunicationAdapter
} }
} }
// 结束动作
finishCmd(command);
//继续执行动作 //继续执行动作
nextCmd(); nextCmd();
} }
@ -778,13 +840,19 @@ public class LoopbackCommunicationAdapter
//更新车辆姿态 //更新车辆姿态
if (params.getPoint() != 0) { if (params.getPoint() != 0) {
LAST_PASSED_POINT = params.getPoint().toString(); //记录最终经过点
if (!Objects.equals(getProcessModel().getPosition(), params.getPoint().toString())) { if (!Objects.equals(getProcessModel().getPosition(), params.getPoint().toString())) {
getProcessModel().setPosition(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 { } else {
//最后经过点为0应该是车辆重启过车辆关机时应该正常对点位进行交管防止车辆碰撞 //最后经过点为0应该是车辆丢失定位或重启过todo 可能需要自动找点
//todo 可能需要实现原点自动定位暂时不做处理 }
if (ACTION_STATUS) {
vehicleState = Vehicle.State.EXECUTING;
} }
//更新电量 //更新电量

View File

@ -53,5 +53,8 @@ public interface LoopbackAdapterConstants {
* AGV 端口 * AGV 端口
*/ */
String AGV_PORT = "AGV:PORT"; String AGV_PORT = "AGV:PORT";
/**
* 对应路线车辆行驶姿态0=正走1=到走
*/
String AGV_DRIVE_POSE = "PATH:DRIVE_POSE";
} }

View File

@ -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.Path;
import org.opentcs.communication.http.dto.kc.move.Point; import org.opentcs.communication.http.dto.kc.move.Point;
import org.opentcs.communication.http.dto.kc.move.RequestAe; import org.opentcs.communication.http.dto.kc.move.RequestAe;
import org.opentcs.communication.http.service.ExecuteOperation;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -55,7 +56,23 @@ public class HttpClient {
*/ */
public static void main(String[] args) { 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 // { //0x02
// //变量成员 // //变量成员
@ -171,49 +188,49 @@ public class HttpClient {
// httpClient.sendCommand(baseRequestTo); // httpClient.sendCommand(baseRequestTo);
// } // }
{ //0xAE // { //0xAE
RequestAe ae = new RequestAe(); // RequestAe ae = new RequestAe();
ae.setWms_order_id(1); // ae.setWms_order_id(1);
ae.setOrder_id(1); // ae.setOrder_id(1);
ae.setTask_key(1); // ae.setTask_key(1);
ae.setPoint_size(2); // ae.setPoint_size(2);
ae.setPath_size(1); // ae.setPath_size(1);
//
ArrayList<Point> pointList = new ArrayList<>(); // ArrayList<Point> pointList = new ArrayList<>();
for (int i = 0; i < ae.getPoint_size(); i++) { // for (int i = 0; i < ae.getPoint_size(); i++) {
Point point = new Point(); // Point point = new Point();
//
if (i == 0) { // if (i == 0) {
point.setPoint_id(1); // point.setPoint_id(1);
point.setPoint_serial(0); // point.setPoint_serial(0);
} else { // } else {
point.setPoint_id(2); // point.setPoint_id(2);
point.setPoint_serial(2); // point.setPoint_serial(2);
} // }
point.setPoint_angle(0); // point.setPoint_angle(0);
//
pointList.add(point); // pointList.add(point);
} // }
ae.setPoint_info(pointList); // ae.setPoint_info(pointList);
//
ArrayList<Path> pathList = new ArrayList<>(); // ArrayList<Path> pathList = new ArrayList<>();
for (int i = 0; i < ae.getPath_size(); i++) { // for (int i = 0; i < ae.getPath_size(); i++) {
Path path = new Path(); // Path path = new Path();
//
path.setPath_id(12); // path.setPath_id(12);
path.setPath_serial(1); // path.setPath_serial(1);
path.setPath_angle(0); // path.setPath_angle(0);
path.setDriver_pose(1); // path.setDriver_pose(1);
path.setMax_speed(1); // path.setMax_speed(1);
path.setMax_angle_speed(1); // path.setMax_angle_speed(1);
//
pathList.add(path); // pathList.add(path);
} // }
ae.setPath_info(pathList); // ae.setPath_info(pathList);
//
BaseRequestTo baseRequestTo = new BaseRequestTo(2, "OPENTCS", "KC-CTRL", 1, "2025-6-6 10:00:00", ae); // 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); // httpClient.sendCommand("http://192.168.124.121:2005", baseRequestTo);
} // }
} }
} }

View File

@ -1,12 +1,34 @@
package org.opentcs.communication.http.service; package org.opentcs.communication.http.service;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
import org.opentcs.communication.http.enums.VehicleEnums; import org.opentcs.communication.http.enums.VehicleEnums;
public class BaseService { public class BaseService {
// 随机初始化起点减少重复概率
private static final AtomicInteger counter = new AtomicInteger(
ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE / 2)
);
public static String getUrl(String vehicleName) { public static String getUrl(String vehicleName) {
VehicleEnums vehicleEnums = VehicleEnums.valueOf(vehicleName); VehicleEnums vehicleEnums = VehicleEnums.valueOf(vehicleName);
return "http://" + vehicleEnums.getIp() + ":" + vehicleEnums.getPort(); 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;
}
} }

View File

@ -5,6 +5,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects; import java.util.Objects;
import org.opentcs.common.LoopbackAdapterConstants;
import org.opentcs.communication.http.HttpClient; import org.opentcs.communication.http.HttpClient;
import org.opentcs.communication.http.dto.BaseRequestTo; import org.opentcs.communication.http.dto.BaseRequestTo;
import org.opentcs.communication.http.dto.kc.move.Path; 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.dto.kc.move.RequestAe;
import org.opentcs.communication.http.entity.OrderInfo; import org.opentcs.communication.http.entity.OrderInfo;
import org.opentcs.drivers.vehicle.MovementCommand; import org.opentcs.drivers.vehicle.MovementCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExecuteMove extends BaseService { public class ExecuteMove extends BaseService {
/**
* LOG
*/
private static final Logger LOG = LoggerFactory.getLogger(ExecuteMove.class);
/** /**
* 订单名映射int类型数据. * 订单名映射int类型数据.
*/ */
private static final HashMap<String, OrderInfo> orderInfoMap = new HashMap<>(); 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; maxVelocity = 5;
Integer drivePose = getDrivePose(pathInfo); //行驶姿态
RequestAe ae = new RequestAe(); RequestAe ae = new RequestAe();
ae.setWms_order_id(1); //todo 测试填写 ae.setWms_order_id(1); //todo 测试填写
ae.setOrder_id(orderID); ae.setOrder_id(orderID);
@ -112,7 +117,7 @@ public class ExecuteMove extends BaseService {
path.setPath_id(pathID); path.setPath_id(pathID);
path.setPath_serial(orderInfo.getPathSerialNum()); path.setPath_serial(orderInfo.getPathSerialNum());
path.setPath_angle(0); path.setPath_angle(0);
path.setDriver_pose(0); path.setDriver_pose(drivePose);
path.setMax_speed(maxVelocity); path.setMax_speed(maxVelocity);
path.setMax_angle_speed(maxVelocity); path.setMax_angle_speed(maxVelocity);
@ -138,13 +143,8 @@ public class ExecuteMove extends BaseService {
//当前车辆已存在集合中 //当前车辆已存在集合中
OrderInfo orderInfo = orderInfoMap.get(vehicleName); OrderInfo orderInfo = orderInfoMap.get(vehicleName);
if (!Objects.equals(orderName, orderInfo.getName())) { if (!Objects.equals(orderName, orderInfo.getName()) && orderInfoMap.containsKey(vehicleName)) {
//订单名称不相等为执行下一个订单初始化订单对应参数 orderInfo.setId(generate());
orderInfoMap.remove(vehicleName);
Integer currentOrderId = orderInfo.getId() + 1;
orderInfo.setId(currentOrderId);
orderInfo.setName(orderName); orderInfo.setName(orderName);
orderInfo.setState(1); orderInfo.setState(1);
orderInfo.setTaskKey(1); orderInfo.setTaskKey(1);
@ -154,7 +154,7 @@ public class ExecuteMove extends BaseService {
} else { } else {
//车辆不在集合中 //车辆不在集合中
OrderInfo orderInfo = new OrderInfo(); OrderInfo orderInfo = new OrderInfo();
orderInfo.setId(1); //todo 测试修改正式上线应该为1 orderInfo.setId(generate());
orderInfo.setName(orderName); orderInfo.setName(orderName);
orderInfo.setState(1); orderInfo.setState(1);
orderInfo.setTaskKey(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 * 获取当前订单ID
*/ */
public static Integer getOrderID(String vehicleName) { public static Integer getOrderID(String vehicleName) {
return orderInfoMap.get(vehicleName).getId(); 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;
}
} }

View File

@ -2,6 +2,7 @@ package org.opentcs.communication.http.service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import org.opentcs.communication.http.HttpClient; import org.opentcs.communication.http.HttpClient;
import org.opentcs.communication.http.dto.BaseRequestTo; import org.opentcs.communication.http.dto.BaseRequestTo;
import org.opentcs.communication.http.dto.kc.operation.Action01; import org.opentcs.communication.http.dto.kc.operation.Action01;
@ -18,6 +19,14 @@ public class ExecuteOperation extends BaseService{
* This class's Logger. * This class's Logger.
*/ */
private static final Logger LOG = LoggerFactory.getLogger(ExecuteOperation.class); 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); b2.setParam_size(4);
Action01 action01 = new Action01(); Action01 action01 = new Action01();
action01.setIsStopImmediately(1); action01.setIsStopImmediately(0);
b2.setParam_data(action01); b2.setParam_data(action01);
@ -49,7 +58,7 @@ public class ExecuteOperation extends BaseService{
Integer orderId = ExecuteMove.getOrderID(vehicleName); Integer orderId = ExecuteMove.getOrderID(vehicleName);
//获取任务key //获取任务key
Integer taskKey = ExecuteMove.getTaskKey(vehicleName); Integer taskKey = getTaskKey(vehicleName);
RequestB2 b2 = new RequestB2(); RequestB2 b2 = new RequestB2();
@ -69,9 +78,8 @@ public class ExecuteOperation extends BaseService{
/** /**
* 撤销订单 * 撤销订单
* @param vehicleName 车辆名称 * @param vehicleName 车辆名称
* @param serialNum 序列号
*/ */
public static void cancelOrder(String vehicleName, Integer serialNum) { public static void cancelOrder(String vehicleName) {
//获取订单ID //获取订单ID
Integer orderId = ExecuteMove.getOrderID(vehicleName); Integer orderId = ExecuteMove.getOrderID(vehicleName);
@ -84,11 +92,11 @@ public class ExecuteOperation extends BaseService{
Action03 action03 = new Action03(); Action03 action03 = new Action03();
action03.setOrderId(orderId); action03.setOrderId(orderId);
action03.setIsStopImmediately(1); action03.setIsStopImmediately(0);
b2.setParam_data(action03); b2.setParam_data(action03);
sendCmd(vehicleName, b2, serialNum); sendCmd(vehicleName, b2, getSerialNum());
} }
public static void sendCmd(String vehicleName, Object data, Integer serialNum) public static void sendCmd(String vehicleName, Object data, Integer serialNum)
@ -107,4 +115,26 @@ public class ExecuteOperation extends BaseService{
httpClient.sendCommand(url, baseRequestTo); 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++;
}
} }

View File

@ -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消息
}
}

View File

@ -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;
}
}

View File

@ -1,7 +0,0 @@
package org.opentcs.communication.mqtt.service;
public class ExecuteOperation {
}

View File

@ -7,11 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.opentcs.access.KernelServicePortal;
import org.opentcs.access.rmi.KernelServicePortalBuilder;
import org.opentcs.common.GuestUserCredentials; 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.AgvInfo;
import org.opentcs.manage.entity.AgvInfoParams; import org.opentcs.manage.entity.AgvInfoParams;
import org.opentcs.manage.entity.AgvStatus; import org.opentcs.manage.entity.AgvStatus;
@ -45,15 +41,6 @@ public class AdapterManage {
* 设置自动关闭适配器时间阈值单位毫秒 * 设置自动关闭适配器时间阈值单位毫秒
*/ */
private static final Long AUTO_CLOSE_TIME = 2000L; 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; private static final String USER = GuestUserCredentials.USER;
@ -63,7 +50,7 @@ public class AdapterManage {
//开启定时任务 //开启定时任务
public void START() { 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(); Date date = new Date();
long currentTime = date.getTime(); long currentTime = date.getTime();
System.out.println("autoManageAdapterStatus sout: " + adapterStatusMap); // System.out.println("autoManageAdapterStatus sout: " + adapterStatusMap);
adapterStatusMap.forEach((key, value) -> { adapterStatusMap.forEach((key, value) -> {
LOG.info("adapterStatusMap starts name: {}", key); // LOG.info("adapterStatusMap starts name: {}", key);
AgvStatus agvStatus = new AgvStatus(); AgvStatus agvStatus = new AgvStatus();
agvStatus.setTime(value.getTime()); agvStatus.setTime(value.getTime());
@ -108,8 +95,7 @@ public class AdapterManage {
//更新记录数据 //更新记录数据
adapterStatusMap.put(key, agvStatus); 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.setTime(jsonObject.getString("time"));
agvInfo.setParams(getAgvInfoParams(jsonObject.getString("params"))); agvInfo.setParams(getAgvInfoParams(jsonObject.getString("params")));
// adapterDataMap.put(name, agvInfo);
return agvInfo; return agvInfo;
} }
@ -181,44 +166,4 @@ public class AdapterManage {
Boolean ENABLE = true; Boolean ENABLE = true;
Boolean DISABLE = false; 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);
// }
} }

View File

@ -1,7 +1,8 @@
package org.opentcs.traffic.common; package org.opentcs.traffic.common;
import java.util.HashMap; import java.awt.geom.Point2D;
import org.opentcs.traffic.entity.VehicleAttr; import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -30,9 +31,19 @@ public class ContourAlgorithm {
* *
* @return true,可通过false不通过 * @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; return true;
} }

View File

@ -15,9 +15,6 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; 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.RouterService;
import org.opentcs.components.kernel.services.VehicleService; import org.opentcs.components.kernel.services.VehicleService;
import org.opentcs.data.ObjectUnknownException; import org.opentcs.data.ObjectUnknownException;
@ -74,8 +71,12 @@ public class VehicleHandler {
System.out.println("jsonObject-----ssss: " + data.toString()); System.out.println("jsonObject-----ssss: " + data.toString());
//截取平台响应的字符串 //截取平台响应的字符串
String jsonStr = data.toString().split("=", 2)[1]; String jsonStr;
// String jsonStr = data.toString(); try {
jsonStr = data.toString().split("=", 2)[1];
} catch (Exception e) {
jsonStr = data.toString();
}
JSONObject jsonObject = JSON.parseObject(jsonStr); JSONObject jsonObject = JSON.parseObject(jsonStr);
String name = jsonObject.getString("vehicle_name"); String name = jsonObject.getString("vehicle_name");
Integer type = jsonObject.getInteger("type"); Integer type = jsonObject.getInteger("type");

View File

@ -42,6 +42,7 @@ public class DefaultPropertySuggestions
keySuggestions.add(LoopbackAdapterConstants.AGV_AUTHORIZE_CODE); keySuggestions.add(LoopbackAdapterConstants.AGV_AUTHORIZE_CODE);
keySuggestions.add(LoopbackAdapterConstants.AGV_IP); keySuggestions.add(LoopbackAdapterConstants.AGV_IP);
keySuggestions.add(LoopbackAdapterConstants.AGV_PORT); keySuggestions.add(LoopbackAdapterConstants.AGV_PORT);
keySuggestions.add(LoopbackAdapterConstants.AGV_DRIVE_POSE);
} }
@Override @Override

View File

@ -10,6 +10,7 @@ import jakarta.inject.Inject;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.opentcs.communication.http.service.ExecuteOperation;
import org.opentcs.components.Lifecycle; import org.opentcs.components.Lifecycle;
import org.opentcs.components.kernel.Router; import org.opentcs.components.kernel.Router;
import org.opentcs.components.kernel.services.InternalTransportOrderService; import org.opentcs.components.kernel.services.InternalTransportOrderService;
@ -355,6 +356,9 @@ public class TransportOrderUtil
// vehicle reports the remaining movements as finished. // vehicle reports the remaining movements as finished.
updateTransportOrderState(order.getReference(), TransportOrder.State.WITHDRAWN); updateTransportOrderState(order.getReference(), TransportOrder.State.WITHDRAWN);
//撤销订单
ExecuteOperation.cancelOrder(vehicle.getName());
VehicleController vehicleController VehicleController vehicleController
= vehicleControllerPool.getVehicleController(vehicle.getName()); = vehicleControllerPool.getVehicleController(vehicle.getName());