任务相关
This commit is contained in:
parent
cd9a97d39e
commit
cdfa6e3a8a
|
@ -14,6 +14,7 @@ import lombok.Getter;
|
||||||
public enum WsCmdTypeEnum {
|
public enum WsCmdTypeEnum {
|
||||||
PATH_UPDATE("path_update"),
|
PATH_UPDATE("path_update"),
|
||||||
PATH_FINISHED("path_finished"),
|
PATH_FINISHED("path_finished"),
|
||||||
|
STATISTIC("statistic"),
|
||||||
PATH_INIT("path_init");
|
PATH_INIT("path_init");
|
||||||
@Getter
|
@Getter
|
||||||
private final String code;
|
private final String code;
|
||||||
|
|
|
@ -1,9 +1,28 @@
|
||||||
package com.hivekion.room.bean;
|
package com.hivekion.room.bean;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.hivekion.Global;
|
||||||
|
import com.hivekion.baseData.entity.Scenario;
|
||||||
|
import com.hivekion.baseData.service.ScenarioService;
|
||||||
|
import com.hivekion.common.MultiPointGeoPosition;
|
||||||
|
import com.hivekion.common.entity.ResponseCmdInfo;
|
||||||
|
import com.hivekion.common.redis.RedisUtil;
|
||||||
|
import com.hivekion.enums.WsCmdTypeEnum;
|
||||||
import com.hivekion.room.RoomManager;
|
import com.hivekion.room.RoomManager;
|
||||||
import com.hivekion.room.func.TaskAction;
|
import com.hivekion.room.func.TaskAction;
|
||||||
import com.hivekion.scenario.entity.ScenarioTask;
|
import com.hivekion.scenario.entity.ScenarioTask;
|
||||||
import com.hivekion.statistic.bean.StatisticBean;
|
import com.hivekion.statistic.bean.StatisticBean;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
@ -11,6 +30,9 @@ import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,16 +44,26 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||||
* @author LiDongYU
|
* @author LiDongYU
|
||||||
* @since 2025/7/22
|
* @since 2025/7/22
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public abstract class AbtParentTask implements TaskAction {
|
public abstract class AbtParentTask implements TaskAction {
|
||||||
|
/**
|
||||||
|
* 开始点坐标
|
||||||
|
*/
|
||||||
|
private final AtomicReference<Double> startPoint = new AtomicReference<>();
|
||||||
|
/**
|
||||||
|
* 距离和坐标的对应关系
|
||||||
|
*/
|
||||||
|
protected final TreeMap<Double, Coordinate> distanceInfoMap = new TreeMap<>();
|
||||||
//任务数据
|
//任务数据
|
||||||
protected final ScenarioTask scenarioTask;
|
protected final ScenarioTask scenarioTask;
|
||||||
//房间ID
|
//房间ID
|
||||||
protected final String roomId;
|
protected final String roomId;
|
||||||
//http请求
|
//http请求
|
||||||
protected WebClient webClient = WebClient.create();
|
protected WebClient webClient = WebClient.create();
|
||||||
|
/**
|
||||||
|
* 任务相对与想定的开始时间
|
||||||
|
*/
|
||||||
|
private long taskRelativeTime = 0;
|
||||||
//线程池
|
//线程池
|
||||||
protected ThreadPoolExecutor executor = new ThreadPoolExecutor(
|
protected ThreadPoolExecutor executor = new ThreadPoolExecutor(
|
||||||
5, // 核心线程数
|
5, // 核心线程数
|
||||||
|
@ -46,7 +78,10 @@ public abstract class AbtParentTask implements TaskAction {
|
||||||
public AbtParentTask(ScenarioTask scenarioTask, String roomId) {
|
public AbtParentTask(ScenarioTask scenarioTask, String roomId) {
|
||||||
this.scenarioTask = scenarioTask;
|
this.scenarioTask = scenarioTask;
|
||||||
this.roomId = roomId;
|
this.roomId = roomId;
|
||||||
|
Scenario scenario = SpringUtil.getBean(ScenarioService.class)
|
||||||
|
.getScenarioById(scenarioTask.getScenarioId());
|
||||||
|
taskRelativeTime = Math.abs(
|
||||||
|
Duration.between(scenario.getStartTime(), scenarioTask.getStartTime()).getSeconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addScheduledExecutorServiceRefenceToRoom(
|
public void addScheduledExecutorServiceRefenceToRoom(
|
||||||
|
@ -89,9 +124,163 @@ public abstract class AbtParentTask implements TaskAction {
|
||||||
addScheduledExecutorServiceRefenceToRoom(schedule);
|
addScheduledExecutorServiceRefenceToRoom(schedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void pushStatistic() {
|
|
||||||
StatisticBean statisticBean = new StatisticBean();
|
protected void initPath(){
|
||||||
//获取分队信息
|
try {
|
||||||
|
|
||||||
|
String url = SpringUtil.getBean(Environment.class).getProperty("path.planning.url");
|
||||||
|
String params = url + "?"
|
||||||
|
+ "profile=car"
|
||||||
|
+ "&point=" + scenarioTask.getFromLat() + ","
|
||||||
|
+ scenarioTask.getFromLng()
|
||||||
|
+ "&point=" + scenarioTask.getToLat() + ","
|
||||||
|
+ scenarioTask.getToLng()
|
||||||
|
+ "&points_encoded=false"
|
||||||
|
+ "&algorithm=alternative_route&alternative_route.max_paths=3";
|
||||||
|
//获取路线信息
|
||||||
|
String result = webClient.get().uri(params)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.block();
|
||||||
|
|
||||||
|
JSONObject pointJson = JSON.parseObject(result);
|
||||||
|
//获取路径点
|
||||||
|
if (pointJson != null) {
|
||||||
|
JSONObject pointsObj = pointJson.getJSONArray("paths").getJSONObject(0)
|
||||||
|
.getJSONObject("points");
|
||||||
|
JSONArray coordinates = pointsObj.getJSONArray("coordinates");
|
||||||
|
//组装信息
|
||||||
|
Map<String, Object> dataMap = new HashMap<>();
|
||||||
|
dataMap.put("resourceId", scenarioTask.getResourceId());
|
||||||
|
dataMap.put("points", coordinates);
|
||||||
|
//推送路径任务
|
||||||
|
Global.sendCmdInfoQueue.add(
|
||||||
|
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_INIT.getCode(), roomId,
|
||||||
|
scenarioTask.getScenarioId(), dataMap));
|
||||||
|
|
||||||
|
SpringUtil.getBean(RedisUtil.class).hset(
|
||||||
|
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
"init_path", JSON.toJSONString(coordinates));
|
||||||
|
|
||||||
|
//计算各个点的累计距离和坐标的对应关系
|
||||||
|
double beforeLng = Double.parseDouble(scenarioTask.getFromLng());
|
||||||
|
double beforeLat = Double.parseDouble(scenarioTask.getFromLat());
|
||||||
|
double total = 0;
|
||||||
|
for (int i = 0; i < coordinates.size(); i++) {
|
||||||
|
JSONArray coordinate = coordinates.getJSONArray(i);
|
||||||
|
Double lng = coordinate.getDouble(0);
|
||||||
|
|
||||||
|
Double lat = coordinate.getDouble(1);
|
||||||
|
|
||||||
|
double distance = MultiPointGeoPosition.haversine(beforeLat, beforeLng, lat, lng);
|
||||||
|
//当前总距离
|
||||||
|
total = total + distance;
|
||||||
|
//定义坐标对象
|
||||||
|
Coordinate coordinateInfo = new Coordinate();
|
||||||
|
coordinateInfo.setLat(lat);
|
||||||
|
coordinateInfo.setLng(lng);
|
||||||
|
|
||||||
|
//记录距离和数组列表直接的索引关系
|
||||||
|
distanceInfoMap.put(total, coordinateInfo);
|
||||||
|
|
||||||
|
beforeLng = lng;
|
||||||
|
beforeLat = lat;
|
||||||
|
|
||||||
|
}
|
||||||
|
//设置第一个开始位置
|
||||||
|
startPoint.set(distanceInfoMap.firstKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error::", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void updatePath(double speed) {
|
||||||
|
|
||||||
|
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
||||||
|
1);
|
||||||
|
schedule.scheduleWithFixedDelay(() -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.getRoomStatus()) {
|
||||||
|
|
||||||
|
long duringTime = getDuringTime() - taskRelativeTime;
|
||||||
|
|
||||||
|
log.info("duringTime::{}", duringTime);
|
||||||
|
//跑动距离
|
||||||
|
double distance = duringTime * speed;
|
||||||
|
//获取大与此距离的第一个路线点key
|
||||||
|
Entry<Double, Coordinate> endPoint = distanceInfoMap.ceilingEntry(distance);
|
||||||
|
//ws数据
|
||||||
|
List<double[]> dataList = new ArrayList<>();
|
||||||
|
HashMap<Object, Object> dataMap = new HashMap<>();
|
||||||
|
dataMap.put("resourceId", scenarioTask.getResourceId());
|
||||||
|
dataMap.put("points", dataList);
|
||||||
|
|
||||||
|
if (Double.compare(distance, endPoint.getKey()) < 0) {
|
||||||
|
//获取小于最大值的第一个key
|
||||||
|
Double lowerKey = distanceInfoMap.lowerKey(endPoint.getKey());
|
||||||
|
// log.info("distance::{},lowerKey::{},endPoint{}",distance,lowerKey,endPoint.getKey());
|
||||||
|
//获取从上一个开始节点到lowKey的数据
|
||||||
|
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
||||||
|
true, lowerKey, true);
|
||||||
|
for (Double key : subPathMap.keySet()) {
|
||||||
|
Coordinate coordinate = subPathMap.get(key);
|
||||||
|
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
||||||
|
}
|
||||||
|
double diff = distance - lowerKey;
|
||||||
|
|
||||||
|
//插入值
|
||||||
|
double[] insertPoints = MultiPointGeoPosition.pointAlong(
|
||||||
|
distanceInfoMap.get(lowerKey).getLat(), distanceInfoMap.get(lowerKey).getLng(),
|
||||||
|
endPoint.getValue().getLat(), endPoint.getValue().getLng(), diff);
|
||||||
|
|
||||||
|
dataList.add(new double[]{insertPoints[1], insertPoints[0]});
|
||||||
|
|
||||||
|
Coordinate coordinate = new Coordinate();
|
||||||
|
coordinate.setLat(insertPoints[0]);
|
||||||
|
coordinate.setLng(insertPoints[1]);
|
||||||
|
distanceInfoMap.put(distance, coordinate);
|
||||||
|
startPoint.set(distance);
|
||||||
|
SpringUtil.getBean(RedisUtil.class).hset(
|
||||||
|
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
"position", JSON.toJSONString(coordinate));
|
||||||
|
|
||||||
|
Global.sendCmdInfoQueue.add(
|
||||||
|
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
||||||
|
scenarioTask.getScenarioId(), dataMap));
|
||||||
|
|
||||||
|
} else if (Double.compare(distance, endPoint.getKey()) == 0) {
|
||||||
|
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
||||||
|
true, endPoint.getKey(), true);
|
||||||
|
for (Double key : subPathMap.keySet()) {
|
||||||
|
Coordinate coordinate = subPathMap.get(key);
|
||||||
|
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
||||||
|
}
|
||||||
|
|
||||||
|
startPoint.set(endPoint.getKey());
|
||||||
|
Global.sendCmdInfoQueue.add(
|
||||||
|
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
||||||
|
scenarioTask.getScenarioId(), dataMap));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//完成路径
|
||||||
|
Global.sendCmdInfoQueue.add(
|
||||||
|
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_FINISHED.getCode(), roomId,
|
||||||
|
scenarioTask.getScenarioId(), dataMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error::", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}, 0, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
//房间统一管理定时器;房间关闭后,定时器销毁
|
||||||
|
addScheduledExecutorServiceRefenceToRoom(schedule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ public class BattleRootTask extends AbtParentTask {
|
||||||
SupplierRequest supplierRequest = new SupplierRequest();
|
SupplierRequest supplierRequest = new SupplierRequest();
|
||||||
supplierRequest.setId(IdUtils.simpleUUID());
|
supplierRequest.setId(IdUtils.simpleUUID());
|
||||||
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
||||||
supplierRequest.setSupplierNum(String.valueOf(suppleAmount));
|
supplierRequest.setSupplierNum(Double.valueOf(String.valueOf(suppleAmount)));
|
||||||
supplierRequest.setSupplierType("ammunition");
|
supplierRequest.setSupplierType("ammunition");
|
||||||
supplierRequest.setGeneralTime(currentDateTime);
|
supplierRequest.setGeneralTime(currentDateTime);
|
||||||
supplierRequest.setLat(jsonObject.get("teamLat").toString());
|
supplierRequest.setLat(jsonObject.get("teamLat").toString());
|
||||||
|
@ -201,7 +201,7 @@ public class BattleRootTask extends AbtParentTask {
|
||||||
SupplierRequest supplierRequest = new SupplierRequest();
|
SupplierRequest supplierRequest = new SupplierRequest();
|
||||||
supplierRequest.setId(IdUtils.simpleUUID());
|
supplierRequest.setId(IdUtils.simpleUUID());
|
||||||
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
||||||
supplierRequest.setSupplierNum(String.valueOf(suppleDeath));
|
supplierRequest.setSupplierNum(Double.valueOf(String.valueOf(suppleDeath)));
|
||||||
supplierRequest.setSupplierType("death");
|
supplierRequest.setSupplierType("death");
|
||||||
supplierRequest.setGeneralTime(currentDateTime);
|
supplierRequest.setGeneralTime(currentDateTime);
|
||||||
supplierRequest.setLat(jsonObject.get("teamLat").toString());
|
supplierRequest.setLat(jsonObject.get("teamLat").toString());
|
||||||
|
@ -213,7 +213,7 @@ public class BattleRootTask extends AbtParentTask {
|
||||||
SupplierRequest supplierRequest = new SupplierRequest();
|
SupplierRequest supplierRequest = new SupplierRequest();
|
||||||
supplierRequest.setId(IdUtils.simpleUUID());
|
supplierRequest.setId(IdUtils.simpleUUID());
|
||||||
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
||||||
supplierRequest.setSupplierNum(String.valueOf(suppleInjured));
|
supplierRequest.setSupplierNum(Double.valueOf(String.valueOf(suppleInjured)));
|
||||||
supplierRequest.setSupplierType("injured");
|
supplierRequest.setSupplierType("injured");
|
||||||
supplierRequest.setGeneralTime(currentDateTime);
|
supplierRequest.setGeneralTime(currentDateTime);
|
||||||
supplierRequest.setLat(jsonObject.get("teamLat").toString());
|
supplierRequest.setLat(jsonObject.get("teamLat").toString());
|
||||||
|
|
19
src/main/java/com/hivekion/room/bean/Coordinate.java
Normal file
19
src/main/java/com/hivekion/room/bean/Coordinate.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package com.hivekion.room.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [类的简要说明]
|
||||||
|
* <p>
|
||||||
|
* [详细描述,可选]
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @author LiDongYU
|
||||||
|
* @since 2025/7/22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Coordinate {
|
||||||
|
|
||||||
|
private double lng;
|
||||||
|
private double lat;
|
||||||
|
}
|
|
@ -47,22 +47,12 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
|
||||||
* 速度 换算为100Km/小时
|
* 速度 换算为100Km/小时
|
||||||
*/
|
*/
|
||||||
private final double SPEED = 27;
|
private final double SPEED = 27;
|
||||||
/**
|
|
||||||
* 距离和坐标的对应关系
|
|
||||||
*/
|
|
||||||
private final TreeMap<Double, Coordinate> distanceInfoMap = new TreeMap<>();
|
|
||||||
/**
|
|
||||||
* 开始点坐标
|
|
||||||
*/
|
|
||||||
private final AtomicReference<Double> startPoint = new AtomicReference<>();
|
|
||||||
/**
|
|
||||||
* 任务相对与想定的开始时间
|
|
||||||
*/
|
|
||||||
private long taskRelativeStartTime = 0;
|
|
||||||
/**
|
/**
|
||||||
* 油料消耗速率
|
* 油料消耗速率
|
||||||
*/
|
*/
|
||||||
private double fuelConsumption = 0;
|
private double fuelConsumption = 0;
|
||||||
|
private double fuelThreshold = 0;
|
||||||
/**
|
/**
|
||||||
* 消耗任务间隔
|
* 消耗任务间隔
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +75,7 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
|
||||||
|
|
||||||
initEnv(); //初始化环境
|
initEnv(); //初始化环境
|
||||||
initPath(); //初始化路径
|
initPath(); //初始化路径
|
||||||
updatePath(); //更新路径
|
updatePath(SPEED); //更新路径
|
||||||
fuelConsumption();//油品消耗
|
fuelConsumption();//油品消耗
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,204 +83,52 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
|
||||||
* 初始化环境
|
* 初始化环境
|
||||||
*/
|
*/
|
||||||
private void initEnv() {
|
private void initEnv() {
|
||||||
//获取任务相对于想定的开始时间
|
|
||||||
Scenario scenario = SpringUtil.getBean(ScenarioService.class)
|
|
||||||
.getScenarioById(scenarioTask.getScenarioId());
|
|
||||||
taskRelativeStartTime = Math.abs(
|
|
||||||
Duration.between(scenario.getStartTime(), scenarioTask.getStartTime()).getSeconds());
|
|
||||||
//获取油品消耗规则
|
//获取油品消耗规则
|
||||||
String fuelConsumptionStr = SpringUtil.getBean(Environment.class)
|
String fuelConsumptionStr = SpringUtil.getBean(Environment.class)
|
||||||
.getProperty("vehicle.fuel.consumption.per.km");
|
.getProperty("fuel_spreed");
|
||||||
fuelConsumption = Double.parseDouble(fuelConsumptionStr == null ? "0" : fuelConsumptionStr);
|
fuelConsumption = Double.parseDouble(fuelConsumptionStr == null ? "0" : fuelConsumptionStr);
|
||||||
|
fuelThreshold = Double.parseDouble(SpringUtil.getBean(Environment.class)
|
||||||
statisticBean = SpringUtil.getBean(StatisticServiceImpl.class).statistic(scenarioTask.getResourceId());
|
.getProperty("fuel.warn ","0"));
|
||||||
|
statisticBean = SpringUtil.getBean(StatisticServiceImpl.class)
|
||||||
|
.statistic(scenarioTask.getResourceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化路径
|
|
||||||
*/
|
|
||||||
private void initPath() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
String url = SpringUtil.getBean(Environment.class).getProperty("path.planning.url");
|
|
||||||
String params = url + "?"
|
|
||||||
+ "profile=car"
|
|
||||||
+ "&point=" + scenarioTask.getFromLat() + ","
|
|
||||||
+ scenarioTask.getFromLng()
|
|
||||||
+ "&point=" + scenarioTask.getToLat() + ","
|
|
||||||
+ scenarioTask.getToLng()
|
|
||||||
+ "&points_encoded=false"
|
|
||||||
+ "&algorithm=alternative_route&alternative_route.max_paths=3";
|
|
||||||
//获取路线信息
|
|
||||||
String result = webClient.get().uri(params)
|
|
||||||
.retrieve()
|
|
||||||
.bodyToMono(String.class)
|
|
||||||
.block();
|
|
||||||
|
|
||||||
JSONObject pointJson = JSON.parseObject(result);
|
|
||||||
//获取路径点
|
|
||||||
if (pointJson != null) {
|
|
||||||
JSONObject pointsObj = pointJson.getJSONArray("paths").getJSONObject(0)
|
|
||||||
.getJSONObject("points");
|
|
||||||
JSONArray coordinates = pointsObj.getJSONArray("coordinates");
|
|
||||||
//组装信息
|
|
||||||
Map<String, Object> dataMap = new HashMap<>();
|
|
||||||
dataMap.put("resourceId", scenarioTask.getResourceId());
|
|
||||||
dataMap.put("points", coordinates);
|
|
||||||
//推送路径任务
|
|
||||||
Global.sendCmdInfoQueue.add(
|
|
||||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_INIT.getCode(), roomId,
|
|
||||||
scenarioTask.getScenarioId(), dataMap));
|
|
||||||
|
|
||||||
redis.hset(
|
|
||||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
|
||||||
"init_path", JSON.toJSONString(coordinates));
|
|
||||||
|
|
||||||
//计算各个点的累计距离和坐标的对应关系
|
|
||||||
double beforeLng = Double.parseDouble(scenarioTask.getFromLng());
|
|
||||||
double beforeLat = Double.parseDouble(scenarioTask.getFromLat());
|
|
||||||
double total = 0;
|
|
||||||
for (int i = 0; i < coordinates.size(); i++) {
|
|
||||||
JSONArray coordinate = coordinates.getJSONArray(i);
|
|
||||||
Double lng = coordinate.getDouble(0);
|
|
||||||
|
|
||||||
Double lat = coordinate.getDouble(1);
|
|
||||||
|
|
||||||
double distance = MultiPointGeoPosition.haversine(beforeLat, beforeLng, lat, lng);
|
|
||||||
//当前总距离
|
|
||||||
total = total + distance;
|
|
||||||
//定义坐标对象
|
|
||||||
Coordinate coordinateInfo = new Coordinate();
|
|
||||||
coordinateInfo.setLat(lat);
|
|
||||||
coordinateInfo.setLng(lng);
|
|
||||||
|
|
||||||
//记录距离和数组列表直接的索引关系
|
|
||||||
distanceInfoMap.put(total, coordinateInfo);
|
|
||||||
|
|
||||||
beforeLng = lng;
|
|
||||||
beforeLat = lat;
|
|
||||||
|
|
||||||
}
|
|
||||||
//设置第一个开始位置
|
|
||||||
startPoint.set(distanceInfoMap.firstKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("error::", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePath() {
|
|
||||||
|
|
||||||
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
|
||||||
1);
|
|
||||||
schedule.scheduleWithFixedDelay(() -> {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (this.getRoomStatus()) {
|
|
||||||
|
|
||||||
long duringTime = getDuringTime() - taskRelativeStartTime;
|
|
||||||
|
|
||||||
log.info("duringTime::{}", duringTime);
|
|
||||||
//跑动距离
|
|
||||||
double distance = duringTime * SPEED;
|
|
||||||
//获取大与此距离的第一个路线点key
|
|
||||||
Entry<Double, Coordinate> endPoint = distanceInfoMap.ceilingEntry(distance);
|
|
||||||
//ws数据
|
|
||||||
List<double[]> dataList = new ArrayList<>();
|
|
||||||
HashMap<Object, Object> dataMap = new HashMap<>();
|
|
||||||
dataMap.put("resourceId", scenarioTask.getResourceId());
|
|
||||||
dataMap.put("points", dataList);
|
|
||||||
|
|
||||||
if (Double.compare(distance, endPoint.getKey()) < 0) {
|
|
||||||
//获取小于最大值的第一个key
|
|
||||||
Double lowerKey = distanceInfoMap.lowerKey(endPoint.getKey());
|
|
||||||
// log.info("distance::{},lowerKey::{},endPoint{}",distance,lowerKey,endPoint.getKey());
|
|
||||||
//获取从上一个开始节点到lowKey的数据
|
|
||||||
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
|
||||||
true, lowerKey, true);
|
|
||||||
for (Double key : subPathMap.keySet()) {
|
|
||||||
Coordinate coordinate = subPathMap.get(key);
|
|
||||||
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
|
||||||
}
|
|
||||||
double diff = distance - lowerKey;
|
|
||||||
|
|
||||||
//插入值
|
|
||||||
double[] insertPoints = MultiPointGeoPosition.pointAlong(
|
|
||||||
distanceInfoMap.get(lowerKey).getLat(), distanceInfoMap.get(lowerKey).getLng(),
|
|
||||||
endPoint.getValue().getLat(), endPoint.getValue().getLng(), diff);
|
|
||||||
|
|
||||||
dataList.add(new double[]{insertPoints[1], insertPoints[0]});
|
|
||||||
|
|
||||||
Coordinate coordinate = new Coordinate();
|
|
||||||
coordinate.setLat(insertPoints[0]);
|
|
||||||
coordinate.setLng(insertPoints[1]);
|
|
||||||
distanceInfoMap.put(distance, coordinate);
|
|
||||||
startPoint.set(distance);
|
|
||||||
redis.hset(
|
|
||||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
|
||||||
"position", JSON.toJSONString(coordinate));
|
|
||||||
|
|
||||||
Global.sendCmdInfoQueue.add(
|
|
||||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
|
||||||
scenarioTask.getScenarioId(), dataMap));
|
|
||||||
|
|
||||||
} else if (Double.compare(distance, endPoint.getKey()) == 0) {
|
|
||||||
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
|
||||||
true, endPoint.getKey(), true);
|
|
||||||
for (Double key : subPathMap.keySet()) {
|
|
||||||
Coordinate coordinate = subPathMap.get(key);
|
|
||||||
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
|
||||||
}
|
|
||||||
|
|
||||||
startPoint.set(endPoint.getKey());
|
|
||||||
Global.sendCmdInfoQueue.add(
|
|
||||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
|
||||||
scenarioTask.getScenarioId(), dataMap));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//完成路径
|
|
||||||
Global.sendCmdInfoQueue.add(
|
|
||||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_FINISHED.getCode(), roomId,
|
|
||||||
scenarioTask.getScenarioId(), dataMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("error::", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}, 0, 1, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
//房间统一管理定时器;房间关闭后,定时器销毁
|
|
||||||
addScheduledExecutorServiceRefenceToRoom(schedule);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fuelConsumption() {
|
private void fuelConsumption() {
|
||||||
|
|
||||||
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
||||||
1);
|
1);
|
||||||
schedule.scheduleWithFixedDelay(() -> {
|
schedule.scheduleWithFixedDelay(() -> {
|
||||||
if (getRoomStatus()) {
|
if (getRoomStatus()) {
|
||||||
double total = consumptionTaskInterval * SPEED / 1000 * fuelConsumption;
|
double currentUseUp = consumptionTaskInterval * SPEED / 1000 * fuelConsumption;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//更新redis中油品的消耗
|
//更新redis中油品的消耗
|
||||||
Object currentFuelObj = redis.hget(
|
Object currentFuelObj = redis.hget(
|
||||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
"fuel");
|
"fuelConsume");
|
||||||
if (currentFuelObj != null) {
|
if (currentFuelObj != null) {
|
||||||
double fuel = Double.parseDouble(currentFuelObj.toString());
|
double fuel = Double.parseDouble(currentFuelObj.toString());
|
||||||
if (fuel > 0) {
|
fuel = fuel + currentUseUp;
|
||||||
fuel = fuel - total < 0 ? 0 : fuel - total;
|
|
||||||
//更新值
|
//更新值
|
||||||
redis.hset(
|
redis.hset(
|
||||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
"fuel", fuel);
|
"fuelConsume", fuel);
|
||||||
//推送前端
|
|
||||||
|
|
||||||
|
|
||||||
|
double totalFuel = statisticBean.getFuel().getTotal();
|
||||||
|
if(fuel*100/totalFuel<fuelThreshold){
|
||||||
|
//产生一个需求
|
||||||
|
//insertRequest(totalFuel-fuel,getDuringTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// statistic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,27 +136,87 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void statistic() {
|
// private void statistic() {
|
||||||
|
//
|
||||||
Object positionObj = redis.hget(
|
// Object positionObj = redis.hget(
|
||||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
"position");
|
// "position");
|
||||||
if (positionObj != null) {
|
// if (positionObj != null) {
|
||||||
Coordinate coordinate = JSONObject.parseObject(positionObj.toString(), Coordinate.class);
|
// Coordinate coordinate = JSONObject.parseObject(positionObj.toString(), Coordinate.class);
|
||||||
statisticBean.getTeam().setLat(coordinate.lat+"");
|
// statisticBean.getTeam().setLat(coordinate.lat + "");
|
||||||
statisticBean.getTeam().setLng(coordinate.lng+"");
|
// statisticBean.getTeam().setLng(coordinate.lng + "");
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
//设置人员受伤信息
|
// //设置人员受伤信息
|
||||||
|
// Object deathPerson = redis.hget(
|
||||||
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
}
|
// "deathConsume");
|
||||||
}
|
// if (deathPerson != null) {
|
||||||
|
// statisticBean.getPerson().setDeath(Integer.parseInt(deathPerson.toString()));
|
||||||
@Data
|
// statisticBean.getPerson().setCurrent(
|
||||||
class Coordinate {
|
// statisticBean.getPerson().getTotal() - Integer.parseInt(deathPerson.toString()));
|
||||||
|
// }
|
||||||
double lng;
|
// Object injuredPerson = redis.hget(
|
||||||
double lat;
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
// "injuredConsume");
|
||||||
|
// if (injuredPerson != null) {
|
||||||
|
// statisticBean.getPerson().setInjured(Integer.parseInt(injuredPerson.toString()));
|
||||||
|
// }
|
||||||
|
// //设置弹药信息
|
||||||
|
// Object ammunitionObj = redis.hget(
|
||||||
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
// "ammunitionConsume");
|
||||||
|
// if (ammunitionObj != null) {
|
||||||
|
// statisticBean.getAmmunition().setCurrent(
|
||||||
|
// statisticBean.getAmmunition().getTotal() - Integer.parseInt(ammunitionObj.toString()));
|
||||||
|
// }
|
||||||
|
// //设置食品信息
|
||||||
|
// Object foodObj = redis.hget(
|
||||||
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
// "foodConsume");
|
||||||
|
// if (foodObj != null) {
|
||||||
|
// statisticBean.getFood()
|
||||||
|
// .setCurrent(statisticBean.getFood().getTotal() - Integer.parseInt(foodObj.toString()));
|
||||||
|
// }
|
||||||
|
// //设置水信息
|
||||||
|
// Object waterObj = redis.hget(
|
||||||
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
// "waterConsume");
|
||||||
|
// if (waterObj != null) {
|
||||||
|
// statisticBean.getWater()
|
||||||
|
// .setCurrent(statisticBean.getWater().getTotal() - Integer.parseInt(waterObj.toString()));
|
||||||
|
// }
|
||||||
|
// //设置油料信息
|
||||||
|
// Object fuelObj = redis.hget(
|
||||||
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
// "fuelConsume");
|
||||||
|
// if (fuelObj != null) {
|
||||||
|
// statisticBean.getFuel()
|
||||||
|
// .setCurrent(statisticBean.getFuel().getTotal() - Integer.parseInt(fuelObj.toString()));
|
||||||
|
// }
|
||||||
|
// //设置药品信息
|
||||||
|
// Object medicalObj = redis.hget(
|
||||||
|
// scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||||
|
// "medicalConsume");
|
||||||
|
// if (medicalObj != null) {
|
||||||
|
// statisticBean.getMedical().setCurrent(
|
||||||
|
// statisticBean.getMedical().getTotal() - Integer.parseInt(medicalObj.toString()));
|
||||||
|
// }
|
||||||
|
// Global.sendCmdInfoQueue.add(
|
||||||
|
// ResponseCmdInfo.create(WsCmdTypeEnum.STATISTIC.getCode(), roomId,
|
||||||
|
// scenarioTask.getScenarioId(), statisticBean));
|
||||||
|
// }
|
||||||
|
//插入需求表
|
||||||
|
// private void insertRequest(double num,long second){
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// //插入消耗表
|
||||||
|
// private void insertConsumption (double num,long second) {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,11 @@ import com.hivekion.scenario.entity.ScenarioTask;
|
||||||
*/
|
*/
|
||||||
public class SupplierTask extends AbtParentTask implements TaskAction {
|
public class SupplierTask extends AbtParentTask implements TaskAction {
|
||||||
|
|
||||||
public SupplierTask(ScenarioTask scenarioTask,String roomId) {
|
public SupplierTask(ScenarioTask scenarioTask, String roomId) {
|
||||||
super(scenarioTask,roomId);
|
super(scenarioTask, roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doSomeThing() {
|
public void doSomeThing() {
|
||||||
|
|
||||||
|
@ -27,6 +26,4 @@ public class SupplierTask extends AbtParentTask implements TaskAction {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user