opt:1.下发任务路由校验。2.添加自动回退功能。3.添加AC闭环建图。

This commit is contained in:
2025-10-17 10:57:39 +08:00
parent affc17afbf
commit 7a464b65fb
17 changed files with 190 additions and 11 deletions

View File

@@ -2,9 +2,11 @@ package org.nl.apt15e.apt.station.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.apt15e.apt.dto.WebResponse;
import org.nl.apt15e.apt.station.dao.Station;
import java.util.List;
import java.util.Map;
/**
* @author dsh
@@ -17,4 +19,17 @@ public interface StationService extends IService<Station> {
List<Station> queryMapAllStation();
Station queryStationById(Integer id);
/**
* 获取返回点
* @return
*/
Station getReturnStation();
/**
* 更新休息点
* @param station_id
* @return
*/
WebResponse updateReturnStation(Integer station_id);
}

View File

@@ -1,14 +1,20 @@
package org.nl.apt15e.apt.station.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.apt15e.apt.dto.WebResponse;
import org.nl.apt15e.apt.station.StationTypeEnum;
import org.nl.apt15e.apt.station.dao.Station;
import org.nl.apt15e.apt.station.service.StationService;
import org.nl.apt15e.apt.station.service.mapper.StationMapper;
import org.nl.apt15e.common.BadRequestException;
import org.nl.apt15e.config.language.LangProcess;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Collections;
@@ -28,7 +34,7 @@ public class StationServiceImpl extends ServiceImpl<StationMapper, Station> impl
@Override
public List<Station> queryAllStation() {
return stationMapper.selectList(new LambdaQueryWrapper<>(Station.class)
.eq(Station::getStation_type, StationTypeEnum.STATION.getCode()));
.ne(Station::getStation_type, StationTypeEnum.SYSTEM.getCode()));
}
@Override
@@ -40,4 +46,38 @@ public class StationServiceImpl extends ServiceImpl<StationMapper, Station> impl
public Station queryStationById(Integer id) {
return stationMapper.selectOne(new LambdaQueryWrapper<Station>().eq(Station::getStation_id, id));
}
@Override
public Station getReturnStation() {
return stationMapper.selectOne(new LambdaQueryWrapper<Station>().eq(Station::getStation_type, StationTypeEnum.BREAKS.getCode()));
}
@Override
@Transactional(rollbackFor = Exception.class)
public WebResponse updateReturnStation(Integer station_id) {
if (ObjectUtil.isEmpty(station_id)) {
throw new BadRequestException(LangProcess.msg("param_is_null"));
}
Station station = this.getReturnStation();
boolean verify = false;
//当前存在返回点就先更新状态为工作点
if (ObjectUtil.isNotEmpty(station)){
station.setStation_type(StationTypeEnum.STATION.getCode());
station.setAction_type(StationTypeEnum.CUSTOMIZE.getCode());
verify = stationMapper.updateById(station)>0;
}
// 判断用户是否选择返回点
if (station_id != -1){
// 更新休息点
verify = stationMapper.update(new Station(),new LambdaUpdateWrapper<>(Station.class)
.set(Station::getStation_type,StationTypeEnum.BREAKS.getCode())
.set(Station::getAction_type,StationTypeEnum.RETURN.getCode())
.eq(Station::getStation_id,station_id)
) > 0;
}
if (!verify){
throw new BadRequestException(LangProcess.msg("failed"));
}
return WebResponse.requestOk();
}
}

View File

@@ -34,4 +34,14 @@ public class StationController {
private ResponseEntity<Object> queryStationById(@RequestParam("station_id") Integer station_id) {
return new ResponseEntity<>(stationService.queryStationById(station_id), HttpStatus.OK);
}
@GetMapping("/getReturnStation")
private ResponseEntity<Object> getReturnStation() {
return new ResponseEntity<>(stationService.getReturnStation(), HttpStatus.OK);
}
@PostMapping("/updateReturnStation")
private ResponseEntity<Object> updateReturnStation(@RequestParam("station_id") Integer station_id){
return new ResponseEntity<>(stationService.updateReturnStation(station_id), HttpStatus.OK);
}
}

View File

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.nl.apt15e.apt.dto.WebResponse;
import org.nl.apt15e.apt.station.StationTypeEnum;
import org.nl.apt15e.apt.station.dao.Station;
import org.nl.apt15e.apt.station.service.StationService;
import org.nl.apt15e.apt.task.enums.TaskStatus;
@@ -16,6 +17,7 @@ import org.nl.apt15e.apt.task.service.dao.Task;
import org.nl.apt15e.apt.taskOperate.service.TaskManageService;
import org.nl.apt15e.apt.taskchain.service.ITaskchainService;
import org.nl.apt15e.apt.taskchain.service.dao.Taskchain;
import org.nl.apt15e.apt.vehicle.service.impl.VehicleInfoServiceImpl;
import org.nl.apt15e.common.BadRequestException;
import org.nl.apt15e.config.language.LangProcess;
import org.nl.apt15e.util.HTTPUtil;
@@ -25,10 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -90,6 +89,24 @@ public class TaskManageServiceImpl implements TaskManageService {
staList.add(breakPoint);
}
// 当前叉腿载货状态(Ascend或者Descend)
// String currentType = VehicleInfoServiceImpl.vehicleInfo.getVehiclePayloads() == 1? StationTypeEnum.ASCEND.getCode():StationTypeEnum.DESCEND.getCode();
String currentType = Objects.equals(VehicleInfoServiceImpl.vehicleInfo.getVehiclePayloads(), 1)? StationTypeEnum.ASCEND.getCode():StationTypeEnum.DESCEND.getCode();
for (int i = 0; i < staList.size(); i++) {
String proposedAction = staList.get(i).getAction_type();
// 检查动作是否与当前动作相同
if (currentType.equals(proposedAction)) {
throw new BadRequestException(LangProcess.msg("task_cannot_be_enforced"));
}
// 只有升叉和降叉会改变当前状态
if (StationTypeEnum.ASCEND.getCode().equals(proposedAction) || StationTypeEnum.DESCEND.getCode().equals(proposedAction)) {
currentType = proposedAction;
}
}
// 任务id
String task_id = "";
// 组织任务下发

View File

@@ -102,4 +102,9 @@ public class TeachingController {
private ResponseEntity<Object> getMappingStatus() {
return new ResponseEntity<>(teachingService.getMappingStatus(), HttpStatus.OK);
}
@PostMapping("/sendAutoBack")
private ResponseEntity<Object> sendAutoBack() {
return new ResponseEntity<>(teachingService.sendAutoBack(), HttpStatus.OK);
}
}

View File

@@ -97,4 +97,9 @@ public interface TeachingService {
* 获取后台地图列表
*/
Map<String,String> getMappingStatus();
/**
* 打点后 自动回到上一个点
*/
Map<String,Object> sendAutoBack();
}

View File

@@ -416,7 +416,7 @@ public class TeachingServiceImpl implements TeachingService {
}
log.info("接收到本体重启信号,发送重定位指令");
Station station = stationService.getOne(new LambdaQueryWrapper<>(Station.class)
.eq(Station::getStation_code,"C")
.eq(Station::getStation_code,"A")
);
this.relocate(station.getX(),station.getY(),station.getAngle());
response.put("code", 200);
@@ -458,4 +458,34 @@ public class TeachingServiceImpl implements TeachingService {
public Map<String, String> getMappingStatus() {
return teachingMappingStatus;
}
@Override
public Map<String, Object> sendAutoBack() {
JSONObject params = new JSONObject();
String attach = "{"+
"'sub_command':0,"+
"'param':''"+
"}";
params.put("cmd", 2212);
params.put("attach", JSON.parseObject(attach));
HttpResponse response = null;
try {
response = HTTPUtil.post(URLConstant.VEHICLE_IP_PORT,"/tool/rob/sendCMD", params);
} catch (Exception e) {
log.info("访问车体自动返回上一个点接口报错:{}",e.getMessage());
throw new BadRequestException(LangProcess.msg("error_auto_back"));
}
// 检查响应状态码
if (response.isOk() && response.body() != null) {
// 获取响应体内容
JSONObject body = JSON.parseObject(response.body());
log.info("自动返回上一个点:{}",body);
if ("200".equals(body.getString("code"))){
body.put("message",LangProcess.msg("successful"));
return body;
}
}
log.info("自动返回上一个点失败");
throw new BadRequestException(LangProcess.msg("error_auto_back"));
}
}

View File

@@ -384,7 +384,7 @@ public class ProcessZip {
private void savePngImage(BufferedImage image, String fileName) {
try {
// 确保输出目录存在
// 确保-输出目录存在
File outputDir = new File(properties.getPath().getPath());
if (!outputDir.exists()) {
outputDir.mkdirs();

View File

@@ -114,4 +114,34 @@ public class VehicleInfo implements Serializable {
*/
private Integer anomalyLevel;
/**
* 打点后是否可以自动沿着路线开出来(0计算中 1失败 2成功)
*/
private String auto_back_enable;
/**
* 起点终点是否重叠,结束建图
*/
private String auto_loop_enable;
/**
* 自动回退状态(0未处理 1成功 2失败)
*/
private String auto_back_finish;
/**
* RCS调度连接状态
*/
private boolean rcsConnected;
/**
* 本体连接状态
*/
private boolean vehicleConnected;
/**
* 车辆载货状态 0未载货 1载货
*/
private Integer vehiclePayloads;
}

View File

@@ -29,6 +29,7 @@ import org.nl.apt15e.apt.websocket.WebSocketVehicleServer;
import org.nl.apt15e.common.BadRequestException;
import org.nl.apt15e.config.language.LangProcess;
import org.nl.apt15e.config.language.RcsLang;
import org.nl.apt15e.config.thread.ProtobufWebSocketHandler;
import org.nl.apt15e.system.enums.ParamCodeConstant;
import org.nl.apt15e.system.service.ParamService;
import org.nl.apt15e.util.HTTPUtil;
@@ -157,6 +158,7 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
@Async("asynchronousTasks")
public void queryVehicleInfo() {
HttpResponse response = null;
vehicleInfo.setRcsConnected(false);
try {
response = HTTPUtil.get(URLConstant.RCS_IP_PORT,"/amr/onlineAmr",null,"");
// 检查响应状态码
@@ -166,7 +168,10 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
JSONArray jsonArray = JSONObject.parseObject(body).getJSONArray("data");
if (jsonArray.isEmpty()) {
log.info("车辆数据为空");
return;
}
//调度连接状态
vehicleInfo.setRcsConnected(true);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject data = jsonArray.getJSONObject(i);
vehicleInfo.setId(data.getString("id"));
@@ -210,6 +215,7 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
public VehicleInfo queryVehicleInfoI18n(String lang,VehicleInfo vehicleInfo) {
HttpResponse response = null;
vehicleInfo.setRcsConnected(false);
try {
response = HTTPUtil.get(URLConstant.RCS_IP_PORT,"/amr/onlineAmr",null,RcsLang.getRcsLanguage(lang));
// 检查响应状态码
@@ -219,7 +225,9 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
JSONArray jsonArray = JSONObject.parseObject(body).getJSONArray("data");
if (jsonArray.isEmpty()) {
log.info("车辆数据为空");
return vehicleInfo;
}
vehicleInfo.setRcsConnected(true);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject data = jsonArray.getJSONObject(i);
vehicleInfo.setId(data.getString("id"));
@@ -271,7 +279,9 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
webSocketSet.forEach(c -> {
Map<String, Object> vehicleInfoMap = new HashMap<>();
VehicleInfo webVehicleInfo = vehicleInfo;
if (!"zh".equals(c.getLang())){
webVehicleInfo = this.queryVehicleInfoI18n(c.getLang(),webVehicleInfo);
}
vehicleInfoMap.put("data", webVehicleInfo);
c.sendDataToClient(vehicleInfoMap);
});

View File

@@ -54,6 +54,14 @@ public class ProtobufWebSocketHandler extends BinaryWebSocketHandler {
String mapping_return = data_pool.getString("mapping_return");
String mapping_percent = data_pool.getString("mapping_percent");
//打点后是否可以自动沿着路线开出来(0计算中 1失败 2成功)
VehicleInfoServiceImpl.vehicleInfo.setAuto_back_enable(data_pool.getString("auto_back_enable"));
//起点终点是否重叠,结束建图
VehicleInfoServiceImpl.vehicleInfo.setAuto_loop_enable(data_pool.getString("auto_loop_enable"));
// 自动回退状态标识 0 不处理 1 自动回退成功 2 自动回退失败
VehicleInfoServiceImpl.vehicleInfo.setAuto_back_finish(data_pool.getString("auto_back_finish"));
// 车辆载货状态 0未载货 1载货
VehicleInfoServiceImpl.vehicleInfo.setVehiclePayloads(robotBase.getPayloads());
String ready = data_pool.getString("ready");
TeachingServiceImpl.teachingMappingStatus.put("mapping_return", mapping_return);
TeachingServiceImpl.teachingMappingStatus.put("mapping_percent", mapping_percent);
@@ -121,6 +129,7 @@ public class ProtobufWebSocketHandler extends BinaryWebSocketHandler {
public void afterConnectionEstablished(WebSocketSession session) {
log.info("Connected to WebSocket server: {}", session.getUri());
isConnected = true;
VehicleInfoServiceImpl.vehicleInfo.setVehicleConnected(true);
currentSession = session;
}
@@ -128,6 +137,7 @@ public class ProtobufWebSocketHandler extends BinaryWebSocketHandler {
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
log.info("Connection closed: {}", status);
isConnected = false;
VehicleInfoServiceImpl.vehicleInfo.setVehicleConnected(false);
currentSession = null;
}
@@ -135,6 +145,7 @@ public class ProtobufWebSocketHandler extends BinaryWebSocketHandler {
public void handleTransportError(WebSocketSession session, Throwable exception) {
log.info("传输错误: {}", exception.getMessage());
isConnected = false;
VehicleInfoServiceImpl.vehicleInfo.setVehicleConnected(false);
currentSession = null;
}

View File

@@ -23,6 +23,7 @@ error_synchronized_map = 同步地图失败
error_relocate = 重定位指令下发失败
error_restart = 车体程序重启失败
error_abandon_mapping = 放弃建图失败
error_auto_back = 自动返回上一个点失败
error_restart_system = 重启系统失败
error_initializing_system = 初始化底层系统失败
error_set_forkLegs= 操作叉腿避障失败

View File

@@ -22,6 +22,7 @@ error_synchronized_map = Syncing maps failed
error_relocate = The relocation instruction failed to be issued
error_restart = The body program restarts failed
error_abandon_mapping = Abandoned mapping failed
error_auto_back = Automatically returning to the previous point failed
error_restart_system = Rebooting the system failed
error_initializing_system = Initializing the underlying system failed
error_set_forkLegs= The operation of the fork leg to avoid obstacles failed

View File

@@ -22,6 +22,7 @@ error_synchronized_map = 同步地图失败
error_relocate = 重定位指令下发失败
error_restart = 车体程序重启失败
error_abandon_mapping = 放弃建图失败
error_auto_back = 自动返回上一个点失败
error_restart_system = 重启系统失败
error_initializing_system = 初始化底层系统失败
error_set_forkLegs= 操作叉腿避障失败

View File

@@ -2,3 +2,4 @@ task_Id_isNull=任务不存在!【{0}】
task_Is_exist=当前有正在执行中的任务!
task_Is_not_exist=当前没有任务在执行中!
not_return_point = 没有返回点!
task_cannot_be_enforced = 任务链操作类型无法执行,请重新选择

View File

@@ -2,3 +2,4 @@ task_Id_isNull=The task with the task code of {0} was not found
task_Is_exist=There are tasks in progress!
task_Is_not_exist=No tasks are currently in progress!
not_return_point = There is no return point!
task_cannot_be_enforced = The task chain operation type cannot be executed, please select it again

View File

@@ -2,3 +2,4 @@ task_Id_isNull=未找到任务编码为{0}的任务
task_Is_exist=当前有正在执行中的任务!
task_Is_not_exist=当前没有任务在执行中!
not_return_point = 没有返回点!
task_cannot_be_enforced = 任务链操作类型无法执行,请重新选择