rts-sim-module/system/psd_system.go

331 lines
10 KiB
Go
Raw Normal View History

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
}