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

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)) te := w.Entry(w.Create(component.UidType, component.TrainPositionInfoType, component.TrainBtmType))
component.UidType.SetValue(te, component.Uid{Id: trainId}) component.UidType.SetValue(te, component.Uid{Id: trainId})
component.TrainPositionInfoType.Set(te, &component.TrainPositionInfo{}) component.TrainPositionInfoType.Set(te, &component.TrainPositionInfo{})
component.TrainBtmType.Set(te, &component.TrainBtm{}) component.TrainBtmType.Set(te, component.NewTrainBtm())
data.EntityMap[trainId] = te data.EntityMap[trainId] = te
return te return te
} }

View File

@ -107,22 +107,21 @@ func TrainBalisePowerAmplifierSwitch(w ecs.World, turnOn bool) error {
return result.Err return result.Err
} }
// BaliseTelegramForSend 获取当前与CANET关联的列车的用于发送的应答器报文 // GetScannedBaliseTelegram 获取扫描到的应答器报文
// 会修改应答器报文状态为已发送 func GetScannedBaliseTelegram(w ecs.World) (<-chan *component.TrainBaliseTelegram, error) {
func BaliseTelegramForSend(w ecs.World) (*component.TrainBaliseTelegram, error) { result := <-ecs.Request[<-chan *component.TrainBaliseTelegram](w, func() ecs.Result[<-chan *component.TrainBaliseTelegram] {
result := <-ecs.Request[*component.TrainBaliseTelegram](w, func() ecs.Result[*component.TrainBaliseTelegram] {
//获取当前关联CANET设备的列车 //获取当前关联CANET设备的列车
canetTrain := findCanetTrain(w) canetTrain := findCanetTrain(w)
if canetTrain == nil { 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) train := component.TrainBtmType.Get(canetTrain)
tbt := train.SetBaliseTelegramHadSentAndGet() tbt := train.FindScannedBalises()
if tbt != nil { if tbt != nil {
return ecs.NewOkResult(tbt) return ecs.NewOkResult(tbt)
} else { } else {
return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("此刻没有要发送的应答器报文")) return ecs.NewResult[<-chan *component.TrainBaliseTelegram](nil, fmt.Errorf("此刻没有要发送的应答器报文"))
} }
}) })
return result.Val, result.Err 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 { for _, detectedBalise := range tt {
//列车应答器天线扫描到应答器,获取应答器报文发送给BTM //列车应答器天线扫描到应答器,获取应答器报文发送给BTM
tbt := s.findBaliseTelegram(wd, detectedBalise) tbt := s.findBaliseTelegram(wd, r.up, detectedBalise)
if tbt != nil { if tbt != nil {
tbts = append(tbts, tbt) tbts = append(tbts, tbt)
} }
} }
} }
if len(tbts) <= 0 { if len(tbts) <= 0 {
btm.Scanning(aboveBalise, "", nil) btm.Scanning(aboveBalise, nil)
} else { } else {
for _, tbt := range tbts { 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 { if detectedBalise == nil {
return 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} baliseState.ValidTelegram = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
// //
if len(baliseState.ValidTelegram) > 0 { if len(baliseState.ValidTelegram) > 0 {
return component.NewTrainBaliseTelegram(detectedBalise.Id(), baliseState.ValidTelegram) return component.NewTrainBaliseTelegram(up, detectedBalise.Id(), baliseState.ValidTelegram)
} }
} else { } else {
slog.Warn(fmt.Sprintf("应答器[%s]实体不存在", detectedBalise.Id())) slog.Warn(fmt.Sprintf("应答器[%s]实体不存在", detectedBalise.Id()))