Compare commits

...

3 Commits

Author SHA1 Message Date
cbs
81423a8ad3 取货高度 2025-05-26 09:05:03 +08:00
cbs
5507e49ff7 socket连接 2025-05-22 17:19:04 +08:00
cbs
dc4a221b20 充电任务优化 2025-05-22 16:23:33 +08:00
13 changed files with 200 additions and 127 deletions

View File

@ -77,7 +77,8 @@ public class RemoteControllerProcessor {
remoteControllerSocketDTO.setControllerPort(cockpitPort);
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(cockpitIp, cockpitPort), 1000);
socket.setKeepAlive(true);
socket.connect(new InetSocketAddress(cockpitIp, cockpitPort), 500);
remoteControllerSocketDTO.setSocket(socket);
} catch (IOException e) {
log.error("添加socket失败 :{}", e);
@ -153,6 +154,8 @@ public class RemoteControllerProcessor {
if (socket == null || socket.isClosed()) {
try {
socket = new Socket();
log.info("连接新的的socket");
socket.setKeepAlive(true);
socket.connect(new InetSocketAddress(cockpitIp, cockpit.getControllerPort()), 1000);
} catch (IOException e) {
log.error("连接socket出现异常 :{}", cockpitIp);

View File

@ -137,6 +137,7 @@ public class PathApiImpl implements PathApi {
@Override
public void graphMatchData(String message) {
TenantContextHolder.setTenantId(1L);
log.info("匹配路网的消息 :{}",message);
pathPlanningService.graphMatchData(message);
}

View File

@ -43,6 +43,9 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
if (ObjectUtil.isNotEmpty(batSoc)) {
String[] split = batSoc.split("\\.");
batSoc = split[1].substring(0,2);
if (batSoc.startsWith("0")) {
batSoc = batSoc.substring(1);
}
redisUtil.set(socKey,batSoc);
}
}

View File

@ -64,7 +64,7 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi {
@Override
public void robotReactiveStatus(String message) {
TenantContextHolder.setTenantId(1L);
log.info("切换地图 :{}",message);
log.info("车辆所在楼层和异常信息 :{}",message);
RobotReactiveStatusDTO data = JSON.parseObject(message, RobotReactiveStatusDTO.class);
String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + data.getMac();
String robotNo = robotInformationService.getRobotNoByMac(data.getMac());

View File

@ -157,30 +157,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
* @param robotCompleteTaskDTO
*/
private void robotTaskDoing(RobotCompleteTaskDTO robotCompleteTaskDTO, String robotDoingActionKey) {
String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac());
RobotTaskDetailActionLogDO lastLog = setLastLogDone(robotCompleteTaskDTO.getOrderId());
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
chargeDoing(robotCompleteTaskDTO, robotDoingActionKey, lastLog);
} else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO();
logOne.setActionMsg("车辆正在前往等待点");
logOne.setRobotNo(robotNo);
logOne.setStartTime(LocalDateTime.now());
logOne.setTaskDetailId(robotCompleteTaskDTO.getOrderId());
if (ObjectUtil.isNotEmpty(lastLog)) {
logOne.setCommandType(lastLog.getCommandType());
logOne.setTaskNo(lastLog.getTaskNo());
}
Long mapId = robotInformationService.getRobotMapIdByRobotNo(robotNo);
if (ObjectUtil.isNotEmpty(mapId)) {
logOne.setPositionMapId(mapId);
}
taskDetailActionLogService.createTaskDetailActionLog(logOne);
redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime);
} else {
taskDoing(robotCompleteTaskDTO, robotDoingActionKey);
}
taskDoing(robotCompleteTaskDTO, robotDoingActionKey);
if ((PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()))
@ -197,6 +175,10 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DOING.getType()
, null);
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
chargeDoing(robotCompleteTaskDTO);
}
}
/**
@ -243,7 +225,10 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
} else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType())) {
taskDone(robotCompleteTaskDTO);
}
} else if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
}
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotChargeLogDO build = RobotChargeLogDO
.builder()
.id(robotCompleteTaskDTO.getOrderId())
@ -355,19 +340,10 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
*
* @param robotCompleteTaskDTO
*/
private void chargeDoing(RobotCompleteTaskDTO robotCompleteTaskDTO, String robotDoingActionKey, RobotTaskDetailActionLogDO lastLog) {
RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO();
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())) {
RobotChargeLogDO robotChargeLogDO = chargeLogMapper.selectById(robotCompleteTaskDTO.getOrderId());
logOne.setActionMsg("车辆正在前往充电点" + robotChargeLogDO.getDeviceNo());
logOne.setTaskStage(RobotTaskStageEnum.MOVE.getType());
taskStatus = ChargeTaskStatusEnum.DOING.getType();
} else if (ObjectUtil.isNotEmpty(commandStatus)) {
logOne.setActionMsg("车辆正在充电");
logOne.setTaskStage(RobotTaskStageEnum.CHARGEING.getType());
}
//编辑地图会判断这表的状态,所以自动充电任务移动到充电点就改为完成
if (ObjectUtil.isNotEmpty(commandStatus) && CommandTypeEnum.MOVE_POSES.getType().equals(commandStatus.getCommandType())
@ -375,19 +351,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now());
}
String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac());
logOne.setRobotNo(robotNo);
logOne.setTaskDetailId(robotCompleteTaskDTO.getOrderId());
logOne.setCommandType(lastLog.getCommandType());
logOne.setTaskNo(lastLog.getTaskNo());
logOne.setStartTime(LocalDateTime.now());
Long mapId = robotInformationService.getRobotMapIdByRobotNo(robotNo);
if (ObjectUtil.isNotEmpty(mapId)) {
logOne.setPositionMapId(mapId);
}
taskDetailActionLogService.createTaskDetailActionLog(logOne);
redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime);
RobotChargeLogDO build = RobotChargeLogDO
.builder()
.id(robotCompleteTaskDTO.getOrderId())
@ -470,7 +433,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType());
}
} else if (PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
} else if (PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotChargeLogDO robotChargeLogDO = chargeLogMapper.selectById(robotCompleteTaskDTO.getOrderId());
if (CommandTypeEnum.MOVE_POSES.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在前往" + robotChargeLogDO.getDeviceNo() + "充电");
@ -480,7 +444,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.CHARGEING.getType());
}
} else if (PathTaskTypeEnum.MOVE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
} else if (PathTaskTypeEnum.MOVE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(robotCompleteTaskDTO.getOrderType())) {
if (CommandTypeEnum.MOVE_POSES.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在前往" + robotTaskDetailDO.getToLocationNo());
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.MOVE.getType());

View File

@ -12,6 +12,7 @@ public enum RobotCacheLockEnum {
TASK_NO("task:robot:no", "任务号"),
MOVE_TASK_NO("task:robot:no:move", "移动任务号"),
CHARGE_TASK_NO("task:robot:no:charge", "自动充电任务号"),
ROBOT_TASK_ADD_LOCK("robot:task:add:lock", "所有创建机器人任务的锁"),
ROBOT_RCS_HEART_BEAT_LOCK("robot:rcs:heart:beat:lock", "RCS维持与车机心跳的锁"),
ROBOT_STATISTICS_DURATION_LOCK("robot:statistics:duration:lock", "统计车辆工作时长的锁"),

View File

@ -114,10 +114,10 @@ public interface PositionMapItemService extends IService<PositionMapItemDO> {
/**
* 批量查询
* @param pointList
* @param ids
* @return
*/
List<PositionMapItemDO> getPositionMapItemByIds(List<Long> pointList);
List<PositionMapItemDO> getPositionMapItemByIds(List<Long> ids);
/**
* 获取随机数id

View File

@ -144,7 +144,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Value("${zn.robot_config.offset_height}")
private Double offsetHeight;
@Value("${zn.robot_config.default_tray_height:1.0}")
@Value("${zn.robot_config.default_tray_height:0.82}")
private Double defaultTrayHeight;
@Resource
@ -526,12 +526,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
throw exception(TASK_CHECK_HAVE_DOING_TASK);
}
List<String> commandTypes = PathTaskTypeEnum.getMistakeTaskTypes();
/*List<String> commandTypes = PathTaskTypeEnum.getMistakeTaskTypes();
List<RobotTaskDetailActionLogDO> actionLogDOList = taskDetailActionLogMapper.getMistakeTaskByCommandType(commandTypes);
if (ObjectUtil.isNotEmpty(actionLogDOList)) {
log.info("编辑地图存在未完成的移动到等待点/自动充电任务");
throw exception(TASK_CHECK_HAVE_DOING_TASK);
}
}*/
}
/**
@ -548,15 +548,13 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_QUERY_DOING_ACTION + mac;
redisUtil.del(robotDoingActionKey);
Long detailId = null;
Map<Long, String> deviceNoMap = new HashMap<>();
Integer robotStatus = RobotStatusEnum.DOING.getType();
//释放ware_position_map_item的使用状态并且将ActionLog设置为完成
releaseMapItemUseStatus(taskAssignDTO.getRobotNo());
RobotChargeLogDO robotChargeLogs = null;
String taskNo = "";
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(taskAssignDTO.getOrderType())) {
robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getOrderId());
@ -568,24 +566,14 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) {
deviceNoMap.put(robotChargeLogs.getTaskDetailId(), robotChargeLogs.getDeviceNo());
} else {
String signDate = DateUtil.date().setTimeZone(TimeZone.getTimeZone("UTC")).toString("yyyyMMdd'T'HHmmss'Z'");
taskNo = "AUTO_CHARGE_" + signDate;
}
detailId = ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId()) ? robotChargeLogs.getTaskDetailId() : null;
} else {
detailId = taskAssignDTO.getOrderId();
}
chargeDone(taskAssignDTO.getRobotNo());
robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), robotStatus, taskAssignDTO.getOrderId());
if (ObjectUtil.isNotEmpty(detailId)) {
RobotTaskDO robotTaskDO = setTaskDoing(detailId, taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId());
taskNo = robotTaskDO.getTaskNo();
}
RobotTaskDO robotTaskDO = setTaskDoing(taskAssignDTO.getOrderId(), taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId());
if (ObjectUtil.isNotEmpty(robotChargeLogs) && ObjectUtil.isNotEmpty(robotChargeLogs.getDeviceNo())) {
setDeviceUseing(robotChargeLogs.getDeviceNo(), taskAssignDTO.getRobotNo());
@ -593,11 +581,11 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO();
logOne.setCommandType(taskAssignDTO.getOrderType());
String actionMsg = ObjectUtil.isEmpty(taskNo) ? taskAssignDTO.getRobotActionMsg() : taskAssignDTO.getRobotActionMsg() + taskNo;
String actionMsg = taskAssignDTO.getRobotActionMsg() + robotTaskDO.getTaskNo();
logOne.setActionMsg(actionMsg);
logOne.setRobotNo(taskAssignDTO.getRobotNo());
logOne.setStartTime(LocalDateTime.now());
logOne.setTaskNo(taskNo);
logOne.setTaskNo(robotTaskDO.getTaskNo());
logOne.setCommandId(-1L);
logOne.setTaskDetailId(taskAssignDTO.getOrderId());
Long mapId = robotInformationService.getRobotMapIdByRobotNo(taskAssignDTO.getRobotNo());
@ -623,7 +611,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
//前一个任务是移动到点位或者移动到等待点需要把点位状态改为空闲
if (ObjectUtil.isEmpty(actionLog) || (!PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(actionLog.getCommandType()))
&& !PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(actionLog.getCommandType())) {
&& !PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(actionLog.getCommandType())) {
return;
}
@ -736,13 +724,16 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (ObjectUtil.isEmpty(taskDetailDO.getRobotNo())) {
taskDetailDO.setRobotNo(robotNo);
}
if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())
&& ObjectUtil.isNotEmpty(deviceNoMap.get(taskDetailDO.getId()))) {
if (ObjectUtil.isNotEmpty(deviceNoMap) && ObjectUtil.isNotEmpty(deviceNoMap.get(taskDetailDO.getId()))) {
taskDetailDO.setToLocationNo(deviceNoMap.get(taskDetailDO.getId()));
}
if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())
&& ObjectUtil.isNotEmpty(waitId)) {
PositionMapItemDO positionMapItem = positionMapItemService.getPositionMapItem(Long.valueOf(waitId));
if (ObjectUtil.isNotEmpty(positionMapItem)) {
taskDetailDO.setToLocationNo(positionMapItem.getSortNum() + "");
}
taskDetailDO.setToLocationId(Long.valueOf(waitId));
}
@ -1477,6 +1468,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (!RobotStatusEnum.CHARGE.getType().equals(robotInformationDO.getRobotStatus())) {
return;
}
RobotChargeLogDO robotChargeLogDO = chargeLogMapper.selectOne(new LambdaQueryWrapperX<RobotChargeLogDO>()
.eq(RobotChargeLogDO::getRobotNo, robotNo)
.orderByDesc(RobotChargeLogDO::getCreateTime)
@ -1484,11 +1476,22 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (ObjectUtil.isEmpty(robotChargeLogDO) || !ChargeTaskStatusEnum.CHARGEING.getType().equals(robotChargeLogDO.getTaskStatus())) {
return;
}
DeviceInformationDO deviceInformationDO = deviceInformationMapper.selectOne(new LambdaQueryWrapperX<DeviceInformationDO>()
.eq(DeviceInformationDO::getLastUser, robotNo)
.eq(DeviceInformationDO::getDeviceNo, robotChargeLogDO.getDeviceNo()));
log.info("结束充电任务 :{}", robotNo);
robotChargeLogDO.setEndTime(LocalDateTime.now());
deviceInformationService.chargeDeviceShrink(robotChargeLogDO.getDeviceNo());
if (ObjectUtil.isNotEmpty(deviceInformationDO)) {
log.info("充电桩设置为空闲 :{}", deviceInformationDO.getDeviceNo());
deviceInformationService.chargeDeviceShrink(robotChargeLogDO.getDeviceNo());
deviceInformationDO.setDeviceUseStatus(DeviceUseStatusEnum.IDLE.getType());
deviceInformationDO.setLastUser(null);
deviceInformationMapper.updateById(deviceInformationDO);
}
String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC +robotInformationDO.getMacAddress();
String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC + robotInformationDO.getMacAddress();
Object socObject = redisUtil.get(socKey);
if (ObjectUtil.isNotEmpty(socObject)) {
@ -1497,18 +1500,11 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
robotChargeLogDO.setTaskStatus(ChargeTaskStatusEnum.DONE.getType());
chargeLogMapper.updateById(robotChargeLogDO);
DeviceInformationDO deviceInformationDO = deviceInformationMapper.selectOne(new LambdaQueryWrapperX<DeviceInformationDO>()
.eq(DeviceInformationDO::getDeviceNo, robotChargeLogDO.getDeviceNo()));
deviceInformationDO.setDeviceUseStatus(DeviceUseStatusEnum.IDLE.getType());
deviceInformationDO.setLastUser(null);
deviceInformationMapper.updateById(deviceInformationDO);
log.info("充电桩设置为空闲 :{}", deviceInformationDO.getDeviceNo());
if (ObjectUtil.isEmpty(robotChargeLogDO.getTaskDetailId())) {
return;
}
RobotTaskDetailDO taskDetail = taskDetailMapper.selectById(robotChargeLogDO.getTaskDetailId());
if (ObjectUtil.isNotEmpty(taskDetail)) {
if (ObjectUtil.isNotEmpty(taskDetail) && RobotTaskTypeEnum.CHARGE.getType().equals(taskDetail.getTaskType())) {
taskDetail.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType());
taskDetailMapper.updateById(taskDetail);
RobotTaskDO robotTask = taskMapper.selectById(taskDetail.getRobotTaskId());

View File

@ -1,16 +1,21 @@
package cn.iocoder.yudao.module.system.service.robot.job;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO;
import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.config.CommonConfigMapper;
import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper;
@ -22,8 +27,10 @@ import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.enums.config.CommandConfigTypeEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceUseStatusEnum;
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.service.positionmap.PositionMapItemService;
import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
@ -37,10 +44,10 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@Service
@Slf4j
@ -70,6 +77,9 @@ public class AutoChargeServiceImpl implements AutoChargeService {
@Value("${zn.full_electricity:100}")
private String fullElectricity;
@Value("${zn.charge-no:CHARGE}")
private String chargeNo;
@Autowired
private RobotPathPlanningService robotPathPlanningService;
@ -89,7 +99,7 @@ public class AutoChargeServiceImpl implements AutoChargeService {
return;
}
CommonConfigVO chargeConfig= JSONUtil.toBean(commonConfigDO.getConfigStr(),CommonConfigVO.class);
CommonConfigVO chargeConfig = JSONUtil.toBean(commonConfigDO.getConfigStr(), CommonConfigVO.class);
List<RobotInformationDO> robots = robotInformationMapper.selectList(new LambdaQueryWrapperX<RobotInformationDO>()
.eq(RobotInformationDO::getRobotStatus, RobotStatusEnum.STAND_BY.getType())
@ -116,7 +126,7 @@ public class AutoChargeServiceImpl implements AutoChargeService {
List<String> chargeFullNos = new ArrayList<>();
if (ObjectUtil.isNotEmpty(chargeConfig.getChanceCycle())) {
//查询充满电
chargeFullNos = chargeLogMapper.getChargeFullRobotNos(chargeConfig.getChanceCycle(),robotNos);
chargeFullNos = chargeLogMapper.getChargeFullRobotNos(chargeConfig.getChanceCycle(), robotNos);
}
List<RobotTaskDetailDO> taskDetailDOS = robotTaskDetailMapper.getChargeTaskDetail();
@ -126,28 +136,37 @@ public class AutoChargeServiceImpl implements AutoChargeService {
}
List<RobotChargeLogDO> logs = new ArrayList<>();
List<RobotTaskDO> tasks = new ArrayList<>();
List<RobotTaskDetailAddVO> taskDetails = new ArrayList<>();
//组装充电任务
assembleChargeTask(robots,deviceInformationDOS,chargeConfig,chargeFullNos,logs,detailMap);
assembleChargeTask(robots, deviceInformationDOS, chargeConfig, chargeFullNos, logs, detailMap, tasks, taskDetails);
if (ObjectUtil.isEmpty(logs)) {
log.info("没有需要执行的充电任务");
return;
}
chargeLogMapper.insertBatch(logs);
robotPathPlanningService.sendChargeTaskToPP(logs,taskDetailDOS,robots);
if (ObjectUtil.isNotEmpty(tasks)) {
robotTaskMapper.insertBatch(tasks);
List<RobotTaskDetailDO> bean = BeanUtils.toBean(taskDetails, RobotTaskDetailDO.class);
robotTaskDetailMapper.insertBatch(bean);
}
chargeLogMapper.insert(logs);
robotPathPlanningService.sendChargeTaskToPP(logs, taskDetailDOS, robots);
//改成异步
logs.stream().forEach(v -> {
String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL +v.getRobotNo();
redisUtil.set(chargeModelKey,v.getChargeModel());
String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL + v.getRobotNo();
redisUtil.set(chargeModelKey, v.getChargeModel());
});
}
/**
* 组装充电任务
*
* @param robots
* @param deviceInformationDOS
* @param chargeConfig
@ -157,33 +176,34 @@ public class AutoChargeServiceImpl implements AutoChargeService {
*/
public void assembleChargeTask(List<RobotInformationDO> robots, List<DeviceInformationDO> deviceInformationDOS,
CommonConfigVO chargeConfig, List<String> chargeFullNos,
List<RobotChargeLogDO> logs, Map<String, List<RobotTaskDetailDO>> detailMap) {
List<RobotChargeLogDO> logs, Map<String, List<RobotTaskDetailDO>> detailMap,
List<RobotTaskDO> tasks, List<RobotTaskDetailAddVO> taskDetails) {
//判断机器人身上的电量少于设定的电量
for (RobotInformationDO robot : robots) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT +robot.getMacAddress();
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robot.getMacAddress();
Object poseCache = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO dataPoseDTO= JSON.parseObject((String)poseCache, RobotStatusDataPoseDTO.class);
RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class);
String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC +robot.getMacAddress();
String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC + robot.getMacAddress();
Object socObject = redisUtil.get(socKey);
if (ObjectUtil.isEmpty(dataPoseDTO) || ObjectUtil.isEmpty(socObject)) {
log.info("当前机器人查不到电量信息,所以不执行充电 :{}",robot.getRobotNo());
log.info("当前机器人查不到电量信息,所以不执行充电 :{}", robot.getRobotNo());
continue;
}
if (ObjectUtil.isEmpty(deviceInformationDOS)) {
log.info("充电桩分配完成 :{}",robot.getRobotNo());
log.info("充电桩分配完成 :{}", robot.getRobotNo());
break;
}
DeviceInformationDO deviceInformationDO = deviceInformationDOS.stream()
.filter(v -> v.getDeviceAttribute().equals(robot.getChargeType())
&& robot.getFloorAreaJson().contains(v.getPositionMapId()))
&& robot.getFloorAreaJson().contains(v.getPositionMapId()))
.findFirst()
.orElse(new DeviceInformationDO());
if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceNo())) {
log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}",robot.getRobotNo());
log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}", robot.getRobotNo());
continue;
}
@ -202,9 +222,12 @@ public class AutoChargeServiceImpl implements AutoChargeService {
&& robotRemainingElectricity.compareTo(robotFullElectricity) < 0) {
//充满电
logDo.setChargeModel(ChargeModelEnum.FULL.getType());
Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo());
logDo.setTaskDetailId(taskDetailId);
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到充满电充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
log.info("分配到充满电充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId());
continue;
}
@ -217,8 +240,9 @@ public class AutoChargeServiceImpl implements AutoChargeService {
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.TASK.getType());
logDo.setTaskDetailId(robotTaskDetailDO.getId());
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId());
continue;
}
}
@ -232,8 +256,9 @@ public class AutoChargeServiceImpl implements AutoChargeService {
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.TASK.getType());
logDo.setTaskDetailId(robotTaskDetailDO.getId());
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId());
continue;
}
}
@ -247,8 +272,9 @@ public class AutoChargeServiceImpl implements AutoChargeService {
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.TASK.getType());
logDo.setTaskDetailId(robotTaskDetailDO.getId());
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId());
continue;
}
}
@ -258,9 +284,12 @@ public class AutoChargeServiceImpl implements AutoChargeService {
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
logDo.setChargeModel(ChargeModelEnum.AUTO.getType());
Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo());
logDo.setTaskDetailId(taskDetailId);
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo());
log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}", logDo.getRobotNo(), logDo.getDeviceNo());
continue;
}
}
@ -270,9 +299,12 @@ public class AutoChargeServiceImpl implements AutoChargeService {
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getStartAutoCharge()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
logDo.setChargeModel(ChargeModelEnum.AUTO.getType());
Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo());
logDo.setTaskDetailId(taskDetailId);
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo());
log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}", logDo.getRobotNo(), logDo.getDeviceNo());
continue;
}
}
@ -282,12 +314,40 @@ public class AutoChargeServiceImpl implements AutoChargeService {
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeStart()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
logDo.setChargeModel(ChargeModelEnum.CHANCE.getType());
Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo());
logDo.setTaskDetailId(taskDetailId);
logDo.setId(logDo.getTaskDetailId());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到机会充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo());
log.info("分配到机会充电任务 :{} ,充电设备编号是 :{}", logDo.getRobotNo(), logDo.getDeviceNo());
}
}
}
}
/**
* 自动充电
*/
public Long createChargeTask(String robotNo, List<RobotTaskDO> tasks, List<RobotTaskDetailAddVO> taskDetails, Long positionMapItemId, String deviceNo) {
RobotTaskDO task = new RobotTaskDO();
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.CHARGE_TASK_NO.getKey());
task.setTaskNo(chargeNo + DateUtils.getYearMonthDay() + incrementByKey);
task.setId(IdUtil.getSnowflakeNextId());
task.setCycleNumber(0L);
task.setRemainingCycleNumber(0L);
task.setStartTime(LocalDateTime.now());
RobotTaskDetailAddVO detailAddVO = new RobotTaskDetailAddVO();
detailAddVO.setId(IdUtil.getSnowflakeNextId());
detailAddVO.setRobotTaskId(task.getId());
detailAddVO.setTaskType(RobotTaskTypeEnum.CHARGE.getType());
detailAddVO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType());
detailAddVO.setReleaseId(positionMapItemId);
detailAddVO.setToLocationNo(deviceNo);
detailAddVO.setRobotNo(robotNo);
tasks.add(task);
taskDetails.add(detailAddVO);
return detailAddVO.getId();
}
}

View File

@ -96,6 +96,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Value("${zn.move-no:MOVE}")
private String moveTaskNo;
@Value("${zn.robot_config.default_tray_height:0.82}")
private Double defaultTrayHeight;
@Autowired
private RobotTaskMapper robotTaskMapper;
@ -262,12 +265,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
detailAddVO.setTaskType(RobotTaskTypeEnum.MOVE_TO_POINT.getType());
detailAddVO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType());
detailAddVO.setReleaseId(v.getId());
detailAddVO.setToLocationNo(sortMap.get(v.getId())+"");
detailAddVO.setToLocationNo(sortMap.get(v.getId()) + "");
detailAddVO.setRobotNo(v.getRobotNo());
taskDetails.add(detailAddVO);
TaskToPathPlanningDTO pathPlanning = TaskToPathPlanningDTO.builder()
.orderId(detailAddVO.getId()+"")
.orderId(detailAddVO.getId() + "")
.orderType(PathTaskTypeEnum.MOVE_TO_WAIT.getType())
.priority(1l)
.createTime(LocalDateTime.now())
@ -297,9 +300,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
@Override
public void sendChargeTaskToPP(List<RobotChargeLogDO> logs, List<RobotTaskDetailDO> taskDetailDOS,
List<RobotInformationDO> robots) {
@ -424,7 +424,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanning.setWaitIds(waitIds);
i++;
} else if (RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(taskDetailDO.getTaskType())) {
moveToPoint(pathPlanning,taskDetailDO);
moveToPoint(pathPlanning, taskDetailDO);
}
if (ObjectUtil.isNotEmpty(robotDoTake) && ObjectUtil.isNotEmpty(taskDetailDO.getRobotNo())
@ -454,9 +454,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLocationId())) {
pathPlanning.setTakeLocationNumber(Math.abs(locationNumberReduce - taskDetailDO.getFromLocationNumber()));
pathPlanning.setTakePointId(fromLocation.getMapItemId());
if (ObjectUtil.isNotEmpty(fromLocation.getLocationTotalHeight())) {
pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTotalHeight() + ""));
}
pathPlanningSetTakeHeight(pathPlanning, fromLocation);
pathPlanning.setTakeLevel(fromLocation.getLocationStorey());
pathPlanning.setTakeOffsetHeight(offsetHeight);
if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) {
@ -469,11 +468,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())) {
pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber());
pathPlanning.setReleasePointId(toLocation.getMapItemId());
if (ObjectUtil.isNotEmpty(toLocation.getLocationStorey()) && ZeroOneEnum.ONE.getType().equals(toLocation.getLocationStorey())) {
pathPlanning.setReleaseHeight(0.0);
}else if (ObjectUtil.isNotEmpty(toLocation.getLocationTrayHeight())) {
pathPlanning.setReleaseHeight(Double.valueOf(toLocation.getLocationTrayHeight() + ""));
}
pathPlanningSetReleaseHeight(pathPlanning,toLocation);
pathPlanning.setReleaseLevel(toLocation.getLocationStorey());
pathPlanning.setReleaseOffsetHeight(offsetHeight);
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) {
@ -495,8 +491,52 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
}
/**
* 设置放货高度
* @param pathPlanning
* @param toLocation
*/
private void pathPlanningSetReleaseHeight(TaskToPathPlanningDTO pathPlanning, WareHouseLocationDO toLocation) {
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)
.last("limit 1"));
if (ObjectUtil.isNotEmpty(nextLocation) && ObjectUtil.isNotEmpty(nextLocation.getLocationTotalHeight())) {
pathPlanning.setReleaseHeight(Double.valueOf(nextLocation.getLocationTotalHeight() + ""));
return;
}
Integer locationStorey = toLocation.getLocationStorey() - 1;
double height = locationStorey * defaultTrayHeight;
log.info("放货设置默认高度 :{}",pathPlanning.getReleaseHeight());
pathPlanning.setReleaseHeight(height);
}
/**
* 设置取货高度
*
* @param pathPlanning
* @param fromLocation
*/
private void pathPlanningSetTakeHeight(TaskToPathPlanningDTO pathPlanning, WareHouseLocationDO fromLocation) {
if (ObjectUtil.isNotEmpty(fromLocation.getLocationTotalHeight())) {
pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTotalHeight() + ""));
return;
}
Integer locationStorey = fromLocation.getLocationStorey();
double height = locationStorey * defaultTrayHeight;
log.info("取货设置默认取货高度 :{}",height);
pathPlanning.setTakeHeight(height);
}
/**
* 移动到路径点
*
* @param pathPlanning
* @param taskDetailDO
*/
@ -692,7 +732,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
//仅取货
takeSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo);
} else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())
|| RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(v.getTaskType())) {
|| RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(v.getTaskType())) {
list.add(v);
}
}

View File

@ -187,6 +187,7 @@ justauth:
zn:
task-no: TASK #任务号开头
move-no: MOVE #自动移动任务号开头
charge-no: CHARGE #自动充电任务号开头
camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥
do_cycle: true #是否开启循环
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库

View File

@ -222,10 +222,11 @@ map:
zn:
task-no: TASK #任务号开头
move-no: MOVE #自动移动任务号开头
charge-no: CHARGE #自动充电任务号开头
camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥
do_cycle: true #是否开启循环
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库
robot_position_cache_time: 10 #机器人上报点位存储时间(秒)
robot_position_cache_time: 10000000 #机器人上报点位存储时间(秒)
cycle_do_auto_move: true #存在循环的任务,是否开启自动移库. true:存在循环任务,开启自动移库; false有循环任务不自动移库
full_electricity: 100 #机器人充满电的电量
task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人)
@ -239,7 +240,7 @@ zn:
check_sku_info: true #校验物料信息
robot_config: #机器人取放货默认配置
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
default_tray_height: 1.1 #默认每层高度
default_tray_height: 0.82 #默认每层高度
open_rate_limiter: true #是否开启限流
path_planning:
task_chche_time: 1209600 #任务缓存的时间, 默认一星期

View File

@ -215,6 +215,7 @@ map:
zn:
task-no: TASK #任务号开头
move-no: MOVE #自动移动任务号开头
charge-no: CHARGE #自动充电任务号开头
camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥
do_cycle: true #是否开启循环
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库