15bdc45892
All checks were successful
local-test分支打包构建docker并发布运行 / Docker-Build (push) Successful in 2m58s
1750 lines
54 KiB
Go
1750 lines
54 KiB
Go
package memory
|
||
|
||
import (
|
||
"encoding/hex"
|
||
"encoding/json"
|
||
"fmt"
|
||
"joylink.club/bj-rtsts-server/config"
|
||
"joylink.club/bj-rtsts-server/dto"
|
||
"joylink.club/bj-rtsts-server/dto/data_proto"
|
||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||
"joylink.club/bj-rtsts-server/sys_error"
|
||
"joylink.club/bj-rtsts-server/third_party/acc"
|
||
"joylink.club/bj-rtsts-server/third_party/electrical_machinery"
|
||
"joylink.club/bj-rtsts-server/third_party/message"
|
||
"joylink.club/bj-rtsts-server/third_party/radar"
|
||
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
||
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
||
"joylink.club/ecs"
|
||
"joylink.club/rtsssimulation/component"
|
||
"joylink.club/rtsssimulation/entity"
|
||
"joylink.club/rtsssimulation/fi"
|
||
"joylink.club/rtsssimulation/repository"
|
||
"joylink.club/rtsssimulation/repository/model/proto"
|
||
"log/slog"
|
||
"math"
|
||
"sort"
|
||
"strconv"
|
||
"strings"
|
||
"sync"
|
||
)
|
||
|
||
// 轨旁仿真定义
|
||
type VerifySimulation struct {
|
||
//地图id
|
||
MapIds []int32
|
||
// 项目ID
|
||
ProjectId int32
|
||
//仿真id
|
||
SimulationId string
|
||
//仿真内存数据
|
||
Memory *WaysideMemory
|
||
//模型仓库
|
||
Repo *repository.Repository
|
||
//Rtss仿真世界的
|
||
World ecs.World
|
||
//设备UID映射 key-uid
|
||
UidMap map[string]*DeviceRelationship
|
||
// 运行环境配置
|
||
runConfig *config.ThirdPartyConfig
|
||
//运行线路code
|
||
ProjectCode string
|
||
}
|
||
|
||
// 轨旁仿真内存模型
|
||
type WaysideMemory struct {
|
||
//可变状态数据:轨旁仿真模型状态(全量数据)
|
||
Status *VerifyStatus
|
||
// 要变更的状态:用户操作过的状态记录在这里,增量推送次数据
|
||
ChangeStatus *ChangeVerifyStatus
|
||
//状态保护锁
|
||
rwLock *sync.RWMutex
|
||
}
|
||
|
||
// 轨旁仿真模型状态
|
||
type VerifyStatus struct {
|
||
//道岔状态,key为道岔id即索引 state_proto.SwitchState
|
||
SwitchStateMap sync.Map
|
||
//轨道状态,key为轨道id即索引 state_proto.LinkState
|
||
LinkStateMap sync.Map
|
||
//列车状态,key为列车id即索引 state_proto.TrainState
|
||
TrainStateMap sync.Map
|
||
//计轴区段状态,key为计轴区段的id即索引 state_proto.SectionState
|
||
AxleSectionStateMap sync.Map
|
||
//物理区段状态,key为物理区段id即索引 state_proto.SectionState
|
||
PhysicalSectionStateMap sync.Map
|
||
//逻辑区段状态,key为逻辑区段id即索引 state_proto.SectionState
|
||
LogicSectionStateMap sync.Map
|
||
//信号机状态,key为信号机id,即索引 state_proto.SignalState
|
||
SignalStateMap sync.Map
|
||
}
|
||
|
||
// 轨旁仿真模型状态(变更)
|
||
type ChangeVerifyStatus struct {
|
||
VerifyStatus
|
||
//删除的列车ID列表
|
||
RemoveTrainId []string
|
||
}
|
||
|
||
func NewWaysideMemory() *WaysideMemory {
|
||
return &WaysideMemory{
|
||
Status: &VerifyStatus{},
|
||
ChangeStatus: &ChangeVerifyStatus{},
|
||
rwLock: &sync.RWMutex{},
|
||
}
|
||
}
|
||
|
||
// 创建仿真对象
|
||
func CreateSimulation(projectId int32, mapIds []int32, runConfig *dto.ProjectRunConfigDto) (*VerifySimulation, error) {
|
||
// 地图信息
|
||
sort.Slice(mapIds, func(i, j int) bool {
|
||
return QueryGiType(mapIds[i]) < QueryGiType(mapIds[j])
|
||
})
|
||
verifySimulation := &VerifySimulation{
|
||
ProjectId: projectId,
|
||
MapIds: mapIds,
|
||
}
|
||
// 设置运行环境
|
||
err := verifySimulation.initRunConfig(runConfig)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
// 构建Repository
|
||
err = verifySimulation.initRepository()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return verifySimulation, nil
|
||
}
|
||
|
||
// 获取仿真世界信息
|
||
func (s *VerifySimulation) GetComIdByUid(uid string) uint32 {
|
||
es := s.UidMap
|
||
if es == nil {
|
||
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: "无映射信息"})
|
||
}
|
||
if es[uid] == nil {
|
||
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: "无【uid】映射信息"})
|
||
}
|
||
return es[uid].CommonId
|
||
}
|
||
|
||
func (s *VerifySimulation) GetRunConfig() config.ThirdPartyConfig {
|
||
if s.runConfig == nil {
|
||
return config.ThirdPartyConfig{}
|
||
}
|
||
return *s.runConfig
|
||
}
|
||
|
||
// GetBtmCanetConfig 获取CANET配置信息
|
||
func (s *VerifySimulation) GetBtmCanetConfig() config.BtmCanetConfig {
|
||
return s.runConfig.BtmCanet
|
||
}
|
||
|
||
func (s *VerifySimulation) GetAllTrain() []*state_proto.TrainState {
|
||
return s.collectorAllTrain()
|
||
}
|
||
|
||
func (s *VerifySimulation) collectorAllTrain() []*state_proto.TrainState {
|
||
allTrain := make([]*state_proto.TrainState, 0)
|
||
s.Memory.Status.TrainStateMap.Range(func(k, v any) bool {
|
||
train := v.(*state_proto.TrainState)
|
||
if train.Show {
|
||
allTrain = append(allTrain, train)
|
||
}
|
||
return true
|
||
})
|
||
return allTrain
|
||
}
|
||
|
||
func (s *VerifySimulation) GetConnVobcTrain() *state_proto.TrainState {
|
||
return s.FindConnTrain(state_proto.TrainConnState_VOBC)
|
||
}
|
||
|
||
// GetBtmVobcConfig 获取11 号线 btm vobc配置信息
|
||
func (s *VerifySimulation) GetBtmVobcConfig() config.BtmVobcConfig {
|
||
return s.runConfig.BtmVobc
|
||
}
|
||
|
||
// GetSectionCodePoints 获取集中站的区段码表
|
||
func (s *VerifySimulation) GetSectionCodePoints(city string, lineId string, centralizedStation string) []*proto.CiSectionCodePoint {
|
||
stationUid := BuildUid(city, lineId, centralizedStation)
|
||
ref := s.Repo.GetCentralizedStationRef(stationUid)
|
||
if ref == nil {
|
||
return nil
|
||
}
|
||
//
|
||
return ref.SectionCodePoints
|
||
}
|
||
|
||
// CollectSectionStatus 收集仿真中计轴区段状态
|
||
func (s *VerifySimulation) CollectSectionStatus(city string, lineId string, centralizedStation string) ([]*message.SectionStatusMsg, error) {
|
||
stationUid := BuildUid(city, lineId, centralizedStation)
|
||
//
|
||
codePoints := s.GetSectionCodePoints(city, lineId, centralizedStation)
|
||
if len(codePoints) <= 0 {
|
||
return nil, fmt.Errorf("没有找到GetCentralizedStationRef[%s]的区段码表为空", stationUid)
|
||
}
|
||
//slog.Debug("收集计轴区段状态", "区段码表len", len(codePoints))
|
||
//
|
||
var msg []*message.SectionStatusMsg
|
||
var axleSectionIds []string
|
||
for _, section := range codePoints {
|
||
axleSectionIds = append(axleSectionIds, section.SectionId)
|
||
}
|
||
//
|
||
//slog.Debug("收集计轴区段状态", "计轴区段len", len(axleSectionIds), "axleSectionIds", axleSectionIds)
|
||
as, e := fi.FindPhysicalSectionsStatus(s.World, axleSectionIds)
|
||
if e != nil { //从仿真中收集计轴区段状态的失败列表
|
||
return nil, e
|
||
}
|
||
//slog.Debug("收集计轴区段状态", "仿真中计轴状态len", len(as))
|
||
//
|
||
stateMap := make(map[string]*fi.PhysicalSectionState)
|
||
for _, a := range as {
|
||
stateMap[a.Id] = a
|
||
}
|
||
//
|
||
sort.SliceStable(codePoints, func(i, j int) bool {
|
||
return codePoints[i].Row < codePoints[j].Row
|
||
})
|
||
//
|
||
for _, codePoint := range codePoints {
|
||
sectionState, find := stateMap[codePoint.SectionId]
|
||
if find {
|
||
state_proto := &message.SectionStatusMsg{}
|
||
state_proto.Rac = sectionState.Rac
|
||
state_proto.Rjt = sectionState.Rjt
|
||
state_proto.Rjo = sectionState.Rjo
|
||
state_proto.Occ = sectionState.Occ
|
||
state_proto.Clr = sectionState.Clr
|
||
msg = append(msg, state_proto)
|
||
} else {
|
||
return nil, fmt.Errorf("仿真中没有对应区段[%s]的状态", codePoint.SectionId)
|
||
}
|
||
}
|
||
//
|
||
//slog.Debug("收集计轴区段状态", "区段计轴msgLen", len(msg))
|
||
return msg, nil
|
||
}
|
||
|
||
// 采集动力学道岔状态
|
||
func (s *VerifySimulation) CollectDynamicsTurnoutInfo() *message.DynamicsTurnoutInfo {
|
||
turnoutState := &message.DynamicsTurnoutInfo{}
|
||
for _, turnout := range s.Repo.TurnoutList() {
|
||
sta := s.UidMap[turnout.Id()]
|
||
if sta == nil {
|
||
continue
|
||
}
|
||
entry, ok := entity.GetEntityByUid(s.World, turnout.Id())
|
||
if !ok {
|
||
slog.Warn(fmt.Sprintf("id=%s的道岔不存在", turnout.Id()))
|
||
return nil
|
||
}
|
||
if !entry.HasComponent(component.TurnoutPositionType) {
|
||
return nil
|
||
}
|
||
pos := component.TurnoutPositionType.Get(entry)
|
||
turnoutState.TurnoutInfos = append(turnoutState.TurnoutInfos, &message.TurnoutInfo{
|
||
Code: uint16(sta.CommonId),
|
||
NPosition: pos.Dw,
|
||
RPosition: pos.Fw,
|
||
})
|
||
}
|
||
return turnoutState
|
||
}
|
||
|
||
// 处理动力学列车速度消息
|
||
func (s *VerifySimulation) HandleDynamicsTrainInfo(info *message.DynamicsTrainInfo) {
|
||
trainId := strconv.Itoa(int(info.Number))
|
||
t, ok := s.Memory.Status.TrainStateMap.Load(trainId)
|
||
if !ok {
|
||
return
|
||
}
|
||
train := t.(*state_proto.TrainState)
|
||
// 更新列车状态
|
||
trainState := UpdateTrainStateByDynamics(s, trainId, info)
|
||
vs := train.VobcState
|
||
if train.ConnState.Conn && train.ConnState.ConnType == state_proto.TrainConnState_VOBC {
|
||
semi_physical_train.Default().SendTrainControlMessage(info)
|
||
electrical_machinery.Default().SendElectricMachineryMessage2(info, trainState)
|
||
radar.Default().TrainSpeedSender(info, trainState)
|
||
acc.Default().TrainAccSender(info, trainState)
|
||
}
|
||
if vs.Ato {
|
||
|
||
if train.TrainPort == state_proto.TrainState_PORT_NONE {
|
||
slog.Info("")
|
||
return
|
||
}
|
||
trainAtoControlTractionAndBrake(train)
|
||
var msgs []message.TrainPcSimBaseMessage
|
||
if vs.AtoOpenRightDoor || vs.AtoOpenLeftDoor {
|
||
btn := train.Tcc.Buttons[KZM]
|
||
if vs.AtoOpenRightDoor {
|
||
btn = train.Tcc.Buttons[KYM]
|
||
}
|
||
msgs = controlDoorOpenBtn(train.VobcState, true, btn, vs.AtoOpenLeftDoor, false)
|
||
} else if vs.AtoCloseRightDoor || vs.AtoCloseLeftDoor {
|
||
btn := train.Tcc.Buttons[GZM]
|
||
if vs.AtoCloseRightDoor {
|
||
btn = train.Tcc.Buttons[GYM]
|
||
}
|
||
msgs = controlDoorCloseBtn(train.VobcState, true, btn, vs.AtoOpenLeftDoor, false)
|
||
}
|
||
train_pc_sim.Default().SendTrainControlMsg2(train, msgs, train.TrainPort)
|
||
} else if vs.TractionStatus {
|
||
f := trainTractionPower(train.TrainLoad, train.Tcc.PushHandler.Val, trainState.DynamicState.Speed, train.TrainMaxAcc, train.TrainMaxSpeed)
|
||
vs.TractionForce = f / 1000 * 100
|
||
}
|
||
|
||
}
|
||
|
||
// 获取动力学配置信息
|
||
func (s *VerifySimulation) GetDynamicsRunConfig() *config.DynamicsConfig {
|
||
return &s.runConfig.Dynamics
|
||
}
|
||
|
||
func (s *VerifySimulation) GetCidcModbusConfig() []config.CidcModbusConfig {
|
||
return s.runConfig.CidcModbus
|
||
}
|
||
|
||
// 获取动力学运行资源
|
||
func (s *VerifySimulation) GetDynamicsRunRepository() *message.LineBaseInfo {
|
||
info := &message.LineBaseInfo{}
|
||
for _, model := range s.Repo.LinkList() {
|
||
id, _ := strconv.Atoi(model.Id())
|
||
link := &message.Link{
|
||
ID: int32(id),
|
||
Len: int32(model.Length()),
|
||
}
|
||
info.LinkList = append(info.LinkList, link)
|
||
if model.ARelation() != nil {
|
||
turnoutId := s.GetComIdByUid(model.ARelation().Device().Id())
|
||
link.ARelTurnoutId = int32(turnoutId)
|
||
switch model.ARelation().Port() {
|
||
case proto.Port_A:
|
||
link.ARelTurnoutPoint = "A"
|
||
case proto.Port_B:
|
||
link.ARelTurnoutPoint = "B"
|
||
case proto.Port_C:
|
||
link.ARelTurnoutPoint = "C"
|
||
}
|
||
}
|
||
if model.BRelation() != nil {
|
||
turnoutId := s.GetComIdByUid(model.BRelation().Device().Id())
|
||
link.BRelTurnoutId = int32(turnoutId)
|
||
switch model.BRelation().Port() {
|
||
case proto.Port_A:
|
||
link.BRelTurnoutPoint = "A"
|
||
case proto.Port_B:
|
||
link.BRelTurnoutPoint = "B"
|
||
case proto.Port_C:
|
||
link.BRelTurnoutPoint = "C"
|
||
}
|
||
}
|
||
}
|
||
for _, model := range s.Repo.SlopeList() {
|
||
id := s.GetComIdByUid(model.Id())
|
||
slope := &message.Slope{
|
||
ID: int32(id),
|
||
StartLinkOffset: int32(model.StartLinkPosition().Offset()),
|
||
EndLinkOffset: int32(model.EndLinkPosition().Offset()),
|
||
DegreeTrig: model.Degree(),
|
||
}
|
||
info.SlopeList = append(info.SlopeList, slope)
|
||
startLinkId, _ := strconv.Atoi(model.StartLinkPosition().Link().Id())
|
||
slope.StartLinkId = int32(startLinkId)
|
||
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
|
||
slope.EndLinkId = int32(endLinkId)
|
||
}
|
||
for _, model := range s.Repo.SectionalCurvatureList() {
|
||
id := s.GetComIdByUid(model.Id())
|
||
curve := &message.Curve{
|
||
ID: int32(id),
|
||
StartLinkOffset: int32(model.StartLinkPosition().Offset()),
|
||
EndLinkOffset: int32(model.EndLinkPosition().Offset()),
|
||
Curvature: model.Radius(),
|
||
}
|
||
info.CurveList = append(info.CurveList, curve)
|
||
startLinkId, _ := strconv.Atoi(model.StartLinkPosition().Link().Id())
|
||
curve.StartLinkId = int32(startLinkId)
|
||
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
|
||
curve.EndLinkId = int32(endLinkId)
|
||
}
|
||
return info
|
||
}
|
||
|
||
// 发送给前端的速度格式化
|
||
func speedParse(speed float32) int32 {
|
||
return int32(math.Abs(float64(speed * 3.6 * 100)))
|
||
}
|
||
|
||
// 处理半实物仿真列车控制消息
|
||
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg(b []byte) {
|
||
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
||
train := value.(*state_proto.TrainState)
|
||
if !train.Show { // 下线列车
|
||
return true
|
||
}
|
||
connState := train.ConnState
|
||
if connState.Conn == true && connState.ConnType == state_proto.TrainConnState_VOBC {
|
||
/*trainId, err := strconv.Atoi(train.Id)
|
||
if err != nil {
|
||
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
||
}*/
|
||
// 存放至列车中
|
||
//接收半实物列车控制不单独发送动力学,由动力学统一发送
|
||
//d := append(b, uint8(trainId))
|
||
//dynamics.Default().SendTrainControlMessage(d)
|
||
controlMessage := &message.TrainControlMsg{}
|
||
controlMessage.Decode(b)
|
||
controlMessage.TrainId = train.Id
|
||
controlMessage.FromVobc = true
|
||
train.VobcState = controlMessage.ControlInfo
|
||
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
}
|
||
func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg {
|
||
cms := make([]message.TrainControlMsg, 0)
|
||
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
||
train := value.(*state_proto.TrainState)
|
||
if !train.Show { // 下线列车
|
||
return true
|
||
}
|
||
vobc := false
|
||
if train.ConnState.Conn == true && train.ConnState.ConnType == state_proto.TrainConnState_VOBC {
|
||
vobc = true
|
||
}
|
||
//train.DynamicState.Speed
|
||
cms = append(cms, message.TrainControlMsg{ControlInfo: train.VobcState, TrainId: train.Id, FromVobc: vobc})
|
||
return true
|
||
})
|
||
return cms
|
||
}
|
||
|
||
// 获取半实物运行配置信息
|
||
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
|
||
return &s.runConfig.Vobc
|
||
}
|
||
|
||
// 处理接到的联锁消息
|
||
func (s *VerifySimulation) HandleInterlockDriverInfo(code string, driveBytes []byte) {
|
||
wd := entity.GetWorldData(s.World)
|
||
for _, m := range s.Repo.CiQcList() { // 获取继电器地图信息
|
||
if m.StationId != code {
|
||
continue
|
||
}
|
||
var driveInfo []bool
|
||
for _, b := range driveBytes {
|
||
for bit := 0; bit < 8; bit++ {
|
||
driveInfo = append(driveInfo, (b&(1<<bit)) != 0)
|
||
}
|
||
}
|
||
for i, b := range driveInfo {
|
||
qdData := m.QdList[i]
|
||
for _, relayId := range qdData.RefRelays {
|
||
if b {
|
||
|
||
}
|
||
err := wd.SetQdBit(relayId, b)
|
||
if err != nil {
|
||
slog.Error("联锁驱动数据设置出错", "error", err)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 采集联锁中的继电器消息
|
||
func (s *VerifySimulation) CollectInterlockRelayInfo(code string) *message.InterlockSendMsgPkg {
|
||
station := s.Repo.FindStationByStationName(code)
|
||
if station == nil {
|
||
return nil
|
||
}
|
||
for _, m := range s.Repo.CiQcList() { // 获取继电器地图信息
|
||
if m.StationId != station.Id() {
|
||
continue
|
||
}
|
||
if len(m.CjList) == 0 {
|
||
return nil
|
||
}
|
||
collectInfo := make([]bool, len(m.CjList))
|
||
for i, l := range m.CjList {
|
||
if l == nil || len(l.RefRelays) == 0 {
|
||
continue
|
||
}
|
||
rs := true
|
||
for _, j := range l.RefRelays {
|
||
if j.Q {
|
||
rs = rs && CollectXQCircuitState(s.World, j.RelayId)
|
||
} else {
|
||
rs = rs && CollectLXCircuitState(s.World, j.RelayId)
|
||
}
|
||
if !rs {
|
||
break
|
||
}
|
||
}
|
||
collectInfo[i] = rs
|
||
}
|
||
return message.NewInterlockSendMsgPkg(collectInfo)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// 获取列车可用连接半实物类型
|
||
func (s *VerifySimulation) FindTrainConnTypes() []dto.TrainConnTypeConfigDto {
|
||
typeConfig := make([]dto.TrainConnTypeConfigDto, 0)
|
||
if /*s.runConfig.Vobc.Open &&*/ s.runConfig.Vobc.Ip != "" {
|
||
typeConfig = append(typeConfig, dto.TrainConnTypeConfigDto{TypeName: "半实物vobc", ConnType: state_proto.TrainConnState_VOBC})
|
||
}
|
||
|
||
for _, pcSim := range s.runConfig.PcSimConfigs {
|
||
|
||
typeConfig = append(typeConfig, dto.TrainConnTypeConfigDto{TypeName: pcSim.ConfigName, ConnType: state_proto.TrainConnState_PC_SIM})
|
||
}
|
||
/* if s.runConfig.PcSimConfig.Open {
|
||
typeConfig = append(typeConfig, dto.TrainConnTypeConfigDto{ConnType: state_proto.TrainConnState_PC_SIM})
|
||
}*/
|
||
return typeConfig
|
||
}
|
||
|
||
// 获取电机转速参数
|
||
func (s *VerifySimulation) GetElectricMachineryRunConfig() []config.ElectricMachineryConfig {
|
||
return s.runConfig.ElectricMachinerys
|
||
}
|
||
|
||
// 初始化仿真运行配置
|
||
func (s *VerifySimulation) initRunConfig(runConfig *dto.ProjectRunConfigDto) error {
|
||
if runConfig == nil || runConfig.ConfigContent == "" {
|
||
return nil
|
||
}
|
||
var configMap config.ThirdPartyConfig
|
||
err := json.Unmarshal([]byte(runConfig.ConfigContent), &configMap)
|
||
if err != nil {
|
||
return sys_error.New("配置信息格式错误", err)
|
||
}
|
||
s.runConfig = &configMap
|
||
s.runConfig.Id = runConfig.Id
|
||
return nil
|
||
}
|
||
|
||
// 获取仿真运行参数ID
|
||
func (s *VerifySimulation) GetRunConfigId() int32 {
|
||
if s.runConfig == nil {
|
||
return 0
|
||
}
|
||
return s.runConfig.Id
|
||
}
|
||
func (s *VerifySimulation) EvnWorld() ecs.World {
|
||
return s.World
|
||
}
|
||
|
||
// 初始化运行资源
|
||
func (s *VerifySimulation) initRepository() error {
|
||
// 构建Repository
|
||
var mapIdStrSlice []string
|
||
var mapVersion []string
|
||
for _, id := range s.MapIds {
|
||
mapIdStrSlice = append(mapIdStrSlice, strconv.Itoa(int(id)))
|
||
mapVersion = append(mapVersion, strconv.Itoa(int(QueryGiVersion(id))))
|
||
}
|
||
repoId := strings.Join(mapIdStrSlice, "|")
|
||
repoVersion := strings.Join(mapVersion, ".")
|
||
repo := repository.FindRepository(repoId, repoVersion)
|
||
if repo == nil {
|
||
protoRepo, err := buildProtoRepository(s.MapIds)
|
||
if err != nil {
|
||
return sys_error.New("数据错误", err)
|
||
}
|
||
protoRepo.Id, protoRepo.Version = repoId, repoVersion
|
||
newRepo, err := repository.BuildRepository(protoRepo)
|
||
if err != nil {
|
||
return sys_error.New("数据错误", err)
|
||
}
|
||
repo = newRepo
|
||
}
|
||
s.Repo = repo
|
||
s.Memory = NewWaysideMemory()
|
||
// 构建所有UID映射关系,
|
||
s.UidMap = buildRepositoryAllUidsMap(s.MapIds, s.Repo)
|
||
return nil
|
||
}
|
||
|
||
// GetRunRadarConfig 获取雷达配置信息
|
||
func (s *VerifySimulation) GetRunRadarConfig() config.RadarConfig {
|
||
return s.runConfig.Radar
|
||
}
|
||
|
||
// GetRunAccConfig 获取加速计配置信息
|
||
func (s *VerifySimulation) GetRunAccConfig() config.AccConfig {
|
||
return s.runConfig.Acc
|
||
}
|
||
|
||
// FindRadarTrain 查找一个列车 只有1端雷达开启啊
|
||
/*func (s *VerifySimulation) FindRadarTrain() *state_proto.TrainState {
|
||
var trainStatus *state_proto.TrainState
|
||
s.Memory.Status.TrainStateMap.Range(func(k any, v any) bool {
|
||
val, ok := v.(*state_proto.TrainState)
|
||
if ok {
|
||
if val.TrainEndsA.RadarEnable || val.TrainEndsB.RadarEnable {
|
||
trainStatus = val
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
})
|
||
return trainStatus
|
||
}*/
|
||
|
||
// FindRadarTrain 查找一个列车 只有1端雷达开启啊
|
||
func (s *VerifySimulation) FindAccTrain() *state_proto.TrainState {
|
||
var trainStatus *state_proto.TrainState
|
||
s.Memory.Status.TrainStateMap.Range(func(k any, v any) bool {
|
||
val, ok := v.(*state_proto.TrainState)
|
||
if ok {
|
||
if val.TrainEndsA.AccEnable && val.TrainEndsB.AccEnable {
|
||
//trainStatus = val
|
||
//return false
|
||
return true
|
||
} else if val.TrainEndsA.AccEnable || val.TrainEndsB.AccEnable {
|
||
trainStatus = val
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
})
|
||
return trainStatus
|
||
}
|
||
func buildProtoRepository(mapIds []int32) (*proto.Repository, error) {
|
||
repo := &proto.Repository{}
|
||
var exceptStationGiMapIds []int32
|
||
//创建设备
|
||
for _, mapId := range mapIds {
|
||
giType := QueryGiType(mapId)
|
||
if giType == data_proto.PictureType_StationLayout {
|
||
stationGi := QueryGiData[*data_proto.RtssGraphicStorage](mapId)
|
||
fillProtoRepository(repo, stationGi, mapId)
|
||
} else {
|
||
exceptStationGiMapIds = append(exceptStationGiMapIds, mapId)
|
||
}
|
||
}
|
||
//构建并关联电子元件
|
||
for _, mapId := range exceptStationGiMapIds {
|
||
giType := QueryGiType(mapId)
|
||
if giType == data_proto.PictureType_RelayCabinetLayout {
|
||
relayGi := QueryGiData[*data_proto.RelayCabinetGraphicStorage](mapId)
|
||
buildAndRelateElectronicComponent(repo, relayGi, mapId)
|
||
}
|
||
}
|
||
//构建信号平面图中物理区段码表与集中站的关系
|
||
for _, mapId := range mapIds {
|
||
giType := QueryGiType(mapId)
|
||
if giType == data_proto.PictureType_StationLayout {
|
||
stationGi := QueryGiData[*data_proto.RtssGraphicStorage](mapId)
|
||
buildSectionCodePoint(repo, stationGi, mapId)
|
||
}
|
||
}
|
||
return repo, nil
|
||
}
|
||
|
||
func buildSectionCodePoint(repo *proto.Repository, storage *data_proto.RtssGraphicStorage, mapId int32) {
|
||
// city := storage.UniqueIdPrefix.City
|
||
// lineId := storage.UniqueIdPrefix.LineId
|
||
uidsMap := QueryUidStructure[*StationUidStructure](mapId)
|
||
for _, sscp := range storage.SectionCodePointList {
|
||
centralizedStation := sscp.CentralizedStation
|
||
sectionGIds := sscp.SectionIds
|
||
centralizedStationId := uidsMap.StationIds[centralizedStation].Uid // GenerateElementUid(city, lineId, nil, centralizedStation)
|
||
ref := queryCentralizedStationRef(centralizedStationId, repo)
|
||
var ccs []*proto.CiSectionCodePoint
|
||
for sectionPoint, sectionGId := range sectionGIds {
|
||
cc := &proto.CiSectionCodePoint{}
|
||
cc.Row = int32(sectionPoint)
|
||
cc.SectionId = QueryUidByMidAndComId(mapId, sectionGId, &data_proto.Section{})
|
||
ccs = append(ccs, cc)
|
||
}
|
||
ref.SectionCodePoints = ccs
|
||
}
|
||
}
|
||
func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *data_proto.RelayCabinetGraphicStorage, mapId int32) {
|
||
relayUidStructure := QueryUidStructure[*RelayUidStructure](mapId)
|
||
city := relayGi.UniqueIdPrefix.City
|
||
lineId := relayGi.UniqueIdPrefix.LineId
|
||
station := relayGi.UniqueIdPrefix.BelongsConcentrationStation
|
||
stationUid := BuildUid(city, lineId, station)
|
||
relayMap := make(map[string]*proto.Relay)
|
||
for _, relay := range relayGi.Relays {
|
||
rid := GetMapElementId(relay.Common)
|
||
var defaultPos proto.Relay_Pos
|
||
switch relay.DefaultInitialPosition {
|
||
case data_proto.CjDataItem_Q:
|
||
defaultPos = proto.Relay_Pos_Q
|
||
case data_proto.CjDataItem_H:
|
||
defaultPos = proto.Relay_Pos_H
|
||
case data_proto.CjDataItem_NONE:
|
||
defaultPos = proto.Relay_Pos_None
|
||
}
|
||
repoRelay := &proto.Relay{
|
||
Id: relayUidStructure.RelayIds[rid].Uid,
|
||
Code: relay.Code,
|
||
Model: convertRelayModel(relay.NewModel),
|
||
StationId: stationUid,
|
||
DefaultPos: defaultPos,
|
||
}
|
||
repo.Relays = append(repo.Relays, repoRelay)
|
||
relayMap[repoRelay.Id] = repoRelay
|
||
}
|
||
for _, pfp := range relayGi.PhaseFailureProtectors {
|
||
pid := GetMapElementId(pfp.Common)
|
||
repo.PhaseFailureProtectors = append(repo.PhaseFailureProtectors, &proto.PhaseFailureProtector{
|
||
Id: relayUidStructure.RelayIds[pid].Uid,
|
||
Code: pfp.Code,
|
||
})
|
||
}
|
||
turnoutMap := make(map[string]*proto.Turnout)
|
||
for _, turnout := range repo.Turnouts {
|
||
turnoutMap[turnout.Id] = turnout
|
||
}
|
||
signalMap := make(map[string]*proto.Signal)
|
||
for _, signal := range repo.Signals {
|
||
signalMap[signal.Id] = signal
|
||
}
|
||
stationMap := make(map[string]*proto.Station)
|
||
for _, station := range repo.Stations {
|
||
stationMap[station.Id] = station
|
||
}
|
||
psdMap := make(map[string]*proto.Psd)
|
||
for _, psd := range repo.Psds {
|
||
psdMap[psd.Id] = psd
|
||
}
|
||
platformMap := make(map[string]*proto.Platform)
|
||
for _, platform := range repo.Platforms {
|
||
platformMap[platform.Id] = platform
|
||
}
|
||
ckmMap := make(map[string]*proto.Ckm)
|
||
for _, ckm := range repo.Ckms {
|
||
ckmMap[ckm.Id] = ckm
|
||
}
|
||
xcjMap := make(map[string]*proto.Xcj)
|
||
for _, xcj := range repo.Xcjs {
|
||
xcjMap[xcj.Id] = xcj
|
||
}
|
||
sectionMap := make(map[string]*proto.PhysicalSection)
|
||
for _, section := range repo.PhysicalSections {
|
||
sectionMap[section.Id] = section
|
||
}
|
||
ciecs := stationMap[stationUid] //联锁集中站
|
||
if ciecs == nil {
|
||
panic(fmt.Errorf("联锁集中站[%s]不存在", stationUid))
|
||
}
|
||
for _, relationship := range relayGi.DeviceRelateRelayList {
|
||
switch relationship.DeviceType {
|
||
case data_proto.RelatedRef_Turnout:
|
||
turnout := turnoutMap[BuildUid(city, lineId, station, relationship.Code)]
|
||
if turnout == nil {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
turnout.ElectronicComponentGroups = append(turnout.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
}
|
||
case data_proto.RelatedRef_signal:
|
||
signal := signalMap[BuildUid(city, lineId, station, relationship.Code)]
|
||
if signal == nil {
|
||
continue
|
||
}
|
||
//信号机只有一个组合类型
|
||
if len(relationship.Combinationtypes) != 1 {
|
||
panic(fmt.Sprintf("信号机[%s]须有一个组合类型", signal.Id))
|
||
}
|
||
group := relationship.Combinationtypes[0]
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
signal.Code = group.Code
|
||
signal.ElectronicComponentGroups = append(signal.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
case data_proto.RelatedRef_station:
|
||
station := stationMap[BuildUid(city, lineId, relationship.Code)]
|
||
if station == nil {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
d := &proto.ElectronicGroup{Code: group.Code}
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
d.Components = append(d.Components, &proto.ElectronicComponent{
|
||
Id: relayUidStructure.RelayIds[relayId].Uid,
|
||
DeviceType: proto.DeviceType_DeviceType_Relay,
|
||
})
|
||
}
|
||
station.ElectronicGroup = append(station.ElectronicGroup, d)
|
||
}
|
||
case data_proto.RelatedRef_ScreenDoor:
|
||
psd, ok := psdMap[BuildUid(city, lineId, relationship.Code)]
|
||
if !ok {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
psd.ElectronicComponentGroups = append(psd.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
}
|
||
case data_proto.RelatedRef_SignalFaultAlarm: // 信号机故障报警仪设备组合
|
||
{
|
||
egs := buildEgs(relationship.Combinationtypes, relayUidStructure)
|
||
ciecs.Deccs = append(ciecs.Deccs, &proto.DeviceEcc{
|
||
DeviceType: proto.DeviceType_DeviceType_SignalFaultAlarm,
|
||
Egs: egs,
|
||
})
|
||
}
|
||
case data_proto.RelatedRef_Breakers: // 断路器
|
||
{
|
||
egs := buildEgs(relationship.Combinationtypes, relayUidStructure)
|
||
ciecs.Deccs = append(ciecs.Deccs, &proto.DeviceEcc{
|
||
DeviceType: proto.DeviceType_DeviceType_Breakers,
|
||
Egs: egs,
|
||
})
|
||
}
|
||
case data_proto.RelatedRef_PowerScreen: // 电源屏
|
||
{
|
||
egs := buildEgs(relationship.Combinationtypes, relayUidStructure)
|
||
ciecs.Deccs = append(ciecs.Deccs, &proto.DeviceEcc{
|
||
DeviceType: proto.DeviceType_DeviceType_PowerScreen,
|
||
Egs: egs,
|
||
})
|
||
}
|
||
case data_proto.RelatedRef_GarageDoor, data_proto.RelatedRef_FloodGate: //车库门||防淹门
|
||
{
|
||
ckm, ok := ckmMap[BuildUid(city, lineId, relationship.Code)]
|
||
if !ok {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
ckm.ElectronicComponentGroups = append(ckm.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
}
|
||
}
|
||
case data_proto.RelatedRef_CarWashing:
|
||
{
|
||
xcj, ok := xcjMap[BuildUid(city, lineId, relationship.Code)]
|
||
if !ok {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
xcj.ElectronicComponentGroups = append(xcj.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
}
|
||
}
|
||
case data_proto.RelatedRef_Section:
|
||
{
|
||
section, ok := sectionMap[GenerateElementUid(city, lineId, []string{station}, relationship.Code)]
|
||
if !ok {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
section.ElectronicComponentGroups = append(section.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
}
|
||
}
|
||
case data_proto.RelatedRef_Platform:
|
||
{
|
||
platform, ok := platformMap[GenerateElementUid(city, lineId, nil, relationship.Code)]
|
||
if !ok {
|
||
continue
|
||
}
|
||
for _, group := range relationship.Combinationtypes {
|
||
var componentIds []string
|
||
for _, relayId := range group.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
platform.ElectronicComponentGroups = append(platform.ElectronicComponentGroups,
|
||
&proto.ElectronicComponentGroup{
|
||
Code: group.Code,
|
||
ComponentIds: componentIds,
|
||
})
|
||
}
|
||
}
|
||
case data_proto.RelatedRef_LS:
|
||
{
|
||
egs := buildEgs(relationship.Combinationtypes, relayUidStructure)
|
||
ciecs.Deccs = append(ciecs.Deccs, &proto.DeviceEcc{
|
||
DeviceType: proto.DeviceType_DeviceType_LS,
|
||
Egs: egs,
|
||
})
|
||
}
|
||
}
|
||
}
|
||
//门控箱
|
||
for _, mkx := range repo.Mkxs {
|
||
platform := platformMap[psdMap[mkx.PsdId].GetPlatformId()]
|
||
station := stationMap[platform.GetStationId()]
|
||
var s string
|
||
if strings.Contains(platform.GetCode(), "上行") {
|
||
s = "S"
|
||
} else if strings.Contains(platform.GetCode(), "下行") {
|
||
s = "X"
|
||
} else {
|
||
continue
|
||
}
|
||
for _, group := range station.ElectronicGroup {
|
||
if group.Code == "MKX" {
|
||
for _, component := range group.Components {
|
||
relay := relayMap[component.Id]
|
||
if strings.Contains(relay.GetCode(), s) {
|
||
if strings.Contains(relay.GetCode(), "PCB") {
|
||
mkx.PcbjId = relay.Id
|
||
} else if strings.Contains(relay.GetCode(), "POB") {
|
||
mkx.PobjId = relay.Id
|
||
} else if strings.Contains(relay.GetCode(), "PAB") || strings.Contains(relay.GetCode(), "DPB") || strings.Contains(relay.GetCode(), "PDB") {
|
||
mkx.PabjId = relay.Id
|
||
} else if strings.Contains(relay.GetCode(), "WRZF") {
|
||
mkx.WrzfjId = relay.Id
|
||
} else if strings.Contains(relay.GetCode(), "QKQR") {
|
||
mkx.QkqrjId = relay.Id
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 处理该集中站采集、驱动配置信息
|
||
centralizedStationId := BuildUid(city, lineId, station)
|
||
ref := queryCentralizedStationRef(centralizedStationId, repo)
|
||
ref.CjList = append(ref.CjList, handlerRelayGiCj(relayUidStructure, centralizedStationId, relayGi.CiCjList)...)
|
||
sortQcTable(ref.CjList)
|
||
ref.QdList = append(ref.QdList, handlerRelayGiQd(relayUidStructure, centralizedStationId, relayGi.CiQdList)...)
|
||
sortQcTable(ref.QdList)
|
||
}
|
||
|
||
func buildEgs(cts []*data_proto.Combinationtype, relayUidStructure *RelayUidStructure) []*proto.ElectronicComponentGroup {
|
||
var egs []*proto.ElectronicComponentGroup
|
||
for _, ct := range cts {
|
||
d := &proto.ElectronicComponentGroup{Code: ct.Code}
|
||
for _, relayId := range ct.RefRelays {
|
||
if relayUidStructure.RelayIds[relayId] == nil {
|
||
continue
|
||
}
|
||
d.ComponentIds = append(d.ComponentIds, relayUidStructure.RelayIds[relayId].Uid)
|
||
}
|
||
egs = append(egs, d)
|
||
}
|
||
return egs
|
||
}
|
||
|
||
type IQcTable interface {
|
||
GetRow() int32
|
||
GetCol() int32
|
||
}
|
||
|
||
func sortQcTable[T IQcTable](s []T) {
|
||
sort.SliceStable(s, func(i, j int) bool {
|
||
a := s[i]
|
||
b := s[j]
|
||
if a.GetCol() < b.GetCol() {
|
||
return true
|
||
} else if a.GetCol() > b.GetCol() {
|
||
return false
|
||
} else {
|
||
if a.GetRow() < b.GetRow() {
|
||
return true
|
||
} else {
|
||
return false
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 查询集中站配置信息
|
||
func queryCentralizedStationRef(stationId string, repo *proto.Repository) *proto.CentralizedStationRef {
|
||
var ref *proto.CentralizedStationRef
|
||
for _, r := range repo.CentralizedStationRefs {
|
||
if r.StationId == stationId {
|
||
ref = r
|
||
break
|
||
}
|
||
}
|
||
if ref == nil {
|
||
ref = &proto.CentralizedStationRef{StationId: stationId}
|
||
repo.CentralizedStationRefs = append(repo.CentralizedStationRefs, ref)
|
||
}
|
||
return ref
|
||
}
|
||
|
||
// 处理继电器采集信息
|
||
func handlerRelayGiCj(uidsMap *RelayUidStructure, stationId string, ciCj *data_proto.CiCj) []*proto.CjData {
|
||
if ciCj == nil {
|
||
return nil
|
||
}
|
||
// 采集信息
|
||
dataLenght := len(ciCj.CjList) * int(ciCj.DsCount)
|
||
if dataLenght == 0 {
|
||
return nil
|
||
}
|
||
cjList := make([]*proto.CjData, dataLenght)
|
||
index := 0
|
||
for ci, col := range ciCj.CjList {
|
||
for ri, row := range col.BitList {
|
||
r := &proto.CjData{Row: int32(ri), Col: int32(ci)}
|
||
if len(row.RefRelays) > 0 {
|
||
for _, j := range row.RefRelays {
|
||
u := uidsMap.RelayIds[j.RelayId]
|
||
if u == nil {
|
||
panic(sys_error.New(fmt.Sprintf("集中站【id:%s】不存在继电器的【comId:%d】UID映射关系", stationId, j.RelayId)))
|
||
}
|
||
d := &proto.CjDataItem{RelayId: u.Uid}
|
||
if j.Position == data_proto.CjDataItem_H {
|
||
d.Q = false
|
||
} else {
|
||
d.Q = true
|
||
}
|
||
r.RefRelays = append(r.RefRelays, d)
|
||
}
|
||
}
|
||
cjList[index] = r
|
||
index++
|
||
}
|
||
}
|
||
return cjList
|
||
}
|
||
|
||
// 处理继电器驱动信息
|
||
func handlerRelayGiQd(uidsMap *RelayUidStructure, stationId string, ciQd *data_proto.CiQd) []*proto.QdData {
|
||
if ciQd == nil {
|
||
return nil
|
||
}
|
||
// 驱动信息
|
||
dataLenght := len(ciQd.QdList) * int(ciQd.DsCount)
|
||
if dataLenght == 0 {
|
||
return nil
|
||
}
|
||
qdList := make([]*proto.QdData, dataLenght)
|
||
index := 0
|
||
for ci, col := range ciQd.QdList {
|
||
for ri, row := range col.BitList {
|
||
r := &proto.QdData{Row: int32(ri), Col: int32(ci)}
|
||
if len(row.RefRelays) > 0 {
|
||
for _, j := range row.RefRelays {
|
||
u := uidsMap.RelayIds[j]
|
||
if u == nil {
|
||
panic(sys_error.New(fmt.Sprintf("集中站【id:%s】不存在继电器的【comId:%d】UID映射关系", stationId, j)))
|
||
}
|
||
r.RefRelays = append(r.RefRelays, u.Uid)
|
||
}
|
||
}
|
||
qdList[index] = r
|
||
index++
|
||
}
|
||
}
|
||
return qdList
|
||
}
|
||
|
||
func convertRelayModel(modelType data_proto.Relay_ModelType) proto.Relay_Model {
|
||
switch modelType {
|
||
case data_proto.Relay_Unknown:
|
||
return proto.Relay_Unknown
|
||
case data_proto.Relay_JPXC_1000:
|
||
return proto.Relay_JPXC_1000
|
||
case data_proto.Relay_JPXC_1700:
|
||
return proto.Relay_JPXC_1700
|
||
case data_proto.Relay_JWJXC_480:
|
||
return proto.Relay_JWJXC_480
|
||
case data_proto.Relay_JWJXC_H125_80:
|
||
return proto.Relay_JWJXC_H125_80
|
||
case data_proto.Relay_JWXC_1700:
|
||
return proto.Relay_JWXC_1700
|
||
case data_proto.Relay_JWXC_H340:
|
||
return proto.Relay_JWXC_H340
|
||
case data_proto.Relay_JYJXC_160_260:
|
||
return proto.Relay_JYJXC_160_260
|
||
case data_proto.Relay_JZXC_H18:
|
||
return proto.Relay_JZXC_H18
|
||
default:
|
||
panic(fmt.Sprintf("意料之外的继电器型号:%s", modelType))
|
||
}
|
||
}
|
||
|
||
func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphicStorage, mapId int32) {
|
||
repo.MainCoordinateSystem = storage.UniqueIdPrefix.MainCoordinateSystem
|
||
axleCountingMap := make(map[uint32]*data_proto.AxleCounting)
|
||
uidsMap := QueryUidStructure[*StationUidStructure](mapId)
|
||
//计轴
|
||
for _, data := range storage.AxleCountings {
|
||
id := GetMapElementId(data.Common)
|
||
axleCountingMap[id] = data
|
||
cpType := proto.CheckPointType_AxleCounter
|
||
if data.Type == data_proto.AxleCounting_SectionBoundary {
|
||
cpType = proto.CheckPointType_Boundary
|
||
}
|
||
cp := &proto.CheckPoint{
|
||
Id: uidsMap.AxlePointIds[id].Uid,
|
||
Km: convertKm(data.KilometerSystem),
|
||
Type: cpType,
|
||
}
|
||
for _, ref := range data.AxleCountingRef {
|
||
cp.DevicePorts = append(cp.DevicePorts, convertDevicePort(ref, uidsMap))
|
||
}
|
||
repo.CheckPoints = append(repo.CheckPoints, cp)
|
||
}
|
||
//物理区段
|
||
for _, data := range storage.Section {
|
||
var turnoutUids []string
|
||
if data.SectionType == data_proto.Section_TurnoutPhysical {
|
||
turnoutIds := findTurnoutIds(axleCountingMap, data.AxleCountings)
|
||
for _, tid := range turnoutIds {
|
||
turnoutUids = append(turnoutUids, uidsMap.TurnoutIds[tid].Uid)
|
||
}
|
||
}
|
||
var centralizedStationIds []string
|
||
for _, station := range uidsMap.PhysicalSectionIds[data.Common.Id].CentralizedStations {
|
||
centralizedStationIds = append(centralizedStationIds, uidsMap.StationIds[station.Common.Id].Uid)
|
||
}
|
||
//var centralizedStation string
|
||
//if len(data.CentralizedStations) > 0 {
|
||
// s := uidsMap.StationIds[data.CentralizedStations[0]]
|
||
// if s != nil {
|
||
// centralizedStation = s.Code
|
||
// }
|
||
//}
|
||
physicalSection := &proto.PhysicalSection{
|
||
Id: uidsMap.PhysicalSectionIds[GetMapElementId(data.Common)].Uid,
|
||
ADevicePort: convertDevicePort(data.PaRef, uidsMap),
|
||
BDevicePort: convertDevicePort(data.PbRef, uidsMap),
|
||
TurnoutIds: turnoutUids,
|
||
CentralizedStation: centralizedStationIds,
|
||
}
|
||
repo.PhysicalSections = append(repo.PhysicalSections, physicalSection)
|
||
}
|
||
//计轴区段
|
||
for _, data := range storage.AxleCountingSections {
|
||
var axleCountingIds []string
|
||
if data.PaRef != nil {
|
||
axleCountingIds = append(axleCountingIds, uidsMap.AxlePointIds[data.PaRef.Id].Uid)
|
||
}
|
||
if data.PbRef != nil {
|
||
axleCountingIds = append(axleCountingIds, uidsMap.AxlePointIds[data.PbRef.Id].Uid)
|
||
}
|
||
var turnoutAndPos []*proto.TurnoutAndPos
|
||
for _, tp := range data.TurnoutPos {
|
||
var pos proto.Turnout_Pos
|
||
switch tp.Position {
|
||
case 0:
|
||
pos = proto.Turnout_Pos_N
|
||
case 1:
|
||
pos = proto.Turnout_Pos_R
|
||
default:
|
||
panic(fmt.Errorf("计轴区段[%s]未知的道岔位置:%d", uidsMap.AxleCountingSectionIds[data.Common.Id].Uid, tp.Position))
|
||
}
|
||
turnoutAndPos = append(turnoutAndPos, &proto.TurnoutAndPos{
|
||
TurnoutId: uidsMap.TurnoutIds[tp.Id].Uid,
|
||
Pos: pos,
|
||
})
|
||
}
|
||
repo.AxleCountingSections = append(repo.AxleCountingSections, &proto.AxleCountingSection{
|
||
Id: uidsMap.AxleCountingSectionIds[data.Common.Id].Uid,
|
||
AxleCountingIds: axleCountingIds,
|
||
TurnoutAndPos: turnoutAndPos,
|
||
})
|
||
}
|
||
//道岔
|
||
for _, data := range storage.Turnouts {
|
||
var km *proto.Kilometer
|
||
for _, ks := range data.KilometerSystem {
|
||
if ks.Kilometer != 0 {
|
||
km = convertKm(ks)
|
||
break
|
||
}
|
||
}
|
||
turnout := &proto.Turnout{
|
||
Id: uidsMap.TurnoutIds[GetMapElementId(data.Common)].Uid,
|
||
Km: km,
|
||
ADevicePort: convertDevicePort(data.PaRef, uidsMap),
|
||
BDevicePort: convertDevicePort(data.PbRef, uidsMap),
|
||
CDevicePort: convertDevicePort(data.PcRef, uidsMap),
|
||
}
|
||
switch data.SwitchMachineType {
|
||
case data_proto.Turnout_ZDJ9_Single:
|
||
turnout.SwitchMachineType = proto.Turnout_ZDJ9_Single
|
||
case data_proto.Turnout_ZDJ9_Double:
|
||
turnout.SwitchMachineType = proto.Turnout_ZDJ9_Double
|
||
}
|
||
repo.Turnouts = append(repo.Turnouts, turnout)
|
||
}
|
||
//信号机
|
||
for _, data := range storage.Signals {
|
||
signal := &proto.Signal{
|
||
Id: uidsMap.SignalIds[GetMapElementId(data.Common)].Uid,
|
||
Km: convertKm(data.KilometerSystem),
|
||
Model: convertToProtoSignalModel(data.Mt),
|
||
}
|
||
switch data.RefDev.DeviceType {
|
||
case data_proto.RelatedRef_Section:
|
||
signal.SectionId = uidsMap.PhysicalSectionIds[data.RefDev.Id].Uid
|
||
case data_proto.RelatedRef_Turnout:
|
||
signal.TurnoutPort = convertDevicePort(data.RefDev, uidsMap)
|
||
}
|
||
repo.Signals = append(repo.Signals, signal)
|
||
}
|
||
stm := make(map[string][]string)
|
||
//应答器
|
||
for _, data := range storage.Transponders {
|
||
fixedTelegram, err := hex.DecodeString(data.FixedTelegram)
|
||
if err != nil {
|
||
slog.Error(fmt.Sprintf("解析应答器[%s]的固定报文出错:", err.Error()))
|
||
}
|
||
fixedUserTelegram, err := hex.DecodeString(data.FixedUserTelegram)
|
||
if err != nil {
|
||
slog.Error(fmt.Sprintf("解析应答器[%s]的固定用户报文出错:", err.Error()))
|
||
}
|
||
responder := &proto.Transponder{
|
||
Id: uidsMap.TransponderIds[GetMapElementId(data.Common)].Uid,
|
||
Km: convertKm(data.KilometerSystem),
|
||
FixedTelegram: fixedTelegram,
|
||
Type: convertToProtoBaliseType(data.Type),
|
||
FixedUserTelegram: fixedUserTelegram,
|
||
LeuIndex: data.LeuIndex,
|
||
IndexInLeu: data.LeuInsideIndex,
|
||
}
|
||
switch data.TransponderRef.DeviceType {
|
||
case data_proto.RelatedRef_Section:
|
||
responder.SectionId = uidsMap.PhysicalSectionIds[data.TransponderRef.Id].Uid
|
||
case data_proto.RelatedRef_Turnout:
|
||
responder.TurnoutPort = convertDevicePort(data.TransponderRef, uidsMap)
|
||
}
|
||
for _, stationId := range data.CentralizedStations {
|
||
var stationName string
|
||
if uidsMap.StationIds[stationId] == nil {
|
||
stationName = uidsMap.StationIds[stationId].Code
|
||
}
|
||
stm[stationName] = append(stm[stationName], responder.Id)
|
||
}
|
||
repo.Transponders = append(repo.Transponders, responder)
|
||
}
|
||
slopeKsMap := make(map[uint32]*data_proto.SlopeKiloMarker)
|
||
//坡度公里标
|
||
for _, data := range storage.SlopeKiloMarker {
|
||
slopeKsMap[GetMapElementId(data.Common)] = data
|
||
}
|
||
//坡度
|
||
for _, data := range storage.Slopes {
|
||
var kms []*proto.Kilometer
|
||
for _, id := range data.RefDeviceId {
|
||
kms = append(kms, convertKm(slopeKsMap[id].KilometerSystem[0]))
|
||
}
|
||
slope := &proto.Slope{
|
||
Id: uidsMap.SlopeIds[GetMapElementId(data.Common)].Uid,
|
||
Kms: kms,
|
||
Degree: data.SlopeNumber,
|
||
}
|
||
repo.Slopes = append(repo.Slopes, slope)
|
||
}
|
||
curveKsMap := make(map[uint32]*data_proto.CurvatureKiloMarker)
|
||
//曲度公里标
|
||
for _, data := range storage.CurvatureKiloMarker {
|
||
curveKsMap[GetMapElementId(data.Common)] = data
|
||
}
|
||
//曲度
|
||
for _, data := range storage.Curvatures {
|
||
var kms []*proto.Kilometer
|
||
for _, id := range data.RefDeviceId {
|
||
kms = append(kms, convertKm(curveKsMap[id].KilometerSystem[0]))
|
||
}
|
||
slope := &proto.SectionalCurvature{
|
||
Id: uidsMap.CurvatureIds[GetMapElementId(data.Common)].Uid,
|
||
Kms: kms,
|
||
Radius: data.CurvatureNumber,
|
||
}
|
||
repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope)
|
||
}
|
||
//公里标转换
|
||
for _, data := range storage.KilometerConvertList {
|
||
repo.KilometerConverts = append(repo.KilometerConverts, &proto.KilometerConvert{
|
||
KmA: convertKm(data.KmA),
|
||
KmB: convertKm(data.KmB),
|
||
SameTrend: data.SameTrend,
|
||
})
|
||
}
|
||
//公里标校准数据
|
||
for _, calibration := range storage.KilometerMarkCalibrations {
|
||
repo.KilometerCalibrations = append(repo.KilometerCalibrations, &proto.KilometerCalibration{
|
||
Design: convertKm(calibration.DesignKm),
|
||
Actual: convertKm(calibration.ActualKm),
|
||
})
|
||
}
|
||
//// 初始化站场图按钮
|
||
//for _, data := range storage.EsbButtons {
|
||
// repo.Buttons = append(repo.Buttons, &proto.Button{
|
||
// Id: uidsMap.EsbIds[GetMapElementId(data.Common)].Uid,
|
||
// Code: data.Code,
|
||
// ButtonType: proto.Button_Reset_Press,
|
||
// })
|
||
//}
|
||
//// 车站关联关系
|
||
//relateMap := make(map[string]*data_proto.StationRelateDevice)
|
||
//for _, data := range storage.StationRelateDeviceList {
|
||
// relateMap[data.Code] = data
|
||
//}
|
||
// 处理车站信息
|
||
repoStationMap := make(map[uint32]*proto.Station)
|
||
for _, data := range storage.Stations {
|
||
station := &proto.Station{
|
||
Id: uidsMap.StationIds[GetMapElementId(data.Common)].Uid,
|
||
Code: data.StationName,
|
||
}
|
||
repoStationMap[GetMapElementId(data.Common)] = station
|
||
//// 关联车站的设备
|
||
//refs, ok := relateMap[station.Code]
|
||
//if ok {
|
||
// for _, c := range refs.Combinationtypes {
|
||
// group := &proto.ElectronicGroup{Code: c.Code}
|
||
// for _, d := range c.RefDevices {
|
||
// var comp *proto.ElectronicComponent
|
||
// if uidsMap.EsbIds[d] != nil { // 目前只处理按钮
|
||
// comp = &proto.ElectronicComponent{
|
||
// Id: uidsMap.EsbIds[d].Uid,
|
||
// DeviceType: proto.DeviceType_DeviceType_Button,
|
||
// }
|
||
// } else {
|
||
// continue
|
||
// }
|
||
// group.Components = append(group.Components, comp)
|
||
// }
|
||
// station.ElectronicGroup = append(station.ElectronicGroup, group)
|
||
// }
|
||
//}
|
||
//// 处理车站关联IBP的设备
|
||
//handlerIBPDeviceToStation(station, repo, data.RefIbpMapCode)
|
||
repo.Stations = append(repo.Stations, station)
|
||
// 处理集中站的信息
|
||
if stm[station.Code] != nil {
|
||
ref := queryCentralizedStationRef(station.Id, repo)
|
||
ref.TransponderId = append(ref.TransponderId, stm[station.Code]...)
|
||
}
|
||
}
|
||
//站台
|
||
platformMap := make(map[uint32]*data_proto.Platform)
|
||
for _, data := range storage.Platforms {
|
||
platformId := GetMapElementId(data.Common)
|
||
platformMap[platformId] = data
|
||
platform := &proto.Platform{
|
||
Id: uidsMap.PlatformIds[platformId].Uid,
|
||
Code: data.Code,
|
||
}
|
||
switch data.Type {
|
||
case data_proto.Platform_up:
|
||
platform.Direction = proto.Platform_Up
|
||
case data_proto.Platform_down:
|
||
platform.Direction = proto.Platform_Down
|
||
case data_proto.Platform_Unknown:
|
||
platform.Direction = proto.Platform_Unknown
|
||
}
|
||
repo.Platforms = append(repo.Platforms, platform)
|
||
platform.StationId = uidsMap.StationIds[data.RefStationId].Uid
|
||
platform.PhysicalSectionId = uidsMap.PhysicalSectionIds[data.RefSectionId].Uid
|
||
}
|
||
//屏蔽门
|
||
platformId_psdUid_map := make(map[uint32]string)
|
||
for _, data := range storage.ScreenDoors {
|
||
var asdGroups []*proto.AsdGroup
|
||
for _, group := range storage.ScreenDoorConfig.ScreenDoorGroupList {
|
||
asdGroups = append(asdGroups, &proto.AsdGroup{
|
||
Group: group.TrainGroupAmount,
|
||
Start: group.StartSmallDoor,
|
||
End: group.EndSmallDoor,
|
||
})
|
||
}
|
||
psd := &proto.Psd{
|
||
Id: uidsMap.PsdIds[GetMapElementId(data.Common)].Uid,
|
||
AsdAmount: storage.ScreenDoorConfig.SonDoorAmount,
|
||
AsdGroups: asdGroups,
|
||
PlatformId: uidsMap.PlatformIds[data.RefPlatformId].Uid,
|
||
}
|
||
platformId_psdUid_map[data.GetRefPlatformId()] = psd.Id
|
||
repo.Psds = append(repo.Psds, psd)
|
||
}
|
||
//屏蔽门PSL
|
||
for _, data := range storage.PslBoxs {
|
||
boxUidInfo := uidsMap.PslIds[GetMapElementId(data.Common)]
|
||
mkx := &proto.Mkx{
|
||
Id: boxUidInfo.Uid,
|
||
PsdId: platformId_psdUid_map[data.RefPlatformId],
|
||
}
|
||
repo.Mkxs = append(repo.Mkxs, mkx)
|
||
_, pslStorage := QueryGiDataByName[*data_proto.PslGraphicStorage](data.RefPslMapCode)
|
||
for _, button := range pslStorage.PslButtons {
|
||
repoButton := &proto.Button{
|
||
Id: boxUidInfo.Uid + "_" + button.Code,
|
||
Code: button.Code,
|
||
ButtonType: proto.Button_Reset_Press,
|
||
HasLight: true,
|
||
}
|
||
repo.Buttons = append(repo.Buttons, repoButton)
|
||
switch button.Code {
|
||
case "PCB":
|
||
mkx.PcbaId = repoButton.Id
|
||
case "PCBPL":
|
||
mkx.PcbplaId = repoButton.Id
|
||
case "POB":
|
||
mkx.PobaId = repoButton.Id
|
||
case "POBPL":
|
||
mkx.PobplaId = repoButton.Id
|
||
case "PAB":
|
||
mkx.PabaId = repoButton.Id
|
||
case "PABPL":
|
||
mkx.PabplaId = repoButton.Id
|
||
case "WRZF":
|
||
mkx.WrzfaId = repoButton.Id
|
||
case "WRZFPL":
|
||
mkx.WrzfplaId = repoButton.Id
|
||
case "QKQR":
|
||
mkx.QkqraId = repoButton.Id
|
||
case "QKQRPL":
|
||
mkx.QkqrplaId = repoButton.Id
|
||
case "MPL":
|
||
mkx.MplaId = repoButton.Id
|
||
case "JXTCPLA":
|
||
mkx.JxtcplaId = repoButton.Id
|
||
}
|
||
}
|
||
}
|
||
//IBP
|
||
for _, data := range storage.IbpBoxs {
|
||
boxUidInfo := uidsMap.IbpIds[data.Common.Id]
|
||
station := repoStationMap[data.RefStationId]
|
||
handlerIBPDeviceToStation(station, boxUidInfo.Uid, repo, data.RefIbpMapCode)
|
||
}
|
||
//车库门和车库门PSL
|
||
fillCkmOrFym(repo, storage.GarageDoors, uidsMap)
|
||
//防淹门和防淹门PSL
|
||
fillCkmOrFym(repo, storage.FloodGates, uidsMap)
|
||
//洗车机
|
||
for _, data := range storage.CarWashings {
|
||
xcj := &proto.Xcj{
|
||
Id: uidsMap.XcjIds[data.Common.Id].Uid,
|
||
NumSegments: data.DuanNum,
|
||
}
|
||
repo.Xcjs = append(repo.Xcjs, xcj)
|
||
}
|
||
//ESB
|
||
for _, data := range storage.EsbButtons {
|
||
repo.Esbs = append(repo.Esbs, &proto.Esb{
|
||
Id: uidsMap.EsbIds[data.Common.Id].Uid,
|
||
PlatformId: uidsMap.PlatformIds[data.RefStand].Uid,
|
||
})
|
||
}
|
||
//SPKS
|
||
for _, data := range storage.SpksSwitchs {
|
||
repo.Spkss = append(repo.Spkss, &proto.Spks{
|
||
Id: uidsMap.SpksIds[data.Common.Id].Uid,
|
||
Code: data.Code,
|
||
PlatformId: uidsMap.PlatformIds[data.RefStand].Uid,
|
||
})
|
||
}
|
||
}
|
||
|
||
func fillCkmOrFym(repo *proto.Repository, doors []*data_proto.GarageDoor, uidsMap *StationUidStructure) {
|
||
for _, data := range doors {
|
||
//车库门
|
||
ckmId := GetMapElementId(data.Common)
|
||
ckm := &proto.Ckm{
|
||
Id: uidsMap.CkmIds[ckmId].Uid,
|
||
}
|
||
repo.Ckms = append(repo.Ckms, ckm)
|
||
//车库门PSL
|
||
pslUid := uidsMap.PslIds[ckmId].Uid
|
||
ckmPsl := &proto.CkmPsl{
|
||
Id: pslUid,
|
||
CkmId: uidsMap.CkmIds[ckmId].Uid,
|
||
}
|
||
repo.CkmPsls = append(repo.CkmPsls, ckmPsl)
|
||
_, pslStorage := QueryGiDataByName[*data_proto.PslGraphicStorage](data.RefPslMapCode)
|
||
for _, button := range pslStorage.PslButtons {
|
||
repoButton := &proto.Button{
|
||
Id: pslUid + "_" + button.Code,
|
||
Code: button.Code,
|
||
ButtonType: proto.Button_Reset_Press,
|
||
HasLight: true,
|
||
}
|
||
repo.Buttons = append(repo.Buttons, repoButton)
|
||
switch button.Code {
|
||
case "KMA":
|
||
ckmPsl.KmaId = repoButton.Id
|
||
case "GMA":
|
||
ckmPsl.GmaId = repoButton.Id
|
||
case "MPLA":
|
||
ckmPsl.MplaId = repoButton.Id
|
||
case "MMSA":
|
||
ckmPsl.MmsaId = repoButton.Id
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 将IBP的设备关联到车站中
|
||
func handlerIBPDeviceToStation(station *proto.Station, ibpBoxUid string, repo *proto.Repository, ibpMapCode string) {
|
||
mapId, storage := QueryGiDataByName[*data_proto.IBPGraphicStorage](ibpMapCode)
|
||
if storage == nil {
|
||
return
|
||
}
|
||
uidMap := QueryUidStructure[*IBPUidStructure](mapId)
|
||
deviceMap := make(map[uint32]*proto.ElectronicComponent) // 对应的设备类型
|
||
for _, data := range storage.IbpButtons { // 处理按钮
|
||
id := GetMapElementId(data.Common)
|
||
b := &proto.Button{
|
||
Id: ibpBoxUid + "_" + uidMap.IbpButtonIds[id].Uid,
|
||
Code: data.Code,
|
||
ButtonType: proto.Button_NO_Reset_Press,
|
||
HasLight: data.HasLight,
|
||
}
|
||
if data.IsSelfReset {
|
||
b.ButtonType = proto.Button_Reset_Press
|
||
}
|
||
deviceMap[id] = &proto.ElectronicComponent{
|
||
Id: b.Id,
|
||
DeviceType: proto.DeviceType_DeviceType_Button,
|
||
}
|
||
repo.Buttons = append(repo.Buttons, b)
|
||
}
|
||
for _, data := range storage.IbpKeys { // 钥匙
|
||
id := GetMapElementId(data.Common)
|
||
b := &proto.Key{
|
||
Id: ibpBoxUid + "_" + uidMap.IbpKeyIds[id].Uid,
|
||
Code: data.Code,
|
||
Gear: 2,
|
||
}
|
||
deviceMap[id] = &proto.ElectronicComponent{
|
||
Id: b.Id,
|
||
DeviceType: proto.DeviceType_DeviceType_Key,
|
||
}
|
||
repo.Keys = append(repo.Keys, b)
|
||
}
|
||
for _, data := range storage.IbpAlarms { // 报警器
|
||
id := GetMapElementId(data.Common)
|
||
b := &proto.Alarm{
|
||
Id: ibpBoxUid + "_" + uidMap.IbpAlarmIds[id].Uid,
|
||
Code: data.Code,
|
||
}
|
||
deviceMap[id] = &proto.ElectronicComponent{
|
||
Id: b.Id,
|
||
DeviceType: proto.DeviceType_DeviceType_Alarm,
|
||
}
|
||
repo.Alarms = append(repo.Alarms, b)
|
||
}
|
||
for _, data := range storage.IbpLights { // 指示灯,
|
||
id := GetMapElementId(data.Common)
|
||
b := &proto.Light{
|
||
Id: ibpBoxUid + "_" + uidMap.IbpLightIds[id].Uid,
|
||
Code: data.Code,
|
||
}
|
||
deviceMap[id] = &proto.ElectronicComponent{
|
||
Id: b.Id,
|
||
DeviceType: proto.DeviceType_DeviceType_Light,
|
||
}
|
||
repo.Lights = append(repo.Lights, b)
|
||
}
|
||
for _, data := range storage.IbpRelatedDevices { // 组信息
|
||
for _, c := range data.Combinationtypes {
|
||
group := &proto.ElectronicGroup{Code: c.Code}
|
||
for _, d := range c.RefDevices {
|
||
deviceType, ok := deviceMap[d]
|
||
if !ok {
|
||
slog.Debug("IBP组合类型类型不存在设备id:%s", d)
|
||
continue
|
||
}
|
||
group.Components = append(group.Components, deviceType)
|
||
}
|
||
station.ElectronicGroup = append(station.ElectronicGroup, group)
|
||
}
|
||
}
|
||
}
|
||
|
||
func convertKm(ks *data_proto.KilometerSystem) *proto.Kilometer {
|
||
var dir proto.Direction
|
||
switch ks.Direction {
|
||
case data_proto.KilometerSystem_LEFT:
|
||
dir = proto.Direction_LEFT
|
||
case data_proto.KilometerSystem_RIGHT:
|
||
dir = proto.Direction_RIGHT
|
||
}
|
||
return &proto.Kilometer{
|
||
Value: ks.Kilometer,
|
||
CoordinateSystem: ks.CoordinateSystem,
|
||
Direction: dir,
|
||
}
|
||
}
|
||
|
||
func convertDevicePort(ref *data_proto.RelatedRef, uidsMap *StationUidStructure) *proto.DevicePort {
|
||
if ref == nil {
|
||
return nil
|
||
}
|
||
var port proto.Port
|
||
switch ref.DevicePort {
|
||
case data_proto.RelatedRef_A:
|
||
port = proto.Port_A
|
||
case data_proto.RelatedRef_B:
|
||
port = proto.Port_B
|
||
case data_proto.RelatedRef_C:
|
||
port = proto.Port_C
|
||
}
|
||
var elementId string
|
||
var deviceType proto.DeviceType
|
||
switch ref.DeviceType {
|
||
case data_proto.RelatedRef_Section:
|
||
deviceType = proto.DeviceType_DeviceType_PhysicalSection
|
||
elementId = uidsMap.PhysicalSectionIds[ref.Id].Uid
|
||
case data_proto.RelatedRef_Turnout:
|
||
deviceType = proto.DeviceType_DeviceType_Turnout
|
||
elementId = uidsMap.TurnoutIds[ref.Id].Uid
|
||
default:
|
||
panic(fmt.Sprintf("异常的设备类型-%s", ref.DeviceType))
|
||
}
|
||
return &proto.DevicePort{
|
||
DeviceId: elementId,
|
||
DeviceType: deviceType,
|
||
Port: port,
|
||
}
|
||
}
|
||
|
||
func findTurnoutIds(axleCountingMap map[uint32]*data_proto.AxleCounting, axleIds []uint32) []uint32 {
|
||
if len(axleIds) <= 2 {
|
||
return nil
|
||
}
|
||
turnoutMap := make(map[uint32]int)
|
||
for _, axleId := range axleIds {
|
||
axle := axleCountingMap[axleId]
|
||
for _, ref := range axle.AxleCountingRef {
|
||
if ref.DeviceType == data_proto.RelatedRef_Turnout {
|
||
turnoutMap[ref.Id] = turnoutMap[ref.Id] + 1
|
||
}
|
||
}
|
||
}
|
||
var turnoutIds []uint32
|
||
for id, num := range turnoutMap {
|
||
if num > 1 {
|
||
turnoutIds = append(turnoutIds, id)
|
||
}
|
||
}
|
||
return turnoutIds
|
||
}
|
||
|
||
/*
|
||
enum Model{
|
||
HL = 0; //2XH-1 红绿
|
||
HLU_FU = 1; //2XH-1 红绿黄,封黄灯,无引导
|
||
HLU_DU_YY = 2; //3XH-1 红绿黄,不封灯,有单黄,带引导
|
||
HLU_YY = 3; //3XH-2或JDXH 红绿黄,不封灯,无单黄,带引导
|
||
HLU_FL_DU_YY = 4;//3XH-3 红绿黄,封绿灯,有单黄,带引导
|
||
HLU_DU = 5; //3XH-4 红绿黄,不封灯,有单黄,无引导
|
||
AB = 6; //DXCH 蓝白
|
||
HBU_DU = 7; //JCKXH 红白黄,不封灯,有单黄,无引导
|
||
}
|
||
*/
|
||
func convertToProtoSignalModel(gSmt data_proto.Signal_Model) proto.Signal_Model {
|
||
switch gSmt {
|
||
case data_proto.Signal_HL:
|
||
return proto.Signal_HL
|
||
case data_proto.Signal_HLU_FU:
|
||
return proto.Signal_HLU_FU
|
||
case data_proto.Signal_HLU_DU_YY:
|
||
return proto.Signal_HLU_DU_YY
|
||
case data_proto.Signal_HLU_YY:
|
||
return proto.Signal_HLU_YY
|
||
case data_proto.Signal_HLU_FL_DU_YY:
|
||
return proto.Signal_HLU_FL_DU_YY
|
||
case data_proto.Signal_HLU_DU:
|
||
return proto.Signal_HLU_DU
|
||
case data_proto.Signal_AB:
|
||
return proto.Signal_AB
|
||
case data_proto.Signal_HBU_DU:
|
||
return proto.Signal_HBU_DU
|
||
default:
|
||
panic(fmt.Sprintf("data_proto.Signal_Model[%d]无法映射到proto.Signal_Model", gSmt))
|
||
}
|
||
}
|
||
func convertToProtoBaliseType(bt data_proto.Transponder_TransponderTypeEnum) proto.Transponder_Type {
|
||
switch bt {
|
||
case data_proto.Transponder_FB:
|
||
return proto.Transponder_FB
|
||
case data_proto.Transponder_WB:
|
||
return proto.Transponder_WB
|
||
case data_proto.Transponder_DB:
|
||
return proto.Transponder_DB
|
||
case data_proto.Transponder_VB:
|
||
return proto.Transponder_VB
|
||
case data_proto.Transponder_IB:
|
||
return proto.Transponder_IB
|
||
default:
|
||
panic(fmt.Sprintf("data_proto.Transponder_TransponderTypeEnum[%d]无法映射到proto.Transponder_Type", bt))
|
||
}
|
||
}
|
||
|
||
// VerifyEvn 测试环境
|
||
type VerifyEvn interface {
|
||
EvnWorld() ecs.World
|
||
}
|