完善test1-仓库-初始化
This commit is contained in:
parent
9f841957e9
commit
2884f70f70
@ -10,6 +10,7 @@ import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 仿真world配置
|
||||
type WorldConfig struct {
|
||||
//模型管理器,接收模型仓库管理器实例的指针
|
||||
ModelManager umi.IModelManager
|
||||
@ -21,6 +22,7 @@ type WorldConfig struct {
|
||||
InitTime time.Time
|
||||
}
|
||||
|
||||
// 初始化仿真world
|
||||
func InitializeWorld(config *WorldConfig) ecs.World {
|
||||
world := ecs.NewWorld(config.Tick)
|
||||
// 初始化系统
|
||||
|
@ -1,118 +1,77 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/creator"
|
||||
"joylink.club/rtsssimulation/examples/test1/tmodel"
|
||||
"joylink.club/rtsssimulation/examples/test1/tstorages"
|
||||
"joylink.club/rtsssimulation/operate"
|
||||
"joylink.club/rtsssimulation/storages/memory"
|
||||
"joylink.club/rtsssimulation/storages/memory/wdcreator"
|
||||
"joylink.club/rtsssimulation/storages/model"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
type Simulation struct {
|
||||
FaceSystem *system.FaceSystem
|
||||
World ecs.World
|
||||
Status memory.StatusStorage
|
||||
}
|
||||
// 具体工序模型仓库key
|
||||
var StorageKeyXaV1 = tstorages.StorageKey{LineId: "xa-1", Version: "0.1"}
|
||||
|
||||
func init() {
|
||||
initShareModels()
|
||||
}
|
||||
func main() {
|
||||
var sim *Simulation = &Simulation{}
|
||||
// 通过共享仓库生成具体仿真world的模型仓库
|
||||
woldModelStorage := tstorages.ShareStoragesMapper.CreateWorldStorageWithShare(StorageKeyXaV1, initLinkModels())
|
||||
//
|
||||
initModels()
|
||||
initSimWorld(sim, 300)
|
||||
config := &creator.WorldConfig{
|
||||
ModelManager: woldModelStorage,
|
||||
Tick: 300,
|
||||
InitTime: time.Now(),
|
||||
Systems: []ecs.ISystem{system.NewPercentageSystem(), system.NewSwitchSystem(), system.NewPsdSystem(), system.NewTimerSystem(), system.NewDebugSystem()},
|
||||
}
|
||||
world := creator.InitializeWorld(config)
|
||||
//
|
||||
sim.World.StartUp()
|
||||
time.Sleep(2 * time.Second)
|
||||
//time.Sleep(60 * time.Second)
|
||||
world.StartUp()
|
||||
//
|
||||
//testSwitchTurn(sim.World, sim.FaceSystem)
|
||||
//testSignalOpt(world, face)
|
||||
//testPsdCellOpt(world, face)
|
||||
//testPsdCellOpt(sim.World, sim.FaceSystem)
|
||||
testButtonOpt(sim.World, sim.FaceSystem)
|
||||
testPsdOpt(world)
|
||||
//
|
||||
time.Sleep(300 * time.Second)
|
||||
time.Sleep(120 * time.Second)
|
||||
}
|
||||
|
||||
// 构建仿真world
|
||||
func initSimWorld(sim *Simulation, tick int) {
|
||||
sim.World = ecs.NewWorld(tick)
|
||||
sim.FaceSystem = wdcreator.InitializeWorld(sim.World, time.Now())
|
||||
// 构建具体仿真link模型
|
||||
func initLinkModels() *tstorages.ModelStorage {
|
||||
mds := tstorages.NewModelStorage()
|
||||
//
|
||||
mds := memory.DeviceModelStorage
|
||||
//信号机相关组件
|
||||
mds.ForEachModelsByType(umi.Signal, func(md memory.ModelData) {
|
||||
entry := wdcreator.CreateSignalEntity(sim.World)
|
||||
components.DeviceIdentityComponent.Set(entry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.SignalStateComponent.Set(entry, &cstate.SignalState{Display: cstate.SignalAspect_No})
|
||||
})
|
||||
//道岔相关组件
|
||||
mds.ForEachModelsByType(umi.Switch, func(md memory.ModelData) {
|
||||
entry := wdcreator.CreateSwitchEntity(sim.World)
|
||||
components.DeviceIdentityComponent.Set(entry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.SwitchRelayStateComponent.Set(entry, &cstate.SwitchRelayState{DcJ: false, FcJ: false, DbJ: true, FbJ: false})
|
||||
components.PercentageDeviceComponent.Set(entry, &cstate.PercentageDeviceState{Rate: system.SwitchNormalRate})
|
||||
})
|
||||
//屏蔽门相关组件
|
||||
mds.ForEachModelsByType(umi.Psd, func(md memory.ModelData) {
|
||||
psdEntry := wdcreator.CreatePsdEntity(sim.World)
|
||||
components.DeviceIdentityComponent.Set(psdEntry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.PsdStateComponent.Set(psdEntry, &cstate.PsdState{AllClosed: true, AllOpened: false, InterlockReleased: false})
|
||||
//
|
||||
psd := md.(umi.IPsdModel)
|
||||
for _, psdCell := range psd.AllDeviceCells() {
|
||||
cellEntry := wdcreator.CreatePsdCellEntity(sim.World, psdEntry)
|
||||
components.DeviceIdentityComponent.Set(cellEntry, &cstate.DeviceIdentity{Id: psdCell.GetId()})
|
||||
components.PercentageDeviceComponent.Set(cellEntry, &cstate.PercentageDeviceState{Rate: system.PsdCellWholeCloseRate})
|
||||
}
|
||||
})
|
||||
//按钮相关组件
|
||||
mds.ForEachModelsByType(umi.TowPosButton, func(md memory.ModelData) {
|
||||
entry := wdcreator.CreateTowPosButtonEntity(sim.World)
|
||||
components.DeviceIdentityComponent.Set(entry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.TowPositionButtonStateComponent.Set(entry, &cstate.TowPositionButtonState{Pos1: false, Pos2: true})
|
||||
})
|
||||
//添加必要的系统
|
||||
sim.World.AddSystem(system.NewSwitchSystem())
|
||||
sim.World.AddSystem(system.NewPsdSystem())
|
||||
sim.World.AddSystem(system.NewPercentageSystem())
|
||||
link1 := tmodel.NewLinkModel("link1")
|
||||
link2 := tmodel.NewLinkModel("link2")
|
||||
mds.AddModel(link1)
|
||||
mds.AddModel(link2)
|
||||
return mds
|
||||
}
|
||||
|
||||
// 构建模型
|
||||
func initModels() {
|
||||
mds := memory.DeviceModelStorage
|
||||
func initShareModels() {
|
||||
mds := tstorages.NewModelStorage()
|
||||
//
|
||||
link1 := model.NewLinkModel("link1")
|
||||
link2 := model.NewLinkModel("link2")
|
||||
mds.AddModel(link1)
|
||||
mds.AddModel(link2)
|
||||
//
|
||||
signal1 := model.NewSignalModel("signal1")
|
||||
signal2 := model.NewSignalModel("signal2")
|
||||
signal1 := tmodel.NewSignalModel("signal1")
|
||||
signal2 := tmodel.NewSignalModel("signal2")
|
||||
mds.AddModel(signal1)
|
||||
mds.AddModel(signal2)
|
||||
//
|
||||
switch1 := model.NewSwitchModel("switch1")
|
||||
switch1 := tmodel.NewSwitchModel("switch1")
|
||||
switch1.TurnTime = 3000
|
||||
switch2 := model.NewSwitchModel("switch2")
|
||||
switch2 := tmodel.NewSwitchModel("switch2")
|
||||
switch2.TurnTime = 2500
|
||||
mds.AddModel(switch1)
|
||||
mds.AddModel(switch2)
|
||||
//
|
||||
psd1 := model.NewPsdModel("psd1")
|
||||
psd1 := tmodel.NewPsdModel("psd1")
|
||||
psd1.MoveTime = 5000
|
||||
psd1Cell1 := model.NewPsdCellModel("psd1Cell1", psd1)
|
||||
psd1Cell2 := model.NewPsdCellModel("psd1Cell2", psd1)
|
||||
psd2 := model.NewPsdModel("psd2")
|
||||
psd1Cell1 := tmodel.NewPsdCellModel("psd1Cell1", psd1)
|
||||
psd1Cell2 := tmodel.NewPsdCellModel("psd1Cell2", psd1)
|
||||
psd2 := tmodel.NewPsdModel("psd2")
|
||||
psd2.MoveTime = 6000
|
||||
psd2Cell1 := model.NewPsdCellModel("psd2Cell1", psd2)
|
||||
psd2Cell2 := model.NewPsdCellModel("psd2Cell2", psd2)
|
||||
psd2Cell1 := tmodel.NewPsdCellModel("psd2Cell1", psd2)
|
||||
psd2Cell2 := tmodel.NewPsdCellModel("psd2Cell2", psd2)
|
||||
mds.AddModel(psd1)
|
||||
mds.AddModel(psd1Cell1)
|
||||
mds.AddModel(psd1Cell2)
|
||||
@ -120,64 +79,39 @@ func initModels() {
|
||||
mds.AddModel(psd2Cell1)
|
||||
mds.AddModel(psd2Cell2)
|
||||
//
|
||||
button1 := model.NewTowPosButtonModel("button1")
|
||||
button1 := tmodel.NewTowPosButtonModel("button1")
|
||||
mds.AddModel(button1)
|
||||
//
|
||||
tstorages.ShareStoragesMapper.AddShareModelStorage(StorageKeyXaV1, mds)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
func testPsdOpt(world ecs.World, face *system.FaceSystem) {
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FirePsdOperation(w, "psd1", true)
|
||||
})
|
||||
func testPsdOpt(w ecs.World) {
|
||||
operate.FirePsdOperation(w, "psd1", true)
|
||||
time.Sleep(5 * time.Second)
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FirePsdOperation(w, "psd1", false)
|
||||
})
|
||||
operate.FirePsdOperation(w, "psd1", false)
|
||||
}
|
||||
func testPsdCellOpt(world ecs.World, face *system.FaceSystem) {
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FirePsdCellOperation(w, "psd1", "psd1Cell1", 0)
|
||||
})
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FirePsdCellOperation(w, "psd1", "psd1Cell2", 0)
|
||||
})
|
||||
func testPsdCellOpt(w ecs.World) {
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell1", 0)
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell2", 0)
|
||||
time.Sleep(10 * time.Second)
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FirePsdCellOperation(w, "psd1", "psd1Cell1", 100-20)
|
||||
})
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FirePsdCellOperation(w, "psd1", "psd1Cell2", 100)
|
||||
})
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell1", 100-20)
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell2", 100)
|
||||
}
|
||||
func testSwitchTurn(world ecs.World, face *system.FaceSystem) {
|
||||
reslult, _ := face.Call(func(w ecs.World) any {
|
||||
fmt.Println("==>>1触发转动道岔 ...")
|
||||
return operate.FireSwitchTurn(w, "switch1", system.SwitchReverseRate)
|
||||
})
|
||||
fmt.Println("==>>1触发转动道岔 。。。", reslult)
|
||||
func testSwitchTurn(w ecs.World) {
|
||||
operate.FireSwitchTurn(w, "switch1", system.SwitchReverseRate)
|
||||
time.Sleep(8 * time.Second)
|
||||
reslult2, _ := face.Call(func(w ecs.World) any {
|
||||
fmt.Println("==>>2触发转动道岔 ...")
|
||||
return operate.FireSwitchTurn(w, "switch1", system.SwitchNormalRate)
|
||||
})
|
||||
fmt.Println("==>>2触发转动道岔 。。。", reslult2)
|
||||
operate.FireSwitchTurn(w, "switch1", system.SwitchNormalRate)
|
||||
|
||||
}
|
||||
func testSignalOpt(world ecs.World, face *system.FaceSystem) {
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.SetSignalDisplay(w, "siganl1", cstate.SignalAspect_B)
|
||||
})
|
||||
func testSignalOpt(w ecs.World) {
|
||||
operate.SetSignalDisplay(w, "siganl1", cstate.SignalAspect_B)
|
||||
}
|
||||
func testButtonOpt(world ecs.World, face *system.FaceSystem) {
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FireTowPositionButtonMoving(world, "button1")
|
||||
})
|
||||
func testButtonOpt(world ecs.World) {
|
||||
operate.FireTowPositionButtonMoving(world, "button1")
|
||||
time.Sleep(3 * time.Second)
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FireTowPositionButtonArrivedPos1(world, "button1")
|
||||
})
|
||||
operate.FireTowPositionButtonArrivedPos1(world, "button1")
|
||||
time.Sleep(3 * time.Second)
|
||||
face.Call(func(w ecs.World) any {
|
||||
return operate.FireTowPositionButtonArrivedPos2(world, "button1")
|
||||
})
|
||||
operate.FireTowPositionButtonArrivedPos2(world, "button1")
|
||||
}
|
||||
|
16
examples/test1/tmodel/axle_model.go
Normal file
16
examples/test1/tmodel/axle_model.go
Normal file
@ -0,0 +1,16 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 计轴检测点模型
|
||||
type AxlePointModel struct {
|
||||
DeviceModel
|
||||
//计轴检测点所在轨道
|
||||
LinkOffset umi.ILinkOffsetRef
|
||||
}
|
||||
|
||||
func NewAxlePointModel(id string) *AxlePointModel {
|
||||
return &AxlePointModel{DeviceModel: DeviceModel{Id: id, Type: umi.AxlePoint}}
|
||||
}
|
16
examples/test1/tmodel/balise_model.go
Normal file
16
examples/test1/tmodel/balise_model.go
Normal file
@ -0,0 +1,16 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 应答器
|
||||
type BaliseModel struct {
|
||||
DeviceModel
|
||||
//应答器所在轨道
|
||||
LinkOffset umi.ILinkOffsetRef
|
||||
}
|
||||
|
||||
func NewBaliseModel(id string) *BaliseModel {
|
||||
return &BaliseModel{DeviceModel: DeviceModel{Id: id, Type: umi.Balise}}
|
||||
}
|
14
examples/test1/tmodel/button_model.go
Normal file
14
examples/test1/tmodel/button_model.go
Normal file
@ -0,0 +1,14 @@
|
||||
package tmodel
|
||||
|
||||
import "joylink.club/rtsssimulation/umi"
|
||||
|
||||
//两档位按钮
|
||||
type TowPosButtonModel struct {
|
||||
DeviceModel
|
||||
// 按钮名称
|
||||
Name string
|
||||
}
|
||||
|
||||
func NewTowPosButtonModel(id string) *TowPosButtonModel {
|
||||
return &TowPosButtonModel{DeviceModel: DeviceModel{Id: id, Type: umi.TowPosButton}}
|
||||
}
|
23
examples/test1/tmodel/device_model.go
Normal file
23
examples/test1/tmodel/device_model.go
Normal file
@ -0,0 +1,23 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 设备模型基础信息
|
||||
type DeviceModel struct {
|
||||
// 设备id
|
||||
Id string
|
||||
// 设备类型
|
||||
Type umi.DeviceType
|
||||
}
|
||||
|
||||
func (me *DeviceModel) GetId() string {
|
||||
return me.Id
|
||||
}
|
||||
func (me *DeviceModel) IsSame(other umi.IDeviceModel) bool {
|
||||
return me.Id == other.GetId()
|
||||
}
|
||||
func (me *DeviceModel) GetType() umi.DeviceType {
|
||||
return me.Type
|
||||
}
|
81
examples/test1/tmodel/link_model.go
Normal file
81
examples/test1/tmodel/link_model.go
Normal file
@ -0,0 +1,81 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 长轨道,道岔端点间的轨道
|
||||
type LinkModel struct {
|
||||
DeviceModel
|
||||
//轨道A端口连接的道岔
|
||||
PortA umi.ISwitchRef
|
||||
//轨道B端口连接的道岔
|
||||
PortB umi.ISwitchRef
|
||||
//长度,单位mm
|
||||
Length int64
|
||||
}
|
||||
|
||||
func NewLinkModel(id string) *LinkModel {
|
||||
return &LinkModel{DeviceModel: DeviceModel{Id: id, Type: umi.Link}}
|
||||
}
|
||||
|
||||
// 获取轨道长度,单位mm
|
||||
func (me *LinkModel) Len() int64 {
|
||||
return me.Length
|
||||
}
|
||||
|
||||
// 轨道A端连接的道岔
|
||||
func (me *LinkModel) PortASwitch() umi.ISwitchRef {
|
||||
return me.PortA
|
||||
}
|
||||
|
||||
// 轨道B端连接的道岔
|
||||
func (me *LinkModel) PortBSwitch() umi.ISwitchRef {
|
||||
return me.PortB
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
// 轨道端口引用
|
||||
type LinkRef struct {
|
||||
Link umi.ILinkModel
|
||||
//引用轨道的端口
|
||||
Port umi.PortEnum
|
||||
}
|
||||
|
||||
func NewLinkRef(link *LinkModel, port umi.PortEnum) *LinkRef {
|
||||
return &LinkRef{Link: link, Port: port}
|
||||
}
|
||||
|
||||
// 被引用的轨道模型
|
||||
func (me *LinkRef) LinkModel() umi.ILinkModel {
|
||||
return me.Link
|
||||
}
|
||||
|
||||
// 被引用的轨道的端口
|
||||
func (me *LinkRef) LinkPort() umi.PortEnum {
|
||||
return me.Port
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// 轨道偏移位置引用,轨道A端为偏移起始位置
|
||||
type LinkOffsetRef struct {
|
||||
Link umi.ILinkModel
|
||||
//偏移位置,单位mm
|
||||
Offset int64
|
||||
}
|
||||
|
||||
func NewLinkOffsetRef(link *LinkModel, offset int64) *LinkOffsetRef {
|
||||
return &LinkOffsetRef{Link: link, Offset: offset}
|
||||
}
|
||||
|
||||
// 被引用的轨道模型
|
||||
func (me *LinkOffsetRef) LinkModel() umi.ILinkModel {
|
||||
return me.Link
|
||||
}
|
||||
|
||||
// 偏移量,单位mm
|
||||
func (me *LinkOffsetRef) GetOffset() int64 {
|
||||
return me.Offset
|
||||
}
|
56
examples/test1/tmodel/psd_model.go
Normal file
56
examples/test1/tmodel/psd_model.go
Normal file
@ -0,0 +1,56 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 站台一侧屏蔽门模型
|
||||
type PsdModel struct {
|
||||
DeviceModel
|
||||
//屏蔽门所包含的单元
|
||||
Cells []*PsdCellModel
|
||||
//屏蔽门移动从0-100耗时,单位ms
|
||||
MoveTime int64
|
||||
}
|
||||
|
||||
func NewPsdModel(id string) *PsdModel {
|
||||
return &PsdModel{DeviceModel: DeviceModel{Id: id, Type: umi.Psd}, Cells: make([]*PsdCellModel, 0)}
|
||||
}
|
||||
func (me *PsdModel) addCell(cell *PsdCellModel) {
|
||||
me.Cells = append(me.Cells, cell)
|
||||
}
|
||||
|
||||
// 屏蔽门移动从0-100耗时,单位ms
|
||||
func (me *PsdModel) MovingTime() int64 {
|
||||
return me.MoveTime
|
||||
}
|
||||
|
||||
// 屏蔽门的所有单元门
|
||||
func (me *PsdModel) AllDeviceCells() []umi.IDeviceModel {
|
||||
rt := make([]umi.IDeviceModel, 0, len(me.Cells))
|
||||
for _, cell := range me.Cells {
|
||||
rt = append(rt, cell)
|
||||
}
|
||||
return rt
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
// 站台一侧屏蔽门单元模型
|
||||
type PsdCellModel struct {
|
||||
DeviceModel
|
||||
//该屏蔽门单元所属的屏蔽门
|
||||
psd umi.IDeviceModel
|
||||
}
|
||||
|
||||
func NewPsdCellModel(id string, psdModel *PsdModel) *PsdCellModel {
|
||||
cell := &PsdCellModel{
|
||||
DeviceModel: DeviceModel{Id: id, Type: umi.PsdCell},
|
||||
psd: psdModel,
|
||||
}
|
||||
psdModel.addCell(cell)
|
||||
return cell
|
||||
}
|
||||
func (me *PsdCellModel) Psd() *PsdModel {
|
||||
return me.psd.(*PsdModel)
|
||||
}
|
21
examples/test1/tmodel/signal_model.go
Normal file
21
examples/test1/tmodel/signal_model.go
Normal file
@ -0,0 +1,21 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 信号机
|
||||
type SignalModel struct {
|
||||
DeviceModel
|
||||
//信号机所在轨道
|
||||
LinkOffset *LinkOffsetRef
|
||||
//信号机类型,出厂已确定,即几个色灯、排列顺序
|
||||
Type cstate.SignalAspect
|
||||
//默认显示信号
|
||||
DefaultDisplay cstate.SignalAspect
|
||||
}
|
||||
|
||||
func NewSignalModel(id string) *SignalModel {
|
||||
return &SignalModel{DeviceModel: DeviceModel{Id: id, Type: umi.Signal}}
|
||||
}
|
65
examples/test1/tmodel/switch_model.go
Normal file
65
examples/test1/tmodel/switch_model.go
Normal file
@ -0,0 +1,65 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 道岔
|
||||
type SwitchModel struct {
|
||||
DeviceModel
|
||||
//道岔A端口连接的轨道
|
||||
PortA umi.ILinkRef
|
||||
//道岔B端口连接的轨道
|
||||
PortB umi.ILinkRef
|
||||
//道岔C端口连接的轨道
|
||||
PortC umi.ILinkRef
|
||||
//道岔转动需要的时间(从开度0-100的时间),单位ms
|
||||
TurnTime int64
|
||||
}
|
||||
|
||||
func NewSwitchModel(id string) *SwitchModel {
|
||||
return &SwitchModel{DeviceModel: DeviceModel{Id: id, Type: umi.Switch}}
|
||||
}
|
||||
|
||||
// 道岔转动从0-100耗时,单位ms
|
||||
func (me *SwitchModel) TurningTime() int64 {
|
||||
return me.TurnTime
|
||||
}
|
||||
|
||||
// 道岔A端口连接的轨道
|
||||
func (me *SwitchModel) PortALink() umi.ILinkRef {
|
||||
return me.PortA
|
||||
}
|
||||
|
||||
// 道岔B端口连接的轨道
|
||||
func (me *SwitchModel) PortBLink() umi.ILinkRef {
|
||||
return me.PortB
|
||||
}
|
||||
|
||||
// 道岔C端口连接的轨道
|
||||
func (me *SwitchModel) PortCLink() umi.ILinkRef {
|
||||
return me.PortC
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
// 道岔端口引用
|
||||
type SwitchRef struct {
|
||||
Switch umi.ISwitchModel
|
||||
//引用道岔的端口
|
||||
Port umi.PortEnum
|
||||
}
|
||||
|
||||
func NewSwitchRef(switchModel *SwitchModel, port umi.PortEnum) *SwitchRef {
|
||||
return &SwitchRef{Switch: switchModel, Port: port}
|
||||
}
|
||||
|
||||
// 被引用的道岔模型
|
||||
func (me *SwitchRef) SwitchModel() umi.ISwitchModel {
|
||||
return me.Switch
|
||||
}
|
||||
|
||||
// 被引用的道岔的端口
|
||||
func (me *SwitchRef) SwitchPort() umi.PortEnum {
|
||||
return me.Port
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package memory
|
||||
package tstorages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -9,10 +9,6 @@ import (
|
||||
// 仿真模型数据定义
|
||||
type ModelData = umi.IDeviceModel
|
||||
|
||||
// 仿真模型数据仓库
|
||||
// 所有仿真实例共用
|
||||
var DeviceModelStorage *ModelStorage = newModelStorage()
|
||||
|
||||
// 模型存储、管理仓库
|
||||
type ModelStorage struct {
|
||||
//key-模型id,value-模型指针
|
||||
@ -21,7 +17,7 @@ type ModelStorage struct {
|
||||
typeModelMap map[umi.DeviceType][]ModelData
|
||||
}
|
||||
|
||||
func newModelStorage() *ModelStorage {
|
||||
func NewModelStorage() *ModelStorage {
|
||||
return &ModelStorage{idModelMap: make(map[string]ModelData, 2048), typeModelMap: make(map[umi.DeviceType][]ModelData, 128)}
|
||||
}
|
||||
|
73
examples/test1/tstorages/storage_manager.go
Normal file
73
examples/test1/tstorages/storage_manager.go
Normal file
@ -0,0 +1,73 @@
|
||||
package tstorages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 共享仓库映射
|
||||
var ShareStoragesMapper *ModelStoragesMapper = &ModelStoragesMapper{storages: make(map[string]*ModelStorage)}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
type StorageKey struct {
|
||||
LineId string
|
||||
Version string
|
||||
}
|
||||
|
||||
func (me *StorageKey) Key() string {
|
||||
return fmt.Sprintf("%s||%s", me.LineId, me.Version)
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
type ModelStoragesMapper struct {
|
||||
//共享模型仓库
|
||||
//key-StorageKey
|
||||
storages map[string]*ModelStorage
|
||||
}
|
||||
|
||||
func (me *ModelStoragesMapper) FindShareModelStorage(skey StorageKey) *ModelStorage {
|
||||
return me.storages[skey.Key()]
|
||||
}
|
||||
func (me *ModelStoragesMapper) AddShareModelStorage(skey StorageKey, storage *ModelStorage) {
|
||||
me.storages[skey.Key()] = storage
|
||||
}
|
||||
|
||||
// 通过共享模型仓库创建world模型仓库
|
||||
func (me *ModelStoragesMapper) CreateWorldStorageWithShare(skey StorageKey, links *ModelStorage) *WorldModelStorage {
|
||||
return &WorldModelStorage{Share: me.storages[skey.Key()], Links: links}
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
// 仿真world的模型仓库
|
||||
type WorldModelStorage struct {
|
||||
// 对公共模型的指针
|
||||
Share *ModelStorage
|
||||
// 该world独享的轨道模型
|
||||
Links *ModelStorage
|
||||
}
|
||||
|
||||
// 根据模型的复合id获取模型数据
|
||||
func (me *WorldModelStorage) FindById(id string) umi.IDeviceModel {
|
||||
md := me.Links.FindModelById(id)
|
||||
if md != md {
|
||||
return md
|
||||
}
|
||||
md = me.Share.FindModelById(id)
|
||||
if md != md {
|
||||
return md
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取某类型设备的所有模型数据
|
||||
func (me *WorldModelStorage) FindByType(deviceType umi.DeviceType) []umi.IDeviceModel {
|
||||
if umi.Link == deviceType {
|
||||
return me.Links.FindModelsByType(deviceType)
|
||||
} else {
|
||||
return me.Share.FindModelsByType(deviceType)
|
||||
}
|
||||
}
|
19
operate/operation.go
Normal file
19
operate/operation.go
Normal file
@ -0,0 +1,19 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
var worldModelStorageQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.ModelStorageRefComponent))
|
||||
|
||||
func worldModelStorage(world ecs.World) umi.IModelManager {
|
||||
e, ok := worldModelStorageQuery.First(world)
|
||||
if ok {
|
||||
return components.ModelStorageRefComponent.Get(e).ModelManager
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/storages/memory"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
@ -34,9 +33,9 @@ func FirePsdOperation(world ecs.World, psdId string, closeOpt bool) error {
|
||||
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
|
||||
psdCellQuery.Each(world, func(psdCellEntry *ecs.Entry) {
|
||||
if closeOpt {
|
||||
FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(psdId), system.PsdCellWholeCloseRate)
|
||||
FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(world, psdId), system.PsdCellWholeCloseRate)
|
||||
} else {
|
||||
FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(psdId), system.PsdCellWholeOpenRate)
|
||||
FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(world, psdId), system.PsdCellWholeOpenRate)
|
||||
}
|
||||
})
|
||||
//
|
||||
@ -62,7 +61,7 @@ func FirePsdCellOperation(world ecs.World, psdId string, psdCellId string, close
|
||||
return fmt.Errorf("屏蔽门[%s]的单元门[%s]的实体不存在", psdId, psdCellId)
|
||||
}
|
||||
//
|
||||
return FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(psdId), closeRate)
|
||||
return FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(world, psdId), closeRate)
|
||||
}
|
||||
|
||||
// 获取屏蔽门实体
|
||||
@ -76,8 +75,8 @@ func findPsdEntry(world ecs.World, psdId string) (*ecs.Entry, error) {
|
||||
}
|
||||
|
||||
// 获取屏蔽门从完全开到完全关所需时间,单位ms
|
||||
func findPsdWholeMoveTime(psdId string) int64 {
|
||||
psd := memory.DeviceModelStorage.FindModelById(psdId)
|
||||
func findPsdWholeMoveTime(world ecs.World, psdId string) int64 {
|
||||
psd := worldModelStorage(world).FindById(psdId)
|
||||
if nil != psd {
|
||||
psdUmi := psd.(umi.IPsdModel)
|
||||
return psdUmi.MovingTime()
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/storages/memory"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
@ -33,13 +32,13 @@ func FireSwitchTurn(w ecs.World, switchId string, terminalRate int32) error {
|
||||
switchRelay.DbJ = false
|
||||
switchRelay.FbJ = false
|
||||
//
|
||||
lhDistance := getSwitchTurnTime(switchId)
|
||||
lhDistance := getSwitchTurnTime(w, switchId)
|
||||
return FirePercentageDeviceOperation(w, switchEntry, lhDistance, terminalRate)
|
||||
}
|
||||
|
||||
// 获取道岔转动耗时ms
|
||||
func getSwitchTurnTime(switchId string) int64 {
|
||||
dcModel := memory.DeviceModelStorage.FindModelById(switchId)
|
||||
func getSwitchTurnTime(world ecs.World, switchId string) int64 {
|
||||
dcModel := worldModelStorage(world).FindById(switchId)
|
||||
if nil != dcModel {
|
||||
var dc umi.ISwitchModel = dcModel.(umi.ISwitchModel)
|
||||
return dc.TurningTime()
|
||||
|
@ -1,85 +0,0 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
//收集实体组件状态生成设备状态
|
||||
//推送设备状态给前端或其他服务
|
||||
|
||||
// 设备状态数据定义
|
||||
type DeviceState = any
|
||||
|
||||
// 设备实体转换为设备状态的方法定义
|
||||
type EntityToStateMethod func(deviceEntry *ecs.Entry) DeviceState
|
||||
|
||||
// 生成对应类型设备的状态的副本的方法定义
|
||||
type StateCopyMethod func(srcState DeviceState) DeviceState
|
||||
|
||||
// 当前时刻设备状态与前一刻设备状态比较
|
||||
// true-状态变化,false-状态未变化
|
||||
type StateCompareMethod func(preState DeviceState, curState DeviceState) bool
|
||||
|
||||
// 设备状态仓库定义
|
||||
type StatusStorage struct {
|
||||
modelStorage *ModelStorage
|
||||
//所有实体,状态对实体只读操作
|
||||
idEntryMap map[string]*ecs.Entry
|
||||
//当前状态
|
||||
//key-设备id,value-状态数据指针
|
||||
idCurStateMap map[string]DeviceState
|
||||
//上一刻状态
|
||||
//key-设备id,value-状态数据指针
|
||||
idPreStateMap map[string]DeviceState
|
||||
//设备类型到设备实体转换为设备状态的方法的映射
|
||||
entityToStateMethodMap map[umi.DeviceType]*EntityToStateMethod
|
||||
//生成对应类型设备的状态的副本的方法的映射
|
||||
stateCopyMethodMap map[umi.DeviceType]*StateCopyMethod
|
||||
//当前时刻设备状态与前一刻设备状态比较的方法映射
|
||||
stateCompareMethodMap map[umi.DeviceType]*StateCompareMethod
|
||||
}
|
||||
|
||||
func NewStatusStorage() *StatusStorage {
|
||||
dms := DeviceModelStorage
|
||||
modelsAmount := dms.AmountOfModels()
|
||||
typesAmount := dms.AmountOfDeviceTypes()
|
||||
return &StatusStorage{
|
||||
modelStorage: dms,
|
||||
idEntryMap: make(map[string]*ecs.Entry, modelsAmount),
|
||||
idCurStateMap: make(map[string]DeviceState, modelsAmount),
|
||||
idPreStateMap: make(map[string]DeviceState, modelsAmount),
|
||||
entityToStateMethodMap: make(map[umi.DeviceType]*EntityToStateMethod, typesAmount),
|
||||
stateCopyMethodMap: make(map[umi.DeviceType]*StateCopyMethod, typesAmount),
|
||||
stateCompareMethodMap: make(map[umi.DeviceType]*StateCompareMethod, typesAmount),
|
||||
}
|
||||
}
|
||||
|
||||
// 从实体运行时生成对应设备状态
|
||||
func (me *StatusStorage) AddStateFromEntity(entry *ecs.Entry) {
|
||||
id := components.DeviceIdentityComponent.Get(entry).Id
|
||||
deviceModel := me.modelStorage.FindModelById(id)
|
||||
deviceState := (*me.entityToStateMethodMap[deviceModel.GetType()])(entry)
|
||||
me.idCurStateMap[id] = deviceState
|
||||
}
|
||||
|
||||
// 添加从设备实体生成状态的方法
|
||||
func (me *StatusStorage) InitEntityToStateMethod(deviceType umi.DeviceType, method *EntityToStateMethod) {
|
||||
me.entityToStateMethodMap[deviceType] = method
|
||||
}
|
||||
|
||||
// 添加生成对应类型设备的状态的副本的方法
|
||||
func (me *StatusStorage) InitStateCopyMethod(deviceType umi.DeviceType, method *StateCopyMethod) {
|
||||
me.stateCopyMethodMap[deviceType] = method
|
||||
}
|
||||
|
||||
// 添加当前时刻设备状态与前一刻设备状态比较的方法
|
||||
func (me *StatusStorage) InitStateCompareMethod(deviceType umi.DeviceType, method *StateCompareMethod) {
|
||||
me.stateCompareMethodMap[deviceType] = method
|
||||
}
|
||||
|
||||
// 获取模型仓库
|
||||
func (me *StatusStorage) ModelStorage() *ModelStorage {
|
||||
return me.modelStorage
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package wdcreator
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
// 初始化world,添加一些内置的组件和系统
|
||||
func InitializeWorld(w ecs.World, worldTime time.Time) *system.FaceSystem {
|
||||
//初始化world时钟
|
||||
timeEntry := w.Create(components.SystemTimerComponent)
|
||||
components.SystemTimerComponent.Set(timeEntry, cstate.NewSystemTimer(&worldTime))
|
||||
w.AddSystem(system.NewTimerSystem())
|
||||
//初始化world与外界交互的门面
|
||||
faceSystem := system.NewFaceSystem(w)
|
||||
w.AddSystem(faceSystem)
|
||||
//添加百分比设备系统
|
||||
w.AddSystem(system.NewPercentageSystem())
|
||||
//添加调试系统
|
||||
w.AddSystem(system.NewDebugSystem())
|
||||
//
|
||||
return faceSystem
|
||||
}
|
||||
|
||||
// 创建道岔实体
|
||||
func CreateSwitchEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.SwitchRelayStateComponent, components.PercentageDeviceComponent)
|
||||
}
|
||||
|
||||
// 创建信号机实体
|
||||
func CreateSignalEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.SignalStateComponent)
|
||||
}
|
||||
|
||||
// 创建物理区段实体
|
||||
func CreatePhysicalSectionEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.PhysicalSectionStateComponent)
|
||||
}
|
||||
|
||||
// 创建站台单侧屏蔽门实体
|
||||
func CreatePsdEntity(w ecs.World) *ecs.Entry {
|
||||
e := w.Create(components.DeviceIdentityComponent, components.PsdStateComponent, components.EntityTagHandlerComponent)
|
||||
components.EntityTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[struct{}]()})
|
||||
return e
|
||||
}
|
||||
|
||||
// 创建屏蔽门cell实体
|
||||
func CreatePsdCellEntity(w ecs.World, psdEntry *ecs.Entry) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.PercentageDeviceComponent, components.EntityTagHandlerComponent.Get(psdEntry).Tag)
|
||||
}
|
||||
|
||||
// 创建应答器实体
|
||||
func CreateBaliseEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.BaliseStateComponent)
|
||||
}
|
||||
|
||||
// 创建列车实体
|
||||
func CreateTrainEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.TrainStateComponent)
|
||||
}
|
||||
|
||||
// 创建两档位按钮实体
|
||||
func CreateTowPosButtonEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.TowPositionButtonStateComponent)
|
||||
}
|
@ -18,10 +18,10 @@ func NewDebugSystem() *DebugSystem {
|
||||
|
||||
// world 执行
|
||||
func (me *DebugSystem) Update(w ecs.World) {
|
||||
//debugPsd(w)
|
||||
debugPsd(w)
|
||||
//debugSwitch(w)
|
||||
//debugSignal(w)
|
||||
debugTowPosButton(w)
|
||||
//debugTowPosButton(w)
|
||||
}
|
||||
|
||||
// 两档位按钮旋钮
|
||||
|
Loading…
Reference in New Issue
Block a user