2023-09-20 18:07:47 +08:00
|
|
|
|
package system
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/yohamta/donburi/filter"
|
|
|
|
|
"joylink.club/ecs"
|
|
|
|
|
)
|
|
|
|
|
|
2023-09-22 14:39:36 +08:00
|
|
|
|
// PsdCircuitState 站台门控制电路状态,Psd为车站所有屏蔽门子门的集合
|
2023-09-20 18:07:47 +08:00
|
|
|
|
// 旁路继电器的工作原理是,当电路中的电流超过预定的阈值时,旁路继电器会自动断开电路,从而防止电路发生短路或过载等故障。
|
2023-09-22 14:39:36 +08:00
|
|
|
|
type PsdCircuitState struct {
|
2023-09-20 18:07:47 +08:00
|
|
|
|
//关门继电器,true-吸合
|
|
|
|
|
XGMJ bool
|
|
|
|
|
//4编组开门继电器,true-吸合
|
|
|
|
|
G4XKMJ bool
|
|
|
|
|
//8编组开门继电器,true-吸合
|
|
|
|
|
G8XKMJ bool
|
|
|
|
|
//门关闭继电器,true-吸合
|
|
|
|
|
XMGJ bool
|
|
|
|
|
//门旁路继电器,true-吸合
|
|
|
|
|
XMPLJ bool
|
2023-09-22 14:39:36 +08:00
|
|
|
|
//车站下行侧屏蔽门开门码
|
|
|
|
|
XOpenCode OpenCode
|
2023-09-20 18:07:47 +08:00
|
|
|
|
//关门继电器,true-吸合
|
|
|
|
|
SGMJ bool
|
|
|
|
|
//4编组开门继电器,true-吸合
|
|
|
|
|
G4SKMJ bool
|
|
|
|
|
//8编组开门继电器,true-吸合
|
|
|
|
|
G8SKMJ bool
|
|
|
|
|
//门关闭继电器,true-吸合
|
|
|
|
|
SMGJ bool
|
|
|
|
|
//门旁路继电器,true-吸合
|
|
|
|
|
SMPLJ bool
|
2023-09-22 14:39:36 +08:00
|
|
|
|
//车站上行侧屏蔽门开门码
|
|
|
|
|
SOpenCode OpenCode
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 14:39:36 +08:00
|
|
|
|
// PsdCellState 车站屏蔽门子门
|
|
|
|
|
type PsdCellState struct {
|
2023-09-20 18:07:47 +08:00
|
|
|
|
//屏蔽门打开的百分比,则0-完全关闭,100-完全打开
|
2023-09-22 16:42:39 +08:00
|
|
|
|
Rate int8
|
2023-09-21 09:46:20 +08:00
|
|
|
|
//关门操作被激活
|
|
|
|
|
actClosing bool
|
|
|
|
|
//开门操作被激活
|
|
|
|
|
actOpening bool
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 14:39:36 +08:00
|
|
|
|
// 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
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 16:42:39 +08:00
|
|
|
|
// 屏蔽门子门查询
|
|
|
|
|
func (me *PsdTags) psdCellsQuery(tag EntityTag) *ecs.Query {
|
2023-09-22 14:39:36 +08:00
|
|
|
|
if query, ok := me.queryMap[tag]; !ok {
|
|
|
|
|
query = ecs.NewQuery(filter.Contains(tag))
|
|
|
|
|
me.queryMap[tag] = query
|
|
|
|
|
}
|
|
|
|
|
return me.queryMap[tag]
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 14:39:36 +08:00
|
|
|
|
// PsdsCircuitSystem 站台门电路系统
|
|
|
|
|
type PsdsCircuitSystem struct {
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
2023-09-22 14:39:36 +08:00
|
|
|
|
|
|
|
|
|
func NewPsdsCircuitSystem() *PsdsCircuitSystem {
|
|
|
|
|
return &PsdsCircuitSystem{}
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
2023-09-22 14:39:36 +08:00
|
|
|
|
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)}
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
2023-09-22 14:39:36 +08:00
|
|
|
|
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}
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 14:39:36 +08:00
|
|
|
|
var (
|
|
|
|
|
PsdCircuitStateComponent = ecs.NewComponentType[PsdCircuitState]()
|
|
|
|
|
PsdCellStateComponent = ecs.NewComponentType[PsdCellState]()
|
|
|
|
|
PsdTagsComponent = ecs.NewComponentType[PsdTags]()
|
2023-09-22 16:42:39 +08:00
|
|
|
|
psdCircuitQuery = ecs.NewQuery(filter.Contains(PsdCircuitStateComponent))
|
|
|
|
|
psdCellQuery = ecs.NewQuery(filter.Contains(PsdCellStateComponent))
|
2023-09-20 18:07:47 +08:00
|
|
|
|
)
|
2023-09-22 14:39:36 +08:00
|
|
|
|
|
|
|
|
|
// OpenCode 开门码
|
|
|
|
|
type OpenCode int8
|
|
|
|
|
|
|
|
|
|
// 开门码枚举
|
2023-09-20 18:07:47 +08:00
|
|
|
|
const (
|
2023-09-22 17:50:25 +08:00
|
|
|
|
OpenCodeNon OpenCode = iota //无效开门码
|
|
|
|
|
OpenCodeUp //运行方向为上行的开门码
|
|
|
|
|
OpenCodeDown //运行方向为下行的开门码
|
2023-09-20 18:07:47 +08:00
|
|
|
|
)
|
2023-09-22 16:42:39 +08:00
|
|
|
|
const (
|
|
|
|
|
PsdCellRateClosed int8 = 0
|
|
|
|
|
PsdCellRateOpened int8 = 100
|
|
|
|
|
)
|
2023-09-20 18:07:47 +08:00
|
|
|
|
|
|
|
|
|
// 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 执行
|
2023-09-22 14:39:36 +08:00
|
|
|
|
func (me *PsdsCircuitSystem) Update(w ecs.World) {
|
2023-09-22 17:01:02 +08:00
|
|
|
|
//
|
|
|
|
|
psdCellQuery.Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
me.calculateCellMove(w, cellEntry)
|
|
|
|
|
})
|
2023-09-22 16:42:39 +08:00
|
|
|
|
//
|
|
|
|
|
psdCircuitQuery.Each(w, func(psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
me.calculateSMG(w, psdCircuitEntry)
|
|
|
|
|
me.calculateXMG(w, psdCircuitEntry)
|
|
|
|
|
me.calculateSGM(w, psdCircuitEntry)
|
|
|
|
|
me.calculateXGM(w, psdCircuitEntry)
|
|
|
|
|
me.calculate4SKM(w, psdCircuitEntry)
|
|
|
|
|
me.calculate4XKM(w, psdCircuitEntry)
|
|
|
|
|
me.calculate8SKM(w, psdCircuitEntry)
|
|
|
|
|
me.calculate8XKM(w, psdCircuitEntry)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 屏蔽门子门移动运算,暂定门从全关到全开耗时2000ms,则v=50/ms
|
2023-09-22 17:01:02 +08:00
|
|
|
|
func (me *PsdsCircuitSystem) calculateCellMove(w ecs.World, cellEntry *ecs.Entry) {
|
|
|
|
|
move := PercentageDeviceStateComponent.Get(cellEntry)
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.Rate = move.GetRate()
|
|
|
|
|
if cell.actOpening {
|
|
|
|
|
move.V = 50
|
|
|
|
|
if cell.Rate >= PsdCellRateOpened { //开门到位
|
|
|
|
|
move.V = 0
|
2023-09-22 16:42:39 +08:00
|
|
|
|
}
|
2023-09-22 17:01:02 +08:00
|
|
|
|
}
|
|
|
|
|
if cell.actClosing {
|
|
|
|
|
move.V = -50
|
|
|
|
|
if cell.Rate <= PsdCellRateClosed { //关门到位
|
2023-09-22 16:42:39 +08:00
|
|
|
|
move.V = 0
|
|
|
|
|
}
|
2023-09-22 17:01:02 +08:00
|
|
|
|
}
|
|
|
|
|
if !cell.actOpening && !cell.actClosing {
|
|
|
|
|
move.V = 0
|
|
|
|
|
}
|
2023-09-22 16:42:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 17:50:25 +08:00
|
|
|
|
// 车站屏蔽门电路系统继电器励磁运算 ????????-----信息缺失
|
|
|
|
|
func (me *PsdsCircuitSystem) calculateRelayLc(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
//psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 16:42:39 +08:00
|
|
|
|
// 车站上行侧所有屏蔽门子门关运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculateSMG(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
isSMG := true
|
|
|
|
|
tags.psdCellsQuery(tags.STag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
if isSMG {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
isSMG = cell.Rate <= PsdCellRateClosed
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
PsdCircuitStateComponent.Get(psdCircuitEntry).SMGJ = isSMG
|
|
|
|
|
}
|
2023-09-21 09:46:20 +08:00
|
|
|
|
|
2023-09-22 16:42:39 +08:00
|
|
|
|
// 车站下行侧所有屏蔽门子门关运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculateXMG(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
isXMG := true
|
|
|
|
|
tags.psdCellsQuery(tags.XTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
if isXMG {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
isXMG = cell.Rate <= PsdCellRateClosed
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
PsdCircuitStateComponent.Get(psdCircuitEntry).XMGJ = isXMG
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 车站上行侧关门操作运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculateSGM(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
if psd.SGMJ && !psd.G4SKMJ && !psd.G8SKMJ {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
tags.psdCellsQuery(tags.STag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = cell.Rate > PsdCellRateClosed
|
|
|
|
|
cell.actOpening = false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 车站下行侧关门操作运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculateXGM(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
if psd.XGMJ && !psd.G4XKMJ && !psd.G8XKMJ {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
tags.psdCellsQuery(tags.XTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = cell.Rate > PsdCellRateClosed
|
|
|
|
|
cell.actOpening = false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 车站上行侧4编组开门操作运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculate4SKM(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
if psd.G4SKMJ && !psd.G8SKMJ && !psd.SGMJ && psd.SOpenCode != OpenCodeNon {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
switch {
|
|
|
|
|
case psd.SOpenCode == OpenCodeUp:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.S4KmUpTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
case psd.SOpenCode == OpenCodeDown:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.S4KmDownTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 车站下行侧4编组开门操作运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculate4XKM(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
if psd.G4XKMJ && !psd.G8XKMJ && !psd.XGMJ && psd.XOpenCode != OpenCodeNon {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
switch {
|
|
|
|
|
case psd.XOpenCode == OpenCodeUp:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.X4KmUpTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
case psd.XOpenCode == OpenCodeDown:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.X4KmDownTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 车站上行侧8编组开门操作运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculate8SKM(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
if !psd.G4SKMJ && psd.G8SKMJ && !psd.SGMJ && psd.SOpenCode != OpenCodeNon {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
switch {
|
|
|
|
|
case psd.SOpenCode == OpenCodeUp:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.S8KmUpTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
case psd.SOpenCode == OpenCodeDown:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.S8KmDownTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 车站下行侧8编组开门操作运算
|
|
|
|
|
func (me *PsdsCircuitSystem) calculate8XKM(w ecs.World, psdCircuitEntry *ecs.Entry) {
|
|
|
|
|
psd := PsdCircuitStateComponent.Get(psdCircuitEntry)
|
|
|
|
|
if !psd.G4XKMJ && psd.G8XKMJ && !psd.XGMJ && psd.XOpenCode != OpenCodeNon {
|
|
|
|
|
tags := PsdTagsComponent.Get(psdCircuitEntry)
|
|
|
|
|
switch {
|
|
|
|
|
case psd.XOpenCode == OpenCodeUp:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.X8KmUpTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
case psd.XOpenCode == OpenCodeDown:
|
|
|
|
|
{
|
|
|
|
|
tags.psdCellsQuery(tags.X8KmDownTag).Each(w, func(cellEntry *ecs.Entry) {
|
|
|
|
|
cell := PsdCellStateComponent.Get(cellEntry)
|
|
|
|
|
cell.actClosing = false
|
|
|
|
|
cell.actOpening = cell.Rate < PsdCellRateOpened
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-20 18:07:47 +08:00
|
|
|
|
}
|