rts-sim-testing-service/ats/verify/simulation/wayside/memory/wayside_simulation.go
2023-10-18 13:53:17 +08:00

782 lines
24 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package memory
import (
"fmt"
"log/slog"
"sort"
"strconv"
"strings"
"sync"
rtss_simulation "joylink.club/rtsssimulation"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
"joylink.club/bj-rtsts-server/dto"
"joylink.club/ecs"
"joylink.club/rtsssimulation/repository"
"joylink.club/rtsssimulation/repository/model/proto"
)
// 轨旁仿真定义
type VerifySimulation struct {
//地图id
MapIds []int32
// 项目ID
ProjectId int32
//仿真id
SimulationId string
//仿真内存数据
Memory *WaysideMemory
//模型仓库
Repo *repository.Repository
//Rtss仿真世界的id
WorldId ecs.WorldId
World ecs.World
//设备UID映射
uidMap map[string]*elementIdStructure
}
// 轨旁仿真内存模型
type WaysideMemory struct {
//可变状态数据:轨旁仿真模型状态(全量数据)
Status *VerifyStatus
// 要变更的状态:用户操作过的状态记录在这里,增量推送次数据
ChangeStatus *ChangeVerifyStatus
//状态保护锁
rwLock *sync.RWMutex
}
// 轨旁仿真模型状态
type VerifyStatus struct {
//道岔状态key为道岔id即索引 state.SwitchState
SwitchStateMap sync.Map
//轨道状态key为轨道id即索引 state.LinkState
LinkStateMap sync.Map
//列车状态key为列车id即索引 state.TrainState
TrainStateMap sync.Map
//计轴区段状态key为计轴区段的id即索引 state.SectionState
AxleSectionStateMap sync.Map
//物理区段状态key为物理区段id即索引 state.SectionState
PhysicalSectionStateMap sync.Map
//逻辑区段状态key为逻辑区段id即索引 state.SectionState
LogicSectionStateMap sync.Map
//信号机状态key为信号机id,即索引 state.SignalState
SignalStateMap sync.Map
}
// 轨旁仿真模型状态(变更)
type ChangeVerifyStatus struct {
VerifyStatus
//删除的列车ID列表
RemoveTrainId []string
}
func NewWaysideMemory() *WaysideMemory {
return &WaysideMemory{
Status: &VerifyStatus{},
ChangeStatus: &ChangeVerifyStatus{},
rwLock: &sync.RWMutex{},
}
}
// 创建仿真对象
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 {
protoRepo, err := buildProtoRepository(mapIds)
if err != nil {
return nil, err
}
protoRepo.Id, protoRepo.Version = repoId, repoVersion
newRepo, err := repository.BuildRepository(protoRepo)
if err != nil {
return nil, err
}
repo = newRepo
}
// 目前用本地构建状态
worldMemory := NewWaysideMemory()
initWorldDeviceState(worldMemory.Status, repo)
// 构建所有UID映射关系
allUidMap := buildRepositoryAllUidsMap(mapIds, repo)
//创建仿真
// worldId := world.CreateSimulation(repo)
w := rtss_simulation.NewSimulation(repo)
w.StartUp()
verifySimulation := &VerifySimulation{
MapIds: mapIds,
ProjectId: projectId,
Memory: worldMemory,
Repo: repo,
World: w,
WorldId: w.Id(),
uidMap: allUidMap,
}
return verifySimulation, nil
}
// 获取全量状态
func (s *VerifySimulation) GetAllState(mapId int32) *state.PushedDevicesStatus {
giType := QueryGiType(mapId)
switch giType {
case graphicData.PictureType_StationLayout:
return &state.PushedDevicesStatus{
All: true,
AllStatus: &state.AllDevicesStatus{
SwitchState: GetMapAllTurnoutState(s, mapId),
TrainState: GetAllTrainState(s),
SignalState: GetMapAllSignalState(s, mapId),
ButtonState: GetMapAllStationButtonState(s, mapId),
},
}
case graphicData.PictureType_RelayCabinetLayout:
return &state.PushedDevicesStatus{
All: true,
AllStatus: &state.AllDevicesStatus{
ReplyState: GetMapAllRelayState(s, mapId),
},
}
}
return &state.PushedDevicesStatus{}
}
// 获取门控箱状态
func (s *VerifySimulation) GetAllPSLState(mapId int32, boxId string) *state.PushedDevicesStatus {
return &state.PushedDevicesStatus{
All: true,
AllStatus: &state.AllDevicesStatus{
ButtonState: []*state.ButtonState{},
},
}
}
// 获取车站IBP状态
func (s *VerifySimulation) GetAllIBPState(mapId int32, stationId string) *state.PushedDevicesStatus {
return &state.PushedDevicesStatus{
All: true,
AllStatus: GetMapAllIBPState(s, mapId, stationId),
}
}
// 获取仿真世界信息
func (s *VerifySimulation) GetSimulationWorld() ecs.World {
return s.World
}
// 获取仿真世界信息
func (s *VerifySimulation) GetComIdByUid(uid string) string {
es := s.uidMap
if es == nil {
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: "无映射信息"})
}
if es[uid] == nil {
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: "无【uid】映射信息"})
}
return es[uid].CommonId
}
func buildProtoRepository(mapIds []int32) (*proto.Repository, error) {
repo := &proto.Repository{}
var exceptStationGiMapIds []int32
//创建设备
for _, mapId := range mapIds {
giType := QueryGiType(mapId)
if giType == graphicData.PictureType_StationLayout {
stationGi := QueryGiData[*graphicData.RtssGraphicStorage](mapId)
fillProtoRepository(repo, stationGi, mapId)
} else {
exceptStationGiMapIds = append(exceptStationGiMapIds, mapId)
}
}
//构建并关联电子元件
for _, mapId := range exceptStationGiMapIds {
giType := QueryGiType(mapId)
if giType == graphicData.PictureType_RelayCabinetLayout {
relayGi := QueryGiData[*graphicData.RelayCabinetGraphicStorage](mapId)
buildAndRelateElectronicComponent(repo, relayGi, mapId)
}
}
return repo, nil
}
func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *graphicData.RelayCabinetGraphicStorage, mapId int32) {
uidsMap := queryUidStructure[*relayUidStructure](mapId)
city := relayGi.UniqueIdPrefix.City
lineId := relayGi.UniqueIdPrefix.LineId
station := relayGi.UniqueIdPrefix.BelongsConcentrationStation
for _, relay := range relayGi.Relays {
repo.Relays = append(repo.Relays, &proto.Relay{
Id: uidsMap.RelayIds[relay.Common.Id].Uid,
Code: relay.Code,
Model: convertRelayModel(relay.NewModel),
})
}
for _, pfp := range relayGi.PhaseFailureProtectors {
repo.PhaseFailureProtectors = append(repo.PhaseFailureProtectors, &proto.PhaseFailureProtector{
Id: uidsMap.RelayIds[pfp.Common.Id].Uid,
Code: pfp.Code,
})
}
turnoutMap := make(map[string]*proto.Turnout)
for _, turnout := range repo.Turnouts {
turnoutMap[turnout.Id] = turnout
}
signalMap := make(map[string]*proto.Signal)
for _, signal := range repo.Signals {
signalMap[signal.Id] = signal
}
stationMap := make(map[string]*proto.Station)
for _, station := range repo.Stations {
stationMap[station.Id] = station
}
for _, relationship := range relayGi.DeviceRelateRelayList {
switch relationship.DeviceType {
case graphicData.RelatedRef_Turnout:
turnout := turnoutMap[GenerateElementUid(city, lineId, []string{station}, relationship.Code)]
if turnout == nil {
continue
}
for _, group := range relationship.Combinationtypes {
var componentIds []string
for _, relayId := range group.RefRelays {
if uidsMap.RelayIds[relayId] == nil {
continue
}
componentIds = append(componentIds, uidsMap.RelayIds[relayId].Uid)
}
turnout.ElectronicComponentGroups = append(turnout.ElectronicComponentGroups,
&proto.ElectronicComponentGroup{
Code: group.Code,
ComponentIds: componentIds,
})
}
case graphicData.RelatedRef_signal:
signal := signalMap[GenerateElementUid(city, lineId, []string{station}, relationship.Code)]
if signal == nil {
continue
}
//信号机只有一个组合类型
if len(relationship.Combinationtypes) != 1 {
panic(fmt.Sprintf("信号机[%s]须有一个组合类型", signal.Id))
}
group := relationship.Combinationtypes[0]
var componentIds []string
for _, relayId := range group.RefRelays {
if uidsMap.RelayIds[relayId] == nil {
continue
}
componentIds = append(componentIds, uidsMap.RelayIds[relayId].Uid)
}
signal.Code = group.Code
signal.ElectronicComponentGroups = append(signal.ElectronicComponentGroups,
&proto.ElectronicComponentGroup{
Code: group.Code,
ComponentIds: componentIds,
})
case graphicData.RelatedRef_station:
station := stationMap[GenerateElementUid(city, lineId, nil, relationship.Code)]
if station == nil {
continue
}
for _, group := range relationship.Combinationtypes {
d := &proto.ElectronicGroup{Code: group.Code}
for _, relayId := range group.RefRelays {
if uidsMap.RelayIds[relayId] == nil {
continue
}
d.Components = append(d.Components, &proto.ElectronicComponent{
Id: uidsMap.RelayIds[relayId].Uid,
DeviceType: proto.DeviceType_DeviceType_Relay,
})
}
station.ElectronicGroup = append(station.ElectronicGroup, d)
}
}
}
}
func convertRelayModel(modelType graphicData.Relay_ModelType) proto.Relay_Model {
switch modelType {
case graphicData.Relay_Unknown:
return proto.Relay_Unknown
case graphicData.Relay_JPXC_1000:
return proto.Relay_JPXC_1000
case graphicData.Relay_JPXC_1700:
return proto.Relay_JPXC_1700
case graphicData.Relay_JWJXC_480:
return proto.Relay_JWJXC_480
case graphicData.Relay_JWJXC_H125_80:
return proto.Relay_JWJXC_H125_80
case graphicData.Relay_JWXC_1700:
return proto.Relay_JWXC_1700
case graphicData.Relay_JWXC_H340:
return proto.Relay_JWXC_H340
case graphicData.Relay_JYJXC_160_260:
return proto.Relay_JYJXC_160_260
case graphicData.Relay_JZXC_H18:
return proto.Relay_JZXC_H18
default:
panic(fmt.Sprintf("意料之外的继电器型号:%s", modelType))
}
}
func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphicStorage, mapId int32) {
axleCountingMap := make(map[string]*graphicData.AxleCounting)
uidsMap := queryUidStructure[*stationUidStructure](mapId)
for _, data := range storage.AxleCountings {
axleCountingMap[data.Common.Id] = data
cpType := proto.CheckPointType_AxleCounter
if data.Type == graphicData.AxleCounting_SectionBoundary {
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, converCheckPointUid(cp, uidsMap))
}
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, converSectionUid(physicalSection, uidsMap))
}
for _, data := range storage.Turnouts {
var km *proto.Kilometer
for _, ks := range data.KilometerSystem {
if ks.Kilometer != 0 {
km = convertKm(ks)
break
}
}
var switchMachineType proto.Turnout_SwitchMachineType
switch data.SwitchMachineType {
case graphicData.Turnout_ZDJ9_Single:
switchMachineType = proto.Turnout_ZDJ9_Single
case graphicData.Turnout_ZDJ9_Double:
switchMachineType = proto.Turnout_ZDJ9_Double
}
turnout := &proto.Turnout{
Id: data.Common.Id,
Km: km,
ADevicePort: convertDevicePort(data.PaRef),
BDevicePort: convertDevicePort(data.PbRef),
CDevicePort: convertDevicePort(data.PcRef),
SwitchMachineType: switchMachineType,
}
repo.Turnouts = append(repo.Turnouts, converTurnoutUid(turnout, uidsMap))
}
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, converSignalUid(signal, uidsMap))
}
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, converTransponderUid(responder, uidsMap))
}
slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker)
for _, data := range storage.SlopeKiloMarker {
slopeKsMap[data.Common.Id] = data
}
curveKsMap := make(map[string]*graphicData.CurvatureKiloMarker)
for _, data := range storage.CurvatureKiloMarker {
curveKsMap[data.Common.Id] = data
}
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, converSlopeUid(slope, uidsMap))
}
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, converCurvatureUid(slope, uidsMap))
}
for _, data := range storage.KilometerConvertList {
repo.KilometerConverts = append(repo.KilometerConverts, &proto.KilometerConvert{
KmA: convertKm(data.KmA),
KmB: convertKm(data.KmB),
SameTrend: data.SameTrend,
})
}
// 初始化站场图按钮
for _, data := range storage.EsbButtons {
repo.Buttons = append(repo.Buttons, &proto.Button{
Id: uidsMap.ButtonIds[data.Common.Id].Uid,
Code: data.Code,
ButtonType: proto.Button_Reset_Press,
})
}
// 车站关联关系
relateMap := make(map[string]*graphicData.StationRelateDevice)
for _, data := range storage.StationRelateDeviceList {
relateMap[data.Code] = data
}
// 处理车站信息
for _, data := range storage.Stations {
station := &proto.Station{
Id: uidsMap.StationIds[data.Common.Id].Uid,
Code: data.Code,
}
// 关联车站的设备
refs, ok := relateMap[data.Code]
if ok {
for _, c := range refs.Combinationtypes {
group := &proto.ElectronicGroup{Code: c.Code}
for _, d := range c.RefDevices {
var comp *proto.ElectronicComponent
if uidsMap.ButtonIds[d] != nil { // 目前只处理按钮
comp = &proto.ElectronicComponent{
Id: uidsMap.ButtonIds[d].Uid,
DeviceType: proto.DeviceType_DeviceType_Button,
}
} else {
continue
}
group.Components = append(group.Components, comp)
}
station.ElectronicGroup = append(station.ElectronicGroup, group)
}
}
// 处理车站关联IBP的设备
handlerIBPDeviceToStation(uidsMap, station, repo, data.RefIbpMapCode)
repo.Stations = append(repo.Stations, station)
}
}
// 将IBP的设备关联到车站中
func handlerIBPDeviceToStation(uidsMap *stationUidStructure, station *proto.Station, repo *proto.Repository, ibpMap string) {
storage := getStorageIBPMapData(ibpMap)
if storage == nil {
return
}
ibpIdMap := uidsMap.IBPIds[station.Code] // 车站对应的UID集合
typeMap := make(map[string]proto.DeviceType) // 对应的设备类型
for _, data := range storage.IbpButtons { // 处理按钮
buttonType := proto.Button_NO_Reset_Press
if data.IsSelfReset {
buttonType = proto.Button_Reset_Press
}
b := &proto.Button{
Id: ibpIdMap[data.Common.Id].Uid,
Code: data.Code,
ButtonType: buttonType,
}
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Button
repo.Buttons = append(repo.Buttons, b)
}
for _, data := range storage.IbpKeys { // 钥匙
b := &proto.Button{
Id: ibpIdMap[data.Common.Id].Uid,
Code: data.Code,
ButtonType: proto.Button_Key_Knob,
}
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Button
repo.Buttons = append(repo.Buttons, b)
}
for _, data := range storage.IbpAlarms { // 报警器
b := &proto.Alarm{
Id: ibpIdMap[data.Common.Id].Uid,
Code: data.Code,
}
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Alarm
repo.Alarms = append(repo.Alarms, b)
}
for _, data := range storage.IbpLights { // 指示灯
b := &proto.Light{
Id: ibpIdMap[data.Common.Id].Uid,
Code: data.Code,
Aspect: converIbpLightAspect(data.Color),
}
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Light
repo.Lights = append(repo.Lights, b)
}
// 组信息
for _, data := range storage.IbpRelatedDevices {
for _, c := range data.Combinationtypes {
group := &proto.ElectronicGroup{Code: c.Code}
for _, d := range c.RefDevices {
deviceType, ok := typeMap[d]
if !ok {
slog.Debug("IBP组合类型类型不确定id:%s", d)
continue
}
group.Components = append(group.Components, &proto.ElectronicComponent{
Id: ibpIdMap[d].Uid,
DeviceType: deviceType,
})
}
station.ElectronicGroup = append(station.ElectronicGroup, group)
}
}
}
// 将IBP的灯颜色转换成repo灯颜色
func converIbpLightAspect(color graphicData.IbpLight_IbpLightColor) proto.Light_LightAspect {
switch color {
case graphicData.IbpLight_white:
return proto.Light_B
case graphicData.IbpLight_red:
return proto.Light_H
case graphicData.IbpLight_green:
return proto.Light_L
case graphicData.IbpLight_blue:
return proto.Light_A
default:
panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "未知的灯颜色类型" + color.String()})
}
}
func converCheckPointUid(data *proto.CheckPoint, uidsMap *stationUidStructure) *proto.CheckPoint {
data.Id = uidsMap.AxlePointIds[data.Id].Uid
for _, c := range data.DevicePorts {
c.DeviceId = converRefUid(c.DeviceId, c.DeviceType, uidsMap)
}
return data
}
func converSectionUid(data *proto.PhysicalSection, uidsMap *stationUidStructure) *proto.PhysicalSection {
data.Id = uidsMap.PhysicalSectionIds[data.Id].Uid
if data.ADevicePort != nil {
data.ADevicePort.DeviceId = converRefUid(data.ADevicePort.DeviceId, data.ADevicePort.DeviceType, uidsMap)
}
if data.BDevicePort != nil {
data.BDevicePort.DeviceId = converRefUid(data.BDevicePort.DeviceId, data.BDevicePort.DeviceType, uidsMap)
}
tids := make([]string, len(data.TurnoutIds))
for i, tid := range data.TurnoutIds {
tids[i] = converRefUid(tid, proto.DeviceType_DeviceType_Turnout, uidsMap)
}
data.TurnoutIds = tids
return data
}
func converTurnoutUid(data *proto.Turnout, uidsMap *stationUidStructure) *proto.Turnout {
data.Id = uidsMap.TurnoutIds[data.Id].Uid
if data.ADevicePort != nil {
data.ADevicePort.DeviceId = converRefUid(data.ADevicePort.DeviceId, data.ADevicePort.DeviceType, uidsMap)
}
if data.BDevicePort != nil {
data.BDevicePort.DeviceId = converRefUid(data.BDevicePort.DeviceId, data.BDevicePort.DeviceType, uidsMap)
}
if data.CDevicePort != nil {
data.CDevicePort.DeviceId = converRefUid(data.CDevicePort.DeviceId, data.CDevicePort.DeviceType, uidsMap)
}
return data
}
func converSignalUid(data *proto.Signal, uidsMap *stationUidStructure) *proto.Signal {
data.Id = uidsMap.SignalIds[data.Id].Uid
if data.SectionId != "" {
data.SectionId = converRefUid(data.SectionId, proto.DeviceType_DeviceType_PhysicalSection, uidsMap)
}
if data.TurnoutPort != nil {
data.TurnoutPort.DeviceId = converRefUid(data.TurnoutPort.DeviceId, data.TurnoutPort.DeviceType, uidsMap)
}
return data
}
func converTransponderUid(data *proto.Transponder, uidsMap *stationUidStructure) *proto.Transponder {
data.Id = uidsMap.TransponderIds[data.Id].Uid
if data.SectionId != "" {
data.SectionId = converRefUid(data.SectionId, proto.DeviceType_DeviceType_PhysicalSection, uidsMap)
}
if data.TurnoutPort != nil {
data.TurnoutPort.DeviceId = converRefUid(data.TurnoutPort.DeviceId, data.TurnoutPort.DeviceType, uidsMap)
}
return data
}
func converSlopeUid(data *proto.Slope, uidsMap *stationUidStructure) *proto.Slope {
data.Id = uidsMap.SlopeIds[data.Id].Uid
return data
}
func converCurvatureUid(data *proto.SectionalCurvature, uidsMap *stationUidStructure) *proto.SectionalCurvature {
data.Id = uidsMap.CurvatureIds[data.Id].Uid
return data
}
func converRefUid(id string, d proto.DeviceType, uidsMap *stationUidStructure) string {
var elementId *elementIdStructure
switch d {
case proto.DeviceType_DeviceType_CheckPoint:
elementId = uidsMap.AxlePointIds[id]
case proto.DeviceType_DeviceType_PhysicalSection:
elementId = uidsMap.PhysicalSectionIds[id]
case proto.DeviceType_DeviceType_SectionalCurvature:
elementId = uidsMap.CurvatureIds[id]
case proto.DeviceType_DeviceType_Signal:
elementId = uidsMap.SignalIds[id]
case proto.DeviceType_DeviceType_Slope:
elementId = uidsMap.SlopeIds[id]
case proto.DeviceType_DeviceType_Transponder:
elementId = uidsMap.TransponderIds[id]
case proto.DeviceType_DeviceType_Turnout:
elementId = uidsMap.TurnoutIds[id]
default:
panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "异常的设备类型-" + d.String()})
}
return elementId.Uid
}
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 initWorldDeviceState(status *VerifyStatus, repo *repository.Repository) {
initWorldTurnoutState(status, repo)
initWorldPhysicalSectionState(status, repo)
}
// 初始化道岔状态
func initWorldTurnoutState(status *VerifyStatus, repo *repository.Repository) {
for _, turnout := range repo.TurnoutList() {
id := turnout.Identity.Id()
status.SwitchStateMap.Store(id, &state.SwitchState{Id: id, Normal: true, Reverse: false})
}
}
// 初始化物理区段状态
func initWorldPhysicalSectionState(status *VerifyStatus, repo *repository.Repository) {
for _, section := range repo.PhysicalSectionList() {
id := section.Identity.Id()
status.PhysicalSectionStateMap.Store(id, &state.SectionState{Id: id, Occupied: false, Type: state.SectionType_Physic})
}
}