package fi import ( "fmt" "joylink.club/ecs" "joylink.club/ecs/filter" "joylink.club/rtsssimulation/component" "joylink.club/rtsssimulation/entity" "joylink.club/rtsssimulation/sys/device_sys" ) // 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 { entity.NewTrainWithBtmEntity(w, trainId) } 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 } // UpdateTrainPositionFromDynamics 更新列车所在的物理区段 func UpdateTrainPositionFromDynamics(w ecs.World, tpi TrainPositionInfo) error { result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { wd := entity.GetWorldData(w) te, find := wd.EntityMap[tpi.TrainId] if find { train := component.TrainPositionInfoType.Get(te) // lastTrainHeadPos := &device_sys.TrainHeadPosition{Up: train.Up, HeadLink: train.HeadLink, HeadLinkOffset: train.HeadLinkOffset} // train.Up = tpi.Up train.Len = int64(tpi.Len) train.HeadLink = tpi.HeadLink train.HeadLinkOffset = int64(tpi.HeadLinkOffset) train.TailLink = tpi.TailLink train.TailLinkOffset = int64(tpi.TailLinkOffset) //列车车头移动范围 curTrainHeadPos := &device_sys.TrainHeadPosition{Up: train.Up, HeadLink: train.HeadLink, HeadLinkOffset: train.HeadLinkOffset} //根据列车位置探测应答器 device_sys.NewBaliseDetection().DetectBalise(w, te, lastTrainHeadPos, curTrainHeadPos) // return ecs.NewOkEmptyResult() } else { return ecs.NewErrResult(fmt.Errorf("列车[%s]实体不存在", tpi.TrainId)) } }) return result.Err } // 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 } // TrainBalisePowerAmplifierSwitch 车载应答器天线功率放大器开关控制 func TrainBalisePowerAmplifierSwitch(w ecs.World, turnOn bool) error { result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { //获取当前关联CANET设备的列车 canetTrain := findCanetTrain(w) if canetTrain == nil { return ecs.NewErrResult(fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体")) } // train := component.TrainBtmType.Get(canetTrain) train.PowerAmplifierSwitch = turnOn return ecs.NewOkEmptyResult() }) return result.Err } // GetScannedBaliseTelegram 获取扫描到的应答器报文 func GetScannedBaliseTelegram(w ecs.World) (*component.TrainBaliseTelegram, error) { result := <-ecs.Request[*component.TrainBaliseTelegram](w, func() ecs.Result[*component.TrainBaliseTelegram] { //获取当前关联CANET设备的列车 canetTrain := findCanetTrain(w) if canetTrain == nil { return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("系统中当前不存在与CANET设备关联的列车实体")) } // train := component.TrainBtmType.Get(canetTrain) tbt := train.FindScannedBalises() if tbt != nil { return ecs.NewOkResult(tbt) } else { return ecs.NewResult[*component.TrainBaliseTelegram](nil, fmt.Errorf("此刻没有要发送的应答器报文")) } }) 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 } // ///////////////////////////////////////////////////////////////////////////////////////// type TrainBtmStatus struct { TrainId string PowerAmplifierOn bool //BTM功率放大器是否开启 PowerAmplifierFault bool //BTM功率放大器是否有故障 AntennaFault bool //BTM应答器天线是否有故障 AboveBalise bool //BTM当前是否在应答器上方 BaliseCounter int //应答器计数(每过一个应答器加一,在同一个应答器内不变) MessageCounter int //报文计数器(每解出一个应答器报文加一) } type TrainPositionInfo struct { //列车id TrainId string //列车头当前运行方向(true偏移量增大/false减小方向) Up bool //列车长度 mm Len uint32 //列车所在轨道link HeadLink string //列车所在link偏移量(mm) HeadLinkOffset uint32 //列车所在轨道link TailLink string //列车所在link偏移量(mm) TailLinkOffset uint32 }