210 lines
5.7 KiB
Go
210 lines
5.7 KiB
Go
package system
|
||
|
||
import (
|
||
"github.com/yohamta/donburi/filter"
|
||
"joylink.club/ecs"
|
||
sysEvent "joylink.club/rtsssimulation/system/event"
|
||
)
|
||
|
||
// StationPsdsCircuitState 站台门控制电路状态
|
||
// 旁路继电器的工作原理是,当电路中的电流超过预定的阈值时,旁路继电器会自动断开电路,从而防止电路发生短路或过载等故障。
|
||
type StationPsdsCircuitState struct {
|
||
//关门继电器,true-吸合
|
||
XGMJ bool
|
||
//4编组开门继电器,true-吸合
|
||
G4XKMJ bool
|
||
//8编组开门继电器,true-吸合
|
||
G8XKMJ bool
|
||
//门关闭继电器,true-吸合
|
||
XMGJ bool
|
||
//门旁路继电器,true-吸合
|
||
XMPLJ bool
|
||
//关门继电器,true-吸合
|
||
SGMJ bool
|
||
//4编组开门继电器,true-吸合
|
||
G4SKMJ bool
|
||
//8编组开门继电器,true-吸合
|
||
G8SKMJ bool
|
||
//门关闭继电器,true-吸合
|
||
SMGJ bool
|
||
//门旁路继电器,true-吸合
|
||
SMPLJ bool
|
||
}
|
||
|
||
// PsdState 站台一侧屏蔽门由多个Psd构成
|
||
type PsdState struct {
|
||
//屏蔽门打开的百分比,则0-完全关闭,100-完全打开
|
||
Rate int
|
||
//关门操作被激活
|
||
actClosing bool
|
||
//开门操作被激活
|
||
actOpening bool
|
||
}
|
||
|
||
// PsdTagHandler 屏蔽门标签,用于ecs query
|
||
type PsdTagHandler struct {
|
||
//上行标签
|
||
STag EntityTag
|
||
//上行4编组标签
|
||
S4Tag EntityTag
|
||
//上行8编组标签
|
||
S8Tag EntityTag
|
||
//下行标签
|
||
XTag EntityTag
|
||
//下行4编组标签
|
||
X4Tag EntityTag
|
||
//下行8编组标签
|
||
X8Tag EntityTag
|
||
}
|
||
|
||
// StationPsdsCircuitSystem 站台门电路系统
|
||
type StationPsdsCircuitSystem struct {
|
||
}
|
||
|
||
func NewStationPsdsCircuitSystem() *StationPsdsCircuitSystem {
|
||
return &StationPsdsCircuitSystem{}
|
||
}
|
||
func NewPsdTagHandler() *PsdTagHandler {
|
||
return &PsdTagHandler{STag: NewTag(), S4Tag: NewTag(), S8Tag: NewTag(), XTag: NewTag(), X4Tag: NewTag(), X8Tag: NewTag()}
|
||
}
|
||
func NewStationPsdsCircuitState() *StationPsdsCircuitState {
|
||
return &StationPsdsCircuitState{}
|
||
}
|
||
func NewPsdState() *PsdState {
|
||
return &PsdState{Rate: PSD_CLOSED_RATE}
|
||
}
|
||
|
||
var StationPsdsCircuitStateComponent = ecs.NewComponentType[StationPsdsCircuitState]()
|
||
var PsdTagHandlerComponent = ecs.NewComponentType[PsdTagHandler]()
|
||
var PsdStateComponent = ecs.NewComponentType[PsdState]()
|
||
var psdsQuery = ecs.NewQuery(filter.Contains(PsdStateComponent, MovableObjectComponent))
|
||
var psdsCircuitQuery = ecs.NewQuery(filter.Contains(StationPsdsCircuitStateComponent))
|
||
|
||
// PSD
|
||
const (
|
||
PSD_CLOSED int64 = 0 //psd 完全关闭
|
||
PSD_OPENED int64 = 2000 //psd 完全打开
|
||
)
|
||
const (
|
||
PSD_CLOSED_RATE = 0
|
||
PSD_OPENED_RATE = 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 *StationPsdsCircuitSystem) Update(w ecs.World) {
|
||
me.psdUpdate(w)
|
||
me.circuitUpdate(w)
|
||
}
|
||
|
||
// 车站上下行屏蔽门电路运算
|
||
func (me *StationPsdsCircuitSystem) circuitUpdate(w ecs.World) {
|
||
psdsCircuitQuery.Each(w, func(e *ecs.Entry) {
|
||
me.calculateMG(w, e)
|
||
me.calculateActGM(w, e)
|
||
})
|
||
}
|
||
|
||
// 关门动作运算
|
||
func (me *StationPsdsCircuitSystem) calculateActGM(w ecs.World, circuitEntry *ecs.Entry) {
|
||
circuit := StationPsdsCircuitStateComponent.Get(circuitEntry)
|
||
tags := PsdTagHandlerComponent.Get(circuitEntry)
|
||
//上行
|
||
isActSGm := circuit.SGMJ && !circuit.G4SKMJ && !circuit.G8SKMJ
|
||
sQuery := ecs.NewQuery(filter.Contains(tags.STag))
|
||
sQuery.Each(w, func(sPsd *ecs.Entry) {
|
||
sPsdState := PsdStateComponent.Get(sPsd)
|
||
sPsdState.actClosing = isActSGm
|
||
})
|
||
//下行
|
||
isActXGm := circuit.XGMJ && !circuit.G4XKMJ && !circuit.G8XKMJ
|
||
xQuery := ecs.NewQuery(filter.Contains(tags.XTag))
|
||
xQuery.Each(w, func(xPsd *ecs.Entry) {
|
||
xPsdState := PsdStateComponent.Get(xPsd)
|
||
xPsdState.actClosing = isActXGm
|
||
})
|
||
}
|
||
|
||
// 4编组开门动作运算
|
||
func (me *StationPsdsCircuitSystem) calculateAct4KM(w ecs.World, circuitEntry *ecs.Entry) {
|
||
|
||
}
|
||
|
||
// 门关状态运算
|
||
func (me *StationPsdsCircuitSystem) calculateMG(w ecs.World, circuitEntry *ecs.Entry) {
|
||
tags := PsdTagHandlerComponent.Get(circuitEntry)
|
||
circuit := StationPsdsCircuitStateComponent.Get(circuitEntry)
|
||
//上行
|
||
isSMg := true
|
||
sQuery := ecs.NewQuery(filter.Contains(tags.STag))
|
||
sQuery.Each(w, func(sPsd *ecs.Entry) {
|
||
if isSMg {
|
||
isSMg = PsdStateComponent.Get(sPsd).Rate == PSD_CLOSED_RATE
|
||
}
|
||
})
|
||
if isSMg != circuit.SMGJ {
|
||
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(circuitEntry).Id, PSD_GT, PSD_SMGJ, isSMg); ok {
|
||
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
|
||
}
|
||
}
|
||
//下行
|
||
isXMg := true
|
||
xQuery := ecs.NewQuery(filter.Contains(tags.XTag))
|
||
xQuery.Each(w, func(xPsd *ecs.Entry) {
|
||
if isXMg {
|
||
isXMg = PsdStateComponent.Get(xPsd).Rate == PSD_CLOSED_RATE
|
||
}
|
||
})
|
||
if isXMg != circuit.XMGJ {
|
||
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(circuitEntry).Id, PSD_GT, PSD_XMGJ, isSMg); ok {
|
||
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
|
||
}
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
// 单个屏蔽门运算
|
||
func (me *StationPsdsCircuitSystem) psdUpdate(w ecs.World) {
|
||
psdsQuery.Each(w, func(e *ecs.Entry) {
|
||
me.calculatePsdMove(e)
|
||
})
|
||
}
|
||
|
||
// 单个屏蔽门移动运算
|
||
func (me *StationPsdsCircuitSystem) calculatePsdMove(psd *ecs.Entry) {
|
||
//move.Value为门当前打开的宽度
|
||
move := MovableObjectComponent.Get(psd)
|
||
state := PsdStateComponent.Get(psd)
|
||
if move.Value < PSD_CLOSED {
|
||
move.Value = PSD_CLOSED
|
||
}
|
||
if move.Value > PSD_OPENED {
|
||
move.Value = PSD_OPENED
|
||
}
|
||
state.Rate = int((float64(move.Value) / float64(PSD_OPENED)) * float64(100))
|
||
//
|
||
switch {
|
||
case state.actClosing && !state.actOpening:
|
||
move.Retreat()
|
||
case !state.actClosing && state.actOpening:
|
||
move.Forward()
|
||
case state.actClosing && state.actOpening:
|
||
move.Pause()
|
||
}
|
||
}
|