rts-sim-module/system/psd_system.go
2023-09-21 09:46:20 +08:00

210 lines
5.7 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 (
"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()
}
}