【地图构建逻辑,计轴区段、物理区段状态构建】

This commit is contained in:
weizhihong 2023-08-03 09:23:46 +08:00
parent e0ed33e0c8
commit 21f4f81972
3 changed files with 255 additions and 30 deletions

View File

@ -9,11 +9,13 @@ import (
// 从地图数据构建仿真内存模型
func InitFromMap(status *VerifyStatus, mapInfo *VerifyStructure) {
initFromMapForTest(status, mapInfo)
initTurnoutState(status, mapInfo)
initAxleSectionState(status, mapInfo)
initPhysicalSectionState(status, mapInfo)
}
// 暂时测试用
func initFromMapForTest(status *VerifyStatus, mapInfo *VerifyStructure) {
// 初始化道岔状态
func initTurnoutState(status *VerifyStatus, mapInfo *VerifyStructure) {
for _, turnout := range mapInfo.SwitchDeviceModelMap {
status.SwitchStateMap.Store(turnout.GetIndex(), &state.SwitchState{
Id: turnout.GetIndex(),
@ -22,3 +24,25 @@ func initFromMapForTest(status *VerifyStatus, mapInfo *VerifyStructure) {
})
}
}
// 初始化区段状态
func initAxleSectionState(status *VerifyStatus, mapInfo *VerifyStructure) {
for _, axleSection := range mapInfo.AxleSectionModelMap {
status.AxleSectionStateMap.Store(axleSection.GetIndex(), &state.SectionState{
Id: axleSection.GetIndex(),
Occupied: false,
Type: state.SectionType_Axle,
})
}
}
// 初始化物理区段状态
func initPhysicalSectionState(status *VerifyStatus, mapInfo *VerifyStructure) {
for _, physicalSection := range mapInfo.PhysicalSectionModelMap {
status.PhysicalSectionStateMap.Store(physicalSection.GetIndex(), &state.SectionState{
Id: physicalSection.GetIndex(),
Occupied: false,
Type: state.SectionType_Physic,
})
}
}

View File

@ -1,6 +1,7 @@
package memory
import (
"container/list"
"fmt"
"strconv"
"sync"
@ -18,7 +19,7 @@ import (
// 仿真存储集合 ID
var graphicDataMap sync.Map
// 轨旁仿真模型结构
// 轨旁仿真模型结构,注意这里的key 为 Index
type VerifyStructure struct {
//计轴检测点设备模型集合,key为索引编号
AxlePointDeviceModelMap map[string]face.AxlePointDeviceModeller
@ -36,7 +37,7 @@ type VerifyStructure struct {
SignalDeviceModelMap map[string]face.SignalDeviceModeller
}
// 设备地图ID对应map结构体(建立关系时便于查找使用)
// 设备地图ID对应map结构体(建立关系时便于查找使用)注意这里的key 为 Common.Id
type GraphicInfoMapStructure struct {
AxlePointMap map[string]*graphicData.AxleCounting
TurnoutMap map[string]*graphicData.Turnout
@ -121,7 +122,9 @@ func initGraphicAxlePoints(axlePoints []*graphicData.AxleCounting, data *VerifyS
GraphicId: a.Common.Id,
Index: id,
},
KilometerSystem: *a.GetKilometerSystem(),
KilometerSystem: *a.GetKilometerSystem(),
SwitchDevices: make(map[string]*ref.SwitchRef),
AreaPhysicalSections: make(map[string]face.PhysicalSectionModeller),
}
}
}
@ -166,6 +169,8 @@ func initGraphicAxleSection(axleSections []*graphicData.AxleCountingSection, dat
GraphicId: s.Common.Id,
Index: id,
},
ViaSwitchPositions: list.New(),
ViaLinks: list.New(),
}
}
}
@ -180,7 +185,9 @@ func initGraphicPhysicalSections(physicalSections []*graphicData.Section, data *
GraphicId: s.Common.Id,
Index: id,
},
SwitchArea: len(s.AxleCountings) > 2,
SwitchArea: len(s.AxleCountings) > 2,
AxlePoints: make(map[string]face.AxlePointDeviceModeller),
AxleSections: make(map[string]face.AxleSectionModeller),
}
}
}
@ -218,16 +225,24 @@ func initGraphicSignal(signals []*graphicData.Signal, data *VerifyStructure, gra
func buildDeviceRef(graphicData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
// 构建link的关联关系
buildLinkDeviceRef(graphicData, verifyStructure)
// 道岔,分析轨道中轨道与道岔的关系来构建道岔与轨道的关系
buildTurnoutDeviceRef(verifyStructure)
// 计轴区段
buildAxleSectionDeviceRef(graphicData, verifyStructure)
// 物理区段
buildPhysicalSectionsDeviceRef(graphicData, verifyStructure)
// 逻辑区段
buildLogicSectionsDeviceRef(graphicData, verifyStructure)
// 计轴检测点-从计轴点角度(非岔区物理区段和道岔)
buildAxlePointDeviceRef(graphicData, verifyStructure)
// 计轴检测点-从物理区段角度
buildPhysicalAxlePointDeviceRef(verifyStructure)
}
// 构建link的关联关系
// 构建link的关联关系(端点间的轨道)
func buildLinkDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for _, v := range mapData.LinkMap {
lf := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(v.Index))]
if lf == nil { // 无对应ID
continue
}
link := lf.(*section.LinkSectionModel)
link := (verifyStructure.LinkSectionModelMap[strconv.Itoa(int(v.Index))]).(*section.LinkSectionModel)
// 轨道A端端点
linkSimRefBuildCommMethod(v.Common.Id, v.ASimRef, mapData, verifyStructure, func(f face.AxlePointDeviceModeller) {
link.AxlePointA = f
@ -240,20 +255,22 @@ func buildLinkDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *Verif
}, func(t *ref.SwitchRef) {
link.SwitchRefB = t
})
if v.ARef != nil {
if v.ARef.DeviceType == graphicData.RelatedRef_SectionLink {
d := mapData.LinkMap[v.ARef.Id]
if d != nil {
ls := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(d.Index))]
link.LinkRefA = &ref.LinkRef{
LinkSection: ls,
Port: face.PortEnum(v.ARef.DevicePort),
}
}
}
}
// A端点关联设备
linkRefBuildCommMethod(v, mapData, verifyStructure, func() *graphicData.RelatedRef {
return v.ARef
}, func(l *ref.LinkRef) {
link.LinkRefA = l
}, func(pe face.PortEnum) {
link.SwitchRefA.Port = pe
})
// B端点关联设备
linkRefBuildCommMethod(v, mapData, verifyStructure, func() *graphicData.RelatedRef {
return v.BRef
}, func(l *ref.LinkRef) {
link.LinkRefB = l
}, func(pe face.PortEnum) {
link.SwitchRefB.Port = pe
})
}
}
@ -264,17 +281,201 @@ func linkSimRefBuildCommMethod(linkGraphicId string, simRef *graphicData.SimpleR
axlePoint := mapData.AxlePointMap[simRef.Id]
if axlePoint != nil {
fp(verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axlePoint.Index))])
} else {
zap.S().Warnf("id为[%s]的轨道的计轴端点[%s]不存在", linkGraphicId, simRef.Id)
}
case graphicData.SimpleRef_Turnout:
turnout := mapData.TurnoutMap[simRef.Id]
if turnout != nil {
ft(&ref.SwitchRef{SwitchDevice: verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]})
} else {
zap.S().Warnf("id为[%s]的轨道的道岔端点[%s]不存在", linkGraphicId, simRef.Id)
}
default:
zap.S().Warnf("link[%s]端点设备类型[%v]未关联", linkGraphicId, simRef.DeviceType)
}
}
func linkRefBuildCommMethod() {
func linkRefBuildCommMethod(v *graphicData.SectionLink, mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure,
gr func() *graphicData.RelatedRef, lr func(*ref.LinkRef), ft func(face.PortEnum)) {
r := gr()
if r != nil {
switch r.DeviceType {
case graphicData.RelatedRef_SectionLink:
d := mapData.LinkMap[r.Id]
if d != nil {
ls := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(d.Index))]
lr(&ref.LinkRef{LinkSection: ls, Port: face.PortEnum(r.DevicePort)})
} else {
zap.S().Warnf("id为[%s]的轨道的连接的轨道[%s]不存在", v.Common.Id, r.Id)
}
case graphicData.RelatedRef_Turnout:
t := mapData.TurnoutMap[r.Id]
if t != nil {
ft(face.PortEnum(v.ARef.DevicePort))
} else {
zap.S().Warnf("id为[%s]的轨道的连接的道岔[%s]不存在", v.Common.Id, r.Id)
}
default:
zap.S().Warnf("link[%s]端点设备类型[%v]未关联", v.Common.Id, r.DeviceType)
}
}
}
// 道岔,分析轨道中轨道与道岔的关系来构建道岔与轨道的关系
func buildTurnoutDeviceRef(verifyStructure *VerifyStructure) {
for _, v := range verifyStructure.LinkSectionModelMap {
s := v.(*section.LinkSectionModel)
buildTurnoutCommMethod(s, s.SwitchRefA, face.A)
buildTurnoutCommMethod(s, s.SwitchRefB, face.B)
}
}
func buildTurnoutCommMethod(s *section.LinkSectionModel, linkSwitch *ref.SwitchRef, p face.PortEnum) {
if linkSwitch != nil {
switchDevice := (linkSwitch.SwitchDevice).(*device.SwitchDeviceModel)
switch linkSwitch.Port {
case face.A:
switchDevice.LinkRefA = &ref.LinkRef{LinkSection: s, Port: p}
case face.B:
switchDevice.LinkRefB = &ref.LinkRef{LinkSection: s, Port: p}
case face.C:
switchDevice.LinkRefC = &ref.LinkRef{LinkSection: s, Port: p}
}
}
}
// 计轴区段
func buildAxleSectionDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for _, v := range mapData.AxleSectionMap {
axleSectionModel := (verifyStructure.AxleSectionModelMap[strconv.Itoa(int(v.Index))]).(*section.AxleSectionModel)
//计轴区段A端计轴检测点
axleCountingA := mapData.AxlePointMap[v.PaRef.Id]
if axleCountingA != nil {
axlePointDeviceModelA := verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axleCountingA.Index))]
axleSectionModel.AxlePointA = axlePointDeviceModelA
} else {
zap.S().Warnf("id为[%s]的计轴区段的A端关联的计轴点[%s]不存在", v.Common.Id, v.PaRef.Id)
}
//计轴区段B端计轴检测点
axleCountingB := mapData.AxlePointMap[v.PbRef.Id]
if axleCountingB != nil {
axlePointDeviceModelB := verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axleCountingB.Index))]
axleSectionModel.AxlePointB = axlePointDeviceModelB
} else {
zap.S().Warnf("id为[%s]的计轴区段的B端关联的计轴点[%s]不存在", v.Common.Id, v.PbRef.Id)
}
//如果该计轴区段在岔区,则描述在该计轴区段中的道岔的位置
vaildMap := make(map[string]int)
for _, turnoutPosRef := range v.TurnoutPos {
turnout := mapData.TurnoutMap[turnoutPosRef.Id]
if turnout != nil {
switchDeviceModel := (verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]).(*device.SwitchDeviceModel)
positionRef := &ref.SwitchPositionRef{SwitchDevice: switchDeviceModel, Normal: 0 == turnoutPosRef.Position}
// 校验道岔设备只能添加一次 todo
if vaildMap[switchDeviceModel.Index] == 0 {
vaildMap[switchDeviceModel.Index] = 1
} else {
zap.S().Warnf("id为[%s]的计轴区段经过的道岔[%s]的次数大于1", v.Common.Id, turnoutPosRef.Id)
}
axleSectionModel.ViaSwitchPositions.PushBack(positionRef)
} else {
zap.S().Warnf("id为[%s]的计轴区段经过的道岔[%s]不存在", v.Common.Id, turnoutPosRef.Id)
}
}
}
}
// 物理区段
func buildPhysicalSectionsDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for id, physicalSection := range mapData.PhysicalSectionMap {
physicalSectionModel := (verifyStructure.PhysicalSectionModelMap[strconv.Itoa(int(physicalSection.Index))]).(*section.PhysicalSectionModel)
for _, axlePointId := range physicalSection.AxleCountings {
axlePoint := mapData.AxlePointMap[axlePointId]
if axlePoint != nil {
axlePointDevice := (verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axlePoint.Index))]).(*device.AxlePointDeviceModel)
physicalSectionModel.AxlePoints[axlePointDevice.Index] = axlePointDevice
} else {
zap.S().Warnf("id为[%s]的物理区段的关联计轴点[%s]不存在", id, axlePointId)
}
}
pl := len(physicalSectionModel.AxlePoints)
if physicalSectionModel.SwitchArea {
if pl <= 2 {
zap.S().Warnf("id为[%s]的岔区物理区段的计轴检测点数量为[%d]", id, pl)
}
} else {
if pl != 2 {
zap.S().Warnf("id为[%s]的非岔区物理区段的计轴检测点数量为[%d]", id, pl)
}
}
}
}
// 逻辑区段
func buildLogicSectionsDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for id, logicSection := range mapData.LogicSectionMap {
logicalSectionModel := (verifyStructure.LogicalSectionModelMap[strconv.Itoa(int(logicSection.Index))]).(*section.LogicalSectionModel)
axleCountingSection := mapData.AxleSectionMap[logicSection.AxleSectionId]
if axleCountingSection == nil {
zap.S().Warnf("id为[%s]的逻辑区段所在的计轴区段[%s]不存在", id, logicSection.AxleSectionId)
}
axleSectionModel := (verifyStructure.AxleSectionModelMap[strconv.Itoa(int(axleCountingSection.Index))]).(*section.AxleSectionModel)
logicalSectionModel.AxleSection = axleSectionModel
if logicSection.TurnoutId != "" {
turnout := mapData.TurnoutMap[logicSection.TurnoutId]
if turnout != nil {
logicalSectionModel.SwitchDevice = verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]
} else {
zap.S().Warnf("id为[%s]的逻辑区段所在的道岔[%s]不存在", id, logicSection.TurnoutId)
}
}
}
}
// 计轴检测点-从计轴点角度(非岔区物理区段和道岔)
func buildAxlePointDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for id, axlePoint := range mapData.AxlePointMap {
axlePointDeviceModel := (verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axlePoint.Index))]).(*device.AxlePointDeviceModel)
for _, relatedRef := range axlePoint.AxleCountingRef {
switch relatedRef.DeviceType {
case graphicData.RelatedRef_Turnout:
turnout := mapData.TurnoutMap[relatedRef.Id]
if turnout == nil {
zap.S().Warnf("id为[%s]的计轴检测点关联的道岔[%s]不存在", id, relatedRef.Id)
}
switchDeviceModel := (verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]).(*device.SwitchDeviceModel)
axlePointDeviceModel.SwitchDevices[switchDeviceModel.Index] = &ref.SwitchRef{
SwitchDevice: switchDeviceModel,
Port: face.PortEnum(relatedRef.DevicePort),
}
case graphicData.RelatedRef_Section:
s := mapData.PhysicalSectionMap[relatedRef.Id]
if s == nil {
zap.S().Warnf("id为[%s]的计轴检测点关联的物理区段[%s]不存在", id, relatedRef.Id)
}
physicalSectionModel := (verifyStructure.PhysicalSectionModelMap[strconv.Itoa(int(s.Index))]).(*section.PhysicalSectionModel)
if physicalSectionModel.SwitchArea {
zap.S().Warnf("id为[%s]的计轴检测点proto数据关联岔区物理区段[%s]不存在", id, relatedRef.Id)
}
switch relatedRef.DevicePort {
case graphicData.RelatedRef_A:
axlePointDeviceModel.LinePhysicalSectionA = physicalSectionModel
case graphicData.RelatedRef_B:
axlePointDeviceModel.LinePhysicalSectionB = physicalSectionModel
}
}
}
}
}
// 计轴检测点-从物理区段角度
func buildPhysicalAxlePointDeviceRef(verifyStructure *VerifyStructure) {
for _, v := range verifyStructure.PhysicalSectionModelMap {
physicalSection := v.(*section.PhysicalSectionModel)
for _, a := range physicalSection.AxlePoints {
axlePointDeviceModel := a.(*device.AxlePointDeviceModel)
axlePointDeviceModel.AreaPhysicalSections[physicalSection.Index] = physicalSection
}
}
}

View File

@ -17,7 +17,7 @@ func (t *SimulationServer) getChannelName() string {
// 消息运行间隔
func (t *SimulationServer) getInterval() time.Duration {
return time.Second
return 200 * time.Millisecond
}
// 返回所有数据