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

158 lines
5.6 KiB
Go
Raw Normal View History

package memory
import (
"fmt"
2024-01-10 11:17:32 +08:00
"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"
2024-01-10 11:17:32 +08:00
"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_proto.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_proto.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))
}
2024-01-10 11:17:32 +08:00
component.LinkPositionType.SetValue(te, component_data.LinkPosition{
LinkId: req.LinkId,
Offset: req.Offset,
})
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
}