This commit is contained in:
xzb 2023-11-29 13:03:59 +08:00
parent ed536bd92d
commit 901009ce13
4 changed files with 42 additions and 37 deletions

View File

@ -3,7 +3,6 @@ package component
import (
"fmt"
"joylink.club/ecs"
"log/slog"
)
// TrainPositionInfo 列车当前位置信息
@ -31,14 +30,14 @@ func (t *TrainPositionInfo) ToString() string {
type TrainBaliseTelegram struct {
BaliseId string //应答器ID
Telegram []byte //一个应答器同一时刻只有一条报文处于激活有效状态
sent bool //true-已经向车载ATP发送过
Up bool //列车经过应答器时的运行方向
}
func NewTrainBaliseTelegram(baliseId string, telegram []byte) *TrainBaliseTelegram {
func NewTrainBaliseTelegram(up bool, baliseId string, telegram []byte) *TrainBaliseTelegram {
return &TrainBaliseTelegram{
BaliseId: baliseId,
Telegram: telegram,
sent: false,
Up: up,
}
}
@ -53,9 +52,14 @@ type TrainBtm struct {
//天线此时是否在应答器上方
AboveBalise bool
//列车在运行方向顺序扫描到的应答器
ScannedBalise *TrainBaliseTelegram
//避免丢失
scannedBalises chan *TrainBaliseTelegram
//最近经过的应答器id
viaBaliseId string
lastTelegram *TrainBaliseTelegram
}
func NewTrainBtm() *TrainBtm {
return &TrainBtm{scannedBalises: make(chan *TrainBaliseTelegram, 16)}
}
// 应答器计数器加1[0,255]
@ -74,32 +78,34 @@ func (t *TrainBtm) baliseMessageCounterAdd1() {
}
}
// SetBaliseTelegramHadSentAndGet 获取未发送的应答器报文并标记已发送
// 通过Canet发送应答器报文时调用该方法来获取要发送的报文
func (t *TrainBtm) SetBaliseTelegramHadSentAndGet() *TrainBaliseTelegram {
if t.ScannedBalise != nil && !t.ScannedBalise.sent {
t.ScannedBalise.sent = true
return t.ScannedBalise
}
func (t *TrainBtm) FindScannedBalises() <-chan *TrainBaliseTelegram {
if len(t.scannedBalises) > 0 {
return t.scannedBalises
} else {
return nil
}
}
// Scanning BTM通过车载应答器天线接收到应答器报文
func (t *TrainBtm) Scanning(aboveBalise bool, aboveBaliseId string, telegram *TrainBaliseTelegram) {
t.AboveBalise = aboveBalise
//BTM此时在一个新的应答器上方
if t.AboveBalise && t.viaBaliseId != aboveBaliseId {
t.viaBaliseId = aboveBaliseId
t.baliseCounterAdd1()
slog.Debug(fmt.Sprintf("列车经过应答器上方,应答器:[%s]", t.viaBaliseId))
func (t *TrainBtm) Scanning(aboveBalise bool, telegram *TrainBaliseTelegram) {
//新报文
isNewTbt := telegram != nil && (t.lastTelegram == nil || t.lastTelegram.Up != telegram.Up || t.lastTelegram.BaliseId != telegram.BaliseId)
if isNewTbt {
t.lastTelegram = telegram
}
//
if telegram == nil {
return
}
t.ScannedBalise = telegram
if isNewTbt {
t.scannedBalises <- telegram
t.baliseMessageCounterAdd1()
}
//
t.AboveBalise = aboveBalise
//BTM此时在一个新的应答器上方
if t.AboveBalise || isNewTbt {
t.baliseCounterAdd1()
//slog.Debug(fmt.Sprintf("列车经过应答器上方,应答器:[%s]", t.viaBaliseId))
}
}
var (
TrainPositionInfoType = ecs.NewComponentType[TrainPositionInfo]()

View File

@ -18,7 +18,7 @@ func NewTrainWithBtmEntity(w ecs.World, trainId string) *ecs.Entry {
te := w.Entry(w.Create(component.UidType, component.TrainPositionInfoType, component.TrainBtmType))
component.UidType.SetValue(te, component.Uid{Id: trainId})
component.TrainPositionInfoType.Set(te, &component.TrainPositionInfo{})
component.TrainBtmType.Set(te, &component.TrainBtm{})
component.TrainBtmType.Set(te, component.NewTrainBtm())
data.EntityMap[trainId] = te
return te
}

View File

@ -107,22 +107,21 @@ func TrainBalisePowerAmplifierSwitch(w ecs.World, turnOn bool) error {
return result.Err
}
// BaliseTelegramForSend 获取当前与CANET关联的列车的用于发送的应答器报文
// 会修改应答器报文状态为已发送
func BaliseTelegramForSend(w ecs.World) (*component.TrainBaliseTelegram, error) {
result := <-ecs.Request[*component.TrainBaliseTelegram](w, func() ecs.Result[*component.TrainBaliseTelegram] {
// GetScannedBaliseTelegram 获取扫描到的应答器报文
func GetScannedBaliseTelegram(w ecs.World) (<-chan *component.TrainBaliseTelegram, error) {
result := <-ecs.Request[<-chan *component.TrainBaliseTelegram](w, func() ecs.Result[<-chan *component.TrainBaliseTelegram] {
//获取当前关联CANET设备的列车
canetTrain := findCanetTrain(w)
if canetTrain == nil {
return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体"))
return ecs.NewResult[<-chan *component.TrainBaliseTelegram](nil, fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体"))
}
//
train := component.TrainBtmType.Get(canetTrain)
tbt := train.SetBaliseTelegramHadSentAndGet()
tbt := train.FindScannedBalises()
if tbt != nil {
return ecs.NewOkResult(tbt)
} else {
return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("此刻没有要发送的应答器报文"))
return ecs.NewResult[<-chan *component.TrainBaliseTelegram](nil, fmt.Errorf("此刻没有要发送的应答器报文"))
}
})
return result.Val, result.Err

View File

@ -38,17 +38,17 @@ func (s *BaliseDetectSystem) DetectBalise(w ecs.World, trainEntry *ecs.Entry, la
}
for _, detectedBalise := range tt {
//列车应答器天线扫描到应答器,获取应答器报文发送给BTM
tbt := s.findBaliseTelegram(wd, detectedBalise)
tbt := s.findBaliseTelegram(wd, r.up, detectedBalise)
if tbt != nil {
tbts = append(tbts, tbt)
}
}
}
if len(tbts) <= 0 {
btm.Scanning(aboveBalise, "", nil)
btm.Scanning(aboveBalise, nil)
} else {
for _, tbt := range tbts {
btm.Scanning(true, tbt.BaliseId, tbt)
btm.Scanning(true, tbt)
}
}
}
@ -121,7 +121,7 @@ func (s *BaliseDetectSystem) headMoveRanges(wd *component.WorldData, last *Train
}
// 获取应答器激活的有效报文
func (s *BaliseDetectSystem) findBaliseTelegram(wd *component.WorldData, detectedBalise *repository.Transponder) *component.TrainBaliseTelegram {
func (s *BaliseDetectSystem) findBaliseTelegram(wd *component.WorldData, up bool, detectedBalise *repository.Transponder) *component.TrainBaliseTelegram {
if detectedBalise == nil {
return nil
}
@ -133,7 +133,7 @@ func (s *BaliseDetectSystem) findBaliseTelegram(wd *component.WorldData, detecte
baliseState.ValidTelegram = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
//
if len(baliseState.ValidTelegram) > 0 {
return component.NewTrainBaliseTelegram(detectedBalise.Id(), baliseState.ValidTelegram)
return component.NewTrainBaliseTelegram(up, detectedBalise.Id(), baliseState.ValidTelegram)
}
} else {
slog.Warn(fmt.Sprintf("应答器[%s]实体不存在", detectedBalise.Id()))