rts-sim-testing-service/ts/simulation/wayside/memory/wayside_memory_transponder.go

155 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package memory
import (
"fmt"
"joylink.club/bj-rtsts-server/dto"
"joylink.club/bj-rtsts-server/sys_error"
"joylink.club/bj-rtsts-server/ts/protos/graphicData"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/component/component_data"
"joylink.club/rtsssimulation/entity"
"joylink.club/rtsssimulation/repository"
"joylink.club/rtsssimulation/repository/model/proto"
"joylink.club/rtsssimulation/util/number"
"sort"
)
// BalisePositionModify 应答器移位
func BalisePositionModify(simulation *VerifySimulation, req *dto.BaliseMoveReqDto) error {
uid := QueryMapUidMapByType(req.MapId, &graphicData.Transponder{})[req.BaliseId].Uid
transponder := simulation.Repo.FindTransponder(uid)
if transponder == nil {
return sys_error.New(fmt.Sprintf("未找到[mapId:%d id:%d]的应答器", req.MapId, req.BaliseId))
}
//将请求参数中的公里标转为rtss仿真所用的公里标
km := &proto.Kilometer{
Value: req.Km.Kilometer,
CoordinateSystem: req.Km.CoordinateSystem,
}
if req.Km.Direction == graphicData.KilometerSystem_LEFT {
km.Direction = proto.Direction_LEFT
} else if req.Km.Direction == graphicData.KilometerSystem_RIGHT {
km.Direction = proto.Direction_RIGHT
} else {
panic(fmt.Sprintf("未知的公里标方向[%d]", req.Km.Direction))
}
//将应答器所在Link的两端公里标转为请求参数中公里标的坐标系
link := transponder.LinkPosition().Link()
akm, err := repository.ConvertKilometer(simulation.Repo, link.AKm(), km.CoordinateSystem)
if err != nil {
panic(sys_error.New("应答器所在Link的起点公里标转换失败"))
}
bkm, err := repository.ConvertKilometer(simulation.Repo, link.BKm(), km.CoordinateSystem)
if err != nil {
panic(sys_error.New("应答器所在Link的终点公里标转换失败"))
}
//筛选出Link上所有的应答器并按公里标大小排序
var transponders []*repository.Transponder
for _, device := range link.Devices() {
t, ok := device.(*repository.Transponder)
if ok {
transponders = append(transponders, t)
}
}
sort.Slice(transponders, func(i, j int) bool {
aT := transponders[i]
bT := transponders[j]
aTKm, err := repository.ConvertKilometer(simulation.Repo, aT.Km(), km.CoordinateSystem)
if err != nil {
panic(sys_error.New(fmt.Sprintf("应答器[id:%s]公里标转换失败", aT.Id())))
}
bTKm, err := repository.ConvertKilometer(simulation.Repo, bT.Km(), km.CoordinateSystem)
if err != nil {
panic(sys_error.New(fmt.Sprintf("应答器[id:%s]公里标转换失败", bT.Id())))
}
return aTKm.Value < bTKm.Value
})
//确保请求的公里标没有超出Link范围且在相邻的应答器之间
var minKm *proto.Kilometer
var maxKm *proto.Kilometer
if akm.Value < bkm.Value {
minKm = akm
maxKm = bkm
} else {
minKm = bkm
maxKm = akm
}
for i, t := range transponders {
if t == transponder {
if i > 0 {
minKm, err = repository.ConvertKilometer(simulation.Repo, transponders[i-1].Km(), km.CoordinateSystem)
}
if i < len(transponders)-1 {
maxKm, err = repository.ConvertKilometer(simulation.Repo, transponders[i+1].Km(), km.CoordinateSystem)
}
}
}
//更新应答器公里标和Link位置
entry, _ := entity.GetEntityByUid(simulation.World, uid)
if km.Value < minKm.Value {
km.Value = minKm.Value
} else if km.Value > maxKm.Value {
km.Value = maxKm.Value
}
component.KmType.Set(entry, km)
offset := number.Abs(km.Value - akm.Value)
component.LinkPositionType.Set(entry, &component_data.LinkPosition{
LinkId: link.Id(),
Offset: offset,
})
return nil
}
// BalisePositionReset 应答器复位
func BalisePositionReset(simulation *VerifySimulation, req *dto.BaliseReqDto) error {
uid := QueryMapUidMapByType(req.MapId, &graphicData.Transponder{})[req.BaliseId].Uid
transponder := simulation.Repo.FindTransponder(uid)
if transponder == nil {
return sys_error.New(fmt.Sprintf("未找到[mapId:%d id:%d]的应答器", req.MapId, req.BaliseId))
}
entry, _ := entity.GetEntityByUid(simulation.World, uid)
component.KmType.Set(entry, transponder.Km())
component.LinkPositionType.SetValue(entry, component_data.LinkPosition{
LinkId: transponder.LinkPosition().Link().Id(),
Offset: transponder.LinkPosition().Offset(),
})
return nil
}
// BaliseTelegramModify 修改应答器报文
func BaliseTelegramModify(simulation *VerifySimulation, req *dto.BaliseModifyTelegramReqDto) error {
uid := QueryMapUidMapByType(req.MapId, &graphicData.Transponder{})[req.BaliseId].Uid
entry, ok := entity.GetEntityByUid(simulation.World, uid)
if !ok {
return sys_error.New(fmt.Sprintf("没有[mapId:%d id:%d]的应答器", req.MapId, req.BaliseId))
}
component.BaliseStateType.SetValue(entry, component.BaliseState{ValidTelegram: req.Telegram})
return nil
}
// BaliseTelegramReset 重置应答器报文
func BaliseTelegramReset(simulation *VerifySimulation, req *dto.BaliseReqDto) error {
uid := QueryMapUidMapByType(req.MapId, &graphicData.Transponder{})[req.BaliseId].Uid
entry, ok := entity.GetEntityByUid(simulation.World, uid)
if !ok {
return sys_error.New(fmt.Sprintf("没有[mapId:%d id:%d]的应答器", req.MapId, req.BaliseId))
}
worldData := entity.GetWorldData(simulation.World)
transponder := worldData.Repo.FindTransponder(uid)
component.BaliseStateType.SetValue(entry, component.BaliseState{
ValidTelegram: transponder.FixedTelegram(),
})
return nil
}
// BaliseReset 重置应答器所有状态
func BaliseReset(simulation *VerifySimulation, req *dto.BaliseReqDto) error {
err := BaliseTelegramReset(simulation, req)
if err != nil {
return err
}
err = BalisePositionReset(simulation, req)
return err
}