rts-sim-module/deprecated/system/psd_system.go
walker 0bba8f0934 删除donburi包引用
修改filter导入为从ecs项目导入
整理包结构,将弃用的包放入deprecated文件中
2023-10-09 11:17:25 +08:00

417 lines
13 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 system
import (
"joylink.club/ecs"
"joylink.club/ecs/filter"
sysEvent "joylink.club/rtsssimulation/deprecated/system/event"
)
// PsdDriveXGMJ 联锁驱动XGMJ
func PsdDriveXGMJ(w ecs.World, psdCircuitId string, lsDrive bool) bool {
psdEntry := FindEntityById(w, psdCircuitId)
if psdEntry == nil {
return false
}
psdState := PsdCircuitStateComponent.Get(psdEntry)
psdState.XGMLs = lsDrive
return true
}
// PsdDriveSGMJ 联锁驱动SGMJ
func PsdDriveSGMJ(w ecs.World, psdCircuitId string, lsDrive bool) bool {
psdEntry := FindEntityById(w, psdCircuitId)
if psdEntry == nil {
return false
}
psdState := PsdCircuitStateComponent.Get(psdEntry)
psdState.SGMLs = lsDrive
return true
}
// PsdDrive4XKMJ 联锁驱动4XKMJ
func PsdDrive4XKMJ(w ecs.World, psdCircuitId string, lsDrive bool) bool {
psdEntry := FindEntityById(w, psdCircuitId)
if psdEntry == nil {
return false
}
psdState := PsdCircuitStateComponent.Get(psdEntry)
psdState.G4XKMLs = lsDrive
return true
}
// PsdDrive4SKMJ 联锁驱动4SKMJ
func PsdDrive4SKMJ(w ecs.World, psdCircuitId string, lsDrive bool) bool {
psdEntry := FindEntityById(w, psdCircuitId)
if psdEntry == nil {
return false
}
psdState := PsdCircuitStateComponent.Get(psdEntry)
psdState.G4SKMLs = lsDrive
return true
}
// PsdDrive8XKMJ 联锁驱动8XKMJ
func PsdDrive8XKMJ(w ecs.World, psdCircuitId string, lsDrive bool) bool {
psdEntry := FindEntityById(w, psdCircuitId)
if psdEntry == nil {
return false
}
psdState := PsdCircuitStateComponent.Get(psdEntry)
psdState.G8XKMLs = lsDrive
return true
}
// PsdDrive8SKMJ 联锁驱动8SKMJ
func PsdDrive8SKMJ(w ecs.World, psdCircuitId string, lsDrive bool) bool {
psdEntry := FindEntityById(w, psdCircuitId)
if psdEntry == nil {
return false
}
psdState := PsdCircuitStateComponent.Get(psdEntry)
psdState.G8SKMLs = lsDrive
return true
}
//////////////////////////////////////////////////////////////
// PsdCircuitState 站台门控制电路状态Psd为车站所有屏蔽门子门的集合
// 旁路继电器的工作原理是,当电路中的电流超过预定的阈值时,旁路继电器会自动断开电路,从而防止电路发生短路或过载等故障。
type PsdCircuitState struct {
//关门继电器,true-吸合
XGMJ bool
//true-联锁驱动
XGMLs bool
//4编组开门继电器,true-吸合
G4XKMJ bool
//true-联锁驱动
G4XKMLs bool
//8编组开门继电器,true-吸合
G8XKMJ bool
//true-联锁驱动
G8XKMLs bool
//门关闭继电器,true-吸合
XMGJ bool
//门旁路继电器,true-吸合
XMPLJ bool
//车站下行侧屏蔽门开门码
XOpenCode OpenCode
//关门继电器,true-吸合
SGMJ bool
//true-联锁驱动
SGMLs bool
//4编组开门继电器,true-吸合
G4SKMJ bool
//true-联锁驱动
G4SKMLs bool
//8编组开门继电器,true-吸合
G8SKMJ bool
//true-联锁驱动
G8SKMLs bool
//门关闭继电器,true-吸合
SMGJ bool
//门旁路继电器,true-吸合
SMPLJ bool
//车站上行侧屏蔽门开门码
SOpenCode OpenCode
}
// PsdCellState 车站屏蔽门子门
type PsdCellState struct {
//屏蔽门打开的百分比则0-完全关闭100-完全打开
Rate int8
//关门操作被激活
actClosing bool
//开门操作被激活
actOpening bool
}
// PsdTags 屏蔽门标签
type PsdTags struct {
STag EntityTag //上行侧屏蔽门子门标签
S4KmUpTag EntityTag //上行侧4编组运行方向上行时屏蔽门子门标签
S4KmDownTag EntityTag //上行侧4编组运行方向下行时屏蔽门子门标签
S8KmUpTag EntityTag //上行侧8编组运行方向上行时屏蔽门子门标签
S8KmDownTag EntityTag //上行侧8编组运行方向下行时屏蔽门子门标签
XTag EntityTag
X4KmUpTag EntityTag
X4KmDownTag EntityTag
X8KmUpTag EntityTag
X8KmDownTag EntityTag
queryMap map[EntityTag]*ecs.Query
}
// 屏蔽门子门查询
func (me *PsdTags) psdCellsQuery(tag EntityTag) *ecs.Query {
if query, ok := me.queryMap[tag]; !ok {
query = ecs.NewQuery(filter.Contains(tag))
me.queryMap[tag] = query
}
return me.queryMap[tag]
}
// PsdsCircuitSystem 站台门电路系统
type PsdsCircuitSystem struct {
}
func NewPsdsCircuitSystem() *PsdsCircuitSystem {
return &PsdsCircuitSystem{}
}
func NewPsdTags() *PsdTags {
return &PsdTags{S4KmUpTag: NewTag(), S8KmDownTag: NewTag(), S4KmDownTag: NewTag(), S8KmUpTag: NewTag(), STag: NewTag(),
XTag: NewTag(), X4KmDownTag: NewTag(), X4KmUpTag: NewTag(), X8KmDownTag: NewTag(), X8KmUpTag: NewTag(),
queryMap: make(map[EntityTag]*ecs.Query, 10)}
}
func NewPsdCellState() *PsdCellState {
return &PsdCellState{}
}
func NewPsdCircuitState() *PsdCircuitState {
return &PsdCircuitState{XMGJ: true, SMGJ: true, XMPLJ: false, XGMJ: false, XOpenCode: OpenCodeNon, G8SKMJ: false,
G4SKMJ: false, G4XKMJ: false, G8XKMJ: false, SGMJ: false, SMPLJ: false, SOpenCode: OpenCodeNon}
}
var (
PsdCircuitStateComponent = ecs.NewComponentType[PsdCircuitState]()
PsdCellStateComponent = ecs.NewComponentType[PsdCellState]()
PsdTagsComponent = ecs.NewComponentType[PsdTags]()
psdCircuitQuery = ecs.NewQuery(filter.Contains(PsdCircuitStateComponent))
psdCellQuery = ecs.NewQuery(filter.Contains(PsdCellStateComponent))
)
// OpenCode 开门码
type OpenCode int8
// 开门码枚举
const (
OpenCodeNon OpenCode = iota //无效开门码
OpenCodeUp //运行方向为上行的开门码
OpenCodeDown //运行方向为下行的开门码
)
const (
PsdCellRateClosed int8 = 0
PsdCellRateOpened int8 = 100
)
// PSD组合类型和继电器功能名称
const (
PSD_GT = "PSD"
PSD_XGMJ = "XGMJ"
PSD_4XKMJ = "4XKMJ"
PSD_8XKMJ = "8XKMJ"
PSD_XMGJ = "XMGJ"
PSD_XMPLJ = "XMPLJ"
PSD_SGMJ = "SGMJ"
PSD_4SKMJ = "4SKMJ"
PSD_8SKMJ = "8SKMJ"
PSD_SMGJ = "SMGJ"
PSD_SMPLJ = "SMPLJ"
)
// Update world 执行
func (me *PsdsCircuitSystem) Update(w ecs.World) {
//
psdCircuitQuery.Each(w, func(psdCircuitEntry *ecs.Entry) {
me.calculateMG(w, psdCircuitEntry)
me.calculateGM(w, psdCircuitEntry)
me.calculate4KM(w, psdCircuitEntry)
me.calculate8KM(w, psdCircuitEntry)
me.calculateCellAct(w, psdCircuitEntry)
me.calculateCellMove(w, psdCircuitEntry)
})
}
// 屏蔽门子门移动运算,暂定门从全关到全开耗时2000ms,则v=50/ms
func (me *PsdsCircuitSystem) calculateCellMove(w ecs.World, psdCircuitEntry *ecs.Entry) {
psdTags := PsdTagsComponent.Get(psdCircuitEntry)
psdTags.psdCellsQuery(psdTags.XTag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellMove := PercentageDeviceStateComponent.Get(cellEntry)
if cellState.actClosing {
cellMove.V = -50
}
if cellState.actOpening {
cellMove.V = 50
}
cellState.Rate = cellMove.GetRate()
})
psdTags.psdCellsQuery(psdTags.STag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellMove := PercentageDeviceStateComponent.Get(cellEntry)
if cellState.actClosing {
cellMove.V = -50
}
if cellState.actOpening {
cellMove.V = 50
}
cellState.Rate = cellMove.GetRate()
})
}
// 屏蔽门子门移动运算,暂定门从全关到全开耗时2000ms,则v=50/ms
func (me *PsdsCircuitSystem) calculateCellAct(w ecs.World, psdCircuitEntry *ecs.Entry) {
state := PsdCircuitStateComponent.Get(psdCircuitEntry)
psdTags := PsdTagsComponent.Get(psdCircuitEntry)
//关门
if state.XGMJ {
psdTags.psdCellsQuery(psdTags.XTag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellState.actClosing = true
cellState.actOpening = false
})
}
if state.SGMJ {
psdTags.psdCellsQuery(psdTags.STag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellState.actClosing = true
cellState.actOpening = false
})
}
//开门
if state.G4XKMJ {
var cellTag EntityTag = nil
if state.XOpenCode == OpenCodeUp {
cellTag = psdTags.X4KmUpTag
} else if state.XOpenCode == OpenCodeDown {
cellTag = psdTags.X4KmDownTag
}
if cellTag != nil {
psdTags.psdCellsQuery(cellTag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellState.actClosing = false
cellState.actOpening = true
})
}
}
if state.G4SKMJ {
var cellTag EntityTag = nil
if state.SOpenCode == OpenCodeUp {
cellTag = psdTags.S4KmUpTag
} else if state.SOpenCode == OpenCodeDown {
cellTag = psdTags.S4KmDownTag
}
if cellTag != nil {
psdTags.psdCellsQuery(cellTag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellState.actClosing = false
cellState.actOpening = true
})
}
}
if state.G8XKMJ {
var cellTag EntityTag = nil
if state.XOpenCode == OpenCodeUp {
cellTag = psdTags.X8KmUpTag
} else if state.XOpenCode == OpenCodeDown {
cellTag = psdTags.X8KmDownTag
}
if cellTag != nil {
psdTags.psdCellsQuery(cellTag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellState.actClosing = false
cellState.actOpening = true
})
}
}
if state.G8SKMJ {
var cellTag EntityTag = nil
if state.SOpenCode == OpenCodeUp {
cellTag = psdTags.S8KmUpTag
} else if state.SOpenCode == OpenCodeDown {
cellTag = psdTags.S8KmDownTag
}
if cellTag != nil {
psdTags.psdCellsQuery(cellTag).Each(w, func(cellEntry *ecs.Entry) {
cellState := PsdCellStateComponent.Get(cellEntry)
cellState.actClosing = false
cellState.actOpening = true
})
}
}
}
func (me *PsdsCircuitSystem) calculateMG(w ecs.World, psdCircuitEntry *ecs.Entry) {
state := PsdCircuitStateComponent.Get(psdCircuitEntry)
psdTags := PsdTagsComponent.Get(psdCircuitEntry)
//
isXMG := true
psdTags.psdCellsQuery(psdTags.XTag).Each(w, func(cellEntry *ecs.Entry) {
if isXMG {
cellState := PsdCellStateComponent.Get(cellEntry)
if cellState.Rate > PsdCellRateClosed {
isXMG = false
}
}
})
if isXMG != state.XMGJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_XMGJ, isXMG); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
//
isSMG := true
psdTags.psdCellsQuery(psdTags.STag).Each(w, func(cellEntry *ecs.Entry) {
if isSMG {
cellState := PsdCellStateComponent.Get(cellEntry)
if cellState.Rate > PsdCellRateClosed {
isSMG = false
}
}
})
if isSMG != state.SMGJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_SMGJ, isSMG); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}
func (me *PsdsCircuitSystem) calculateGM(w ecs.World, psdCircuitEntry *ecs.Entry) {
state := PsdCircuitStateComponent.Get(psdCircuitEntry)
//关门继电器:联锁励磁||自闭保持
isXGM := state.XGMLs || state.XGMJ && !state.G4XKMJ && !state.G8XKMJ
isSGM := state.SGMLs || state.SGMJ && !state.G4SKMJ && !state.G8SKMJ
if isXGM != state.XGMJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_XGMJ, isXGM); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
if isSGM != state.SGMJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_SGMJ, isSGM); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}
func (me *PsdsCircuitSystem) calculate4KM(w ecs.World, psdCircuitEntry *ecs.Entry) {
//4编组开门继电器联锁励磁||自闭保持
state := PsdCircuitStateComponent.Get(psdCircuitEntry)
is4XKM := state.G4XKMLs || state.G4XKMJ && !state.G8XKMJ && !state.XGMJ
is4SKM := state.G4SKMLs || state.G4SKMJ && !state.G8SKMJ && !state.SGMJ
if is4XKM != state.G4XKMJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_4XKMJ, is4XKM); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
if is4SKM != state.G4SKMJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_4SKMJ, is4SKM); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}
func (me *PsdsCircuitSystem) calculate8KM(w ecs.World, psdCircuitEntry *ecs.Entry) {
//8编组开门继电器联锁励磁||自闭保持
state := PsdCircuitStateComponent.Get(psdCircuitEntry)
is8XKM := state.G8XKMLs || state.G8XKMJ && !state.G4XKMJ && !state.XGMJ
is8SKM := state.G8SKMLs || state.G8SKMJ && !state.G4SKMJ && !state.SGMJ
if is8XKM != state.G8XKMJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_8XKMJ, is8XKM); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
if is8SKM != state.G8SKMJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(psdCircuitEntry).Id, PSD_GT, PSD_8SKMJ, is8SKM); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}