opt:完善地图相关数据和基础数据

This commit is contained in:
2025-07-25 09:45:12 +08:00
parent ae4feca5b3
commit 76c308ba84
27 changed files with 476 additions and 173 deletions

View File

@@ -23,6 +23,11 @@ public class MapInfo {
*/ */
private String mapName; private String mapName;
/**
* 地图图片地址
*/
private String mapImageAddress;
/** /**
* 图片像素宽 * 图片像素宽
*/ */

View File

@@ -4,6 +4,7 @@ import org.nl.apt15e.apt.map.dao.MapInfo;
import org.nl.apt15e.apt.map.service.MapInfoService; import org.nl.apt15e.apt.map.service.MapInfoService;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -21,8 +22,8 @@ public class MapInfoController {
@Resource @Resource
private MapInfoService mapInfoService; private MapInfoService mapInfoService;
@RequestMapping("/getMapInfoByCode") @GetMapping("/getMapInfoByCode")
public ResponseEntity<Object> getMapInfoByCode(@RequestParam("mapCode") String mapCode) { public ResponseEntity<Object> getMapInfoByCode() {
return new ResponseEntity<>(mapInfoService.getMapInfoByCode(mapCode), HttpStatus.OK); return new ResponseEntity<>(mapInfoService.getMapInfoByCode(), HttpStatus.OK);
} }
} }

View File

@@ -4,12 +4,17 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.apt15e.apt.map.dao.MapInfo; import org.nl.apt15e.apt.map.dao.MapInfo;
import java.util.List;
/** /**
* @author dsh * @author dsh
* 2025/7/17 * 2025/7/17
*/ */
public interface MapInfoService extends IService<MapInfo> { public interface MapInfoService extends IService<MapInfo> {
JSONObject getMapInfoByCode(String mapCode); /**
* 返回当前正在使用的地图数据
*/
MapInfo getMapInfoByCode();
} }

View File

@@ -13,6 +13,8 @@ import org.nl.apt15e.common.BadRequestException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* @author dsh * @author dsh
* 2025/7/17 * 2025/7/17
@@ -22,13 +24,7 @@ import org.springframework.stereotype.Service;
public class MapInfoServiceImpl extends ServiceImpl<MapInfoMapper, MapInfo> implements MapInfoService { public class MapInfoServiceImpl extends ServiceImpl<MapInfoMapper, MapInfo> implements MapInfoService {
@Override @Override
public JSONObject getMapInfoByCode(String mapCode) { public MapInfo getMapInfoByCode() {
if (StrUtil.isEmpty(mapCode)) { return this.getOne(new LambdaQueryWrapper<>(MapInfo.class));
throw new BadRequestException("mapCode is null");
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", HttpStatus.OK.value());
jsonObject.put("data", this.getOne(new LambdaQueryWrapper<>(MapInfo.class).eq(MapInfo::getMapCode,mapCode)));
return jsonObject;
} }
} }

View File

@@ -51,11 +51,11 @@ public class RouteInfo {
/** /**
* 导航模式 前进模式, 后退模式 ,无头模式 * 导航模式 前进模式, 后退模式 ,无头模式
*/ */
private Integer navigation_mode; private String navigation_mode;
/** /**
* 路线类型 直行,转弯 * 路线类型 直行,转弯
*/ */
private Integer route_type; private String route_type;
} }

View File

@@ -4,11 +4,13 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.apt15e.apt.route.dao.RouteInfo; import org.nl.apt15e.apt.route.dao.RouteInfo;
import java.util.List;
/** /**
* @author dsh * @author dsh
* 2025/7/18 * 2025/7/18
*/ */
public interface RouteInfoService extends IService<RouteInfo> { public interface RouteInfoService extends IService<RouteInfo> {
JSONObject getAllRouteInfo(); List<RouteInfo> getAllRouteInfo();
} }

View File

@@ -12,6 +12,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
/** /**
* @author dsh * @author dsh
@@ -24,10 +25,7 @@ public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo
private RouteInfoMapper routeInfoMapper; private RouteInfoMapper routeInfoMapper;
@Override @Override
public JSONObject getAllRouteInfo() { public List<RouteInfo> getAllRouteInfo() {
JSONObject jsonObject = new JSONObject(); return routeInfoMapper.selectList(null);
jsonObject.put("code", HttpStatus.OK.value());
jsonObject.put("data", routeInfoMapper.selectList(null));
return jsonObject;
} }
} }

View File

@@ -3,6 +3,7 @@ package org.nl.apt15e.apt.route.service.rest;
import org.nl.apt15e.apt.route.service.RouteInfoService; import org.nl.apt15e.apt.route.service.RouteInfoService;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -19,7 +20,7 @@ public class RouteInfoController {
@Resource @Resource
private RouteInfoService routeInfoService; private RouteInfoService routeInfoService;
@RequestMapping("/getRouteInfo") @GetMapping("/getRouteInfo")
public ResponseEntity<Object> getRouteInfo(){ public ResponseEntity<Object> getRouteInfo(){
return new ResponseEntity<>(routeInfoService.getAllRouteInfo(), HttpStatus.OK); return new ResponseEntity<>(routeInfoService.getAllRouteInfo(), HttpStatus.OK);
} }

View File

@@ -12,18 +12,19 @@ import lombok.Getter;
public enum StationTypeEnum { public enum StationTypeEnum {
//站点类型 Station工位点 Charge充电点 Breaks休息点 Docking对接点 System系统自动生成点 //站点类型 Station工位点 Charge充电点 Breaks休息点 Docking对接点 System系统自动生成点
STATION(1, "STATION", "工位点"), STATION(1, "Station", "工位点"),
CHARGE(2, "CHARGE", "充电点"), CHARGE(2, "Charge", "充电点"),
BREAKS(3, "BREAKS", "休息点"), BREAKS(3, "Breaks", "休息点"),
DOCKING(4, "DOCKING", "对接点"), DOCKING(4, "Docking", "对接点"),
SYSTEM(5, "SYSTEM", "系统自动生成点"), SYSTEM(5, "System", "系统自动生成点"),
//动作类型 Ascend升叉 Descend降叉 Move移动 Customize自定义 //动作类型 Ascend升叉 Descend降叉 Move移动 Customize自定义 Return返回
ASCEND(1, "Ascend", "升叉"), ASCEND(1, "Ascend", "升叉"),
DESCEND(2, "Descend", "降叉"), DESCEND(2, "Descend", "降叉"),
MOVE(3, "Move", "移动"), MOVE(3, "Move", "移动"),
CUSTOMIZE(4, "Customize", "自定义"); CUSTOMIZE(4, "Customize", "自定义"),
RETURN(5, "Return", "返回");
/** /**

View File

@@ -35,7 +35,7 @@ public class Station implements Serializable {
private String station_type; private String station_type;
/** /**
* 动作类型 (Ascend升叉 Descend降叉 Move移动 Customize自定义) * 动作类型 (Ascend升叉 Descend降叉 Move移动 Customize自定义 Return返回)
*/ */
private String action_type; private String action_type;

View File

@@ -14,4 +14,7 @@ public interface StationService extends IService<Station> {
List<Station> queryAllStation(); List<Station> queryAllStation();
List<Station> queryMapAllStation();
Station queryStationById(Integer id);
} }

View File

@@ -27,7 +27,17 @@ public class StationServiceImpl extends ServiceImpl<StationMapper, Station> impl
@Override @Override
public List<Station> queryAllStation() { public List<Station> queryAllStation() {
return stationMapper.selectList(stationMapper.selectList(new LambdaQueryWrapper<>(Station.class) return stationMapper.selectList(new LambdaQueryWrapper<>(Station.class)
.eq(Station::getStation_type, StationTypeEnum.STATION.getCode()))); .eq(Station::getStation_type, StationTypeEnum.STATION.getCode()));
}
@Override
public List<Station> queryMapAllStation() {
return stationMapper.selectList(null);
}
@Override
public Station queryStationById(Integer id) {
return stationMapper.selectOne(new LambdaQueryWrapper<Station>().eq(Station::getStation_id, id));
} }
} }

View File

@@ -21,8 +21,17 @@ public class StationController {
private StationService stationService; private StationService stationService;
@GetMapping("/queryAllStation") @GetMapping("/queryAllStation")
private ResponseEntity<Object> startMapping() { private ResponseEntity<Object> queryAllStation() {
return new ResponseEntity<>(stationService.queryAllStation(), HttpStatus.OK); return new ResponseEntity<>(stationService.queryAllStation(), HttpStatus.OK);
} }
@GetMapping("/queryMapAllStation")
private ResponseEntity<Object> queryMapAllStation() {
return new ResponseEntity<>(stationService.queryMapAllStation(), HttpStatus.OK);
}
@GetMapping("/queryStationById")
private ResponseEntity<Object> queryStationById(@RequestParam("station_id") Integer station_id) {
return new ResponseEntity<>(stationService.queryStationById(station_id), HttpStatus.OK);
}
} }

View File

@@ -82,4 +82,9 @@ public class TeachingController {
private ResponseEntity<Object> oneClickDeployment(@RequestParam("mapName") String mapName) { private ResponseEntity<Object> oneClickDeployment(@RequestParam("mapName") String mapName) {
return new ResponseEntity<>(teachingService.oneClickDeployment(mapName), HttpStatus.OK); return new ResponseEntity<>(teachingService.oneClickDeployment(mapName), HttpStatus.OK);
} }
@PostMapping("/abandonMapping")
private ResponseEntity<Object> abandonMapping() {
return new ResponseEntity<>(teachingService.abandonMapping(),HttpStatus.OK);
}
} }

View File

@@ -86,4 +86,10 @@ public interface TeachingService {
* @return * @return
*/ */
Map<String, Object> oneClickDeployment(String mapName); Map<String, Object> oneClickDeployment(String mapName);
/**
* 放弃当前示教建图
* @return
*/
Map<String, Object> abandonMapping();
} }

View File

@@ -264,6 +264,8 @@ public class TeachingServiceImpl implements TeachingService {
if (response.isOk() && response.body() != null) { if (response.isOk() && response.body() != null) {
// 获取zip包 // 获取zip包
byte[] zipBytes = response.bodyBytes(); byte[] zipBytes = response.bodyBytes();
File fileName = new File(mapName);
File tempZipFile = FileUtil.writeBytes(zipBytes, FileUtil.createTempFile(fileName));
log.info("解析地图包数据"); log.info("解析地图包数据");
processZip.processZipResponse(zipBytes); processZip.processZipResponse(zipBytes);
return zipBytes; return zipBytes;
@@ -409,4 +411,34 @@ public class TeachingServiceImpl implements TeachingService {
// } // }
return response; return response;
} }
@Override
public Map<String, Object> abandonMapping() {
JSONObject params = new JSONObject();
String attach = "{"+
"'sub_command':0,"+
"'param':''"+
"}";
params.put("cmd", 906);
params.put("attach", JSON.parseObject(attach));
HttpResponse response = null;
try {
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/sendCMD", params);
} catch (Exception e) {
log.info("访问车体放弃示教建图接口报错:{}",e.getMessage());
throw new BadRequestException("车体放弃示教建图失败");
}
// 检查响应状态码
if (response.isOk() && response.body() != null) {
// 获取响应体内容
JSONObject body = JSON.parseObject(response.body());
log.info("放弃示教建图:{}",body);
if ("200".equals(body.getString("code"))){
body.put("message","放弃示教建图成功");
return body;
}
}
log.info("放弃示教建图失败");
throw new BadRequestException("放弃示教建图失败");
}
} }

View File

@@ -13,12 +13,15 @@ import org.nl.apt15e.apt.station.dao.Station;
import org.nl.apt15e.apt.station.service.StationService; import org.nl.apt15e.apt.station.service.StationService;
import org.nl.apt15e.apt.station.service.impl.StationServiceImpl; import org.nl.apt15e.apt.station.service.impl.StationServiceImpl;
import org.nl.apt15e.common.BadRequestException; import org.nl.apt15e.common.BadRequestException;
import org.nl.apt15e.config.file.FileProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte; import java.awt.image.DataBufferByte;
import java.io.*; import java.io.*;
@@ -48,9 +51,11 @@ public class ProcessZip {
@Resource @Resource
private RouteInfoService routeInfoService; private RouteInfoService routeInfoService;
@Resource
private FileProperties properties;
private static final String PGM_MAGIC_NUMBER = "P5"; private static final String PGM_MAGIC_NUMBER = "P5";
private static final String OUTPUT_DIR = "/logs";
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void processZipResponse(byte[] zipBytes) { public void processZipResponse(byte[] zipBytes) {
@@ -59,6 +64,11 @@ public class ProcessZip {
MapInfo mapInfo = new MapInfo(); MapInfo mapInfo = new MapInfo();
//存储之前先清除站点表中数据和路径表中的数据
stationService.remove(new LambdaQueryWrapper<>());
routeInfoService.remove(new LambdaQueryWrapper<>());
mapInfoService.remove(new LambdaQueryWrapper<>());
ZipEntry entry; ZipEntry entry;
// 遍历ZIP文件中的每个条目 // 遍历ZIP文件中的每个条目
while ((entry = zis.getNextEntry()) != null) { while ((entry = zis.getNextEntry()) != null) {
@@ -72,10 +82,6 @@ public class ProcessZip {
BufferedReader reader = new BufferedReader( BufferedReader reader = new BufferedReader(
new InputStreamReader(zis, StandardCharsets.UTF_8)); new InputStreamReader(zis, StandardCharsets.UTF_8));
//存储站点之前先清除站点表中数据和路径表中的数据
stationService.remove(new LambdaQueryWrapper<>());
routeInfoService.remove(new LambdaQueryWrapper<>());
String line; String line;
int lineNumber = 0; int lineNumber = 0;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
@@ -110,11 +116,15 @@ public class ProcessZip {
throw new BadRequestException("地图PGM转换失败: "); throw new BadRequestException("地图PGM转换失败: ");
} }
// 将灰度图转换为透明背景图
pngImage = convertToTransparentBackground(pngImage);
// 保存PNG文件 // 保存PNG文件
String pngFileName = entryName.substring(0, entryName.lastIndexOf('.')) + ".png"; String pngFileName = entryName.substring(0, entryName.lastIndexOf('.')) + ".png";
// 记录地图编码、名称 // 记录地图编码、名称
mapInfo.setMapCode(pngFileName); mapInfo.setMapCode(pngFileName);
mapInfo.setMapName(pngFileName); mapInfo.setMapName(pngFileName);
mapInfo.setMapImageAddress("/file/"+pngFileName);
savePngImage(pngImage, pngFileName); savePngImage(pngImage, pngFileName);
} }
} }
@@ -173,6 +183,71 @@ public class ProcessZip {
} }
} }
// 将灰度图像转换为透明背景图像
private BufferedImage convertToTransparentBackground(BufferedImage grayImage) {
try {
// 创建支持透明度的ARGB图像
BufferedImage transparentImage = new BufferedImage(
grayImage.getWidth(),
grayImage.getHeight(),
BufferedImage.TYPE_INT_ARGB
);
// 获取灰度图像的像素数据
byte[] grayPixels = ((DataBufferByte) grayImage.getRaster().getDataBuffer()).getData();
int width = grayImage.getWidth();
int height = grayImage.getHeight();
// 创建ARGB像素数组
int[] argbPixels = new int[width * height];
// // 转换每个像素
// for (int y = 0; y < height; y++) {
// for (int x = 0; x < width; x++) {
// int index = y * width + x;
// // 灰度值0-2550=黑255=白
// int grayValue = grayPixels[index] & 0xFF;
//
// // 创建ARGB像素Alpha, Red, Green, Blue
// // 白色背景(>=250设为完全透明其他保持黑色但完全不透明
// if (grayValue >= 250) {
// // 完全透明 (Alpha=0)
// argbPixels[index] = 0x00FFFFFF;
// } else {
// // 完全不透明 (Alpha=255) + 灰度值转为RGB
// int rgb = grayValue << 16 | grayValue << 8 | grayValue;
// argbPixels[index] = 0xFF000000 | rgb;
// }
// }
// }
// 转换每个像素
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int index = y * width + x;
// 灰度值0-2550=黑255=白
int grayValue = grayPixels[index] & 0xFF;
// 创建ARGB像素Alpha, Red, Green, Blue
if (grayValue >= 250) {
// 白色背景(>=250设为完全透明
argbPixels[index] = 0x00FFFFFF; // 透明
} else {
// 黑色点云转为白色点云(完全不透明)
argbPixels[index] = 0xFFFFFFFF; // 不透明的白色
}
}
}
// 设置ARGB像素数据
transparentImage.setRGB(0, 0, width, height, argbPixels, 0, width);
return transparentImage;
}catch (Exception e) {
log.info(".png点云图将灰度图像转换为透明背景图像失败:{}",e.getMessage());
throw new BadRequestException(".png点云图将灰度图像转换为透明背景图像失败:"+e.getMessage());
}
}
public void processLine(String line, int lineNumber) { public void processLine(String line, int lineNumber) {
// 跳过空行 // 跳过空行
if (line.trim().isEmpty()) { if (line.trim().isEmpty()) {
@@ -211,7 +286,7 @@ public class ProcessZip {
stationService.save(station); stationService.save(station);
System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, station); System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, station);
//Route路径标识 //Route路径标识
}else if ("Route".equals(processData[0]) && processData.length > 23){ }else if ("Route".equals(processData[0]) && processData.length >22 ){
System.out.printf("行号 %d - 有效路径数据: %s%n", lineNumber, Arrays.toString(processData)); System.out.printf("行号 %d - 有效路径数据: %s%n", lineNumber, Arrays.toString(processData));
RouteInfo routeInfo = new RouteInfo(); RouteInfo routeInfo = new RouteInfo();
routeInfo.setRoute_id(Integer.valueOf(processData[1])); routeInfo.setRoute_id(Integer.valueOf(processData[1]));
@@ -221,8 +296,8 @@ public class ProcessZip {
routeInfo.setStart_y(Double.valueOf(processData[5])); routeInfo.setStart_y(Double.valueOf(processData[5]));
routeInfo.setEnd_x(Double.valueOf(processData[6])); routeInfo.setEnd_x(Double.valueOf(processData[6]));
routeInfo.setEnd_y(Double.valueOf(processData[7])); routeInfo.setEnd_y(Double.valueOf(processData[7]));
routeInfo.setNavigation_mode(Integer.valueOf(processData[16])); routeInfo.setNavigation_mode(processData[16].replaceAll("^\"|\"$", ""));
routeInfo.setRoute_type(Integer.valueOf(processData[17])); routeInfo.setRoute_type(processData[17].replaceAll("^\"|\"$", ""));
routeInfoService.save(routeInfo); routeInfoService.save(routeInfo);
System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, routeInfo); System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, routeInfo);
@@ -287,7 +362,7 @@ public class ProcessZip {
private void savePngImage(BufferedImage image, String fileName) { private void savePngImage(BufferedImage image, String fileName) {
try { try {
// 确保输出目录存在 // 确保输出目录存在
File outputDir = new File(OUTPUT_DIR); File outputDir = new File(properties.getPath().getPath());
if (!outputDir.exists()) { if (!outputDir.exists()) {
outputDir.mkdirs(); outputDir.mkdirs();
} }

View File

@@ -55,7 +55,7 @@ public class VehicleInfo implements Serializable {
/** /**
* 电量 * 电量
*/ */
private Long batteryPower; private Double batteryPower;
/** /**
* 异常信息 * 异常信息
@@ -76,4 +76,9 @@ public class VehicleInfo implements Serializable {
* 车辆角度 * 车辆角度
*/ */
private Double theta; private Double theta;
/**
* 是否是手动模式
*/
private Boolean isManual;
} }

View File

@@ -10,4 +10,6 @@ public interface VehicleInfoService {
VehicleInfo getVehicleInfo(); VehicleInfo getVehicleInfo();
void setVehicleInfo(VehicleInfo vehicleInfo);
} }

View File

@@ -37,6 +37,11 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
return vehicleInfo; return vehicleInfo;
} }
@Override
public void setVehicleInfo(VehicleInfo vehicleInfo) {
}
@Async("asynchronousTasks") @Async("asynchronousTasks")
public void queryVehicleInfo() { public void queryVehicleInfo() {
HttpResponse response = null; HttpResponse response = null;
@@ -52,18 +57,17 @@ public class VehicleInfoServiceImpl implements VehicleInfoService {
} }
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
JSONObject data = jsonArray.getJSONObject(i); JSONObject data = jsonArray.getJSONObject(i);
vehicleInfo = JSONObject.toJavaObject(data, VehicleInfo.class); vehicleInfo.setId(data.getString("id"));
//电量 vehicleInfo.setName(data.getString("name"));
vehicleInfo.setBatteryPower(data.getLong("batteryPercentile")); vehicleInfo.setIp(data.getString("ip"));
vehicleInfo.setMapId(data.getLong("mapId"));
vehicleInfo.setMapName(data.getString("mapName"));
vehicleInfo.setStateId(data.getLong("stateId"));
vehicleInfo.setState(data.getString("state"));
vehicleInfo.setAreaId(data.getLong("areaId"));
//上报的异常信息 //上报的异常信息
VehicleException vehicleException = JSONObject.toJavaObject(data.getJSONObject("amrException"), VehicleException.class); VehicleException vehicleException = JSONObject.toJavaObject(data.getJSONObject("amrException"), VehicleException.class);
vehicleInfo.setExceptionInfo(vehicleException); vehicleInfo.setExceptionInfo(vehicleException);
//xytheta
JSONObject coordinate = data.getJSONObject("coordinate");
vehicleInfo.setX(coordinate.getDouble("x"));
vehicleInfo.setY(coordinate.getDouble("y"));
vehicleInfo.setTheta(coordinate.getDouble("theta"));
System.out.println("Response Body: " + data);
System.out.println("vehicleInfo: " + vehicleInfo); System.out.println("vehicleInfo: " + vehicleInfo);
} }
} else { } else {

View File

@@ -1,8 +1,11 @@
package org.nl.apt15e.config; package org.nl.apt15e.config;
import org.nl.apt15e.config.file.FileProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/** /**
@@ -10,7 +13,27 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
* 2025/7/14 * 2025/7/14
*/ */
@Configuration @Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer { public class CorsConfig implements WebMvcConfigurer {
/** 文件配置 */
private final FileProperties properties;
public CorsConfig(FileProperties properties) {
this.properties = properties;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
FileProperties.ElPath path = properties.getPath();
String avatarUtl = "file:" + path.getAvatar().replace("\\","/");
String pathUtl = "file:" + path.getPath().replace("\\","/");
registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0);
registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
}
@Override @Override
public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") registry.addMapping("/**")

View File

@@ -0,0 +1,45 @@
package org.nl.apt15e.config.file;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author dsh
* 2025/7/24
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "file")
public class FileProperties {
/** 文件大小限制 */
private Long maxSize;
/** 头像大小限制 */
private Long avatarMaxSize;
private ElPath mac;
private ElPath linux;
private ElPath windows;
public ElPath getPath(){
String os = System.getProperty("os.name");
if(os.toLowerCase().startsWith("win")) {
return windows;
} else if(os.toLowerCase().startsWith("mac")){
return mac;
}
return linux;
}
@Data
public static class ElPath{
private String path;
private String avatar;
}
}

View File

@@ -1,73 +1,111 @@
//package org.nl.apt15e.config.thread; package org.nl.apt15e.config.thread;
//
//import comm_protocol.Robottype; import comm_protocol.Robottype;
//import comm_protocol.Uidata; import comm_protocol.Uidata;
//import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component; import org.nl.apt15e.apt.vehicle.service.impl.VehicleInfoServiceImpl;
//import org.springframework.web.socket.BinaryMessage; import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.socket.CloseStatus; import org.springframework.scheduling.annotation.EnableScheduling;
//import org.springframework.web.socket.TextMessage; import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.web.socket.WebSocketSession; import org.springframework.stereotype.Component;
//import org.springframework.web.socket.handler.BinaryWebSocketHandler; import org.springframework.web.socket.BinaryMessage;
// import org.springframework.web.socket.CloseStatus;
//import static comm_protocol.Uidata.UiDatagram.ItemCase.*; import org.springframework.web.socket.TextMessage;
// import org.springframework.web.socket.WebSocketSession;
///** import org.springframework.web.socket.client.WebSocketConnectionManager;
// * @author dsh import org.springframework.web.socket.handler.BinaryWebSocketHandler;
// * 2025/7/9
// */ import javax.annotation.Resource;
//@Slf4j import java.util.concurrent.atomic.AtomicBoolean;
//@Component
//public class ProtobufWebSocketHandler extends BinaryWebSocketHandler { import static comm_protocol.Uidata.UiDatagram.ItemCase.*;
//
// @Override /**
// protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) { * @author dsh
// try { * 2025/7/9
// // 解析Protobuf数据 */
// byte[] payload = message.getPayload().array(); @Slf4j
// Uidata.UiDatagram datagram = Uidata.UiDatagram.parseFrom(payload); @Component
// @EnableScheduling
// switch (datagram.getItemCase()) { public class ProtobufWebSocketHandler extends BinaryWebSocketHandler {
// case ONLINE_INFO:
// Uidata.UiOnline online = datagram.getOnlineInfo(); private static Boolean isConnected = false;
// System.out.println("Received online_info: " + online); @Autowired
// break; private WebSocketConnectionManager connectionManager;
// private WebSocketSession currentSession;
// case HEARTBEAT:
// Uidata.UiHeartbeat heartbeat = datagram.getHeartbeat();
// System.out.println("Received heartbeat: " + heartbeat); @Override
// break; protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
// try {
// case LASER_SCAN: // 解析Protobuf数据
byte[] payload = message.getPayload().array();
Uidata.UiDatagram datagram = Uidata.UiDatagram.parseFrom(payload);
switch (datagram.getItemCase()) {
case ROBOT_BASE:
Robottype.RobotBase robotBase = datagram.getRobotBase();
// 电量
VehicleInfoServiceImpl.vehicleInfo.setBatteryPower(robotBase.getBatteryInfo().getSoc());
//xytheta
VehicleInfoServiceImpl.vehicleInfo.setX(robotBase.getLocate().getCurrentState().getX());
VehicleInfoServiceImpl.vehicleInfo.setY(robotBase.getLocate().getCurrentState().getY());
VehicleInfoServiceImpl.vehicleInfo.setTheta(robotBase.getLocate().getCurrentState().getTheta());
// 手自动模式
VehicleInfoServiceImpl.vehicleInfo.setIsManual(robotBase.getRobotInactive());
// System.out.println("vehicleInfo2: " + VehicleInfoServiceImpl.vehicleInfo);
break;
case HEARTBEAT:
Uidata.UiHeartbeat heartbeat = datagram.getHeartbeat();
System.out.println("Received heartbeat: " + heartbeat);
break;
case LASER_SCAN:
// Robottype.LaserData laser = datagram.getLaserScan(); // Robottype.LaserData laser = datagram.getLaserScan();
// System.out.println("Received laser_scan: " + laser); // System.out.println("Received laser_scan: " + laser.getScanList());
// break; break;
// }
// case IMAGE: } catch (Exception e) {
// // 处理图像数据 log.error("Error processing protobuf message", e);
// break; }
// }
// case CONTROL_SPEED:
// // 处理速度控制 @Override
// break; public void afterConnectionEstablished(WebSocketSession session) {
// log.info("Connected to WebSocket server: {}", session.getUri());
// case ITEM_NOT_SET: isConnected = true;
// System.err.println("UiDatagram item not set!"); currentSession = session;
// break; }
// }
// session.close(); @Override
// } catch (Exception e) { public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
// log.error("Error processing protobuf message", e); log.info("Connection closed: {}", status);
// } isConnected = false;
// } currentSession = null;
// }
// @Override
// public void afterConnectionEstablished(WebSocketSession session) { @Override
// log.info("Connected to WebSocket server: {}", session.getUri()); public void handleTransportError(WebSocketSession session, Throwable exception) {
// } log.info("传输错误: {}", exception.getMessage());
// isConnected = false;
// @Override currentSession = null;
// public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { }
// log.info("Connection closed: {}", status);
// } @Scheduled(fixedDelay = 5000)
//} public synchronized void reconnectTask() {
if (!isConnected) {
try {
log.info("websocket 正在进行重连..");
// 先停止当前连接(如果正在运行)
if (connectionManager.isRunning()) {
connectionManager.stop();
}
// 启动新连接
connectionManager.start();
}catch (Exception e) {
log.error("websocket重连失败:{}",e.getMessage());
}
}
}
}

View File

@@ -1,45 +1,52 @@
//package org.nl.apt15e.config.thread; package org.nl.apt15e.config.thread;
//
//import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
//import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
//import org.springframework.stereotype.Component; import org.springframework.scheduling.annotation.EnableScheduling;
//import org.springframework.web.socket.client.WebSocketClient; import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.web.socket.client.WebSocketConnectionManager; import org.springframework.stereotype.Component;
//import org.springframework.web.socket.client.standard.StandardWebSocketClient; import org.springframework.web.socket.WebSocketHandler;
// import org.springframework.web.socket.client.WebSocketClient;
//import javax.websocket.ContainerProvider; import org.springframework.web.socket.client.WebSocketConnectionManager;
//import javax.websocket.WebSocketContainer; import org.springframework.web.socket.client.standard.StandardWebSocketClient;
//
///** import javax.annotation.PostConstruct;
// * @author dsh import javax.annotation.PreDestroy;
// * 2025/7/9 import javax.websocket.ContainerProvider;
// */ import javax.websocket.WebSocketContainer;
//@Slf4j
//@Configuration /**
//public class WebsocketClientConfig { * @author dsh
// * 2025/7/9
// @Bean */
// public WebSocketClient webSocketClient() { @Slf4j
// // 创建WebSocket容器并配置缓冲区大小 @Configuration
// WebSocketContainer container = ContainerProvider.getWebSocketContainer(); public class WebsocketClientConfig {
// // 256KB
// container.setDefaultMaxBinaryMessageBufferSize(100 * 1024); @Bean
// container.setDefaultMaxTextMessageBufferSize(100 * 1024); public WebSocketClient webSocketClient() {
// // 创建WebSocket容器并配置缓冲区大小
// return new StandardWebSocketClient(container); WebSocketContainer container = ContainerProvider.getWebSocketContainer();
// } // 256KB
// container.setDefaultMaxBinaryMessageBufferSize(100 * 1024);
// @Bean container.setDefaultMaxTextMessageBufferSize(100 * 1024);
// public WebSocketConnectionManager webSocketConnectionManager() {
// String serverUrl = "ws://192.168.100.82:9998/ws/AGVInfo"; return new StandardWebSocketClient(container);
// }
// WebSocketConnectionManager manager = new WebSocketConnectionManager(
// this.webSocketClient(), @Bean
// new ProtobufWebSocketHandler(), public WebSocketConnectionManager webSocketConnectionManager() {
// serverUrl String serverUrl = "ws://192.168.100.82:9998/ws/AGVInfo";
// );
// manager.setAutoStartup(true); WebSocketConnectionManager manager = new WebSocketConnectionManager(
// return manager; this.webSocketClient(),
// } new ProtobufWebSocketHandler(),
//} serverUrl
);
manager.setAutoStartup(false);
return manager;
}
}

View File

@@ -13,7 +13,7 @@ public class URLConstant {
/** /**
* RCS调度IP及端口 * RCS调度IP及端口
*/ */
public final static String RCS_IP_PORT = "127.0.0.1:8011"; public final static String RCS_IP_PORT = "192.168.100.82:8081";
/** /**
* 下发任务URL * 下发任务URL

View File

@@ -1,12 +1,12 @@
server: server:
# 端口 # 端口
port: 8081 port: 8011
spring: spring:
datasource: datasource:
druid: druid:
db-type: com.alibaba.druid.pool.DruidDataSource db-type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/apt_data?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false url: jdbc:mysql://localhost:3306/nl_apt15e?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false
username: root username: root
password: 123456 password: 123456
# 初始连接数 # 初始连接数
@@ -49,4 +49,19 @@ spring:
merge-sql: true merge-sql: true
wall: wall:
config: config:
multi-statement-allow: true multi-statement-allow: true
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
linux:
path: /home/eladmin/file/
avatar: /home/eladmin/avatar/
windows:
path: C:\eladmin\file\
avatar: C:\eladmin\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5

View File

@@ -49,4 +49,19 @@ spring:
merge-sql: true merge-sql: true
wall: wall:
config: config:
multi-statement-allow: true multi-statement-allow: true
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
linux:
path: /home/eladmin/file/
avatar: /home/eladmin/avatar/
windows:
path: C:\eladmin\file\
avatar: C:\eladmin\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5