任务优化

This commit is contained in:
cbs 2025-05-30 14:16:30 +08:00
parent 4683480d39
commit 58755daf70
11 changed files with 154 additions and 53 deletions

View File

@ -42,7 +42,11 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
String batSoc = robotStatusData.getHwStates().getBatSoc();
if (ObjectUtil.isNotEmpty(batSoc)) {
String[] split = batSoc.split("\\.");
batSoc = split[1].substring(0,2);
batSoc = split[1];
if (batSoc.length() > 2) {
batSoc = batSoc.substring(0,2);
}
if (batSoc.startsWith("0")) {
batSoc = batSoc.substring(1);
}

View File

@ -27,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@ -45,9 +47,11 @@ public class RobotStatusApiImpl implements RobotStatusApi {
@Resource
private RequestProcessor processor;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
private static final ExecutorService executorService = Executors.newFixedThreadPool(5);
/*@Autowired
private ThreadPoolTaskExecutor taskExecutor;
*/
@Resource
private CommonApi commonApi;
@ -60,7 +64,9 @@ public class RobotStatusApiImpl implements RobotStatusApi {
@Override
@SystemRateLimiter(time = 1, count = 150, keyArg = "robotStatusUpdate", message = "机器人上报点位超过限流")
public void robotStatusUpdate(RobotPoseStatusDTO robotStatusDataDTO) {
updateRobotPosed(robotStatusDataDTO);
executorService.execute(() -> {
updateRobotPosed(robotStatusDataDTO);
});
}
/**
@ -126,8 +132,6 @@ public class RobotStatusApiImpl implements RobotStatusApi {
}
private void sendToPP(RobotStatusDataPoseDTO robotStatusDataPoseDTO) {
taskExecutor.execute(() -> {
commonApi.commonMethod(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE);
});
commonApi.commonMethod(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE);
}
}

View File

@ -192,7 +192,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DOING.getType()
, null);
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) ) {
chargeDoing(robotCompleteTaskDTO);
}
}
@ -258,12 +259,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotChargeLogDO build = RobotChargeLogDO
.builder()
.id(robotCompleteTaskDTO.getOrderId())
.taskStatus(ChargeTaskStatusEnum.CHARGEING.getType())
.build();
chargeLogMapper.updateById(build);
chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(),ChargeTaskStatusEnum.DONE.getType());
}
taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now());
@ -472,28 +468,18 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
private void chargeDoing(RobotCompleteTaskDTO robotCompleteTaskDTO) {
RobotCommandStateDTO commandStatus = robotCompleteTaskDTO.getCommandStatus();
Integer taskStatus = ChargeTaskStatusEnum.CHARGEING.getType();
//编辑地图会判断这表的状态,所以自动充电任务移动到充电点就改为完成
//自动充电任务移动到充电点就改为完成
if (ObjectUtil.isNotEmpty(commandStatus) && CommandTypeEnum.MOVE_POSES.getType().equals(commandStatus.getCommandType())
&& RobotExecutionStateConstant.DONE.equals(commandStatus.getExecutionState())) {
taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now());
setTaskDone(robotCompleteTaskDTO);
}
RobotChargeLogDO build = RobotChargeLogDO
.builder()
.id(robotCompleteTaskDTO.getOrderId())
.taskStatus(taskStatus)
.build();
chargeLogMapper.updateById(build);
chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(),ChargeTaskStatusEnum.CHARGEING.getType());
}
/**
* 任务完成
*
* @param robotCompleteTaskDTO
*/
private void taskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) {
public RobotTaskDetailDO setTaskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) {
//更新任务状态
RobotTaskDetailDO detailDO = new RobotTaskDetailDO();
detailDO.setId(robotCompleteTaskDTO.getOrderId());
@ -505,7 +491,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId());
List<RobotTaskDetailDO> taskDetails = robotTaskDetailMapper.queryByTaskId(robotTaskDetailDO.getRobotTaskId());
boolean done =
taskDetails.stream().noneMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.NEW.getType())));
taskDetails.stream().noneMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.NEW.getType()) ||
v.getTaskStatus().equals(RobotTaskDetailStatusEnum.DOING.getType())));
if (done) {
RobotTaskDO robotTaskDO = new RobotTaskDO();
robotTaskDO.setId(taskDetails.get(0).getRobotTaskId());
@ -514,6 +501,17 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskMapper.updateRobot(robotTaskDO);
taskCycleMapper.deletByRobotTaskId(taskDetails.get(0).getRobotTaskId());
}
return detailDO;
}
/**
* 任务完成
*
* @param robotCompleteTaskDTO
*/
private void taskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) {
RobotTaskDetailDO robotTaskDetailDO = setTaskDone(robotCompleteTaskDTO);
RobotInformationDO robotInformationDO = robotInformationMapper.selectOne(new LambdaQueryWrapperX<RobotInformationDO>()
.eq(RobotInformationDO::getRobotNo, robotTaskDetailDO.getRobotNo()));

View File

@ -36,4 +36,11 @@ public interface RobotChargeLogMapper extends BaseMapperX<RobotChargeLogDO> {
*/
List<String> getChargeFullRobotNos(@Param("chanceCycle") Integer chanceCycle,
@Param("robotNos") List<String> robotNos);
/**
*
* @param taskDetailId
* @param taskStatus
*/
void updateChargStatusByTaskId(@Param("taskDetailId") Long taskDetailId, @Param("taskStatus") Integer taskStatus);
}

View File

@ -50,6 +50,7 @@ import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogServic
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskService;
import cn.iocoder.yudao.module.system.service.robot.mapstop.RobotMapStopService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
@ -57,6 +58,7 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -123,6 +125,10 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl<RemoteCo
@Resource
private RobotTaskDetailService taskDetailService;
@Resource
@Lazy
private RobotTaskService taskService;
@Resource
private ControllerTaskTransferLogService controllerTaskTransferLogService;
@ -324,7 +330,12 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl<RemoteCo
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return doRobotChangeMode(remoteMode, remoteIp, robotNo,remoteControllerPort,remoteControllerIp);
RemoteRobotTransferDTO dto = doRobotChangeMode(remoteMode, remoteIp, robotNo, remoteControllerPort, remoteControllerIp);
if (!RemoteModeEnum.AUTOMATIC.getType().equals(remoteMode)) {
taskService.chargeDone(robotNo);
}
return dto;
} finally {
lock.unlock();
}

View File

@ -109,4 +109,10 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
* 校验是否存在未完成的任务
*/
void checkHaveDoingTask();
/**
* 设置车辆充电完成
* @param robotNo
*/
void chargeDone(String robotNo);
}

View File

@ -553,28 +553,28 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(taskAssignDTO.getOrderType())) {
robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getOrderId());
robotChargeLogs.setTaskStatus(ChargeTaskStatusEnum.DOING.getType());
chargeLogMapper.updateById(robotChargeLogs);
robotChargeLogs = chargeLogMapper.selectOne(new LambdaQueryWrapperX<RobotChargeLogDO>()
.eq(RobotChargeLogDO::getTaskDetailId, taskAssignDTO.getOrderId())
.orderByDesc(RobotChargeLogDO::getCreateTime)
.last("limit 1"));
chargeLogMapper.updateChargStatusByTaskId(taskAssignDTO.getOrderId(),ChargeTaskStatusEnum.CHARGEING.getType());
robotStatus = RobotStatusEnum.CHARGE.getType();
if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) {
if (ObjectUtil.isNotEmpty(robotChargeLogs) && ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) {
deviceNoMap.put(robotChargeLogs.getTaskDetailId(), robotChargeLogs.getDeviceNo());
}
if (ObjectUtil.isNotEmpty(robotChargeLogs) && ObjectUtil.isNotEmpty(robotChargeLogs.getDeviceNo())) {
setDeviceUseing(robotChargeLogs.getDeviceNo(), taskAssignDTO.getRobotNo());
}
}
chargeDone(taskAssignDTO.getRobotNo());
// chargeDone(taskAssignDTO.getRobotNo());
robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), robotStatus, taskAssignDTO.getOrderId());
RobotTaskDO robotTaskDO = setTaskDoing(taskAssignDTO.getOrderId(), taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId());
if (ObjectUtil.isNotEmpty(robotChargeLogs) && ObjectUtil.isNotEmpty(robotChargeLogs.getDeviceNo())) {
setDeviceUseing(robotChargeLogs.getDeviceNo(), taskAssignDTO.getRobotNo());
}
RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO();
logOne.setCommandType(taskAssignDTO.getOrderType());
String actionMsg = taskAssignDTO.getRobotActionMsg() + robotTaskDO.getTaskNo();
@ -1459,10 +1459,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
*
* @param robotNo
*/
private void chargeDone(String robotNo) {
@Override
public void chargeDone(String robotNo) {
RobotInformationDO robotInformationDO = robotInformationMapper.selectOne(new LambdaQueryWrapperX<RobotInformationDO>()
.eq(RobotInformationDO::getRobotNo, robotNo));
if (!RobotStatusEnum.CHARGE.getType().equals(robotInformationDO.getRobotStatus())) {
log.info("车辆非充电状态:{}",robotNo);
return;
}

View File

@ -15,7 +15,9 @@ import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
@ -90,6 +92,7 @@ public class RobotCameraServiceImpl extends ServiceImpl<RobotCameraMapper, Robot
/**
* 判断IP是否存在
*
* @param cameraAddVOList
*/
@Override
@ -107,7 +110,7 @@ public class RobotCameraServiceImpl extends ServiceImpl<RobotCameraMapper, Robot
}
List<String> ips = robotCameraDOs.stream().map(RobotCameraDO::getCameraIp).collect(Collectors.toList());
String join = StringUtils.join(ips, ",");
throw exception(CAMERA_IP_EXIST,"以下摄像头IP已经存在 "+join);
throw exception(CAMERA_IP_EXIST, "以下摄像头IP已经存在 " + join);
}
@Override
@ -116,20 +119,47 @@ public class RobotCameraServiceImpl extends ServiceImpl<RobotCameraMapper, Robot
List<RobotCameraDO> cameraDOList = BeanUtils.toBean(cameraAddVOList, RobotCameraDO.class);
for (RobotCameraDO robotCameraDO : cameraDOList) {
try {
if (ObjectUtil.isEmpty(robotCameraDO.getId())) {
robotCameraDO.setCameraAccount(AESEncryptionUtil.encrypt(robotCameraDO.getCameraAccount(),cameraSecretKey));
robotCameraDO.setCameraPassword(AESEncryptionUtil.encrypt(robotCameraDO.getCameraPassword(),cameraSecretKey));
}
setCameraAccountAndPassword(robotCameraDO);
} catch (Exception e) {
throw new RuntimeException(e);
throw exception(CAMERA_DECRYPTION_FAILED);
}
robotCameraDO.setRobotNo(robotNo);
}
cameraMapper.insert(cameraDOList);
}
private void setCameraAccountAndPassword(RobotCameraDO robotCameraDO) {
if (ObjectUtil.isEmpty(robotCameraDO.getId())) {
try {
robotCameraDO.setCameraAccount(AESEncryptionUtil.encrypt(robotCameraDO.getCameraAccount(), cameraSecretKey));
robotCameraDO.setCameraPassword(AESEncryptionUtil.encrypt(robotCameraDO.getCameraPassword(), cameraSecretKey));
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
robotCameraDO.setCameraAccount(getEncrypt(robotCameraDO.getCameraAccount()));
robotCameraDO.setCameraPassword(getEncrypt(robotCameraDO.getCameraPassword()));
}
}
public String getEncrypt(String str){
try {
AESEncryptionUtil.decrypt(str, cameraSecretKey);
return str;
} catch (Exception e) {
}
try {
return AESEncryptionUtil.encrypt(str, cameraSecretKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 根据车辆编号删除
*
* @param robotNo
*/
@Override

View File

@ -34,6 +34,7 @@ import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
import cn.iocoder.yudao.module.system.enums.robot.*;
import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum;
import cn.iocoder.yudao.module.system.enums.robot.information.ChargeTypeEnum;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskService;
import cn.iocoder.yudao.module.system.service.robot.job.DistributeTasksService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
@ -42,6 +43,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -105,6 +107,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Resource
private CommonApi commonApi;
@Resource
@Lazy
private RobotTaskService taskService;
/**
* 下发任务给PP
*/
@ -250,6 +256,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
List<RobotTaskDetailAddVO> taskDetails = new ArrayList<>();
List<RobotTaskDO> tasks = new ArrayList<>();
for (PositionMapItemDO v : robotMapItems) {
taskService.chargeDone(v.getRobotNo());
RobotTaskDO task = new RobotTaskDO();
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.MOVE_TASK_NO.getKey());
task.setTaskNo(moveTaskNo + DateUtils.getYearMonthDay() + incrementByKey);
@ -392,6 +401,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
//前一个任务是仅取货
List<String> robotDoTake = getRobotDoTake(robots);
for (RobotInformationDO robot : robots) {
taskService.chargeDone(robot.getRobotNo());
}
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.eq(PositionMapItemDO::getUseStatus, UseStatusEnum.FREE.getType()));
@ -469,7 +482,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber());
pathPlanning.setReleasePointId(toLocation.getMapItemId());
pathPlanningSetReleaseHeight(pathPlanning,toLocation);
pathPlanningSetReleaseHeight(pathPlanning, toLocation);
pathPlanning.setReleaseLevel(toLocation.getLocationStorey());
pathPlanning.setReleaseOffsetHeight(offsetHeight);
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) {
@ -493,18 +506,19 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
/**
* 设置放货高度
*
* @param pathPlanning
* @param toLocation
*/
private void pathPlanningSetReleaseHeight(TaskToPathPlanningDTO pathPlanning, WareHouseLocationDO toLocation) {
if ( ZeroOneEnum.ONE.getType().equals(toLocation.getLocationStorey())) {
if (ZeroOneEnum.ONE.getType().equals(toLocation.getLocationStorey())) {
pathPlanning.setReleaseHeight(0.0);
return;
}
WareHouseLocationDO nextLocation = locationMapper.selectOne(new LambdaQueryWrapperX<WareHouseLocationDO>()
.eq(WareHouseLocationDO::getId, toLocation.getMapItemId())
.eq(WareHouseLocationDO::getLocationStorey, toLocation.getLocationStorey()-1)
.eq(WareHouseLocationDO::getLocationStorey, toLocation.getLocationStorey() - 1)
.last("limit 1"));
if (ObjectUtil.isNotEmpty(nextLocation) && ObjectUtil.isNotEmpty(nextLocation.getLocationTotalHeight())) {
pathPlanning.setReleaseHeight(Double.valueOf(nextLocation.getLocationTotalHeight() + ""));
@ -513,7 +527,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
Integer locationStorey = toLocation.getLocationStorey() - 1;
double height = locationStorey * defaultTrayHeight;
log.info("放货设置默认高度 :{}",pathPlanning.getReleaseHeight());
log.info("放货设置默认高度 :{}", pathPlanning.getReleaseHeight());
pathPlanning.setReleaseHeight(height);
}
@ -530,7 +544,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
Integer locationStorey = fromLocation.getLocationStorey();
double height = locationStorey * defaultTrayHeight;
log.info("取货设置默认取货高度 :{}",height);
log.info("取货设置默认取货高度 :{}", height);
pathPlanning.setTakeHeight(height);
}

View File

@ -8,6 +8,13 @@ import java.util.Base64;
public class AESEncryptionUtil {
private static final String AES_ALGORITHM = "AES";
/**
* 加密
* @param plaintext
* @param key
* @return
* @throws Exception
*/
public static String encrypt(String plaintext, String key) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES_ALGORITHM);
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
@ -16,6 +23,13 @@ public class AESEncryptionUtil {
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* 解密
* @param ciphertext
* @param key
* @return
* @throws Exception
*/
public static String decrypt(String ciphertext, String key) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES_ALGORITHM);
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);

View File

@ -2,6 +2,17 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.robot.RobotChargeLogMapper">
<update id="updateChargStatusByTaskId">
update
robot_charge_log
set
task_status = #{taskStatus}
where
task_detail_id = #{taskDetailId}
and deleted = '0'
</update>
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。