# Conflicts:
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapItemMapper.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml
#	yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/positionmap/PositionMapItemMapper.xml
This commit is contained in:
aikai 2025-06-21 11:43:51 +08:00
commit 954ab0e034
94 changed files with 2437 additions and 435 deletions

View File

@ -370,3 +370,5 @@
| ![](/.image/admin-uniapp/07.png) | ![](/.image/admin-uniapp/08.png) | ![](/.image/admin-uniapp/09.png) |
目前已经实现登录、我的、工作台、编辑资料、头像修改、密码修改、常见问题、关于我们等基础功能。
### CICD 测试6

View File

@ -34,7 +34,9 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
private static final String ATTRIBUTE_STOP_WATCH = "ApiAccessLogInterceptor.StopWatch";
private static final List<String> ignoreInterfaceUrls = Arrays.asList("/rpc-api/system/task/robotStatusUpdate","/rpc-api/system/task/updateRobotCommonStatus");
private static final List<String> ignoreInterfaceUrls = Arrays.asList("/rpc-api/system/task/robotStatusUpdate",
"/rpc-api/system/task/robotReactiveStatus",
"/rpc-api/system/task/updateRobotCommonStatus");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

View File

@ -13,6 +13,7 @@ import java.util.List;
@AllArgsConstructor
public class PathToRobotChangeXYArgDTO {
private List<PathToRobotChangeXYArgMovePoseDTO> pose2ds;
private PathToRobotChangeXYArgMovePoseDTO pose2d;
private PathToRobotChangeXYArgPoseDTO backPose;
private PathToRobotChangeXYArgPoseDTO cargoPose;
private Double height;

View File

@ -19,6 +19,7 @@ public class PathToRobotChangeXYDTO {
//这个实体类不要修改
private String executionType;
private String orderId;
private String timeStamp;
private String orderType;
private String robotNo;
private String taskType;

View File

@ -18,6 +18,7 @@ public class PathToRobotDTO {
//这个实体类的信息,不能修改
//这个实体类的信息,不能修改
private String orderType;
private String timeStamp;
private Integer isCommandEnd;
private String robotNo;
private String commandType;

View File

@ -31,4 +31,8 @@ public class RobotDimensionsDTO {
@Schema(description = "转弯半径(单位米)")
private Double robotTurningRadius;
@Schema(description = "偏移量")
private Double robotOffset;
}

View File

@ -23,6 +23,9 @@ public class CommonApiImpl implements CommonApi {
try {
String str = JSON.toJSONString(obj);
mqttUtils.pub(topic, JSON.toJSONString(obj));
if(topic.equals("AGV_POSE")) {
return;
}
if (str.length() > 510) {
log.info("MQTT消息发送成功topic :{}, 内容 :{}",topic, str.substring(0, 500));
}else {
@ -37,6 +40,9 @@ public class CommonApiImpl implements CommonApi {
public void commonMethodStr(String str, String topic) {
try {
mqttUtils.pub(topic, str);
if(topic.equals("AGV_POSE")) {
return;
}
if (str.length() > 510) {
log.info("MQTT消息发送成功topic :{}, 内容 :{}",topic, str.substring(0, 500));
}else {

View File

@ -9,6 +9,8 @@ import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* MQTT回调
@ -17,6 +19,9 @@ import java.nio.charset.StandardCharsets;
@Configuration
public class MqttCallBack implements MqttCallback {
private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
/**
* 与服务器断开的回调
*/
@ -35,16 +40,19 @@ public class MqttCallBack implements MqttCallback {
*/
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
String msg = new String(mqttMessage.getPayload(), StandardCharsets.UTF_8);
fixedThreadPool.execute(() -> {
String msg = new String(mqttMessage.getPayload(), StandardCharsets.UTF_8);
// log.info("[MQTT]接收当前消息为 :{}", msg);
try {
MqttService mqttService = MqttFactory.getMqttFactory(topic);
mqttService.analysisMessage(msg);
} catch (Exception e) {
log.info("消费失败的消息主题 :{},消息内容 :{}", topic, msg);
log.info("消费消息异常 :{}", e);
}
try {
MqttService mqttService = MqttFactory.getMqttFactory(topic);
mqttService.analysisMessage(msg);
} catch (Exception e) {
log.info("消费失败的消息主题 :{},消息内容 :{}", topic, msg);
log.info("消费消息异常 :{}", e);
}
});
}
/**

View File

@ -21,7 +21,7 @@ public class RobotGenericsStatusServiceImpl implements MqttService{
@Override
public void analysisMessage(String message) {
log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
// log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
RobotGenericsDataDTO robotStatusData = JSON.parseObject(message , RobotGenericsDataDTO.class);
robotGenericsStatusApi.updateRobotCommonStatus(robotStatusData);
}

View File

@ -22,7 +22,7 @@ public class RobotStatusServiceImpl implements MqttService {
*/
@Override
public void analysisMessage(String message) {
// log.info("处理RobotStatusServiceImpl的消息 :{}", message);
log.info("处理RobotStatusServiceImpl的消息 :{}", message);
RobotPoseStatusDTO robotStatusData = JSON.parseObject(message, RobotPoseStatusDTO.class);
robotStatusApi.robotStatusUpdate(robotStatusData);
}

View File

@ -35,7 +35,8 @@ management:
mqtt:
# host: tcp://123.57.12.40:1883
host: tcp://127.0.0.1:1883
# host: tcp://10.10.7.195:1883
# host: tcp://10.10.7.116:1883
# host: tcp://10.10.7.114:1883
username: adminuser
password: adminuser
qos: 2

View File

@ -34,7 +34,8 @@ management:
# MQTT
mqtt:
# host: tcp://123.57.12.40:1883
host: tcp://10.10.100.42:1883
# host: tcp://10.10.100.42:1883
host: tcp://127.0.0.1:1883
username: adminuser
password: adminuser
qos: 0

View File

@ -18,6 +18,7 @@ public class RobotPoseStatusDTO {
* true表示可以做任务如果是到达了充电点正在充电中应该返回true
*/
public Boolean taskStatus;
public String timestamp;
/**
* 机器人位姿

View File

@ -20,4 +20,6 @@ public class RobotStatusDataPoseDTO {
public Double forkHeight;
//电池剩余容量 废弃 从ROBOT_INFORMATION_SOC 获取电量
// public String batSoc;
public String timestamp;
}

View File

@ -202,6 +202,7 @@ public interface ErrorCodeConstants {
ErrorCode ROBOT_PORT_NOT_COMPLIANCE = new ErrorCode(1-002-034-016, "车辆端口范围在4096至65535之间");
ErrorCode ROBOT_IP_NOT_COMPLIANCE = new ErrorCode(1-002-034-017, "请检测车辆IP是否符合规范");
ErrorCode ROBOT_IP_OR_PORT_EMPTY = new ErrorCode(1-002-034-020, "车辆IP或者端口为空");
ErrorCode ROBOT_PART_AREA = new ErrorCode(1-002-034-021, "车辆选择的楼层,不包含目前车辆停靠的楼层");
// ========== 机器人任务主表 1-002-035-000 ==========
ErrorCode TASK_NOT_EXISTS = new ErrorCode(1-002-035-001, "车辆任务主表不存在");

View File

@ -46,6 +46,12 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-remote-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
@ -179,6 +185,15 @@
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -98,6 +98,7 @@ public class PathApiImpl implements PathApi {
*/
@Override
public void ppDistributionTaskFail(String message) {
log.info("111111路径规划上报失败的消息");
TenantContextHolder.setTenantId(1L);
RobotWarnMsgSaveReqVO data = JSON.parseObject(message, RobotWarnMsgSaveReqVO.class);
warnMsgService.createWarnMsg(data);
@ -108,7 +109,7 @@ public class PathApiImpl implements PathApi {
@Override
public void pathPlanningMove(String message) {
log.info("收到路径规划路径的消息 :{}", message);
log.info("111111路径规划发给车机的消息 :{}", message);
taskExecutor.execute(() -> {
TenantContextHolder.setTenantId(1L);
pathPlanningService.sendPosedsToRobot(message);
@ -145,7 +146,7 @@ public class PathApiImpl implements PathApi {
@Override
public void graphMatchData(String message) {
TenantContextHolder.setTenantId(1L);
log.info("匹配路网的消息 :{}",message);
log.info("111111路径规划匹配路网的消息 :{}",message);
pathPlanningService.graphMatchData(message);
}

View File

@ -5,12 +5,14 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.api.remote.dto.*;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO;
import cn.iocoder.yudao.module.system.service.remote.RemoteControllerInformationService;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService;
import cn.iocoder.yudao.module.system.service.robot.camera.RobotCameraService;
import cn.iocoder.yudao.module.system.util.aes.AESEncryptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -39,8 +41,8 @@ public class RemoteExceptionTaskApiImpl implements RemoteExceptionTaskApi{
@Resource
private RobotCameraService cameraService;
@Value("${zn.camera_secret_key}")
private String cameraSecretKey;
@Autowired
private ZnConfigConstant znConfigConstant;
/**
* 远遥查询异常的车辆
@ -67,8 +69,8 @@ public class RemoteExceptionTaskApiImpl implements RemoteExceptionTaskApi{
for (RemoteRobotCameraDTO robotCameraDO : list) {
try {
robotCameraDO.setCameraAccount(AESEncryptionUtil.decrypt(robotCameraDO.getCameraAccount(),cameraSecretKey));
robotCameraDO.setCameraPassword(AESEncryptionUtil.decrypt(robotCameraDO.getCameraPassword(),cameraSecretKey));
robotCameraDO.setCameraAccount(AESEncryptionUtil.decrypt(robotCameraDO.getCameraAccount(),znConfigConstant.getCameraSecretKey()));
robotCameraDO.setCameraPassword(AESEncryptionUtil.decrypt(robotCameraDO.getCameraPassword(),znConfigConstant.getCameraSecretKey()));
} catch (Exception e) {
throw exception(CAMERA_DECRYPTION_FAILED);
}

View File

@ -30,7 +30,7 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
}
public void doUpdateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) {
// log.info("车机每3秒上报其他状态信息 :{}", JSONUtil.toJsonStr(robotStatusData));
// log.info("111111车机每3秒上报其他状态信息 :{}", JSONUtil.toJsonStr(robotStatusData));
if (ObjectUtil.isEmpty(robotStatusData) || ObjectUtil.isEmpty(robotStatusData.getHwStates())
|| ObjectUtil.isEmpty(robotStatusData.getMac())) {
log.info("参数不全 :{}", JSON.toJSONString(robotStatusData));

View File

@ -41,7 +41,7 @@ public class RobotObstaclesStatusApiImpl implements RobotObstaclesStatusApi{
@Override
public void robotObstaclesStatus(String message) {
log.info("障碍物状态上报 :{}" ,message);
log.info("111111障碍物状态上报 :{}" ,message);
RobotObstaclesStatusDTO data = JSON.parseObject(message, RobotObstaclesStatusDTO.class);
if (!data.getObstacles()) {

View File

@ -41,7 +41,7 @@ public class RobotPathStatusApiImpl implements RobotPathStatusApi {
}
private void doRobotPathStatus(String message) {
log.info("导航实时行为上报: {}", message);
log.info("111111导航实时行为上报: {}", message);
TenantContextHolder.setTenantId(1L);
RobotPathStatusDTO data = JSON.parseObject(message, RobotPathStatusDTO.class);
String robotNo = robotInformationService.getRobotNoByMac(data.getMac());

View File

@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.system.api.robot.processor.RequestProcessor;
import cn.iocoder.yudao.module.system.api.robot.websocket.RobotInformationVO;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotReactiveStatusDTO;
import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter;
import cn.iocoder.yudao.module.system.constant.CommonConstant;
import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant;
@ -41,16 +43,19 @@ public class RobotStatusApiImpl implements RobotStatusApi {
@Autowired
private RobotInformationService robotInformationService;
@Value("${zn.robot_position_cache_time:10}")
private Long robotPositionCacheTime;
@Autowired
private ZnConfigConstant znConfigConstant;
@Resource
private RequestProcessor processor;
private static final ExecutorService executorService = Executors.newFixedThreadPool(5);
private static final ExecutorService executorService = Executors.newFixedThreadPool(50);
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
/**
* 更新机器人点位/异常/能否做任务
@ -107,13 +112,10 @@ public class RobotStatusApiImpl implements RobotStatusApi {
robotStatusDataPoseDTO.setForkHeight(data.getForkHeight());
}
redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime);
redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), znConfigConstant.getRobotPositionCacheTime());
//机器人身上是否有货
String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robotStatusDataDTO.getMac();
String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + robotStatusDataDTO.getMac();
redisUtil.set(taskStatusKey, robotStatusDataDTO.getTaskStatus(), robotPositionCacheTime);
redisUtil.set(cargoDetectedKey, robotStatusDataDTO.getCargoDetected(), robotPositionCacheTime);
robotStatusDataPoseDTO.setTimestamp(robotStatusDataDTO.getTimestamp());
sendToPP(robotStatusDataPoseDTO);
// -- 通过mac 地址获取车辆信息 - (并且加入到缓存中)
Map<String, RobotInformationVO> robotInformationVOS = robotInformationService.getAllRobotByRedis();
@ -123,18 +125,30 @@ public class RobotStatusApiImpl implements RobotStatusApi {
}
robotInformationVO.setPose2d(robotStatusDataPoseDTO);
Map<String, Object> map = new HashMap<>();
String value = FloorAreaConstant.FLOOR_AREA_ROBOT + floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea();
map.put(robotStatusDataDTO.getMac(), JSON.toJSONString(robotInformationVO));
redisUtil.hmset(value, map, 20);
RobotInformationVO finalRobotInformationVO = robotInformationVO;
String floorArea = floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea();
executorService.execute(() ->{
//机器人身上是否有货
String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robotStatusDataDTO.getMac();
String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + robotStatusDataDTO.getMac();
redisUtil.set(taskStatusKey, robotStatusDataDTO.getTaskStatus(), znConfigConstant.getRobotPositionCacheTime());
redisUtil.set(cargoDetectedKey, robotStatusDataDTO.getCargoDetected(), znConfigConstant.getRobotPositionCacheTime());
Map<String, Object> map = new HashMap<>();
String value = FloorAreaConstant.FLOOR_AREA_ROBOT +floorArea;
map.put(robotStatusDataDTO.getMac(), JSON.toJSONString(finalRobotInformationVO));
redisUtil.hmset(value, map, 5);
});
/* executorService.execute(() ->{
// 合并请求 - 这里接受到的数据都丢给 RequestProcessor - 再整合数据通过WebSocket丢给前端
processor.handleRequest(floorArea,robotStatusDataDTO.getMac(), JSONUtil.toJsonStr(finalRobotInformationVO));
});*/
// 合并请求 - 这里接受到的数据都丢给 RequestProcessor - 再整合数据通过WebSocket丢给前端
processor.handleRequest(floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea(),
robotStatusDataDTO.getMac(), JSONUtil.toJsonStr(robotInformationVO));
sendToPP(robotStatusDataPoseDTO);
}
private void sendToPP(RobotStatusDataPoseDTO robotStatusDataPoseDTO) {
commonApi.commonMethod(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE);
// commonApi.commonMethod(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE);
mqttUtils.pub(PathPlanningTopicConstant.AGV_POSE,JSON.toJSONString(robotStatusDataPoseDTO));
}
}

View File

@ -13,6 +13,8 @@ import cn.iocoder.yudao.module.system.api.robot.dto.RobotCommandStateDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import cn.iocoder.yudao.module.system.api.robot.websocket.RobotSkuInfoDTO;
import cn.iocoder.yudao.module.system.api.robot.websocket.WsWareHouseLocationDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.CommonConstant;
import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
@ -99,8 +101,11 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Resource
private RobotChargeLogMapper chargeLogMapper;
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
public WebSocketSenderApi webSocketSenderApi;
@ -120,15 +125,12 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Resource
private DeviceInformationService deviceInformationService;
@Value("${zn.robot_doing_action.doing_action_cache_time:2*24*60*60}")
private Long doingActionCacheTime;
@Value("${zn.is_simulation:false}")
private Boolean isSimulation;
@Autowired
private ZnConfigConstant znConfigConstant;
@Transactional(rollbackFor = Exception.class)
public void doRobotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) {
log.info("机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO));
log.info("111111机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO));
TenantContextHolder.setTenantId(1L);
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_QUERY_DOING_ACTION + robotCompleteTaskDTO.getMac();
@ -139,8 +141,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
if (!RobotStatusCodeEnum.SUCCESS.getType().equals(robotCompleteTaskDTO.getStatusCode())) {
log.info("车机上报异常 :{}", JSON.toJSONString(robotCompleteTaskDTO));
closeTask(robotCompleteTaskDTO);//todo 取不了和放不了的异常
//todo 取不了和放不了的异常
redisUtil.del(robotDoingActionKey);
closeTask(robotCompleteTaskDTO);
return;
}
@ -193,7 +196,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
, null);
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) ) {
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
chargeDoing(robotCompleteTaskDTO);
}
}
@ -206,6 +209,12 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
* @param orderId
*/
public void sendStartDoActionToPP(RobotCommandStateDTO commandStatus, String mac, String orderId) {
if (ObjectUtil.isNotEmpty(commandStatus)
|| CommandTypeEnum.WORK_PICK_UP_GOODS_MOVE_TO_CHECK.getType().equals(commandStatus.getCommandType())
|| CommandTypeEnum.WORK_DROP_OFF_GOODS_MOVE_TO_CHECK.getType().equals(commandStatus.getCommandType())) {
log.info("不发作业");
return;
}
if (ObjectUtil.isNotEmpty(commandStatus) && RobotExecutionStateConstant.DOING.equals(commandStatus.getExecutionState())
&& !CommandTypeEnum.MOVE_POSES.getType().equals(commandStatus.getCommandType())) {
String robotNo = robotInformationService.getRobotNoByMac(mac);
@ -247,10 +256,10 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
} else if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId());
if (CommandTypeEnum.WORK_PICK_UP_GOODS.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType())) {
log.info("告诉路径规划任务完成 :{}, 状态: {}", robotCompleteTaskDTO.getOrderId(), PathIsReachEnum.END_WORK.getType());
log.info("告诉路径规划取货任务完成 :{}, 状态: {}", robotCompleteTaskDTO.getOrderId(), PathIsReachEnum.END_WORK.getType());
pathPlanningService.updateBehavior(String.valueOf(robotCompleteTaskDTO.getOrderId()), robotTaskDetailDO.getRobotNo()
, "", PathIsReachEnum.END_WORK.getType());
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.TAKEING.getType());
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType());
robotTaskDetailMapper.updateById(robotTaskDetailDO);
return;
} else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType())) {
@ -260,7 +269,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(),ChargeTaskStatusEnum.DONE.getType());
chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(), ChargeTaskStatusEnum.DONE.getType());
}
taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now());
@ -289,7 +298,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
toWareHouseLocation.setLocationLock(LocationLockEnum.YES.getType());
toWareHouseLocation.setLocationUseStatus(LocationUseStatusEnum.YES.getType());
locationMapper.updateById(toWareHouseLocation);
pushWareLocation(toWareHouseLocation,robotCompleteTaskDTO.getMac(),ZeroOneEnum.ONE.getType());
pushWareLocation(toWareHouseLocation, robotCompleteTaskDTO.getMac(), ZeroOneEnum.ONE.getType());
}
/**
@ -345,7 +354,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
wareHouseLocationDO.setLocationLock(LocationLockEnum.YES.getType());
wareHouseLocationDO.setLocationUseStatus(LocationUseStatusEnum.NO.getType());
locationMapper.updateById(wareHouseLocationDO);
pushWareLocation(wareHouseLocationDO,robotCompleteTaskDTO.getMac(),ZeroOneEnum.ZERO.getType());
pushWareLocation(wareHouseLocationDO, robotCompleteTaskDTO.getMac(), ZeroOneEnum.ZERO.getType());
}
public void pushWareLocation(WareHouseLocationDO wareHouseLocationDO, String mac, Integer type) {
@ -378,7 +387,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
.robotNo(robotNo)
.id(robotCompleteTaskDTO.getOrderId().toString())
.build();
commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
// commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
mqttUtils.pub(PathPlanningTopicConstant.KILL_TASK,JSON.toJSONString(closePathPlanting));
log.info("通知PP把任务取消 :{}", robotCompleteTaskDTO.getOrderId());
}
@ -389,19 +399,28 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
*/
@Transactional(rollbackFor = Exception.class)
public void closeTask(RobotCompleteTaskDTO robotCompleteTaskDTO) {
if (RobotStatusCodeEnum.EXCEEDING_SECONDS.getType().equals(robotCompleteTaskDTO.getStatusCode())) {
doTaskContinue(robotCompleteTaskDTO);
return;
}
PPCloseOrder(robotCompleteTaskDTO);
// taskService.closeTaskDetail(robotCompleteTaskDTO.getOrderId().toString(),robotCompleteTaskDTO.getMac());
String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac());
String msg = "";
String msg = null;
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId());
if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.TAKE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId());
if (RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetailDO.getTaskStage())
|| RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetailDO.getTaskStage())) {
robotTaskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.NEW.getType());
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.UN_START.getType());
robotTaskDetailDO.setRobotNo("");
if (!znConfigConstant.getIsSimulation()) {
// robotTaskDetailDO.setRobotNo("");
}
robotTaskDetailDO.setOccurError(ZeroOneEnum.ZERO.getType());
robotTaskDetailMapper.updateById(robotTaskDetailDO);
String taskNo = taskDetailService.getTaskNoByDetailId(robotCompleteTaskDTO.getOrderId());
@ -439,8 +458,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
String solve = "";
String taskNo = "";
if (!PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
&& ObjectUtil.isEmpty(msg)) {
if (ObjectUtil.isEmpty(msg)) {
taskNo = taskDetailService.getTaskNoByDetailId(robotCompleteTaskDTO.getOrderId());
solve = " 并且到任务列表关闭任务 " + taskNo;
taskDetailService.setTaskDetailError(robotCompleteTaskDTO.getOrderId());
@ -462,6 +480,12 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
warnMsgService.sendWarnMsgToWebsocket(warnMsg.getWarnMsg());
}
private void doTaskContinue(RobotCompleteTaskDTO robotCompleteTaskDTO) {
log.info("恢复任务");
String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac());
robotInformationService.doTaskContinue(robotNo, true);
}
/**
* 处理充电中
*
@ -478,7 +502,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
setTaskDone(robotCompleteTaskDTO);
}
chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(),ChargeTaskStatusEnum.CHARGEING.getType());
chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(), ChargeTaskStatusEnum.CHARGEING.getType());
}
public RobotTaskDetailDO setTaskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) {
@ -513,7 +537,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
*/
private void taskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) {
RobotTaskDetailDO robotTaskDetailDO = setTaskDone(robotCompleteTaskDTO);
RobotTaskDetailDO robotTaskDetailDO = setTaskDone(robotCompleteTaskDTO);
RobotInformationDO robotInformationDO = robotInformationMapper.selectOne(new LambdaQueryWrapperX<RobotInformationDO>()
.eq(RobotInformationDO::getRobotNo, robotTaskDetailDO.getRobotNo()));
@ -528,7 +552,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
pathPlanningService.updateBehavior(String.valueOf(robotCompleteTaskDTO.getOrderId()), robotTaskDetailDO.getRobotNo()
, "", PathIsReachEnum.END_WORK.getType());
if (!isSimulation) {
if (!znConfigConstant.getIsSimulation()) {
String plantingKey = PathPlanningChcheConstant.PATH_PLANNING_TASK + robotCompleteTaskDTO.getOrderId();
redisUtil.del(plantingKey);
}
@ -558,13 +582,17 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_TAKE.getType());
} else if (CommandTypeEnum.WORK_PICK_UP_GOODS.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在取货");
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.TAKEING.getType());
if (!RobotTaskStageEnum.GO_RELEASE.getType().equals(taskStage)) {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.TAKEING.getType());
}
} else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在放货");
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.RELEASEING.getType());
} else if (CommandTypeEnum.MOVE_POSES.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在前往" + robotTaskDetailDO.getToLocationNo() + "放货");
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType());
if (!RobotTaskStageEnum.DONE.getType().equals(taskStage)) {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType());
}
}
} else if (PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
@ -596,7 +624,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_TAKE.getType());
} else if (CommandTypeEnum.WORK_PICK_UP_GOODS.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在取货");
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.TAKEING.getType());
if (!RobotTaskStageEnum.DONE.getType().equals(taskStage)) {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.TAKEING.getType());
}
}
} else if (PathTaskTypeEnum.RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
@ -605,7 +635,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType());
} else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(commandType)) {
logOne.setActionMsg("车辆正在放货");
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.RELEASEING.getType());
if (!RobotTaskStageEnum.DONE.getType().equals(taskStage)) {
robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.RELEASEING.getType());
}
}
}
@ -631,7 +663,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
logOne.setPositionMapId(mapId);
}
taskDetailActionLogService.createTaskDetailActionLog(logOne);
redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime);
redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), znConfigConstant.getRobotDoingAction().getDoingActionCacheTime());
robotTaskDetailMapper.updateById(robotTaskDetailDO);
}

View File

@ -50,7 +50,7 @@ public class RobotUpdatePalletHeightApiImpl implements RobotUpdatePalletHeightAp
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePalletHeight(String message) {
log.info("高度反馈 :{}", message);
log.info("111111高度反馈 :{}", message);
TenantContextHolder.setTenantId(1L);
RobotUpdatePalletHeightDTO data = JSON.parseObject(message, RobotUpdatePalletHeightDTO.class);
if (RobotCommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(data.getCommandType())) {

View File

@ -4,9 +4,15 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotWorkStatusDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotExecutionStateConstant;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.RobotOperationLogSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.enums.path.PathIsReachEnum;
import cn.iocoder.yudao.module.system.enums.robot.CommandTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaskStageEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.WorkProgressEnum;
import cn.iocoder.yudao.module.system.service.log.RobotOperationLogService;
import cn.iocoder.yudao.module.system.service.path.PathPlanningService;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
@ -32,9 +38,12 @@ public class RobotWorkStatusApiImpl implements RobotWorkStatusApi {
@Resource
private PathPlanningService pathPlanningService;
@Autowired
private RobotTaskDetailMapper robotTaskDetailMapper;
@Override
public void robotWorkStatus(String message) {
log.info("作业实时行为上报: {}", message);
log.info("111111作业实时行为上报: {}", message);
TenantContextHolder.setTenantId(1L);
RobotWorkStatusDTO data = JSON.parseObject(message, RobotWorkStatusDTO.class);
@ -61,6 +70,59 @@ public class RobotWorkStatusApiImpl implements RobotWorkStatusApi {
, data.getCommandType(), PathIsReachEnum.END_WORK.getType());
}
if (CommandTypeEnum.WORK_PICK_UP_GOODS.getType().equals(data.getCommandType())
&& RobotExecutionStateConstant.DONE.equals(Integer.valueOf(data.getExecutionState()))
&& WorkProgressEnum.FORK_OFFSET.getType().equals(data.getWorkProgress())) {
setTakeDone(data.getOrderId());
}else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(data.getCommandType())
&& RobotExecutionStateConstant.DONE.equals(Integer.valueOf(data.getExecutionState()))
&& WorkProgressEnum.FORK_OFFSET.getType().equals(data.getWorkProgress())) {
setReleaseDone(data.getOrderId());
}
}
private void setReleaseDone(String orderId) {
RobotTaskDetailDO data = new RobotTaskDetailDO();
data.setId(Long.valueOf(orderId));
data.setTaskStage(RobotTaskStageEnum.DONE.getType());
data.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType());
robotTaskDetailMapper.updateRobotDetailById(data);
}
private void setTakeDone(String orderId) {
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(orderId);
if (RobotTaskTypeEnum.TAKE_RELEASE.getType().equals(robotTaskDetailDO.getTaskType())) {
RobotTaskDetailDO data = new RobotTaskDetailDO();
data.setId(robotTaskDetailDO.getId());
data.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType());
robotTaskDetailMapper.updateRobotDetailById(data);
}else if (RobotTaskTypeEnum.TAKE.getType().equals(robotTaskDetailDO.getTaskType())){
RobotTaskDetailDO data = new RobotTaskDetailDO();
data.setId(robotTaskDetailDO.getId());
data.setTaskStage(RobotTaskStageEnum.DONE.getType());
data.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType());
robotTaskDetailMapper.updateRobotDetailById(data);
}
}
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.config.aop;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
@ -13,6 +14,7 @@ import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
@ -36,8 +38,9 @@ public class SystemRateLimiterAspect {
@Resource
private RedisUtil redisUtil;
@Value("${zn.open_rate_limiter:false}")
private Boolean openRateLimiter;
@Autowired
private ZnConfigConstant znConfigConstant;
@Pointcut("@annotation(cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter)")
public void serviceLimit() {
@ -46,7 +49,7 @@ public class SystemRateLimiterAspect {
@Around("serviceLimit()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
if (!openRateLimiter) {
if (!znConfigConstant.getOpenRateLimiter()) {
return joinPoint.proceed();
}
MethodSignature signature = (MethodSignature) joinPoint.getSignature();

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.system.config.mqtt;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 初始化执行
*/
@Slf4j
@Order(1)
@Component
public class MqttBeforePoint implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
// 初始化Mqtt连接
try {
MqttFactory.getInstance();
log.info("[MQTT]初始化成功");
} catch (MqttException e) {
log.info("[MQTT]初始化失败。考虑是否服务端掉线");
MqttFactory.reconnect();
}
}
}

View File

@ -0,0 +1,69 @@
package cn.iocoder.yudao.module.system.config.mqtt;
import cn.iocoder.yudao.module.system.service.mqtt.MqttService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* MQTT回调
*/
@Slf4j
@Configuration
public class MqttCallBack implements MqttCallback {
private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
/**
* 与服务器断开的回调
*/
@Override
public void connectionLost(Throwable throwable) {
log.info("[MQTT]断开了与服务端的连接。考虑是否服务端掉线 or 回调参数解析报错 or 无默认sub");
// 执行自动重连
MqttFactory.reconnect();
}
/**
* 消息到达的回调
*
* @param topic 话题
* @param mqttMessage 消息内容
*/
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
fixedThreadPool.execute(() -> {
String msg = new String(mqttMessage.getPayload(), StandardCharsets.UTF_8);
// log.info("[MQTT]接收当前消息为 :{}", msg);
try {
MqttService mqttService = MqttFactory.getMqttFactory(topic);
mqttService.analysisMessage(msg);
} catch (Exception e) {
log.info("消费失败的消息主题 :{},消息内容 :{}", topic, msg);
log.info("消费消息异常 :{}", e);
}
});
}
/**
* 消息发布成功的回调
*
* @param token token
*/
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
IMqttAsyncClient client = token.getClient();
// log.info("[MQTT]{}:消息发布成功!", client.getClientId());
}
}

View File

@ -0,0 +1,190 @@
package cn.iocoder.yudao.module.system.config.mqtt;
//import cn.iododer.yudao.module.mqtt.customer.MqttMessageListener;
import cn.iocoder.yudao.module.system.config.mqtt.enums.DefineSubTopicEnum;
import cn.iocoder.yudao.module.system.config.mqtt.util.BeanUtils;
import cn.iocoder.yudao.module.system.service.mqtt.MqttService;
import cn.iocoder.yudao.module.system.service.mqtt.PathPlanningDistributionFailServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PathPlanningDistributionTaskServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PathPlanningInitDataServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PathPlanningMoveServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PathRouteDisplayPlanningServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PlanningGraphMatchDataServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PlanningRemoteRobotMovePosePlanningImpl;
import cn.iocoder.yudao.module.system.service.mqtt.PlanningSimulationRobotPoseRequestServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotGenericsStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotObstaclesStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotPathStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotReactiveStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotTaskStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotUpdatePalletHeightServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotWirelessSignalStatusServiceImpl;
import cn.iocoder.yudao.module.system.service.mqtt.RobotWorkStatusServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
/**
* Mqtt 工厂类
*/
@Slf4j
@Component
public class MqttFactory {
@Autowired
private MqttProperties config;
private static MqttFactory factory;
private static MqttClient client;
@PostConstruct
public void init() {
factory = this;
factory.config = this.config;
}
/**
* 获取客户端实例
* 单例模式存在即返回不存在则初始化
*
* @return client
* @throws MqttException 此处刻意抛出异常否则无法执行断线重连
*/
public static MqttClient getInstance() throws MqttException {
if (client == null) {
connect();
}
return client;
}
/**
* 清空客户端实例
* mqtt 断开连接时需清空 clientId再执行断线重连
*/
public static void clear() {
client = null;
}
/**
* 断线重连方法
*/
public static void reconnect() {
int count = 0;
while (true) {
clear();
++ count;
try {
log.info("----------------[MQTT]即将执行自动重连----------------");
getInstance();
log.info("----------------[MQTT]自动重连成功----------------");
break;
} catch (MqttException e) {
log.error("----------------[MQTT]自动重连失败,当前为第 {} 次尝试----------------", count);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException ex) {
log.error("----------------[MQTT]自动重连,休眠失败!----------------", e);
}
}
}
}
/**
* 客户端连接服务端
*
* @throws MqttException 此处刻意抛出异常否则无法执行断线重连
*/
private static void connect() throws MqttException {
// 创建MQTT客户端对象
client = new MqttClient(factory.config.getHostUrl(), factory.config.getClientId(), new MemoryPersistence());
// 连接设置
MqttConnectOptions options = new MqttConnectOptions();
// 是否清空session设置false表示服务器会保留客户端的连接记录订阅主题qos,客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
// 设置为true表示每次连接服务器都是以新的身份
options.setCleanSession(false);
// 设置连接用户名
options.setUserName(factory.config.getUsername());
// 设置连接密码
options.setPassword(factory.config.getPassword().toCharArray());
// 设置超时时间单位为秒
options.setConnectionTimeout(100);
// 设置心跳时间 单位为秒表示服务器每隔 20 秒的时间向客户端发送心跳判断客户端是否在线
options.setKeepAliveInterval(20);
// 调整客户端连接参数
options.setMaxInflight(factory.config.getMaxInflight());
// 设置遗嘱消息的话题若客户端和服务器之间的连接意外断开服务器将发布客户端的遗嘱信息
options.setWill("willTopic", (factory.config.getClientId() + "MQTT客户端与服务器断开连接").getBytes(), 0, false);
// 设置回调
client.setCallback(new MqttCallBack());
client.connect(options);
// 设置默认订阅主题
// 消息等级与主题数组一一对应
int[] qos = DefineSubTopicEnum.queryAllQos();
// 主题
String[] topics = DefineSubTopicEnum.queryAllTopic();
// 订阅主题
client.subscribe(topics, qos);
}
/**
* 根据topic去实现自己的业务
* @param topic
* @return
*/
public static MqttService getMqttFactory(String topic){
DefineSubTopicEnum defineSubTopicEnum = DefineSubTopicEnum.getDefineSubTopicEnumByTopic(topic);
switch (defineSubTopicEnum){
case ROBOT_STATUS:
return BeanUtils.getBean(RobotStatusServiceImpl.class);
case ROBOT_REACTIVE_STATUS:
return BeanUtils.getBean(RobotReactiveStatusServiceImpl.class);
case ROBOT_GENERICS_STATUS:
return BeanUtils.getBean(RobotGenericsStatusServiceImpl.class);
case ROBOT_PATH_STATUS:
return BeanUtils.getBean(RobotPathStatusServiceImpl.class);
case ROBOT_WORK_STATUS:
return BeanUtils.getBean(RobotWorkStatusServiceImpl.class);
case ROBOT_UPDATE_PALLET_HEIGHT:
return BeanUtils.getBean(RobotUpdatePalletHeightServiceImpl.class);
case ROBOT_OBSTACLES_STATUS:
return BeanUtils.getBean(RobotObstaclesStatusServiceImpl.class);
case ROBOT_WIRELESS_SIGNAL_STATUS:
return BeanUtils.getBean(RobotWirelessSignalStatusServiceImpl.class);
case PLANNING_INIT_DATA:
return BeanUtils.getBean(PathPlanningInitDataServiceImpl.class);
case PLANNING_DISTRIBUTION_TASK:
return BeanUtils.getBean(PathPlanningDistributionTaskServiceImpl.class);
case PLANNING_DISTRIBUTION_FAIL:
return BeanUtils.getBean(PathPlanningDistributionFailServiceImpl.class);
case PLANNING_SIMULATION_ROBOT_POSE_REQUEST:
return BeanUtils.getBean(PlanningSimulationRobotPoseRequestServiceImpl.class);
case PLANNING_MOVE:
return BeanUtils.getBean(PathPlanningMoveServiceImpl.class);
case PLANNING_ROUTE_DISPLAY:
return BeanUtils.getBean(PathRouteDisplayPlanningServiceImpl.class);
case PLANNING_GRAPH_MATCH_DATA:
return BeanUtils.getBean(PlanningGraphMatchDataServiceImpl.class);
case PLANNING_REMOTE_ROBOT_MOVE_POSE_PLANNING:
return BeanUtils.getBean(PlanningRemoteRobotMovePosePlanningImpl.class);
default :
return BeanUtils.getBean(RobotTaskStatusServiceImpl.class);
}
}
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.system.config.mqtt;
import cn.hutool.core.util.IdUtil;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Mqtt Config
* * 备注以下刻意将 defaultClientIdclientId 区分使用
* * 防止断线重连的时候clientId 被重复拼接时间戳
*/
@Getter
@Configuration
public class MqttProperties {
@Value("${mqtt.host}")
private String hostUrl;
@Value("${mqtt.username}")
private String username;
@Value("${mqtt.password}")
private String password;
@Value("${mqtt.clientId}")
private String clientId;
@Value("${mqtt.qos}")
private int qos;
@Value("${mqtt.maxInflight}")
private int maxInflight;
private String clientUUId;
public String getClientId() {
if (clientUUId == null) {
clientUUId = clientId + IdUtil.fastSimpleUUID();
}
return clientUUId;
}
}

View File

@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.system.config.mqtt.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
/**
* 默认订阅的话题 -- 枚举类
*/
@Getter
@AllArgsConstructor
public enum DefineSubTopicEnum {
//qos 0-至多1次1-至少1次2-正好一次
ROBOT_STATUS("ROBOT_STATUS", 2,"点位"),
ROBOT_TASK_STATUS("ROBOT_TASK_STATUS", 2,"机器人任务完成上报"),
ROBOT_REACTIVE_STATUS("ROBOT_REACTIVE_STATUS", 2,"机器人响应式状态上报"),
ROBOT_GENERICS_STATUS("ROBOT_GENERICS_STATUS", 2,"机器人异常"),
ROBOT_PATH_STATUS("ROBOT_PATH_STATUS", 2,"导航实时行为上报"),
ROBOT_WORK_STATUS("ROBOT_WORK_STATUS", 2,"作业实时行为上报"),
ROBOT_UPDATE_PALLET_HEIGHT("UPDATE_PALLET_HEIGHT", 2,"放货后货物高度反馈和取货后货物高度反馈"),
ROBOT_OBSTACLES_STATUS("ROBOT_OBSTACLES_STATUS", 2,"障碍物状态上报"),
ROBOT_WIRELESS_SIGNAL_STATUS("ROBOT_WIRELESS_SIGNAL_STATUS", 2,"信号强度上报"),
PLANNING_INIT_DATA("SYNCHRONOUS_ALL_MAP_REQUEST", 2,"路径规划需要初始数据上报"),
PLANNING_DISTRIBUTION_TASK("TASK_ASSIGNMENT_FEEDBACK", 2,"路径规划任务分配上报"),
PLANNING_DISTRIBUTION_FAIL("TASK_ASSIGNMENT_FAIL", 2,"路径规划失败上报"),
PLANNING_SIMULATION_ROBOT_POSE_REQUEST("SIMULATION_ROBOT_POSE_REQUEST", 2,"仿真初始化点位信息"),
PLANNING_MOVE("UPDATE_ROUTE_DISPLAY_PLANNING", 2,"车辆即将走的点位"),
PLANNING_ROUTE_DISPLAY("ROBOT_MOVE_POSE_PLANNING", 2,"路径规划上报实时路径"),
PLANNING_GRAPH_MATCH_DATA("GRAPH_MATCH_DATA", 2,"路网匹配实时数据"),
PLANNING_REMOTE_ROBOT_MOVE_POSE_PLANNING("REMOTE_ROBOT_MOVE_POSE_PLANNING", 2,"远遥车辆行走导航");
private final String topic;
private final int qos;
private final String msg;
/**
* 获取所有话题名
*
* @return topicArr
*/
public static String[] queryAllTopic() {
List<String> topicList = new ArrayList<>();
for (DefineSubTopicEnum item : DefineSubTopicEnum.values()) {
topicList.add(item.getTopic());
}
String[] topicArr = new String[topicList.size()];
topicArr = topicList.toArray(topicArr);
return topicArr;
}
/**
* 获取所有qos
*
* @return qosArr
*/
public static int[] queryAllQos() {
List<Integer> qosList = new ArrayList<>();
for (DefineSubTopicEnum item : DefineSubTopicEnum.values()) {
qosList.add(item.getQos());
}
int[] qosArr = new int[qosList.size()];
qosArr = qosList.stream().mapToInt(Integer::intValue).toArray();
return qosArr;
}
public static DefineSubTopicEnum getDefineSubTopicEnumByTopic(String topic) {
for (DefineSubTopicEnum item : DefineSubTopicEnum.values()) {
if (item.getTopic().equals(topic)) {
return item;
}
}
return null;
}
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.config.mqtt.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtils implements ApplicationContextAware {
protected static ApplicationContext applicationContext ;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
if (applicationContext == null) {
applicationContext = arg0;
}
}
public static Object getBean(String name) {
//name表示其他要注入的注解name名
return applicationContext.getBean(name);
}
/**
* 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象
*/
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}

View File

@ -0,0 +1,93 @@
package cn.iocoder.yudao.module.system.config.mqtt.util;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.config.mqtt.MqttFactory;
import cn.iocoder.yudao.module.system.config.mqtt.MqttProperties;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
@Component
public class MqttUtils {
@Autowired
private MqttProperties config;
private static final ExecutorService executorService = Executors.newFixedThreadPool(50);
/**
* 发布消息
*
* @param qos 0-至多1次1-至少1次2-一次
* @param retained 是否保留true-sub重新连接mqtt服务端时总能拿到该主题的最新消息false-sub重新连接mqtt服务端时只能拿到连接后发布的消息
* @param topic 话题
* @param message 消息内容
*/
public void pub(String topic, String message) {
executorService.execute(() ->{
send(topic, message);
});
}
public void send(String topic, String message) {
// 获取客户端实例
MqttClient client = null;
try {
client = MqttFactory.getInstance();
} catch (MqttException e) {
log.info("获取客户端异常 :{}",e);
}
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setQos(config.getQos());
mqttMessage.setRetained(false);
// 此处必须指明编码方式否则会出现订阅端中文乱码的情况
mqttMessage.setPayload(message.getBytes(StandardCharsets.UTF_8));
// 主题的目的地用于发布/订阅信息
MqttTopic mqttTopic = client.getTopic(topic);
// 提供一种机制来跟踪消息的传递进度
// 用于在以非阻塞方式在后台运行执行发布是跟踪消息的传递进度
MqttDeliveryToken token;
try {
// 将指定消息发布到主题但不等待消息传递完成返回的token可用于跟踪消息的传递状态
// 一旦此方法干净地返回消息就已被客户端接受发布当连接可用将在后台完成消息传递
token = mqttTopic.publish(mqttMessage);
token.waitForCompletion();
} catch (MqttException e) {
log.info("MQTT");
}
if (PathPlanningTopicConstant.AGV_POSE.equals(topic)) {
return;
}
if (message.length() > 510) {
log.info("发送的主题 :{}, 内容 :{}",topic, message.substring(0, 500));
}else {
log.info("发送的主题 :{}, 内容 :{}",topic, message);
}
}
/**
* 断开连接
*/
public static void disConnect() {
try {
// 获取客户端实例
MqttClient client = MqttFactory.getInstance();
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.system.config.poperties;
import cn.iocoder.yudao.module.system.config.poperties.dto.RobotCharge;
import cn.iocoder.yudao.module.system.config.poperties.dto.RobotConfig;
import cn.iocoder.yudao.module.system.config.poperties.dto.RobotDoingAction;
import cn.iocoder.yudao.module.system.config.poperties.dto.Task;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Data
@RefreshScope
@Component
@ConfigurationProperties(prefix = "zn")
public class ZnConfigConstant {
private String taskNo;
private String moveNo;
private String chargeNo;
private String cameraSecretKey;
private Boolean doCycle;
private Boolean laneAutoMove;
private Long robotPositionCacheTime;
private Boolean cycleDoAutoMove;
private String fullElectricity;
private Boolean taskNeedSingle;
private Long locationNumberReduce;
private RobotDoingAction robotDoingAction;
private RobotCharge robotCharge;
private Task task ;
private RobotConfig robotConfig;
private Boolean openRateLimiter;
private Boolean isSimulation;
private Boolean sendRobotInitPose;
private Integer synchronousAllMapNode;
private Boolean taskNotCheck;
}

View File

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.system.config.poperties.dto;
import lombok.Data;
@Data
public class RobotCharge {
private Long releaseLocationNumberConfig;
private Long priorityConfig;
}

View File

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.system.config.poperties.dto;
import lombok.Data;
@Data
public class RobotConfig {
private Double offsetHeight;
private Double defaultTrayHeight;
}

View File

@ -0,0 +1,8 @@
package cn.iocoder.yudao.module.system.config.poperties.dto;
import lombok.Data;
@Data
public class RobotDoingAction {
private Long doingActionCacheTime;
}

View File

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.system.config.poperties.dto;
import lombok.Data;
@Data
public class Task {
private Boolean checkSkuInfo;
private Long taskCacheTime;
}

View File

@ -49,4 +49,7 @@ public class RobotTaskChcheConstant {
//机器人物料数量(拼接的是mac地址)
public static String ROBOT_TASK_SKU_INFO = "robot:task:sku:info";
//所有的车辆信息 获得到一个map key是 macvalue是具体信息
public static String ROBOT_ALL_INFORMATION = "robot:all:information";
}

View File

@ -153,7 +153,7 @@ public class RobotInformationController {
@Operation(summary = "恢复任务")
@PreAuthorize("@ss.hasPermission('robot:information:doTaskContinue')")
public CommonResult<Boolean> doTaskContinue(@RequestParam("robotNo") String robotNo) {
informationService.doTaskContinue(robotNo);
informationService.doTaskContinue(robotNo,false);
return success(true);
}

View File

@ -130,4 +130,11 @@ public class RobotTaskController {
return success(true);
}
@GetMapping("/getRobotTaskNum")
@Operation(summary = "获取这台车工作的任务总数")
@Parameter(name = "robotNo", description = "车辆编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:task:getRobotTaskNum')")
public CommonResult<Integer> getRobotTaskNum(@RequestParam("robotNo") String robotNo) {
return success(taskService.getRobotTaskNum(robotNo));
}
}

View File

@ -84,6 +84,7 @@ public class PositionMapItemDO extends BaseDO {
/**
* AGV编号
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String robotNo;
}

View File

@ -27,4 +27,10 @@ public interface TaskCycleMapper extends BaseMapperX<TaskCycleDO> {
}
void deletByRobotTaskId(@Param("robotTaskId") Long robotTaskId);
/**
* 批量删除
* @param taskIds
*/
void deletByRobotTaskIds(@Param("taskIds") Set<Long> taskIds);
}

View File

@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mqtt.api.path.dto.PositionMapItemSynDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.Pose2ds;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.RobotPositionMapDTO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapIdNumMapVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import org.apache.ibatis.annotations.Mapper;
@ -96,5 +95,7 @@ public interface PositionMapItemMapper extends BaseMapperX<PositionMapItemDO> {
* @param ids
* @return
*/
List<PositionMapIdNumMapVO> selectSortNumByIds(@Param("ids") List<Long> ids);
/*@MapKey("id")
Map<Long, Long> selectSortNumByIds(@Param("ids") List<Long> ids);*/
List<PositionMapItemDO> selectSortNumByIds(@Param("ids") List<Long> ids);
}

View File

@ -88,4 +88,8 @@ public interface RobotInformationMapper extends BaseMapperX<RobotInformationDO>
* @return
*/
List<RobotInformationDO> getListByMapId(@Param("mapId") Long mapId);
RobotInformationDO selectByRobotNoAndIdNotIn(@Param("robotNo") String robotNo, @Param("id") Long id);
RobotInformationDO selectByMacAndIdNotIn(@Param("macAddress") String macAddress,@Param("id") Long id);
}

View File

@ -13,7 +13,8 @@ public enum RobotStatusCodeEnum {
FAIL_JSON("10001","入参JSON解析失败"),
FAIL_SYSTEM("10002","系统内部异常"),
FAIL_UN_KNOW("10003","未知错误"),
FAIL_UN_SUPPOD("10004","未支持该指令执行");
FAIL_UN_SUPPOD("10004","未支持该指令执行"),
EXCEEDING_SECONDS("10017","PP发送的任务超过5秒到达");
/**
* 类型
*/

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.system.enums.robot.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum WorkProgressEnum {
FORK_OFFSET("FORK_OFFSET","取放货");
/**
* 类型
*/
private final String type;
private final String msg;
}

View File

@ -3,10 +3,11 @@ package cn.iocoder.yudao.module.system.framework.mqtt;
import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import cn.iocoder.yudao.module.remote.api.path.RemotePathApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {RobotTaskApi.class, PathPlanningApi.class, CommonApi.class})
@EnableFeignClients(clients = {RobotTaskApi.class, PathPlanningApi.class, CommonApi.class, RemotePathApi.class})
public class MqttConfiguration {
}

View File

@ -84,9 +84,11 @@ public class RobotJob {
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
if (lock.tryLock()){
try {
log.info("----下发自动充电任务----");
log.info("----111111下发自动充电任务----");
autoChargeService.autoChargeJob();
} finally {
} catch (Exception e) {
log.info("自动充电异常 :{}",e);
} finally {
lock.unlock();
}
}else {
@ -105,9 +107,11 @@ public class RobotJob {
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
if (lock.tryLock()){
try {
log.info("----下发任务给路径规划----");
log.info("----111111下发任务给路径规划----");
robotPathPlanningService.sendTaskToPP();
} finally {
} catch (Exception e) {
log.info("----分配任务异常---- :{}",e);
} finally {
lock.unlock();
}
}else {
@ -127,12 +131,16 @@ public class RobotJob {
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_ADD_LOCK.getKey());
if (lock.tryLock()){
try {
log.info("----创建循环任务----");
log.info("----111111创建循环任务----");
cycleService.cycleTaskJob();
} finally {
} catch (Exception e) {
log.error("创建循环任务异常 :{}",e);
} finally {
lock.unlock();
}
}else {
log.info("下发任务给路径规划未获取到锁");
throw exception(REDISSON_NOT_OBTAIN_LOCK);
@ -173,7 +181,9 @@ public class RobotJob {
log.info("----统计时长开始----");
TenantContextHolder.setTenantId(1L);
robotWorkingHoursStatisticsService.statisticsRobotDuration();
} finally {
} catch (Exception e) {
log.info("统计工作时长异常 :{}",e);
} finally {
lock.unlock();
}
}else {

View File

@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.system.schedul;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
import cn.iocoder.yudao.module.system.constant.CommonConstant;
import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant;
import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@EnableScheduling
@Component
@Slf4j
public class RcsMapScheduled {
@Resource
private RedisUtil redisUtil;
@Resource
private PositionMapService positionMapService;
@Resource
public WebSocketSenderApi webSocketSenderApi;
private static final ExecutorService FIXED_THREAD_POOL = Executors.newFixedThreadPool(10);
// 这个方法将每200毫秒执行一次
@Scheduled(fixedDelay = 100, timeUnit = TimeUnit.MILLISECONDS)
public void executeTask() {
FIXED_THREAD_POOL.execute(this::sendRobotInformationToRcsMap);
}
private void sendRobotInformationToRcsMap() {
TenantContextHolder.setTenantId(1L);
Object o = redisUtil.get(FloorAreaConstant.FLOOR_AREA_ALL);
List<PositionMapDO> allMap = null;
if (ObjectUtil.isEmpty(o)) {
allMap = positionMapService.getAllMap();
if (ObjectUtil.isEmpty(allMap)) {
return;
}
redisUtil.set(FloorAreaConstant.FLOOR_AREA_ALL, JSON.toJSONString(allMap),600);
}else {
allMap = JSON.parseArray(String.valueOf(o), PositionMapDO.class);
}
for (PositionMapDO positionMap : allMap) {
String floorArea = positionMap.getFloor() + CommonConstant.SYMBOL + positionMap.getArea();
String key = FloorAreaConstant.FLOOR_AREA_ROBOT + floorArea;
Map<Object, Object> data = redisUtil.hmget(key);
if (ObjectUtil.isEmpty(data)) {
continue;
}
webSocketSenderApi.sendObject(floorArea, WebSocketConstant.MAP_PUSH, data);
}
}
}

View File

@ -28,7 +28,7 @@ import java.util.concurrent.TimeUnit;
@EnableScheduling
@Component
@Slf4j
public class ScheduledTasks {
public class ThreeDimensionalScheduled {
@Resource
private PositionMapService positionMapService;
@ -39,17 +39,12 @@ public class ScheduledTasks {
@Resource
public WebSocketSenderApi webSocketSenderApi;
private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
private static final ExecutorService FIXED_THREAD_POOL = Executors.newFixedThreadPool(3);
// 这个方法将每200毫秒执行一次
// @Scheduled(fixedDelay = 300, timeUnit = TimeUnit.MILLISECONDS)
public void executeTask() {
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
sendData();
}
});
FIXED_THREAD_POOL.execute(this::sendData);
}
public void sendData() {
@ -61,7 +56,7 @@ public class ScheduledTasks {
if (ObjectUtil.isEmpty(allMap)) {
return;
}
redisUtil.set(FloorAreaConstant.FLOOR_AREA_ALL,JSON.toJSONString(allMap),60);
redisUtil.set(FloorAreaConstant.FLOOR_AREA_ALL,JSON.toJSONString(allMap),600);
}else {
allMap = JSON.parseArray(String.valueOf(o), PositionMapDO.class);
}

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.device.DeviceChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.DeviceInformationDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.MapBindDeviceInfoDTO;
@ -40,6 +41,7 @@ import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@ -91,8 +93,8 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
@Resource
private PositionMapItemService positionMapItemService;
@Value("${zn.camera_secret_key}")
private String cameraSecretKey;
@Autowired
private ZnConfigConstant znConfigConstant;
@Override
public Long createInformation(DeviceInformationSaveReqVO createReqVO) {
@ -114,7 +116,7 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
if (DeviceTypeEnum.CAMERA.getType().equals(createReqVO.getDeviceType())) {
try {
createReqVO.setCameraCode(AESEncryptionUtil.getEncrypt(createReqVO.getCameraCode(), cameraSecretKey));
createReqVO.setCameraCode(AESEncryptionUtil.getEncrypt(createReqVO.getCameraCode(), znConfigConstant.getCameraSecretKey()));
} catch (Exception ignored) {
}
}
@ -149,7 +151,7 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
// 更新
if (DeviceTypeEnum.CAMERA.getType().equals(updateReqVO.getDeviceType())) {
try {
updateReqVO.setCameraCode(AESEncryptionUtil.getEncrypt(updateReqVO.getCameraCode(), cameraSecretKey));
updateReqVO.setCameraCode(AESEncryptionUtil.getEncrypt(updateReqVO.getCameraCode(), znConfigConstant.getCameraSecretKey()));
} catch (Exception ignored) {
}
}
@ -478,7 +480,7 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
return "";
}
return AESEncryptionUtil.decrypt(deviceInformationDO.getCameraCode(), cameraSecretKey);
return AESEncryptionUtil.decrypt(deviceInformationDO.getCameraCode(), znConfigConstant.getCameraSecretKey());
}
public void shrink(String ip, int port, String deviceNo) {

View File

@ -0,0 +1,5 @@
package cn.iocoder.yudao.module.system.service.mqtt;
public interface MqttService {
void analysisMessage(String message);
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class PathPlanningDistributionFailServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
@Override
public void analysisMessage(String message) {
log.info("路径规划失败信息上报 :{}", message);
pathApi.ppDistributionTaskFail(message);
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class PathPlanningDistributionTaskServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
/**
* PP分配任务上报
* @param message
*/
@Override
public void analysisMessage(String message) {
log.info("PP上报任务分配 :{}", message);
pathApi.ppDistributionTask(message);
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class PathPlanningInitDataServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
/**
* 路径规划需要初始数据上报
* @param message
*/
@Override
public void analysisMessage(String message) {
log.info("收到路径规划需要初始化数据的请求");
pathApi.pathInitData();
}
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class PathPlanningMoveServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
@Override
public void analysisMessage(String message) {
log.info("收到路径规划规划即将要走的点位的消息 :{}",message);
pathApi.pathPlanningMovePose(message);
}
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class PathRouteDisplayPlanningServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
@Override
public void analysisMessage(String message) {
log.info("收到路径规划的消息 :{}",message);
pathApi.pathPlanningMove(message);
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 路网匹配实时数据
*/
@Slf4j
@Service
public class PlanningGraphMatchDataServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
@Override
public void analysisMessage(String message) {
log.info("匹配路网实时数据 :{}",message);
pathApi.graphMatchData(message);
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.remote.api.path.RemotePathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class PlanningRemoteRobotMovePosePlanningImpl implements MqttService{
@Resource
private RemotePathApi remotePathApi;
@Override
public void analysisMessage(String message) {
log.info("处理远遥导航的消息 :{}",message);
remotePathApi.remoteDistanceInformation(message);
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class PlanningSimulationRobotPoseRequestServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
@Override
public void analysisMessage(String message) {
log.info("收到仿真初始化点位的消息 :{}",message);
pathApi.simulationRobotPoseRequest(message);
}
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotGenericsStatusApi;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class RobotGenericsStatusServiceImpl implements MqttService{
@Resource
private RobotGenericsStatusApi robotGenericsStatusApi;
@Override
public void analysisMessage(String message) {
// log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
RobotGenericsDataDTO robotStatusData = JSON.parseObject(message , RobotGenericsDataDTO.class);
robotGenericsStatusApi.updateRobotCommonStatus(robotStatusData);
}
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotObstaclesStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RobotObstaclesStatusServiceImpl implements MqttService{
@Autowired
private RobotObstaclesStatusApi robotObstaclesStatusApi;
@Override
public void analysisMessage(String message) {
log.info("障碍物状态上报 :{}", message);
robotObstaclesStatusApi.robotObstaclesStatus(message);
}
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotPathStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class RobotPathStatusServiceImpl implements MqttService{
@Resource
private RobotPathStatusApi robotPathStatusApi;
@Override
public void analysisMessage(String message) {
log.info("导航实时行为上报 :{}", message);
robotPathStatusApi.robotPathStatus(message);
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotReactiveStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RobotReactiveStatusServiceImpl implements MqttService{
@Autowired
private RobotReactiveStatusApi robotReactiveStatusApi;
@Override
public void analysisMessage(String message) {
// log.info("机器人状态上报 :{}", message);
robotReactiveStatusApi.robotReactiveStatus(message);
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotPoseStatusDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class RobotStatusServiceImpl implements MqttService {
@Resource
private RobotStatusApi robotStatusApi;
/**
* 机器人点位
*
* @param message
*/
@Override
public void analysisMessage(String message) {
// log.info("处理RobotStatusServiceImpl的消息 :{}", message);
RobotPoseStatusDTO robotStatusData = JSON.parseObject(message, RobotPoseStatusDTO.class);
robotStatusApi.robotStatusUpdate(robotStatusData);
}
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotTaskStatusApi;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class RobotTaskStatusServiceImpl implements MqttService {
@Autowired
private RobotTaskStatusApi robotTaskStatusApi;
@Override
public void analysisMessage(String message) {
log.info("处理RobotTaskStatusServiceImpl的消息 :{}",message);
RobotCompleteTaskDTO robotCompleteTask = JSON.parseObject(message , RobotCompleteTaskDTO.class);
robotTaskStatusApi.robotDoneTask(robotCompleteTask);
}
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotUpdatePalletHeightApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class RobotUpdatePalletHeightServiceImpl implements MqttService {
@Autowired
private RobotUpdatePalletHeightApi robotUpdatePalletHeightApi;
@Override
public void analysisMessage(String message) {
log.info("处理RobotTaskStatusServiceImpl的消息 :{}",message);
robotUpdatePalletHeightApi.updatePalletHeight(message);
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.remote.api.path.RemotePathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class RobotWirelessSignalStatusServiceImpl implements MqttService{
@Resource
private RemotePathApi remotePathApi;
@Override
public void analysisMessage(String message) {
log.info("车辆信号上报 :{}",message);
remotePathApi.wirelessSignalStatus(message);
}
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.system.service.mqtt;
import cn.iocoder.yudao.module.system.api.robot.RobotWorkStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RobotWorkStatusServiceImpl implements MqttService{
@Autowired
private RobotWorkStatusApi robotWorkStatusApi;
@Override
public void analysisMessage(String message) {
log.info("作业实时行为上报 :{}", message);
robotWorkStatusApi.robotWorkStatus(message);
}
}

View File

@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.mqtt.api.path.dto.*;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskPathPlanningDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
import cn.iocoder.yudao.module.system.api.robot.vo.PathPlanningMovePoseVO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.CommonConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
@ -101,8 +103,11 @@ public class PathPlanningServiceImpl implements PathPlanningService {
@Autowired
private RobotInformationService robotInformationService;
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
private RedisUtil redisUtil;
@ -120,11 +125,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
@Resource
private PositionMapItemService positionMapItemService;
@Value("${zn.send_robot_init_pose:false}")
private Boolean sendRobotInitPose;
@Value("${zn.synchronous_all_map_node:500}")
private Integer synchronousAllMapNodeSize;
@Autowired
private ZnConfigConstant znConfigConstant;
@Resource
private PositionChangePointBindingService positionChangePointBindingService;
@ -175,7 +177,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
assembleDataToPP(relatedPathNode, positionMapLineDOS);
}
commonApi.commonMethod(new PositionMapLineDTO(), PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE_END);
// commonApi.commonMethod(new PositionMapLineDTO(), PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE_END);
mqttUtils.pub(PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE_END,JSON.toJSONString(new PositionMapLineDO()));
}
/**
@ -200,14 +203,15 @@ public class PathPlanningServiceImpl implements PathPlanningService {
continue;
}
List<List<PositionMapItemSynDTO>> partition = Lists.partition(positionMapItemSynDTOS, synchronousAllMapNodeSize);
List<List<PositionMapItemSynDTO>> partition = Lists.partition(positionMapItemSynDTOS, znConfigConstant.getSynchronousAllMapNode());
for (List<PositionMapItemSynDTO> nodes : partition) {
PositionMapItemPathDTO relatedPathNode = new PositionMapItemPathDTO();
relatedPathNode.setFloor(positionMapDO.getFloor());
relatedPathNode.setArea(positionMapDO.getArea());
relatedPathNode.setType(PathTypeEnum.INIT.getType());
relatedPathNode.setControl_nodes(nodes);
commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_NODE);
// commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_NODE);
mqttUtils.pub(PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_NODE,JSON.toJSONString(relatedPathNode));
}
}
@ -257,7 +261,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
relatedPathNode.setArea(positionMapDO.getArea());
relatedPathNode.setControl_nodes(list);
commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.ADD_MAP_LINE);
// commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.ADD_MAP_LINE);
mqttUtils.pub(PathPlanningTopicConstant.ADD_MAP_LINE,JSON.toJSONString(relatedPathNode));
}
/**
@ -287,8 +292,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
ids.add(data.getId());
relatedPathNode.setIds(ids);
commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.DELETE_MAP_LINE);
// commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.DELETE_MAP_LINE);
mqttUtils.pub(PathPlanningTopicConstant.DELETE_MAP_LINE,JSON.toJSONString(relatedPathNode));
}
/**
@ -335,7 +340,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
relatedPathNode.setType(PathTypeEnum.UPDATE.getType());
relatedPathNode.setControl_nodes(list);
commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.UPDATE_MAP_LINE);
// commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.UPDATE_MAP_LINE);
mqttUtils.pub(PathPlanningTopicConstant.UPDATE_MAP_LINE,JSON.toJSONString(relatedPathNode));
}
/**
@ -377,7 +383,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
PositionMapItemPathDTO.setType(PathTypeEnum.ADD.getType());
PositionMapItemPathDTO.setControl_nodes(Arrays.asList(build));
commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.ADD_MAP_NODE);
// commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.ADD_MAP_NODE);
mqttUtils.pub(PathPlanningTopicConstant.ADD_MAP_NODE,JSON.toJSONString(PositionMapItemPathDTO));
}
/**
@ -411,7 +418,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
PositionMapItemPathDTO.setType(PathTypeEnum.DELETE.getType());
PositionMapItemPathDTO.setIds(Arrays.asList(data.getId()));
commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.DELETE_MAP_NODE);
// commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.DELETE_MAP_NODE);
mqttUtils.pub( PathPlanningTopicConstant.DELETE_MAP_NODE,JSON.toJSONString(PositionMapItemPathDTO));
}
@Override
@ -448,13 +456,15 @@ public class PathPlanningServiceImpl implements PathPlanningService {
PositionMapItemPathDTO.setType(PathTypeEnum.UPDATE.getType());
PositionMapItemPathDTO.setControl_nodes(Arrays.asList(build));
commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.UPDATE_MAP_NODE);
// commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.UPDATE_MAP_NODE);
mqttUtils.pub(PathPlanningTopicConstant.UPDATE_MAP_NODE,JSON.toJSONString(PositionMapItemPathDTO));
}
@Override
public void robotDimensions() {
List<RobotDimensionsDTO> list = informationMapper.selectRobotDimensions();
commonApi.commonMethod(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
// commonApi.commonMethod(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
mqttUtils.pub(PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS,JSON.toJSONString(list));
}
/**
@ -470,10 +480,11 @@ public class PathPlanningServiceImpl implements PathPlanningService {
String topic = RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac;
if(RobotCommandTypeEnum.SWITCH_MAP.getType().equals(pathRobotDTO.getTaskType())) {
switchMap(pathRobotDTO,topic);
} else if (PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType().equals(pathRobotDTO.getTaskType())) {
} /*else if (PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType().equals(pathRobotDTO.getTaskType())) {
wordDropOffGoods(message,topic,pathRobotDTO.getRobotNo());
} else {
commonApi.commonMethodStr(message, topic);
} */else {
// commonApi.commonMethodStr(message, topic);
mqttUtils.pub(topic,message);
}
}
@ -487,7 +498,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
RobotModelDO model = modelService.getModel(robotInformation.getRobotModelId());
if (String.valueOf(ZeroOneEnum.ZERO.getType()).equals(model.getRobotXOffset())
&& String.valueOf(ZeroOneEnum.ZERO.getType()).equals(model.getRobotYOffset())) {
commonApi.commonMethodStr(message, topic);
// commonApi.commonMethodStr(message, topic);
mqttUtils.pub(topic,message);
return;
}
PathToRobotChangeXYDTO pathToRobotChangeXY = JSON.parseObject(message, PathToRobotChangeXYDTO.class);
@ -502,7 +514,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
}
if (!needOffset) {
commonApi.commonMethodStr(message, topic);
// commonApi.commonMethodStr(message, topic);
mqttUtils.pub(topic,message);
return;
}
@ -518,8 +531,10 @@ public class PathPlanningServiceImpl implements PathPlanningService {
BigDecimal y = (sino.multiply(robotXOffset, MathContext.DECIMAL32)).add(coso.multiply(robotYOffset, MathContext.DECIMAL32)).add(y1);
cargoPose.setX(x.doubleValue());
cargoPose.setY(y.doubleValue());
log.info("转换后 :{}",JSON.toJSONString(pathToRobotChangeXY));
commonApi.commonMethodStr(JSON.toJSONString(pathToRobotChangeXY), topic);
log.info("111111转换前数据 :{}",message);
log.info("111111转换后 :{}",JSON.toJSONString(pathToRobotChangeXY));
// commonApi.commonMethodStr(JSON.toJSONString(pathToRobotChangeXY), topic);
mqttUtils.pub(topic,JSON.toJSONString(pathToRobotChangeXY));
}
/**
@ -531,7 +546,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
String mapFileName = positionMapService.getMapFileNameByFloorAndAreaName(pathRobotDTO.getArg().getFloor(),pathRobotDTO.getArg().getAreaId());
pathRobotDTO.getArg().setMapName(mapFileName);
controllerInformationService.robotChangeSpeed(pathRobotDTO);
commonApi.commonMethodStr(JSON.toJSONString(pathRobotDTO), topic);
// commonApi.commonMethodStr(JSON.toJSONString(pathRobotDTO), topic);
mqttUtils.pub(topic,JSON.toJSONString(pathRobotDTO));
RobotTaskDetailActionLogDO actionLog = taskDetailActionLogService.getLastTaskByRobotNo(pathRobotDTO.getRobotNo(),null);
if (ObjectUtil.isNotEmpty(actionLog)) {
//为了统计各个地图的工作时间
@ -568,7 +584,9 @@ public class PathPlanningServiceImpl implements PathPlanningService {
public void updateBehavior(String orderId, String robotNo, String behaviorId, String isReach) {
TaskPathPlanningDTO build = TaskPathPlanningDTO.builder().orderId(orderId).robotNo(robotNo)
.behaviorId(behaviorId).isReach(isReach).build();
commonApi.commonMethod(build, PathPlanningTopicConstant.UPDATE_BEHAVIOR);
log.info("111111发给PP的数据 :{}",JSON.toJSONString(build));
// commonApi.commonMethod(build, PathPlanningTopicConstant.UPDATE_BEHAVIOR);
mqttUtils.pub(PathPlanningTopicConstant.UPDATE_BEHAVIOR,JSON.toJSONString(build));
}
/**
@ -577,7 +595,7 @@ public class PathPlanningServiceImpl implements PathPlanningService {
*/
@Override
public void pathPlanningMovePose(String message) {
log.info("车辆即将行走的点位 :{}",message);
log.info("111111路径规划车辆即将行走的点位 :{}",message);
PathPlanningMovePoseVO robotStatusData = JSON.parseObject(message, PathPlanningMovePoseVO.class);
String mac = robotInformationService.getMacByRobotNo(robotStatusData.getRobotNo());
String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + mac;
@ -593,7 +611,7 @@ public class PathPlanningServiceImpl implements PathPlanningService {
@Override
public void simulationRobotPoseRequest() {
if (!sendRobotInitPose) {
if (!znConfigConstant.getSendRobotInitPose()) {
log.info("不同步初始点位信息");
return;
}
@ -660,7 +678,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
simulationList.add(simulationRobotPoseDTO);
i++;
}
commonApi.commonMethod(simulationList, PathPlanningTopicConstant.INIT_ROBOT_POSE);
// commonApi.commonMethod(simulationList, PathPlanningTopicConstant.INIT_ROBOT_POSE);
mqttUtils.pub( PathPlanningTopicConstant.INIT_ROBOT_POSE,JSON.toJSONString(simulationList));
}
/**
@ -676,7 +695,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
@Override
public void synchronousStart() {
commonApi.commonMethodStr("开始同步点位信息", PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_INIT);
// commonApi.commonMethodStr("开始同步点位信息", PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_INIT);
mqttUtils.pub(PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_INIT,"开始同步点位信息");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
@ -688,7 +708,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
public void sendPositionChangePointBinding() {
List<PositionAllChangePointBindingDTO> bindingDTOS = positionChangePointBindingService.getAllPositionChangePointBinding();
if (ObjectUtil.isNotEmpty(bindingDTOS)) {
commonApi.commonMethod(bindingDTOS, PathPlanningTopicConstant.SYNCHRONOUS_ALL_SWITCH_POINT_BINDING);
// commonApi.commonMethod(bindingDTOS, PathPlanningTopicConstant.SYNCHRONOUS_ALL_SWITCH_POINT_BINDING);
mqttUtils.pub(PathPlanningTopicConstant.SYNCHRONOUS_ALL_SWITCH_POINT_BINDING,JSON.toJSONString(bindingDTOS));
}
}
@ -745,8 +766,8 @@ public class PathPlanningServiceImpl implements PathPlanningService {
relatedPathNode.setControl_nodes(list);
commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE);
// commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE);
mqttUtils.pub(PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE,JSON.toJSONString(relatedPathNode));
}

View File

@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapIdNumMapVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLinePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapLineMapper;
@ -66,8 +67,10 @@ public class PositionMapLineServiceImpl extends ServiceImpl<PositionMapLineMappe
List<Long> endPointIds = addList.stream().map(PositionMapLineDO::getEndPointId).collect(Collectors.toList());
//合并startPointIds endPointIds 并且去重
Set<Long> pointIds = CollUtil.unionDistinct(startPointIds, endPointIds);
List<PositionMapIdNumMapVO> positionMapIdNumMapVOS = positionMapItemMapper.selectSortNumByIds(new ArrayList<>(pointIds));
map = positionMapIdNumMapVOS.stream().collect(Collectors.toMap(PositionMapIdNumMapVO::getId, PositionMapIdNumMapVO::getSortNum));
List<PositionMapItemDO> positionMapItemDOS = positionMapItemMapper.selectSortNumByIds(new ArrayList<>(pointIds));
if (ObjectUtil.isNotEmpty(positionMapItemDOS)) {
map = positionMapItemDOS.stream().collect(Collectors.toMap(PositionMapItemDO::getId, PositionMapItemDO::getSortNum));
}
}
for (PositionMapLineDO positionMapLineDO : newList) {
positionMapLineDO.setPositionMapId(positionMapId);

View File

@ -7,8 +7,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotSimulationPoseDTO;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDetailDTO;
import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapDTO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapPageReqVO;
@ -91,6 +93,10 @@ public class PositionMapServiceImpl extends ServiceImpl<PositionMapMapper, Posit
@Resource
private RobotInformationService informationService;
@Resource
@Lazy
private PathApi pathApi;
@Resource
private UserOperationLogService userOperationLogService;
@ -257,6 +263,8 @@ public class PositionMapServiceImpl extends ServiceImpl<PositionMapMapper, Posit
houseLaneService.deleteHouseLaneByMapId(positionMap.getId());
parkingSpotService.deleteParkingByMapId(positionMap.getId());
redisUtil.del("pngBase64");
redisUtil.del(FloorAreaConstant.FLOOR_AREA_ALL);
pathApi.pathInitData();
}
// 处理 PNG 文件

View File

@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotTransferDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteTaskTransferDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataSpeedDTO;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotReactiveStatusDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
@ -58,6 +59,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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -113,8 +115,11 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl<RemoteCo
@Resource
private RedisUtil redisUtil;
@Resource
private CommonApi commonApi;
@Autowired
private MqttUtils mqttUtils;
/* @Resource
private CommonApi commonApi;*/
@Resource
private CommonConfigMapper configMapper;
@ -783,7 +788,8 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl<RemoteCo
robotModeDTO.setMaxSpeed(v);
}
String mac = informationService.getMacByRobotNo(robotNo);
commonApi.commonMethod(robotModeDTO, RobotTopicConstant.ROBOT_COMMAND_TOPIC + mac);
// commonApi.commonMethod(robotModeDTO, RobotTopicConstant.ROBOT_COMMAND_TOPIC + mac);
mqttUtils.pub(RobotTopicConstant.ROBOT_COMMAND_TOPIC + mac,JSON.toJSONString(robotModeDTO));
log.info("发送消息让车机 :{} 切换模式 :{}", robotNo, JSON.toJSONString(robotModeDTO));
}
@ -796,7 +802,8 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl<RemoteCo
RemotePathPlanningDTO remotePathPlanning = new RemotePathPlanningDTO();
remotePathPlanning.setRobotNo(robotNo);
remotePathPlanning.setOperationMode(operationMode);
commonApi.commonMethod(remotePathPlanning, topic);
// commonApi.commonMethod(remotePathPlanning, topic);
mqttUtils.pub(topic,JSON.toJSONString(remotePathPlanning));
}
/**

View File

@ -162,7 +162,7 @@ public interface RobotInformationService extends IService<RobotInformationDO> {
* 继续做任务
* @param robotNo
*/
void doTaskContinue(String robotNo);
void doTaskContinue(String robotNo,Boolean isRobot);
/**
*

View File

@ -23,6 +23,8 @@ import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.api.robot.websocket.RobotInformationVO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.CommonConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
@ -50,7 +52,6 @@ import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMappe
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
import cn.iocoder.yudao.module.system.dal.mysql.remote.RemoteControllerInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.*;
import cn.iocoder.yudao.module.system.dal.mysql.statistics.RobotWorkingHoursStatisticsMapper;
import cn.iocoder.yudao.module.system.dal.mysql.wait.MoveToWaitMapper;
import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
@ -118,8 +119,11 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
@Resource
private RobotModelMapper modelMapper;
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
private UserOperationLogService userOperationLogService;
@ -159,27 +163,12 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
@Resource
private RedissonUtils redissonUtils;
@Value("${zn.is_simulation:false}")
private Boolean isSimulation;
@Value("${zn.restore_task_restart:true}")
private Boolean restoreTaskRestart;
@Value("${zn.full_electricity:95}")
private String fullElectricity;
@Value("${zn.path_planning.task_chche_time:604800}")
private Long taskChcheTime;
@Resource
private RobotCameraService cameraService;
@Resource
private RobotChargeLogMapper chargeLogMapper;
@Resource
private RobotWorkingHoursStatisticsMapper robotWorkingHoursStatisticsMapper;
@Resource
private MoveToWaitMapper moveToWaitMapper;
@ -189,23 +178,23 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
@Resource
private RobotMapStopMapper mapStopMapper;
@Autowired
private ZnConfigConstant znConfigConstant;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createInformation(RobotInformationSaveReqVO createReqVO) {
//判断mac地址是否重复
RobotInformationDO existRobotMac = informationMapper.selectOne(new LambdaQueryWrapper<RobotInformationDO>()
.eq(RobotInformationDO::getMacAddress, createReqVO.getMacAddress())
.last("limit 1"));
if (ObjectUtil.isNotEmpty(existRobotMac)) {
RobotInformationDO existRobotInformationDO =
informationMapper.selectByMacAndIdNotIn(createReqVO.getMacAddress(),null);
if (ObjectUtil.isNotEmpty(existRobotInformationDO)) {
throw exception(ROBOT_MAC_ADDRESS_EXISTS);
}
//判断机器人编号
RobotInformationDO existRobotNo = informationMapper.selectOne(new LambdaQueryWrapper<RobotInformationDO>()
.eq(RobotInformationDO::getRobotNo, createReqVO.getRobotNo())
.last("limit 1"));
if (ObjectUtil.isNotEmpty(existRobotNo)) {
HashSet<String> set = new HashSet<>();
set.add(createReqVO.getRobotNo());
List<RobotInformationDO> robots = informationMapper.selectByRobotNos(set);
if (ObjectUtil.isNotEmpty(robots)) {
throw exception(ROBOT_ROBOT_NO_EXISTS);
}
@ -251,7 +240,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
userOperationLogService.createUserOperationLog(operationLog);
List<RobotDimensionsDTO> list = informationMapper.selectRobotDimensions();
commonApi.commonMethod(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
// commonApi.commonMethod(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
mqttUtils.pub(PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS, JSON.toJSONString(list));
redisUtil.del(key);
// 返回
@ -369,6 +359,21 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
validateInformationExists(updateReqVO.getId());
RobotInformationDO robotInformationDO = informationMapper.selectById(updateReqVO.getId());
if (RobotStatusEnum.STAND_BY.getType().equals(robotInformationDO.getRobotStatus())) {
PositionMapItemDO positionMapItem = positionMapItemMapper.selectOne(new LambdaQueryWrapper<PositionMapItemDO>()
.eq(PositionMapItemDO::getRobotNo, robotInformationDO.getRobotNo())
.eq(PositionMapItemDO::getUseStatus, UseStatusEnum.USEING.getType())
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.last("limit 1"));
if (ObjectUtil.isNotEmpty(positionMapItem) && ObjectUtil.isEmpty(updateReqVO.getFloorAreaJson())) {
log.info("车辆 :{} ,停靠在 :{},", robotInformationDO.getRobotNo(), positionMapItem.getPositionMapId());
throw exception(ROBOT_PART_AREA);
} else if (ObjectUtil.isNotEmpty(positionMapItem) && ObjectUtil.isNotEmpty(updateReqVO.getFloorAreaJson())
&& !updateReqVO.getFloorAreaJson().contains(positionMapItem.getPositionMapId())) {
throw exception(ROBOT_PART_AREA);
}
}
RemoteControllerInformationDO remoteControllerInformation = controllerInformationMapper.selectOne(new LambdaQueryWrapper<RemoteControllerInformationDO>()
.eq(RemoteControllerInformationDO::getRobotNo, robotInformationDO.getRobotNo())
.last("limit 1"));
@ -385,24 +390,22 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
}
}
//校验MAC地址
RobotInformationDO query = new RobotInformationDO();
query.setMacAddress(updateReqVO.getMacAddress());
List<RobotInformationDO> existRobot = informationMapper.queryAllByLimit(query);
boolean exist = existRobot.stream().anyMatch(v -> (v.getMacAddress().equals(updateReqVO.getMacAddress())
&& !v.getId().equals(updateReqVO.getId())));
if (exist) {
throw exception(ROBOT_MAC_ADDRESS_EXISTS);
if (!updateReqVO.getRobotNo().equals(robotInformationDO.getRobotNo())) {
RobotInformationDO existRobotInformationDO =
informationMapper.selectByRobotNoAndIdNotIn(updateReqVO.getRobotNo(),updateReqVO.getId());
if (ObjectUtil.isNotEmpty(existRobotInformationDO)) {
throw exception(ROBOT_ROBOT_NO_EXISTS);
}
}
//校验机器人编号
query.setMacAddress(null);
query.setRobotNo(updateReqVO.getRobotNo());
List<RobotInformationDO> existRobotNo = informationMapper.queryAllByLimit(query);
boolean robotNoExist = existRobotNo.stream().anyMatch(v -> (v.getRobotNo().equals(updateReqVO.getRobotNo())
&& !v.getId().equals(updateReqVO.getId())));
if (robotNoExist) {
throw exception(ROBOT_ROBOT_NO_EXISTS);
if (!updateReqVO.getMacAddress().equals(robotInformationDO.getMacAddress())) {
RobotInformationDO existRobotInformationDO =
informationMapper.selectByMacAndIdNotIn(updateReqVO.getMacAddress(),updateReqVO.getId());
if (ObjectUtil.isNotEmpty(existRobotInformationDO)) {
throw exception(ROBOT_MAC_ADDRESS_EXISTS);
}
}
//校验IP
RobotInformationDO existRobotIp = informationMapper.selectOne(new LambdaQueryWrapper<RobotInformationDO>()
.eq(RobotInformationDO::getRobotIp, updateReqVO.getRobotIp())
@ -425,7 +428,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
checkIpAndPort(updateObj);
if (!updateReqVO.getRobotNo().equals(robotInformationDO.getRobotNo())) {
updateRobotNo(robotInformationDO.getRobotNo(),updateReqVO.getRobotNo());
updateRobotNo(robotInformationDO.getRobotNo(), updateReqVO.getRobotNo());
}
informationMapper.updateById(updateObj);
@ -477,21 +480,23 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
List<RobotDimensionsDTO> RobotDimensions = informationMapper.selectRobotDimensions();
commonApi.commonMethod(RobotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
List<RobotDimensionsDTO> robotDimensions = informationMapper.selectRobotDimensions();
// commonApi.commonMethod(robotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
mqttUtils.pub(PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS, JSON.toJSONString(robotDimensions));
}
/**
* 跟新车辆编号
*
* @param oldRobotNo
* @param newRobotNo
*/
@Transactional(rollbackFor = Exception.class)
public void updateRobotNo(String oldRobotNo, String newRobotNo) {
deviceInformationMapper.updateRobotNo(oldRobotNo,newRobotNo);
deviceInformationMapper.updateRobotNo(oldRobotNo, newRobotNo);
controllerInformationMapper.updateRobotNo(oldRobotNo,newRobotNo);
controllerInformationMapper.updateRobotNo(oldRobotNo, newRobotNo);
RobotChargeLogDO robotChargeLog = chargeLogMapper.selectOne(new LambdaQueryWrapperX<RobotChargeLogDO>()
.eq(RobotChargeLogDO::getRobotNo, oldRobotNo)
@ -504,11 +509,11 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
//这表暂时不改
// robotWorkingHoursStatisticsMapper
mapStopMapper.updateRobotNo(oldRobotNo,newRobotNo);
mapStopMapper.updateRobotNo(oldRobotNo, newRobotNo);
moveToWaitMapper.updateRobotNo(oldRobotNo,newRobotNo);
moveToWaitMapper.updateRobotNo(oldRobotNo, newRobotNo);
positionMapItemMapper.updateRobotNo(oldRobotNo,newRobotNo);
positionMapItemMapper.updateRobotNo(oldRobotNo, newRobotNo);
}
@Override
@ -543,11 +548,22 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
// 删除
informationMapper.deleteById(id);
PositionMapItemDO positionMapItem = positionMapItemMapper.selectOne(new LambdaQueryWrapper<PositionMapItemDO>()
.eq(PositionMapItemDO::getRobotNo, robotInformationDO.getRobotNo())
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.last("limit 1"));
if (ObjectUtil.isNotEmpty(positionMapItem)) {
positionMapItem.setRobotNo(null);
positionMapItem.setUseStatus(UseStatusEnum.FREE.getType());
positionMapItemMapper.updateById(positionMapItem);
}
//释放暂停记录
releaseRobotStop(robotInformationDO);
List<RobotDimensionsDTO> RobotDimensions = informationMapper.selectRobotDimensions();
commonApi.commonMethod(RobotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
List<RobotDimensionsDTO> robotDimensions = informationMapper.selectRobotDimensions();
// commonApi.commonMethod(robotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS);
mqttUtils.pub(PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS, JSON.toJSONString(robotDimensions));
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robotInformationDO.getMacAddress();
redisUtil.del(pose2dKey);
@ -668,7 +684,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
if (ObjectUtil.isNotEmpty(cargoDetected) && RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))) {
//说明取货完成
v.setCargoDetected("有货");
}else {
} else {
v.setCargoDetected("空车");
}
if (RobotStatisticsTypeEnum.STANDBY.getType().equals(pageReqVO.getRobotStatisticsType())
@ -1074,7 +1090,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
List<RobotInformationDO> robotInformations = informationMapper.queryAllByLimit(query);
for (RobotInformationDO robotInformationDO : robotInformations) {
String topic = RobotTopicConstant.RCS_HEART_BEAT + robotInformationDO.getMacAddress();
commonApi.commonMethod(new RobotRcsHeartBeatDTO(), topic);
// commonApi.commonMethod(new RobotRcsHeartBeatDTO(), topic);
mqttUtils.pub(topic, JSON.toJSONString(new RobotRcsHeartBeatDTO()));
}
}
@ -1117,13 +1134,14 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
.eq(RobotInformationDO::getRobotNo, robotNo)
.last("limit 1"));
robotInformationDO.setRobotStatus(RobotStatusEnum.STAND_BY.getType());
robotInformationDO.setRobotTaskModel(RobotTaskModelEnum.REJECTION.getType());
// robotInformationDO.setRobotTaskModel(RobotTaskModelEnum.REJECTION.getType());
informationMapper.updateById(robotInformationDO);
}
public RobotTaskDetailActionLogDO closeTask(String robotNo) {
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
// commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
mqttUtils.pub(PathPlanningTopicConstant.CLEAN_AGV, JSON.toJSONString(build));
RobotTaskDetailActionLogDO log = taskDetailActionLogService.getLastTaskByRobotNo(robotNo, CommandIdEnum.TASK.getType());
if (ObjectUtil.isEmpty(log) || ActionStatusEnum.DONE.getType().equals(log.getActionStatus())
|| ActionStatusEnum.CLOSE.getType().equals(log.getActionStatus())) {
@ -1141,7 +1159,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void doTaskContinue(String robotNo) {
public void doTaskContinue(String robotNo, Boolean isRobot) {
RobotTaskDetailActionLogDO actionLog = taskDetailActionLogService.getOriginalLastTaskByRobotNo(robotNo);
if (ObjectUtil.isEmpty(actionLog)) {
@ -1156,12 +1174,13 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
String mac = getMacByRobotNo(robotNo);
robotCloseTaskDetail(actionLog.getTaskDetailId() + "", mac, actionLog.getCommandType());
if (!isSimulation && ActionStatusEnum.DONE.getType().equals(actionLog.getActionStatus())) {
throw exception(TASK_CHECK_TASK_STATUS);
if (!znConfigConstant.getIsSimulation()) {
checkTaskDone(actionLog.getTaskDetailId() + "");
}
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
// commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
mqttUtils.pub(PathPlanningTopicConstant.CLEAN_AGV, JSON.toJSONString(build));
Object o = checkTaskDetailExist(actionLog.getTaskDetailId());
@ -1182,16 +1201,20 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
TaskToPathPlanningDTO pathPlanning = JSONUtil.toBean((String) o, TaskToPathPlanningDTO.class);
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
if (lock.tryLock()) {
try {
resendToPP(pathPlanning, actionLog, robotInformationDO);
} finally {
lock.unlock();
}
if (isRobot) {
resendToPP(pathPlanning, actionLog, robotInformationDO);
} else {
log.info("下发任务给路径规划未获取到锁");
throw exception(REDISSON_NOT_OBTAIN_LOCK);
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
if (lock.tryLock()) {
try {
resendToPP(pathPlanning, actionLog, robotInformationDO);
} finally {
lock.unlock();
}
} else {
log.info("下发任务给路径规划未获取到锁");
throw exception(REDISSON_NOT_OBTAIN_LOCK);
}
}
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
@ -1228,18 +1251,17 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
List<TaskRobotNoLimittationAreaDTO> robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO);
pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions);
if (!isSimulation || !restoreTaskRestart) {
resendToPPData(pathPlanning, actionLog, robotInformationDO, false);
}
resendToPPData(pathPlanning, actionLog, robotInformationDO, false);
List<TaskToPathPlanningDTO> pathPlanningList = new ArrayList<>();
pathPlanningList.add(pathPlanning);
String plantingKey = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(plantingKey, JSON.toJSONString(pathPlanning), taskChcheTime);
redisUtil.set(plantingKey, JSON.toJSONString(pathPlanning), znConfigConstant.getTask().getTaskCacheTime());
log.info("任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
// commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
mqttUtils.pub(PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST, JSON.toJSONString(pathPlanningList));
}
private void resendToPPData(TaskToPathPlanningDTO pathPlanning, RobotTaskDetailActionLogDO actionLog, RobotInformationDO robotInformationDO, Boolean isRemote) {
@ -1256,7 +1278,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
} else if (PathTaskTypeEnum.RELEASE.getType().equals(actionLog.getCommandType())) {
releaseTask(pathPlanning);
} else if (PathTaskTypeEnum.MOVE.getType().equals(actionLog.getCommandType())
|| PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(actionLog.getCommandType())) {
|| PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(actionLog.getCommandType())) {
}
}
@ -1267,8 +1289,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
* @param pathPlanning
*/
private void releaseTask(TaskToPathPlanningDTO pathPlanning) {
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
releaseCheck(robotTaskDetail.getToLocationId(), robotTaskDetail.getRobotTaskId());
// RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
// releaseCheck(robotTaskDetail.getToLocationId(), robotTaskDetail.getRobotTaskId());
}
/**
@ -1277,13 +1299,14 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
* @param pathPlanning
*/
private void takeTask(TaskToPathPlanningDTO pathPlanning, Boolean isRemote) {
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
takeCheck(robotTaskDetail.getFromLocationId(), robotTaskDetail.getRobotTaskId(), isRemote);
// RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
// takeCheck(robotTaskDetail.getFromLocationId(), robotTaskDetail.getRobotTaskId(), isRemote);
}
public RobotTaskDetailDO checkTaskDone(String id) {
RobotTaskDetailDO robotTaskDetail = taskDetailMapper.selectById(id);
if (RobotTaskStageEnum.DONE.getType().equals(robotTaskDetail.getTaskStage())) {
if (RobotTaskStageEnum.DONE.getType().equals(robotTaskDetail.getTaskStage())
|| RobotTaskStageEnum.MANUALLY_COMPLETED.getType().equals(robotTaskDetail.getTaskStage()) ) {
throw exception(ROBOT_LAST_TASK_NO_EXISTS);
}
return robotTaskDetail;
@ -1297,31 +1320,54 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
private void takeReleaseTask(TaskToPathPlanningDTO pathPlanning, Boolean isRemote) {
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
if (RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetail.getTaskStage())
|| RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())
|| RobotTaskStageEnum.TAKEING.getType().equals(robotTaskDetail.getTaskStage())) {
return;
}
String robotNo = pathPlanning.getRobotNoLimitationAreaDTOS().get(0).getRobotNo();
String mac = getMacByRobotNo(robotNo);
String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + mac;
Object cargoDetected = redisUtil.get(cargoDetectedKey);
if (ObjectUtil.isNotEmpty(cargoDetected) && RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))) {
//说明取货完成
pathPlanning.setTakeLevel(null);
pathPlanning.setTakeGroupId(null);
pathPlanning.setTakeLocationNumber(null);
pathPlanning.setTakePointId(null);
pathPlanning.setTakeOffsetHeight(null);
pathPlanning.setTakeOffsetHeight(null);
pathPlanning.setTaskType(PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType());
takeDone(pathPlanning, robotTaskDetail);
} else if (RobotTaskStageEnum.GO_RELEASE.getType().equals(robotTaskDetail.getTaskStage())
|| RobotTaskStageEnum.RELEASEING.getType().equals(robotTaskDetail.getTaskStage())) {
takeDone(pathPlanning, robotTaskDetail);
} else if (RobotTaskStageEnum.CLOSE.getType().equals(robotTaskDetail.getTaskStage())
|| RobotTaskStageEnum.EXCEPTION.getType().equals(robotTaskDetail.getTaskStage()) ) {
WareHouseLocationDO wareHouseLocation = wareHouseLocationMapper.selectById(robotTaskDetail.getFromLocationId());
if (wareHouseLocation.getTaskId().equals(robotTaskDetail.getTakeId()) && LocationLockEnum.NO.getType().equals(wareHouseLocation.getLocationLock())) {
wareHouseLocation.setSkuInfo(null);
wareHouseLocation.setSkuNumber(0L);
wareHouseLocation.setLocationLock(LocationLockEnum.YES.getType());
wareHouseLocation.setLocationUseStatus(LocationUseStatusEnum.NO.getType());
wareHouseLocationMapper.updateById(wareHouseLocation);
if (ZeroOneEnum.ZERO.getType().equals(wareHouseLocation.getLocationUseStatus())) {
takeDone(pathPlanning, robotTaskDetail);
}
}else {
}
/*else {
takeCheck(robotTaskDetail.getFromLocationId(), robotTaskDetail.getRobotTaskId(), isRemote);
}
releaseCheck(robotTaskDetail.getToLocationId(), robotTaskDetail.getRobotTaskId());
releaseCheck(robotTaskDetail.getToLocationId(), robotTaskDetail.getRobotTaskId());*/
}
public void takeDone(TaskToPathPlanningDTO pathPlanning, RobotTaskDetailDO robotTaskDetail) {
pathPlanning.setTakeLevel(null);
pathPlanning.setTakeGroupId(null);
pathPlanning.setTakeLocationNumber(null);
pathPlanning.setTakePointId(null);
pathPlanning.setTakeOffsetHeight(null);
pathPlanning.setTakeOffsetHeight(null);
pathPlanning.setTaskType(PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType());
WareHouseLocationDO wareHouseLocation = wareHouseLocationMapper.selectById(robotTaskDetail.getFromLocationId());
if (wareHouseLocation.getTaskId().equals(robotTaskDetail.getTakeId()) && LocationLockEnum.NO.getType().equals(wareHouseLocation.getLocationLock())) {
wareHouseLocation.setSkuInfo(null);
wareHouseLocation.setSkuNumber(0L);
wareHouseLocation.setLocationLock(LocationLockEnum.YES.getType());
wareHouseLocation.setLocationUseStatus(LocationUseStatusEnum.NO.getType());
wareHouseLocationMapper.updateById(wareHouseLocation);
}
}
/**
@ -1401,12 +1447,19 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
throw exception(ROBOT_NOT_FOUND_FREE_CHARGING_STATION);
}
DeviceInformationDO deviceInformationDO = deviceInformations.stream()
.filter(v -> v.getDeviceAttribute().equals(robot.getChargeType())
&& robot.getFloorAreaJson().contains(v.getPositionMapId()))
.findFirst()
.orElse(new DeviceInformationDO());
if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceNo())) {
DeviceInformationDO deviceInformationDO = null;
for (DeviceInformationDO v : deviceInformations) {
if (ObjectUtil.isNotEmpty(v.getLastUser()) && v.getLastUser().equals(robot.getRobotNo())) {
deviceInformationDO = v;
break;
}
if (v.getDeviceAttribute().equals(robot.getChargeType())
&& robot.getFloorAreaJson().contains(v.getPositionMapId()) && DeviceUseStatusEnum.IDLE.getType().equals(v.getDeviceUseStatus())) {
deviceInformationDO = v;
}
}
if (ObjectUtil.isEmpty(deviceInformationDO)) {
log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}", robot.getRobotNo());
throw exception(ROBOT_NOT_FOUND_FREE_CHARGING_STATION);
}
@ -1453,7 +1506,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
|| RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())) {
log.info("清除交管--任务阶段是前往取货/待执行/前往放货 :{}", robotTaskDetail.getRobotNo());
robotTaskDetail.setTaskStatus(RobotTaskDetailStatusEnum.NEW.getType());
robotTaskDetail.setRobotNo(null);
// robotTaskDetail.setRobotNo(null);
taskDetailMapper.updateById(robotTaskDetail);
}
}
@ -1472,7 +1525,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
robotTask.setOrderType(orderType);
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac);
robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType());
commonApi.commonMethod(robotTask, robotTask.getTopic());
// commonApi.commonMethod(robotTask, robotTask.getTopic());
mqttUtils.pub(robotTask.getTopic(), JSON.toJSONString(robotTask));
}
/**
@ -1493,7 +1547,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
List<String> robotNos = robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList());
List<String> list = new ArrayList<>();
String floorArea = floor + CommonConstant.SYMBOL + area;
String floorArea = floor + CommonConstant.SYMBOL + area;
Map<Object, Object> hmget = redisUtil.hmget(floorArea);
if (ObjectUtil.isEmpty(hmget)) {
return new ArrayList<>();
@ -1519,7 +1573,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
public void sendEmergencyStopOrRecoveryToRobot(RobotSimulationPoseDTO robotSimulationPose, List<String> robotNos, String str) {
for (String robotNo : robotNos) {
String mac = getMacByRobotNo(robotNo);
commonApi.commonMethod(robotSimulationPose, RobotTopicConstant.ROBOT_COMMAND_TOPIC + mac);
// commonApi.commonMethod(robotSimulationPose, RobotTopicConstant.ROBOT_COMMAND_TOPIC + mac);
mqttUtils.pub(RobotTopicConstant.ROBOT_COMMAND_TOPIC + mac, JSON.toJSONString(robotSimulationPose));
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction(str + robotNo)
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
@ -1643,7 +1698,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
robotCloseTaskDetail(actionLog.getTaskDetailId() + "", mac, actionLog.getCommandType());
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
// commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
mqttUtils.pub(PathPlanningTopicConstant.CLEAN_AGV, JSON.toJSONString(build));
TaskToPathPlanningDTO pathPlanning = JSONUtil.toBean((String) o, TaskToPathPlanningDTO.class);
@ -1656,12 +1712,13 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
resendToPPData(pathPlanning, actionLog, robotInformationDO, true);
String plantingKey = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(plantingKey, JSON.toJSONString(pathPlanning), taskChcheTime);
redisUtil.set(plantingKey, JSON.toJSONString(pathPlanning), znConfigConstant.getTask().getTaskCacheTime());
List<TaskToPathPlanningDTO> pathPlanningList = new ArrayList<>();
pathPlanningList.add(pathPlanning);
log.info("远遥任务转移, 任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
// commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
mqttUtils.pub(PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST, JSON.toJSONString(pathPlanningList));
}
/**
@ -1692,7 +1749,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
&& !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(fullElectricity);
robotEndElectricity = new BigDecimal(znConfigConstant.getFullElectricity());
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache)
&& ObjectUtil.isNotEmpty(chargeConfig.getChanceChargeEnd())) {
robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd()));

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteExceptionTaskDetailDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteTaskQueryDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotDoingTaskDTO;
@ -35,6 +36,7 @@ import cn.iocoder.yudao.module.system.service.path.PathPlanningService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -82,8 +84,11 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService {
@Resource
private RobotWarnMsgService warnMsgService;
@Resource
private CommonApi commonApi;
/* @Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
private UserOperationLogService userOperationLogService;
@ -224,7 +229,8 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService {
.robotNo(robotTaskDetailDO.getRobotNo())
.id(robotTaskDetailDO.getId().toString())
.build();
commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
// commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
mqttUtils.pub(PathPlanningTopicConstant.KILL_TASK,JSON.toJSONString(closePathPlanting));
}
@Override
@ -246,6 +252,7 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService {
public void setTaskDetailError(Long id) {
RobotTaskDetailDO robotTaskDetailDO = new RobotTaskDetailDO();
robotTaskDetailDO.setId(id);
robotTaskDetailDO.setTaskStatus(RobotTaskStatusEnum.Exc.getType());
robotTaskDetailDO.setOccurError(ZeroOneEnum.ONE.getType());
taskDetailMapper.updateById(robotTaskDetailDO);
}

View File

@ -115,4 +115,11 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
* @param robotNo
*/
void chargeDone(String robotNo);
/**
* 查询车辆的工作总数
* @param robotNo
* @return
*/
Integer getRobotTaskNum(String robotNo);
}

View File

@ -13,6 +13,8 @@ import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.mqtt.api.task.dto.*;
import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum;
import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant;
@ -62,6 +64,7 @@ import cn.iocoder.yudao.module.system.service.information.DeviceInformationServi
import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService;
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import cn.iocoder.yudao.module.system.service.robot.simulation.RobotSimulationService;
import cn.iocoder.yudao.module.system.service.statistics.RobotWorkingHoursStatisticsService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
@ -129,20 +132,8 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Autowired
private RobotInformationService robotInformationService;
@Value("${zn.task-no:ZN}")
private String taskNo;
@Value("${zn.do_cycle:true}")
private Boolean doCycle;
@Value("${zn.task.check_sku_info:true}")
private Boolean checkSkuInfo;
@Value("${zn.robot_config.offset_height}")
private Double offsetHeight;
@Value("${zn.robot_config.default_tray_height:0.82}")
private Double defaultTrayHeight;
@Autowired
private ZnConfigConstant znConfigConstant;
@Resource
private WareHouseLaneMapper houseLaneMapper;
@ -156,8 +147,11 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Resource
private DeviceInformationMapper deviceInformationMapper;
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
private UserOperationLogService userOperationLogService;
@ -165,18 +159,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Resource
private DeviceInformationService deviceInformationService;
@Resource
private RobotTaskDetailActionLogMapper taskDetailActionLogMapper;
@Autowired
private RobotTaskMapper robotTaskMapper;
@Autowired
private RobotTaskDetailMapper robotTaskDetailMapper;
@Value("${zn.move-no:MOVE}")
private String moveTaskNo;
@Resource
private PositionMapItemService positionMapItemService;
@ -186,16 +174,23 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Resource
private RobotWorkingHoursStatisticsService robotWorkingHoursStatisticsService;
@Resource
private RobotSimulationService robotSimulationService;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createTask(RobotTaskSaveReqVO createReqVO) throws InterruptedException {
if (znConfigConstant.getTaskNotCheck()) {
robotSimulationService.createTask(createReqVO);
return 1L;
}
//校验
doTaskCheck(createReqVO);
//设置任务号
if (ObjectUtil.isEmpty(createReqVO.getTaskNo())) {
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.TASK_NO.getKey());
createReqVO.setTaskNo(taskNo + DateUtils.getYearMonthDay() + incrementByKey);
createReqVO.setTaskNo(znConfigConstant.getTaskNo() + DateUtils.getYearMonthDay() + incrementByKey);
}
//获取库位id
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_ADD_LOCK.getKey());
@ -228,7 +223,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
throw exception(TASK_DATA_NOT_FULL);
}
//校验循环任务的配置未开启
if (DoCycleEnum.YES.getType().equals(createReqVO.getDoCycle()) && !doCycle) {
if (DoCycleEnum.YES.getType().equals(createReqVO.getDoCycle()) && !znConfigConstant.getDoCycle()) {
throw exception(TASK_CYCLE_NOT_OPEN);
}
//搬空任务只能选择线库或者区域
@ -352,7 +347,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
List<Long> laneIds = new ArrayList<>();
List<Long> areaIds = new ArrayList<>();
if (ObjectUtil.isNotEmpty(task.getSkuInfo()) && checkSkuInfo) {
if (ObjectUtil.isNotEmpty(task.getSkuInfo()) && znConfigConstant.getTask().getCheckSkuInfo()) {
List<WareHouseLaneDO> wareHouseLaneDOS = houseLaneMapper.selectList(new LambdaQueryWrapper<WareHouseLaneDO>()
.eq(WareHouseLaneDO::getLaneMsg, task.getSkuInfo()));
if (ObjectUtil.isNotEmpty(wareHouseLaneDOS)) {
@ -385,7 +380,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
locationMapper.updateLocationLockList(list, task.getId(), LocationLockEnum.NO.getType());
});
if (doCycle && ObjectUtil.isNotEmpty(createReqVO.getDoCycle())
if (znConfigConstant.getDoCycle() && ObjectUtil.isNotEmpty(createReqVO.getDoCycle())
&& ZeroOneEnum.ONE.getType().equals(createReqVO.getDoCycle().intValue())) {
addCycle(task.getId(), createReqVO.getTaskDetailList());
}
@ -504,7 +499,8 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
.robotNo(taskDetailDO.getRobotNo())
.id(taskDetailDO.getId().toString())
.build();
commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
// commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
mqttUtils.pub(PathPlanningTopicConstant.KILL_TASK, JSON.toJSONString(closePathPlanting));
}
RobotTaskDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDO.class);
@ -512,6 +508,8 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
taskDetailMapper.updateById(taskDetailDOS);
taskCycleMapper.deletByRobotTaskId(robotTaskDO.getId());
if (ObjectUtil.isNotEmpty(locationIds)) {
locationMapper.releaseLocationLockList(locationIds, robotTaskDO.getId()
, LocationLockEnum.YES.getType());
@ -536,13 +534,11 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
robotInformationDO.setRobotTaskModel(RobotTaskModelEnum.REJECTION.getType());
}*/
//因为机器人如果正在抬叉取货这时把任务取消如果货叉刚好伸到托盘底下还是需要人为控制
robotInformationDO.setRobotTaskModel(RobotTaskModelEnum.REJECTION.getType());
// robotInformationDO.setRobotTaskModel(RobotTaskModelEnum.REJECTION.getType());
robotInformationDO.setRobotStatus(RobotStatusEnum.STAND_BY.getType());
}
informationMapper.updateById(robotInformationDOS);
taskCycleMapper.deletByRobotTaskId(robotTaskDO.getId());
}
@Override
@ -552,7 +548,8 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
robotTask.setOrderType(orderType);
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac);
robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType());
commonApi.commonMethod(robotTask, robotTask.getTopic());
// commonApi.commonMethod(robotTask, robotTask.getTopic());
mqttUtils.pub(robotTask.getTopic(), JSON.toJSONString(robotTask));
}
/**
@ -560,6 +557,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
*/
@Override
public void checkHaveDoingTask() {
//暂时注释
if (true) {
return;
}
List<RobotTaskDO> taskDOS = taskMapper.selectList(new LambdaQueryWrapper<RobotTaskDO>()
.in(RobotTaskDO::getTaskStatus, RobotTaskStatusEnum.NEW.getType(), RobotTaskStatusEnum.DOING.getType()));
if (ObjectUtil.isNotEmpty(taskDOS)) {
@ -582,7 +585,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
*/
@Override
public void assignTasks(String message) {
log.info("PP分配任务,开始更新任务状态 :{}", message);
log.info("111111PP路径规划分配任务,开始更新任务状态 :{}", message);
TaskAssignDTO taskAssignDTO = JSON.parseObject(message, TaskAssignDTO.class);
String mac = robotInformationService.getMacByRobotNo(taskAssignDTO.getRobotNo());
@ -649,7 +652,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
private RobotTaskDO ppCreateMove(TaskAssignDTO taskAssignDTO) {
RobotTaskDO task = new RobotTaskDO();
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.MOVE_TASK_NO.getKey());
task.setTaskNo(moveTaskNo + DateUtils.getYearMonthDay() + incrementByKey);
task.setTaskNo(znConfigConstant.getMoveNo() + DateUtils.getYearMonthDay() + incrementByKey);
task.setId(IdUtil.getSnowflakeNextId());
task.setCycleNumber(0L);
task.setRemainingCycleNumber(0L);
@ -664,7 +667,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
taskDetailDO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType());
taskDetailDO.setReleaseId(Long.valueOf(taskAssignDTO.getWaitId()));
taskDetailDO.setToLocationId(Long.valueOf(taskAssignDTO.getWaitId()));
taskDetailDO.setToLocationNo( positionMapItem.getSortNum() + "");
taskDetailDO.setToLocationNo(positionMapItem.getSortNum() + "");
taskDetailDO.setRobotNo(taskAssignDTO.getRobotNo());
taskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
taskDetailDO.setStartTime(LocalDateTime.now());
@ -742,7 +745,8 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
data.add(robotAssignTaskData);
}
log.info("发送任务给车机 :{}", JSON.toJSONString(build));
commonApi.commonMethod(build, build.getTopic());
// commonApi.commonMethod(build, build.getTopic());
mqttUtils.pub(build.getTopic(),JSON.toJSONString(build));
}
public RobotAssignTaskDataDTO getEmptyRobotAssignTaskData() {
@ -765,7 +769,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
location = locationMapper.selectById(v.getFromLocationId());
build = RobotAssignTaskArgDTO.builder()
.level(Double.valueOf(location.getLocationStorey()))
.offsetHeight(offsetHeight)
.offsetHeight(znConfigConstant.getRobotConfig().getOffsetHeight())
.build();
take.setArg(Arrays.asList(build));
} else if (PathTaskTypeEnum.RELEASE.getType().equals(taskAssignDTO.getOrderType())) {
@ -773,7 +777,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
location = locationMapper.selectById(v.getToLocationId());
build = RobotAssignTaskArgDTO.builder()
.level(Double.valueOf(location.getLocationStorey()))
.offsetHeight(offsetHeight)
.offsetHeight(znConfigConstant.getRobotConfig().getOffsetHeight())
.build();
}
@ -790,7 +794,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
private void setRobotAssignTaskArgHeigth(WareHouseLocationDO location, RobotAssignTaskArgDTO build) {
Integer locationStorey = location.getLocationStorey() - 1;
double height = locationStorey * defaultTrayHeight;
double height = locationStorey * znConfigConstant.getRobotConfig().getDefaultTrayHeight();
build.setHeight(height);
}
@ -818,6 +822,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
taskDetailMapper.updateById(taskDetailDO);
RobotTaskDO task = new RobotTaskDO();
task.setId(taskDetailDO.getRobotTaskId());
task.setStartTime(LocalDateTime.now());
task.setTaskStatus(RobotTaskStatusEnum.DOING.getType());
taskMapper.updateById(task);
String taskNo = taskDetailMapper.getTaskNoByDetailId(detailId);
@ -838,7 +843,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
List<RobotTaskDetailAddVO> newTaskDetailList = new ArrayList<>();
List<Long> mapItemIds = new ArrayList<>();
if (doCycle) {
if (znConfigConstant.getDoCycle()) {
List<TaskCycleDO> taskCycleDOS = taskCycleMapper.selectList(new LambdaQueryWrapper<TaskCycleDO>());
if (ObjectUtil.isNotEmpty(taskCycleDOS)) {
mapItemIds = taskCycleDOS.stream().map(TaskCycleDO::getMapItemId).collect(Collectors.toList());
@ -1008,7 +1013,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
releaseMapItemIds = new ArrayList<>();
}
if (doCycle) {
if (znConfigConstant.getDoCycle()) {
List<TaskCycleDO> taskCycleDOS = taskCycleMapper.selectList(new LambdaQueryWrapper<TaskCycleDO>());
if (ObjectUtil.isNotEmpty(taskCycleDOS)) {
List<Long> mapItemIds =
@ -1482,7 +1487,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Override
public String getTaskNo() {
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.TASK_NO.getKey());
return taskNo + DateUtils.getYearMonthDay() + incrementByKey;
return znConfigConstant.getTaskNo() + DateUtils.getYearMonthDay() + incrementByKey;
}
/**
@ -1622,6 +1627,15 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
}
@Override
public Integer getRobotTaskNum(String robotNo) {
List<RobotTaskDetailDO> taskDetailDOS = taskDetailMapper.selectList(new LambdaQueryWrapperX<RobotTaskDetailDO>()
.eq(RobotTaskDetailDO::getRobotNo, robotNo)
.ne(RobotTaskDetailDO::getTaskStatus, RobotTaskStatusEnum.NEW.getType()));
return ObjectUtil.isEmpty(taskDetailDOS) ? 0 : taskDetailDOS.size();
}
/**
* 任务日志分页
*

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.service.robot.camera;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraRespVO;
@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.system.util.aes.AESEncryptionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -45,8 +47,8 @@ public class RobotCameraServiceImpl extends ServiceImpl<RobotCameraMapper, Robot
@Resource
private RobotCameraMapper cameraMapper;
@Value("${zn.camera_secret_key}")
private String cameraSecretKey;
@Autowired
private ZnConfigConstant znConfigConstant;
@Override
public Long createCamera(RobotCameraSaveReqVO createReqVO) {
@ -131,14 +133,14 @@ public class RobotCameraServiceImpl extends ServiceImpl<RobotCameraMapper, Robot
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));
robotCameraDO.setCameraAccount(AESEncryptionUtil.encrypt(robotCameraDO.getCameraAccount(), znConfigConstant.getCameraSecretKey()));
robotCameraDO.setCameraPassword(AESEncryptionUtil.encrypt(robotCameraDO.getCameraPassword(), znConfigConstant.getCameraSecretKey()));
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
robotCameraDO.setCameraAccount(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraAccount(),cameraSecretKey));
robotCameraDO.setCameraPassword(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraPassword(),cameraSecretKey));
robotCameraDO.setCameraAccount(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraAccount(),znConfigConstant.getCameraSecretKey()));
robotCameraDO.setCameraPassword(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraPassword(),znConfigConstant.getCameraSecretKey()));
}
}

View File

@ -8,6 +8,7 @@ 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.websocket.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO;
@ -74,11 +75,8 @@ public class AutoChargeServiceImpl implements AutoChargeService {
@Resource
private RedisUtil redisUtil;
@Value("${zn.full_electricity:100}")
private String fullElectricity;
@Value("${zn.charge-no:CHARGE}")
private String chargeNo;
@Autowired
private ZnConfigConstant znConfigConstant;
@Autowired
private RobotPathPlanningService robotPathPlanningService;
@ -307,7 +305,7 @@ public class AutoChargeServiceImpl implements AutoChargeService {
&& !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(fullElectricity);
robotEndElectricity = new BigDecimal(znConfigConstant.getFullElectricity());
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache)
&& ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())) {
robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd()));
@ -386,7 +384,7 @@ public class AutoChargeServiceImpl implements AutoChargeService {
logDo.setStartElectricity(electricity);
//配置的充满电电量
BigDecimal robotFullElectricity = new BigDecimal(fullElectricity);
BigDecimal robotFullElectricity = new BigDecimal(znConfigConstant.getFullElectricity());
//车子剩余电量
BigDecimal robotRemainingElectricity = new BigDecimal(electricity + "");
if (ObjectUtil.isNotEmpty(chargeConfig.getChanceCycle()) && !chargeFullNos.contains(robot.getRobotNo())
@ -502,7 +500,7 @@ public class AutoChargeServiceImpl implements AutoChargeService {
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.setTaskNo(znConfigConstant.getChargeNo() + DateUtils.getYearMonthDay() + incrementByKey);
task.setId(IdUtil.getSnowflakeNextId());
task.setCycleNumber(0L);
task.setRemainingCycleNumber(0L);

View File

@ -4,9 +4,11 @@ import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO;
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.cycle.TaskCycleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
@ -20,6 +22,7 @@ import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -45,11 +48,8 @@ public class CycleServiceImpl implements CycleService {
@Resource
private RobotTaskDetailMapper taskDetailMapper;
@Value("${zn.do_cycle:true}")
private Boolean doCycle;
@Value("${zn.task-no:ZN}")
private String taskNo;
@Autowired
private ZnConfigConstant znConfigConstant;
@Resource
private RedisUtil redisUtil;
@ -59,6 +59,9 @@ public class CycleServiceImpl implements CycleService {
@Resource
private RobotTaskService robotTaskService;
@Resource
private TaskCycleMapper taskCycleMapper;
/**
* 创建循环任务
*/
@ -66,7 +69,7 @@ public class CycleServiceImpl implements CycleService {
public void cycleTaskJob() {
TenantContextHolder.setTenantId(1L);
if (!doCycle) {
if (!znConfigConstant.getDoCycle()) {
log.info("循环任务关闭了--不自动创建循环任务");
}
@ -86,11 +89,12 @@ public class CycleServiceImpl implements CycleService {
Map<Long, List<RobotTaskDetailDO>> taskIdMap =
detailDOS.stream().collect(Collectors.groupingBy(RobotTaskDetailDO::getRobotTaskId));
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.TASK_NO.getKey());
List<RobotTaskDO> taskDOList = new ArrayList<>();
List<RobotTaskDetailDO> taskDetailList = new LinkedList<>();
for (RobotTaskDO v : taskList) {
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.TASK_NO.getKey());
RobotTaskDO taskData = getTaskData(incrementByKey, v);
List<RobotTaskDetailDO> taskDetailDOS = getTaskDetailData(taskData,taskIdMap,v.getId());
taskDOList.add(taskData);
@ -98,10 +102,21 @@ public class CycleServiceImpl implements CycleService {
v.setRemainingCycleNumber(0l);
}
taskMapper.insertBatch(taskDOList);
taskMapper.insert(taskDOList);
taskMapper.updateById(taskList);
Collections.reverse(taskDetailList);
taskDetailMapper.insertBatch(taskDetailList);
List<RobotTaskDetailDO> moves = taskDetailList.stream().filter(v -> RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(v.getTaskType())).collect(Collectors.toList());
List<RobotTaskDetailDO> takes = taskDetailList.stream().filter(v -> !RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(v.getTaskType())).collect(Collectors.toList());
List<RobotTaskDetailDO> taskDetails= new LinkedList<>();
if (ObjectUtil.isNotEmpty(moves)) {
taskDetails.addAll(moves);
}
if (ObjectUtil.isNotEmpty(takes)) {
Collections.reverse(takes);
taskDetails.addAll(takes);
}
taskDetailMapper.insert(taskDetails);
List<Long> fromLocationIds = taskDetailList.stream().map(RobotTaskDetailDO::getFromLocationId).collect(Collectors.toList());
List<Long> toLocationIds = taskDetailList.stream().map(RobotTaskDetailDO::getToLocationId).collect(Collectors.toList());
@ -114,12 +129,13 @@ public class CycleServiceImpl implements CycleService {
locationMapper.updateLocationLockList(list, -1l, LocationLockEnum.NO.getType());
});
List<RobotTaskDetailAddVO> bean = BeanUtils.toBean(taskDetailList, RobotTaskDetailAddVO.class);
List<RobotTaskDetailAddVO> bean = BeanUtils.toBean(taskDetails, RobotTaskDetailAddVO.class);
Map<Long, List<RobotTaskDetailAddVO>> taskDetailMap =
bean.stream().collect(Collectors.groupingBy(RobotTaskDetailAddVO::getRobotTaskId));
taskDetailMap.forEach((k,v) ->{
robotTaskService.addCycle(k,v);
});
taskCycleMapper.deletByRobotTaskIds(taskIds);
}
private List<RobotTaskDetailDO> getTaskDetailData(RobotTaskDO taskData, Map<Long,
@ -178,7 +194,7 @@ public class CycleServiceImpl implements CycleService {
* @return
*/
public RobotTaskDO getTaskData(String incrementByKey, RobotTaskDO v ) {
String taskNoStr = taskNo + DateUtils.getYearMonthDay() + incrementByKey;
String taskNoStr = znConfigConstant.getTaskNo() + DateUtils.getYearMonthDay() + incrementByKey;
RobotTaskDO task = new RobotTaskDO();
BeanUtils.copyProperties(v, task);
task.setRemainingCycleNumber(v.getRemainingCycleNumber() - 1);

View File

@ -5,6 +5,7 @@ import cn.hutool.json.JSONUtil;
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.websocket.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO;
@ -54,9 +55,6 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
@Autowired
private RobotTaskDetailMapper robotTaskDetailMapper;
@Value("${zn.full_electricity:95}")
private String fullElectricity;
@Resource
private CommonConfigMapper configMapper;
@ -66,6 +64,9 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
@Resource
private RemoteControllerInformationMapper controllerInformationMapper;
@Autowired
private ZnConfigConstant znConfigConstant;
/**
* 获取待执行的机器人和任务
@ -92,7 +93,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
.in(RobotInformationDO::getRobotStatus, RobotStatusEnum.STAND_BY.getType(), RobotStatusEnum.CHARGE.getType())
.eq(RobotInformationDO::getRobotTaskModel, RobotTaskModelEnum.NORMAL.getType()));
if (robots.isEmpty()) {
if (ObjectUtil.isEmpty(robots)) {
log.info("暂无空闲的机器人");
return pair;
}
@ -258,7 +259,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
&& !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(fullElectricity);
robotEndElectricity = new BigDecimal(znConfigConstant.getFullElectricity());
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache)
&& ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())) {
robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd()));

View File

@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskAutoMovePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskAutoMoveSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
@ -60,12 +61,8 @@ public class RobotTaskAutoMoveServiceImpl implements RobotTaskAutoMoveService {
@Resource
private WareHouseLocationMapper locationMapper;
@Value("${zn.lane_auto_move:true}")
private Boolean laneAutoMove;
@Value("${zn.cycle_do_auto_move:true}")
private Boolean cycleDoAutoMove;
@Autowired
private ZnConfigConstant znConfigConstant;
@Override
public Long createTaskAutoMove(RobotTaskAutoMoveSaveReqVO createReqVO) {
@ -311,7 +308,7 @@ public class RobotTaskAutoMoveServiceImpl implements RobotTaskAutoMoveService {
*/
public List<Pair<RobotTaskDetailDO, List<WareHouseLocationDO>>> getLaneAutoMoveLocation(List<RobotTaskDetailDO> taskDetailDOS) {
List<Pair<RobotTaskDetailDO, List<WareHouseLocationDO>>> result = new ArrayList<>();
if (ObjectUtil.isEmpty(taskDetailDOS) || !laneAutoMove) {
if (ObjectUtil.isEmpty(taskDetailDOS) || !znConfigConstant.getLaneAutoMove()) {
log.info("没有线库的任务明细, 不需要执行线库移库");
return result;
}

View File

@ -10,6 +10,8 @@ import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskLimitationAreaDTO;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant;
@ -68,12 +70,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Resource
private PositionMapItemMapper positionMapItemMapper;
@Value("${zn.task_need_single:true}")
private Boolean taskNeedSingle;
@Value("${zn.location_number_reduce:100000000}")
private Long locationNumberReduce;
@Resource
private WareHouseLocationMapper locationMapper;
@ -86,29 +82,17 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Resource
private PositionMapMapper positionMapMapper;
@Value("${zn.robot_chearg.release_location_number_config:50}")
private Long releaseLocationNumberConfig;
@Value("${zn.robot_chearg.priority_config:50}")
private Long priorityConfig;
@Value("${zn.robot_config.offset_height}")
private Double offsetHeight;
@Value("${zn.path_planning.task_chche_time:604800}")
private Long taskChcheTime;
@Value("${zn.move-no:MOVE}")
private String moveTaskNo;
@Value("${zn.robot_config.default_tray_height:0.82}")
private Double defaultTrayHeight;
@Autowired
private ZnConfigConstant znConfigConstant;
@Autowired
private RobotTaskMapper robotTaskMapper;
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
@Lazy
@ -137,7 +121,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
List<RobotTaskDetailDO> taskDetailDOS = robotAndTaskDetails.getRight();
if (ObjectUtil.isEmpty(taskDetailDOS)) {
log.info("--不存在需要执行的任务--派车辆去等待点");
moveRobotToWait(robots);
// moveRobotToWait(robots);
return;
}
@ -148,7 +132,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
return;
}
log.info("-------查找到车子和任务------");
log.info("-------可以分配任务的车辆编号------ ,:{}",JSON.toJSONString(robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList())));
log.info("-------需要执行的任务id------ ,:{}",JSON.toJSONString(taskDetailDOS.stream().map(RobotTaskDetailDO::getId).collect(Collectors.toList())));
distributeTasksToPP(robots, taskDetailDOS);
}
@ -205,6 +190,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
return;
}
Map<Long, Long> sortMap = positionMapItems.stream().collect(Collectors.toMap(PositionMapItemDO::getId, PositionMapItemDO::getSortNum));
List<String> inStopPointRobotNos = new ArrayList<>();
for (PositionMapItemDO positionMapItem : positionMapItems) {
if (UseStatusEnum.USEING.getType().equals(positionMapItem.getUseStatus()) && ObjectUtil.isNotEmpty(positionMapItem.getRobotNo())) {
@ -285,8 +272,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
return;
}
Map<Long, Long> sortMap = positionMapItems.stream().collect(Collectors.toMap(PositionMapItemDO::getId, PositionMapItemDO::getSortNum));
//机器人不能行走的区域
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationArea = getRobotNoLimitationArea(robots);
Map<String, TaskRobotNoLimittationAreaDTO> robotNoLimittationAreaDTOMap =
@ -301,7 +286,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
RobotTaskDO task = new RobotTaskDO();
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.MOVE_TASK_NO.getKey());
task.setTaskNo(moveTaskNo + DateUtils.getYearMonthDay() + incrementByKey);
task.setTaskNo(znConfigConstant.getMoveNo() + DateUtils.getYearMonthDay() + incrementByKey);
task.setId(IdUtil.getSnowflakeNextId());
task.setCycleNumber(0L);
task.setRemainingCycleNumber(0L);
@ -332,7 +317,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions);
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
redisUtil.set(key, JSON.toJSONString(pathPlanning), znConfigConstant.getTask().getTaskCacheTime());
pathPlanningList.add(pathPlanning);
}
@ -344,7 +329,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
positionMapItemMapper.updateById(robotMapItems);
log.info("派车去停车点--任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
// commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
mqttUtils.pub(PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST,JSON.toJSONString(pathPlanningList));
}
@ -369,7 +355,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
for (RobotChargeLogDO v : logs) {
Long priority = priorityConfig;
Long priority = znConfigConstant.getRobotCharge().getPriorityConfig();
LocalDateTime createTime = LocalDateTime.now();
if (ObjectUtil.isEmpty(ChargeModelEnum.TASK.getType().equals(v.getChargeModel()))
&& ObjectUtil.isNotEmpty(v.getTaskDetailId())
@ -396,17 +382,18 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanning.setTaskType(taskType);
pathPlanning.setReleaseGroupId("POINT_" + v.getPositionMapItemId());
pathPlanning.setReleaseLocationNumber(releaseLocationNumberConfig);
pathPlanning.setReleaseLocationNumber(znConfigConstant.getRobotCharge().getReleaseLocationNumberConfig());
pathPlanning.setWaitIds(Collections.singletonList(v.getPositionMapItemId() + ""));
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
redisUtil.set(key, JSON.toJSONString(pathPlanning), znConfigConstant.getTask().getTaskCacheTime());
pathPlanningList.add(pathPlanning);
}
log.info("充电任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
// commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
mqttUtils.pub(PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST,JSON.toJSONString(pathPlanningList));
}
@Transactional(rollbackFor = Exception.class)
@ -484,20 +471,21 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + mac;
Object cargoDetected = redisUtil.get(cargoDetectedKey);
log.info("传感器是否按下 :{}", cargoDetected);
if (ObjectUtil.isEmpty(cargoDetected) || (RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))
/* if (ObjectUtil.isNotEmpty(cargoDetected) && (RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))
&& !RobotTaskTypeEnum.RELEASE.getType().equals(taskDetailDO.getTaskType()))) {
log.info("车机上报传感器为空, 或者 被按下且任务非仅放货任务 :{} ,任务id {}", taskDetailDO.getRobotNo(), taskDetailDO.getId());
continue;
} else if (!RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))
} else if (ObjectUtil.isNotEmpty(cargoDetected) && !RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))
&& RobotTaskTypeEnum.RELEASE.getType().equals(taskDetailDO.getTaskType())) {
log.info("仅放货任务,传感器未被按下,所以不执行任务 :{}, 任务id {}", taskDetailDO.getRobotNo(), taskDetailDO.getId());
continue;
}
}*/
List<TaskRobotNoLimittationAreaDTO> robotNoLimitions = null;
if (ObjectUtil.isEmpty(taskDetailDO.getRobotNo())) {
robotNoLimitions = robotNoLimitationArea;
} else {
log.info("区域 :{}",JSON.toJSONString(robotDoReleaseMap));
TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO = robotDoReleaseMap.get(taskDetailDO.getRobotNo());
if (ObjectUtil.isEmpty(taskRobotNoLimittationAreaDTO)) {
log.info("车辆没有能行走的区域 :{}", taskDetailDO.getRobotNo());
@ -516,12 +504,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
WareHouseLocationDO toLocation = locationDOMap.get(taskDetailDO.getToLocationId());
if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLocationId())) {
pathPlanning.setTakeLocationNumber(Math.abs(locationNumberReduce - taskDetailDO.getFromLocationNumber()));
pathPlanning.setTakeLocationNumber(Math.abs(znConfigConstant.getLocationNumberReduce() - taskDetailDO.getFromLocationNumber()));
pathPlanning.setTakePointId(fromLocation.getMapItemId());
pathPlanningSetTakeHeight(pathPlanning, fromLocation);
pathPlanning.setTakeLevel(fromLocation.getLocationStorey());
pathPlanning.setTakeOffsetHeight(offsetHeight);
pathPlanning.setTakeOffsetHeight(znConfigConstant.getRobotConfig().getOffsetHeight());
if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) {
pathPlanning.setTakeGroupId("LINE_" + taskDetailDO.getFromLaneId());
} else {
@ -535,7 +523,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanningSetReleaseHeight(pathPlanning, toLocation);
pathPlanning.setReleaseLevel(toLocation.getLocationStorey());
pathPlanning.setReleaseOffsetHeight(offsetHeight);
pathPlanning.setReleaseOffsetHeight(znConfigConstant.getRobotConfig().getOffsetHeight());
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) {
pathPlanning.setReleaseGroupId("LINE_" + taskDetailDO.getToLaneId());
} else {
@ -544,14 +532,15 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
redisUtil.set(key, JSON.toJSONString(pathPlanning), znConfigConstant.getTask().getTaskCacheTime());
pathPlanningList.add(pathPlanning);
}
if (ObjectUtil.isNotEmpty(pathPlanningList)) {
log.info("作业任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
log.info("111111作业任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
// commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
mqttUtils.pub(PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST,JSON.toJSONString(pathPlanningList));
}
}
@ -567,18 +556,18 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
return;
}
WareHouseLocationDO nextLocation = locationMapper.selectOne(new LambdaQueryWrapperX<WareHouseLocationDO>()
/*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());
double height = locationStorey * znConfigConstant.getRobotConfig().getDefaultTrayHeight();
log.info("放货设置默认高度 :{}", height);
pathPlanning.setReleaseHeight(height);
}
@ -589,12 +578,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
* @param fromLocation
*/
private void pathPlanningSetTakeHeight(TaskToPathPlanningDTO pathPlanning, WareHouseLocationDO fromLocation) {
if (ObjectUtil.isNotEmpty(fromLocation.getLocationTotalHeight())) {
/*if (ObjectUtil.isNotEmpty(fromLocation.getLocationTotalHeight())) {
pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTotalHeight() + ""));
return;
}
}*/
Integer locationStorey = fromLocation.getLocationStorey();
double height = locationStorey * defaultTrayHeight;
double height = locationStorey * znConfigConstant.getRobotConfig().getDefaultTrayHeight();
log.info("取货设置默认取货高度 :{}", height);
pathPlanning.setTakeHeight(height);
}
@ -699,7 +688,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
*/
private List<RobotTaskDetailDO> getSingleTask(List<RobotTaskDetailDO> taskDetailDOS) {
//剔除目前正在做的线库和点位
if (!taskNeedSingle) {
if (!znConfigConstant.getTaskNeedSingle()) {
return taskDetailDOS;
}

View File

@ -0,0 +1,8 @@
package cn.iocoder.yudao.module.system.service.robot.simulation;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
public interface RobotSimulationService {
void createTask(RobotTaskSaveReqVO createReqVO);
}

View File

@ -0,0 +1,504 @@
package cn.iocoder.yudao.module.system.service.robot.simulation;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.cycle.TaskCycleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
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.cycle.TaskCycleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.housearea.HouseAreaMapper;
import cn.iocoder.yudao.module.system.dal.mysql.houselane.WareHouseLaneMapper;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.log.RobotTaskDetailActionLogMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotChargeLogMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
import cn.iocoder.yudao.module.system.enums.robot.LocationEnableEnum;
import cn.iocoder.yudao.module.system.enums.robot.LocationLockEnum;
import cn.iocoder.yudao.module.system.enums.robot.LocationUseStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.MoveAllEnum;
import cn.iocoder.yudao.module.system.enums.robot.ReleaseTakeEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskTypeEnum;
import cn.iocoder.yudao.module.system.service.information.DeviceInformationService;
import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService;
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
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.statistics.RobotWorkingHoursStatisticsService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_CREATE_FAIL;
@Slf4j
@Service
@Validated
public class RobotSimulationServiceImpl implements RobotSimulationService{
@Resource
private RobotTaskMapper taskMapper;
@Resource
private WareHouseLocationMapper locationMapper;
@Resource
private RedisUtil redisUtil;
@Resource
private RobotTaskDetailMapper taskDetailMapper;
@Resource
private RobotTaskDetailService robotTaskDetailService;
@Resource
private RobotInformationMapper informationMapper;
@Resource
private WareHouseLaneMapper houseLaneMapper;
@Resource
private HouseAreaMapper houseAreaMapper;
@Resource
private PositionMapItemService positionMapItemService;
@Autowired
private ZnConfigConstant znConfigConstant;
@Override
public void createTask(RobotTaskSaveReqVO createReqVO) {
//设置任务号
if (ObjectUtil.isEmpty(createReqVO.getTaskNo())) {
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.TASK_NO.getKey());
createReqVO.setTaskNo(znConfigConstant.getTaskNo() + DateUtils.getYearMonthDay() + incrementByKey);
}
log.info("111111创建一个不校验的任务 :{}",createReqVO.getTaskNo());
RobotTaskDO task = BeanUtils.toBean(createReqVO, RobotTaskDO.class);
task.setRemainingCycleNumber(task.getCycleNumber());
taskMapper.insert(task);
List<Long> laneIds = new ArrayList<>();
List<Long> areaIds = new ArrayList<>();
if (ObjectUtil.isNotEmpty(task.getSkuInfo()) && znConfigConstant.getTask().getCheckSkuInfo()) {
List<WareHouseLaneDO> wareHouseLaneDOS = houseLaneMapper.selectList(new LambdaQueryWrapper<WareHouseLaneDO>()
.eq(WareHouseLaneDO::getLaneMsg, task.getSkuInfo()));
if (ObjectUtil.isNotEmpty(wareHouseLaneDOS)) {
laneIds = wareHouseLaneDOS.stream().map(WareHouseLaneDO::getId).collect(Collectors.toList());
}
List<HouseAreaDO> houseAreaDOS = houseAreaMapper.selectList(new LambdaQueryWrapper<HouseAreaDO>()
.eq(HouseAreaDO::getSkuInfo, task.getSkuInfo()));
if (ObjectUtil.isNotEmpty(houseAreaDOS)) {
areaIds = houseAreaDOS.stream().map(HouseAreaDO::getId).collect(Collectors.toList());
}
}
//查找库位
List<Long> locationIds = new ArrayList<>();
if (MoveAllEnum.NO.getType().equals(createReqVO.getDoMoveAll())) {
locationIds = setSingleLocationIdNo(createReqVO.getTaskDetailList(), task, laneIds, areaIds);
} else {
locationIds = setAllLocationIdNo(createReqVO, task.getId(), laneIds, areaIds, task.getSkuInfo());
}
// 插入
createReqVO.getTaskDetailList()
.forEach(taskDetail -> {
taskDetail.setRobotTaskId(task.getId());
});
robotTaskDetailService.insertRobotDetailList(createReqVO.getTaskDetailList());
List<List<Long>> fromPartition = Lists.partition(locationIds, 100);
fromPartition.forEach(list -> {
locationMapper.updateLocationLockList(list, task.getId(), LocationLockEnum.NO.getType());
});
}
@Transactional(rollbackFor = Exception.class)
public List<Long> setSingleLocationIdNo(List<RobotTaskDetailAddVO> taskDetailList, RobotTaskDO task,
List<Long> laneIds, List<Long> areaIds) {
//取货中的map_item_id 此集合不能执行放货的任务
List<Long> takeMapItemIds = taskDetailMapper.selectTakeMapItemIds();
if (ObjectUtil.isEmpty(takeMapItemIds)) {
takeMapItemIds = new ArrayList<>();
}
//放货中的map_item_id 此集合不能执行取货的任务
List<Long> releaseMapItemIds = taskDetailMapper.selectReleaseMapItemIds();
if (ObjectUtil.isEmpty(releaseMapItemIds)) {
releaseMapItemIds = new ArrayList<>();
}
List<Long> locationIds = new ArrayList<>();
Set<Long> chooseLocationIds = new HashSet<>();
for (RobotTaskDetailAddVO robotTaskVo : taskDetailList) {
robotTaskVo.setRobotTaskId(task.getId());
robotTaskVo.setPriority(task.getPriority());
RobotTaskTypeEnum robotTaskType = RobotTaskTypeEnum.getRobotTaskType(robotTaskVo.getTaskType());
switch (robotTaskType) {
case TAKE_RELEASE:
doTakeRelease(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds, laneIds, areaIds, task.getSkuInfo(), chooseLocationIds);
break;
case PARK:
doPark(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds);
break;
case CHARGE:
doCharge(robotTaskVo, takeMapItemIds, releaseMapItemIds);
break;
case MOVE:
doMove(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds);
break;
case TAKE:
doTake(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds, chooseLocationIds);
break;
case RELEASE:
doRelease(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds, laneIds, areaIds, task.getSkuInfo(), chooseLocationIds);
break;
case SCAN:
//暂无此功能
doScan(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds);
break;
case DETECTING_TRAYS:
//暂无此功能
doDetectingTrays(robotTaskVo, locationIds, takeMapItemIds, releaseMapItemIds);
break;
case MOVE_TO_POINT:
doMoveToPoint(robotTaskVo);
break;
default:
log.error("任务类型不存在 ");
throw exception0(TASK_CREATE_FAIL.getCode(), "任务类型不存在");
}
}
return locationIds;
}
public void doTakeRelease(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds,
List<Long> takeMapItemIds, List<Long> releaseMapItemIds,
List<Long> laneIds, List<Long> areaIds, String skuInfo, Set<Long> chooseLocationIds) {
//校验放货库位
setToLocation(robotTaskVo, null, locationIds, takeMapItemIds, releaseMapItemIds, laneIds, areaIds, skuInfo, chooseLocationIds);
locationIds.add(robotTaskVo.getToLocationId());
//校验取货库位
setFromLocation(robotTaskVo, null, locationIds, takeMapItemIds, releaseMapItemIds, chooseLocationIds);
locationIds.add(robotTaskVo.getFromLocationId());
//验证取货库位是否存在未完成的任务
Set<Long> set = new HashSet<>();
set.add(robotTaskVo.getFromLocationId());
}
/**
* 移动到指定点位
*
* @param robotTaskVo
*/
private void doMoveToPoint(RobotTaskDetailAddVO robotTaskVo) {
PositionMapItemDO positionMapItem = positionMapItemService.getPositionMapItem(robotTaskVo.getReleaseId());
robotTaskVo.setToLocationNo(String.valueOf(positionMapItem.getSortNum()));
}
/**
* 检测托盘类型
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doDetectingTrays(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds) {
/*setToLocation(robotTaskVo,getMapIdsByRobotNo(robotTaskVo.getRobotNo()),new ArrayList<>());
locationIds.add(robotTaskVo.getToLocationId());*/
}
/**
* 扫描码
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doScan(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds) {
/*setToLocation(robotTaskVo,getMapIdsByRobotNo(robotTaskVo.getRobotNo()),new ArrayList<>());
locationIds.add(robotTaskVo.getToLocationId());*/
}
/**
* 仅放货
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doRelease(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds, List<Long> laneIds, List<Long> areaIds, String skuInfo,
Set<Long> chooseLocationIds) {
setToLocation(robotTaskVo, null, locationIds, takeMapItemIds,
releaseMapItemIds, laneIds, areaIds, skuInfo, chooseLocationIds);
locationIds.add(robotTaskVo.getToLocationId());
}
public void setFromLocation(RobotTaskDetailAddVO robotTaskVo, Set<Long> mapIds, List<Long> locationIds,
List<Long> takeMapItemIds, List<Long> releaseMapItemIds, Set<Long> chooseLocationIds) {
if (ReleaseTakeEnum.TO_LOCATION.getType().equals(robotTaskVo.getTakeType())) {
WareHouseLocationDO query = WareHouseLocationDO.builder().id(robotTaskVo.getTakeId()).build();
WareHouseLocationDO locationDO = locationMapper.queryAllByLimit(query);
robotTaskVo.setFromLocationNo(locationDO.getLocationNo());
robotTaskVo.setFromLocationId(robotTaskVo.getTakeId());
robotTaskVo.setFromLocationStorey(locationDO.getLocationStorey());
robotTaskVo.setFromLaneId(locationDO.getLaneId());
robotTaskVo.setFromLocationNumber(locationDO.getLocationNumber());
robotTaskVo.setFromMapItemId(locationDO.getMapItemId());
takeMapItemIds.add(locationDO.getMapItemId());
} else {
WareHouseLocationDO wareHouseLocationDO =
locationMapper.selectByTypeAndId(LocationUseStatusEnum.YES.getType(), robotTaskVo.getTakeType(),
robotTaskVo.getTakeId(), locationIds, null, releaseMapItemIds, new ArrayList<>(), new ArrayList<>());
robotTaskVo.setFromLocationNo(wareHouseLocationDO.getLocationNo());
robotTaskVo.setFromLocationId(wareHouseLocationDO.getId());
robotTaskVo.setFromLocationStorey(wareHouseLocationDO.getLocationStorey());
robotTaskVo.setFromLaneId(wareHouseLocationDO.getLaneId());
robotTaskVo.setFromLocationNumber(wareHouseLocationDO.getLocationNumber());
robotTaskVo.setFromMapItemId(wareHouseLocationDO.getMapItemId());
takeMapItemIds.add(wareHouseLocationDO.getMapItemId());
}
}
/**
* 仅取货
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doTake(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds, Set<Long> chooseLocationIds) {
setFromLocation(robotTaskVo, null, locationIds, takeMapItemIds, releaseMapItemIds, chooseLocationIds);
locationIds.add(robotTaskVo.getFromLocationId());
}
public Set<Long> getMapIdsByRobotNo(String robotNo) {
if (ObjectUtil.isNotEmpty(robotNo)) {
RobotInformationPageReqVO pageReqVO = new RobotInformationPageReqVO();
pageReqVO.setRobotNo(robotNo);
return informationMapper.selectPage(pageReqVO).getList()
.stream()
.findFirst()
.map(RobotInformationDO::getFloorAreaJson)
.orElse(new HashSet<>());
}
return new HashSet<>();
}
/**
* 移动
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doMove(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds) {
setToLocation(robotTaskVo, null, locationIds, takeMapItemIds, releaseMapItemIds,
null, null, null, null);
locationIds.add(robotTaskVo.getToLocationId());
}
/**
* 充电
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doCharge(RobotTaskDetailAddVO robotTaskVo, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds) {
}
/**
* 停车
*
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doPark(RobotTaskDetailAddVO robotTaskVo, List<Long> locationIds, List<Long> takeMapItemIds,
List<Long> releaseMapItemIds) {
// todo 停车后续停到等待点
/*setToLocation(robotTaskVo,getMapIdsByRobotNo(robotTaskVo.getRobotNo()),locationIds);
locationIds.add(robotTaskVo.getToLocationId());*/
}
/**
* 设置放货和取货的id
*
* @param createReqVO
* @param taskId
*/
@Transactional(rollbackFor = Exception.class)
public List<Long> setAllLocationIdNo(RobotTaskSaveReqVO createReqVO, Long taskId,
List<Long> laneIds, List<Long> areaIds, String skuInfo) {
List<RobotTaskDetailAddVO> taskDetailList = createReqVO.getTaskDetailList();
List<RobotTaskDetailAddVO> newTaskDetailList = new ArrayList<>();
List<Long> mapItemIds = new ArrayList<>();
//被此次任务锁定的空库位id
List<Long> toLocationIds = new ArrayList<>();
//被此次任务锁定的有货库位id
List<Long> fromLocationIds = new ArrayList<>();
for (RobotTaskDetailAddVO robotTaskVo : taskDetailList) {
Set<Long> mapIds = new HashSet<>();
//查找有货且非锁定的库位
WareHouseLocationDO query = null;
if (ReleaseTakeEnum.TO_LANE.getType().equals(robotTaskVo.getTakeType())) {
query = WareHouseLocationDO.builder()
.laneId(robotTaskVo.getTakeId())
.build();
} else if (ReleaseTakeEnum.TO_AREA.getType().equals(robotTaskVo.getTakeType())) {
query = WareHouseLocationDO.builder()
.areaId(robotTaskVo.getTakeId())
.build();
}
List<WareHouseLocationDO> stockList = locationMapper.selectLocations(query, toLocationIds, mapIds,
new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
if (ObjectUtil.isEmpty(stockList)) {
log.error("取货线库/区域为空或者已锁定或者机器人取放货区域受限制 :{}", robotTaskVo.toString());
throw exception0(TASK_CREATE_FAIL.getCode(), "取货线库/区域为空或者已锁定或者机器人取放货区域受限制");
}
//查找空库位
WareHouseLocationDO releaseQuery = null;
if (ReleaseTakeEnum.TO_LANE.getType().equals(robotTaskVo.getReleaseType())) {
releaseQuery = WareHouseLocationDO.builder()
.laneId(robotTaskVo.getReleaseId())
.build();
} else if (ReleaseTakeEnum.TO_AREA.getType().equals(robotTaskVo.getReleaseType())) {
releaseQuery = WareHouseLocationDO.builder()
.areaId(robotTaskVo.getReleaseId())
.build();
}
List<WareHouseLocationDO> releaseStockList = locationMapper.selectLocations(releaseQuery, toLocationIds, mapIds,
laneIds, areaIds, mapItemIds);
if (ObjectUtil.isEmpty(releaseStockList) || releaseStockList.size() < stockList.size()) {
log.error("放货线库/区域库位数量不足或者机器人取放货区域受限制 :{}", robotTaskVo.toString());
throw exception0(TASK_CREATE_FAIL.getCode(), "放货线库/区域库位数量不足或者机器人取放货区域受限制");
}
Collections.reverse(releaseStockList);
//赋值数据
List<RobotTaskDetailAddVO> addTaskDetailList = getTaskDatail(stockList, releaseStockList, toLocationIds,
robotTaskVo, taskId, fromLocationIds);
newTaskDetailList.addAll(addTaskDetailList);
}
createReqVO.setTaskDetailList(newTaskDetailList);
if (ObjectUtil.isNotEmpty(fromLocationIds)) {
toLocationIds.addAll(fromLocationIds);
}
return toLocationIds;
}
private List<RobotTaskDetailAddVO> getTaskDatail(List<WareHouseLocationDO> stockList,
List<WareHouseLocationDO> releaseStockList,
List<Long> toLocationIds, RobotTaskDetailAddVO robotTaskVo,
Long taskId, List<Long> fromLocationIds) {
List<RobotTaskDetailAddVO> addTaskDetailList = new ArrayList<>();
for (int i = 0; i < stockList.size(); i++) {
RobotTaskDetailAddVO robotTaskDetailAddVo = new RobotTaskDetailAddVO();
robotTaskDetailAddVo.setTaskType(robotTaskVo.getTaskType());
robotTaskDetailAddVo.setReleaseType(robotTaskVo.getReleaseType());
robotTaskDetailAddVo.setTakeType(robotTaskVo.getTakeType());
robotTaskDetailAddVo.setTakeId(robotTaskVo.getTakeId());
robotTaskDetailAddVo.setReleaseId(robotTaskVo.getReleaseId());
robotTaskDetailAddVo.setRobotNo(robotTaskVo.getRobotNo());
robotTaskDetailAddVo.setFromLocationNo(stockList.get(i).getLocationNo());
robotTaskDetailAddVo.setFromLocationId(stockList.get(i).getId());
robotTaskDetailAddVo.setToLocationNo(releaseStockList.get(i).getLocationNo());
robotTaskDetailAddVo.setToLocationId(releaseStockList.get(i).getId());
robotTaskDetailAddVo.setFromLaneId(stockList.get(i).getLaneId());
robotTaskDetailAddVo.setToLaneId(releaseStockList.get(i).getLaneId());
robotTaskDetailAddVo.setFromLocationNumber(stockList.get(i).getLocationNumber());
robotTaskDetailAddVo.setFromMapItemId(stockList.get(i).getMapItemId());
robotTaskDetailAddVo.setToMapItemId(releaseStockList.get(i).getMapItemId());
robotTaskDetailAddVo.setRobotTaskId(taskId);
robotTaskDetailAddVo.setPriority(robotTaskVo.getPriority());
robotTaskDetailAddVo.setFromLocationStorey(stockList.get(i).getLocationStorey());
robotTaskDetailAddVo.setToLocationStorey(releaseStockList.get(i).getLocationStorey());
addTaskDetailList.add(robotTaskDetailAddVo);
toLocationIds.add(releaseStockList.get(i).getId());
fromLocationIds.add(stockList.get(i).getId());
}
return addTaskDetailList;
}
public void setToLocation(RobotTaskDetailAddVO robotTaskVo, Set<Long> mapIds, List<Long> locationIds,
List<Long> takeMapItemIds, List<Long> releaseMapItemIds,
List<Long> laneIds, List<Long> areaIds, String skuInfo, Set<Long> chooseLocationIds) {
if (ReleaseTakeEnum.TO_LOCATION.getType().equals(robotTaskVo.getReleaseType())) {
WareHouseLocationDO query = WareHouseLocationDO.builder().id(robotTaskVo.getReleaseId()).build();
WareHouseLocationDO locationDO = locationMapper.queryAllByLimit(query);
robotTaskVo.setToLocationNo(locationDO.getLocationNo());
robotTaskVo.setToLocationId(robotTaskVo.getReleaseId());
robotTaskVo.setToLocationStorey(locationDO.getLocationStorey());
robotTaskVo.setToLaneId(locationDO.getLaneId());
robotTaskVo.setToLocationNumber(locationDO.getLocationNumber());
robotTaskVo.setToMapItemId(locationDO.getMapItemId());
releaseMapItemIds.add(locationDO.getMapItemId());
} else {
WareHouseLocationDO wareHouseLocationDO =
locationMapper.selectByTypeAndId(LocationUseStatusEnum.NO.getType(), robotTaskVo.getReleaseType()
, robotTaskVo.getReleaseId(), locationIds, null, takeMapItemIds, laneIds, areaIds);
robotTaskVo.setToLocationNo(wareHouseLocationDO.getLocationNo());
robotTaskVo.setToLocationId(wareHouseLocationDO.getId());
robotTaskVo.setToLocationStorey(wareHouseLocationDO.getLocationStorey());
robotTaskVo.setToLaneId(wareHouseLocationDO.getLaneId());
robotTaskVo.setToLocationNumber(wareHouseLocationDO.getLocationNumber());
robotTaskVo.setToMapItemId(wareHouseLocationDO.getMapItemId());
releaseMapItemIds.add(wareHouseLocationDO.getMapItemId());
}
}
}

View File

@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotSimulationPoseDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotSimulationPoseDataDTO;
import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum;
import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO;
import cn.iocoder.yudao.module.system.config.mqtt.util.MqttUtils;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant;
import cn.iocoder.yudao.module.system.controller.admin.config.dto.TaskOrderConfigDTO;
@ -48,8 +50,11 @@ import java.util.List;
@Validated
public class ToolsServiceImpl implements ToolsService {
@Resource
private CommonApi commonApi;
/*@Resource
private CommonApi commonApi;*/
@Autowired
private MqttUtils mqttUtils;
@Resource
private CommonConfigMapper configMapper;
@ -69,14 +74,11 @@ public class ToolsServiceImpl implements ToolsService {
@Resource
private PositionMapItemService positionMapItemService;
/*@Resource
private CommonConfigService configService;*/
@Resource
private PositionMapService positionMapService;
@Value("${zn.is_simulation:false}")
private Boolean isSimulation;
@Autowired
private ZnConfigConstant znConfigConstant;
/**
* 发送时间优先级距离的权重给PP
@ -100,8 +102,9 @@ public class ToolsServiceImpl implements ToolsService {
List<RobotInformationDO> robots = informationService.getAllRobot();
if (ObjectUtil.isNotEmpty(robots)) {
for (RobotInformationDO robot : robots) {
commonApi.commonMethodStr(String.valueOf(chargeConfig.getWarnWaitTime()),
RobotTopicConstant.WARN_WAIT_TIME_TOPIC+robot.getMacAddress());
// commonApi.commonMethodStr(String.valueOf(chargeConfig.getWarnWaitTime()),
// RobotTopicConstant.WARN_WAIT_TIME_TOPIC+robot.getMacAddress());
mqttUtils.pub(RobotTopicConstant.WARN_WAIT_TIME_TOPIC+robot.getMacAddress(),String.valueOf(chargeConfig.getWarnWaitTime()));
}
}
}
@ -120,8 +123,9 @@ public class ToolsServiceImpl implements ToolsService {
}
TaskOrderConfigDTO taskOrderConfigDTO = JSONUtil.toBean(config.getConfigStr(), TaskOrderConfigDTO.class);
commonApi.commonMethod(taskOrderConfigDTO,
PathPlanningTopicConstant.SEND_SORT_CONFIG_TO_PP);
// commonApi.commonMethod(taskOrderConfigDTO,
// PathPlanningTopicConstant.SEND_SORT_CONFIG_TO_PP);
mqttUtils.pub(PathPlanningTopicConstant.SEND_SORT_CONFIG_TO_PP,JSON.toJSONString(taskOrderConfigDTO));
return "发送数据库权重配置成功";
}
@ -134,7 +138,8 @@ public class ToolsServiceImpl implements ToolsService {
@Override
public String cleanAgv(String robotNo) {
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
// commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
mqttUtils.pub(PathPlanningTopicConstant.CLEAN_AGV,JSON.toJSONString(build));
return "清除交管成功 " + robotNo;
}
@ -150,15 +155,16 @@ public class ToolsServiceImpl implements ToolsService {
.robotNo(informationDO.getRobotNo())
.id(taskDetailId)
.build();
commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
// commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK);
mqttUtils.pub(PathPlanningTopicConstant.KILL_TASK,JSON.toJSONString(closePathPlanting));
RobotAcceptTaskDTO robotTask = new RobotAcceptTaskDTO();
robotTask.setOrderId(taskDetailId);
String mac = robotInformationService.getMacByRobotNo(informationDO.getRobotNo());
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac);
robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType());
commonApi.commonMethod(robotTask, robotTask.getTopic());
// commonApi.commonMethod(robotTask, robotTask.getTopic());
mqttUtils.pub(robotTask.getTopic(),JSON.toJSONString(robotTask));
return "关闭任务成功";
}
@ -170,7 +176,8 @@ public class ToolsServiceImpl implements ToolsService {
}
for (RobotInformationDO robot : robots) {
commonApi.commonMethodStr("请同步告警码值", RobotTopicConstant.UPDATE_ERROR_TOPIC+robot.getMacAddress());
// commonApi.commonMethodStr("请同步告警码值", RobotTopicConstant.UPDATE_ERROR_TOPIC+robot.getMacAddress());
mqttUtils.pub(RobotTopicConstant.UPDATE_ERROR_TOPIC+robot.getMacAddress(),"请同步告警码值");
try {
//怕车机同时间同步对内存有影响
Thread.sleep(500);
@ -183,7 +190,7 @@ public class ToolsServiceImpl implements ToolsService {
@Override
public void simulationPose() {
if (!isSimulation) {
if (!znConfigConstant.getIsSimulation()) {
log.info("非仿真环境不需要同步默认的节点数据");
}
@ -238,7 +245,8 @@ public class ToolsServiceImpl implements ToolsService {
poseData.setYaw(Double.valueOf(itemDOList.get(i).getLocationYaw()));
simulationPoseDTO.setPose2d(poseData);
simulationPoseDTO.setCommandType(RobotCommandTypeEnum.MOVE_POSE.getType());
commonApi.commonMethod(simulationPoseDTO, RobotTopicConstant.ROBOT_COMMAND_TOPIC + robot.getMacAddress());
// commonApi.commonMethod(simulationPoseDTO, RobotTopicConstant.ROBOT_COMMAND_TOPIC + robot.getMacAddress());
mqttUtils.pub(RobotTopicConstant.ROBOT_COMMAND_TOPIC + robot.getMacAddress(),JSON.toJSONString(simulationPoseDTO));
log.info("仿真环境发送机器人默认点位信息 {}", JSON.toJSONString(poseData));
i++;
}
@ -246,7 +254,8 @@ public class ToolsServiceImpl implements ToolsService {
@Override
public void sendMsgToMQTT(SendMsgToMqttDTO dto) {
commonApi.commonMethodStr(dto.getMsg(),dto.getTopic());
// commonApi.commonMethodStr(dto.getMsg(),dto.getTopic());
mqttUtils.pub(dto.getTopic(),dto.getMsg());
}

View File

@ -191,28 +191,27 @@ zn:
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 #机器人充满电的电量
full_electricity: 95 #机器人充满电的电量
task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人)
location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值)
robot_doing_action: # 机器人正在做的动作
doing_action_cache_time: 172800 #单个动作缓存时间 8小时
robot_chearg: #机器人充电的配置
robot_charge: #机器人充电的配置
release_location_number_config: 50 #同一组序号,越大越先执行
priority_config: 50 #优先级
task: #任务相关的配置
check_sku_info: true #校验物料信息
task_cache_time: 1209600 #任务缓存的时间, 默认一星期
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 #任务缓存的时间, 默认一星期
is_simulation: false # 是否为仿真环境
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始
synchronous_all_map_node: 500 # 点位信息每次发送的数据量
task_not_check: true # 创建任务不校验
#海康威视的相关配置
@ -227,4 +226,19 @@ resource:
#视频能力
video:
previewUrls: /artemis/api/video/v2/cameras/previewURLs
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
# MQTT
mqtt:
# host: tcp://123.57.12.40:1883
host: tcp://127.0.0.1:1883
# host: tcp://10.10.7.116:1883
# host: tcp://10.10.7.114:1883
username: adminuser
password: adminuser
qos: 2
clientId: mqttx_b82345a52
# 表示允许同时在传输中的最大消息数量
maxInflight: 1000
timeout: 10
keepalive: 20

View File

@ -228,26 +228,25 @@ zn:
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库
robot_position_cache_time: 10000000 #机器人上报点位存储时间(秒)
cycle_do_auto_move: true #存在循环的任务,是否开启自动移库. true:存在循环任务,开启自动移库; false有循环任务不自动移库
full_electricity: 100 #机器人充满电的电量
full_electricity: 95 #机器人充满电的电量
task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人)
location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值)
robot_doing_action: # 机器人正在做的动作
doing_action_cache_time: 172800 #单个动作缓存时间 8小时
robot_chearg: #机器人充电的配置
robot_charge: #机器人充电的配置
release_location_number_config: 50 #同一组序号,越大越先执行
priority_config: 50 #优先级
task: #任务相关的配置
check_sku_info: true #校验物料信息
task_cache_time: 1209600 #任务缓存的时间, 默认一星期
robot_config: #机器人取放货默认配置
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
default_tray_height: 0.82 #默认每层高度
open_rate_limiter: true #是否开启限流
path_planning:
task_chche_time: 1209600 #任务缓存的时间, 默认一星期
is_simulation: true # 是否为仿真环境
is_simulation: false # 是否为仿真环境
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
restore_task_restart: true # 恢复任务是否全部重新执行 true:全部重新开始
synchronous_all_map_node: 500 # 点位信息每次发送的数据量
task_not_check: true # 创建任务不校验
logging:
file:
@ -266,3 +265,18 @@ resource:
video:
previewUrls: /artemis/api/video/v2/cameras/previewURLs
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
# MQTT
mqtt:
# host: tcp://123.57.12.40:1883
host: tcp://127.0.0.1:1883
# host: tcp://10.10.7.116:1883
# host: tcp://10.10.7.114:1883
username: adminuser
password: adminuser
qos: 2
clientId: mqttx_b82345a52
# 表示允许同时在传输中的最大消息数量
maxInflight: 1000
timeout: 10
keepalive: 20

View File

@ -219,28 +219,27 @@ zn:
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 #机器人充满电的电量
full_electricity: 95 #机器人充满电的电量
task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人)
location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值)
robot_doing_action: # 机器人正在做的动作
doing_action_cache_time: 172800 #单个动作缓存时间 8小时
robot_chearg: #机器人充电的配置
robot_charge: #机器人充电的配置
release_location_number_config: 50 #同一组序号,越大越先执行
priority_config: 50 #优先级
task: #任务相关的配置
check_sku_info: true #校验物料信息
task_cache_time: 1209600 #任务缓存的时间, 默认一星期
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 #任务缓存的时间, 默认一星期
is_simulation: false # 是否为仿真环境
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始
synchronous_all_map_node: 500 # 点位信息每次发送的数据量
task_not_check: true # 创建任务不校验
#海康威视的相关配置
isc:
@ -254,4 +253,18 @@ resource:
#视频能力
video:
previewUrls: /artemis/api/video/v2/cameras/previewURLs
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
# MQTT
mqtt:
# host: tcp://123.57.12.40:1883
# host: tcp://10.10.100.42:1883
host: tcp://127.0.0.1:1883
username: adminuser
password: adminuser
qos: 0
clientId: mqttx_b82345a52
# 表示允许同时在传输中的最大消息数量
maxInflight: 1000
timeout: 10
keepalive: 20

View File

@ -86,7 +86,7 @@
(#{item.positionMapId}, #{item.actualLocationX}, #{item.actualLocationY}, #{item.type})
</foreach>
</select>
<select id="selectSortNumByIds" resultType="cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapIdNumMapVO">
<select id="selectSortNumByIds" resultType="cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO">
select
id,
sort_num as sortNum

View File

@ -160,8 +160,7 @@
from
robot_information
where
deleted = '0'
and robot_no in
robot_no in
<foreach collection="robotNos" item="robotNo" index="index" open="(" close=")"
separator=",">
#{robotNo}
@ -176,7 +175,8 @@
t2.robot_center_headstock AS robotCenterHeadstock,
t2.robot_center_tail AS robotCenterTail,
t1.mac_address as macAddress,
t2.robot_turning_radius as robotTurningRadius
t2.robot_turning_radius as robotTurningRadius,
t2.robot_offset as robotOffset
FROM
robot_information t1
LEFT JOIN robot_model t2 ON t1.robot_model_id = t2.id
@ -198,4 +198,28 @@
</if>
</where>
</select>
<select id="selectByRobotNoAndIdNotIn"
resultType="cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO">
select
<include refid="base_sql"></include>
from
robot_information
where
robot_no = #{robotNo}
and id != #{id}
limit 1
</select>
<select id="selectByMacAndIdNotIn"
resultType="cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO">
select
<include refid="base_sql"></include>
from
robot_information
where
mac_address = #{macAddress}
<if test="id != null">
and id != #{id}
</if>
limit 1
</select>
</mapper>

View File

@ -12,4 +12,12 @@
<delete id="deletByRobotTaskId">
delete from robot_task_cycle where robot_task_id = #{robotTaskId}
</delete>
<delete id="deletByRobotTaskIds">
delete from robot_task_cycle
where robot_task_id in
<foreach collection="taskIds" item="robotTaskId" index="index" open="(" close=")"
separator=",">
#{robotTaskId}
</foreach>
</delete>
</mapper>