diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java index 50b508e..c0fd233 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java @@ -18,10 +18,7 @@ import com.casic.missiles.modular.robot.model.RouteInfo; import com.casic.missiles.modular.robot.model.TaskInfo; import com.casic.missiles.modular.robot.opt.instruct.dto.StartTrackRequest; -import com.casic.missiles.modular.robot.service.IAlarmRecordService; -import com.casic.missiles.modular.robot.service.IRobotStatusInfoService; -import com.casic.missiles.modular.robot.service.IRouteInfoService; -import com.casic.missiles.modular.robot.service.ITaskInfoService; +import com.casic.missiles.modular.robot.service.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,12 +42,14 @@ private final IRobotStatusInfoService statusInfoService; private final AbstractDictService dictService; private final IAlarmRecordService recordService; + private final ITaskHeatMapService taskHeatMapService; - public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService) { + public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService, @Lazy ITaskHeatMapService taskHeatMapService) { this.routeInfoService = routeInfoService; this.statusInfoService = statusInfoService; this.dictService = dictService; this.recordService = recordService; + this.taskHeatMapService = taskHeatMapService; } @Override @@ -58,6 +57,7 @@ return this.baseMapper.selectTaskInfoPage(page, query); } + @Transactional @Override public TaskInfo getById(Serializable id) { TaskInfo taskInfo = super.getById(id); @@ -65,6 +65,7 @@ return taskInfo; } + @Transactional @Override public > E page(E page, Wrapper queryWrapper) { E infoIPage = super.page(page, queryWrapper); @@ -78,6 +79,7 @@ taskInfo.setTaskStatusName(dictService.getDictNameByCode(RobotDictConstants.TASK_STATUS, taskInfo.getTaskType() + "")); //检索当前任务告警数量 taskInfo.setAlarmNum(recordService.selectCountByTaskId(taskInfo.getId(), taskInfo.getRobotId())); + taskInfo.setHeatMap(taskHeatMapService.getByTaskId(taskInfo.getId())); } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java index 50b508e..c0fd233 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java @@ -18,10 +18,7 @@ import com.casic.missiles.modular.robot.model.RouteInfo; import com.casic.missiles.modular.robot.model.TaskInfo; import com.casic.missiles.modular.robot.opt.instruct.dto.StartTrackRequest; -import com.casic.missiles.modular.robot.service.IAlarmRecordService; -import com.casic.missiles.modular.robot.service.IRobotStatusInfoService; -import com.casic.missiles.modular.robot.service.IRouteInfoService; -import com.casic.missiles.modular.robot.service.ITaskInfoService; +import com.casic.missiles.modular.robot.service.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,12 +42,14 @@ private final IRobotStatusInfoService statusInfoService; private final AbstractDictService dictService; private final IAlarmRecordService recordService; + private final ITaskHeatMapService taskHeatMapService; - public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService) { + public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService, @Lazy ITaskHeatMapService taskHeatMapService) { this.routeInfoService = routeInfoService; this.statusInfoService = statusInfoService; this.dictService = dictService; this.recordService = recordService; + this.taskHeatMapService = taskHeatMapService; } @Override @@ -58,6 +57,7 @@ return this.baseMapper.selectTaskInfoPage(page, query); } + @Transactional @Override public TaskInfo getById(Serializable id) { TaskInfo taskInfo = super.getById(id); @@ -65,6 +65,7 @@ return taskInfo; } + @Transactional @Override public > E page(E page, Wrapper queryWrapper) { E infoIPage = super.page(page, queryWrapper); @@ -78,6 +79,7 @@ taskInfo.setTaskStatusName(dictService.getDictNameByCode(RobotDictConstants.TASK_STATUS, taskInfo.getTaskType() + "")); //检索当前任务告警数量 taskInfo.setAlarmNum(recordService.selectCountByTaskId(taskInfo.getId(), taskInfo.getRobotId())); + taskInfo.setHeatMap(taskHeatMapService.getByTaskId(taskInfo.getId())); } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java new file mode 100644 index 0000000..a248484 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java @@ -0,0 +1,61 @@ +package com.casic.missiles.modular.robot.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class AlgorithmUtils { + + /** + * 方法执行体 + * + * @param params + */ + public static void invokeJob(List params) { + try { + BufferedReader br = null; + BufferedReader brError; + String line = null; + Process p = new ProcessBuilder(params).start(); + br = new BufferedReader(new InputStreamReader(p.getInputStream())); + brError = new BufferedReader(new InputStreamReader(p.getErrorStream())); + while ((line = br.readLine()) != null || (line = brError.readLine()) != null) { + //输出exe输出的信息以及错误信息 + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + //算法初始化调用 + String exePath = "D:\\casic\\dist\\" + "PathPlanning_init.exe"; + + ArrayList invocation = new ArrayList(); + invocation.add(exePath); + invocation.add(10 + ""); + invocation.add(10 + ""); + invocation.add("0.05"); + invocation.add("8"); + invocation.add("8"); + +// invokeJob(invocation); + + String planning = "D:\\casic\\dist\\" + "PathPlanning.exe"; + + ArrayList planInvocation = new ArrayList(); + planInvocation.add(planning); + planInvocation.add(5 + ""); + planInvocation.add(5 + ""); + planInvocation.add("1,1,0,1,1,1,1,1"); + planInvocation.add("0.05"); + planInvocation.add("10"); + planInvocation.add("10"); + + invokeJob(planInvocation); + + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java index 50b508e..c0fd233 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java @@ -18,10 +18,7 @@ import com.casic.missiles.modular.robot.model.RouteInfo; import com.casic.missiles.modular.robot.model.TaskInfo; import com.casic.missiles.modular.robot.opt.instruct.dto.StartTrackRequest; -import com.casic.missiles.modular.robot.service.IAlarmRecordService; -import com.casic.missiles.modular.robot.service.IRobotStatusInfoService; -import com.casic.missiles.modular.robot.service.IRouteInfoService; -import com.casic.missiles.modular.robot.service.ITaskInfoService; +import com.casic.missiles.modular.robot.service.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,12 +42,14 @@ private final IRobotStatusInfoService statusInfoService; private final AbstractDictService dictService; private final IAlarmRecordService recordService; + private final ITaskHeatMapService taskHeatMapService; - public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService) { + public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService, @Lazy ITaskHeatMapService taskHeatMapService) { this.routeInfoService = routeInfoService; this.statusInfoService = statusInfoService; this.dictService = dictService; this.recordService = recordService; + this.taskHeatMapService = taskHeatMapService; } @Override @@ -58,6 +57,7 @@ return this.baseMapper.selectTaskInfoPage(page, query); } + @Transactional @Override public TaskInfo getById(Serializable id) { TaskInfo taskInfo = super.getById(id); @@ -65,6 +65,7 @@ return taskInfo; } + @Transactional @Override public > E page(E page, Wrapper queryWrapper) { E infoIPage = super.page(page, queryWrapper); @@ -78,6 +79,7 @@ taskInfo.setTaskStatusName(dictService.getDictNameByCode(RobotDictConstants.TASK_STATUS, taskInfo.getTaskType() + "")); //检索当前任务告警数量 taskInfo.setAlarmNum(recordService.selectCountByTaskId(taskInfo.getId(), taskInfo.getRobotId())); + taskInfo.setHeatMap(taskHeatMapService.getByTaskId(taskInfo.getId())); } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java new file mode 100644 index 0000000..a248484 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java @@ -0,0 +1,61 @@ +package com.casic.missiles.modular.robot.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class AlgorithmUtils { + + /** + * 方法执行体 + * + * @param params + */ + public static void invokeJob(List params) { + try { + BufferedReader br = null; + BufferedReader brError; + String line = null; + Process p = new ProcessBuilder(params).start(); + br = new BufferedReader(new InputStreamReader(p.getInputStream())); + brError = new BufferedReader(new InputStreamReader(p.getErrorStream())); + while ((line = br.readLine()) != null || (line = brError.readLine()) != null) { + //输出exe输出的信息以及错误信息 + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + //算法初始化调用 + String exePath = "D:\\casic\\dist\\" + "PathPlanning_init.exe"; + + ArrayList invocation = new ArrayList(); + invocation.add(exePath); + invocation.add(10 + ""); + invocation.add(10 + ""); + invocation.add("0.05"); + invocation.add("8"); + invocation.add("8"); + +// invokeJob(invocation); + + String planning = "D:\\casic\\dist\\" + "PathPlanning.exe"; + + ArrayList planInvocation = new ArrayList(); + planInvocation.add(planning); + planInvocation.add(5 + ""); + planInvocation.add(5 + ""); + planInvocation.add("1,1,0,1,1,1,1,1"); + planInvocation.add("0.05"); + planInvocation.add("10"); + planInvocation.add("10"); + + invokeJob(planInvocation); + + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java new file mode 100644 index 0000000..624df1f --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.robot.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import cn.hutool.core.util.StrUtil; + + +/** + * 监测热力图对象VO + * + * @author lwh + * @date 2023-11-29 + */ +@Data +public class TaskHeatMapVO { + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "热力图" , dataType = "String") + private String repetition; + +public QueryWrapper genQuery() { +QueryWrapper query = new QueryWrapper<>(); +if (StrUtil.isNotEmpty(repetition)) { + query.eq("repetition",repetition); +} +return query; +}} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java index 50b508e..c0fd233 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java @@ -18,10 +18,7 @@ import com.casic.missiles.modular.robot.model.RouteInfo; import com.casic.missiles.modular.robot.model.TaskInfo; import com.casic.missiles.modular.robot.opt.instruct.dto.StartTrackRequest; -import com.casic.missiles.modular.robot.service.IAlarmRecordService; -import com.casic.missiles.modular.robot.service.IRobotStatusInfoService; -import com.casic.missiles.modular.robot.service.IRouteInfoService; -import com.casic.missiles.modular.robot.service.ITaskInfoService; +import com.casic.missiles.modular.robot.service.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,12 +42,14 @@ private final IRobotStatusInfoService statusInfoService; private final AbstractDictService dictService; private final IAlarmRecordService recordService; + private final ITaskHeatMapService taskHeatMapService; - public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService) { + public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService, @Lazy ITaskHeatMapService taskHeatMapService) { this.routeInfoService = routeInfoService; this.statusInfoService = statusInfoService; this.dictService = dictService; this.recordService = recordService; + this.taskHeatMapService = taskHeatMapService; } @Override @@ -58,6 +57,7 @@ return this.baseMapper.selectTaskInfoPage(page, query); } + @Transactional @Override public TaskInfo getById(Serializable id) { TaskInfo taskInfo = super.getById(id); @@ -65,6 +65,7 @@ return taskInfo; } + @Transactional @Override public > E page(E page, Wrapper queryWrapper) { E infoIPage = super.page(page, queryWrapper); @@ -78,6 +79,7 @@ taskInfo.setTaskStatusName(dictService.getDictNameByCode(RobotDictConstants.TASK_STATUS, taskInfo.getTaskType() + "")); //检索当前任务告警数量 taskInfo.setAlarmNum(recordService.selectCountByTaskId(taskInfo.getId(), taskInfo.getRobotId())); + taskInfo.setHeatMap(taskHeatMapService.getByTaskId(taskInfo.getId())); } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java new file mode 100644 index 0000000..a248484 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java @@ -0,0 +1,61 @@ +package com.casic.missiles.modular.robot.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class AlgorithmUtils { + + /** + * 方法执行体 + * + * @param params + */ + public static void invokeJob(List params) { + try { + BufferedReader br = null; + BufferedReader brError; + String line = null; + Process p = new ProcessBuilder(params).start(); + br = new BufferedReader(new InputStreamReader(p.getInputStream())); + brError = new BufferedReader(new InputStreamReader(p.getErrorStream())); + while ((line = br.readLine()) != null || (line = brError.readLine()) != null) { + //输出exe输出的信息以及错误信息 + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + //算法初始化调用 + String exePath = "D:\\casic\\dist\\" + "PathPlanning_init.exe"; + + ArrayList invocation = new ArrayList(); + invocation.add(exePath); + invocation.add(10 + ""); + invocation.add(10 + ""); + invocation.add("0.05"); + invocation.add("8"); + invocation.add("8"); + +// invokeJob(invocation); + + String planning = "D:\\casic\\dist\\" + "PathPlanning.exe"; + + ArrayList planInvocation = new ArrayList(); + planInvocation.add(planning); + planInvocation.add(5 + ""); + planInvocation.add(5 + ""); + planInvocation.add("1,1,0,1,1,1,1,1"); + planInvocation.add("0.05"); + planInvocation.add("10"); + planInvocation.add("10"); + + invokeJob(planInvocation); + + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java new file mode 100644 index 0000000..624df1f --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.robot.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import cn.hutool.core.util.StrUtil; + + +/** + * 监测热力图对象VO + * + * @author lwh + * @date 2023-11-29 + */ +@Data +public class TaskHeatMapVO { + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "热力图" , dataType = "String") + private String repetition; + +public QueryWrapper genQuery() { +QueryWrapper query = new QueryWrapper<>(); +if (StrUtil.isNotEmpty(repetition)) { + query.eq("repetition",repetition); +} +return query; +}} diff --git a/casic-web/src/main/resources/config/application.yml b/casic-web/src/main/resources/config/application.yml index b3c29a0..0a3cc06 100644 --- a/casic-web/src/main/resources/config/application.yml +++ b/casic-web/src/main/resources/config/application.yml @@ -39,6 +39,9 @@ no-login-urls: /user/login,/kaptcha,/config/baseConfig hikSdk: D:\code\robot\casic-robot-inspection\casic-web\src\main\resources\config\hiklib\HCNetSDK.dll hikPlay: D:\code\robot\casic-robot-inspection\casic-web\src\main\resources\config\hiklib\PlayCtrl.dll + algorithm: + initPath: D:\workspace\server\keti\casic-robot-inspection\casic-web\src\main\resources\config\path\PathPlanning_init.exe + planPath: D:\workspace\server\keti\casic-robot-inspection\casic-web\src\main\resources\config\path\PathPlanning.exe config: export-path: D:\java\boot\guns-web-1.0.0-SNAPSHOT\export\ config-path: E:\Develop\IdeaProject\smartcity\casic-smartcity-dcms\casic-web\src\main\resources\config\ diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java index 50b508e..c0fd233 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java @@ -18,10 +18,7 @@ import com.casic.missiles.modular.robot.model.RouteInfo; import com.casic.missiles.modular.robot.model.TaskInfo; import com.casic.missiles.modular.robot.opt.instruct.dto.StartTrackRequest; -import com.casic.missiles.modular.robot.service.IAlarmRecordService; -import com.casic.missiles.modular.robot.service.IRobotStatusInfoService; -import com.casic.missiles.modular.robot.service.IRouteInfoService; -import com.casic.missiles.modular.robot.service.ITaskInfoService; +import com.casic.missiles.modular.robot.service.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,12 +42,14 @@ private final IRobotStatusInfoService statusInfoService; private final AbstractDictService dictService; private final IAlarmRecordService recordService; + private final ITaskHeatMapService taskHeatMapService; - public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService) { + public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService, @Lazy ITaskHeatMapService taskHeatMapService) { this.routeInfoService = routeInfoService; this.statusInfoService = statusInfoService; this.dictService = dictService; this.recordService = recordService; + this.taskHeatMapService = taskHeatMapService; } @Override @@ -58,6 +57,7 @@ return this.baseMapper.selectTaskInfoPage(page, query); } + @Transactional @Override public TaskInfo getById(Serializable id) { TaskInfo taskInfo = super.getById(id); @@ -65,6 +65,7 @@ return taskInfo; } + @Transactional @Override public > E page(E page, Wrapper queryWrapper) { E infoIPage = super.page(page, queryWrapper); @@ -78,6 +79,7 @@ taskInfo.setTaskStatusName(dictService.getDictNameByCode(RobotDictConstants.TASK_STATUS, taskInfo.getTaskType() + "")); //检索当前任务告警数量 taskInfo.setAlarmNum(recordService.selectCountByTaskId(taskInfo.getId(), taskInfo.getRobotId())); + taskInfo.setHeatMap(taskHeatMapService.getByTaskId(taskInfo.getId())); } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java new file mode 100644 index 0000000..a248484 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java @@ -0,0 +1,61 @@ +package com.casic.missiles.modular.robot.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class AlgorithmUtils { + + /** + * 方法执行体 + * + * @param params + */ + public static void invokeJob(List params) { + try { + BufferedReader br = null; + BufferedReader brError; + String line = null; + Process p = new ProcessBuilder(params).start(); + br = new BufferedReader(new InputStreamReader(p.getInputStream())); + brError = new BufferedReader(new InputStreamReader(p.getErrorStream())); + while ((line = br.readLine()) != null || (line = brError.readLine()) != null) { + //输出exe输出的信息以及错误信息 + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + //算法初始化调用 + String exePath = "D:\\casic\\dist\\" + "PathPlanning_init.exe"; + + ArrayList invocation = new ArrayList(); + invocation.add(exePath); + invocation.add(10 + ""); + invocation.add(10 + ""); + invocation.add("0.05"); + invocation.add("8"); + invocation.add("8"); + +// invokeJob(invocation); + + String planning = "D:\\casic\\dist\\" + "PathPlanning.exe"; + + ArrayList planInvocation = new ArrayList(); + planInvocation.add(planning); + planInvocation.add(5 + ""); + planInvocation.add(5 + ""); + planInvocation.add("1,1,0,1,1,1,1,1"); + planInvocation.add("0.05"); + planInvocation.add("10"); + planInvocation.add("10"); + + invokeJob(planInvocation); + + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java new file mode 100644 index 0000000..624df1f --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.robot.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import cn.hutool.core.util.StrUtil; + + +/** + * 监测热力图对象VO + * + * @author lwh + * @date 2023-11-29 + */ +@Data +public class TaskHeatMapVO { + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "热力图" , dataType = "String") + private String repetition; + +public QueryWrapper genQuery() { +QueryWrapper query = new QueryWrapper<>(); +if (StrUtil.isNotEmpty(repetition)) { + query.eq("repetition",repetition); +} +return query; +}} diff --git a/casic-web/src/main/resources/config/application.yml b/casic-web/src/main/resources/config/application.yml index b3c29a0..0a3cc06 100644 --- a/casic-web/src/main/resources/config/application.yml +++ b/casic-web/src/main/resources/config/application.yml @@ -39,6 +39,9 @@ no-login-urls: /user/login,/kaptcha,/config/baseConfig hikSdk: D:\code\robot\casic-robot-inspection\casic-web\src\main\resources\config\hiklib\HCNetSDK.dll hikPlay: D:\code\robot\casic-robot-inspection\casic-web\src\main\resources\config\hiklib\PlayCtrl.dll + algorithm: + initPath: D:\workspace\server\keti\casic-robot-inspection\casic-web\src\main\resources\config\path\PathPlanning_init.exe + planPath: D:\workspace\server\keti\casic-robot-inspection\casic-web\src\main\resources\config\path\PathPlanning.exe config: export-path: D:\java\boot\guns-web-1.0.0-SNAPSHOT\export\ config-path: E:\Develop\IdeaProject\smartcity\casic-smartcity-dcms\casic-web\src\main\resources\config\ diff --git a/casic-web/src/main/resources/config/path/PathPlanning.exe b/casic-web/src/main/resources/config/path/PathPlanning.exe new file mode 100644 index 0000000..fa6af4b --- /dev/null +++ b/casic-web/src/main/resources/config/path/PathPlanning.exe Binary files differ diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java index 427a6d9..ab67fac 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/controller/RouteInfoController.java @@ -6,13 +6,16 @@ import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; import com.casic.missiles.model.response.dto.ResponseDataDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; import com.casic.missiles.modular.robot.model.RouteInfo; +import com.casic.missiles.modular.robot.service.IAlgorithmService; import com.casic.missiles.modular.robot.service.IRouteInfoService; import com.casic.missiles.modular.robot.vo.RouteInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.List; /** @@ -21,20 +24,38 @@ * @author lwh * @date 2023-10-30 */ -@Api(tags = "线路信息管理(其他信息待定)") +@Api(tags = "线路信息管理") @RestController @RequestMapping("/robot/routeInfo") public class RouteInfoController extends BaseController { private final IRouteInfoService routeInfoService; + private final IAlgorithmService algorithmService; - public RouteInfoController(IRouteInfoService routeInfoService) { + public RouteInfoController(IRouteInfoService routeInfoService, IAlgorithmService algorithmService) { this.routeInfoService = routeInfoService; + this.algorithmService = algorithmService; } /** * 线路信息管理(其他信息待定)列表 */ + @ApiOperation(value = "测试", hidden = true) + @GetMapping(value = "/test") + public ResponseDataDTO> test(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.pathPlanningInit(pathInitDTO)); + } + /** + * 线路信息管理(其他信息待定)列表 + */ + @ApiOperation(value = "栅格转换", hidden = true) + @GetMapping(value = "/testGrid") + public ResponseDataDTO> testGrid(@RequestBody PathInitDTO pathInitDTO) { + return ResponseDataDTO.success(algorithmService.convertSlamToGrid(new BigDecimal(pathInitDTO.getX()),new BigDecimal(pathInitDTO.getY()),10,new BigDecimal(4))); + } + /** + * 线路信息管理(其他信息待定)列表 + */ @ApiOperation(value = "列表查询") @GetMapping(value = "/list") public ResponseDataDTO> list(RouteInfoVO routeInfoVO) { @@ -45,7 +66,7 @@ /** * 线路信息管理(其他信息待定)分页列表 */ - @ApiOperation(value = "分页查询" , hidden = true) + @ApiOperation(value = "分页查询", hidden = true) @GetMapping(value = "/listPage") public ResponseDataDTO> listPage(RouteInfoVO routeInfoVO) { Page page = PageFactory.defaultPage(); @@ -57,7 +78,7 @@ /** * 新增线路信息管理(其他信息待定) */ - @ApiOperation(value = "新增接口" , hidden = true) + @ApiOperation(value = "新增接口", hidden = true) @PostMapping(value = "/add") public ResponseDataDTO add(@RequestBody RouteInfo routeInfo) { routeInfoService.save(routeInfo); @@ -67,7 +88,7 @@ /** * 修改线路信息管理(其他信息待定) */ - @ApiOperation(value = "修改接口" , hidden = true) + @ApiOperation(value = "修改接口", hidden = true) @PostMapping(value = "/update") public ResponseDataDTO update(@RequestBody RouteInfo routeInfo) { routeInfoService.updateById(routeInfo); @@ -87,7 +108,7 @@ /** * 线路信息管理(其他信息待定)详情 */ - @ApiOperation(value = "详情查询" , hidden = true) + @ApiOperation(value = "详情查询", hidden = true) @GetMapping(value = "/detail") public ResponseDataDTO detail(String id) { return ResponseDataDTO.success(routeInfoService.getById(id)); diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java new file mode 100644 index 0000000..86ecf67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/TaskHeatMapMapper.java @@ -0,0 +1,25 @@ +package com.casic.missiles.modular.robot.dao; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 监测热力图 Mapper 接口 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface TaskHeatMapMapper extends BaseMapper { + /** + * 监测热力图 分页检索 + */ + List selectTaskHeatMapPage(@Param("page") Page page, @Param("ew") QueryWrapper query); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml new file mode 100644 index 0000000..2707ec8 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dao/mapping/TaskHeatMapMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + id + , + create_time as createTime , + update_time as updateTime , + repetition + + + a + . + id + , + a.create_time + as createTime , + a.update_time + as updateTime , + a.repetition + + + + + + and repetition = #{request.repetition} + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java new file mode 100644 index 0000000..749f559 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/AlgorithmResponse.java @@ -0,0 +1,16 @@ +package com.casic.missiles.modular.robot.dto; + +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import lombok.Data; + +@Data +public class AlgorithmResponse { + /** + * 热力数据 + */ + private TaskHeatMap taskHeatMap; + /** + * 规划点位信息 + */ + private PointNextDTO pointNextDTO; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java new file mode 100644 index 0000000..e9fb527 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/GridPointDTO.java @@ -0,0 +1,11 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GridPointDTO { + BigDecimal x; + BigDecimal y; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java new file mode 100644 index 0000000..8c88242 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathInitDTO.java @@ -0,0 +1,48 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathInitDTO { + //---------------------算法参数 + /** + * x坐标最大值(x方向栅格总数) + */ + private String xMax; + /** + * y坐标最大值(y方向栅格总数) + */ + private String yMax; + /** + * 初始位置计数率 + */ + private String count; + /** + * 初始位置x坐标(0<=x toArray() { + List list = new ArrayList<>(); + list.add(xMax); + list.add(yMax); + list.add(count); + list.add(x); + list.add(y); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java new file mode 100644 index 0000000..4112415 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PathPlanDTO.java @@ -0,0 +1,29 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 路线规划初始化DTO + */ +@Data +public class PathPlanDTO extends PathInitDTO { + + /** + * 长度为8的数组,记录(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1)8个坐标的可通行信息。 + * 若某坐标有障碍物(不可通行行)则记为0,否则记为1 + */ + private String open; + + public List toArray() { + List list = new ArrayList<>(); + list.add(getXMax()); + list.add(getYMax()); + list.add(getCount()); + list.add(getX()); + list.add(getY()); + return list; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java new file mode 100644 index 0000000..a29734d --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/PointNextDTO.java @@ -0,0 +1,12 @@ +package com.casic.missiles.modular.robot.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PointNextDTO { + private String x; + private String y; + private String z; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java index 955b8a5..0b6266a 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/dto/RobotInfoSetDTO.java @@ -1,5 +1,6 @@ package com.casic.missiles.modular.robot.dto; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,10 +17,13 @@ @ApiModelProperty(value = "设置角速度", dataType = "BigDecimal") private BigDecimal confW; - @ApiModelProperty(value = "阈值设定", dataType = "BigDecimal") private BigDecimal alarmThreshold; - @ApiModelProperty(value = "栅格设定", dataType = "BigDecimal") - private BigDecimal gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; } diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java index 7f30c44..985c7f9 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/RobotInfo.java @@ -124,9 +124,12 @@ @TableField("voltage_min") private Integer voltageMin; - @ApiModelProperty(value = "地图栅格设定", dataType = "Integer") - @TableField("grid_scale") - private Integer gridScale; + @ApiModelProperty(value = "栅格顶点值", dataType = "Integer") + @TableField("grid_size") + private BigDecimal gridSize; + @ApiModelProperty(value = "栅格数量", dataType = "Integer") + @TableField("grid_number") + private Integer gridNumber; @ApiModelProperty(value = "机器人云台信息", dataType = "Integer") @TableField(exist = false) diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java new file mode 100644 index 0000000..c6246fe --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskHeatMap.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.robot.model; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 监测热力图对象 task_heat_map + * + * @author lwh + * @date 2023-11-29 + */ +@Slf4j +@Data +@TableName("task_heat_map") +public class TaskHeatMap extends Model { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键", dataType = "Long") + @TableField("id") + private Long id; + + @ApiModelProperty(value = "创建时间", dataType = "Date") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty(value = "修改时间", dataType = "Date") + @TableField("update_time") + private Date updateTime; + + @ApiModelProperty(value = "热力图原始数据", dataType = "String") + @TableField("repetition") + private String repetition; + @ApiModelProperty(value = "任务id", dataType = "Long") + @TableField("task_id") + private Long taskId; + + @ApiModelProperty(value = "热力图数组", dataType = "String") + @TableField(exist = false) + private List> repetitionList; + + public List> getRepetitionList() { + if (CollectionUtil.isEmpty(repetitionList)) { + try { + if (StrUtil.isNotEmpty(repetition)) { + List strList = StrUtil.split(repetition.trim(), "\r\n"); + repetitionList = strList.stream().map(str -> { + List list = new ArrayList<>(); + for (String s : StrUtil.split(str, " ")) { + BigDecimal bigDecimal = new BigDecimal(s); + DecimalFormat decimalFormat = new DecimalFormat(); + String format = decimalFormat.format(bigDecimal); + list.add(format); + } + return list; + }).collect(Collectors.toList()); + } + } catch (Exception e) { + log.error("task_heat_map parse error,task_id:{}", taskId); + } + } + return repetitionList; + } + + @Override + public String toString() { + return "TaskHeatMap{" + + "id=" + id + + "createTime=" + createTime + + "updateTime=" + updateTime + + "repetition=" + repetition + + "}"; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java index 49e822a..4f5053c 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/model/TaskInfo.java @@ -123,6 +123,10 @@ @TableField(exist = false) private Integer alarmNum; + @ApiModelProperty(value = "热力图数据") + @TableField(exist = false) + private TaskHeatMap heatMap; + @Override public String toString() { return "TaskInfo{" diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java new file mode 100644 index 0000000..b570568 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/IAlgorithmService.java @@ -0,0 +1,33 @@ +package com.casic.missiles.modular.robot.service; + +import com.casic.missiles.modular.robot.dto.AlgorithmResponse; +import com.casic.missiles.modular.robot.dto.GridPointDTO; +import com.casic.missiles.modular.robot.dto.PathInitDTO; +import com.casic.missiles.modular.robot.dto.PathPlanDTO; + +import java.math.BigDecimal; + +/** + * 循迹算法调用 + */ +public interface IAlgorithmService { + + /** + * 寻源任务初始化 + */ + AlgorithmResponse pathPlanningInit(PathInitDTO initDTO); + + /** + * 寻源点位获取 + */ + AlgorithmResponse pathPlanning(PathPlanDTO planDTO); + + /** slam经纬度转换为 栅格坐标 + * @param x slam x + * @param y slam y + * @param gridNum 栅格总数 + * @param gridSize 栅格顶点经纬度 + * @return + */ + GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize); +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java new file mode 100644 index 0000000..e9e8744 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/ITaskHeatMapService.java @@ -0,0 +1,27 @@ +package com.casic.missiles.modular.robot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.List; + + +/** + *

+ * 监测热力图 服务类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +public interface ITaskHeatMapService extends IService { +/** +* 监测热力图 分页检索 +*/ +List selectTaskHeatMapPage(Page page,QueryWrapper query); + + void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap); + + TaskHeatMap getByTaskId(Long id); +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..a4882c7 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,151 @@ +package com.casic.missiles.modular.robot.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.modular.robot.dto.*; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.IAlgorithmService; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import com.casic.missiles.modular.robot.utils.AlgorithmUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 寻源算法调用 + */ +@Slf4j +@Service +public class AlgorithmServiceImpl implements IAlgorithmService { + @Value("${casic.algorithm.initPath:-1}") + private String initPath; + @Value("${casic.algorithm.planPath:-1}") + private String planPath; + private final ITaskHeatMapService heatMapService; + + public AlgorithmServiceImpl(ITaskHeatMapService heatMapService) { + this.heatMapService = heatMapService; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanningInit(PathInitDTO initDTO) { + //算法路径及入参配置 + List commends = new ArrayList<>(); + commends.add(initPath); + commends.addAll(initDTO.toArray()); + AlgorithmUtils.invokeJob(commends); + + File repetitionFile = new File("repetition.txt"); + //判断当前任务是否开启 + AlgorithmResponse response = new AlgorithmResponse(); + if (initDTO.getTaskId() != null && repetitionFile.exists()) { + readAlgorithmResponse("repetition.txt", response, initDTO.getTaskId()); + heatMapService.saveOrUpdateByTaskId(response.getTaskHeatMap()); + } else { + log.info("taskId is empty!"); + } + readAlgorithmResponse("xy_train.txt", response, initDTO.getTaskId()); + readAlgorithmResponse("z_train.txt", response, initDTO.getTaskId()); + return response; + } + + @Transactional + @Override + public AlgorithmResponse pathPlanning(PathPlanDTO planDTO) { + return null; + } + + /** + * 读取算法输出数据 + * + * @param fileName 文件名称 + * @param response 结果集 + * @param taskId 任务ID + */ + public void readAlgorithmResponse(String fileName, AlgorithmResponse response, Long taskId) { + File file = new File(fileName); + if (!file.exists()) { + log.info("{} file is empty!", fileName); + return; + } + if (response.getPointNextDTO() == null) { + response.setPointNextDTO(new PointNextDTO()); + } + switch (fileName) { + case "repetition.txt": + String msg = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + TaskHeatMap taskHeatMap = createEmptyTaskHeatMap(taskId); + taskHeatMap.setRepetition(msg); + response.setTaskHeatMap(taskHeatMap); + break; + case "xy_train.txt": + String xyTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(xyTrain)) { + xyTrain = StrUtil.removeAll(xyTrain, "\r\n"); + List list = StrUtil.split(xyTrain, " "); + if (list != null && list.size() == 2) { + response.getPointNextDTO().setX(formatBigDecimal(list.get(0))); + response.getPointNextDTO().setY(formatBigDecimal(list.get(1))); + } + } + break; + case "z_train.txt": + String zTrain = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8); + if (StrUtil.isNotEmpty(zTrain)) { + zTrain = StrUtil.removeAll(zTrain, "\r\n"); + response.getPointNextDTO().setZ(formatBigDecimal(zTrain)); + } + break; + } + } + + /** + * slam经纬度转换为栅格 + * + * @param x slam x + * @param y slam y + */ + @Override + public GridPointDTO convertSlamToGrid(BigDecimal x, BigDecimal y, Integer gridNum, BigDecimal gridSize) { + GridPointDTO pointDTO = new GridPointDTO(); + BigDecimal scale = gridSize.divide(new BigDecimal(gridNum), 5, BigDecimal.ROUND_HALF_UP); + pointDTO.setX(x.multiply(scale)); + pointDTO.setY(y.multiply(scale)); + return pointDTO; + } + + /** + * 数值格式化 + * + * @param str + * @return + */ + private String formatBigDecimal(String str) { + DecimalFormat decimalFormat = new DecimalFormat(); + return decimalFormat.format(new BigDecimal(str)); + } + + /** + * 热力图数据对象初始化 + * + * @param taskId 任务ID + * @return + */ + private TaskHeatMap createEmptyTaskHeatMap(Long taskId) { + TaskHeatMap taskHeatMap = new TaskHeatMap(); + taskHeatMap.setCreateTime(new Date()); + taskHeatMap.setUpdateTime(new Date()); + taskHeatMap.setTaskId(taskId); + return taskHeatMap; + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java index 63e10b3..c6ecaaa 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/RobotInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -68,24 +69,30 @@ wrapRobotInfo(robotInfo); return robotInfo; } - + @Transactional @Override public void updateSpeed(RobotInfoSetDTO robotInfo) { - UpdateWrapper update = new UpdateWrapper<>(); + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); if (robotInfo.getConfV() != null) { - update.set("conf_v", robotInfo.getConfV()); + update.set(RobotInfo::getConfV, robotInfo.getConfV()); } if (robotInfo.getConfW() != null) { - update.set("conf_w", robotInfo.getConfW()); + update.set(RobotInfo::getConfW, robotInfo.getConfW()); } if (robotInfo.getAlarmThreshold() != null) { - update.set("alarm_threshold", robotInfo.getAlarmThreshold()); + update.set(RobotInfo::getAlarmThreshold, robotInfo.getAlarmThreshold()); } - if (robotInfo.getGridScale() != null) { - update.set("grid_scale", robotInfo.getGridScale()); + if (robotInfo.getGridSize() != null) { + update.set(RobotInfo::getGridSize, robotInfo.getGridSize()); } - update.eq("id", robotInfo.getId()); + if (robotInfo.getGridNumber() != null) { + update.set(RobotInfo::getGridNumber, robotInfo.getGridNumber()); + } + update.eq(RobotInfo::getId, robotInfo.getId()); update(update); + + + } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java new file mode 100644 index 0000000..9339341 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskHeatMapServiceImpl.java @@ -0,0 +1,42 @@ +package com.casic.missiles.modular.robot.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.missiles.modular.robot.dao.TaskHeatMapMapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import com.casic.missiles.modular.robot.service.ITaskHeatMapService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + *

+ * 监测热力图 服务实现类 + *

+ * + * @author lwh + * @date 2023-11-29 + */ +@Service +public class TaskHeatMapServiceImpl extends ServiceImpl implements ITaskHeatMapService { + @Override + public List selectTaskHeatMapPage(Page page, QueryWrapper query) { + return this.baseMapper.selectTaskHeatMapPage(page, query); + } + + @Transactional + @Override + public void saveOrUpdateByTaskId(TaskHeatMap taskHeatMap) { + saveOrUpdate(taskHeatMap, new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, taskHeatMap.getTaskId())); + } + + @Transactional + @Override + public TaskHeatMap getByTaskId(Long id) { + return getOne(new LambdaQueryWrapper().eq(TaskHeatMap::getTaskId, id)); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java index 50b508e..c0fd233 100644 --- a/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/service/impl/TaskInfoServiceImpl.java @@ -18,10 +18,7 @@ import com.casic.missiles.modular.robot.model.RouteInfo; import com.casic.missiles.modular.robot.model.TaskInfo; import com.casic.missiles.modular.robot.opt.instruct.dto.StartTrackRequest; -import com.casic.missiles.modular.robot.service.IAlarmRecordService; -import com.casic.missiles.modular.robot.service.IRobotStatusInfoService; -import com.casic.missiles.modular.robot.service.IRouteInfoService; -import com.casic.missiles.modular.robot.service.ITaskInfoService; +import com.casic.missiles.modular.robot.service.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,12 +42,14 @@ private final IRobotStatusInfoService statusInfoService; private final AbstractDictService dictService; private final IAlarmRecordService recordService; + private final ITaskHeatMapService taskHeatMapService; - public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService) { + public TaskInfoServiceImpl(@Lazy IRouteInfoService routeInfoService, IRobotStatusInfoService statusInfoService, AbstractDictService dictService, @Lazy IAlarmRecordService recordService, @Lazy ITaskHeatMapService taskHeatMapService) { this.routeInfoService = routeInfoService; this.statusInfoService = statusInfoService; this.dictService = dictService; this.recordService = recordService; + this.taskHeatMapService = taskHeatMapService; } @Override @@ -58,6 +57,7 @@ return this.baseMapper.selectTaskInfoPage(page, query); } + @Transactional @Override public TaskInfo getById(Serializable id) { TaskInfo taskInfo = super.getById(id); @@ -65,6 +65,7 @@ return taskInfo; } + @Transactional @Override public > E page(E page, Wrapper queryWrapper) { E infoIPage = super.page(page, queryWrapper); @@ -78,6 +79,7 @@ taskInfo.setTaskStatusName(dictService.getDictNameByCode(RobotDictConstants.TASK_STATUS, taskInfo.getTaskType() + "")); //检索当前任务告警数量 taskInfo.setAlarmNum(recordService.selectCountByTaskId(taskInfo.getId(), taskInfo.getRobotId())); + taskInfo.setHeatMap(taskHeatMapService.getByTaskId(taskInfo.getId())); } @Transactional diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java new file mode 100644 index 0000000..a248484 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/utils/AlgorithmUtils.java @@ -0,0 +1,61 @@ +package com.casic.missiles.modular.robot.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class AlgorithmUtils { + + /** + * 方法执行体 + * + * @param params + */ + public static void invokeJob(List params) { + try { + BufferedReader br = null; + BufferedReader brError; + String line = null; + Process p = new ProcessBuilder(params).start(); + br = new BufferedReader(new InputStreamReader(p.getInputStream())); + brError = new BufferedReader(new InputStreamReader(p.getErrorStream())); + while ((line = br.readLine()) != null || (line = brError.readLine()) != null) { + //输出exe输出的信息以及错误信息 + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + //算法初始化调用 + String exePath = "D:\\casic\\dist\\" + "PathPlanning_init.exe"; + + ArrayList invocation = new ArrayList(); + invocation.add(exePath); + invocation.add(10 + ""); + invocation.add(10 + ""); + invocation.add("0.05"); + invocation.add("8"); + invocation.add("8"); + +// invokeJob(invocation); + + String planning = "D:\\casic\\dist\\" + "PathPlanning.exe"; + + ArrayList planInvocation = new ArrayList(); + planInvocation.add(planning); + planInvocation.add(5 + ""); + planInvocation.add(5 + ""); + planInvocation.add("1,1,0,1,1,1,1,1"); + planInvocation.add("0.05"); + planInvocation.add("10"); + planInvocation.add("10"); + + invokeJob(planInvocation); + + } +} \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java new file mode 100644 index 0000000..624df1f --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/robot/vo/TaskHeatMapVO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.robot.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.casic.missiles.modular.robot.model.TaskHeatMap; +import cn.hutool.core.util.StrUtil; + + +/** + * 监测热力图对象VO + * + * @author lwh + * @date 2023-11-29 + */ +@Data +public class TaskHeatMapVO { + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "热力图" , dataType = "String") + private String repetition; + +public QueryWrapper genQuery() { +QueryWrapper query = new QueryWrapper<>(); +if (StrUtil.isNotEmpty(repetition)) { + query.eq("repetition",repetition); +} +return query; +}} diff --git a/casic-web/src/main/resources/config/application.yml b/casic-web/src/main/resources/config/application.yml index b3c29a0..0a3cc06 100644 --- a/casic-web/src/main/resources/config/application.yml +++ b/casic-web/src/main/resources/config/application.yml @@ -39,6 +39,9 @@ no-login-urls: /user/login,/kaptcha,/config/baseConfig hikSdk: D:\code\robot\casic-robot-inspection\casic-web\src\main\resources\config\hiklib\HCNetSDK.dll hikPlay: D:\code\robot\casic-robot-inspection\casic-web\src\main\resources\config\hiklib\PlayCtrl.dll + algorithm: + initPath: D:\workspace\server\keti\casic-robot-inspection\casic-web\src\main\resources\config\path\PathPlanning_init.exe + planPath: D:\workspace\server\keti\casic-robot-inspection\casic-web\src\main\resources\config\path\PathPlanning.exe config: export-path: D:\java\boot\guns-web-1.0.0-SNAPSHOT\export\ config-path: E:\Develop\IdeaProject\smartcity\casic-smartcity-dcms\casic-web\src\main\resources\config\ diff --git a/casic-web/src/main/resources/config/path/PathPlanning.exe b/casic-web/src/main/resources/config/path/PathPlanning.exe new file mode 100644 index 0000000..fa6af4b --- /dev/null +++ b/casic-web/src/main/resources/config/path/PathPlanning.exe Binary files differ diff --git a/casic-web/src/main/resources/config/path/PathPlanning_init.exe b/casic-web/src/main/resources/config/path/PathPlanning_init.exe new file mode 100644 index 0000000..d89dc16 --- /dev/null +++ b/casic-web/src/main/resources/config/path/PathPlanning_init.exe Binary files differ