Merge remote-tracking branch 'origin/master'

This commit is contained in:
joylink_zhangsai 2023-09-20 18:21:39 +08:00
commit b4d3e75e06
4 changed files with 247 additions and 5 deletions

50
entities/psd_entity.go Normal file
View File

@ -0,0 +1,50 @@
package entities
import (
"github.com/yohamta/donburi"
"joylink.club/ecs"
"joylink.club/rtsssimulation/system"
"joylink.club/rtsssimulation/umi"
)
// CreateStationPsdsCircuitEntity 创建车站屏蔽门电路实体
func CreateStationPsdsCircuitEntity(w ecs.World, stationId string, psds []umi.IPsdModel) *ecs.Entry {
circuit := w.Create(system.EntityIdentityComponent, system.StationPsdsCircuitStateComponent, system.PsdTagHandlerComponent)
system.EntityIdentityComponent.Set(circuit, &system.EntityIdentity{Id: stationId})
system.StationPsdsCircuitStateComponent.Set(circuit, system.NewStationPsdsCircuitState())
system.PsdTagHandlerComponent.Set(circuit, system.NewPsdTagHandler())
tags := system.PsdTagHandlerComponent.Get(circuit)
//
for _, psd := range psds {
cc := make([]donburi.IComponentType, 6)
cc = append(cc, system.EntityIdentityComponent)
cc = append(cc, system.PsdStateComponent)
cc = append(cc, system.MovableObjectComponent)
if psd.IsS() {
cc = append(cc, tags.STag)
}
if psd.IsS4() {
cc = append(cc, tags.S4Tag)
}
if psd.IsS8() {
cc = append(cc, tags.S8Tag)
}
if psd.IsX() {
cc = append(cc, tags.XTag)
}
if psd.IsX4() {
cc = append(cc, tags.X4Tag)
}
if psd.IsX8() {
cc = append(cc, tags.X8Tag)
}
psdEntry := w.Create(cc...)
//
psdId := psd.(umi.IDeviceModel).GetId()
system.EntityIdentityComponent.Set(psdEntry, &system.EntityIdentity{Id: psdId})
system.PsdStateComponent.Set(psdEntry, system.NewPsdState())
system.MovableObjectComponent.Set(psdEntry, system.NewMovableObject())
}
//
return circuit
}

173
system/psd_system.go Normal file
View File

@ -0,0 +1,173 @@
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
}
// 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{}
}
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)
})
}
// 关门动作运算
func (me *StationPsdsCircuitSystem) calculateGM(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))
}

View File

@ -2,6 +2,7 @@ package system
import (
"fmt"
"github.com/yohamta/donburi/component"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
@ -58,6 +59,16 @@ type EntityTagHandler struct {
Tag EntityTag
}
func NewTag() EntityTag {
return ecs.NewComponentType[struct{}]()
}
func NewEntityTagHandler() *EntityTagHandler {
h := &EntityTagHandler{Tag: NewTag()}
return h
}
var EntityTagHandlerComponent = ecs.NewComponentType[EntityTagHandler]()
/////////////////////////////////////////////////////////
// ModelStorageRef 模型仓库引用
@ -82,7 +93,7 @@ func DriveRelay(w ecs.World, circuitModelId string, relayGroup string, relayName
if relayModel := roler.FindRelayModelByCRole(relayGroup, relayName); relayModel != nil {
if deviceModel, isDm := relayModel.(umi.IDeviceModel); isDm {
relayId := deviceModel.GetId()
sysEvent.RelayNeedChangeEventBus.PublishOutWorld(w, &sysEvent.RelayNeedChangeEvent{Id: relayId, Xh: xh})
sysEvent.RelayNeedChangeEventBus.Publish(w, &sysEvent.RelayNeedChangeEvent{Id: relayId, Xh: xh})
return true
}
}

View File

@ -93,10 +93,18 @@ type ISwitchRef interface {
// IPsdModel 仿真底层屏蔽门模型
// 用户所有屏蔽门模型定义须实现该接口
type IPsdModel interface {
//MovingTime 屏蔽门移动从0-100耗时单位ms
MovingTime() int64
//AllDeviceCells 屏蔽门的所有单元门
AllDeviceCells() []IDeviceModel
//IsS true-上行
IsS() bool
//IsS4 true-上行4编组
IsS4() bool
//IsS8 true-上行8编组
IsS8() bool
//IsX true-下行
IsX() bool
//IsX4 true-下行4编组
IsX4() bool
//IsX8 true-下行8编组
IsX8() bool
}
// //////////////////////////////////////////////////////////