2023-11-22 14:02:25 +08:00
|
|
|
|
package device_sys
|
|
|
|
|
|
2023-11-22 16:35:54 +08:00
|
|
|
|
import (
|
|
|
|
|
"joylink.club/ecs"
|
|
|
|
|
"joylink.club/ecs/filter"
|
|
|
|
|
"joylink.club/rtsssimulation/component"
|
|
|
|
|
"joylink.club/rtsssimulation/entity"
|
|
|
|
|
"joylink.club/rtsssimulation/repository"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// BaliseDetectSystem 列车应答器天线探测轨旁应答器
|
|
|
|
|
type BaliseDetectSystem struct {
|
|
|
|
|
trainQuery *ecs.Query
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewBaliseDetectSystem() *BaliseDetectSystem {
|
|
|
|
|
return &BaliseDetectSystem{
|
|
|
|
|
trainQuery: ecs.NewQuery(filter.Contains(component.UidType, component.TrainPositionInfoType)),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
func (s *BaliseDetectSystem) Update(w ecs.World) {
|
|
|
|
|
wd := entity.GetWorldData(w)
|
|
|
|
|
balises := wd.Repo.ResponderList()
|
|
|
|
|
//所有列车
|
|
|
|
|
//列车速度80KM/H时,222mm/10ms
|
|
|
|
|
s.trainQuery.Each(w, func(entry *ecs.Entry) {
|
|
|
|
|
tp := component.TrainPositionInfoType.Get(entry)
|
|
|
|
|
detectedBalise := s.detect(wd, tp, balises)
|
|
|
|
|
if detectedBalise != nil { //列车应答器天线扫描到应答器,获取应答器报文发送给BTM
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
func (s *BaliseDetectSystem) detect(wd *component.WorldData, tp *component.TrainPositionInfo, balises []*repository.Transponder) *repository.Transponder {
|
|
|
|
|
scanRange := s.calculateScanRange(wd, tp)
|
|
|
|
|
for _, balise := range balises {
|
|
|
|
|
if scanRange.contains(balise.LinkPosition()) {
|
|
|
|
|
return balise
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const scanWidth = int64(1000) //1000mm
|
|
|
|
|
// 计算车载应答器天线扫描范围,如果应答器在此范围内则天线可以接收到应答器报文
|
|
|
|
|
func (s *BaliseDetectSystem) calculateScanRange(wd *component.WorldData, tp *component.TrainPositionInfo) *scanRange {
|
|
|
|
|
headLink := wd.Repo.FindLink(tp.HeadLink)
|
|
|
|
|
if tp.Up { //列车运行方向a->b
|
|
|
|
|
if tp.HeadLinkOffset >= scanWidth {
|
|
|
|
|
return newScanRange(headLink.Id(), tp.HeadLinkOffset-scanWidth, tp.HeadLinkOffset)
|
|
|
|
|
} else {
|
|
|
|
|
return newScanRange(headLink.Id(), 0, tp.HeadLinkOffset)
|
|
|
|
|
}
|
|
|
|
|
} else { //列车运行方向b->a
|
|
|
|
|
if headLink.Length()-tp.HeadLinkOffset >= scanWidth {
|
|
|
|
|
return newScanRange(headLink.Id(), tp.HeadLinkOffset, tp.HeadLinkOffset+scanWidth)
|
|
|
|
|
} else {
|
|
|
|
|
return newScanRange(headLink.Id(), tp.HeadLinkOffset, headLink.Length())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type scanRange struct {
|
|
|
|
|
linkId string
|
|
|
|
|
startOffset int64
|
|
|
|
|
endOffset int64
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newScanRange(linkId string, start int64, end int64) *scanRange {
|
|
|
|
|
return &scanRange{linkId: linkId, startOffset: start, endOffset: end}
|
|
|
|
|
}
|
|
|
|
|
func (s *scanRange) format() {
|
|
|
|
|
if s.startOffset > s.endOffset {
|
|
|
|
|
s.startOffset, s.endOffset = s.endOffset, s.startOffset
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// true-应答器balisePosition在该scanRange内
|
|
|
|
|
func (s *scanRange) contains(balisePosition *repository.LinkPosition) bool {
|
|
|
|
|
if s.linkId != balisePosition.Link().Id() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
s.format()
|
|
|
|
|
return balisePosition.Offset() >= s.startOffset && balisePosition.Offset() <= s.endOffset
|
|
|
|
|
}
|