package memory import ( "fmt" "joylink.club/bj-rtsts-server/ats/verify/protos/graphicData" "joylink.club/bj-rtsts-server/ats/verify/protos/state" "joylink.club/rtsssimulation/repository" "joylink.club/rtsssimulation/repository/model/proto" "joylink.club/rtsssimulation/simulation" "sort" "strconv" "strings" ) // 轨旁仿真定义 type VerifySimulation struct { //地图id MapIds []int32 // 项目ID ProjectId int32 //仿真id SimulationId string //仿真内存数据 Memory *WaysideMemory //模型仓库 Repo *repository.Repository //Rtss仿真世界的id WorldId int } // 创建仿真对象 func CreateSimulation(projectId int32, mapIds []int32) (*VerifySimulation, error) { //构建Repository sort.Slice(mapIds, func(i, j int) bool { return mapIds[i] < mapIds[j] }) var mapIdStrSlice []string for _, id := range mapIds { mapIdStrSlice = append(mapIdStrSlice, strconv.Itoa(int(id))) } repoId := strings.Join(mapIdStrSlice, "|") repoVersion := "0.1" repo := repository.FindRepository(repoId, repoVersion) if repo == nil { var storages []*graphicData.RtssGraphicStorage for _, mapId := range mapIds { storages = append(storages, QueryGraphicStorage(mapId)) } protoRepo := buildProtoRepository(storages) newRepo, err := repository.BuildRepository(protoRepo) repo = newRepo if err != nil { return nil, err } } //创建仿真 worldId := simulation.CreateSimulation(repo, &simulation.WorldConfig{}) verifySimulation := &VerifySimulation{ MapIds: mapIds, ProjectId: projectId, Memory: NewWaysideMemory(), Repo: repo, WorldId: worldId, } return verifySimulation, nil //m := &WaysideMemory{} //verifySimulation := &VerifySimulation{ // MapIds: mapIds, // ProjectId: projectId, // Memory: m.Create(), //} //s := verifySimulation.Memory.Status //// 初始化构地图设备状态 //for _, mapId := range mapIds { // InitFromMap(s, QueryMapVerifyStructure(mapId)) //} //return verifySimulation } // 获取全量状态 func (s *VerifySimulation) GetAllState() *state.PushedDevicesStatus { return &state.PushedDevicesStatus{ All: true, AllStatus: &state.AllDevicesStatus{ SwitchState: GetAllTurnoutState(s), TrainState: GetAllTrainState(s), SectionState: append(GetAllAxleSectionState(s), GetAllPhysicalSectionState(s)...), }, } } // 获取变量状态 func (s *VerifySimulation) GetChangeState() *state.PushedDevicesStatus { return &state.PushedDevicesStatus{ All: false, VarStatus: &state.VariationStatus{ UpdatedSwitch: GetChangeTurnoutState(s), RemovedTrainId: GetRemovedTrainId(s), UpdatedTrain: GetUpdatedTrainState(s), }, } } func buildProtoRepository(storages []*graphicData.RtssGraphicStorage) *proto.Repository { repo := &proto.Repository{} for _, storage := range storages { fillProtoRepository(repo, storage) } return repo } func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphicStorage) { axleCountingMap := make(map[string]*graphicData.AxleCounting) for _, data := range storage.AxleCountings { if data.KilometerSystem == nil { println(fmt.Sprintf("计轴[%s]缺少公里标", data.Common.Id)) continue } axleCountingMap[data.Common.Id] = data cpType := proto.CheckPointType_AxleCounter if data.Invent { cpType = proto.CheckPointType_Boundary } cp := &proto.CheckPoint{ Id: data.Common.Id, Km: convertKm(data.KilometerSystem), Type: cpType, DevicePorts: convertDevicePorts(data.AxleCountingRef), } repo.CheckPoints = append(repo.CheckPoints, cp) } for _, data := range storage.Section { var turnoutIds []string if data.SectionType == graphicData.Section_TurnoutPhysical { turnoutIds = findTurnoutIds(axleCountingMap, data.AxleCountings) } physicalSection := &proto.PhysicalSection{ Id: data.Common.Id, ADevicePort: convertDevicePort(data.PaRef), BDevicePort: convertDevicePort(data.PbRef), TurnoutIds: turnoutIds, } repo.PhysicalSections = append(repo.PhysicalSections, physicalSection) } for _, data := range storage.Turnouts { var km *proto.Kilometer for _, ks := range data.KilometerSystem { if ks.Kilometer != 0 { km = convertKm(ks) break } } for _, kc := range buildKmConverts(data.KilometerSystem) { repo.KilometerConverts = append(repo.KilometerConverts, kc) } turnout := &proto.Turnout{ Id: data.Common.Id, Km: km, ADevicePort: convertDevicePort(data.PaRef), BDevicePort: convertDevicePort(data.PbRef), CDevicePort: convertDevicePort(data.PcRef), } repo.Turnouts = append(repo.Turnouts, turnout) } for _, data := range storage.Signals { var sectionId string var turnoutPort *proto.DevicePort switch data.RefDev.DeviceType { case graphicData.RelatedRef_Section: sectionId = data.RefDev.Id case graphicData.RelatedRef_Turnout: turnoutPort = convertDevicePort(data.RefDev) } signal := &proto.Signal{ Id: data.Common.Id, Km: convertKm(data.KilometerSystem), SectionId: sectionId, TurnoutPort: turnoutPort, } repo.Signals = append(repo.Signals, signal) } for _, data := range storage.Transponders { var sectionId string var turnoutPort *proto.DevicePort switch data.TransponderRef.DeviceType { case graphicData.RelatedRef_Section: sectionId = data.TransponderRef.Id case graphicData.RelatedRef_Turnout: turnoutPort = convertDevicePort(data.TransponderRef) } responder := &proto.Transponder{ Id: data.Common.Id, Km: convertKm(data.KilometerSystem), SectionId: sectionId, TurnoutPort: turnoutPort, } repo.Transponders = append(repo.Transponders, responder) } slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker) for _, data := range storage.SlopeKiloMarker { slopeKsMap[data.Common.Id] = data for _, kc := range buildKmConverts(data.KilometerSystem) { repo.KilometerConverts = append(repo.KilometerConverts, kc) } } curveKsMap := make(map[string]*graphicData.CurvatureKiloMarker) for _, data := range storage.CurvatureKiloMarker { curveKsMap[data.Common.Id] = data for _, kc := range buildKmConverts(data.KilometerSystem) { repo.KilometerConverts = append(repo.KilometerConverts, kc) } } 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: data.Common.Id, Kms: kms, Degree: data.SlopeNumber, } repo.Slopes = append(repo.Slopes, slope) } 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: data.Common.Id, Kms: kms, Radius: data.CurvatureNumber, } repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope) } } func convertKm(ks *graphicData.KilometerSystem) *proto.Kilometer { var dir proto.Direction switch ks.Direction { case graphicData.Direction_LEFT: dir = proto.Direction_LEFT case graphicData.Direction_RIGHT: dir = proto.Direction_RIGHT } return &proto.Kilometer{ Value: ks.Kilometer, CoordinateSystem: ks.CoordinateSystem, Direction: dir, } } func convertDevicePort(ref *graphicData.RelatedRef) *proto.DevicePort { if ref == nil { return nil } var deviceType proto.DeviceType var port proto.Port switch ref.DevicePort { case graphicData.RelatedRef_A: port = proto.Port_A case graphicData.RelatedRef_B: port = proto.Port_B case graphicData.RelatedRef_C: port = proto.Port_C } switch ref.DeviceType { case graphicData.RelatedRef_Section: deviceType = proto.DeviceType_DeviceType_PhysicalSection case graphicData.RelatedRef_Turnout: deviceType = proto.DeviceType_DeviceType_Turnout default: panic(fmt.Sprintf("异常的设备类型-%s", ref.DeviceType)) } return &proto.DevicePort{ DeviceId: ref.Id, DeviceType: deviceType, Port: port, } } func convertDevicePorts(refList []*graphicData.RelatedRef) []*proto.DevicePort { var dps []*proto.DevicePort for _, ref := range refList { dps = append(dps, convertDevicePort(ref)) } return dps } func findTurnoutIds(axleCountingMap map[string]*graphicData.AxleCounting, axleIds []string) []string { if len(axleIds) <= 2 { return nil } turnoutMap := make(map[string]bool) for _, axleId := range axleIds { axle := axleCountingMap[axleId] relTurnoutCount := 0 var turnoutId string for _, ref := range axle.AxleCountingRef { if ref.DeviceType == graphicData.RelatedRef_Turnout { relTurnoutCount++ turnoutId = ref.Id } } if relTurnoutCount == 1 { turnoutMap[turnoutId] = true } } var turnoutIds []string for id, _ := range turnoutMap { turnoutIds = append(turnoutIds, id) } return turnoutIds } func buildKmConverts(ksList []*graphicData.KilometerSystem) []*proto.KilometerConvert { var kmConverts []*proto.KilometerConvert for i, ks := range ksList { if ks.Kilometer == 0 { continue } for j := i + 1; j < len(ksList); j++ { if ks.Kilometer == 0 { continue } kmConverts = append(kmConverts, buildKmConvert(ks, ksList[j])) } } return kmConverts } func buildKmConvert(ks1 *graphicData.KilometerSystem, ks2 *graphicData.KilometerSystem) *proto.KilometerConvert { return &proto.KilometerConvert{ KmA: convertKm(ks1), KmB: convertKm(ks2), SameTrend: false, } }