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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/yohamta/donburi/filter"
|
"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() {
|
func main() {
|
||||||
//
|
//
|
||||||
simWorld := ecs.NewWorld(400)
|
simWorld := ecs.NewWorld(300)
|
||||||
//
|
//
|
||||||
initMemoryModel(simWorld)
|
initMemoryModel(simWorld)
|
||||||
//道岔
|
//道岔
|
||||||
initSwitchState(simWorld)
|
initSwitchState(simWorld)
|
||||||
//轨道
|
//轨道
|
||||||
initLinkState(simWorld)
|
initLinkState(simWorld)
|
||||||
//添加列车
|
//物理区段
|
||||||
initTrainState(simWorld, "train1", iwayside.LinkLocation{LinkId: "link4", LinkOffset: 3000 * 100 * 10}, false)
|
initPhsicalSectionState(simWorld)
|
||||||
//
|
//
|
||||||
simWorld.AddSystem(system.NewSwitchSystem())
|
simWorld.AddSystem(system.NewSwitchSystem())
|
||||||
simWorld.AddSystem(system.NewTrainSystem())
|
simWorld.AddSystem(system.NewTrainSystem())
|
||||||
simWorld.AddSystem(system.NewCiSystem())
|
//simWorld.AddSystem(system.NewCiSystem())
|
||||||
|
simWorld.AddSystem(system.NewSectionSystem())
|
||||||
//
|
//
|
||||||
simWorld.StartUp()
|
simWorld.StartUp()
|
||||||
//
|
//
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
//
|
|
||||||
operateSwitch(simWorld, "dc1")
|
operateSwitch(simWorld, "dc1")
|
||||||
operateSwitch(simWorld, "dc2")
|
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)
|
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) {
|
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}
|
train := &state.TrainState{Id: trainId, LinkId: linkLocation.LinkId, LinkOffset: linkLocation.LinkOffset, Up: up}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package mwayside
|
package mwayside
|
||||||
|
|
||||||
|
import "joylink.club/rtss/iwayside"
|
||||||
|
|
||||||
//长link只与道岔相连
|
//长link只与道岔相连
|
||||||
type LinkModel struct {
|
type LinkModel struct {
|
||||||
//轨道基本信息
|
//轨道基本信息
|
||||||
@ -11,3 +13,15 @@ type LinkModel struct {
|
|||||||
//轨道B端连接的道岔
|
//轨道B端连接的道岔
|
||||||
PortB *SwitchRef
|
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,6 +1,8 @@
|
|||||||
package mwayside
|
package mwayside
|
||||||
|
|
||||||
import "joylink.club/rtss/iwayside"
|
import (
|
||||||
|
"joylink.club/rtss/iwayside"
|
||||||
|
)
|
||||||
|
|
||||||
// 物理区段
|
// 物理区段
|
||||||
type PhysicalSectionModel struct {
|
type PhysicalSectionModel struct {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package mwayside
|
package mwayside
|
||||||
|
|
||||||
|
import "joylink.club/rtss/iwayside"
|
||||||
|
|
||||||
type SwitchModel struct {
|
type SwitchModel struct {
|
||||||
//道岔基本信息
|
//道岔基本信息
|
||||||
DeviceModel
|
DeviceModel
|
||||||
@ -12,3 +14,17 @@ type SwitchModel struct {
|
|||||||
//道岔公里标,单位mm
|
//道岔公里标,单位mm
|
||||||
KilometerSign int64
|
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 ComLinkState = ecs.NewComponentType[state.LinkState]()
|
||||||
|
|
||||||
|
// 物理区段状态
|
||||||
|
var ComPhsicalSectionState = ecs.NewComponentType[state.PhysicalSectionState]()
|
||||||
|
|
||||||
// 列车状态组件
|
// 列车状态组件
|
||||||
var ComTrainState = ecs.NewComponentType[state.TrainState]()
|
var ComTrainState = ecs.NewComponentType[state.TrainState]()
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/yohamta/donburi/filter"
|
"github.com/yohamta/donburi/filter"
|
||||||
"joylink.club/ecs"
|
"joylink.club/ecs"
|
||||||
"joylink.club/rtss/iwayside"
|
"joylink.club/rtss/iwayside"
|
||||||
|
"joylink.club/rtss/mwayside"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SimMemory struct {
|
type SimMemory struct {
|
||||||
@ -29,3 +30,13 @@ func GetMemoryModel(world ecs.World) *SimMemory {
|
|||||||
}
|
}
|
||||||
return nil
|
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"
|
"github.com/yohamta/donburi/filter"
|
||||||
"joylink.club/ecs"
|
"joylink.club/ecs"
|
||||||
|
"joylink.club/rtss/mwayside"
|
||||||
"joylink.club/rtss/simulation"
|
"joylink.club/rtss/simulation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,3 +37,16 @@ func (me *SwitchSystem) Update(w ecs.World) {
|
|||||||
func NewSwitchSystem() *SwitchSystem {
|
func NewSwitchSystem() *SwitchSystem {
|
||||||
return &SwitchSystem{ComQuery: ecs.NewQuery(filter.Contains(simulation.ComSwitchOperating))}
|
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)
|
fmt.Println("==>>列车 id = ", train.Id, " linkId = ", train.LinkId, " offset = ", train.LinkOffset, " up = ", train.Up)
|
||||||
curLink := findTrainLinkModel(w, train.LinkId)
|
curLink := findTrainLinkModel(w, train.LinkId)
|
||||||
var offset int64 = train.LinkOffset + func() int64 {
|
var offset int64 = train.LinkOffset + func() int64 {
|
||||||
|
//列车一个循环移动1m
|
||||||
if train.Up {
|
if train.Up {
|
||||||
return 20 * 1000
|
return 20 * 1000
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user