2023-11-09 14:59:18 +08:00
|
|
|
|
package fi
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"joylink.club/ecs"
|
2023-11-24 15:20:04 +08:00
|
|
|
|
"joylink.club/ecs/filter"
|
2023-11-09 14:59:18 +08:00
|
|
|
|
"joylink.club/rtsssimulation/component"
|
|
|
|
|
"joylink.club/rtsssimulation/entity"
|
2023-11-28 13:30:04 +08:00
|
|
|
|
"joylink.club/rtsssimulation/sys/device_sys"
|
2023-11-09 14:59:18 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// AddTrainToWorld 添加列车
|
|
|
|
|
func AddTrainToWorld(w ecs.World, trainId string) error {
|
|
|
|
|
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
|
|
|
|
|
wd := entity.GetWorldData(w)
|
|
|
|
|
_, find := wd.EntityMap[trainId]
|
|
|
|
|
if !find {
|
2023-11-23 15:12:16 +08:00
|
|
|
|
entity.NewTrainWithBtmEntity(w, trainId)
|
2023-11-09 14:59:18 +08:00
|
|
|
|
}
|
|
|
|
|
return ecs.NewOkEmptyResult()
|
|
|
|
|
})
|
|
|
|
|
return result.Err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoveTrainFromWorld 移除列车
|
|
|
|
|
func RemoveTrainFromWorld(w ecs.World, trainId string) error {
|
|
|
|
|
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
|
|
|
|
|
wd := entity.GetWorldData(w)
|
|
|
|
|
te, find := wd.EntityMap[trainId]
|
|
|
|
|
if find {
|
|
|
|
|
te.Remove()
|
|
|
|
|
delete(wd.EntityMap, trainId)
|
|
|
|
|
}
|
|
|
|
|
return ecs.NewOkEmptyResult()
|
|
|
|
|
})
|
|
|
|
|
return result.Err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 16:03:33 +08:00
|
|
|
|
// UpdateTrainPositionFromDynamics 更新列车所在的物理区段
|
|
|
|
|
func UpdateTrainPositionFromDynamics(w ecs.World, tpi TrainPositionInfo) error {
|
2023-11-09 14:59:18 +08:00
|
|
|
|
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
|
|
|
|
|
wd := entity.GetWorldData(w)
|
2023-11-10 16:03:33 +08:00
|
|
|
|
te, find := wd.EntityMap[tpi.TrainId]
|
2023-11-09 14:59:18 +08:00
|
|
|
|
if find {
|
2023-11-10 16:03:33 +08:00
|
|
|
|
train := component.TrainPositionInfoType.Get(te)
|
2023-11-28 16:05:41 +08:00
|
|
|
|
//
|
|
|
|
|
lastTrainHeadPos := &device_sys.TrainHeadPosition{Up: train.Up, HeadLink: train.HeadLink, HeadLinkOffset: train.HeadLinkOffset}
|
|
|
|
|
//
|
2023-11-10 16:03:33 +08:00
|
|
|
|
train.Up = tpi.Up
|
|
|
|
|
train.Len = int64(tpi.Len)
|
|
|
|
|
train.HeadLink = tpi.HeadLink
|
2023-11-13 13:53:46 +08:00
|
|
|
|
train.HeadLinkOffset = int64(tpi.HeadLinkOffset)
|
2023-11-10 16:03:33 +08:00
|
|
|
|
train.TailLink = tpi.TailLink
|
2023-11-13 13:53:46 +08:00
|
|
|
|
train.TailLinkOffset = int64(tpi.TailLinkOffset)
|
2023-11-28 16:05:41 +08:00
|
|
|
|
//列车车头移动范围
|
|
|
|
|
curTrainHeadPos := &device_sys.TrainHeadPosition{Up: train.Up, HeadLink: train.HeadLink, HeadLinkOffset: train.HeadLinkOffset}
|
2023-11-28 13:30:04 +08:00
|
|
|
|
//根据列车位置探测应答器
|
2023-11-28 16:05:41 +08:00
|
|
|
|
device_sys.NewBaliseDetection().DetectBalise(w, te, lastTrainHeadPos, curTrainHeadPos)
|
2023-11-28 13:30:04 +08:00
|
|
|
|
//
|
2023-11-09 14:59:18 +08:00
|
|
|
|
return ecs.NewOkEmptyResult()
|
|
|
|
|
} else {
|
2023-11-10 16:03:33 +08:00
|
|
|
|
return ecs.NewErrResult(fmt.Errorf("列车[%s]实体不存在", tpi.TrainId))
|
2023-11-09 14:59:18 +08:00
|
|
|
|
}
|
2023-11-10 10:39:41 +08:00
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
return result.Err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-24 15:20:04 +08:00
|
|
|
|
// FindTrainBaliseBtmStatus 获取车载BTM的相关状态信息
|
|
|
|
|
func FindTrainBaliseBtmStatus(w ecs.World) (*TrainBtmStatus, error) {
|
|
|
|
|
result := <-ecs.Request[*TrainBtmStatus](w, func() ecs.Result[*TrainBtmStatus] {
|
|
|
|
|
//获取当前关联CANET设备的列车
|
|
|
|
|
canetTrain := findCanetTrain(w)
|
|
|
|
|
if canetTrain == nil {
|
|
|
|
|
return ecs.NewResult[*TrainBtmStatus](nil, fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体"))
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
trainId := component.UidType.Get(canetTrain).Id
|
|
|
|
|
btm := component.TrainBtmType.Get(canetTrain)
|
|
|
|
|
btmStatus := &TrainBtmStatus{
|
|
|
|
|
TrainId: trainId,
|
|
|
|
|
PowerAmplifierOn: btm.PowerAmplifierSwitch,
|
|
|
|
|
PowerAmplifierFault: false,
|
|
|
|
|
AboveBalise: btm.AboveBalise,
|
|
|
|
|
AntennaFault: false,
|
|
|
|
|
BaliseCounter: btm.BaliseCounter,
|
|
|
|
|
MessageCounter: btm.MessageCounter,
|
|
|
|
|
}
|
|
|
|
|
return ecs.NewOkResult(btmStatus)
|
|
|
|
|
})
|
|
|
|
|
return result.Val, result.Err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 16:30:39 +08:00
|
|
|
|
// TrainBalisePowerAmplifierSwitch 车载应答器天线功率放大器开关控制
|
2023-11-24 15:20:04 +08:00
|
|
|
|
func TrainBalisePowerAmplifierSwitch(w ecs.World, turnOn bool) error {
|
2023-11-23 16:30:39 +08:00
|
|
|
|
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
|
2023-11-24 15:20:04 +08:00
|
|
|
|
//获取当前关联CANET设备的列车
|
|
|
|
|
canetTrain := findCanetTrain(w)
|
|
|
|
|
if canetTrain == nil {
|
|
|
|
|
return ecs.NewErrResult(fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体"))
|
2023-11-23 16:30:39 +08:00
|
|
|
|
}
|
2023-11-24 15:20:04 +08:00
|
|
|
|
//
|
|
|
|
|
train := component.TrainBtmType.Get(canetTrain)
|
|
|
|
|
train.PowerAmplifierSwitch = turnOn
|
|
|
|
|
return ecs.NewOkEmptyResult()
|
2023-11-23 16:30:39 +08:00
|
|
|
|
})
|
|
|
|
|
return result.Err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-29 13:03:59 +08:00
|
|
|
|
// GetScannedBaliseTelegram 获取扫描到的应答器报文
|
2023-11-29 17:28:33 +08:00
|
|
|
|
func GetScannedBaliseTelegram(w ecs.World) (*component.TrainBaliseTelegram, error) {
|
|
|
|
|
result := <-ecs.Request[*component.TrainBaliseTelegram](w, func() ecs.Result[*component.TrainBaliseTelegram] {
|
2023-11-24 15:20:04 +08:00
|
|
|
|
//获取当前关联CANET设备的列车
|
|
|
|
|
canetTrain := findCanetTrain(w)
|
|
|
|
|
if canetTrain == nil {
|
2023-11-29 17:28:33 +08:00
|
|
|
|
return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体"))
|
2023-11-24 15:20:04 +08:00
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
train := component.TrainBtmType.Get(canetTrain)
|
2023-11-29 13:03:59 +08:00
|
|
|
|
tbt := train.FindScannedBalises()
|
2023-11-24 15:20:04 +08:00
|
|
|
|
if tbt != nil {
|
|
|
|
|
return ecs.NewOkResult(tbt)
|
2023-11-23 16:30:39 +08:00
|
|
|
|
} else {
|
2023-11-29 17:28:33 +08:00
|
|
|
|
return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("此刻没有要发送的应答器报文"))
|
2023-11-23 16:30:39 +08:00
|
|
|
|
}
|
|
|
|
|
})
|
2023-11-24 15:20:04 +08:00
|
|
|
|
return result.Val, result.Err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var trainQuery = ecs.NewQuery(filter.Contains(component.UidType, component.TrainPositionInfoType, component.TrainBtmType))
|
|
|
|
|
|
|
|
|
|
// 获取当前关联CANET设备的列车
|
|
|
|
|
func findCanetTrain(w ecs.World) *ecs.Entry {
|
|
|
|
|
var canetTrain *ecs.Entry = nil
|
|
|
|
|
trainQuery.Each(w, func(entry *ecs.Entry) { //目前默认取第一辆
|
|
|
|
|
if canetTrain == nil {
|
|
|
|
|
canetTrain = entry
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return canetTrain
|
2023-11-23 16:30:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// /////////////////////////////////////////////////////////////////////////////////////////
|
2023-11-24 15:20:04 +08:00
|
|
|
|
|
|
|
|
|
type TrainBtmStatus struct {
|
|
|
|
|
TrainId string
|
2023-11-23 16:30:39 +08:00
|
|
|
|
PowerAmplifierOn bool //BTM功率放大器是否开启
|
|
|
|
|
PowerAmplifierFault bool //BTM功率放大器是否有故障
|
|
|
|
|
AntennaFault bool //BTM应答器天线是否有故障
|
|
|
|
|
AboveBalise bool //BTM当前是否在应答器上方
|
2023-11-24 15:20:04 +08:00
|
|
|
|
BaliseCounter int //应答器计数(每过一个应答器加一,在同一个应答器内不变)
|
|
|
|
|
MessageCounter int //报文计数器(每解出一个应答器报文加一)
|
2023-11-23 16:30:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 10:39:41 +08:00
|
|
|
|
type TrainPositionInfo struct {
|
|
|
|
|
//列车id
|
|
|
|
|
TrainId string
|
|
|
|
|
//列车头当前运行方向(true偏移量增大/false减小方向)
|
|
|
|
|
Up bool
|
|
|
|
|
//列车长度 mm
|
|
|
|
|
Len uint32
|
|
|
|
|
//列车所在轨道link
|
2023-11-10 10:50:09 +08:00
|
|
|
|
HeadLink string
|
2023-11-10 10:39:41 +08:00
|
|
|
|
//列车所在link偏移量(mm)
|
|
|
|
|
HeadLinkOffset uint32
|
|
|
|
|
//列车所在轨道link
|
2023-11-10 10:50:09 +08:00
|
|
|
|
TailLink string
|
2023-11-10 10:39:41 +08:00
|
|
|
|
//列车所在link偏移量(mm)
|
|
|
|
|
TailLinkOffset uint32
|
|
|
|
|
}
|