155 lines
5.5 KiB
Go
155 lines
5.5 KiB
Go
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
|
||
}
|