Merge branch 'master' of http://101.43.238.71:3000/zouju/auto-solution
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
package com.solution.rule.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 装备匹配规则默认参数,与 {@code resources/rules/rule.drl} 中 {@code buildParam} 键保持一致。
|
||||
*/
|
||||
public final class FireRuleMatchDefaultParams {
|
||||
|
||||
private FireRuleMatchDefaultParams() {
|
||||
}
|
||||
|
||||
public static Map<String, Object> defaults() {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("weight", 1);
|
||||
param.put("minSelectedScore", 1);
|
||||
param.put("tankScore", 1);
|
||||
param.put("airScore", 2);
|
||||
param.put("groundScore", 1);
|
||||
param.put("missileScore", 1);
|
||||
param.put("airTaskScore", 10);
|
||||
param.put("bluePlatformKeywords_air", "F-16,J-10,F-35");
|
||||
param.put("redPreferredWhenBlueAir", "防空,导弹,无人机,直升机,空空");
|
||||
param.put("redPreferredWhenGround", "远火,榴弹,炮,火箭");
|
||||
param.put("airTaskKeywords", "空中,制空,拦截,空战");
|
||||
param.put("groundTaskKeywords", "地面,突击,登陆");
|
||||
param.put("tankKeywords", "坦克,装甲");
|
||||
param.put("missileKeywords", "导弹,火箭弹,巡航");
|
||||
param.put("tieBreak", "equipmentId");
|
||||
return param;
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,16 @@ public class Task {
|
||||
|
||||
//防区经纬高
|
||||
private List<Coordinate> defZoneLocation;
|
||||
|
||||
//阵型类型:TRIANGLE/DIAMOND/LINE/COLUMN/WEDGE
|
||||
private String formationType;
|
||||
|
||||
//阵型基础间距(米)
|
||||
private Integer formationSpacingMeters;
|
||||
|
||||
//主僚标准距离(米)
|
||||
private Integer mainWingDistanceMeters;
|
||||
|
||||
//阵型朝向(0~359)
|
||||
private Integer formationHeadingDeg;
|
||||
}
|
||||
|
||||
@@ -30,4 +30,13 @@ public class Weapon {
|
||||
|
||||
//目标id
|
||||
private String targetId;
|
||||
|
||||
//编队角色:MAIN=主机,WING=僚机
|
||||
private String formationRole;
|
||||
|
||||
//僚机相对主机距离(米)
|
||||
private Integer wingRelativeDistanceMeters;
|
||||
|
||||
//僚机相对主机方位角(度)
|
||||
private Integer wingRelativeBearingDeg;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 装备组件参数项
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleComponentParamDTO {
|
||||
|
||||
/**
|
||||
* 参数唯一标识
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* 属性默认值
|
||||
*/
|
||||
private String attDefaultValue;
|
||||
|
||||
/**
|
||||
* 属性说明
|
||||
*/
|
||||
private String attExplain;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Integer number;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 经纬高坐标点
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleCoordinateDTO {
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 高程(米)
|
||||
*/
|
||||
private Double height;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputArithmeticRefDTO {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 火力规则输入根文档,与 {@code 火力规则输入-无注释.json} 顶层字段对应。
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputDTO {
|
||||
|
||||
/**
|
||||
* 来源场景文件名
|
||||
*/
|
||||
private String sourceFile;
|
||||
|
||||
/**
|
||||
* 蓝方任务列表
|
||||
*/
|
||||
private List<FireRuleTaskInputDTO> tasks;
|
||||
|
||||
/**
|
||||
* 红方装备等条目列表,对应 JSON 键 {@code redWeapons}(当前 {@link FireRuleInputRedWeaponElementDTO} 与装备结构一致)
|
||||
*/
|
||||
@JsonProperty("equipments")
|
||||
private List<FireRuleInputRedWeaponElementDTO> equipments;
|
||||
|
||||
/**
|
||||
* 阵营与姿态关系列表,对应 JSON 键 {@code ForceSides}
|
||||
*/
|
||||
@JsonProperty("ForceSides")
|
||||
private List<FireRuleInputForceSideDTO> forceSides;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputDeviceRefDTO {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String refId;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 阵营侧一方与其它方的姿态关系项
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputForcePostureDTO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
@JsonProperty("Type")
|
||||
private Integer type;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 阵营侧(ForceSides 数组中的一项)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputForceSideDTO {
|
||||
|
||||
private String groupType;
|
||||
|
||||
@JsonProperty("Postures")
|
||||
private List<FireRuleInputForcePostureDTO> postures;
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
@JsonProperty("ForceSideName")
|
||||
private String forceSideName;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputLauncherConfigurationDTO {
|
||||
|
||||
private String classifyName;
|
||||
|
||||
private Integer isMount;
|
||||
|
||||
private FireRuleInputMountedWeaponRefDTO mountedWeapon;
|
||||
|
||||
private Integer number;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputMountedWeaponRefDTO {
|
||||
|
||||
@JsonProperty("_id")
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputRedCommSlotDTO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleInputArithmeticRefDTO arithmetic;
|
||||
|
||||
private FireRuleInputDeviceRefDTO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private Boolean employLabel;
|
||||
|
||||
private String facilityName;
|
||||
|
||||
private String soleId;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputRedMotorizedSlotDTO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleInputArithmeticRefDTO arithmetic;
|
||||
|
||||
private FireRuleInputDeviceRefDTO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private String soleId;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputRedPlatformSlotDTO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleInputArithmeticRefDTO arithmetic;
|
||||
|
||||
private FireRuleInputDeviceRefDTO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private Boolean employLabel;
|
||||
|
||||
private String facilityName;
|
||||
|
||||
private String soleId;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
|
||||
@JsonProperty("TrackParamId")
|
||||
private String trackParamId;
|
||||
|
||||
private List<Double> positions;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputRedSubComponentsDTO {
|
||||
|
||||
private List<FireRuleInputRedCommSlotDTO> communication;
|
||||
|
||||
@JsonProperty("motorized_assembly")
|
||||
private List<FireRuleInputRedMotorizedSlotDTO> motorizedAssembly;
|
||||
|
||||
private List<FireRuleInputRedPlatformSlotDTO> platform;
|
||||
|
||||
private List<FireRuleInputRedWeaponSlotDTO> weapon;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@code redWeapons} 中红方装备(platform)条目,与 {@code 火力规则输入-无注释.json} 中带
|
||||
* {@code SubComponents} 的装备对象字段一致。
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputRedWeaponElementDTO {
|
||||
|
||||
@JsonProperty("SupportType")
|
||||
private String supportType;
|
||||
|
||||
@JsonProperty("TroopsDetail")
|
||||
private Map<String, Object> troopsDetail;
|
||||
|
||||
@JsonProperty("Platform_type")
|
||||
private String platformType;
|
||||
|
||||
private Boolean isStrikeTarget;
|
||||
|
||||
private Boolean isReconTarget;
|
||||
|
||||
private Boolean isInterferenceTarget;
|
||||
|
||||
private Boolean isDefendImportantPlace;
|
||||
//命中率
|
||||
private Double successTargetRad;
|
||||
|
||||
private String groupType;
|
||||
|
||||
@JsonProperty("EquipmentID")
|
||||
private String equipmentId;
|
||||
|
||||
@JsonProperty("Name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("OwnerForceSide")
|
||||
private String ownerForceSide;
|
||||
|
||||
@JsonProperty("PlatID")
|
||||
private String platId;
|
||||
|
||||
@JsonProperty("SubComponents")
|
||||
private FireRuleInputRedSubComponentsDTO subComponents;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleInputRedWeaponSlotDTO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleInputArithmeticRefDTO arithmetic;
|
||||
|
||||
private String codedQueue;
|
||||
|
||||
private FireRuleInputLauncherConfigurationDTO configuration;
|
||||
|
||||
private FireRuleInputDeviceRefDTO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private Boolean employLabel;
|
||||
|
||||
private String facilityName;
|
||||
|
||||
private String serialNumber;
|
||||
|
||||
private String soleId;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单条火力规则任务输入(蓝方多任务时为列表中的一项)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTaskInputDTO {
|
||||
|
||||
/**
|
||||
* 任务唯一标识
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
private String drawName;
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 任务所属阵营
|
||||
*/
|
||||
private String side;
|
||||
|
||||
/**
|
||||
* 蓝方任务装备命中率
|
||||
*/
|
||||
private Double successTargetRad;
|
||||
|
||||
/**
|
||||
* 航迹所属实体或阵营标识
|
||||
*/
|
||||
private String trackPointsId;
|
||||
|
||||
/**
|
||||
* 任务航迹点列表
|
||||
*/
|
||||
private List<FireRuleTrackPointDTO> trackPoints;
|
||||
|
||||
/**
|
||||
* 任务武器配置列表
|
||||
*/
|
||||
private List<FireRuleTaskWeaponDTO> taskWeapons;
|
||||
|
||||
/**
|
||||
* 任务目标 id
|
||||
*/
|
||||
private String targetId;
|
||||
|
||||
/**
|
||||
* 作战区经纬高坐标列表
|
||||
*/
|
||||
private List<FireRuleCoordinateDTO> warZoneLocation;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务挂载的武器配置
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTaskWeaponDTO {
|
||||
|
||||
/**
|
||||
* 装备 id(武器唯一标识)
|
||||
*/
|
||||
private String equipmentId;
|
||||
|
||||
/**
|
||||
* 装备名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 装备类型
|
||||
*/
|
||||
private String supportType;
|
||||
|
||||
/**
|
||||
* 装备组件列表
|
||||
*/
|
||||
private List<FireRuleWeaponComponentDTO> components;
|
||||
|
||||
/**
|
||||
* 装备部署位置
|
||||
*/
|
||||
private FireRuleCoordinateDTO coordinate;
|
||||
|
||||
/**
|
||||
* 武器数量;对应 JSON 键 {@code number}。{@code _comment_number} 为注释键,不映射。
|
||||
* 可为数值或业务文案(如「最大载弹量」)。
|
||||
*/
|
||||
private Object number;
|
||||
|
||||
/**
|
||||
* 该武器打击目标 id
|
||||
*/
|
||||
private String targetId;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 任务航迹点
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTrackPointDTO {
|
||||
|
||||
/**
|
||||
* 航迹点序号
|
||||
*/
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 高度
|
||||
*/
|
||||
private Double height;
|
||||
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
private Double speed;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务武器下的设备组件
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleWeaponComponentDTO {
|
||||
|
||||
/**
|
||||
* 设备 id
|
||||
*/
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 组件参数列表
|
||||
*/
|
||||
private List<FireRuleComponentParamDTO> componentParams;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 火力规则输入侧 DTO,与 {@code resources/json/火力规则输入-无注释.json} 对齐。
|
||||
* <p>
|
||||
* {@code redWeapons} 中装备项为 {@link com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO}(含 {@code SubComponents})。
|
||||
*/
|
||||
package com.solution.rule.domain.ultimately.dto;
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.solution.rule.domain.ultimately.fact;
|
||||
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleTaskInputDTO;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleOutputVO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DroolsFact {
|
||||
|
||||
//蓝方任务列表
|
||||
private FireRuleTaskInputDTO task;
|
||||
|
||||
//红方武器库
|
||||
private List<FireRuleInputRedWeaponElementDTO> redWeapons;
|
||||
|
||||
private FireRuleOutputVO fireRuleOutputVO;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 算法引用(id / 名称)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleArithmeticRefVO {
|
||||
|
||||
/**
|
||||
* 算法 id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 算法名称
|
||||
*/
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 装备组件参数项
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleComponentParamVO {
|
||||
|
||||
/**
|
||||
* 参数唯一标识
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* 属性默认值
|
||||
*/
|
||||
private String attDefaultValue;
|
||||
|
||||
/**
|
||||
* 属性说明
|
||||
*/
|
||||
private String attExplain;
|
||||
|
||||
/**
|
||||
* 数量或序号
|
||||
*/
|
||||
private Integer number;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 经纬高坐标点
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleCoordinateVO {
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 高程(米)
|
||||
*/
|
||||
private Double height;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 巡航航线偏移量项(上下 / 前后 / 左右 三选一与取值)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleCruiseRouteOffsetItemVO {
|
||||
|
||||
@JsonProperty("UpOrDown")
|
||||
private Boolean upOrDown;
|
||||
|
||||
@JsonProperty("BeforeOrAfter")
|
||||
private Boolean beforeOrAfter;
|
||||
|
||||
@JsonProperty("LeftOrRight")
|
||||
private Boolean leftOrRight;
|
||||
|
||||
/**
|
||||
* 偏移数值
|
||||
*/
|
||||
private Number value;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 设备引用
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleDeviceRefVO {
|
||||
|
||||
/**
|
||||
* 设备 id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 引用 id
|
||||
*/
|
||||
private String refId;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务载荷中的单次执行块(含目标列表与类型)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleExecuteBlockVO {
|
||||
|
||||
private List<FireRuleExecuteTargetItemVO> targetList;
|
||||
|
||||
/**
|
||||
* 执行类型,如 assault
|
||||
*/
|
||||
private String type;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 打击执行块中单个目标条目
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleExecuteTargetItemVO {
|
||||
|
||||
@JsonProperty("ID")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 阵列位置 id
|
||||
*/
|
||||
private Integer arrayPositionId;
|
||||
|
||||
/**
|
||||
* 阵列位置 id 备份
|
||||
*/
|
||||
private String arrayPositionIdBak;
|
||||
|
||||
/**
|
||||
* 到达时间配置
|
||||
*/
|
||||
@JsonProperty("at_time")
|
||||
private FireRuleTargetAttTimeVO atTime;
|
||||
|
||||
@JsonProperty("times_interval")
|
||||
private Integer timesInterval;
|
||||
|
||||
private String attackType;
|
||||
|
||||
private String boost;
|
||||
|
||||
private String bootTime;
|
||||
|
||||
private String companion;
|
||||
|
||||
private String cruiseRouteId;
|
||||
|
||||
private String moveRouteId;
|
||||
|
||||
private List<FireRuleCruiseRouteOffsetItemVO> cruiseRouteOffset;
|
||||
|
||||
private String fireType;
|
||||
|
||||
private List<Object> strategy;
|
||||
|
||||
private String targetId;
|
||||
|
||||
private String weaponId;
|
||||
|
||||
private String weaponRelease;
|
||||
|
||||
private String weaponType;
|
||||
|
||||
private Integer weaponUseCount;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 发射架配置块
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleLauncherConfigurationVO {
|
||||
|
||||
/**
|
||||
* 分类名称
|
||||
*/
|
||||
private String classifyName;
|
||||
|
||||
/**
|
||||
* 是否挂载
|
||||
*/
|
||||
private Integer isMount;
|
||||
|
||||
/**
|
||||
* 已挂载武器
|
||||
*/
|
||||
private FireRuleMountedWeaponRefVO mountedWeapon;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Integer number;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 任务载荷中的挂载/任务清单项
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleMissionListItemVO {
|
||||
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 发射器类型,如 sam
|
||||
*/
|
||||
private String launcherType;
|
||||
|
||||
private Integer number;
|
||||
|
||||
private String value;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 挂载武器简要信息
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleMountedWeaponRefVO {
|
||||
|
||||
/**
|
||||
* 武器文档 id
|
||||
*/
|
||||
@JsonProperty("_id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 武器名称
|
||||
*/
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleOutputVO {
|
||||
private String sourceFile;
|
||||
private List<FireRuleTaskInputVO> fireRuleInputs;
|
||||
@JsonProperty("Tasks")
|
||||
private List<FireRuleSceneTaskNodeVO> tasks;
|
||||
@JsonProperty("TrackParam")
|
||||
private FireRuleTrackParamVO trackParam;
|
||||
|
||||
@JsonIgnore
|
||||
public List<FireRuleSceneGroupNodeVO> getGroups() {
|
||||
return trackParam == null ? null : trackParam.getGroups();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setGroups(List<FireRuleSceneGroupNodeVO> groups) {
|
||||
if (trackParam == null) {
|
||||
trackParam = new FireRuleTrackParamVO();
|
||||
}
|
||||
trackParam.setGroups(groups);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public List<FireRuleRedWeaponEquipmentVO> getRedWeapons() {
|
||||
return trackParam == null ? null : trackParam.getRedWeapons();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setRedWeapons(List<FireRuleRedWeaponEquipmentVO> redWeapons) {
|
||||
if (trackParam == null) {
|
||||
trackParam = new FireRuleTrackParamVO();
|
||||
}
|
||||
trackParam.setRedWeapons(redWeapons);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 红方装备子组件:通信类数组元素
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRedCommunicationSlotVO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleArithmeticRefVO arithmetic;
|
||||
|
||||
private FireRuleDeviceRefVO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private Boolean employLabel;
|
||||
|
||||
private String facilityName;
|
||||
|
||||
private String soleId;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 红方装备子组件:机动组件数组元素
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRedMotorizedSlotVO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleArithmeticRefVO arithmetic;
|
||||
|
||||
private FireRuleDeviceRefVO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private String soleId;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 红方装备子组件:平台数组元素
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRedPlatformSlotVO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleArithmeticRefVO arithmetic;
|
||||
|
||||
private FireRuleDeviceRefVO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private Boolean employLabel;
|
||||
|
||||
private String facilityName;
|
||||
|
||||
private String soleId;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
|
||||
@JsonProperty("TrackParamId")
|
||||
private String trackParamId;
|
||||
|
||||
private List<Double> positions;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 红方装备子组件分组(按 communication / motorized_assembly / platform / weapon)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRedSubComponentsVO {
|
||||
|
||||
private List<FireRuleRedCommunicationSlotVO> communication;
|
||||
|
||||
@JsonProperty("motorized_assembly")
|
||||
private List<FireRuleRedMotorizedSlotVO> motorizedAssembly;
|
||||
|
||||
private List<FireRuleRedPlatformSlotVO> platform;
|
||||
|
||||
private List<FireRuleRedWeaponSlotVO> weapon;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRedWeaponEquipmentVO {
|
||||
|
||||
@JsonProperty("SupportType")
|
||||
private String supportType;
|
||||
|
||||
@JsonProperty("TroopsDetail")
|
||||
private Map<String, Object> troopsDetail;
|
||||
|
||||
@JsonProperty("Platform_type")
|
||||
private String platformType;
|
||||
|
||||
private Boolean isStrikeTarget;
|
||||
private Boolean isReconTarget;
|
||||
private Boolean isInterferenceTarget;
|
||||
private Boolean isDefendImportantPlace;
|
||||
private Double successTargetRad;
|
||||
private String groupType;
|
||||
|
||||
@JsonProperty("EquipmentID")
|
||||
private String equipmentId;
|
||||
|
||||
@JsonProperty("Name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("OwnerForceSide")
|
||||
private String ownerForceSide;
|
||||
|
||||
@JsonProperty("PlatID")
|
||||
private String platId;
|
||||
|
||||
@JsonProperty("SubComponents")
|
||||
private FireRuleRedSubComponentsVO subComponents;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 红方装备子组件:武器 / 发射架子项
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRedWeaponSlotVO {
|
||||
|
||||
@JsonProperty("ObjectHandle")
|
||||
private String objectHandle;
|
||||
|
||||
private FireRuleArithmeticRefVO arithmetic;
|
||||
|
||||
private String codedQueue;
|
||||
|
||||
private FireRuleLauncherConfigurationVO configuration;
|
||||
|
||||
private FireRuleDeviceRefVO device;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private Boolean employLabel;
|
||||
|
||||
private String facilityName;
|
||||
|
||||
private String serialNumber;
|
||||
|
||||
private String soleId;
|
||||
|
||||
private Map<String, Object> twiceModified;
|
||||
|
||||
private List<Object> zLists;
|
||||
|
||||
@JsonProperty("ParentPlat")
|
||||
private String parentPlat;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleRouteTrackPointVO {
|
||||
private String index;
|
||||
private String longitude;
|
||||
private String latitude;
|
||||
private String height;
|
||||
private String speed;
|
||||
private String psia;
|
||||
private Integer time;
|
||||
private String active;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 火力规则输出中 Groups 数组的单项
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleSceneGroupNodeVO {
|
||||
|
||||
private Number allAngle;
|
||||
|
||||
private String drawName;
|
||||
|
||||
private List<Object> editPermission;
|
||||
|
||||
private String groupType;
|
||||
|
||||
private String id;
|
||||
|
||||
private String idKey;
|
||||
|
||||
private Boolean isSelected;
|
||||
|
||||
private Boolean isShow;
|
||||
|
||||
private String leader;
|
||||
|
||||
private String name;
|
||||
|
||||
private String parentId;
|
||||
|
||||
private List<String> permission;
|
||||
|
||||
private Boolean show;
|
||||
|
||||
private Long sort;
|
||||
|
||||
private List<FireRuleWingmanDataVO> wingmanData;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 火力规则输出中 Tasks 数组的单项(场景树任务节点)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleSceneTaskNodeVO {
|
||||
|
||||
private String color;
|
||||
|
||||
private String dataType;
|
||||
|
||||
private String drawName;
|
||||
|
||||
private String groupType;
|
||||
|
||||
private String id;
|
||||
|
||||
private String idKey;
|
||||
|
||||
private Boolean isSelected;
|
||||
|
||||
private String name;
|
||||
|
||||
private String parentId;
|
||||
|
||||
private List<String> permission;
|
||||
|
||||
private Boolean show;
|
||||
|
||||
private String side;
|
||||
|
||||
private Long sort;
|
||||
|
||||
private FireRuleSceneTaskPayloadVO task;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景任务节点中的内层 task 对象
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleSceneTaskPayloadVO {
|
||||
|
||||
@JsonProperty("at_time")
|
||||
private String atTime;
|
||||
|
||||
private String attackId;
|
||||
|
||||
private String color;
|
||||
|
||||
private String departureAirport;
|
||||
|
||||
private List<FireRuleExecuteBlockVO> execute;
|
||||
|
||||
private String landAirport;
|
||||
|
||||
private List<FireRuleMissionListItemVO> missionList;
|
||||
|
||||
private String name;
|
||||
|
||||
private String side;
|
||||
|
||||
private String sideId;
|
||||
|
||||
private Integer speed;
|
||||
|
||||
private String type;
|
||||
|
||||
private String weaponId;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 目标项中的到达时间开关与取值
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTargetAttTimeVO {
|
||||
|
||||
/**
|
||||
* 时间上限是否为真
|
||||
*/
|
||||
private Boolean timeUp;
|
||||
|
||||
/**
|
||||
* 时间值
|
||||
*/
|
||||
private Number value;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单条火力规则任务输出(相对输入增加防区坐标)
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTaskInputVO {
|
||||
|
||||
/**
|
||||
* 任务唯一标识
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
private String drawName;
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 任务所属阵营
|
||||
*/
|
||||
private String side;
|
||||
|
||||
/**
|
||||
* 航迹所属实体或阵营标识
|
||||
*/
|
||||
private String trackPointsId;
|
||||
|
||||
/**
|
||||
* 任务航迹点列表
|
||||
*/
|
||||
private List<FireRuleTrackPointVO> trackPoints;
|
||||
|
||||
/**
|
||||
* 任务武器配置列表
|
||||
*/
|
||||
private List<FireRuleTaskWeaponVO> taskWeapons;
|
||||
|
||||
/**
|
||||
* 任务目标 id
|
||||
*/
|
||||
private String targetId;
|
||||
|
||||
/**
|
||||
* 作战区经纬高坐标列表
|
||||
*/
|
||||
private List<FireRuleCoordinateVO> warZoneLocation;
|
||||
|
||||
/**
|
||||
* 防区经纬高坐标列表
|
||||
*/
|
||||
private List<FireRuleCoordinateVO> defZoneLocation;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务挂载的武器配置
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTaskWeaponVO {
|
||||
|
||||
/**
|
||||
* 装备 id(武器唯一标识)
|
||||
*/
|
||||
private String equipmentId;
|
||||
|
||||
/**
|
||||
* 装备名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 装备类型编码
|
||||
*/
|
||||
private String supportType;
|
||||
|
||||
/**
|
||||
* 装备组件列表
|
||||
*/
|
||||
private List<FireRuleWeaponComponentVO> components;
|
||||
|
||||
/**
|
||||
* 装备部署位置
|
||||
*/
|
||||
private FireRuleCoordinateVO coordinate;
|
||||
|
||||
/**
|
||||
* 武器数量;可为数值或业务文案(如「最大载弹量」)
|
||||
*/
|
||||
private Object number;
|
||||
|
||||
/**
|
||||
* 该武器打击目标 id
|
||||
*/
|
||||
private String targetId;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTrackParamVO {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private Map<String, FireRuleTrackRouteVO> routeMap = new LinkedHashMap<>();
|
||||
|
||||
@JsonProperty("Groups")
|
||||
private List<FireRuleSceneGroupNodeVO> groups;
|
||||
|
||||
@JsonProperty("redWeapons")
|
||||
private List<FireRuleRedWeaponEquipmentVO> redWeapons;
|
||||
|
||||
@JsonAnySetter
|
||||
public void putRoute(String key, JsonNode value) {
|
||||
if ("Groups".equals(key) || "redWeapons".equals(key) || value == null) {
|
||||
return;
|
||||
}
|
||||
routeMap.put(key, MAPPER.convertValue(value, FireRuleTrackRouteVO.class));
|
||||
}
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, FireRuleTrackRouteVO> getRouteMap() {
|
||||
return routeMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 任务航迹点
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTrackPointVO {
|
||||
|
||||
/**
|
||||
* 航迹点序号
|
||||
*/
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 高度
|
||||
*/
|
||||
private Double height;
|
||||
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
private Double speed;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleTrackRouteVO {
|
||||
private String name;
|
||||
@JsonProperty("StartTime")
|
||||
private Integer startTime;
|
||||
@JsonProperty("EndTime")
|
||||
private Integer endTime;
|
||||
@JsonProperty("TrackType")
|
||||
private String trackType;
|
||||
@JsonProperty("HeightType")
|
||||
private String heightType;
|
||||
private String seaType;
|
||||
@JsonProperty("TrackPoints")
|
||||
private List<FireRuleRouteTrackPointVO> trackPoints;
|
||||
@JsonProperty("Color")
|
||||
private String color;
|
||||
@JsonProperty("PointCount")
|
||||
private Integer pointCount;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务武器下的设备组件
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleWeaponComponentVO {
|
||||
|
||||
/**
|
||||
* 设备 id
|
||||
*/
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 组件参数列表
|
||||
*/
|
||||
private List<FireRuleComponentParamVO> componentParams;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.solution.rule.domain.ultimately.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 编组中的僚机相对参数
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FireRuleWingmanDataVO {
|
||||
|
||||
private Integer alt;
|
||||
|
||||
private String angle;
|
||||
|
||||
private Integer distance;
|
||||
|
||||
private Integer key;
|
||||
|
||||
private String name;
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
//package com.solution.rule.parser;
|
||||
//
|
||||
//import com.fasterxml.jackson.core.JsonParser;
|
||||
//import com.fasterxml.jackson.core.JsonToken;
|
||||
//import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//import java.io.IOException;
|
||||
//import java.util.*;
|
||||
//
|
||||
//public class JsonStreamParser {
|
||||
//
|
||||
// // 核心:解析所有集合 → 内存关联ID → 组装完整数据
|
||||
// public List<AssembledWeapon> parseAndAssemble(HttpServletRequest request) throws IOException {
|
||||
// ObjectMapper mapper = new ObjectMapper();
|
||||
// try (JsonParser parser = mapper.getFactory().createParser(request.getInputStream())) {
|
||||
//
|
||||
// // ========== 步骤1:流式解析,把所有关联集合存到内存 ==========
|
||||
// String version = null;
|
||||
// // 存储所有集合:key=集合名(weaponList/weaponParams),value=数据列表
|
||||
// Map<String, List<Map<String, Object>>> allCollections = new HashMap<>();
|
||||
//
|
||||
// // 解析状态
|
||||
// String currentCollection = null;
|
||||
// Map<String, Object> currentItem = null;
|
||||
//
|
||||
// JsonToken token;
|
||||
// while ((token = parser.nextToken()) != null) {
|
||||
// switch (token) {
|
||||
// case START_OBJECT:
|
||||
// if (currentCollection != null) currentItem = new HashMap<>();
|
||||
// break;
|
||||
// case END_OBJECT:
|
||||
// if (currentCollection != null && currentItem != null) {
|
||||
// allCollections.get(currentCollection).add(currentItem);
|
||||
// currentItem = null;
|
||||
// }
|
||||
// break;
|
||||
// case START_ARRAY:
|
||||
// currentCollection = parser.getCurrentName();
|
||||
// allCollections.putIfAbsent(currentCollection, new ArrayList<>());
|
||||
// break;
|
||||
// case END_ARRAY:
|
||||
// currentCollection = null;
|
||||
// break;
|
||||
// case FIELD_NAME:
|
||||
// String field = parser.getCurrentName();
|
||||
// // 解析版本号
|
||||
// if ("version".equals(field) && isInMeta(parser)) {
|
||||
// version = parser.nextTextValue();
|
||||
// break;
|
||||
// }
|
||||
// // 解析普通字段
|
||||
// if (currentItem != null) {
|
||||
// parser.nextToken();
|
||||
// currentItem.put(field, getValue(parser));
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // ========== 步骤2:核心!通过ID关联匹配,组装完整数据 ==========
|
||||
// return assembleFullWeaponData(allCollections);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 【核心逻辑】ID关联匹配:武器列表 + 参数列表 → 完整武器
|
||||
// */
|
||||
// private List<AssembledWeapon> assembleFullWeaponData(Map<String, List<Map<String, Object>>> allCollections) {
|
||||
// List<AssembledWeapon> result = new ArrayList<>();
|
||||
//
|
||||
// // 1. 获取武器主列表
|
||||
// List<Map<String, Object>> weaponList = allCollections.getOrDefault("weaponList", Collections.emptyList());
|
||||
// // 2. 获取武器参数列表
|
||||
// List<Map<String, Object>> paramList = allCollections.getOrDefault("weaponParams", Collections.emptyList());
|
||||
//
|
||||
// // 3. 构建【ID -> 参数】索引Map(O(1)快速匹配,效率最高)
|
||||
// Map<Long, Map<String, Object>> paramIndex = new HashMap<>();
|
||||
// for (Map<String, Object> param : paramList) {
|
||||
// Long weaponId = Long.valueOf(param.get("weaponId").toString());
|
||||
// paramIndex.put(weaponId, param);
|
||||
// }
|
||||
//
|
||||
// // 4. 遍历武器,通过ID匹配参数,组装完整对象
|
||||
// for (Map<String, Object> weapon : weaponList) {
|
||||
// AssembledWeapon fullWeapon = new AssembledWeapon();
|
||||
// Long weaponId = Long.valueOf(weapon.get("id").toString());
|
||||
//
|
||||
// // 填充基础信息
|
||||
// fullWeapon.setId(weaponId);
|
||||
// fullWeapon.setName((String) weapon.get("name"));
|
||||
//
|
||||
// // 匹配参数(通过ID)
|
||||
// Map<String, Object> param = paramIndex.get(weaponId);
|
||||
// if (param != null) {
|
||||
// fullWeapon.setDamage(Integer.valueOf(param.get("damage").toString()));
|
||||
// fullWeapon.setMagazine(Integer.valueOf(param.get("magazine").toString()));
|
||||
// fullWeapon.setType((String) param.get("type"));
|
||||
// }
|
||||
//
|
||||
// result.add(fullWeapon);
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// // ---------------- 工具方法 ----------------
|
||||
// private boolean isInMeta(JsonParser parser) {
|
||||
// return parser.getParsingContext().getParent() != null
|
||||
// && "meta".equals(parser.getParsingContext().getParent().getCurrentName());
|
||||
// }
|
||||
//
|
||||
// private Object getValue(JsonParser parser) throws IOException {
|
||||
// if (parser.getCurrentToken().isNumeric()) return parser.getLongValue();
|
||||
// if (parser.getCurrentToken() == JsonToken.VALUE_STRING) return parser.getText();
|
||||
// if (parser.getCurrentToken() == JsonToken.VALUE_TRUE) return true;
|
||||
// if (parser.getCurrentToken() == JsonToken.VALUE_FALSE) return false;
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
@@ -5,6 +5,8 @@ import com.solution.rule.domain.FireRuleExecuteDTO;
|
||||
import com.solution.rule.domain.Platform;
|
||||
import com.solution.rule.domain.PlatformComponent;
|
||||
import com.solution.rule.domain.simplerulepojo.Task;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleInputDTO;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleOutputVO;
|
||||
import com.solution.rule.domain.vo.PlatformComponentNamesVO;
|
||||
import com.solution.rule.domain.vo.PlatformWeaponAggregateVO;
|
||||
|
||||
@@ -58,4 +60,11 @@ public interface FireRuleService {
|
||||
* @return
|
||||
*/
|
||||
Task executeTask(Task task);
|
||||
|
||||
/**
|
||||
* 火力规则
|
||||
* @param task
|
||||
* @return
|
||||
*/
|
||||
FireRuleOutputVO rule(FireRuleInputDTO task);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,14 @@ import com.solution.rule.domain.*;
|
||||
import com.solution.rule.domain.dto.WeaponModelDTO;
|
||||
import com.solution.rule.domain.simplerulepojo.Task;
|
||||
import com.solution.rule.domain.simplerulepojo.Weapon;
|
||||
import com.solution.rule.domain.simplerulepojo.fact.FactTask;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleInputDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleInputForceSideDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleTaskInputDTO;
|
||||
import com.solution.rule.config.FireRuleMatchDefaultParams;
|
||||
import com.solution.rule.domain.ultimately.fact.DroolsFact;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleOutputVO;
|
||||
import com.solution.rule.domain.vo.ComponentCountVO;
|
||||
import com.solution.rule.domain.vo.PlatformComponentNamesVO;
|
||||
import com.solution.rule.domain.vo.PlatformWeaponAggregateVO;
|
||||
@@ -19,13 +27,12 @@ import com.solution.rule.simpstrategy.FireRuleStrategyFactory;
|
||||
import com.solution.rule.strategy.SceneStrategy;
|
||||
import com.solution.rule.strategy.SceneStrategyFactory;
|
||||
import org.kie.api.KieBase;
|
||||
import org.kie.api.runtime.KieSession;
|
||||
import org.kie.api.runtime.rule.FactHandle;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@@ -186,6 +193,64 @@ public class FireRuleServiceImpl implements FireRuleService {
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
* @param task
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FireRuleOutputVO rule(FireRuleInputDTO task) {
|
||||
if(ObjectUtil.isEmpty(task)){
|
||||
throw new RuntimeException(ExceptionConstants.PARAMETER_EXCEPTION);
|
||||
}
|
||||
List<FireRuleTaskInputDTO> tasks = task.getTasks();
|
||||
if(CollUtil.isEmpty( tasks)){
|
||||
throw new RuntimeException(ExceptionConstants.PARAMETER_EXCEPTION);
|
||||
}
|
||||
//创建KieSession
|
||||
KieSession kieSession = kieBase.newKieSession();
|
||||
Map<String, Object> globalParams = new HashMap<>();
|
||||
// globalParams.putAll(FireRuleMatchDefaultParams.defaults());
|
||||
kieSession.setGlobal("globalParams", globalParams);
|
||||
//获取红方阵营id
|
||||
String redObjectHandleId = getObjectHandle(task);
|
||||
if(ObjectUtil.isEmpty(redObjectHandleId)){
|
||||
throw new RuntimeException(ExceptionConstants.PARAMETER_EXCEPTION);
|
||||
}
|
||||
//获取所有武器库
|
||||
List<FireRuleInputRedWeaponElementDTO> allWeapons = task.getEquipments();
|
||||
//获取红方武器库
|
||||
List<FireRuleInputRedWeaponElementDTO> redWeapons = allWeapons.stream()
|
||||
.filter(weapon -> redObjectHandleId.equals(weapon.getOwnerForceSide()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
//创建返回数据
|
||||
FireRuleOutputVO fireRuleOutputVO = new FireRuleOutputVO();
|
||||
fireRuleOutputVO.setSourceFile(task.getSourceFile());
|
||||
|
||||
DroolsFact droolsFact = new DroolsFact();
|
||||
droolsFact.setRedWeapons(new ArrayList<>(redWeapons));
|
||||
droolsFact.setFireRuleOutputVO(fireRuleOutputVO);
|
||||
|
||||
FactHandle droolsFactHandle = null;
|
||||
try {
|
||||
for (FireRuleTaskInputDTO fireRuleTaskInputDTO : tasks) {
|
||||
droolsFact.setTask(fireRuleTaskInputDTO);
|
||||
if (droolsFactHandle == null) {
|
||||
droolsFactHandle = kieSession.insert(droolsFact);
|
||||
} else {
|
||||
kieSession.update(droolsFactHandle, droolsFact);
|
||||
}
|
||||
kieSession.fireAllRules();
|
||||
}
|
||||
} finally {
|
||||
kieSession.dispose();
|
||||
}
|
||||
|
||||
return fireRuleOutputVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有组件以及数量
|
||||
* @return
|
||||
@@ -217,4 +282,15 @@ public class FireRuleServiceImpl implements FireRuleService {
|
||||
return ruleMapper.findAllBasicPlatformComponents();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取红方阵营id
|
||||
* @param task
|
||||
* @return
|
||||
*/
|
||||
private String getObjectHandle(FireRuleInputDTO task){
|
||||
List<FireRuleInputForceSideDTO> forceSides = task.getForceSides();
|
||||
List<FireRuleInputForceSideDTO> collect = forceSides.stream().filter(f -> "红方".equals(f.getForceSideName())).collect(Collectors.toList());
|
||||
return collect.get(0).getObjectHandle();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,482 @@
|
||||
package com.solution.rule.utils;
|
||||
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleTaskInputDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleTaskWeaponDTO;
|
||||
import com.solution.rule.domain.ultimately.dto.FireRuleWeaponComponentDTO;
|
||||
import com.solution.rule.domain.ultimately.fact.DroolsFact;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleOutputVO;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleRedWeaponEquipmentVO;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleTaskInputVO;
|
||||
import com.solution.rule.domain.ultimately.vo.FireRuleTaskWeaponVO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Drools 规则调用的装备匹配逻辑。所有业务词均来自 globalParams(由 rule.drl 的 buildParam 注入),本类不写死中文业务词。
|
||||
* <p>
|
||||
* <b>总分公式(每件候选红装)</b>
|
||||
* <pre>
|
||||
* score(red) = scoreRuleSlots(...) + scoreLegacyLayer(...)
|
||||
*
|
||||
* scoreRuleSlots = Σ(i=1..ruleSlotCount) [ containsAny(blueBlob, blueRuleKeywords_i)
|
||||
* ∧ containsAny(redBlob, redRuleKeywords_i)
|
||||
* ? ruleScore_i * weight : 0 ]
|
||||
*
|
||||
* scoreLegacyLayer = ①空中平台 + ②空中任务 + ③地面任务 + ④坦克 + ⑤导弹 五段条件之和,每段若满足均为「对应 *Score * weight」
|
||||
* (五段含义见 scoreLegacyLayer 方法注释与 rule.drl 中各键说明)。
|
||||
* </pre>
|
||||
* <p>
|
||||
* <b>文本串定义</b>
|
||||
* <ul>
|
||||
* <li>blueBlob:{@link #buildBlueTextBlob} — 蓝方任务 drawName、dataType、taskWeapons 及组件名拼接成一大串,用于关键词包含判断。</li>
|
||||
* <li>redBlob:{@link #buildRedTextBlob} — 红装 name、platformType、supportType 拼接。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <b>选优与输出</b>
|
||||
* <ul>
|
||||
* <li>在 redWeapons 池中对每件算 score,取最大值;若并列,{@link #compareRedForTieBreak}(由 tieBreak 参数控制,默认 equipmentId 小者优先)。</li>
|
||||
* <li>若 maxScore < minSelectedScore:不追加 fireRuleInputs;仍将当前池映射到 FireRuleOutputVO.redWeapons。</li>
|
||||
* <li>否则:池中 remove 选中项;fireRuleInputs 追加一行,drawName += outputDrawNameSuffix,taskWeapons 一条映射自选中红装;redWeapons 为剩余池。</li>
|
||||
* </ul>
|
||||
*/
|
||||
public final class RuleFunction {
|
||||
|
||||
private RuleFunction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 单轮规则执行:对当前 DroolsFact 的一条蓝方任务,从 redWeapons 中选一件装备并写回输出。
|
||||
* <p>
|
||||
* 参数 p(globalParams)中各键含义与运算见 {@link RuleFunction} 类注释及 resources/rules/rule.drl 内 buildParam 行内注释。
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void equipmentRule(DroolsFact fact, Map globalParams) {
|
||||
if (fact == null || fact.getTask() == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> p = castParams(globalParams);
|
||||
FireRuleTaskInputDTO blue = fact.getTask();
|
||||
List<FireRuleInputRedWeaponElementDTO> pool = fact.getRedWeapons();
|
||||
if (pool == null) {
|
||||
pool = new ArrayList<>();
|
||||
fact.setRedWeapons(pool);
|
||||
}
|
||||
|
||||
// weight、minSelectedScore:见 rule.drl 注释
|
||||
String blueBlob = buildBlueTextBlob(blue);
|
||||
int weight = readInt(p, "weight", 1);
|
||||
int minScore = readInt(p, "minSelectedScore", 1);
|
||||
|
||||
int bestIndex = -1;
|
||||
int bestScore = Integer.MIN_VALUE;
|
||||
|
||||
for (int i = 0; i < pool.size(); i++) {
|
||||
FireRuleInputRedWeaponElementDTO red = pool.get(i);
|
||||
String redBlob = buildRedTextBlob(red);
|
||||
int score = scoreRuleSlots(blueBlob, redBlob, p, weight)
|
||||
+ scoreLegacyLayer(blueBlob, redBlob, p, weight);
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
bestIndex = i;
|
||||
} else if (score == bestScore && bestIndex >= 0) {
|
||||
// 并列:compareRedForTieBreak(a,b)>0 表示当前 best 的 equipmentId 比候选 red 大,应换成更小的 id
|
||||
if (compareRedForTieBreak(pool.get(bestIndex), red, p) > 0) {
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FireRuleOutputVO out = fact.getFireRuleOutputVO();
|
||||
if (out == null) {
|
||||
out = new FireRuleOutputVO();
|
||||
fact.setFireRuleOutputVO(out);
|
||||
}
|
||||
|
||||
// 未达门槛或池空:不写 fireRuleInputs,仅同步「剩余池」到输出 redWeapons
|
||||
if (bestIndex < 0 || pool.isEmpty() || bestScore < minScore) {
|
||||
out.setRedWeapons(convertPoolToEquipmentVoList(pool));
|
||||
// Tasks 由最终输出 redWeapons 一一生成(一个装备 -> 一个任务)
|
||||
out.setTasks(FireRuleRedWeaponOutputFillHelper.toTaskNodes(out.getRedWeapons()));
|
||||
return;
|
||||
}
|
||||
|
||||
pool.remove(bestIndex);
|
||||
|
||||
out.setRedWeapons(convertPoolToEquipmentVoList(pool));
|
||||
// Tasks 由最终输出 redWeapons 一一生成(一个装备 -> 一个任务)
|
||||
out.setTasks(FireRuleRedWeaponOutputFillHelper.toTaskNodes(out.getRedWeapons()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 目标规则:显式为 Tasks 填 targetId,并按红方命中率不足时补拿装备(出池,带上限)。
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void target(DroolsFact fact, Map globalParams){
|
||||
if (fact == null || fact.getTask() == null || fact.getFireRuleOutputVO() == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> p = castParams(globalParams);
|
||||
FireRuleTaskInputDTO blue = fact.getTask();
|
||||
FireRuleOutputVO out = fact.getFireRuleOutputVO();
|
||||
List<FireRuleInputRedWeaponElementDTO> pool = fact.getRedWeapons();
|
||||
if (pool == null) {
|
||||
pool = new ArrayList<>();
|
||||
fact.setRedWeapons(pool);
|
||||
}
|
||||
if (out.getRedWeapons() == null) {
|
||||
out.setRedWeapons(convertPoolToEquipmentVoList(pool));
|
||||
}
|
||||
if (out.getTasks() == null || out.getTasks().size() != out.getRedWeapons().size()) {
|
||||
out.setTasks(FireRuleRedWeaponOutputFillHelper.toTaskNodes(out.getRedWeapons()));
|
||||
}
|
||||
|
||||
double threshold = readDouble(p, "redHitRateThreshold", 0.6d);
|
||||
int maxExtra = readInt(p, "maxExtraWeaponsPerTask", 2);
|
||||
int maxRounds = readInt(p, "maxSupplementRounds", 5);
|
||||
int extraMinScore = readInt(p, "extraPickMinScore", 1);
|
||||
int weight = readInt(p, "weight", 1);
|
||||
String blueBlob = buildBlueTextBlob(blue);
|
||||
|
||||
if (maxExtra > 0 && maxRounds > 0 && !pool.isEmpty()) {
|
||||
Set<String> selectedIds = new HashSet<>();
|
||||
for (FireRuleRedWeaponEquipmentVO w : out.getRedWeapons()) {
|
||||
if (w != null && !isBlank(w.getEquipmentId())) {
|
||||
selectedIds.add(w.getEquipmentId());
|
||||
}
|
||||
}
|
||||
|
||||
int extraCount = 0;
|
||||
int rounds = 0;
|
||||
while (rounds < maxRounds && extraCount < maxExtra && !pool.isEmpty()) {
|
||||
rounds++;
|
||||
boolean needExtra = false;
|
||||
for (FireRuleRedWeaponEquipmentVO w : out.getRedWeapons()) {
|
||||
Double rad = w != null ? w.getSuccessTargetRad() : null;
|
||||
if (rad == null || rad.doubleValue() < threshold) {
|
||||
needExtra = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!needExtra) {
|
||||
break;
|
||||
}
|
||||
|
||||
int bestIdx = -1;
|
||||
int bestScore = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < pool.size(); i++) {
|
||||
FireRuleInputRedWeaponElementDTO red = pool.get(i);
|
||||
if (red == null) {
|
||||
continue;
|
||||
}
|
||||
if (!isBlank(red.getEquipmentId()) && selectedIds.contains(red.getEquipmentId())) {
|
||||
continue;
|
||||
}
|
||||
String redBlob = buildRedTextBlob(red);
|
||||
int s = scoreRuleSlots(blueBlob, redBlob, p, weight)
|
||||
+ scoreLegacyLayer(blueBlob, redBlob, p, weight);
|
||||
if (s > bestScore) {
|
||||
bestScore = s;
|
||||
bestIdx = i;
|
||||
} else if (s == bestScore && bestIdx >= 0) {
|
||||
if (compareRedForTieBreak(pool.get(bestIdx), red, p) > 0) {
|
||||
bestIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestIdx < 0 || bestScore < extraMinScore) {
|
||||
break;
|
||||
}
|
||||
FireRuleInputRedWeaponElementDTO extra = pool.remove(bestIdx);
|
||||
FireRuleRedWeaponEquipmentVO vo = toRedEquipmentVo(extra);
|
||||
out.getRedWeapons().add(vo);
|
||||
if (!isBlank(vo.getEquipmentId())) {
|
||||
selectedIds.add(vo.getEquipmentId());
|
||||
}
|
||||
extraCount++;
|
||||
}
|
||||
}
|
||||
|
||||
out.setTasks(FireRuleRedWeaponOutputFillHelper.toTaskNodes(out.getRedWeapons()));
|
||||
FireRuleRedWeaponOutputFillHelper.assignTargetsToTasks(out.getTasks(), out.getRedWeapons(), blue, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 阵位规则:根据蓝方武器 coordinate + trackPoints + warZone 计算红方平台 positions。
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void position(DroolsFact fact, Map globalParams) {
|
||||
if (fact == null || fact.getTask() == null || fact.getFireRuleOutputVO() == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> p = castParams(globalParams);
|
||||
boolean enabled = Boolean.parseBoolean(String.valueOf(p.getOrDefault("positionRuleEnabled", true)));
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
FireRuleOutputVO out = fact.getFireRuleOutputVO();
|
||||
if (out.getRedWeapons() == null || out.getRedWeapons().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
FireRuleRedWeaponOutputFillHelper.fillPlatformPositions(out.getRedWeapons(), fact.getTask(), p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 航迹规则:根据蓝方 trackPoints 与作战区生成 TrackParam 航迹,并绑定 execute.targetList.moveRouteId。
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void trackRoute(DroolsFact fact, Map globalParams) {
|
||||
if (fact == null || fact.getTask() == null || fact.getFireRuleOutputVO() == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> p = castParams(globalParams);
|
||||
boolean enabled = Boolean.parseBoolean(String.valueOf(p.getOrDefault("trackRuleEnabled", true)));
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
FireRuleOutputVO out = fact.getFireRuleOutputVO();
|
||||
if (out.getTasks() == null || out.getTasks().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
FireRuleRedWeaponOutputFillHelper.fillTrackParamAndBindMoveRoute(out, fact.getTask(), p);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<String, Object> castParams(Map raw) {
|
||||
return raw == null ? new java.util.HashMap<>() : (Map<String, Object>) raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 蓝方侧用于「关键词包含」判断的合并文本(空格分隔各字段)。
|
||||
*/
|
||||
private static String buildBlueTextBlob(FireRuleTaskInputDTO task) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
append(sb, task.getDrawName());
|
||||
append(sb, task.getDataType());
|
||||
if (task.getTaskWeapons() != null) {
|
||||
for (FireRuleTaskWeaponDTO w : task.getTaskWeapons()) {
|
||||
if (w == null) {
|
||||
continue;
|
||||
}
|
||||
append(sb, w.getName());
|
||||
append(sb, w.getSupportType());
|
||||
append(sb, w.getEquipmentId());
|
||||
if (w.getComponents() != null) {
|
||||
for (FireRuleWeaponComponentDTO c : w.getComponents()) {
|
||||
if (c == null) {
|
||||
continue;
|
||||
}
|
||||
append(sb, c.getDeviceName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 红方侧用于「关键词包含」判断的合并文本。
|
||||
*/
|
||||
private static String buildRedTextBlob(FireRuleInputRedWeaponElementDTO red) {
|
||||
if (red == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
append(sb, red.getName());
|
||||
append(sb, red.getPlatformType());
|
||||
append(sb, red.getSupportType());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void append(StringBuilder sb, String s) {
|
||||
if (s != null && !s.isEmpty()) {
|
||||
sb.append(s).append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 规则槽得分:对 i=1..ruleSlotCount,若 blueBlob 命中 blueRuleKeywords_i 且 redBlob 命中 redRuleKeywords_i,
|
||||
* 则累加 ruleScore_i * weight。关键词为英文逗号分隔,任一词作为子串出现在文本中即命中。
|
||||
*/
|
||||
private static int scoreRuleSlots(String blueBlob, String redBlob, Map<String, Object> p, int weight) {
|
||||
int n = readInt(p, "ruleSlotCount", 0);
|
||||
int sum = 0;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
String bk = str(p, "blueRuleKeywords_" + i, "");
|
||||
String rk = str(p, "redRuleKeywords_" + i, "");
|
||||
if (bk.isEmpty() || rk.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (containsAny(blueBlob, bk) && containsAny(redBlob, rk)) {
|
||||
sum += readInt(p, "ruleScore_" + i, 0) * weight;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 兼容层得分:五段独立条件,可叠加。每段均为「蓝关键词命中 ∧ 红关键词命中 → 加 对应分数 * weight」。
|
||||
* <ul>
|
||||
* <li>① bluePlatformKeywords_air + redPreferredWhenBlueAir → airScore</li>
|
||||
* <li>② airTaskKeywords + redPreferredWhenBlueAir → airTaskScore</li>
|
||||
* <li>③ groundTaskKeywords + redPreferredWhenGround → groundScore</li>
|
||||
* <li>④ tankKeywords + redMatchKeywords_tank → tankScore</li>
|
||||
* <li>⑤ missileKeywords + redMatchKeywords_missile → missileScore</li>
|
||||
* </ul>
|
||||
* 键名与 rule.drl 中 param.put 一致。
|
||||
*/
|
||||
private static int scoreLegacyLayer(String blueBlob, String redBlob, Map<String, Object> p, int weight) {
|
||||
int s = 0;
|
||||
if (containsAny(blueBlob, str(p, "bluePlatformKeywords_air", ""))
|
||||
&& containsAny(redBlob, str(p, "redPreferredWhenBlueAir", ""))) {
|
||||
s += readInt(p, "airScore", 0) * weight;
|
||||
}
|
||||
if (containsAny(blueBlob, str(p, "airTaskKeywords", ""))
|
||||
&& containsAny(redBlob, str(p, "redPreferredWhenBlueAir", ""))) {
|
||||
s += readInt(p, "airTaskScore", 0) * weight;
|
||||
}
|
||||
if (containsAny(blueBlob, str(p, "groundTaskKeywords", ""))
|
||||
&& containsAny(redBlob, str(p, "redPreferredWhenGround", ""))) {
|
||||
s += readInt(p, "groundScore", 0) * weight;
|
||||
}
|
||||
if (containsAny(blueBlob, str(p, "tankKeywords", ""))
|
||||
&& containsAny(redBlob, str(p, "redMatchKeywords_tank", ""))) {
|
||||
s += readInt(p, "tankScore", 0) * weight;
|
||||
}
|
||||
if (containsAny(blueBlob, str(p, "missileKeywords", ""))
|
||||
&& containsAny(redBlob, str(p, "redMatchKeywords_missile", ""))) {
|
||||
s += readInt(p, "missileScore", 0) * weight;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 并列时比较两件红装:tieBreak=equipmentId 时返回 id 字典序比较结果(>0 表示 a 的 id 大于 b,应选 b)。
|
||||
*/
|
||||
private static int compareRedForTieBreak(
|
||||
FireRuleInputRedWeaponElementDTO a,
|
||||
FireRuleInputRedWeaponElementDTO b,
|
||||
Map<String, Object> p) {
|
||||
if (a == null) {
|
||||
return b == null ? 0 : 1;
|
||||
}
|
||||
if (b == null) {
|
||||
return -1;
|
||||
}
|
||||
String mode = str(p, "tieBreak", "equipmentId");
|
||||
if ("equipmentId".equals(mode)) {
|
||||
String ida = nz(a.getEquipmentId());
|
||||
String idb = nz(b.getEquipmentId());
|
||||
return ida.compareTo(idb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* commaKeywords:英文逗号分隔;若 text 包含其中任一词(trim 后非空)则命中。
|
||||
*/
|
||||
private static boolean containsAny(String text, String commaKeywords) {
|
||||
if (text == null || text.isEmpty() || commaKeywords == null || commaKeywords.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (String part : commaKeywords.split(",")) {
|
||||
String k = part.trim();
|
||||
if (!k.isEmpty() && text.contains(k)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String str(Map<String, Object> p, String key, String def) {
|
||||
Object v = p.get(key);
|
||||
return v == null ? def : String.valueOf(v);
|
||||
}
|
||||
|
||||
private static int readInt(Map<String, Object> p, String key, int def) {
|
||||
Object v = p.get(key);
|
||||
if (v == null) {
|
||||
return def;
|
||||
}
|
||||
if (v instanceof Number) {
|
||||
return ((Number) v).intValue();
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(String.valueOf(v).trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
private static double readDouble(Map<String, Object> p, String key, double def) {
|
||||
Object v = p.get(key);
|
||||
if (v == null) {
|
||||
return def;
|
||||
}
|
||||
if (v instanceof Number) {
|
||||
return ((Number) v).doubleValue();
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(String.valueOf(v).trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
private static String nz(String s) {
|
||||
return s == null ? "" : s;
|
||||
}
|
||||
|
||||
private static boolean isBlank(String s) {
|
||||
return s == null || s.trim().isEmpty();
|
||||
}
|
||||
|
||||
private static FireRuleTaskWeaponVO toTaskWeaponVo(FireRuleInputRedWeaponElementDTO r) {
|
||||
FireRuleTaskWeaponVO w = new FireRuleTaskWeaponVO();
|
||||
if (r != null) {
|
||||
w.setEquipmentId(r.getEquipmentId());
|
||||
w.setName(r.getName());
|
||||
w.setSupportType(r.getSupportType());
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
private static List<FireRuleRedWeaponEquipmentVO> convertPoolToEquipmentVoList(
|
||||
List<FireRuleInputRedWeaponElementDTO> pool) {
|
||||
List<FireRuleRedWeaponEquipmentVO> list = new ArrayList<>();
|
||||
if (pool == null) {
|
||||
return list;
|
||||
}
|
||||
for (FireRuleInputRedWeaponElementDTO e : pool) {
|
||||
list.add(toRedEquipmentVo(e));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static FireRuleRedWeaponEquipmentVO toRedEquipmentVo(FireRuleInputRedWeaponElementDTO src) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
FireRuleRedWeaponEquipmentVO vo = new FireRuleRedWeaponEquipmentVO();
|
||||
vo.setSupportType(src.getSupportType());
|
||||
vo.setTroopsDetail(src.getTroopsDetail());
|
||||
vo.setPlatformType(src.getPlatformType());
|
||||
vo.setIsStrikeTarget(src.getIsStrikeTarget());
|
||||
vo.setIsReconTarget(src.getIsReconTarget());
|
||||
vo.setIsInterferenceTarget(src.getIsInterferenceTarget());
|
||||
vo.setIsDefendImportantPlace(src.getIsDefendImportantPlace());
|
||||
vo.setSuccessTargetRad(src.getSuccessTargetRad());
|
||||
vo.setGroupType(src.getGroupType());
|
||||
vo.setEquipmentId(src.getEquipmentId());
|
||||
vo.setName(src.getName());
|
||||
vo.setOwnerForceSide(src.getOwnerForceSide());
|
||||
vo.setPlatId(src.getPlatId());
|
||||
vo.setSubComponents(FireRuleRedWeaponOutputFillHelper.toOutputSubComponents(src.getSubComponents()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
}
|
||||
392
auto-solution-rule/src/main/resources/json/new火力规则输出.json
Normal file
392
auto-solution-rule/src/main/resources/json/new火力规则输出.json
Normal file
@@ -0,0 +1,392 @@
|
||||
{
|
||||
"sourceFile": "区域防空31111_2026-04-02 15_29_03.json",
|
||||
"fireRuleInputs": [
|
||||
{
|
||||
"taskWeapons": [
|
||||
{
|
||||
"equipmentId": "40b341f6-d60a-4a29-b84d-2973a3065124",
|
||||
"name": "导弹",
|
||||
"supportType": "2001",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "81c7e7da-cb7b-4435-bba3-1648e946d2b2",
|
||||
"deviceName": "导弹机动组件",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "b47f34c2-3cba-4be3-a1d5-be0a986dff6f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "4cf26cd0-bd5b-4d4c-a2eb-bca6184be5a1",
|
||||
"deviceName": "导弹平台",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "32beea38-ffc2-445a-9687-e9bdb087727f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"coordinate": {
|
||||
"longitude": 124.74107151788,
|
||||
"latitude": 26.74143394432,
|
||||
"height": -498.06469972014
|
||||
},
|
||||
"number": 10,
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1"
|
||||
}
|
||||
],
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1",
|
||||
"warZoneLocation": [
|
||||
{
|
||||
"longitude": 122.18971775079,
|
||||
"latitude": 28.64177652916,
|
||||
"height": -99.95248993318
|
||||
},
|
||||
{
|
||||
"longitude": 127.22874089381,
|
||||
"latitude": 28.54075963352,
|
||||
"height": -1063.0224849918
|
||||
},
|
||||
{
|
||||
"longitude": 127.99831970891,
|
||||
"latitude": 23.81306022325,
|
||||
"height": -5900.62524601637
|
||||
},
|
||||
{
|
||||
"longitude": 120.14866648107,
|
||||
"latitude": 23.90272134296,
|
||||
"height": -22.17614107099
|
||||
}
|
||||
],
|
||||
"defZoneLocation": []
|
||||
}
|
||||
],
|
||||
"TrackParam": {
|
||||
"routeLine_220e5b3c-270d-4006-87f0-a0ab4b22deda": {
|
||||
"name": "F-22航线1",
|
||||
"StartTime": 0,
|
||||
"EndTime": 1657,
|
||||
"TrackType": "routeLineAir",
|
||||
"HeightType": "msl",
|
||||
"seaType": "seaLevel",
|
||||
"TrackPoints": [
|
||||
{
|
||||
"index": "1",
|
||||
"longitude": "124.69258218394617",
|
||||
"latitude": "27.801527639000142",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "2",
|
||||
"longitude": "122.9223606765063",
|
||||
"latitude": "27.585793910609084",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "3",
|
||||
"longitude": "121.59995205693548",
|
||||
"latitude": "27.41556157737817",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "4",
|
||||
"longitude": "121.00161216798338",
|
||||
"latitude": "27.07354384591234",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "5",
|
||||
"longitude": "121.0190476615353",
|
||||
"latitude": "26.599336790536423",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "6",
|
||||
"longitude": "121.67869100949231",
|
||||
"latitude": "26.183061747705537",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "7",
|
||||
"longitude": "123.7900051477299",
|
||||
"latitude": "25.733670416880216",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
},
|
||||
{
|
||||
"index": "8",
|
||||
"longitude": "125.47545066085917",
|
||||
"latitude": "26.136857380879235",
|
||||
"height": "6000",
|
||||
"speed": "600",
|
||||
"psia": "0",
|
||||
"time": 0,
|
||||
"active": "null"
|
||||
}
|
||||
],
|
||||
"Color": "rgb(4,161,246)",
|
||||
"PointCount": 8
|
||||
},
|
||||
"Groups": [
|
||||
{
|
||||
"allAngle": 0,
|
||||
"drawName": "J15编组1",
|
||||
"editPermission": [],
|
||||
"groupType": "addGroup",
|
||||
"id": "5dea9ff7-5e45-4f8e-a67f-3ff4187c39ed",
|
||||
"idKey": "id",
|
||||
"isSelected": false,
|
||||
"isShow": false,
|
||||
"leader": "7a16c098-ceec-4c4d-8a24-8f44976a90ca",
|
||||
"name": "addGroup",
|
||||
"parentId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_batFormation",
|
||||
"permission": [
|
||||
"14bc8ff9-3c93-4218-b01a-e144add196f9"
|
||||
],
|
||||
"show": false,
|
||||
"sort": 1774271497726,
|
||||
"wingmanData": [
|
||||
{
|
||||
"alt": 40,
|
||||
"angle": "50",
|
||||
"distance": 100,
|
||||
"key": 0,
|
||||
"name": "9aa9e5aa-9273-4c27-88e1-e582ff561685"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"redWeapons": [
|
||||
{
|
||||
"SupportType": "car",
|
||||
"TroopsDetail": {},
|
||||
"Platform_type": "HQ-9发射车",
|
||||
"isStrikeTarget": false,
|
||||
"isReconTarget": false,
|
||||
"isInterferenceTarget": false,
|
||||
"isDefendImportantPlace": false,
|
||||
"groupType": "equipment",
|
||||
"EquipmentID": "b3c6de29-2b27-4500-a9ce-95d0bebc5cb9",
|
||||
"Name": "HQ-9发射车--5",
|
||||
"OwnerForceSide": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"PlatID": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_equipmentPlane",
|
||||
"SubComponents": {
|
||||
"communication": [
|
||||
{
|
||||
"ObjectHandle": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"arithmetic": {
|
||||
"id": "66cd29fdce08f520f1d9bf0e",
|
||||
"name": "短波电台"
|
||||
},
|
||||
"device": {
|
||||
"id": "5e0e5b064f1fae2ee9fa1000",
|
||||
"name": "3MHZ通信电台",
|
||||
"refId": "5e0e5b064f1fae2ee9fa1000"
|
||||
},
|
||||
"deviceId": "0b700ca6-290e-422a-b4e3-73b222809938",
|
||||
"deviceName": "3MHZ通信电台",
|
||||
"employLabel": false,
|
||||
"facilityName": "3MHZ通信电台",
|
||||
"soleId": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"motorized_assembly": [
|
||||
{
|
||||
"ObjectHandle": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"arithmetic": {},
|
||||
"device": {},
|
||||
"deviceId": "55915bc4-c825-43c4-93eb-6a76ab345e42",
|
||||
"deviceName": "",
|
||||
"soleId": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"platform": [
|
||||
{
|
||||
"ObjectHandle": "04a96dbc-837a-48be-8c04-e4f53586c47e",
|
||||
"arithmetic": {
|
||||
"id": "68876d0fd41989f086e905b8",
|
||||
"name": "通用发射车算法"
|
||||
},
|
||||
"device": {
|
||||
"id": "68876d2dd41989f086e905b9",
|
||||
"name": "发射车平台",
|
||||
"refId": "68876d2dd41989f086e905b9"
|
||||
},
|
||||
"deviceId": "164c75ec-6db5-48f9-8285-a7e726fd2a11",
|
||||
"deviceName": "发射车平台",
|
||||
"employLabel": false,
|
||||
"facilityName": "发射车平台",
|
||||
"soleId": "87905d6b-857a-4c5a-a922-5e2d191588d4",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"TrackParamId": "",
|
||||
"positions": [
|
||||
119.28585462691,
|
||||
25.67974332623,
|
||||
34.28352933882
|
||||
]
|
||||
}
|
||||
],
|
||||
"weapon": [
|
||||
{
|
||||
"ObjectHandle": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"arithmetic": {
|
||||
"id": "669dd6356bc286bd64e5d66c",
|
||||
"name": "发射架算法"
|
||||
},
|
||||
"codedQueue": "weapon.launcher",
|
||||
"configuration": {
|
||||
"classifyName": "导弹平台",
|
||||
"isMount": 1,
|
||||
"mountedWeapon": {
|
||||
"_id": "68f681794ddde62a52c7e569",
|
||||
"name": "HQ-9"
|
||||
},
|
||||
"number": 4
|
||||
},
|
||||
"device": {
|
||||
"id": "67ff279dafa7ea5aaa3a1236",
|
||||
"name": "通用发射架",
|
||||
"refId": "b9665788-9437-40fb-8a24-eff3d4d3b529"
|
||||
},
|
||||
"deviceId": "4e910ccf-d937-4a93-9b68-116167eda202",
|
||||
"deviceName": "通用发射架",
|
||||
"employLabel": false,
|
||||
"facilityName": "通用发射架",
|
||||
"serialNumber": "launcher",
|
||||
"soleId": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"twiceModified": {
|
||||
"launcherType": "sam"
|
||||
},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"color": "rgb(220,39,39)",
|
||||
"dataType": "taskPlane",
|
||||
"drawName": "HQ-9发射车--3打击任务",
|
||||
"groupType": "tasks",
|
||||
"id": "41d3c5ce-3fda-4dee-a38f-fd3ae7e15e69",
|
||||
"idKey": "id",
|
||||
"isSelected": false,
|
||||
"name": "HQ-9发射车--3打击任务",
|
||||
"parentId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_taskPlane",
|
||||
"permission": [
|
||||
"14bc8ff9-3c93-4218-b01a-e144add196f9",
|
||||
"56a96b1b-14a8-4daf-a2d0-47c7faa4b831"
|
||||
],
|
||||
"show": true,
|
||||
"side": "红方",
|
||||
"sort": 1774271151846,
|
||||
"task": {
|
||||
"at_time": "180",
|
||||
"attackId": "267c5d87-bf36-42f2-b0a8-09c608d94b62",
|
||||
"color": "rgb(220,39,39)",
|
||||
"departureAirport": "",
|
||||
"execute": [
|
||||
{
|
||||
"targetList": [
|
||||
{
|
||||
"ID": "fbddc49c-f7b0-4d07-8000-1b5a2633c461",
|
||||
"arrayPositionId": 4,
|
||||
"arrayPositionIdBak": "",
|
||||
"at_time": {
|
||||
"timeUp": true,
|
||||
"value": 180
|
||||
},
|
||||
"attackType": "",
|
||||
"boost": "",
|
||||
"bootTime": "",
|
||||
"companion": "",
|
||||
"cruiseRouteId": "routeLine_f01be820-33ca-4843-8354-3f93a9986fe3",
|
||||
"cruiseRouteOffset": [
|
||||
{
|
||||
"UpOrDown": true,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"BeforeOrAfter": true,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"LeftOrRight": true,
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"moveRouteId": "routeLine_de092f0b-d8a3-4382-8e46-398efae3649c",
|
||||
"fireType": "absolute",
|
||||
"strategy": [],
|
||||
"targetId": "dd20d7d9-7ce8-4531-aa0c-0b2056e7fbcd",
|
||||
"times_interval": 1,
|
||||
"weaponId": "HQ-9",
|
||||
"weaponRelease": "",
|
||||
"weaponType": "",
|
||||
"weaponUseCount": 3
|
||||
}
|
||||
],
|
||||
"type": "assault"
|
||||
}
|
||||
],
|
||||
"landAirport": "",
|
||||
"missionList": [
|
||||
{
|
||||
"label": "HQ-9(4)",
|
||||
"launcherType": "sam",
|
||||
"number": 4,
|
||||
"value": "HQ-9"
|
||||
}
|
||||
],
|
||||
"name": "HQ-9发射车--3打击任务",
|
||||
"side": "红方",
|
||||
"sideId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"speed": 600,
|
||||
"type": "assault",
|
||||
"weaponId": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
349
auto-solution-rule/src/main/resources/json/火力规则输入-无注释.json
Normal file
349
auto-solution-rule/src/main/resources/json/火力规则输入-无注释.json
Normal file
@@ -0,0 +1,349 @@
|
||||
{
|
||||
"sourceFile": "区域防空31111_2026-04-02 15_29_03.json",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "ed0e67e8-691f-4902-bb67-bd289aec89a1",
|
||||
"drawName": "F-22-1打击任务",
|
||||
"dataType": "taskPlane",
|
||||
"side": "BLUE",
|
||||
"trackPointsId": "d685ca26-2ffa-4b2b-8e75-ecf5897338f5",
|
||||
"trackPoints": [
|
||||
{
|
||||
"index": 1,
|
||||
"longitude": 124.02895007578839,
|
||||
"latitude": 26.836172676390202,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"longitude": 122.81034067987203,
|
||||
"latitude": 27.017765463140986,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"longitude": 121.49435868664283,
|
||||
"latitude": 27.17048502942595,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"longitude": 120.87774502345792,
|
||||
"latitude": 27.16848996890842,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"longitude": 120.86773193816859,
|
||||
"latitude": 26.390372000100005,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"longitude": 122.81161998730377,
|
||||
"latitude": 25.50052904615808,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"longitude": 125.09035998725984,
|
||||
"latitude": 24.79876865711152,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
}
|
||||
],
|
||||
"taskWeapons": [
|
||||
{
|
||||
"equipmentId": "40b341f6-d60a-4a29-b84d-2973a3065124",
|
||||
"name": "导弹",
|
||||
"supportType": "2001",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "81c7e7da-cb7b-4435-bba3-1648e946d2b2",
|
||||
"deviceName": "导弹机动组件",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "b47f34c2-3cba-4be3-a1d5-be0a986dff6f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "4cf26cd0-bd5b-4d4c-a2eb-bca6184be5a1",
|
||||
"deviceName": "导弹平台",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "32beea38-ffc2-445a-9687-e9bdb087727f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"coordinate": {
|
||||
"longitude": 124.74107151788,
|
||||
"latitude": 26.74143394432,
|
||||
"height": -498.06469972014
|
||||
},
|
||||
"number": "1" ,
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1"
|
||||
}
|
||||
],
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1",
|
||||
"warZoneLocation": [
|
||||
{
|
||||
"longitude": 122.18971775079,
|
||||
"latitude": 28.64177652916,
|
||||
"height": -99.95248993318
|
||||
},
|
||||
{
|
||||
"longitude": 127.22874089381,
|
||||
"latitude": 28.54075963352,
|
||||
"height": -1063.0224849918
|
||||
},
|
||||
{
|
||||
"longitude": 127.99831970891,
|
||||
"latitude": 23.81306022325,
|
||||
"height": -5900.62524601637
|
||||
},
|
||||
{
|
||||
"longitude": 120.14866648107,
|
||||
"latitude": 23.90272134296,
|
||||
"height": -22.17614107099
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"redWeapons": [
|
||||
{
|
||||
"name": "HQ-9",
|
||||
"id": "07e18ffb-3826-4e84-b884-68d77838ae25",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "89a639f5-3675-457b-ad4c-6b91a8d900e3",
|
||||
"deviceName": "",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "647087e6-ccad-4b14-ba32-9962ae42eee7",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "7c6529f5-3fe5-4cfe-b4c8-b5a5a8178cda",
|
||||
"deviceName": "导弹平台",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "a2ac6d74-09ac-49d5-8e05-fcaec47757c5",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"number": 1,
|
||||
"successTargetRad": "命中率",
|
||||
"isLead": {
|
||||
"leader": "长机平台的唯一标识 id",
|
||||
"side": "阵营",
|
||||
"supportType": "长机平台类型",
|
||||
"positions": [
|
||||
{
|
||||
"longitude": "经度",
|
||||
"latitude": "纬度",
|
||||
"height": "高度"
|
||||
}
|
||||
]
|
||||
},
|
||||
"isWing": [
|
||||
{
|
||||
"name": "僚机名称",
|
||||
"distance": "距离",
|
||||
"angle": "角度",
|
||||
"alt": "高度差"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SupportType": "car",
|
||||
"TroopsDetail": {},
|
||||
"Platform_type": "HQ-9发射车",
|
||||
"isStrikeTarget": false,
|
||||
"isReconTarget": false,
|
||||
"isInterferenceTarget": false,
|
||||
"isDefendImportantPlace": false,
|
||||
"groupType": "equipment",
|
||||
"EquipmentID": "b3c6de29-2b27-4500-a9ce-95d0bebc5cb9",
|
||||
"Name": "HQ-9发射车--5",
|
||||
"OwnerForceSide": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"PlatID": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_equipmentPlane",
|
||||
"SubComponents": {
|
||||
"communication": [
|
||||
{
|
||||
"ObjectHandle": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"arithmetic": {
|
||||
"id": "66cd29fdce08f520f1d9bf0e",
|
||||
"name": "短波电台"
|
||||
},
|
||||
"device": {
|
||||
"id": "5e0e5b064f1fae2ee9fa1000",
|
||||
"name": "3MHZ通信电台",
|
||||
"refId": "5e0e5b064f1fae2ee9fa1000"
|
||||
},
|
||||
"deviceId": "0b700ca6-290e-422a-b4e3-73b222809938",
|
||||
"deviceName": "3MHZ通信电台",
|
||||
"employLabel": false,
|
||||
"facilityName": "3MHZ通信电台",
|
||||
"soleId": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"motorized_assembly": [
|
||||
{
|
||||
"ObjectHandle": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"arithmetic": {},
|
||||
"device": {},
|
||||
"deviceId": "55915bc4-c825-43c4-93eb-6a76ab345e42",
|
||||
"deviceName": "",
|
||||
"soleId": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"platform": [
|
||||
{
|
||||
"ObjectHandle": "04a96dbc-837a-48be-8c04-e4f53586c47e",
|
||||
"arithmetic": {
|
||||
"id": "68876d0fd41989f086e905b8",
|
||||
"name": "通用发射车算法"
|
||||
},
|
||||
"device": {
|
||||
"id": "68876d2dd41989f086e905b9",
|
||||
"name": "发射车平台",
|
||||
"refId": "68876d2dd41989f086e905b9"
|
||||
},
|
||||
"deviceId": "164c75ec-6db5-48f9-8285-a7e726fd2a11",
|
||||
"deviceName": "发射车平台",
|
||||
"employLabel": false,
|
||||
"facilityName": "发射车平台",
|
||||
"soleId": "87905d6b-857a-4c5a-a922-5e2d191588d4",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"TrackParamId": "",
|
||||
"positions": [
|
||||
119.28585462691,
|
||||
25.67974332623,
|
||||
34.28352933882
|
||||
]
|
||||
}
|
||||
],
|
||||
"weapon": [
|
||||
{
|
||||
"ObjectHandle": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"arithmetic": {
|
||||
"id": "669dd6356bc286bd64e5d66c",
|
||||
"name": "发射架算法"
|
||||
},
|
||||
"codedQueue": "weapon.launcher",
|
||||
"configuration": {
|
||||
"classifyName": "导弹平台",
|
||||
"isMount": 1,
|
||||
"mountedWeapon": {
|
||||
"_id": "68f681794ddde62a52c7e569",
|
||||
"name": "HQ-9"
|
||||
},
|
||||
"number": 4
|
||||
},
|
||||
"device": {
|
||||
"id": "67ff279dafa7ea5aaa3a1236",
|
||||
"name": "通用发射架",
|
||||
"refId": "b9665788-9437-40fb-8a24-eff3d4d3b529"
|
||||
},
|
||||
"deviceId": "4e910ccf-d937-4a93-9b68-116167eda202",
|
||||
"deviceName": "通用发射架",
|
||||
"employLabel": false,
|
||||
"facilityName": "通用发射架",
|
||||
"serialNumber": "launcher",
|
||||
"soleId": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"twiceModified": {
|
||||
"launcherType": "sam"
|
||||
},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "营指挥所",
|
||||
"id": "9843e2ec-59a5-440f-9669-67f910b8edc3",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "7f41d14e-83bc-41c7-8e20-cb61f4fc1289",
|
||||
"deviceName": "",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "5da5f834-a8a9-407d-8a10-6dc78e488af9",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "591217ed-04e5-4120-87db-b5896d87b44d",
|
||||
"deviceName": "地面指挥所",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "2c53125c-76da-4454-9f91-04ab3c940b9a",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"number": 1,
|
||||
"successTargetRad": "命中率"
|
||||
},
|
||||
{
|
||||
"name": "防区2",
|
||||
"id": "c2259481-279a-4c10-ae45-cf2a669e7b52_Circle",
|
||||
"isLead": {
|
||||
"drawName": "圆形名称",
|
||||
"airspaceType": "空域类型",
|
||||
"side": "阵营",
|
||||
"selectLonLat": "positions",
|
||||
"positions": [
|
||||
{
|
||||
"longitude": "圆心经度",
|
||||
"latitude": "圆心纬度",
|
||||
"height": "圆心高程"
|
||||
}
|
||||
],
|
||||
"radius": "圆半径(KM)",
|
||||
"height": "高度(米)",
|
||||
"extrudedHeight": "离地高度(米)"
|
||||
},
|
||||
"isWing": {
|
||||
"outlineWidth": "线宽",
|
||||
"lineType": "线条",
|
||||
"outlineColor": "轮廓色",
|
||||
"color": "填充色"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
474
auto-solution-rule/src/main/resources/json/火力规则输入.json
Normal file
474
auto-solution-rule/src/main/resources/json/火力规则输入.json
Normal file
@@ -0,0 +1,474 @@
|
||||
{
|
||||
"_comment_sourceFile": "来源场景文件名",
|
||||
"sourceFile": "区域防空31111_2026-04-02 15_29_03.json",
|
||||
"_comment_tasks": "蓝方火力规则任务列表(数组,每项为一条任务)",
|
||||
"tasks": [
|
||||
{
|
||||
"_comment_id": "任务id:唯一标识符",
|
||||
"id": "ed0e67e8-691f-4902-bb67-bd289aec89a1",
|
||||
"_comment_drawName": "任务名称",
|
||||
"drawName": "F-22-1打击任务",
|
||||
"_comment_dataType": "任务类型",
|
||||
"dataType": "taskPlane",
|
||||
"_comment_side": "任务所属阵营",
|
||||
"side": "BLUE",
|
||||
"_comment_trackPointsId": "航迹所属实体/阵营标识",
|
||||
"trackPointsId": "d685ca26-2ffa-4b2b-8e75-ecf5897338f5",
|
||||
"_comment_trackPoints": "任务航迹点列表",
|
||||
"trackPoints": [
|
||||
{
|
||||
"index": 1,
|
||||
"longitude": 124.02895007578839,
|
||||
"latitude": 26.836172676390202,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"longitude": 122.81034067987203,
|
||||
"latitude": 27.017765463140986,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"longitude": 121.49435868664283,
|
||||
"latitude": 27.17048502942595,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"longitude": 120.87774502345792,
|
||||
"latitude": 27.16848996890842,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"longitude": 120.86773193816859,
|
||||
"latitude": 26.390372000100005,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"longitude": 122.81161998730377,
|
||||
"latitude": 25.50052904615808,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"longitude": 125.09035998725984,
|
||||
"latitude": 24.79876865711152,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
}
|
||||
],
|
||||
"_comment_taskWeapons": "任务武器配置列表",
|
||||
"taskWeapons": [
|
||||
{
|
||||
"_comment_equipmentId": "装备id:武器唯一标识",
|
||||
"equipmentId": "40b341f6-d60a-4a29-b84d-2973a3065124",
|
||||
"_comment_name": "装备名称",
|
||||
"name": "导弹",
|
||||
"_comment_supportType": "装备类型",
|
||||
"supportType": "2001",
|
||||
"_comment_components": "装备组件列表",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "81c7e7da-cb7b-4435-bba3-1648e946d2b2",
|
||||
"deviceName": "导弹机动组件",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "b47f34c2-3cba-4be3-a1d5-be0a986dff6f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "4cf26cd0-bd5b-4d4c-a2eb-bca6184be5a1",
|
||||
"deviceName": "导弹平台",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "32beea38-ffc2-445a-9687-e9bdb087727f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"_comment_coordinate": "装备部署位置:经纬高坐标",
|
||||
"coordinate": {
|
||||
"longitude": 124.74107151788,
|
||||
"latitude": 26.74143394432,
|
||||
"height": -498.06469972014
|
||||
},
|
||||
"_comment_number": "武器数量",
|
||||
"number": "最大载弹量" ,
|
||||
"_comment_targetId": "目标id",
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1"
|
||||
}
|
||||
],
|
||||
"_comment_targetId": "任务目标id",
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1",
|
||||
"_comment_warZoneLocation": "作战区经纬高坐标列表",
|
||||
"warZoneLocation": [
|
||||
{
|
||||
"longitude": 122.18971775079,
|
||||
"latitude": 28.64177652916,
|
||||
"height": -99.95248993318
|
||||
},
|
||||
{
|
||||
"longitude": 127.22874089381,
|
||||
"latitude": 28.54075963352,
|
||||
"height": -1063.0224849918
|
||||
},
|
||||
{
|
||||
"longitude": 127.99831970891,
|
||||
"latitude": 23.81306022325,
|
||||
"height": -5900.62524601637
|
||||
},
|
||||
{
|
||||
"longitude": 120.14866648107,
|
||||
"latitude": 23.90272134296,
|
||||
"height": -22.17614107099
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"_comment_redWeapons": "红方武器汇总()",
|
||||
"redWeapons": [
|
||||
{
|
||||
"_comment_name": "红方武器名称",
|
||||
"name": "HQ-9",
|
||||
"_comment_id": "红方武器id",
|
||||
"id": "07e18ffb-3826-4e84-b884-68d77838ae25",
|
||||
"_comment_components": "红方武器下组件列表",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "89a639f5-3675-457b-ad4c-6b91a8d900e3",
|
||||
"deviceName": "",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "647087e6-ccad-4b14-ba32-9962ae42eee7",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "7c6529f5-3fe5-4cfe-b4c8-b5a5a8178cda",
|
||||
"deviceName": "导弹平台",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "a2ac6d74-09ac-49d5-8e05-fcaec47757c5",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"_comment_number": "红方武器弹药数量",
|
||||
"number": 1,
|
||||
"_comment_successTargetRad": "红方武器命中率(目前无)",
|
||||
"successTargetRad": "命中率",
|
||||
"_comment_isLead": "长机入参结构",
|
||||
"isLead": {
|
||||
"leader": "长机平台的唯一标识 id",
|
||||
"side": "阵营",
|
||||
"supportType": "长机平台类型",
|
||||
"positions": [
|
||||
{
|
||||
"longitude": "经度",
|
||||
"latitude": "纬度",
|
||||
"height": "高度"
|
||||
}
|
||||
]
|
||||
},
|
||||
"_comment_isWing": "僚机入参结构",
|
||||
"isWing": [
|
||||
{
|
||||
"name": "僚机名称",
|
||||
"distance": "距离",
|
||||
"angle": "角度",
|
||||
"alt": "高度差"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "rgb(220,39,39)",
|
||||
"dataType": "taskPlane",
|
||||
"drawName": "",
|
||||
"groupType": "tasks",
|
||||
"id": "41d3c5ce-3fda-4dee-a38f-fd3ae7e15e69",
|
||||
"idKey": "id",
|
||||
"isSelected": false,
|
||||
"name": "",
|
||||
"parentId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_taskPlane",
|
||||
"permission": [
|
||||
"14bc8ff9-3c93-4218-b01a-e144add196f9",
|
||||
"56a96b1b-14a8-4daf-a2d0-47c7faa4b831"
|
||||
],
|
||||
"show": true,
|
||||
"side": "红方",
|
||||
"sort": 1774271151846,
|
||||
"task": {
|
||||
"at_time": "180",
|
||||
"attackId": "267c5d87-bf36-42f2-b0a8-09c608d94b62",
|
||||
"color": "rgb(220,39,39)",
|
||||
"departureAirport": "",
|
||||
"execute": [
|
||||
{
|
||||
"targetList": [
|
||||
{
|
||||
"ID": "fbddc49c-f7b0-4d07-8000-1b5a2633c461",
|
||||
"arrayPositionId": 4,
|
||||
"arrayPositionIdBak": "",
|
||||
"at_time": {
|
||||
"timeUp": true,
|
||||
"value": 180
|
||||
},
|
||||
"attackType": "",
|
||||
"boost": "",
|
||||
"bootTime": "",
|
||||
"companion": "",
|
||||
"cruiseRouteId": "routeLine_f01be820-33ca-4843-8354-3f93a9986fe3",
|
||||
"cruiseRouteOffset": [
|
||||
{
|
||||
"UpOrDown": true,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"BeforeOrAfter": true,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"LeftOrRight": true,
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"decoyNum": "0",
|
||||
"decoyTime": "0",
|
||||
"disturbNum": "0",
|
||||
"disturbStartTime": "0",
|
||||
"droneNum": "",
|
||||
"fireType": "absolute",
|
||||
"hitNum": "",
|
||||
"launchAngle": "",
|
||||
"launchAzimuth": "",
|
||||
"noFlyZone": "",
|
||||
"orbitInclination": "",
|
||||
"refulId": "",
|
||||
"salvo": {
|
||||
"salvoUp": true,
|
||||
"value": 0
|
||||
},
|
||||
"strategy": [],
|
||||
"targetId": "dd20d7d9-7ce8-4531-aa0c-0b2056e7fbcd",
|
||||
"times_interval": 1,
|
||||
"weaponId": "HQ-9",
|
||||
"weaponRelease": "",
|
||||
"weaponType": "",
|
||||
"weaponUseCount": 3
|
||||
}
|
||||
],
|
||||
"type": "assault" //任务类型
|
||||
}
|
||||
],
|
||||
"landAirport": "",
|
||||
"missionList": [
|
||||
{
|
||||
"label": "HQ-9(4)",
|
||||
"launcherType": "sam",
|
||||
"number": 4,
|
||||
"value": "HQ-9"
|
||||
}
|
||||
],
|
||||
"name": "HQ-9发射车--3打击任务",
|
||||
"side": "红方",
|
||||
"sideId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"speed": 600,
|
||||
"type": "assault",
|
||||
"weaponId": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"SupportType": "car",
|
||||
"TroopsDetail": {},
|
||||
"Platform_type": "HQ-9发射车",
|
||||
"isStrikeTarget": false,
|
||||
"isReconTarget": false,
|
||||
"isInterferenceTarget": false,
|
||||
"isDefendImportantPlace": false,
|
||||
"groupType": "equipment",
|
||||
"EquipmentID": "b3c6de29-2b27-4500-a9ce-95d0bebc5cb9",
|
||||
"Name": "HQ-9发射车--5",
|
||||
"OwnerForceSide": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"PlatID": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_equipmentPlane",
|
||||
"SubComponents": {
|
||||
"communication": [
|
||||
{
|
||||
"ObjectHandle": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"arithmetic": {
|
||||
"id": "66cd29fdce08f520f1d9bf0e",
|
||||
"name": "短波电台"
|
||||
},
|
||||
"device": {
|
||||
"id": "5e0e5b064f1fae2ee9fa1000",
|
||||
"name": "3MHZ通信电台",
|
||||
"refId": "5e0e5b064f1fae2ee9fa1000"
|
||||
},
|
||||
"deviceId": "0b700ca6-290e-422a-b4e3-73b222809938",
|
||||
"deviceName": "3MHZ通信电台",
|
||||
"employLabel": false,
|
||||
"facilityName": "3MHZ通信电台",
|
||||
"soleId": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"motorized_assembly": [
|
||||
{
|
||||
"ObjectHandle": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"arithmetic": {},
|
||||
"device": {},
|
||||
"deviceId": "55915bc4-c825-43c4-93eb-6a76ab345e42",
|
||||
"deviceName": "",
|
||||
"soleId": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"platform": [
|
||||
{
|
||||
"ObjectHandle": "04a96dbc-837a-48be-8c04-e4f53586c47e",
|
||||
"arithmetic": {
|
||||
"id": "68876d0fd41989f086e905b8",
|
||||
"name": "通用发射车算法"
|
||||
},
|
||||
"device": {
|
||||
"id": "68876d2dd41989f086e905b9",
|
||||
"name": "发射车平台",
|
||||
"refId": "68876d2dd41989f086e905b9"
|
||||
},
|
||||
"deviceId": "164c75ec-6db5-48f9-8285-a7e726fd2a11",
|
||||
"deviceName": "发射车平台",
|
||||
"employLabel": false,
|
||||
"facilityName": "发射车平台",
|
||||
"soleId": "87905d6b-857a-4c5a-a922-5e2d191588d4",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"TrackParamId": "",
|
||||
"positions": [
|
||||
119.28585462691,
|
||||
25.67974332623,
|
||||
34.28352933882
|
||||
]
|
||||
}
|
||||
],
|
||||
"weapon": [
|
||||
{
|
||||
"ObjectHandle": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"arithmetic": {
|
||||
"id": "669dd6356bc286bd64e5d66c",
|
||||
"name": "发射架算法"
|
||||
},
|
||||
"codedQueue": "weapon.launcher",
|
||||
"configuration": {
|
||||
"classifyName": "导弹平台",
|
||||
"isMount": 1,
|
||||
"mountedWeapon": {
|
||||
"_id": "68f681794ddde62a52c7e569",
|
||||
"name": "HQ-9"
|
||||
},
|
||||
"number": 4
|
||||
},
|
||||
"device": {
|
||||
"id": "67ff279dafa7ea5aaa3a1236",
|
||||
"name": "通用发射架",
|
||||
"refId": "b9665788-9437-40fb-8a24-eff3d4d3b529"
|
||||
},
|
||||
"deviceId": "4e910ccf-d937-4a93-9b68-116167eda202",
|
||||
"deviceName": "通用发射架",
|
||||
"employLabel": false,
|
||||
"facilityName": "通用发射架",
|
||||
"serialNumber": "launcher",
|
||||
"soleId": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"twiceModified": {
|
||||
"launcherType": "sam"
|
||||
},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "营指挥所",
|
||||
"id": "9843e2ec-59a5-440f-9669-67f910b8edc3",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "7f41d14e-83bc-41c7-8e20-cb61f4fc1289",
|
||||
"deviceName": "",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "5da5f834-a8a9-407d-8a10-6dc78e488af9",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "591217ed-04e5-4120-87db-b5896d87b44d",
|
||||
"deviceName": "地面指挥所",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "2c53125c-76da-4454-9f91-04ab3c940b9a",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"number": 1,
|
||||
"successTargetRad": "命中率"
|
||||
},
|
||||
{
|
||||
"name": "防区2",
|
||||
"id": "c2259481-279a-4c10-ae45-cf2a669e7b52_Circle",
|
||||
"_comment_isLead": "圆形编辑入参结构",
|
||||
"isLead": {
|
||||
"drawName": "圆形名称",
|
||||
"airspaceType": "空域类型",
|
||||
"side": "阵营",
|
||||
"selectLonLat": "positions",
|
||||
"positions": [
|
||||
{
|
||||
"longitude": "圆心经度",
|
||||
"latitude": "圆心纬度",
|
||||
"height": "圆心高程"
|
||||
}
|
||||
],
|
||||
"radius": "圆半径(KM)",
|
||||
"height": "高度(米)",
|
||||
"extrudedHeight": "离地高度(米)"
|
||||
},
|
||||
"_comment_isWing": "圆形样式入参结构",
|
||||
"isWing": {
|
||||
"outlineWidth": "线宽",
|
||||
"lineType": "线条",
|
||||
"outlineColor": "轮廓色",
|
||||
"color": "填充色"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
355
auto-solution-rule/src/main/resources/json/火力规则输出.json
Normal file
355
auto-solution-rule/src/main/resources/json/火力规则输出.json
Normal file
@@ -0,0 +1,355 @@
|
||||
{
|
||||
"sourceFile": "区域防空31111_2026-04-02 15_29_03.json",
|
||||
"fireRuleInputs": [
|
||||
|
||||
{
|
||||
"id": "ed0e67e8-691f-4902-bb67-bd289aec89a1",
|
||||
"drawName": "红方打击任务",
|
||||
"dataType": "taskPlane",
|
||||
"side": "RED",
|
||||
"trackPointsId": "d685ca26-2ffa-4b2b-8e75-ecf5897338f5",
|
||||
"trackPoints": [
|
||||
{
|
||||
"index": 1,
|
||||
"longitude": 124.02895007578839,
|
||||
"latitude": 26.836172676390202,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"longitude": 122.81034067987203,
|
||||
"latitude": 27.017765463140986,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"longitude": 121.49435868664283,
|
||||
"latitude": 27.17048502942595,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"longitude": 120.87774502345792,
|
||||
"latitude": 27.16848996890842,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"longitude": 120.86773193816859,
|
||||
"latitude": 26.390372000100005,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"longitude": 122.81161998730377,
|
||||
"latitude": 25.50052904615808,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"longitude": 125.09035998725984,
|
||||
"latitude": 24.79876865711152,
|
||||
"height": 6000.0,
|
||||
"speed": 600.0
|
||||
}
|
||||
],
|
||||
"taskWeapons": [
|
||||
{
|
||||
"equipmentId": "40b341f6-d60a-4a29-b84d-2973a3065124",
|
||||
"name": "导弹",
|
||||
"supportType": "2001",
|
||||
"components": [
|
||||
{
|
||||
"deviceId": "81c7e7da-cb7b-4435-bba3-1648e946d2b2",
|
||||
"deviceName": "导弹机动组件",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "b47f34c2-3cba-4be3-a1d5-be0a986dff6f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceId": "4cf26cd0-bd5b-4d4c-a2eb-bca6184be5a1",
|
||||
"deviceName": "导弹平台",
|
||||
"componentParams": [
|
||||
{
|
||||
"uuid": "32beea38-ffc2-445a-9687-e9bdb087727f",
|
||||
"attDefaultValue": "",
|
||||
"attExplain": "",
|
||||
"number": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"coordinate": {
|
||||
"longitude": 124.74107151788,
|
||||
"latitude": 26.74143394432,
|
||||
"height": -498.06469972014
|
||||
},
|
||||
"number": 10,
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1"
|
||||
}
|
||||
],
|
||||
"targetId": "0c058874-0c12-4902-8fd0-2cde015965e1",
|
||||
"warZoneLocation": [
|
||||
{
|
||||
"longitude": 122.18971775079,
|
||||
"latitude": 28.64177652916,
|
||||
"height": -99.95248993318
|
||||
},
|
||||
{
|
||||
"longitude": 127.22874089381,
|
||||
"latitude": 28.54075963352,
|
||||
"height": -1063.0224849918
|
||||
},
|
||||
{
|
||||
"longitude": 127.99831970891,
|
||||
"latitude": 23.81306022325,
|
||||
"height": -5900.62524601637
|
||||
},
|
||||
{
|
||||
"longitude": 120.14866648107,
|
||||
"latitude": 23.90272134296,
|
||||
"height": -22.17614107099
|
||||
}
|
||||
],
|
||||
"defZoneLocation": []
|
||||
}
|
||||
],
|
||||
"Tasks": [
|
||||
{
|
||||
"color": "rgb(220,39,39)",
|
||||
"dataType": "taskPlane",
|
||||
"drawName": "HQ-9发射车--3打击任务",
|
||||
"groupType": "tasks",
|
||||
"id": "41d3c5ce-3fda-4dee-a38f-fd3ae7e15e69",
|
||||
"idKey": "id",
|
||||
"isSelected": false,
|
||||
"name": "HQ-9发射车--3打击任务",
|
||||
"parentId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_taskPlane",
|
||||
"permission": [
|
||||
"14bc8ff9-3c93-4218-b01a-e144add196f9",
|
||||
"56a96b1b-14a8-4daf-a2d0-47c7faa4b831"
|
||||
],
|
||||
"show": true,
|
||||
"side": "红方",
|
||||
"sort": 1774271151846,
|
||||
"task": {
|
||||
"at_time": "180",
|
||||
"attackId": "267c5d87-bf36-42f2-b0a8-09c608d94b62",
|
||||
"color": "rgb(220,39,39)",
|
||||
"departureAirport": "",
|
||||
"execute": [
|
||||
{
|
||||
"targetList": [
|
||||
{
|
||||
"ID": "fbddc49c-f7b0-4d07-8000-1b5a2633c461",
|
||||
"arrayPositionId": 4,
|
||||
"arrayPositionIdBak": "",
|
||||
"at_time": {
|
||||
"timeUp": true,
|
||||
"value": 180
|
||||
},
|
||||
"attackType": "",
|
||||
"boost": "",
|
||||
"bootTime": "",
|
||||
"companion": "",
|
||||
"cruiseRouteId": "routeLine_f01be820-33ca-4843-8354-3f93a9986fe3",
|
||||
"cruiseRouteOffset": [
|
||||
{
|
||||
"UpOrDown": true,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"BeforeOrAfter": true,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"LeftOrRight": true,
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
|
||||
"fireType": "absolute",
|
||||
"strategy": [],
|
||||
"targetId": "dd20d7d9-7ce8-4531-aa0c-0b2056e7fbcd",
|
||||
"times_interval": 1,
|
||||
"weaponId": "HQ-9",
|
||||
"weaponRelease": "",
|
||||
"weaponType": "",
|
||||
"weaponUseCount": 3
|
||||
}
|
||||
],
|
||||
"type": "assault"
|
||||
}
|
||||
],
|
||||
"landAirport": "",
|
||||
"missionList": [
|
||||
{
|
||||
"label": "HQ-9(4)",
|
||||
"launcherType": "sam",
|
||||
"number": 4,
|
||||
"value": "HQ-9"
|
||||
}
|
||||
],
|
||||
"name": "HQ-9发射车--3打击任务",
|
||||
"side": "红方",
|
||||
"sideId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"speed": 600,
|
||||
"type": "assault",
|
||||
"weaponId": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"Groups": [
|
||||
{
|
||||
"allAngle": 0,
|
||||
"drawName": "J15编组1",
|
||||
"editPermission": [],
|
||||
"groupType": "addGroup",
|
||||
"id": "5dea9ff7-5e45-4f8e-a67f-3ff4187c39ed",
|
||||
"idKey": "id",
|
||||
"isSelected": false,
|
||||
"isShow": false,
|
||||
"leader": "7a16c098-ceec-4c4d-8a24-8f44976a90ca",
|
||||
"name": "addGroup",
|
||||
"parentId": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_batFormation",
|
||||
"permission": [
|
||||
"14bc8ff9-3c93-4218-b01a-e144add196f9"
|
||||
],
|
||||
"show": false,
|
||||
"sort": 1774271497726,
|
||||
"wingmanData": [
|
||||
{
|
||||
"alt": 40,
|
||||
"angle": "50",
|
||||
"distance": 100,
|
||||
"key": 0,
|
||||
"name": "9aa9e5aa-9273-4c27-88e1-e582ff561685"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"redWeapons": [
|
||||
{
|
||||
"SupportType": "car",
|
||||
"TroopsDetail": {},
|
||||
"Platform_type": "HQ-9发射车",
|
||||
"isStrikeTarget": false,
|
||||
"isReconTarget": false,
|
||||
"isInterferenceTarget": false,
|
||||
"isDefendImportantPlace": false,
|
||||
"groupType": "equipment",
|
||||
"EquipmentID": "b3c6de29-2b27-4500-a9ce-95d0bebc5cb9",
|
||||
"Name": "HQ-9发射车--5",
|
||||
"OwnerForceSide": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831",
|
||||
"PlatID": "56a96b1b-14a8-4daf-a2d0-47c7faa4b831_equipmentPlane",
|
||||
"SubComponents": {
|
||||
"communication": [
|
||||
{
|
||||
"ObjectHandle": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"arithmetic": {
|
||||
"id": "66cd29fdce08f520f1d9bf0e",
|
||||
"name": "短波电台"
|
||||
},
|
||||
"device": {
|
||||
"id": "5e0e5b064f1fae2ee9fa1000",
|
||||
"name": "3MHZ通信电台",
|
||||
"refId": "5e0e5b064f1fae2ee9fa1000"
|
||||
},
|
||||
"deviceId": "0b700ca6-290e-422a-b4e3-73b222809938",
|
||||
"deviceName": "3MHZ通信电台",
|
||||
"employLabel": false,
|
||||
"facilityName": "3MHZ通信电台",
|
||||
"soleId": "3ed86636-a33a-41ac-aff2-0627eb1f9b28",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"motorized_assembly": [
|
||||
{
|
||||
"ObjectHandle": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"arithmetic": {},
|
||||
"device": {},
|
||||
"deviceId": "55915bc4-c825-43c4-93eb-6a76ab345e42",
|
||||
"deviceName": "",
|
||||
"soleId": "83ea5d33-90f4-4fd8-9121-eced6c7a44ea",
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
],
|
||||
"platform": [
|
||||
{
|
||||
"ObjectHandle": "04a96dbc-837a-48be-8c04-e4f53586c47e",
|
||||
"arithmetic": {
|
||||
"id": "68876d0fd41989f086e905b8",
|
||||
"name": "通用发射车算法"
|
||||
},
|
||||
"device": {
|
||||
"id": "68876d2dd41989f086e905b9",
|
||||
"name": "发射车平台",
|
||||
"refId": "68876d2dd41989f086e905b9"
|
||||
},
|
||||
"deviceId": "164c75ec-6db5-48f9-8285-a7e726fd2a11",
|
||||
"deviceName": "发射车平台",
|
||||
"employLabel": false,
|
||||
"facilityName": "发射车平台",
|
||||
"soleId": "87905d6b-857a-4c5a-a922-5e2d191588d4",
|
||||
"twiceModified": {},
|
||||
"zLists": [],
|
||||
"TrackParamId": "",
|
||||
"positions": [
|
||||
119.28585462691,
|
||||
25.67974332623,
|
||||
34.28352933882
|
||||
]
|
||||
}
|
||||
],
|
||||
"weapon": [
|
||||
{
|
||||
"ObjectHandle": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"arithmetic": {
|
||||
"id": "669dd6356bc286bd64e5d66c",
|
||||
"name": "发射架算法"
|
||||
},
|
||||
"codedQueue": "weapon.launcher",
|
||||
"configuration": {
|
||||
"classifyName": "导弹平台",
|
||||
"isMount": 1,
|
||||
"mountedWeapon": {
|
||||
"_id": "68f681794ddde62a52c7e569",
|
||||
"name": "HQ-9"
|
||||
},
|
||||
"number": 4
|
||||
},
|
||||
"device": {
|
||||
"id": "67ff279dafa7ea5aaa3a1236",
|
||||
"name": "通用发射架",
|
||||
"refId": "b9665788-9437-40fb-8a24-eff3d4d3b529"
|
||||
},
|
||||
"deviceId": "4e910ccf-d937-4a93-9b68-116167eda202",
|
||||
"deviceName": "通用发射架",
|
||||
"employLabel": false,
|
||||
"facilityName": "通用发射架",
|
||||
"serialNumber": "launcher",
|
||||
"soleId": "4e575d4d-2f36-436b-9939-0b96cde96b89",
|
||||
"twiceModified": {
|
||||
"launcherType": "sam"
|
||||
},
|
||||
"zLists": [],
|
||||
"ParentPlat": "04a96dbc-837a-48be-8c04-e4f53586c47e"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,33 @@
|
||||
|
||||
## 2. 参数-效果对照(给业务人员)
|
||||
|
||||
### 2.0 规则过程总览(先看这一条)
|
||||
|
||||
引擎按 **salience 从高到低** 依次执行(同一 `agenda-group` 内数字越大越先跑)。主链路可以理解为:**先定武器与目标关系 → 再补组件与数量 → 再定任务名与空间位置 → 最后射程与航迹**。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
step1["红方武器自适应装配 55"]
|
||||
step2["导弹联动增强 54"]
|
||||
step3["导弹组件数量匹配 53"]
|
||||
step4["命中率动态数量与offset 52"]
|
||||
step5["任务自动匹配 50"]
|
||||
step6["阵位区域解析 49"]
|
||||
step7["阵位武器部署赋位 48"]
|
||||
step8["射程合理性校验 47"]
|
||||
step9["航迹生成 46"]
|
||||
step1 --> step2 --> step3 --> step4 --> step5 --> step6 --> step7 --> step8 --> step9
|
||||
```
|
||||
|
||||
**两种装配主路径(由 `enableRuleScoring` 决定)**
|
||||
|
||||
| 模式 | 开关 | 武器从哪来 | `targetId` 怎么定 |
|
||||
|------|------|------------|---------------------|
|
||||
| 过程驱动整数加分 | `enableRuleScoring=true`(默认) | 对每个蓝方目标抽特征 → 红方候选池打分 → **并列最高分全选** → 按需求数克隆武器 | 生成红方武器时 **直接写入** 对应该蓝目标的 `equipmentId`(见 `allocateRedWeaponsForBlueTarget`) |
|
||||
| 传统白名单映射 | `enableRuleScoring=false` | 按 `enableAirRule` 等开关 + `map_*_targets` 映射追加武器 | 装配结束后调用 **`bindTargetIdsForRedWeapons`**:可行性过滤 + **五维加权分** + 边际递减 + 比例/回退 |
|
||||
|
||||
**调参时的阅读顺序建议**:先确认当前是过程驱动还是白名单 → 再改对应段落里的开关与阈值 → 最后看下游规则(命中率改数量、阵位改坐标)是否仍符合预期。
|
||||
|
||||
### 2.1 武器名称映射(改名字,不改逻辑)
|
||||
- `redStrikeDroneName`:空中反制组中的无人机名称。
|
||||
- `redArmedHelicopterName`:空中反制组中的武装直升机名称。
|
||||
@@ -26,17 +53,20 @@
|
||||
- `redMissileVehicleName`:导弹补充组中的导弹发射车名称。
|
||||
|
||||
### 2.2 白名单开关(决定“是否匹配”)
|
||||
- `enableAirRule`:`true` 时,蓝方空中目标会触发红方空中反制组;`false` 时该组永不触发。
|
||||
- `enableGroundRule`:`true` 时,蓝方地面目标会触发红方炮类反制组;`false` 时不触发。
|
||||
- `enableArmorRule`:`true` 时,蓝方装甲目标会触发红方反坦克组;`false` 时不触发。
|
||||
- `enableMissileVehicleRule`:`true` 时,蓝方有导弹能力可追加导弹发射车;`false` 时不追加。
|
||||
- `enableMissileLinkage`:`true` 时开启导弹数量/范围联动;`false` 时不做导弹联动增强。
|
||||
- `allowMultiGroup`:
|
||||
- `true`:同一批输入可命中多组策略并叠加武器;
|
||||
- `false`:只命中第一组,后续组不再生效(更“死规则”)。
|
||||
- `enableArmedHelicopterOnAir`:空中组中是否包含武装直升机。
|
||||
|
||||
### 2.3 蓝方类型到红方方案映射(核心,可多选)
|
||||
> **仅当 `enableRuleScoring=false` 时**,下列开关与映射主导装配;`enableRuleScoring=true` 时走过程驱动,本节开关对**是否出武器**基本不生效(仍可能影响你后续阅读的兼容映射字段)。
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `enableAirRule` | 是否允许“蓝方有空中目标”时走空中反制映射 | `false` 时空中组整条链路不追加武器 | 不需要空中反制时置 `false`,减少误匹配 |
|
||||
| `enableGroundRule` | 是否允许蓝方地面目标触发炮类反制组 | 影响迫榴炮/车载迫击炮等是否出现 | 只想反装甲不上炮时置 `false` |
|
||||
| `enableArmorRule` | 是否允许装甲目标触发反坦克组 | 影响反坦克火箭/导弹系统等是否出现 | 关闭后装甲线完全不走映射 |
|
||||
| `enableMissileVehicleRule` | 蓝方有导弹能力时是否追加导弹发射车 | 控制是否额外生成 `map_missile_targets` 对应武器 | 默认多为 `false`,需导弹车时再开 |
|
||||
| `enableMissileLinkage` | 导弹联动增强(`applyMissileLinkage`)是否执行 | 为 `true` 且满足门槛时,给红方**空中**武器补/增强导弹组件数量与射程 | 不想自动改导弹数量与范围时置 `false` |
|
||||
| `allowMultiGroup` | 多组策略是否可叠加 | `true`:空中/地面/装甲等多条可同时命中;`false`:**只命中第一组**,后续不再加武器 | 想规则更“硬”、少组合时置 `false` |
|
||||
| `enableArmedHelicopterOnAir` | 空中映射中是否包含武装直升机 | 影响空中组是否出 `redArmedHelicopterName` 对应装备 | 只要无人机不要武直时置 `false` |
|
||||
|
||||
### 2.3 蓝方类型到红方方案映射(兼容项,评分模式下弱化)
|
||||
|
||||
先解释你提到的 “k”:
|
||||
- 这里的 `k` 就是 **key(键名)**,例如 `map_armor_targets`。
|
||||
@@ -51,68 +81,173 @@
|
||||
- `map_missile_targets`:蓝方有导弹能力时,红方使用哪些武器。
|
||||
|
||||
映射规则说明:
|
||||
- 值必须是红方武器库内合法名称,否则该项会被忽略。
|
||||
- 为空时视为该组不配置,允许不命中。
|
||||
- 示例:`map_armor_targets=反坦克火箭,反坦克导弹系统` 表示坦克可同时触发两种红方反制武器。
|
||||
- 当 `enableScoringSelection=true` 时,本组配置不再主导最终结果,仅作为兼容保留。
|
||||
- 当前主决策由“过程驱动评分引擎”完成(类型/距离/命中率/成本综合评分)。
|
||||
|
||||
### 2.4 数量和阈值(决定“匹配后给多少”)
|
||||
- `defaultAirNum`:空中组默认数量。
|
||||
- `defaultGroundNum`:地面/装甲组默认数量。
|
||||
- `defaultMissileVehicleNum`:导弹发射车默认数量。
|
||||
- `shellRangeDefault`:炮类组件参数值,单位固定 `范围米`。
|
||||
- `missileCountOffset`:红方导弹数量 = 蓝方导弹数量 + 偏移量。
|
||||
- `missileRangeOffset`:红方导弹范围 = 蓝方导弹范围 + 偏移量(单位 `破坏范围米`)。
|
||||
- `blueMissileRangeDefault`:蓝方导弹范围缺失时采用的默认值。
|
||||
- `minBlueMissileCountForLinkage`:蓝方导弹数量达到该值才触发联动增强。
|
||||
### 2.4 数量与参数(匹配后给多少、导弹与炮类参数)
|
||||
|
||||
### 2.5 全组件数量匹配参数(新增)
|
||||
- `enableComponentQuantityMatch`:是否启用全组件数量覆盖(非导弹组件)。
|
||||
- `componentDeviceNameMappingCsv`:组件名映射表(逗号分隔),格式 `蓝组件deviceName->红组件deviceName`;为空则默认 `deviceName` 直匹配。
|
||||
- `skipMissileComponentsByNameContains`:跳过覆盖关键词:蓝方组件 `deviceName` 包含该关键词则不覆盖;默认 `导弹`(用于保留导弹联动偏移)。
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `defaultAirNum` | 白名单路径下空中映射默认实例数量 | 每轮 `map_air_targets` 展开时基数 | 需要更多同型机时调大 |
|
||||
| `defaultGroundNum` | 地面/装甲/炮类映射默认数量 | 非空中组映射展开基数 | 同上 |
|
||||
| `defaultMissileVehicleNum` | 导弹发射车映射默认数量 | `enableMissileVehicleRule=true` 时追加数量 | 导弹车要多台时调大 |
|
||||
| `shellRangeDefault` | 炮类武器“炮弹”组件射程字符串 | `limitRedArtilleryToShellOnly` 写入的默认 `范围米` | 想压远/压近打击时改数值 |
|
||||
| `missileCountOffset` | 联动时红方导弹数量相对蓝方的增量 | `applyMissileLinkage` 中目标导弹发数 | 希望红方导弹明显多于蓝方时调大 |
|
||||
| `missileRangeOffset` | 联动时红方导弹射程在蓝方基础上的增量 | 红方空中武器导弹组件首参数(破坏范围米) | 需要更远覆盖时调大 |
|
||||
| `blueMissileRangeDefault` | 蓝方未给导弹射程时的假定值 | 联动计算 `redRangeTarget` 的输入 | 输入不全时兜底,按典型弹种改 |
|
||||
| `minBlueMissileCountForLinkage` | 联动触发门槛(蓝方导弹总数) | 低于则 `applyMissileLinkage` 直接返回 | 想更难触发联动时调大(如 2、3) |
|
||||
|
||||
### 2.6 targetId 自动绑定参数(新增)
|
||||
- `enableTargetAutoBind`:是否自动给红方武器写入 `targetId`。
|
||||
- `minTargetBindRatio`:最低绑定比例(例如 `0.7` 表示至少 70% 红方武器有目标)。
|
||||
- `allowReserveWithoutTarget`:
|
||||
- `true`:允许少量红方武器 `targetId` 为空(火力冗余)。
|
||||
- `false`:尽量给每个红方武器分配目标。
|
||||
### 2.5 仅导弹组件匹配(`导弹组件数量匹配规则`,salience 53)
|
||||
|
||||
绑定规则说明(固定,不需要业务改代码):
|
||||
- 绑定来源是蓝方武器 `equipmentId`。
|
||||
- 匹配优先级按武器类型:
|
||||
- 防空类红方武器优先绑定蓝方空中目标
|
||||
- 反装甲类红方武器优先绑定蓝方装甲目标
|
||||
- 炮类红方武器优先绑定蓝方炮类/地面目标
|
||||
- 导弹发射车优先绑定蓝方导弹能力目标
|
||||
- 当优先池不足时自动回退到地面池/全目标池,保证大部分武器有目标。
|
||||
**规则过程**:在红方武器已有 `targetId` 的前提下,按蓝方对应装备的**导弹类组件**去对齐红方导弹组件的**数量**与**首参数**;其它组件不动。
|
||||
|
||||
### 2.7 命中率与动态火力参数(新增)
|
||||
- `hitRateCsv`:业务可配置红方武器命中率,格式 `武器名=0.72,武器名2=0.55`。
|
||||
- `defaultHitRateFallback`:未命中 `hitRateCsv` 且武器未携带 `hitRate` 时的兜底命中率。
|
||||
- `desiredKillProbability`:目标毁伤置信度(例如 `0.9`)。
|
||||
- `offsetCsvByWeapon`:显式 offset(最高优先级),格式 `武器名=1,武器名2=2`。
|
||||
- `enableDynamicMultiRedPerBlue`:是否按命中率动态决定“一个蓝方目标需要几把红方武器”。
|
||||
- `minRedWeaponsPerBlueTarget` / `maxRedWeaponsPerBlueTargetCap`:每个蓝方目标的最小/最大红方分配数。
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `enableComponentQuantityMatch` | 总开关 | `false` 时本规则不改写任何组件 | 完全手工控组件时关闭 |
|
||||
| `componentDeviceNameMappingCsv` | 蓝/红导弹组件 `deviceName` 映射 | 解决双方组件命名不一致导致对不上 | 填 `机载导弹->某某导弹` 形式,逗号分隔多对 |
|
||||
| `missileComponentNameContains` | 判定“导弹组件”的关键词 | 只有 `deviceName` 含该词的组件参与匹配 | 若业务用“火箭弹”等命名,可改关键词 |
|
||||
|
||||
优先级说明(重要):
|
||||
- 若 `offsetCsvByWeapon` 命中某武器,则直接使用显式 offset,不再使用命中率推导 offset。
|
||||
- 未配置显式 offset 时,规则按命中率与 `desiredKillProbability` 自动推导所需火力数量。
|
||||
- 同一蓝方 `equipmentId` 可能被多个红方武器绑定(不是固定 2 把),数量由命中率动态计算并受 cap 限制。
|
||||
**输出影响**:仅改导弹组件 `componentParams[0].number` 与 `componentParams[0].attDefaultValue`(破坏范围等),非导弹组件保持红方原值。
|
||||
|
||||
### 2.8 阵位规则参数(新增)
|
||||
- `enablePositionRules`:阵位规则总开关。
|
||||
- 阵位输入来源:`blueTask.warZoneLocation` 与 `blueTask.defZoneLocation`(各 4 个经纬点)。
|
||||
- `fireUnitSpacingMeters`:防区/作战区点位间距(米),例如 `100` 代表约每 100 米一个火力单元。
|
||||
- `airDeployZonePreference`:飞机优先部署区域(`combat` 或 `defense`)。
|
||||
- `defensePriorityWeapons`:优先部署在防区的武器名单(逗号分隔)。
|
||||
- `groundDeployHeight` / `airDeployHeight`:地面/空中武器部署高度。
|
||||
### 2.6 targetId 自动绑定(仅传统白名单路径)
|
||||
|
||||
阵位规则效果:
|
||||
- 新增两条规则:
|
||||
- `阵位规则-区域解析与点位生成`
|
||||
- `阵位规则-武器部署赋位`
|
||||
- 飞机可在任意区(按偏好区优先);反坦克等重火力优先防区。
|
||||
- 在多边形区域内按间距生成候选点,并给红方武器写入 `weapon.coordinate`。
|
||||
> **`enableRuleScoring=true`(过程驱动)时**:装配阶段已在 `allocateRedWeaponsForBlueTarget` 里把 `targetId` 设为对应蓝方 `equipmentId`,**不会**再走下表的五维分配逻辑。下表仅在 **`enableRuleScoring=false`** 且 `configureRedWeaponsByBlue` 末尾调用 `bindTargetIdsForRedWeapons` 时生效。
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `enableTargetAutoBind` | 是否执行绑定函数 | `false` 时红方 `targetId` 保持入参/空 | 全手工指定目标时关闭 |
|
||||
| `minTargetBindRatio` | 最低绑定比例下限 | 绑定数/红武器总数低于该比例时,尝试用 `pickAnyBlueId` 补足 | 想“几乎全要有目标”时调高(如 0.9);允许大量空则调低 |
|
||||
| `allowReserveWithoutTarget` | 是否允许故意留空 | `true`:允许火力冗余;`false`:尽量全部塞满目标 | 与 `minTargetBindRatio` 配合使用 |
|
||||
| `w_target_type` | 类型匹配在总分中的权重 | 越大越强调类型对口 | 类型错配不可接受时略调高 |
|
||||
| `w_target_dist` | 距离权重 | 越大越偏向更近、易打击的蓝目标 | 强调近战压制时调高 |
|
||||
| `w_target_height` | 高度差权重 | 越大越惩罚高度层不匹配 | 空地混合作战可略调高 |
|
||||
| `w_target_hit` | 命中率权重 | 越大高 `hitRate` 武器越易抢到好目标 | 强调效费比时调高 |
|
||||
| `w_target_threat` | 蓝方威胁权重 | 越大越优先高威胁蓝目标 | 要“先打高威胁”时调高 |
|
||||
| `maxEffectiveDistance` | 配对最大有效距离 | 超过则 `isPairFeasible` 直接否 | 只允许远程交火时调大;强制近战调小 |
|
||||
| `maxHeightGap` | 允许的最大高度差 | 超过则候选失效 | 高原/低空混编时适度调大 |
|
||||
| `targetDecayAlpha` | 边际递减系数 | `marginal = score / (1 + alpha*k)`,`k` 为该蓝目标已分配数;**越大越不扎堆** | 避免多机打同一目标时调大 |
|
||||
| `fallbackToNearestTarget` | 无可行候选时是否按距离回退 | `true` 时尽量给一个最近蓝 `equipmentId` | 不想硬塞错误目标时改 `false` 并配合 `allowUnassignedRedWeapon` |
|
||||
| `allowUnassignedRedWeapon` | 仍无可行时是否允许 `targetId` 为空 | `true` 允许空;`false` 会再 `pickAnyBlueId` 硬填 | 与火力冗余策略一致即可 |
|
||||
|
||||
**绑定过程(白名单路径,固定实现)**:绑定键为蓝方 `equipmentId` → 逐把红武器在可行集合上算分 → 取边际最高 → 更新已分配计数 → 不足比例再补 → 仍不行则按上表回退或留空。
|
||||
|
||||
### 2.7 过程驱动整数加分参数(核心,`enableRuleScoring=true`)
|
||||
|
||||
**规则过程**(函数 `runProcessDrivenSelection`):对每个带 `equipmentId` 的蓝方武器抽一条特征 → 在配置给出的红方武器池里用 `scoreRedWeaponByRules` 打**整数分** → 去掉低于 `minScoreToAssign` 的 → **并列最高分全部保留** → 按 `computeNeededRedCountFromFeature` 得到 `needCount`,再被 `minRedWeaponsPerBlueTarget`~`maxRedWeaponsPerBlueTargetCap` 钳位 → 轮询 `topNames` 克隆武器并 `setTargetId(blueId)`。
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `enableRuleScoring` | 是否走过程驱动主路径 | `true` 走本节;`false` 回退 2.2 白名单 + 2.6 绑定 | 与旧映射二选一 |
|
||||
| `minScoreToAssign` | 候选武器最低整数分 | 低于则该红方武器名不参与本蓝目标的并列候选 | 想更少种类参与时调大;想多并列时调小 |
|
||||
| `nearDefenseDistanceMeters` | 蓝方到防区距离“近”的米阈值 | 与 `score_nearDefense_artillery` 联动:近且炮名命中则加分 | 防区尺度变化时同步改 |
|
||||
| `highThreatLevel` | 任务威胁等级算“高威胁”的整数阈值 | 与 `score_highThreat_missile` 等联动 | 想更容易触发“高威胁分支”时调低 |
|
||||
| `highTargetCount` | 蓝方该目标 `number` 的“数量高”阈值 | 与 `score_highCount_artillery` 联动 | 集群目标多时调低 |
|
||||
| `score_type_antiArmor` | 装甲特征下反坦克类名加分 | 含“反坦克”的红方名更容易进并列最高 | 强化反坦时调大 |
|
||||
| `score_nearDefense_artillery` | 近防区 + 迫榴/迫击炮名加分 | 近防区时更倾向出炮 | 强调要炮时调大 |
|
||||
| `score_highThreat_missile` | 高威胁或空中场景下导弹/防空类加分(实现中与多项条件叠加) | 高威胁/空中时防空、导弹类名分更高 | 防空压制想加重时调大 |
|
||||
| `score_highCount_artillery` | 蓝方数量高时炮类加分 | 多目标时更倾向炮 | 炮火优先时调大 |
|
||||
| `score_hasMissile_airDefence` | 蓝方有导弹组件时防空/导弹发射车类加分 | 有导弹威胁时更倾向防空与导弹车 | 导弹对抗想加重时调大 |
|
||||
|
||||
**并列全选机制**:
|
||||
|
||||
- 对同一蓝方 `equipmentId`,所有红方候选算分后取 `maxScore`,**凡 `score == maxScore` 的武器名称都进入 `topNames`**。
|
||||
- 需要数量大于名称种数时,会在 `allocateRedWeaponsForBlueTarget` 里**轮询** `topNames` 重复添加,故同名武器可出现多把。
|
||||
- 另:实现里若估算射程覆盖蓝方距离(含安全裕量)还会 **+1 分**,便于优先能打的装备。
|
||||
|
||||
### 2.8 命中率与动态火力(`命中率规则-动态数量与offset`,salience 52)
|
||||
|
||||
**规则过程**:在装配之后,对**已有**红方武器的 `number` 做增量:优先读 `offsetCsvByWeapon` 显式 offset;否则用命中率与阈值的 **gap 阶梯** 加 `hitRateStep*Offset`。
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `hitRateCsv` | 按武器名配置命中率 | `applyDefaultHitRateIfAbsent` 与 gap 计算 | 调整个体武器假定命中能力 |
|
||||
| `defaultHitRateFallback` | 未配置且武器无 `hitRate` 时 | gap 计算用的默认 p | 整体偏乐观/悲观时改 |
|
||||
| `desiredKillProbability` | 过程驱动里毁伤置信目标 | `computeNeededRedCountFromFeature` 中 `computeRequiredShots` 的输入 | 想“打得更保险”时调高(需求发数可能变多) |
|
||||
| `offsetCsvByWeapon` | **最高优先级**数量偏移 | 命中武器名则 **忽略** gap 阶梯,直接 `base + offset` | 某武器必须固定加 N 发时配置 |
|
||||
| `hitRateThreshold` | 命中率门槛 | `gap = threshold - hitRate`,决定进哪一档增量 | 门槛越高,低命中武器越易吃到正 offset |
|
||||
| `hitRateGapStep1Max` / `hitRateGapStep2Max` | gap 的一、二档上界 | 分档加 `hitRateStep1Offset` 或 `hitRateStep2Offset` | 拉宽档位可减少落到高档 |
|
||||
| `hitRateStep1Offset` / `hitRateStep2Offset` | 各档对 `number` 的加量 | 直接增加 `weapon.number` | 低命中时想多压弹药则调大 |
|
||||
| `minRedWeaponsPerBlueTarget` | 每蓝目标至少分配红武器数下限 | 过程驱动里与 `needCount` 取大 | 强制“至少 N 把伺候一个目标” |
|
||||
| `maxRedWeaponsPerBlueTargetCap` | 每蓝目标分配上限 | 与 `needCount` 取小,防止无限膨胀 | 控制火力上限 |
|
||||
| `enableDynamicMultiRedPerBlue` | 配置项(当前实现**未读取**) | 预留;**改之暂无效果**,以 `desiredKillProbability` + min/max 钳位为准 | 待代码接入后再用 |
|
||||
|
||||
**阶梯优先级(与代码一致)**:
|
||||
|
||||
1. `offsetCsvByWeapon` 命中 → 只用显式 offset。
|
||||
2. 否则 `gap <= 0` → `+0`。
|
||||
3. `0 < gap <= hitRateGapStep1Max` → `+hitRateStep1Offset`。
|
||||
4. `hitRateGapStep1Max < gap <= hitRateGapStep2Max` → `+hitRateStep2Offset`。
|
||||
5. `gap > hitRateGapStep2Max` → 仍按 **第二档 offset**(避免数量无上限膨胀)。
|
||||
|
||||
### 2.9 阵位规则参数(`阵位规则` 49→48)
|
||||
|
||||
**规则过程**:`prepareDeploymentPools` 用作战区/防区多边形生成候选点网格;`applyWeaponDeployment` 用蓝方航迹与防区关系得到 **部署模式** `deployMode`(近快/远快/近慢/默认)→ 选锚点 → `resolveFormationType`(人工阵型 / 自动阵型 / 默认)→ `buildFormationOffsets` 展开队形 → 写入 `weapon.coordinate`;地面高度固定、空中可走自动生成高度。
|
||||
|
||||
**输入依赖**:`blueTask.warZoneLocation`、`blueTask.defZoneLocation`(各 4 点经纬);部署模式还依赖 `trackPoints`(算速度与距防区)。
|
||||
|
||||
#### 2.9.1 总开关与点位
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `enablePositionRules` | 阵位总开关 | `false` 时跳过点位池与赋位 | 仅要装配不要坐标时关闭 |
|
||||
| `fireUnitSpacingMeters` | 作战区/防区内网格点间距(米) | 点密度:越小点越多、部署越密 | 地形细粒度要求高调小 |
|
||||
| `airDeployZonePreference` | 空中锚点优先作战区还是防区 | `combat`/`defense` 影响 `pickAnchorByMode` 选取 | 想飞机靠前压则偏 `combat` |
|
||||
| `defensePriorityWeapons` | 名单内武器优先取防区点 | 名单武器在无锚点回退时优先 `defense` 池 | 要扼守防区的装备写入 |
|
||||
|
||||
#### 2.9.2 部署模式(与 `speedFastThreshold`、距离阈值)
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `speedFastThreshold` | 蓝方平均速度是否算“快” | 与 `distanceNearDefenseThresholdMeters`、`distanceFarDefenseThresholdMeters` 组合成 **near_fast / far_fast / near_slow / default** | 高速标准提高则更少判成“快” |
|
||||
| `distanceNearDefenseThresholdMeters` | 蓝方航迹末端距防区“近”的米阈值 | 参与部署模式与锚点策略 | 防区尺度大时略调大 |
|
||||
| `distanceFarDefenseThresholdMeters` | “远”阈值 | 同上 | 与上配合拉开近/远带 |
|
||||
|
||||
#### 2.9.3 高度(地面固定 / 空中可自动)
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `groundDeployHeight` | 地面武器统一高度 | 地面编队 `moveCoordinateByMeters` / 克隆点高度 | 地表 DEM 约定高度 |
|
||||
| `airDeployHeight` | 关闭自动或兜底时用 | 过程驱动关闭自动高度时的固定空高 | 与 `airHeightFallback` 一般同量级 |
|
||||
| `enableAutoAirDeployHeight` | 空中是否按态势算高 | `false` 时空中全程用 `airDeployHeight` | 想完全手工高时关 |
|
||||
| `airHeightFallback` | 无航迹且无蓝方武器高度时的基准 | `resolveBlueBaseHeight` 最后兜底 | 与默认战术层一致即可 |
|
||||
| `airHeightMin` / `airHeightMax` | 自动高度钳位 | 防止算出过矮/过高 | 任务高度包线 |
|
||||
| `airHeightSpeedThreshold` / `airHeightAdjustFast` | 快于阈值则加高度 | 快目标对应更高拦截层 | 拦截想更猛则加 `AdjustFast` |
|
||||
| `airHeightNearDefenseDistance` / `airHeightFarDefenseDistance` | 距防区近/远分界 | 近用 `airHeightAdjustNear`(多为负)、远用 `airHeightAdjustFar` | 调整防区内外高度差 |
|
||||
| `airHeightAdjustMain` / `airHeightAdjustWing` | 主僚高度差 | 主机略高、僚机略低 | 战术队形垂直疏开 |
|
||||
|
||||
#### 2.9.4 阵型类型(人工 / 自动 / 默认)
|
||||
|
||||
**说明(与部署模式共用阈值)**:`resolveDeployModeByBlueState` 用 **`speedFastThreshold`**、`distanceNearDefenseThresholdMeters`、`distanceFarDefenseThresholdMeters` 得到 `near_fast / far_fast / near_slow / default`,`autoSelectFormationType` 直接消费该 `deployMode` 字符串选 `formationRule_*`。配置里的 **`formationFastSpeedThreshold`、`formationNearDefenseDistance`、`formationFarDefenseDistance` 当前未参与运算**,调整无效;若要与部署模式解耦,需开发在代码中改为读取这三项。
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `formationDefaultType` | 阵型名兜底 | 非法或未选时 `normalizeFormationType` 回退 | 填 `TRIANGLE` 等合法枚举 |
|
||||
| `enableAutoFormationSelect` | 是否 `autoSelectFormationType` | `false` 时只用 Task 指定或默认 | 想完全人工阵型时关 |
|
||||
| `formationHighThreatLevel` | 威胁≥该值走 `formationRule_high_threat` | **优先于**速度距离分支 | 想更早用“高威胁阵型”则调低 |
|
||||
| `formationLargeGroupCount` | **大编队**阈值 | 比较 **`redTask.taskWeapons.size()`(红方武器条数)** ≥ 阈值则走 `formationRule_large_group`(不是蓝方数量) | 想更早切换“大编队阵型”则调小 |
|
||||
| `formationRule_near_fast` 等 | 各分支对应阵型名 | 决策序:**高威胁 > 近快/远快/近慢 > 大编队(红方条数)> 空中占比≥0.5 > default** | 改字符串即改映射 |
|
||||
| `formationRule_air_majority` | 红方空中占比高时阵型 | `computeRedAirRatio` ≥ 0.5 | 无人机群战术时调整 |
|
||||
|
||||
#### 2.9.5 间距、主僚距、朝向(自动 + 兜底)
|
||||
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `formationDefaultSpacingMeters` | 阵型间距兜底 | 自动间距失败时用 | 与最小安全间距匹配 |
|
||||
| `formationSpacingMinMeters` / `formationSpacingMaxMeters` | 自动间距上下界 | 限制 `resolveFormationSpacing` 输出 | 地形窄/宽时收放 |
|
||||
| `defenseScaleMinMeters` / `defenseScaleMaxMeters` | 防区尺度映射到间距的范围 | 防区越大间距可越大 | 与防区实际大小一致 |
|
||||
| `mainWingDistanceDefaultMeters` | 主僚距兜底 | 自动主僚距失败时 | 编队纵向尺度 |
|
||||
| `mainWingDistanceMinMeters` / `mainWingDistanceMaxMeters` | 主僚距钳位 | 限制自动主僚距 | 避免过近相撞 |
|
||||
| `mainWingDistanceModeFactor_near_fast` 等 | 部署模式对主僚距的乘子 | 近快更紧、远快更疏等 | 战术疏密 |
|
||||
| `formationHeadingDefaultDeg` | 朝向兜底 | 无航迹、无 Task 朝向时 | 默认机头方向 |
|
||||
|
||||
**实体覆盖优先级(与代码一致)**:
|
||||
|
||||
- 阵型类型:`Task.formationType`(非空)> 自动选阵型 > `formationDefaultType`。
|
||||
- 间距:`Task.formationSpacingMeters` > 防区尺度自动 > `formationDefaultSpacingMeters`。
|
||||
- 主僚距:`Weapon.wingRelativeDistanceMeters` > `Task.mainWingDistanceMeters` > 自动 > `mainWingDistanceDefaultMeters`。
|
||||
- 朝向:`Task.formationHeadingDeg` > 航迹末段方向 > `formationHeadingDefaultDeg`。
|
||||
|
||||
**实体字段建议**:`Task`:`formationType`、`formationSpacingMeters`、`mainWingDistanceMeters`、`formationHeadingDeg`;`Weapon`:`formationRole`、`wingRelativeDistanceMeters`、`wingRelativeBearingDeg`。
|
||||
|
||||
阵位输入示例(仅经纬度,4点):
|
||||
|
||||
@@ -133,7 +268,7 @@
|
||||
}
|
||||
```
|
||||
|
||||
### 2.9 航迹规则参数(新增)
|
||||
### 2.10 航迹规则参数(新增)
|
||||
- `enableTrajectoryRules`:航迹规则总开关。
|
||||
- `strategyMode`:`auto/shortest/flank/interfere`。
|
||||
- `auto`:智能选择策略。
|
||||
@@ -159,38 +294,40 @@
|
||||
## 3. 当前规则行为(简版)
|
||||
|
||||
- `装备组件匹配`、`组件参数匹配`:已作为 `legacy` 占位,不承担当前业务决策。
|
||||
- 主决策在 `红方武器自适应装配规则`:调用 `configureRedWeaponsByBlue(...)`,按“映射配置”添加武器。
|
||||
- 主决策在 `红方武器自适应装配规则`:调用 `configureRedWeaponsByBlue(...)`,默认走“过程驱动整数加分选武器”。
|
||||
- 过程驱动链路:蓝方特征提取 -> 候选整数加分 -> 最高分并列全选 -> 动态分配数量与 targetId。
|
||||
- 导弹增强在 `导弹联动增强规则`:调用 `applyMissileLinkage(...)`,受开关和阈值控制。
|
||||
- 全组件数量匹配在 `全组件数量匹配规则`:按红方 `targetId` 绑定蓝方装备,覆盖非导弹组件 `componentParams[0].number`;找不到组件/targetId 允许跳过。
|
||||
- 命中率驱动数量在 `命中率规则-动态数量与offset`:按 `hitRate` 与目标毁伤概率推导火力数量;显式 offset 配置优先。
|
||||
- `全组件数量匹配规则` 当前语义已收敛为“仅导弹组件匹配”:只改导弹组件数量与首参数,非导弹不改。
|
||||
- 命中率驱动数量在 `命中率规则-动态数量与offset`:按 `hitRateThreshold` 与 `gap` 阶梯增量计算数量;显式 offset 配置优先。
|
||||
- 任务命名在 `任务自动匹配规则`:调用 `assignTaskNameByRedWeapons(...)`,按红方最终武器自动生成任务名和 `dataType`。
|
||||
- 炮类约束:命中炮类条件时,炮类武器只保留 `炮弹` 组件,单位 `范围米`。
|
||||
- `targetId` 绑定:在装配后自动执行,按命中率动态给蓝目标分配多个红方武器(受上下限约束),允许少量空值冗余。
|
||||
- 阵位部署:按多边形区域和武器类型自动赋位,保证防区火力覆盖。
|
||||
- `targetId`:**过程驱动**下在装配时直接写入对应蓝方 `equipmentId`;**白名单路径**下用“可行性 + 五维评分 + 边际递减”分配(见 2.6)。
|
||||
- 阵位部署:按“速度距离驱动锚点 + 阵型偏移 + 主僚机相对位移”自动赋位,最终输出经纬高。
|
||||
- 射程合理性在 `射程合理性校验规则`:基于蓝/红武器坐标计算距离,自动避免“射程不足却打击”的不合理情况(可自动调参)。
|
||||
- 航迹生成:根据蓝方 `trackPoints` 生成红方 `trackPoints`,点数与蓝方一致,支持三套策略和智能选择。
|
||||
|
||||
## 3.1 任务名称自动匹配(新增)
|
||||
## 3.1 任务名称自动匹配(`任务自动匹配规则`,salience 50)
|
||||
|
||||
任务命名依据:**红方最终武器**(不是蓝方任务名关键字)。
|
||||
**规则过程**:在武器与数量基本落定之后,按 **红方最终 `taskWeapons` 列表** 做分类(不看蓝方 `drawName` 关键字),写入 `redTask.drawName` 与 `redTask.dataType`。
|
||||
|
||||
当前分类优先级:
|
||||
- 导弹突击(导弹发射车)
|
||||
- 防空压制(防空导弹武器/火力打击无人机/武装直升机)
|
||||
- 反装甲打击(反坦克火箭/反坦克导弹系统)
|
||||
- 炮火压制(迫榴炮/车载迫击炮)
|
||||
- 通用打击(兜底)
|
||||
**分类优先级(先命中先生效)**:
|
||||
|
||||
业务可调模板(在 `buildBusinessConfig()`):
|
||||
- `taskName_missile_strike` / `taskDataType_missile_strike`
|
||||
- `taskName_air_defence` / `taskDataType_air_defence`
|
||||
- `taskName_anti_armor` / `taskDataType_anti_armor`
|
||||
- `taskName_artillery` / `taskDataType_artillery`
|
||||
- `taskName_general` / `taskDataType_general`
|
||||
1. 导弹突击:含导弹发射车类武器名
|
||||
2. 防空压制:防空导弹 / 火力打击无人机 / 武装直升机
|
||||
3. 反装甲打击:反坦克火箭 / 反坦克导弹系统
|
||||
4. 炮火压制:迫榴炮 / 车载迫击炮
|
||||
5. 通用打击:兜底
|
||||
|
||||
效果说明:
|
||||
- 只改这些模板文字,不改函数,也能改变最终任务展示名。
|
||||
- 若分类与武器不一致,会自动回落到 `通用打击任务`,避免“任务名和武器不符”。
|
||||
| 参数 | 作用 | 影响什么 | 怎么调整 |
|
||||
|------|------|----------|----------|
|
||||
| `taskName_missile_strike` | 导弹突击类展示名 | `drawName` 当命中导弹突击分支时 | 改中文任务标题 |
|
||||
| `taskDataType_missile_strike` | 导弹突击类业务类型 | `dataType` 同步写入 | 与前端/报表枚举对齐 |
|
||||
| `taskName_air_defence` / `taskDataType_air_defence` | 防空压制类 | 同上 | 同上 |
|
||||
| `taskName_anti_armor` / `taskDataType_anti_armor` | 反装甲类 | 同上 | 同上 |
|
||||
| `taskName_artillery` / `taskDataType_artillery` | 炮火类 | 同上 | 同上 |
|
||||
| `taskName_general` / `taskDataType_general` | 兜底类 | 无上述特征或冲突回落时使用 | 默认任务名与类型 |
|
||||
|
||||
**效果说明**:只改模板字符串即可改展示;若红方武器组合与期望分类不一致,会落到 `taskName_general`,避免“名不副实”。
|
||||
|
||||
## 4. 快速修改示例(业务常用)
|
||||
|
||||
@@ -330,7 +467,7 @@
|
||||
- **联动门控**:`applyMissileLinkage(...)` 必须同时满足:
|
||||
- `enableMissileLinkage=true`
|
||||
- 蓝方导弹数量 `>= minBlueMissileCountForLinkage`
|
||||
- **目标绑定**:`bindTargetIdsForRedWeapons(...)` 基于蓝方 `equipmentId` 分配 `targetId`,支持“优先匹配 + 绑定率阈值 + 冗余空目标”。
|
||||
- **目标绑定**:`bindTargetIdsForRedWeapons(...)` 基于蓝方 `equipmentId` 执行“可行性过滤 + 打分 + 边际收益递减分配 + 回退兜底”。
|
||||
- **阵位部署**:`prepareDeploymentPools(...)` + `applyWeaponDeployment(...)` 负责区域解析、点位生成与部署赋位。
|
||||
- **航迹生成**:`applyTrajectoryGeneration(...)` + `chooseTrajectoryStrategy(...)` + `generateRedTrackPoints(...)` 负责红方航迹策略生成。
|
||||
- **任务命名**:`assignTaskNameByRedWeapons(...)` 仅基于红方最终武器,避免旧版按蓝方 `drawName` 关键字造成误判。
|
||||
|
||||
220
auto-solution-rule/src/main/resources/rules/rule.drl
Normal file
220
auto-solution-rule/src/main/resources/rules/rule.drl
Normal file
@@ -0,0 +1,220 @@
|
||||
package rules;
|
||||
|
||||
import com.solution.rule.domain.ultimately.fact.DroolsFact;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.solution.rule.utils.RuleFunction.equipmentRule;
|
||||
import static com.solution.rule.utils.RuleFunction.target;
|
||||
import static com.solution.rule.utils.RuleFunction.position;
|
||||
import static com.solution.rule.utils.RuleFunction.trackRoute;
|
||||
|
||||
|
||||
global java.util.Map globalParams;
|
||||
|
||||
/**
|
||||
* 构建装备匹配所需的全部可调参数(会 merge 进 globalParams,覆盖 Java 侧同名默认值)。
|
||||
*
|
||||
* ========== 总体运算逻辑(与 RuleFunction.equipmentRule 一致)==========
|
||||
* 1)先拼「蓝方文本串」blueBlob:任务 drawName、dataType、taskWeapons 下各武器的 name/supportType/equipmentId、组件 deviceName。
|
||||
* 2)对每个红方装备拼「红方文本串」redBlob:name、platform_type、SupportType。
|
||||
* 3)每件红装得分 score = 规则槽得分(scoreRuleSlots) + 兼容层得分(scoreLegacyLayer),均为整数。
|
||||
* - 规则槽:对 i=1..ruleSlotCount,若 blueBlob 命中 blueRuleKeywords_i 且 redBlob 命中 redRuleKeywords_i,
|
||||
* 则加上 ruleScore_i * weight。
|
||||
* - 兼容层:多组「蓝关键词 + 红关键词 + 对应分数」,见下方各键说明;每组条件同时满足则加上 对应Score * weight。
|
||||
* 4)在池中取 score 最大者;若多人并列,由 tieBreak 决定(见 tieBreak)。
|
||||
* 5)若 maxScore < minSelectedScore,视为未匹配:不往 fireRuleInputs 追加行,redWeapons 输出仍为当前池。
|
||||
* 6)若匹配成功:从池中 remove 该件;fireRuleInputs 追加一行,drawName 后接 outputDrawNameSuffix;taskWeapons 填选中红装映射。
|
||||
*
|
||||
* 关键词格式:英文逗号分隔,子串包含即算命中(contains),不要求整词匹配。
|
||||
*/
|
||||
function Map buildParam(){
|
||||
Map param = new java.util.HashMap();
|
||||
|
||||
// ---------- 全局倍率与门槛 ----------
|
||||
// weight:对上述所有「基础分数」的统一乘数(规则槽的 ruleScore_i、兼容层的 *Score 都会乘 weight)。
|
||||
param.put("weight", 1);
|
||||
// minSelectedScore:单件红装总分达到该值及以上才会被选中并写入 fireRuleInputs;否则本任务视为未匹配到装备。
|
||||
param.put("minSelectedScore", 1);
|
||||
// tieBreak:并列最高分时的决胜方式。当前实现仅支持 "equipmentId":装备 ID 字典序更小的优先。
|
||||
param.put("tieBreak", "equipmentId");
|
||||
// outputDrawNameSuffix:匹配成功写入 fireRuleInputs 时,在蓝方原 drawName 后面拼接的后缀(如「打击任务」)。
|
||||
param.put("outputDrawNameSuffix", "打击任务");
|
||||
|
||||
// ---------- 规则槽(可配置条数,便于只改本文件而不改 Java)----------
|
||||
// ruleSlotCount:启用几条槽规则;第 i 条使用 blueRuleKeywords_i、redRuleKeywords_i、ruleScore_i。
|
||||
param.put("ruleSlotCount", 3);
|
||||
// 槽1:蓝方文本中出现任一子串 且 红方文本中出现任一子串 → 加 ruleScore_1 * weight。
|
||||
param.put("blueRuleKeywords_1", "F-16,F-35");
|
||||
param.put("redRuleKeywords_1", "防空,导弹,无人机");
|
||||
param.put("ruleScore_1", 5);
|
||||
param.put("blueRuleKeywords_2", "坦克,装甲");
|
||||
param.put("redRuleKeywords_2", "反坦克");
|
||||
param.put("ruleScore_2", 4);
|
||||
param.put("blueRuleKeywords_3", "地面,突击");
|
||||
param.put("redRuleKeywords_3", "远火,榴弹,炮");
|
||||
param.put("ruleScore_3", 2);
|
||||
|
||||
// ---------- 兼容层:按「场景关键词」配对加分(与 RuleFunction.scoreLegacyLayer 一一对应)----------
|
||||
// 以下每组均为:蓝方文本命中第一列关键词 且 红方文本命中第二列关键词 → 加 第三列分数 * weight。
|
||||
//
|
||||
// ① 空中平台类:蓝方像「对空/机型」且红方像对空装备 → + airScore * weight
|
||||
param.put("bluePlatformKeywords_air", "F-16,J-10,F-35");
|
||||
param.put("redPreferredWhenBlueAir", "防空,导弹,无人机,直升机,空空");
|
||||
param.put("airScore", 2);
|
||||
// ② 任务文案像空中任务 且 红方偏好对空 → + airTaskScore * weight(可与①叠加)
|
||||
param.put("airTaskKeywords", "空中,制空,拦截,空战");
|
||||
param.put("airTaskScore", 10);
|
||||
// ③ 任务文案像地面任务 且 红方偏好地面火力 → + groundScore * weight
|
||||
param.put("groundTaskKeywords", "地面,突击,登陆");
|
||||
param.put("redPreferredWhenGround", "远火,榴弹,炮,火箭");
|
||||
param.put("groundScore", 1);
|
||||
// ④ 蓝方像坦克/装甲目标 且 红方文本命中 redMatchKeywords_tank → + tankScore * weight
|
||||
param.put("tankKeywords", "坦克,装甲");
|
||||
param.put("redMatchKeywords_tank", "反坦克");
|
||||
param.put("tankScore", 1);
|
||||
// ⑤ 蓝方像导弹类 且 红方文本命中 redMatchKeywords_missile → + missileScore * weight
|
||||
param.put("missileKeywords", "导弹,火箭弹,巡航");
|
||||
param.put("redMatchKeywords_missile", "防空,导弹,导弹发射");
|
||||
param.put("missileScore", 1);
|
||||
|
||||
// ===================== 目标分配参数(写入 Tasks.task.execute) =====================
|
||||
// executeTypeDefault:生成 execute[0] 的类型字段
|
||||
param.put("executeTypeDefault", "assault");
|
||||
// targetPickMode:roundRobin(稳定轮询) / random(伪随机但同输入稳定)
|
||||
param.put("targetPickMode", "roundRobin");
|
||||
// minTargetsPerRed / maxTargetsPerRedCap:每个红方任务最少/最多分配的目标数
|
||||
param.put("minTargetsPerRed", 1);
|
||||
param.put("maxTargetsPerRedCap", 3);
|
||||
// radToTargetsCsv:successTargetRad(命中率) -> 每红装目标数 的映射(阈值:目标数),按阈值从大到小匹配
|
||||
// 例:0.8:1,0.5:2,0.2:3 表示 successTargetRad>=0.8 分1个;>=0.5 分2个;>=0.2 分3个
|
||||
param.put("radToTargetsCsv", "0.8:1,0.5:2,0.2:3");
|
||||
// rangeParseRegex:从 attDefaultValue/attExplain 中提取射程数值的正则(取第1个数字)
|
||||
param.put("rangeParseRegex", "(\\\\d+(?:\\\\.\\\\d+)?)");
|
||||
// rangeUnit:提取数值的单位,km/m(二选一)
|
||||
param.put("rangeUnit", "km");
|
||||
// minRangeToAllowAssignKm:若解析到的蓝方射程小于该值,则该蓝方装备不参与被分配(无法解析则忽略此过滤)
|
||||
param.put("minRangeToAllowAssignKm", 0);
|
||||
|
||||
// ===================== 低命中率补拿装备参数 =====================
|
||||
// redHitRateThreshold:红方装备命中率阈值(低于该值时触发补拿)
|
||||
param.put("redHitRateThreshold", 0.6);
|
||||
// maxExtraWeaponsPerTask:每条蓝方任务最多补拿几件红装
|
||||
param.put("maxExtraWeaponsPerTask", 2);
|
||||
// maxSupplementRounds:补拿循环最大轮次(防死循环)
|
||||
param.put("maxSupplementRounds", 2);
|
||||
// extraPickMinScore:补拿时红装最低匹配分
|
||||
param.put("extraPickMinScore", 1);
|
||||
|
||||
// ===================== 阵位规则参数(写入 SubComponents.platform[].positions) =====================
|
||||
// positionRuleEnabled:是否启用阵位规则。true=执行阵位生成;false=跳过,不改 platform.positions。
|
||||
param.put("positionRuleEnabled", true);
|
||||
// positionAnchorMode:锚点模式。当前实现使用 hybrid(蓝方 taskWeapons.coordinate 的中心点作为主锚点)。
|
||||
param.put("positionAnchorMode", "hybrid");
|
||||
// trackPointDirectionMode:航向计算模式。
|
||||
// - head2next:取 trackPoints[0] -> trackPoints[1] 作为方向(默认)
|
||||
// - tail2prev:取倒数第二个 -> 最后一个点作为方向
|
||||
param.put("trackPointDirectionMode", "head2next");
|
||||
// fallbackBearingDeg:当 trackPoints 缺失或无法计算方位时,使用该默认方位角(度,0-360)。
|
||||
param.put("fallbackBearingDeg", 0);
|
||||
// deployDistanceKmMin:部署距离下限(km)。最终距离不会小于该值。
|
||||
param.put("deployDistanceKmMin", 8);
|
||||
// deployDistanceKmMax:部署距离上限(km)。最终距离不会大于该值。
|
||||
param.put("deployDistanceKmMax", 30);
|
||||
// deployDistanceKmDefault:默认部署距离(km)。
|
||||
// 当 distanceByPlatformCsv 未命中任何关键词时,使用该值。
|
||||
param.put("deployDistanceKmDefault", 15);
|
||||
// distanceByPlatformCsv:按“关键词”覆盖部署距离(km),不写死具体类型,完全由业务配置。
|
||||
// 格式:关键词:距离,关键词:距离(示例:防空:18,反坦克:10,迫击炮:8)
|
||||
// 匹配范围:红方装备 Name / Platform_type 文本包含关键词即命中。
|
||||
// 优先级:命中后覆盖 deployDistanceKmDefault;但最终仍受 deployDistanceKmMin 与 deployDistanceKmMax 约束。
|
||||
param.put("distanceByPlatformCsv", "");
|
||||
// formationType:编队样式,可选 line / wedge / circle。
|
||||
param.put("formationType", "line");
|
||||
// formationSpacingMeters:编队间距(米),影响同一红装下 platform[] 点位离散程度。
|
||||
// 说明:Java 侧会与 minInterPlatformDistanceMeters 比较,取更大值,避免平台重叠过近。
|
||||
param.put("formationSpacingMeters", 300);
|
||||
// formationHeadingOffsetDeg:编队相对主航向的偏转角(度),主要用于 wedge/circle 的分散方向。
|
||||
param.put("formationHeadingOffsetDeg", 15);
|
||||
// defaultDeployHeight:默认部署高度(米),用于 positions 第3位高度值基线。
|
||||
param.put("defaultDeployHeight", 30);
|
||||
// heightFollowBlueRatio:高度跟随蓝方比例(>=0)。
|
||||
// 计算方式:高度 = defaultDeployHeight + 蓝方锚点平均高度 * heightFollowBlueRatio。
|
||||
// 0 表示不跟随蓝方高度,仅使用默认高度。
|
||||
param.put("heightFollowBlueRatio", 0.0);
|
||||
// enableWarZoneClamp:是否启用作战区约束。true=超出 warZoneLocation 时回拉到区内。
|
||||
param.put("enableWarZoneClamp", true);
|
||||
// warZoneClampMode:作战区约束模式。当前实现使用 nearestInside(沿锚点到目标点方向二分回拉到区内)。
|
||||
param.put("warZoneClampMode", "nearestInside");
|
||||
// minInterPlatformDistanceMeters:平台最小间距(米)下限,用于抑制平台点位过度重叠。
|
||||
param.put("minInterPlatformDistanceMeters", 80);
|
||||
|
||||
// ===================== 航迹规则参数(写入 TrackParam 动态 key + execute.targetList.moveRouteId) =====================
|
||||
// trackRuleEnabled:是否启用航迹生成与 moveRouteId 绑定。
|
||||
param.put("trackRuleEnabled", true);
|
||||
// trackRouteAlgorithm:航迹变形算法。followBlue(默认) / shortestPath / flank / jam
|
||||
param.put("trackRouteAlgorithm", "followBlue");
|
||||
// trackRouteNameSuffix:航迹名称 = 红方任务 drawName + 此后缀(默认「航迹」→ 如 xxx打击任务航迹)
|
||||
param.put("trackRouteNameSuffix", "航迹");
|
||||
// trackAirDataTypeCsv:蓝方 dataType 命中任一子串(忽略大小写)则 TrackType=routeLineAir
|
||||
param.put("trackAirDataTypeCsv", "taskPlane,air,plane,flight");
|
||||
// trackAirKeywordsCsv:蓝方 drawName 或红方 name/platformType 命中任一子串则视为飞行航迹
|
||||
param.put("trackAirKeywordsCsv", "机,飞,空,J-,F-,无人机,直升机");
|
||||
// trackGroundTrackType:非飞行类时 TrackType 取值(可先占位,后续再接地面路网)
|
||||
param.put("trackGroundTrackType", "routeLineGround");
|
||||
// 航迹侧向算法复用上方「阵位规则」中的 trackPointDirectionMode(head2next / tail2prev);缺省回退见 trackFallbackBearingDeg
|
||||
param.put("trackFallbackBearingDeg", 0);
|
||||
// enableTrackWarZoneClamp:航迹点是否约束在 warZoneLocation 多边形内
|
||||
param.put("enableTrackWarZoneClamp", true);
|
||||
// trackExtraNodesMax:在蓝方航迹点基础上最多额外插入的点数(0=与蓝方点数持平;>0 时在中段均匀插值)
|
||||
param.put("trackExtraNodesMax", 0);
|
||||
// shortestPath:相邻两点间直线插值分段数(>=1),越大折线越平滑(非真实路网最短路径)
|
||||
param.put("trackShortPathSegments", 3);
|
||||
// flank:侧向偏移距离(米);trackFlankSideMode:alternate / left / right
|
||||
param.put("trackFlankOffsetMeters", 800);
|
||||
param.put("trackFlankSideMode", "alternate");
|
||||
// jam:正弦扰动振幅(米)、沿航迹起伏周期数(越大摆动越密)
|
||||
param.put("trackJamWobbleMeters", 400);
|
||||
param.put("trackJamSegments", 4);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
rule "装备匹配"
|
||||
salience 100
|
||||
when
|
||||
$fact : DroolsFact(task != null)
|
||||
then
|
||||
// 以本文件 buildParam 为真源覆盖同名键,再执行 Java 侧匹配逻辑
|
||||
globalParams.putAll(buildParam());
|
||||
equipmentRule($fact, globalParams);
|
||||
end
|
||||
|
||||
rule "目标匹配"
|
||||
salience 90
|
||||
when
|
||||
$fact : DroolsFact(task != null)
|
||||
then
|
||||
// 显式目标分配规则:填充 Tasks.task.execute.targetList[*].targetId
|
||||
globalParams.putAll(buildParam());
|
||||
target($fact, globalParams);
|
||||
end
|
||||
|
||||
rule "阵位匹配"
|
||||
salience 80
|
||||
when
|
||||
$fact : DroolsFact(task != null)
|
||||
then
|
||||
// 显式阵位规则:填充 redWeapons.SubComponents.platform[].positions
|
||||
globalParams.putAll(buildParam());
|
||||
position($fact, globalParams);
|
||||
end
|
||||
|
||||
rule "航迹匹配"
|
||||
salience 70
|
||||
when
|
||||
$fact : DroolsFact(task != null)
|
||||
then
|
||||
// 显式航迹规则:填充 TrackParam 下各航迹 id,并绑定 execute[0].targetList[*].moveRouteId
|
||||
globalParams.putAll(buildParam());
|
||||
trackRoute($fact, globalParams);
|
||||
end
|
||||
Reference in New Issue
Block a user