Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud-wcs into dev
This commit is contained in:
commit
a59d1ec224
@ -15,5 +15,8 @@ public class PathToRobotChangeXYArgDTO {
|
||||
private List<PathToRobotChangeXYArgMovePoseDTO> pose2ds;
|
||||
private PathToRobotChangeXYArgPoseDTO backPose;
|
||||
private PathToRobotChangeXYArgPoseDTO cargoPose;
|
||||
private Double height;
|
||||
private Integer level;
|
||||
private Double offsetHeight;
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@ -21,5 +23,5 @@ public class PathToRobotChangeXYDTO {
|
||||
private String robotNo;
|
||||
private String taskType;
|
||||
|
||||
private PathToRobotChangeXYDataDTO data;
|
||||
private List<PathToRobotChangeXYDataDTO> data;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ management:
|
||||
# MQTT
|
||||
mqtt:
|
||||
# host: tcp://123.57.12.40:1883
|
||||
host: tcp://127.0.0.1:1883
|
||||
host: tcp://10.10.100.42:1883
|
||||
username: adminuser
|
||||
password: adminuser
|
||||
qos: 0
|
||||
|
@ -130,6 +130,13 @@
|
||||
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.hikvision.ga</groupId>
|
||||
<artifactId>artemis-http-client</artifactId>
|
||||
<version>1.1.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 三方云服务相关 -->
|
||||
<dependency>
|
||||
<groupId>com.xingyuv</groupId>
|
||||
|
@ -53,9 +53,9 @@ public class RobotUpdatePalletHeightApiImpl implements RobotUpdatePalletHeightAp
|
||||
log.info("高度反馈 :{}", message);
|
||||
TenantContextHolder.setTenantId(1L);
|
||||
RobotUpdatePalletHeightDTO data = JSON.parseObject(message, RobotUpdatePalletHeightDTO.class);
|
||||
if (RobotCommandTypeEnum.WORD_DROP_OFF_GOODS.getType().equals(data.getCommandType())) {
|
||||
if (RobotCommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(data.getCommandType())) {
|
||||
dropOffGoods(data);
|
||||
} else if (RobotCommandTypeEnum.WORD_PICK_UP_GOODS.getType().equals(data.getCommandType())) {
|
||||
} else if (RobotCommandTypeEnum.WORK_PICK_UP_GOODS.getType().equals(data.getCommandType())) {
|
||||
pickUpGoods(data);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,13 @@ package cn.iocoder.yudao.module.system.api.robot;
|
||||
|
||||
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.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.service.log.RobotOperationLogService;
|
||||
import cn.iocoder.yudao.module.system.service.path.PathPlanningService;
|
||||
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -24,6 +29,9 @@ public class RobotWorkStatusApiImpl implements RobotWorkStatusApi {
|
||||
@Autowired
|
||||
private RobotInformationService robotInformationService;
|
||||
|
||||
@Resource
|
||||
private PathPlanningService pathPlanningService;
|
||||
|
||||
@Override
|
||||
public void robotWorkStatus(String message) {
|
||||
log.info("作业实时行为上报: {}", message);
|
||||
@ -40,6 +48,19 @@ public class RobotWorkStatusApiImpl implements RobotWorkStatusApi {
|
||||
.executionState(data.getExecutionState())
|
||||
.build();
|
||||
operationLogService.createOperationLog(createReqVO);
|
||||
|
||||
if ((CommandTypeEnum.WORK_PICK_UP_GOODS_MOVE_TO_CHECK.getType().equals(data.getCommandType())
|
||||
|| CommandTypeEnum.WORK_DROP_OFF_GOODS_MOVE_TO_CHECK.getType().equals(data.getCommandType()))
|
||||
&& RobotExecutionStateConstant.DOING.equals(Integer.valueOf(data.getExecutionState()))) {
|
||||
pathPlanningService.updateBehavior(String.valueOf(data.getOrderId()), robotNo
|
||||
, data.getCommandType(), PathIsReachEnum.START_WORK.getType());
|
||||
}else if ((CommandTypeEnum.WORK_PICK_UP_GOODS_MOVE_TO_CHECK.getType().equals(data.getCommandType())
|
||||
|| CommandTypeEnum.WORK_DROP_OFF_GOODS_MOVE_TO_CHECK.getType().equals(data.getCommandType()))
|
||||
&& RobotExecutionStateConstant.DONE.equals(Integer.valueOf(data.getExecutionState()))) {
|
||||
pathPlanningService.updateBehavior(String.valueOf(data.getOrderId()), robotNo
|
||||
, data.getCommandType(), PathIsReachEnum.END_WORK.getType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ public class RobotUpdatePalletHeightDTO {
|
||||
private String goodsHeight;
|
||||
private String mac;
|
||||
private String orderId;
|
||||
//作业类型 WORD_PICK_UP_GOODS/WORD_DROP_OFF_GOODS
|
||||
//作业类型 WORK_PICK_UP_GOODS/WORK_DROP_OFF_GOODS
|
||||
private String commandType;
|
||||
private String orderType;
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.module.system.config.hik;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@PropertySource("classpath:application-hik.yaml")
|
||||
public class ArtemisApiConstant implements CommandLineRunner {
|
||||
|
||||
public static String camerasApi;
|
||||
public static String previewUrlsApi;
|
||||
public static String replayUrlApi;
|
||||
|
||||
public static String operateUrlApi = "/artemis/api/video/v1/ptzs/controlling";
|
||||
|
||||
@Value("${resource.cameras}")
|
||||
public void setCamerasApi(String a) {
|
||||
camerasApi = a;
|
||||
}
|
||||
|
||||
@Value("${video.previewUrls}")
|
||||
public void setPreviewUrls(String a) {
|
||||
previewUrlsApi = a;
|
||||
}
|
||||
|
||||
@Value("${video.replayUrlApi}")
|
||||
public void setReplayUrlApi(String a) {
|
||||
replayUrlApi = a;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("# 【ArtemisApiConstant】 camerasApi:{} #", camerasApi);
|
||||
log.info("# 【ArtemisApiConstant】 previewUrlsApi:{} #", previewUrlsApi);
|
||||
log.info("# 【ArtemisApiConstant】 replayUrlApi:{} #", replayUrlApi);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.system.config.hik;
|
||||
|
||||
import com.hikvision.artemis.sdk.config.ArtemisConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@PropertySource("classpath:application-hik.yaml")
|
||||
public class ArtemisConfigConstant implements CommandLineRunner {
|
||||
|
||||
|
||||
public static String host;
|
||||
public static String appKey;
|
||||
public static String appSecret;
|
||||
|
||||
@Value("${isc.host}")
|
||||
public void setHost(String a) {
|
||||
host = a;
|
||||
ArtemisConfig.host = a;
|
||||
}
|
||||
|
||||
@Value("${isc.appKey}")
|
||||
public void setAppKey(String a) {
|
||||
appKey = a;
|
||||
ArtemisConfig.appKey = a;
|
||||
}
|
||||
|
||||
@Value("${isc.appSecret}")
|
||||
public void setAppSecret(String a) {
|
||||
appSecret = a;
|
||||
ArtemisConfig.appSecret = a;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("# 【ArtemisConfigConstant】 host:{} #", ArtemisConfigConstant.host);
|
||||
log.info("# 【ArtemisConfigConstant】 appKey:{} #", ArtemisConfigConstant.appKey);
|
||||
log.info("# 【ArtemisConfigConstant】 appSecret:{} #", ArtemisConfigConstant.appSecret);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.hik;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.system.service.hik.HikService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
|
||||
/**
|
||||
* 工厂管理-工厂列表
|
||||
*
|
||||
* @author qun.xu
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/smartfactory/hik")
|
||||
@Tag(name = "海康接口")
|
||||
public class HikController {
|
||||
|
||||
@Resource
|
||||
private HikService hikService;
|
||||
|
||||
@GetMapping("/getCameraUrl")
|
||||
@Operation(summary = "视频播放->查询播放地址")
|
||||
// @PreAuthorize("@ss.hasPermission('smartfactory:camera:view')")
|
||||
@PermitAll
|
||||
public CommonResult<String> getCameraUrl(String cameraCode) {
|
||||
String url = hikService.getPreviewUrlsApi(cameraCode, 0);
|
||||
return CommonResult.success(url);
|
||||
}
|
||||
|
||||
}
|
@ -84,7 +84,7 @@ public class DeviceInformationController {
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得设备信息列表")
|
||||
@Operation(summary = "获得设备信息列表,3D地图也用到")
|
||||
public CommonResult<List<DeviceInformationRespVO>> getList(@Valid DeviceInformationDTO dto) {
|
||||
List<DeviceInformationDO> list = informationService.getList(dto);
|
||||
return success(BeanUtils.toBean(list, DeviceInformationRespVO.class));
|
||||
|
@ -29,6 +29,12 @@ public class DeviceInformationPageReqVO extends PageParam {
|
||||
@Schema(description = "库位坐标y轴")
|
||||
private String locationY;
|
||||
|
||||
@Schema(description = "实际坐标x轴")
|
||||
private String actualLocationX;
|
||||
|
||||
@Schema(description = "实际坐标Y轴")
|
||||
private String actualLocationY;
|
||||
|
||||
@Schema(description = "宽度")
|
||||
private BigDecimal locationWide;
|
||||
|
||||
|
@ -34,6 +34,14 @@ public class DeviceInformationRespVO {
|
||||
@ExcelProperty("库位坐标y轴")
|
||||
private String locationY;
|
||||
|
||||
@Schema(description = "实际坐标x轴")
|
||||
@ExcelProperty("实际坐标x轴")
|
||||
private String actualLocationX;
|
||||
|
||||
@Schema(description = "实际坐标Y轴")
|
||||
@ExcelProperty("实际坐标Y轴")
|
||||
private String actualLocationY;
|
||||
|
||||
@Schema(description = "宽度")
|
||||
@ExcelProperty("宽度")
|
||||
private BigDecimal locationWide;
|
||||
|
@ -29,6 +29,12 @@ public class DeviceInformationSaveReqVO {
|
||||
@Schema(description = "库位坐标y轴")
|
||||
private String locationY;
|
||||
|
||||
@Schema(description = "实际坐标x轴")
|
||||
private String actualLocationX;
|
||||
|
||||
@Schema(description = "实际坐标Y轴")
|
||||
private String actualLocationY;
|
||||
|
||||
@Schema(description = "宽度")
|
||||
private BigDecimal locationWide;
|
||||
|
||||
|
@ -29,7 +29,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 车辆摄像头信息")
|
||||
@RestController
|
||||
@RequestMapping("/robot/camera")
|
||||
@RequestMapping("/system/robot/camera")
|
||||
@Validated
|
||||
public class RobotCameraController {
|
||||
|
||||
|
@ -50,6 +50,8 @@ public class TaskAssignDTO {
|
||||
return "机器人分配到自动充电任务 ";
|
||||
}if (PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(orderType)) {
|
||||
return "机器人分配到移动到点位任务 ";
|
||||
}if (PathTaskTypeEnum.MOVE_TO_PP_POINT.getType().equals(orderType)) {
|
||||
return "路径规划分配机器人移动到点位任务 ";
|
||||
}
|
||||
return "未知任务";
|
||||
}
|
||||
|
@ -15,10 +15,11 @@ import java.util.List;
|
||||
public enum PathTaskTypeEnum {
|
||||
TAKE_RELEASE("TAKE_RELEASE","取放货任务"),
|
||||
CHARGE("CHARGE","充电任务"),
|
||||
MOVE("MOVE","移动任务"),//移动到库位
|
||||
MOVE("MOVE","移动任务(移动到库位)"),
|
||||
MOVE_TO_WAIT("MOVE_TO_WAIT","移动到等待点(没任务时去等待点)"),
|
||||
MOVE_TO_WAIT_STOP("MOVE_TO_WAIT_STOP","停车任务"),
|
||||
MOVE_TO_POINT("MOVE_TO_POINT","移动到路径点任务"),
|
||||
MOVE_TO_PP_POINT("MOVE_TO_PP_POINT","移动到路径规划指定的点位"),
|
||||
TAKE("TAKE","仅取货任务"),
|
||||
RELEASE("RELEASE","仅放货任务"),
|
||||
AUTO_CHARGE("AUTO_CHARGE","自动充电");
|
||||
|
@ -9,6 +9,8 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CommandTypeEnum {
|
||||
WORK_PICK_UP_GOODS_MOVE_TO_CHECK("WORK_PICK_UP_GOODS_MOVE_TO_CHECK","取货导航到检测点"),
|
||||
WORK_DROP_OFF_GOODS_MOVE_TO_CHECK("WORK_DROP_OFF_GOODS_MOVE_TO_CHECK","放货导航到检测点"),
|
||||
WORK_PICK_UP_GOODS("WORK_PICK_UP_GOODS","取货控叉"),
|
||||
WORK_DROP_OFF_GOODS("WORK_DROP_OFF_GOODS","放货控叉"),
|
||||
MOVE_POSES("MOVE_POSES","移动"),
|
||||
|
@ -9,8 +9,8 @@ public enum RobotCommandTypeEnum {
|
||||
MOVE_POSES("MOVE_POSES","移动"),
|
||||
SWITCH_MAP("SWITCH_MAP","切图"),
|
||||
WORK_START_CHARGE("WORK_START_CHARGE","充电"),
|
||||
WORD_PICK_UP_GOODS("WORD_PICK_UP_GOODS","取货"),
|
||||
WORD_DROP_OFF_GOODS("WORD_DROP_OFF_GOODS","放货"),
|
||||
WORK_PICK_UP_GOODS("WORK_PICK_UP_GOODS","取货"),
|
||||
WORK_DROP_OFF_GOODS("WORK_DROP_OFF_GOODS","放货"),
|
||||
MOVE_POSE("MOVE_POSE","仿真移动点位"),
|
||||
MODE("MODE","远遥/RCS模式切换"),
|
||||
EMERGENCY_STOP("EMERGENCY_STOP","急停车辆"),
|
||||
|
@ -0,0 +1,5 @@
|
||||
package cn.iocoder.yudao.module.system.service.hik;
|
||||
|
||||
public interface HikService {
|
||||
String getPreviewUrlsApi(String cameraCode, int i);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package cn.iocoder.yudao.module.system.service.hik;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.cloud.commons.lang.StringUtils;
|
||||
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class HikServiceImpl implements HikService{
|
||||
|
||||
@Override
|
||||
public String getPreviewUrlsApi(String cameraCode, int streamType) {
|
||||
final String previewUrlsApi ="/artemis/api/video/v2/cameras/previewURLs";
|
||||
Map<String, String> path = new HashMap<String, String>(1) {
|
||||
{
|
||||
put("https://", previewUrlsApi);
|
||||
}
|
||||
};
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("cameraIndexCode", cameraCode);
|
||||
body.set("streamType", streamType);
|
||||
body.set("protocol", "ws");
|
||||
body.set("transmode", 1);
|
||||
body.set("expand", "streamform=ps");
|
||||
try {
|
||||
String result = ArtemisHttpUtil
|
||||
.doPostStringArtemis(path, JSONUtil.toJsonStr(body), null, null, "application/json") ;
|
||||
log.info("{}监控查看预览地址返回:{}", JSONUtil.toJsonStr(body), result);
|
||||
if (StringUtils.isEmpty(result)) {
|
||||
// throw new ServiceException("监控查看预览地址返回为空");
|
||||
System.out.println("监控查看预览地址返回为空");
|
||||
}
|
||||
JSONObject json = JSONUtil.parseObj(result);
|
||||
String url = "";
|
||||
if (json.getJSONObject("data") != null) {
|
||||
url = json.getJSONObject("data").getStr("url");
|
||||
}
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -5,10 +5,8 @@ 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.api.robot.vo.RobotPathStatusDTO;
|
||||
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.DeviceInformationDataJsonDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.information.dto.MapBindDeviceInfoDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.information.dto.StatisticsInformationDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationPageReqVO;
|
||||
@ -26,7 +24,6 @@ import cn.iocoder.yudao.module.system.enums.device.DeviceAttributeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.device.DeviceStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.device.PictureConfigEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
|
||||
import cn.iocoder.yudao.module.system.service.config.CommonConfigService;
|
||||
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
|
||||
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
|
||||
|
@ -37,6 +37,7 @@ import cn.iocoder.yudao.module.system.enums.config.CommandConfigTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.line.DirectionEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeToRobotEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.path.PathTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.robot.task.RobotCommandTypeEnum;
|
||||
@ -50,6 +51,7 @@ import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
|
||||
import cn.iocoder.yudao.module.system.service.robot.RobotModelService;
|
||||
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -57,6 +59,8 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
@ -78,6 +82,8 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.PATH_PLANN
|
||||
@Service
|
||||
public class PathPlanningServiceImpl implements PathPlanningService {
|
||||
|
||||
private static final double PI = Math.PI;
|
||||
|
||||
|
||||
@Resource
|
||||
private PositionMapLineMapper positionMapLineMapper;
|
||||
@ -115,6 +121,9 @@ public class PathPlanningServiceImpl implements PathPlanningService {
|
||||
@Value("${zn.send_robot_init_pose:false}")
|
||||
private Boolean sendRobotInitPose;
|
||||
|
||||
@Value("${zn.synchronous_all_map_node:500}")
|
||||
private Integer synchronousAllMapNodeSize;
|
||||
|
||||
@Resource
|
||||
private PositionChangePointBindingService positionChangePointBindingService;
|
||||
|
||||
@ -187,14 +196,17 @@ public class PathPlanningServiceImpl implements PathPlanningService {
|
||||
if (ObjectUtil.isEmpty(positionMapItemSynDTOS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<List<PositionMapItemSynDTO>> partition = Lists.partition(positionMapItemSynDTOS, synchronousAllMapNodeSize);
|
||||
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(positionMapItemSynDTOS);
|
||||
|
||||
relatedPathNode.setControl_nodes(nodes);
|
||||
commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_NODE);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("同步点位信息结束");
|
||||
}
|
||||
@ -450,11 +462,12 @@ public class PathPlanningServiceImpl implements PathPlanningService {
|
||||
@Override
|
||||
public void sendPosedsToRobot(String message) {
|
||||
PathToRobotDTO pathRobotDTO = JSON.parseObject(message, PathToRobotDTO.class);
|
||||
log.info("任务类型 :{}",pathRobotDTO.getTaskType());
|
||||
String mac = robotInformationService.getMacByRobotNo(pathRobotDTO.getRobotNo());
|
||||
String topic = RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac;
|
||||
if(RobotCommandTypeEnum.SWITCH_MAP.getType().equals(pathRobotDTO.getCommandType())) {
|
||||
if(RobotCommandTypeEnum.SWITCH_MAP.getType().equals(pathRobotDTO.getTaskType())) {
|
||||
switchMap(pathRobotDTO,topic);
|
||||
} else if (RobotCommandTypeEnum.WORD_DROP_OFF_GOODS.getType().equals(pathRobotDTO.getCommandType())) {
|
||||
} else if (PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType().equals(pathRobotDTO.getTaskType())) {
|
||||
wordDropOffGoods(message,topic,pathRobotDTO.getRobotNo());
|
||||
} else {
|
||||
commonApi.commonMethodStr(message, topic);
|
||||
@ -474,9 +487,36 @@ public class PathPlanningServiceImpl implements PathPlanningService {
|
||||
commonApi.commonMethodStr(message, topic);
|
||||
return;
|
||||
}
|
||||
// PathToRobotChangeXYDTO pathToRobotChangeXY = JSON.parseObject(message, PathToRobotChangeXYDTO.class);
|
||||
PathToRobotChangeXYDTO pathToRobotChangeXY = JSON.parseObject(message, PathToRobotChangeXYDTO.class);
|
||||
List<PathToRobotChangeXYDataDTO> data = pathToRobotChangeXY.getData();
|
||||
boolean needOffset = false;
|
||||
PathToRobotChangeXYArgPoseDTO cargoPose = new PathToRobotChangeXYArgPoseDTO();
|
||||
for (PathToRobotChangeXYDataDTO item : data) {
|
||||
if (RobotCommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(item.getCommandType()) && ZeroOneEnum.ONE.getType().equals(item.getIsCommandEnd())) {
|
||||
needOffset = true;
|
||||
cargoPose = item.getArg().getCargoPose();
|
||||
}
|
||||
}
|
||||
|
||||
if (!needOffset) {
|
||||
commonApi.commonMethodStr(message, topic);
|
||||
return;
|
||||
}
|
||||
|
||||
BigDecimal robotXOffset = new BigDecimal(model.getRobotXOffset());
|
||||
BigDecimal robotYOffset = new BigDecimal(model.getRobotYOffset());
|
||||
double sin = Math.sin(cargoPose.getYaw());
|
||||
double cos = Math.cos(cargoPose.getYaw());
|
||||
BigDecimal sino = new BigDecimal(String.valueOf(sin));
|
||||
BigDecimal coso = new BigDecimal(String.valueOf(cos));
|
||||
BigDecimal x1 = new BigDecimal(String.valueOf(cargoPose.getX()));
|
||||
BigDecimal y1 = new BigDecimal(String.valueOf(cargoPose.getY()));
|
||||
BigDecimal x = (coso.multiply(robotXOffset, MathContext.DECIMAL32)).subtract(sino.multiply(robotYOffset, MathContext.DECIMAL32)).add(x1);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.service.robot;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
@ -45,6 +46,7 @@ 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.common.ZeroOneEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.device.DeviceUseStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
|
||||
@ -166,6 +168,15 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
|
||||
@Resource
|
||||
private RobotTaskDetailActionLogMapper taskDetailActionLogMapper;
|
||||
|
||||
@Autowired
|
||||
private RobotTaskMapper robotTaskMapper;
|
||||
|
||||
@Autowired
|
||||
private RobotTaskDetailMapper robotTaskDetailMapper;
|
||||
|
||||
@Value("${zn.move-no:MOVE}")
|
||||
private String moveTaskNo;
|
||||
|
||||
@Resource
|
||||
private PositionMapItemService positionMapItemService;
|
||||
|
||||
@ -608,7 +619,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
|
||||
|
||||
robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), robotStatus, taskAssignDTO.getOrderId());
|
||||
|
||||
RobotTaskDO robotTaskDO = setTaskDoing(taskAssignDTO.getOrderId(), taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId());
|
||||
RobotTaskDO robotTaskDO = null;
|
||||
if (PathTaskTypeEnum.MOVE_TO_PP_POINT.getType().equals(taskAssignDTO.getOrderType())) {
|
||||
robotTaskDO = ppCreateMove(taskAssignDTO);
|
||||
} else {
|
||||
robotTaskDO = setTaskDoing(taskAssignDTO.getOrderId(), taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId());
|
||||
}
|
||||
|
||||
RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO();
|
||||
logOne.setCommandType(taskAssignDTO.getOrderType());
|
||||
@ -629,6 +645,36 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
|
||||
robotWorkingHoursStatisticsService.createFreeTime(taskAssignDTO.getRobotNo());
|
||||
}
|
||||
|
||||
|
||||
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.setId(IdUtil.getSnowflakeNextId());
|
||||
task.setCycleNumber(0L);
|
||||
task.setRemainingCycleNumber(0L);
|
||||
task.setStartTime(LocalDateTime.now());
|
||||
task.setTaskStatus(RobotTaskStatusEnum.DOING.getType());
|
||||
|
||||
PositionMapItemDO positionMapItem = positionMapItemService.getPositionMapItem(Long.valueOf(taskAssignDTO.getWaitId()));
|
||||
RobotTaskDetailDO taskDetailDO = new RobotTaskDetailDO();
|
||||
taskDetailDO.setId(taskAssignDTO.getOrderId());
|
||||
taskDetailDO.setRobotTaskId(task.getId());
|
||||
taskDetailDO.setTaskType(RobotTaskTypeEnum.MOVE_TO_POINT.getType());
|
||||
taskDetailDO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType());
|
||||
taskDetailDO.setReleaseId(Long.valueOf(taskAssignDTO.getWaitId()));
|
||||
taskDetailDO.setToLocationId(Long.valueOf(taskAssignDTO.getWaitId()));
|
||||
taskDetailDO.setToLocationNo( positionMapItem.getSortNum() + "");
|
||||
taskDetailDO.setRobotNo(taskAssignDTO.getRobotNo());
|
||||
taskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
|
||||
taskDetailDO.setStartTime(LocalDateTime.now());
|
||||
|
||||
robotTaskMapper.insert(task);
|
||||
robotTaskDetailMapper.insert(taskDetailDO);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放ware_position_map_item的使用状态
|
||||
*
|
||||
@ -715,7 +761,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
|
||||
WareHouseLocationDO location = null;
|
||||
if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(taskAssignDTO.getOrderType()) ||
|
||||
PathTaskTypeEnum.TAKE.getType().equals(taskAssignDTO.getOrderType())) {
|
||||
take.setCommandType(RobotCommandTypeEnum.WORD_PICK_UP_GOODS.getType());
|
||||
take.setCommandType(RobotCommandTypeEnum.WORK_PICK_UP_GOODS.getType());
|
||||
location = locationMapper.selectById(v.getFromLocationId());
|
||||
build = RobotAssignTaskArgDTO.builder()
|
||||
.level(Double.valueOf(location.getLocationStorey()))
|
||||
@ -723,7 +769,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
|
||||
.build();
|
||||
take.setArg(Arrays.asList(build));
|
||||
} else if (PathTaskTypeEnum.RELEASE.getType().equals(taskAssignDTO.getOrderType())) {
|
||||
take.setCommandType(RobotCommandTypeEnum.WORD_DROP_OFF_GOODS.getType());
|
||||
take.setCommandType(RobotCommandTypeEnum.WORK_DROP_OFF_GOODS.getType());
|
||||
location = locationMapper.selectById(v.getToLocationId());
|
||||
build = RobotAssignTaskArgDTO.builder()
|
||||
.level(Double.valueOf(location.getLocationStorey()))
|
||||
|
@ -197,14 +197,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
return;
|
||||
}
|
||||
|
||||
robots = robots.stream()
|
||||
.filter(v -> v.getRobotStatus().equals(RobotStatusEnum.STAND_BY.getType()))
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtil.isEmpty(robots)) {
|
||||
log.info("------没有空闲的机器人可以去等待点-----");
|
||||
return;
|
||||
}
|
||||
|
||||
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
|
||||
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()));
|
||||
|
||||
@ -213,19 +205,50 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> robotNos = robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList());
|
||||
List<String> inStopPointRobotNos = new ArrayList<>();
|
||||
for (PositionMapItemDO positionMapItem : positionMapItems) {
|
||||
if (UseStatusEnum.USEING.getType().equals(positionMapItem.getUseStatus()) && ObjectUtil.isNotEmpty(positionMapItem.getRobotNo())) {
|
||||
inStopPointRobotNos.add(positionMapItem.getRobotNo());
|
||||
}
|
||||
}
|
||||
|
||||
List<String> robotNos = new ArrayList<>();
|
||||
Map<String,Set<Long>> robotFloorAreaJsonMap = new HashMap<>();
|
||||
for (RobotInformationDO robot : robots) {
|
||||
if (!RobotStatusEnum.STAND_BY.getType().equals(robot.getRobotStatus())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ObjectUtil.isEmpty(robot.getFloorAreaJson())) {
|
||||
log.info("车辆没有能行走的区域 :{}",robot.getRobotNo());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotEmpty(inStopPointRobotNos) && inStopPointRobotNos.contains(robot.getRobotNo())) {
|
||||
log.info("车辆已经在停车点了 :{}",robot.getRobotNo());
|
||||
continue;
|
||||
}
|
||||
|
||||
robotNos.add(robot.getRobotNo());
|
||||
robotFloorAreaJsonMap.put(robot.getRobotNo(),robot.getFloorAreaJson());
|
||||
}
|
||||
|
||||
if (ObjectUtil.isEmpty(robotNos)) {
|
||||
log.info("------没有空闲的机器人可以去等待点-----");
|
||||
return;
|
||||
}
|
||||
|
||||
List<PositionMapItemDO> existMapItems = positionMapItems.stream()
|
||||
.filter(v -> ObjectUtil.isNotEmpty(v.getRobotNo()) && robotNos.contains(v.getRobotNo()))
|
||||
.filter(v -> ObjectUtil.isNotEmpty(v.getRobotNo())
|
||||
&& robotNos.contains(v.getRobotNo())
|
||||
&& robotFloorAreaJsonMap.get(v.getRobotNo()).contains(v.getPositionMapId()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
//车辆直接分配的停车点集合
|
||||
List<PositionMapItemDO> robotMapItems = new ArrayList<>();
|
||||
if (ObjectUtil.isNotEmpty(existMapItems)) {
|
||||
|
||||
for (PositionMapItemDO positionMapItem : existMapItems) {
|
||||
if (ObjectUtil.isEmpty(robots)) {
|
||||
if (ObjectUtil.isEmpty(robotNos)) {
|
||||
break;
|
||||
}
|
||||
robotNos.removeIf(v -> v.equals(positionMapItem.getRobotNo()));
|
||||
@ -244,7 +267,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
if (ObjectUtil.isEmpty(robotNos)) {
|
||||
break;
|
||||
}
|
||||
positionMapItem.setRobotNo(robotNos.get(0));
|
||||
String robotNo = robotNos.get(0);
|
||||
if (!robotFloorAreaJsonMap.get(robotNo).contains(positionMapItem.getPositionMapId())) {
|
||||
log.info("车辆不能在此停车点 :{}, 车辆编号 :{}",positionMapItem.getSortNum(), robotNo);
|
||||
continue;
|
||||
}
|
||||
positionMapItem.setRobotNo(robotNo);
|
||||
robotNos.removeIf(v -> v.equals(positionMapItem.getRobotNo()));
|
||||
positionMapItem.setUseStatus(UseStatusEnum.PRE_OCCUPANCY.getType());
|
||||
robotMapItems.add(positionMapItem);
|
||||
|
@ -212,3 +212,19 @@ zn:
|
||||
is_simulation: false # 是否为仿真环境
|
||||
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
|
||||
restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始
|
||||
synchronous_all_map_node: 500 # 点位信息每次发送的数据量
|
||||
|
||||
|
||||
#海康威视的相关配置
|
||||
isc:
|
||||
previewUrl: https://api.znkj.ispt.com.cn
|
||||
host: 111.75.51.123:10443
|
||||
appKey: 24991430
|
||||
appSecret: jQd4pIYZBzwW8cnuI9IN
|
||||
#视频资源
|
||||
resource:
|
||||
cameras: /artemis/api/resource/v1/cameras
|
||||
#视频能力
|
||||
video:
|
||||
previewUrls: /artemis/api/video/v2/cameras/previewURLs
|
||||
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
|
@ -0,0 +1,12 @@
|
||||
#海康威视的相关配置
|
||||
isc:
|
||||
host: hik.znkj.ispt.com.cn:10443
|
||||
appKey: 24991430
|
||||
appSecret: jQd4pIYZBzwW8cnuI9IN
|
||||
#视频资源
|
||||
resource:
|
||||
cameras: /artemis/api/resource/v1/cameras
|
||||
#视频能力
|
||||
video:
|
||||
previewUrls: /artemis/api/video/v2/cameras/previewURLs
|
||||
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
|
@ -247,7 +247,22 @@ zn:
|
||||
is_simulation: true # 是否为仿真环境
|
||||
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
|
||||
restore_task_restart: true # 恢复任务是否全部重新执行 true:全部重新开始
|
||||
synchronous_all_map_node: 500 # 点位信息每次发送的数据量
|
||||
|
||||
logging:
|
||||
file:
|
||||
name: C:\system\install\log/${spring.application.name}.log
|
||||
|
||||
#海康威视的相关配置
|
||||
isc:
|
||||
previewUrl: https://api.znkj.ispt.com.cn
|
||||
host: 111.75.51.123:10443
|
||||
appKey: 24991430
|
||||
appSecret: jQd4pIYZBzwW8cnuI9IN
|
||||
#视频资源
|
||||
resource:
|
||||
cameras: /artemis/api/resource/v1/cameras
|
||||
#视频能力
|
||||
video:
|
||||
previewUrls: /artemis/api/video/v2/cameras/previewURLs
|
||||
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
|
@ -240,4 +240,18 @@ zn:
|
||||
is_simulation: false # 是否为仿真环境
|
||||
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
|
||||
restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始
|
||||
synchronous_all_map_node: 500 # 点位信息每次发送的数据量
|
||||
|
||||
#海康威视的相关配置
|
||||
isc:
|
||||
previewUrl: https://api.znkj.ispt.com.cn
|
||||
host: 111.75.51.123:10443
|
||||
appKey: 24991430
|
||||
appSecret: jQd4pIYZBzwW8cnuI9IN
|
||||
#视频资源
|
||||
resource:
|
||||
cameras: /artemis/api/resource/v1/cameras
|
||||
#视频能力
|
||||
video:
|
||||
previewUrls: /artemis/api/video/v2/cameras/previewURLs
|
||||
replayUrlApi: /artemis/api/video/v2/cameras/playbackURLs
|
Loading…
Reference in New Issue
Block a user