台湾展会用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

398 lines
16 KiB

package com.galaxis.rcs;
import com.galaxis.rcs.common.entity.AddTaskRequest;
import com.galaxis.rcs.common.entity.AddTaskResult;
import com.galaxis.rcs.common.enums.LCCDirection;
import com.galaxis.rcs.connector.cl2.Cl2Item;
import com.galaxis.rcs.plan.path.PathUtils;
import com.google.common.base.Strings;
import com.yvan.logisticsModel.LogisticsRuntime;
import com.yvan.logisticsModel.LogisticsRuntimeService;
import com.yvan.logisticsModel.StaticItem;
import com.yvan.workbench.SpringContext;
import com.yvan.workbench.model.entity.LccProject;
import com.yvan.workbench.service.LccMapService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.clever.core.Conv;
import org.clever.core.json.JsonWrapper;
import org.clever.core.mapper.JacksonMapper;
import org.clever.data.jdbc.DaoFactory;
import org.clever.data.jdbc.QueryDSL;
import org.clever.data.jdbc.querydsl.utils.QueryDslUtils;
import java.util.List;
import java.util.Map;
import static com.galaxis.rcs.common.query.QLccBasExecutor.lccBasExecutor;
/**
* RCS 对外API调用类
*/
@Slf4j
public class RCSService {
public static void ok() {
}
/**
* 添加任务
*/
public static AddTaskResult addTask(String projectUuid, long envId, AddTaskRequest request) {
AddTaskResult result = new AddTaskResult();
LogisticsRuntime logisticsRuntime = LogisticsRuntimeService.INSTANCE.getByProjectEnv(projectUuid, envId);
String bizTaskId = logisticsRuntime.taskService.addBizTask(request);
result.bizTaskId = bizTaskId;
return result;
}
@SneakyThrows
public static void projectStart(String projectUuid, Long envId) {
LogisticsRuntime runtime = LogisticsRuntimeService.INSTANCE.getByProjectEnv(projectUuid, envId);
if (runtime != null) {
log.info("Project {} with envId {} is already started.", projectUuid, envId);
return;
}
var lccMapService = SpringContext.HOLDER.getBean(LccMapService.class);
var project = lccMapService.getProjectById(projectUuid);
if (project == null) {
throw new RuntimeException("Project not found: " + projectUuid);
}
if (project.getOtherData().isEmpty()) {
throw new RuntimeException("Project " + projectUuid + " has no data.");
}
if (project.getDirectoryData().length == 0) {
throw new RuntimeException("Project " + projectUuid + " has no catalog data.");
}
var env = lccMapService.getEnvById(projectUuid, envId);
if (env.getEnvConfig() == null) {
throw new RuntimeException("Project " + projectUuid + " envId " + envId + " has no envConfig data.");
}
runtime = LogisticsRuntimeService.INSTANCE.create(project, env);
// 获取所有楼层数据
for (LccProject.CatalogGroup floor : project.getDirectoryData()) {
for (LccProject.CatalogItem item : floor.getItems()) {
String catalogCode = item.getCatalogCode();
if (Strings.isNullOrEmpty(catalogCode)) {
continue;
}
// 读取楼层数据
String floorJson = lccMapService.loadFloor(projectUuid, catalogCode);
if (!Strings.isNullOrEmpty(floorJson)) {
List<Map<String, Object>> items = JacksonMapper.getInstance().fromJson(floorJson, List.class);
runtime.loadMap(catalogCode, items);
}
}
}
// 读取所有的库存
// 读取所有的执行器
// 读取地图上所有的车
final QueryDSL queryDSL = DaoFactory.getQueryDSL();
var list = queryDSL.select(QueryDslUtils.linkedMap(
lccBasExecutor.executorId,
lccBasExecutor.virtualLocationAt,
lccBasExecutor.virtualExecutorPayload
))
.from(lccBasExecutor)
.where(lccBasExecutor.envId.eq(envId))
.where(lccBasExecutor.isActive.eq(true))
.fetch();
for (var item : list) {
// 车的属性
String payload = Conv.asString(item.get("virtual_executor_payload"));
/**
* {
* "id": "3",
* "t": "cl2",
* "v": true,
* "dt": {
* "ptrWidth": 1.5,
* "ptrDepth": 1.5,
* "ptrHeight": 1.98
* }
* }
*/
JsonWrapper jwPayload = new JsonWrapper(payload);
String wayPointId = "";
String direction = "";
if (env.getIsVirtual()) {
// 如果是虚拟车,需要读取虚拟姿态
String virtualLocationAt = Conv.asString(item.get("virtual_location_at"));
if (Strings.isNullOrEmpty(virtualLocationAt)) {
log.warn("Virtual location at is null for executorId: {}", item.get("executor_id"));
continue; // 跳过虚拟位置为空的执行器
}
if (!virtualLocationAt.contains(":")) {
log.warn("Invalid virtual_location_at format: {}, id:{}", virtualLocationAt, item.get("executor_id"));
continue; // 跳过格式不正确的虚拟位置
}
String[] parts = virtualLocationAt.split(":");
wayPointId = parts[0];
direction = parts[1];
if(Strings.isNullOrEmpty(wayPointId)){
log.warn("wayPointId is empty for executorId: {}", item.get("executor_id"));
continue; // 跳过wayPointId为空的执行器
}
if(Strings.isNullOrEmpty(direction)) {
log.warn("direction is empty for executorId: {}", item.get("executor_id"));
continue; // 跳过方向为空的执行器
}
}
switch (jwPayload.asStr("t")) {
case "cl2":
case "clx":
// 处理 CL2 或 CLX 类型的执行器
// 车所在的标记位置,及方向 11_4:RIGHT
var eitem = new Cl2Item(runtime, (Map<String, Object>) jwPayload.getInnerMap());
// 找到地标位置
StaticItem staticItem = runtime.getStaticItemById(wayPointId);
if (staticItem != null) {
eitem.logicX = staticItem.logicX;
eitem.logicY = staticItem.logicY;
eitem.direction = PathUtils.convertDirectionToPtrDiretion(LCCDirection.fromString(direction));
} else {
log.warn("Static item not found for wayPointId: {}", wayPointId);
}
runtime.executorItemMap.put(eitem.getId(), eitem);
break;
default:
log.warn("Unknown executor type: {}", jwPayload.asStr("t"));
continue; // 跳过未知类型
}
}
runtime.start();
}
// /**
// * 初始化RCS服务
// */
// public void init() {
// this.createAutoStartEnv();
// }
//
// /**
// * 加载所有自动启动的环境和楼层数据
// * 并启动对应的环境
// */
// @SneakyThrows
// private void createAutoStartEnv() {
// QueryDSL queryDSL = DaoFactory.getQueryDSL();
// var list = queryDSL.select(QueryDslUtils.linkedMap(
// lccEnvInfo.envId,
// lccEnvInfo.worldId,
// lccEnvInfo.envPayload,
// lccModelFloor.catalogCode
//
// )).from(lccEnvInfo)
// .innerJoin(lccModelFloor).on(
// lccEnvInfo.worldId.eq(lccModelFloor.projectUuid)
// )
// .where(lccEnvInfo.autoStart.eq(true))
// .where(lccModelFloor.autoStart.eq(true))
// .fetch();
//
// Map<LogisticsRuntime, EnvConfig> runtimePayLoad = Maps.newHashMap();
// for (Map<String, Object> map : list) {
// long envId = Conv.asLong(map.get("env_id"));
// String projectUuid = Conv.asString(map.get("world_id"));
// String envPayload = Conv.asString(map.get("env_payload"));
// String catalogCode = Conv.asString(map.get("catalog_code"));
//
// EnvConfig payload;
// if (!Strings.isNullOrEmpty(envPayload) && !"N/A".equals(envPayload)) {
// payload = new JsonWrapper(envPayload).asObject(EnvConfig.class);
// } else {
// payload = new EnvConfig();
// }
//
// var runtime = loadFloor(projectUuid, catalogCode, envId, payload);
// runtimePayLoad.put(runtime, payload);
// }
//
// String[] logBanners = new String[runtimePayLoad.entrySet().size()];
// int i = 0;
// for (Map.Entry<LogisticsRuntime, EnvConfig> entry : runtimePayLoad.entrySet()) {
// var runtime = entry.getKey();
// var envPayload = entry.getValue();
//
// logBanners[i++] = String.format("projectUUID: %s, envId: %d", runtime.projectUUID, runtime.envId);
//
// EnvStartParam param = new EnvStartParam();
// param.setTimeRate(1);
// param.setVirtual(false);
// param.setEnvConfig(envPayload);
// param.setClientId(InetAddress.getLocalHost().getHostName());
// runtime.start(param);
// }
//
// BannerUtils.printConfig(log, "RCS服务已启动", logBanners);
// }
// /**
// * 加载项目的楼层数据 (只加载物理生产环境)
// */
// @SneakyThrows
// public static LogisticsRuntime loadFloor(String projectUUID, String catalogCode, long envId, EnvConfig envConfig) {
// LogisticsRuntime runtime = LogisticsRuntimeService.INSTANCE.getByProjectEnv(projectUUID, envId);
// if (runtime == null) {
// QueryDSL queryDsl = DaoFactory.getQueryDSL();
// String floorPayload = queryDsl.select(QLccModelFloor.lccModelFloor.items)
// .from(QLccModelFloor.lccModelFloor)
// .where(QLccModelFloor.lccModelFloor.projectUuid.eq(projectUUID))
// .where(QLccModelFloor.lccModelFloor.catalogCode.eq(catalogCode))
// .fetchFirst();
//
// if (Strings.isNullOrEmpty(floorPayload)) {
// throw new RuntimeException("not found floor data for projectUUID: " + projectUUID + ", catalogCode: " + catalogCode);
// }
//
// JsonWrapper jw = new JsonWrapper("{ \"catalogCode\": \"" + catalogCode + "\", \"t\": \"floor\", \"items\": " + floorPayload + "}");
//
// runtime = LogisticsRuntimeService.INSTANCE.createEnv(projectUUID, envId);
//
// log.info("loadFloor: projectUUID={}, catalogCode={}, envId={}", projectUUID, catalogCode, envId);
// runtime.loadMap(jw);
// }
// return runtime;
// }
// public static Object runPath() {
// String executorId = "10"; // 执行器ID
// String lpn = "pallet1124";
// long envId = 1;
//
// LogisticsRuntime logisticsRuntime = LogisticsRuntimeService.INSTANCE.findByEnvCode(envId);
// RcsTaskBiz bizTask = new RcsTaskBiz();
// bizTask.setBizTaskId(100L);
// bizTask.setEnvId(envId);
// bizTask.setBizType(BizTaskType.CARRY.toString());
// bizTask.setLpn(lpn);
// bizTask.setPriority(1);
// bizTask.setTaskFrom("rack1_0_1_0");
// bizTask.setTaskTo("54_0_0_0");
// bizTask.setAllocatedExecutorId(executorId);
// bizTask.setBizTaskPayload("N/A");
// bizTask.setBizTaskErrorInfo("N/A");
// bizTask.setBizTaskDescription("N/A");
// bizTask.setBizTaskStatus(BizTaskStatus.WAITING_FOR_DISPATCH.toString());
//
// PlanTaskSequence planSequence = new PlanTaskSequence(executorId, logisticsRuntime, bizTask, "demo");
//
// CarryTask carryTask = new CarryTask(
// executorId, lpn, 1,
// new StoreLocation("rack1", 0, 1, 0),
// new StoreLocation("54", 0, 0, 0)
// );
//
// logisticsRuntime.pathPlannerMap.get("cl2")
// .planCarryTask(planSequence, "17", LCCDirection.DOWN, carryTask);
// return planSequence.toPrettyMap();
// }
//
// public static Object runPath2() {
// String executorId = "10"; // 执行器ID
// String lpn = "pallet1124";
// long envId = 1;
//
// LogisticsRuntime logisticsRuntime = LogisticsRuntimeService.INSTANCE.findByEnvCode(envId);
// RcsTaskBiz bizTask = new RcsTaskBiz();
// bizTask.setBizTaskId(100L);
// bizTask.setEnvId(envId);
// bizTask.setBizType(BizTaskType.CARRY.toString());
// bizTask.setLpn(lpn);
// bizTask.setPriority(1);
// bizTask.setTaskFrom("rack1_0_1_0");
// bizTask.setTaskTo("54_0_0_0");
// bizTask.setAllocatedExecutorId(executorId);
// bizTask.setBizTaskPayload("N/A");
// bizTask.setBizTaskErrorInfo("N/A");
// bizTask.setBizTaskDescription("N/A");
// bizTask.setBizTaskStatus(BizTaskStatus.WAITING_FOR_DISPATCH.toString());
//
// PlanTaskSequence planSequence = new PlanTaskSequence(executorId, logisticsRuntime, bizTask, "demo");
//
// CarryTask carryTask = new CarryTask(
// executorId, lpn, 1,
// new StoreLocation("rack1", 0, 1, 0),
// new StoreLocation("54", 0, 0, 0)
// );
//
// logisticsRuntime.pathPlannerMap.get("cl2")
// .planCarryTask(planSequence, "27", LCCDirection.UP, carryTask);
// return planSequence.toPrettyMap();
// }
//
// public static void runDemo() {
// String executorId = "10"; // 执行器ID
// String lpn = "pallet1124";
// long envId = 1;
//
// AddTaskRequest request = new AddTaskRequest();
// request.setType(BizTaskType.CARRY);
// request.setTaskExecutorId(executorId);
// request.setLpn(lpn);
// request.setPriority(1);
// request.setFrom(new StoreLocation("rack1", 0, 1, 0));
// request.setTo(new StoreLocation("54", 0, 0, 0));
// request.setDescription("从rack1的0/1/0, 取货到地堆54");
// request.setCreateBy("runDemo");
//
// AddTaskResult result = RCSService.addTask(envId, request);
//
// LogisticsRuntime logisticsRuntime = LogisticsRuntimeService.INSTANCE.findByEnvCode(envId);
// RcsTaskBiz bizTask = logisticsRuntime.taskService.waitingTaskList.get(logisticsRuntime.taskService.waitingTaskList.size() - 1);
//
//
// Planner planner = TaskPlannerFactory.getPlanner("cl2");
//
// // 规划任务序列
// PlanTaskSequence planSequence = new PlanTaskSequence(executorId, logisticsRuntime, bizTask, "demo");
// planSequence.addMoveTo("20");
// planSequence.addMoveTo("21");
// planSequence.addMoveTo("22");
// planSequence.addMoveTo("23");
// planSequence.addRotationTo(90);
// planSequence.addMoveTo("24");
// planSequence.addMoveTo("25");
// planSequence.addMoveTo("26");
// planSequence.addMoveTo("27");
// planSequence.addLoad(lpn, "rack1", 0, 1, 0);
// planSequence.addMoveTo("26");
// planSequence.addMoveTo("25");
// planSequence.addMoveTo("24");
// planSequence.addMoveTo("23");
// planSequence.addRotationTo(-90);
// planSequence.addMoveTo("22");
// planSequence.addMoveTo("21");
// planSequence.addMoveTo("20");
// planSequence.addUnload("54", 0, 0, 0);
// planSequence.addFinish();
//
// planner.appendSequence(planSequence);
// }
//
// public static LogisticsRuntime getDemo() {
// return LogisticsRuntimeService.INSTANCE.findByEnvCode(1L);
// }
}