rts-sim-testing-service/ats/verify/simulation/wayside/memory/wayside_simulation.go

342 lines
9.4 KiB
Go

package memory
import (
"fmt"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
"joylink.club/rtsssimulation/repository"
"joylink.club/rtsssimulation/repository/model/proto"
"joylink.club/rtsssimulation/simulation"
"joylink.club/rtsssimulation/system"
"sort"
"strconv"
"strings"
)
// 轨旁仿真定义
type VerifySimulation struct {
//地图id
MapIds []int32
// 项目ID
ProjectId int32
//仿真id
SimulationId string
//仿真内存数据
Memory *WaysideMemory
//模型仓库
Repo *repository.Repository
//Rtss仿真世界的id
WorldId int
}
// 创建仿真对象
func CreateSimulation(projectId int32, mapIds []int32) (*VerifySimulation, error) {
//构建Repository
sort.Slice(mapIds, func(i, j int) bool {
return mapIds[i] < mapIds[j]
})
var mapIdStrSlice []string
for _, id := range mapIds {
mapIdStrSlice = append(mapIdStrSlice, strconv.Itoa(int(id)))
}
repoId := strings.Join(mapIdStrSlice, "|")
repoVersion := "0.1"
repo := repository.FindRepository(repoId, repoVersion)
if repo == nil {
var storages []*graphicData.RtssGraphicStorage
for _, mapId := range mapIds {
storages = append(storages, QueryGraphicStorage(mapId))
}
protoRepo := buildProtoRepository(storages)
newRepo, err := repository.BuildRepository(protoRepo)
repo = newRepo
if err != nil {
return nil, err
}
}
//创建仿真
worldId := simulation.CreateSimulation(repo, system.SWITCH_ZDJ9_2)
verifySimulation := &VerifySimulation{
MapIds: mapIds,
ProjectId: projectId,
Memory: NewWaysideMemory(),
Repo: repo,
WorldId: worldId,
}
return verifySimulation, nil
//m := &WaysideMemory{}
//verifySimulation := &VerifySimulation{
// MapIds: mapIds,
// ProjectId: projectId,
// Memory: m.Create(),
//}
//s := verifySimulation.Memory.Status
//// 初始化构地图设备状态
//for _, mapId := range mapIds {
// InitFromMap(s, QueryMapVerifyStructure(mapId))
//}
//return verifySimulation
}
// 获取全量状态
func (s *VerifySimulation) GetAllState() *state.PushedDevicesStatus {
return &state.PushedDevicesStatus{
All: true,
AllStatus: &state.AllDevicesStatus{
SwitchState: GetAllTurnoutState(s),
TrainState: GetAllTrainState(s),
SectionState: append(GetAllAxleSectionState(s), GetAllPhysicalSectionState(s)...),
},
}
}
// 获取变量状态
func (s *VerifySimulation) GetChangeState() *state.PushedDevicesStatus {
return &state.PushedDevicesStatus{
All: false,
VarStatus: &state.VariationStatus{
UpdatedSwitch: GetChangeTurnoutState(s),
RemovedTrainId: GetRemovedTrainId(s),
UpdatedTrain: GetUpdatedTrainState(s),
},
}
}
func buildProtoRepository(storages []*graphicData.RtssGraphicStorage) *proto.Repository {
repo := &proto.Repository{}
for _, storage := range storages {
fillProtoRepository(repo, storage)
}
return repo
}
func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphicStorage) {
axleCountingMap := make(map[string]*graphicData.AxleCounting)
for _, data := range storage.AxleCountings {
if data.KilometerSystem == nil {
println(fmt.Sprintf("计轴[%s]缺少公里标", data.Common.Id))
continue
}
axleCountingMap[data.Common.Id] = data
cpType := proto.CheckPointType_AxleCounter
if data.Invent {
cpType = proto.CheckPointType_Boundary
}
cp := &proto.CheckPoint{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
Type: cpType,
DevicePorts: convertDevicePorts(data.AxleCountingRef),
}
repo.CheckPoints = append(repo.CheckPoints, cp)
}
for _, data := range storage.Section {
var turnoutIds []string
if data.SectionType == graphicData.Section_TurnoutPhysical {
turnoutIds = findTurnoutIds(axleCountingMap, data.AxleCountings)
}
physicalSection := &proto.PhysicalSection{
Id: data.Common.Id,
ADevicePort: convertDevicePort(data.PaRef),
BDevicePort: convertDevicePort(data.PbRef),
TurnoutIds: turnoutIds,
}
repo.PhysicalSections = append(repo.PhysicalSections, physicalSection)
}
for _, data := range storage.Turnouts {
var km *proto.Kilometer
for _, ks := range data.KilometerSystem {
if ks.Kilometer != 0 {
km = convertKm(ks)
break
}
}
for _, kc := range buildKmConverts(data.KilometerSystem) {
repo.KilometerConverts = append(repo.KilometerConverts, kc)
}
turnout := &proto.Turnout{
Id: data.Common.Id,
Km: km,
ADevicePort: convertDevicePort(data.PaRef),
BDevicePort: convertDevicePort(data.PbRef),
CDevicePort: convertDevicePort(data.PcRef),
}
repo.Turnouts = append(repo.Turnouts, turnout)
}
for _, data := range storage.Signals {
var sectionId string
var turnoutPort *proto.DevicePort
switch data.RefDev.DeviceType {
case graphicData.RelatedRef_Section:
sectionId = data.RefDev.Id
case graphicData.RelatedRef_Turnout:
turnoutPort = convertDevicePort(data.RefDev)
}
signal := &proto.Signal{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
SectionId: sectionId,
TurnoutPort: turnoutPort,
}
repo.Signals = append(repo.Signals, signal)
}
for _, data := range storage.Transponders {
var sectionId string
var turnoutPort *proto.DevicePort
switch data.TransponderRef.DeviceType {
case graphicData.RelatedRef_Section:
sectionId = data.TransponderRef.Id
case graphicData.RelatedRef_Turnout:
turnoutPort = convertDevicePort(data.TransponderRef)
}
responder := &proto.Transponder{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
SectionId: sectionId,
TurnoutPort: turnoutPort,
}
repo.Transponders = append(repo.Transponders, responder)
}
slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker)
for _, data := range storage.SlopeKiloMarker {
slopeKsMap[data.Common.Id] = data
for _, kc := range buildKmConverts(data.KilometerSystem) {
repo.KilometerConverts = append(repo.KilometerConverts, kc)
}
}
curveKsMap := make(map[string]*graphicData.CurvatureKiloMarker)
for _, data := range storage.CurvatureKiloMarker {
curveKsMap[data.Common.Id] = data
for _, kc := range buildKmConverts(data.KilometerSystem) {
repo.KilometerConverts = append(repo.KilometerConverts, kc)
}
}
for _, data := range storage.Slopes {
var kms []*proto.Kilometer
for _, id := range data.RefDeviceId {
kms = append(kms, convertKm(slopeKsMap[id].KilometerSystem[0]))
}
slope := &proto.Slope{
Id: data.Common.Id,
Kms: kms,
Degree: data.SlopeNumber,
}
repo.Slopes = append(repo.Slopes, slope)
}
for _, data := range storage.Curvatures {
var kms []*proto.Kilometer
for _, id := range data.RefDeviceId {
kms = append(kms, convertKm(curveKsMap[id].KilometerSystem[0]))
}
slope := &proto.SectionalCurvature{
Id: data.Common.Id,
Kms: kms,
Radius: data.CurvatureNumber,
}
repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope)
}
}
func convertKm(ks *graphicData.KilometerSystem) *proto.Kilometer {
var dir proto.Direction
switch ks.Direction {
case graphicData.Direction_LEFT:
dir = proto.Direction_LEFT
case graphicData.Direction_RIGHT:
dir = proto.Direction_RIGHT
}
return &proto.Kilometer{
Value: ks.Kilometer,
CoordinateSystem: ks.CoordinateSystem,
Direction: dir,
}
}
func convertDevicePort(ref *graphicData.RelatedRef) *proto.DevicePort {
if ref == nil {
return nil
}
var deviceType proto.DeviceType
var port proto.Port
switch ref.DevicePort {
case graphicData.RelatedRef_A:
port = proto.Port_A
case graphicData.RelatedRef_B:
port = proto.Port_B
case graphicData.RelatedRef_C:
port = proto.Port_C
}
switch ref.DeviceType {
case graphicData.RelatedRef_Section:
deviceType = proto.DeviceType_DeviceType_PhysicalSection
case graphicData.RelatedRef_Turnout:
deviceType = proto.DeviceType_DeviceType_Turnout
default:
panic(fmt.Sprintf("异常的设备类型-%s", ref.DeviceType))
}
return &proto.DevicePort{
DeviceId: ref.Id,
DeviceType: deviceType,
Port: port,
}
}
func convertDevicePorts(refList []*graphicData.RelatedRef) []*proto.DevicePort {
var dps []*proto.DevicePort
for _, ref := range refList {
dps = append(dps, convertDevicePort(ref))
}
return dps
}
func findTurnoutIds(axleCountingMap map[string]*graphicData.AxleCounting, axleIds []string) []string {
if len(axleIds) <= 2 {
return nil
}
turnoutMap := make(map[string]bool)
for _, axleId := range axleIds {
axle := axleCountingMap[axleId]
relTurnoutCount := 0
var turnoutId string
for _, ref := range axle.AxleCountingRef {
if ref.DeviceType == graphicData.RelatedRef_Turnout {
relTurnoutCount++
turnoutId = ref.Id
}
}
if relTurnoutCount == 1 {
turnoutMap[turnoutId] = true
}
}
var turnoutIds []string
for id, _ := range turnoutMap {
turnoutIds = append(turnoutIds, id)
}
return turnoutIds
}
func buildKmConverts(ksList []*graphicData.KilometerSystem) []*proto.KilometerConvert {
var kmConverts []*proto.KilometerConvert
for i, ks := range ksList {
if ks.Kilometer == 0 {
continue
}
for j := i + 1; j < len(ksList); j++ {
if ks.Kilometer == 0 {
continue
}
kmConverts = append(kmConverts, buildKmConvert(ks, ksList[j]))
}
}
return kmConverts
}
func buildKmConvert(ks1 *graphicData.KilometerSystem, ks2 *graphicData.KilometerSystem) *proto.KilometerConvert {
return &proto.KilometerConvert{
KmA: convertKm(ks1),
KmB: convertKm(ks2),
SameTrend: false,
}
}