178 lines
6.2 KiB
Go
178 lines
6.2 KiB
Go
package memory
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
|
||
"joylink.club/bj-rtsts-server/dto"
|
||
"joylink.club/bj-rtsts-server/dto/data_proto"
|
||
"joylink.club/bj-rtsts-server/sys_error"
|
||
"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) *sys_error.BusinessError {
|
||
uid := QueryMapUidMapByType(req.MapId, &data_proto.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 == data_proto.KilometerSystem_LEFT {
|
||
km.Direction = proto.Direction_LEFT
|
||
} else if req.Km.Direction == data_proto.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 >= maxKm.Value {
|
||
return sys_error.New(fmt.Sprintf("超出可设置范围(%d:%d)", minKm.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, &data_proto.Transponder{})[req.BaliseId].Uid
|
||
balise := simulation.Repo.FindTransponder(uid)
|
||
if balise == nil {
|
||
return sys_error.New(fmt.Sprintf("未找到[mapId:%d id:%d]的应答器", req.MapId, req.BaliseId))
|
||
}
|
||
return balisePositionReset(simulation, balise)
|
||
}
|
||
|
||
func balisePositionReset(simulation *VerifySimulation, balise *repository.Transponder) error {
|
||
entry, _ := entity.GetEntityByUid(simulation.World, balise.Id())
|
||
component.KmType.Set(entry, balise.Km())
|
||
component.LinkPositionType.SetValue(entry, component_data.LinkPosition{
|
||
LinkId: balise.LinkPosition().Link().Id(),
|
||
Offset: balise.LinkPosition().Offset(),
|
||
})
|
||
return nil
|
||
}
|
||
|
||
// BaliseTelegramModify 修改应答器报文
|
||
func BaliseTelegramModify(simulation *VerifySimulation, req *dto.BaliseModifyTelegramReqDto) error {
|
||
uid := QueryMapUidMapByType(req.MapId, &data_proto.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, &data_proto.Transponder{})[req.BaliseId].Uid
|
||
worldData := entity.GetWorldData(simulation.World)
|
||
balise := worldData.Repo.FindTransponder(uid)
|
||
if balise == nil {
|
||
return sys_error.New(fmt.Sprintf("未找到[mapId:%d id:%d]的应答器", req.MapId, req.BaliseId))
|
||
}
|
||
return baliseTelegramReset(simulation, balise)
|
||
}
|
||
|
||
func baliseTelegramReset(simulation *VerifySimulation, balise *repository.Transponder) error {
|
||
entry, _ := entity.GetEntityByUid(simulation.World, balise.Id())
|
||
component.BaliseStateType.SetValue(entry, component.BaliseState{
|
||
ValidTelegram: balise.FixedTelegram(),
|
||
})
|
||
return nil
|
||
}
|
||
|
||
// BaliseReset 重置应答器所有状态
|
||
func BaliseReset(simulation *VerifySimulation) error {
|
||
var errs []error
|
||
for _, balise := range simulation.Repo.ResponderList() {
|
||
err := baliseTelegramReset(simulation, balise)
|
||
if err != nil {
|
||
errs = append(errs, err)
|
||
}
|
||
err = balisePositionReset(simulation, balise)
|
||
if err != nil {
|
||
errs = append(errs, err)
|
||
}
|
||
}
|
||
if len(errs) > 0 {
|
||
var userMsg []string
|
||
for _, err := range errs {
|
||
be, ok := err.(*sys_error.BusinessError)
|
||
if ok {
|
||
userMsg = append(userMsg, be.UserMsg)
|
||
}
|
||
}
|
||
return sys_error.New(strings.Join(userMsg, "\n"))
|
||
}
|
||
return nil
|
||
}
|