ecs 测试
This commit is contained in:
parent
b2a4bdb779
commit
73b1bfcb96
9
examples/rtss-cg/linux_amd64_make.bat
Normal file
9
examples/rtss-cg/linux_amd64_make.bat
Normal file
@ -0,0 +1,9 @@
|
||||
@echo off
|
||||
|
||||
set CGO_ENABLED=0
|
||||
set GOARCH=amd64
|
||||
set GOOS=linux
|
||||
set APP_NAME=%GOOS%_%GOARCH%_app
|
||||
echo complie ...
|
||||
go build -o %APP_NAME% main.go
|
||||
echo complie output %APP_NAME%
|
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
@ -35,34 +34,31 @@ import (
|
||||
*/
|
||||
//
|
||||
//
|
||||
func init() {
|
||||
log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
|
||||
}
|
||||
|
||||
// 1 world 须增加attach , 绑定与该world相关的信息
|
||||
// 2 事件的订阅、发布、处理是独立调用执行的,事件处理可以集中处理也可以只处理某类事件
|
||||
func main() {
|
||||
//
|
||||
simWorld := ecs.NewWorld(400)
|
||||
simWorld := ecs.NewWorld(300)
|
||||
//
|
||||
initMemoryModel(simWorld)
|
||||
//道岔
|
||||
initSwitchState(simWorld)
|
||||
//轨道
|
||||
initLinkState(simWorld)
|
||||
//添加列车
|
||||
initTrainState(simWorld, "train1", iwayside.LinkLocation{LinkId: "link4", LinkOffset: 3000 * 100 * 10}, false)
|
||||
//物理区段
|
||||
initPhsicalSectionState(simWorld)
|
||||
//
|
||||
simWorld.AddSystem(system.NewSwitchSystem())
|
||||
simWorld.AddSystem(system.NewTrainSystem())
|
||||
simWorld.AddSystem(system.NewCiSystem())
|
||||
//simWorld.AddSystem(system.NewCiSystem())
|
||||
simWorld.AddSystem(system.NewSectionSystem())
|
||||
//
|
||||
simWorld.StartUp()
|
||||
//
|
||||
time.Sleep(2 * time.Second)
|
||||
//
|
||||
operateSwitch(simWorld, "dc1")
|
||||
operateSwitch(simWorld, "dc2")
|
||||
time.Sleep(10 * time.Second)
|
||||
//添加列车
|
||||
initTrainState(simWorld, "train1", iwayside.LinkLocation{LinkId: "link4", LinkOffset: 3000 * 100 * 10}, false)
|
||||
initTrainState(simWorld, "train2", iwayside.LinkLocation{LinkId: "link4", LinkOffset: 1000 * 100 * 10}, false)
|
||||
time.Sleep(200 * time.Second)
|
||||
}
|
||||
|
||||
@ -108,6 +104,16 @@ func initLinkState(world ecs.World) {
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化物理区段状态
|
||||
func initPhsicalSectionState(world ecs.World) {
|
||||
simMemory := simulation.GetMemoryModel(world)
|
||||
for _, phSecModel := range simMemory.PhysicalSections {
|
||||
sectionState := &state.PhysicalSectionState{Id: phSecModel.GetId(), Occupied: false}
|
||||
sectionEntry := world.Create(simulation.ComPhsicalSectionState)
|
||||
simulation.ComPhsicalSectionState.Set(sectionEntry, sectionState)
|
||||
}
|
||||
}
|
||||
|
||||
// 添加列车并初始化
|
||||
func initTrainState(world ecs.World, trainId string, linkLocation iwayside.LinkLocation, up bool) {
|
||||
train := &state.TrainState{Id: trainId, LinkId: linkLocation.LinkId, LinkOffset: linkLocation.LinkOffset, Up: up}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package mwayside
|
||||
|
||||
import "joylink.club/rtss/iwayside"
|
||||
|
||||
//长link只与道岔相连
|
||||
type LinkModel struct {
|
||||
//轨道基本信息
|
||||
@ -11,3 +13,15 @@ type LinkModel struct {
|
||||
//轨道B端连接的道岔
|
||||
PortB *SwitchRef
|
||||
}
|
||||
|
||||
//与该轨道连接的所有道岔
|
||||
func (me *LinkModel) FindSwitchModels() []iwayside.ISwitchModel {
|
||||
var dcs []iwayside.ISwitchModel
|
||||
if nil != me.PortA {
|
||||
dcs = append(dcs, me.PortA.Switch)
|
||||
}
|
||||
if nil != me.PortB {
|
||||
dcs = append(dcs, me.PortB.Switch)
|
||||
}
|
||||
return dcs
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package mwayside
|
||||
|
||||
import "joylink.club/rtss/iwayside"
|
||||
import (
|
||||
"joylink.club/rtss/iwayside"
|
||||
)
|
||||
|
||||
//物理区段
|
||||
// 物理区段
|
||||
type PhysicalSectionModel struct {
|
||||
DeviceModel
|
||||
//true-线性物理区段;false-岔区物理区段
|
||||
@ -15,7 +17,7 @@ type PhysicalSectionModel struct {
|
||||
AreaAxlePoints []iwayside.IAxlePointModel
|
||||
}
|
||||
|
||||
//创建线性物理区段模型
|
||||
// 创建线性物理区段模型
|
||||
func NewLinePhysicalSectionModel(id string, axlePointPortA iwayside.IAxlePointModel, axlePointPortB iwayside.IAxlePointModel) *PhysicalSectionModel {
|
||||
return &PhysicalSectionModel{
|
||||
DeviceModel: DeviceModel{Id: id, Type: iwayside.PhysicalSection},
|
||||
@ -25,7 +27,7 @@ func NewLinePhysicalSectionModel(id string, axlePointPortA iwayside.IAxlePointMo
|
||||
}
|
||||
}
|
||||
|
||||
//创建岔区物理区段模型
|
||||
// 创建岔区物理区段模型
|
||||
func NewAreaPhysicalSectionModel(id string, axlePointPorts ...iwayside.IAxlePointModel) *PhysicalSectionModel {
|
||||
return &PhysicalSectionModel{
|
||||
DeviceModel: DeviceModel{Id: id, Type: iwayside.PhysicalSection},
|
||||
|
@ -1,5 +1,7 @@
|
||||
package mwayside
|
||||
|
||||
import "joylink.club/rtss/iwayside"
|
||||
|
||||
type SwitchModel struct {
|
||||
//道岔基本信息
|
||||
DeviceModel
|
||||
@ -12,3 +14,17 @@ type SwitchModel struct {
|
||||
//道岔公里标,单位mm
|
||||
KilometerSign int64
|
||||
}
|
||||
|
||||
// 判端轨道是否与该道岔连接
|
||||
func (me *SwitchModel) IsLink(link iwayside.ILinkModel) bool {
|
||||
if nil != me.PortA && link.GetId() == me.PortA.Link.GetId() {
|
||||
return true
|
||||
}
|
||||
if nil != me.PortB && link.GetId() == me.PortB.Link.GetId() {
|
||||
return true
|
||||
}
|
||||
if nil != me.PortC && link.GetId() == me.PortC.Link.GetId() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ var ComSwitchOperating = ecs.NewComponentType[state.SwitchOperating]()
|
||||
// 轨道状态组件
|
||||
var ComLinkState = ecs.NewComponentType[state.LinkState]()
|
||||
|
||||
// 物理区段状态
|
||||
var ComPhsicalSectionState = ecs.NewComponentType[state.PhysicalSectionState]()
|
||||
|
||||
// 列车状态组件
|
||||
var ComTrainState = ecs.NewComponentType[state.TrainState]()
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtss/iwayside"
|
||||
"joylink.club/rtss/mwayside"
|
||||
)
|
||||
|
||||
type SimMemory struct {
|
||||
@ -29,3 +30,13 @@ func GetMemoryModel(world ecs.World) *SimMemory {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 将列车轨道位置偏移转换为公里标,道岔处用投影近似
|
||||
func (me *SimMemory) LinkOffsetToKilometerSign(linkId string, linkOffset int64) int64 {
|
||||
link := me.Links[linkId].(*mwayside.LinkModel)
|
||||
if nil != link.PortA {
|
||||
return link.PortA.Switch.(*mwayside.SwitchModel).KilometerSign + linkOffset
|
||||
} else {
|
||||
return link.PortB.Switch.(*mwayside.SwitchModel).KilometerSign - linkOffset
|
||||
}
|
||||
}
|
||||
|
9
examples/rtss-cg/state/section_state.go
Normal file
9
examples/rtss-cg/state/section_state.go
Normal file
@ -0,0 +1,9 @@
|
||||
package state
|
||||
|
||||
//物理区段状态
|
||||
type PhysicalSectionState struct {
|
||||
//区段id
|
||||
Id string
|
||||
//是否有车占用
|
||||
Occupied bool
|
||||
}
|
132
examples/rtss-cg/system/section_system.go
Normal file
132
examples/rtss-cg/system/section_system.go
Normal file
@ -0,0 +1,132 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtss/iwayside"
|
||||
"joylink.club/rtss/mwayside"
|
||||
"joylink.club/rtss/simulation"
|
||||
"joylink.club/rtss/state"
|
||||
)
|
||||
|
||||
// 物理区段状态检测
|
||||
type SectionSystem struct {
|
||||
//列车查询
|
||||
trainQuery *ecs.Query
|
||||
//物理区段查询
|
||||
sectionQuery *ecs.Query
|
||||
}
|
||||
|
||||
func NewSectionSystem() *SectionSystem {
|
||||
return &SectionSystem{
|
||||
trainQuery: ecs.NewQuery(filter.Contains(simulation.ComTrainState)),
|
||||
sectionQuery: ecs.NewQuery(filter.Contains(simulation.ComPhsicalSectionState)),
|
||||
}
|
||||
}
|
||||
func (me *SectionSystem) Update(w ecs.World) {
|
||||
memory := simulation.GetMemoryModel(w)
|
||||
//收集轨道占用点
|
||||
var standPoints []*standingPoint
|
||||
me.trainQuery.Each(w, func(e *ecs.Entry) {
|
||||
train := simulation.ComTrainState.Get(e)
|
||||
standPoints = append(standPoints, &standingPoint{link: memory.Links[train.LinkId].(*mwayside.LinkModel), offset: train.LinkOffset})
|
||||
})
|
||||
//物理区段状态
|
||||
me.sectionQuery.Each(w, func(e *ecs.Entry) {
|
||||
sectionState := simulation.ComPhsicalSectionState.Get(e)
|
||||
sectionState.Occupied = checkOccupy(memory, standPoints, sectionState)
|
||||
})
|
||||
//
|
||||
sb := &strings.Builder{}
|
||||
me.sectionQuery.Each(w, func(e *ecs.Entry) {
|
||||
sectionState := simulation.ComPhsicalSectionState.Get(e)
|
||||
sb.WriteString(fmt.Sprintf("区段[%s]占用[%t] ||", sectionState.Id, sectionState.Occupied))
|
||||
})
|
||||
fmt.Println("==>>", sb.String())
|
||||
}
|
||||
|
||||
// 判断物理区段是否有列车占用
|
||||
func checkOccupy(memory *simulation.SimMemory, standPoints []*standingPoint, sectionState *state.PhysicalSectionState) bool {
|
||||
occupied := false
|
||||
//
|
||||
sectionModel := memory.PhysicalSections[sectionState.Id].(*mwayside.PhysicalSectionModel)
|
||||
for _, standPoint := range standPoints {
|
||||
if occupied = containsPoint(sectionModel, standPoint); occupied {
|
||||
break
|
||||
}
|
||||
}
|
||||
//
|
||||
return occupied
|
||||
}
|
||||
func containsPoint(sectionModel *mwayside.PhysicalSectionModel, point *standingPoint) bool {
|
||||
|
||||
if sectionModel.Line {
|
||||
if sectionModel.AxlePointPortA.(*mwayside.AxlePointModel).Link.GetId() != point.link.GetId() || sectionModel.AxlePointPortB.(*mwayside.AxlePointModel).Link.GetId() != point.link.GetId() {
|
||||
return false
|
||||
}
|
||||
offsetKilometerSign := linkOffsetToKilometerSign(point.link, point.offset)
|
||||
return offsetKilometerSign > sectionModel.AxlePointPortA.(*mwayside.AxlePointModel).KilometerSign && offsetKilometerSign < sectionModel.AxlePointPortB.(*mwayside.AxlePointModel).KilometerSign
|
||||
} else { //岔区物理区段
|
||||
//物理区段中的道岔
|
||||
sectionDc := findPhsicalSectionSwitches(sectionModel).(*mwayside.SwitchModel)
|
||||
sectionDcKilometerSign := sectionDc.KilometerSign
|
||||
//占用点公里标
|
||||
standKilometerSign := linkOffsetToKilometerSign(point.link, point.offset)
|
||||
for _, axle := range sectionModel.AreaAxlePoints {
|
||||
if sectionDc.IsLink(axle.(*mwayside.AxlePointModel).Link) {
|
||||
axleKilometerSign := axle.(*mwayside.AxlePointModel).KilometerSign
|
||||
if axleKilometerSign < sectionDcKilometerSign {
|
||||
return standKilometerSign > axleKilometerSign && standKilometerSign < sectionDcKilometerSign
|
||||
} else {
|
||||
return standKilometerSign > sectionDcKilometerSign && standKilometerSign < axleKilometerSign
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 轨道偏移转换为公里标
|
||||
func linkOffsetToKilometerSign(link *mwayside.LinkModel, offset int64) int64 {
|
||||
var rate float64 = float64(offset) / float64(link.Len)
|
||||
if nil != link.PortA && nil != link.PortB {
|
||||
portASwitch := link.PortA.Switch.(*mwayside.SwitchModel)
|
||||
portBSwitch := link.PortB.Switch.(*mwayside.SwitchModel)
|
||||
return portASwitch.KilometerSign + int64(float64(portBSwitch.KilometerSign-portASwitch.KilometerSign)*rate)
|
||||
} else if nil != link.PortA && nil == link.PortB {
|
||||
portASwitch := link.PortA.Switch.(*mwayside.SwitchModel)
|
||||
return portASwitch.KilometerSign + offset
|
||||
} else { //nil == link.PortA && nil != link.PortB
|
||||
portBSwitch := link.PortB.Switch.(*mwayside.SwitchModel)
|
||||
return portBSwitch.KilometerSign - link.Len + offset
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 被占用的轨道点定义
|
||||
type standingPoint struct {
|
||||
link *mwayside.LinkModel
|
||||
offset int64
|
||||
}
|
||||
|
||||
// 岔区物理区段,则返回计轴集合框定的道岔
|
||||
func findPhsicalSectionSwitches(me *mwayside.PhysicalSectionModel) iwayside.ISwitchModel {
|
||||
if len(me.AreaAxlePoints) == 0 {
|
||||
return nil
|
||||
}
|
||||
dcMap := make(map[string]iwayside.ISwitchModel)
|
||||
for _, axle := range me.AreaAxlePoints {
|
||||
linkDcs := axle.(*mwayside.AxlePointModel).Link.(*mwayside.LinkModel).FindSwitchModels()
|
||||
for _, linkDc := range linkDcs {
|
||||
if _, ok := dcMap[linkDc.GetId()]; !ok {
|
||||
dcMap[linkDc.GetId()] = linkDc
|
||||
} else {
|
||||
return linkDc
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtss/mwayside"
|
||||
"joylink.club/rtss/simulation"
|
||||
)
|
||||
|
||||
@ -36,3 +37,16 @@ func (me *SwitchSystem) Update(w ecs.World) {
|
||||
func NewSwitchSystem() *SwitchSystem {
|
||||
return &SwitchSystem{ComQuery: ecs.NewQuery(filter.Contains(simulation.ComSwitchOperating))}
|
||||
}
|
||||
|
||||
// 判断点是否在该物理区段内
|
||||
func ContainsPoint(me *mwayside.PhysicalSectionModel, linkId string, kilometerSign int64) bool {
|
||||
if me.AxlePointPortA.(*mwayside.AxlePointModel).Link.GetId() != linkId || me.AxlePointPortB.(*mwayside.AxlePointModel).Link.GetId() != linkId {
|
||||
return false
|
||||
}
|
||||
if me.Line {
|
||||
return me.AxlePointPortA.(*mwayside.AxlePointModel).KilometerSign < kilometerSign && me.AxlePointPortB.(*mwayside.AxlePointModel).KilometerSign > kilometerSign
|
||||
} else {
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ func (me *TrainSystem) Update(w ecs.World) {
|
||||
fmt.Println("==>>列车 id = ", train.Id, " linkId = ", train.LinkId, " offset = ", train.LinkOffset, " up = ", train.Up)
|
||||
curLink := findTrainLinkModel(w, train.LinkId)
|
||||
var offset int64 = train.LinkOffset + func() int64 {
|
||||
//列车一个循环移动1m
|
||||
if train.Up {
|
||||
return 20 * 1000
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user