From 3a22950790472199d0c621f43f18f72d527230f7 Mon Sep 17 00:00:00 2001 From: thesai <1021828630@qq.com> Date: Wed, 18 Sep 2024 11:40:20 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BF=AE=E6=94=B9]11=E5=8F=B7=E7=BA=BF?= =?UTF-8?q?=E8=81=94=E9=94=81=E9=80=9A=E4=BF=A1=E9=80=BB=E8=BE=91=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E9=85=8D=E7=BD=AE=E4=B8=AD=E7=9A=84=E9=9B=86=E4=B8=AD?= =?UTF-8?q?=E7=AB=99=EF=BC=8C=E5=85=A8=E7=BA=BF=E9=80=9A=E4=BF=A1=EF=BC=9B?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BB=BF=E7=9C=9F=E6=97=B6=EF=BC=8C=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E8=AE=BE=E7=BD=AE=E7=BB=A7=E7=94=B5=E5=99=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81=EF=BC=8C=E5=88=9D=E5=A7=8B=E5=8C=96=E9=81=93=E5=B2=94?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E5=88=B0=E5=AE=9A=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- third_party/interlock/beijing11/msg_test.go | 4 +- third_party/interlock/beijing11/repo.go | 11 +- third_party/interlock/beijing11/service.go | 438 +++++++++++--------- ts/test_simulation_manage.go | 32 +- 4 files changed, 276 insertions(+), 209 deletions(-) diff --git a/third_party/interlock/beijing11/msg_test.go b/third_party/interlock/beijing11/msg_test.go index 8152080..ab3785e 100644 --- a/third_party/interlock/beijing11/msg_test.go +++ b/third_party/interlock/beijing11/msg_test.go @@ -9,7 +9,7 @@ import ( ) func TestFromInterlockFrame_Decode(t *testing.T) { - str := "58bea4c65e0e583f5bdedc310800450000bd030c0000801100003d0b0a0d3d0b7814413c40d800a9fcf182009a3c016301000600010000020000030000060000070000080000020001000005aa00020001aaaa0005aaaa00000008000401000501000601000701001801001901001a01001b010010000400000500000600000700000800000900000a00001d00001e00001f000020000021000022000023000024000025000000000000040001aaaa0002aaaa0003aaaa0004aaaa0000000000000000000000004c428d88" + str := "58bea4c65e0e583f5bdedc310800450000c94eae0000801100003d0b0a0d3d0b7814413c40d800b5fcfd8200a63c0363010003000400000500000900000200040000080000020004aaaa0008aaaa0000000f000d06000e01000f060010060021060023060011060012060026060027010013060014010022060024060025060010001300001400001500001600001700001800001900001a00002c00002d00002e00002f00003000003100003200003300000000000004000daaaa000eaaaa000faaaa0010aaaa00000000000000000000000058f24545" data, err := hex.DecodeString(str) if err != nil { t.Fatal(err) @@ -112,7 +112,7 @@ func TestFromInterlockFrame_Decode(t *testing.T) { } func TestToInterlockFrame_Decode(t *testing.T) { - str := "583f5bdedc3158bea4c65e0e0800450000f6dfe9400040115dd63d0b78143d0b0a0dd341413c00e2e8c88300d363013c0100060001010002010003010006010007010008010002000102eeaaaaaa000502eeaaaaaa00020001aa000005aa0000000011000101000201000301000401000501000601000701001501001601001701001801001901001a01001b01002901002a01002c010015000100000200000300000400000500000600000700000800000900000a00001b00001c00001d00001e00001f000020000021000022000023000024000025000000000000040001aaff0002aaff0003aaff0004aaff00000100000000000000000000000000000000f38414ee" + str := "583f5bdedc3158bea4c65e0e080045000172b52c4000401188173d0b78143d0b0a0d40d8413c015ebe7f83014f63013c0200030004010005010009020006000202eeaaaaaa000302eeaaaaaa000402eeaaaaaa000602eeaaaaaa000702eeaaaaaa000802eeaaaaaa00060002aaaa0003aaaa0004aaaa0006aaaa0007aaaa0008aaaa0000001b000800000900000a00000b00000c00000d06000e01000f06001006001106001206001306001401001c00001d00001e00001f00002000002106002206002306002406002506002606002701002800002b00001e000b00000c00000d00000e00000f00001000001100001200001300001400001500001600001700001800001900001a00002600002700002800002900002a00002b00002c00002d00002e00002f0000300000310000320000330000000000000c0005aaaa0006aaaa0007aaaa0008aaaa0009aaaa000aaaaa000baaaa000caaaa000daaaa000eaaaa000faaaa0010aaaa00000100000000000000000000000000000000328ef0af" data, err := hex.DecodeString(str) if err != nil { t.Fatal(err) diff --git a/third_party/interlock/beijing11/repo.go b/third_party/interlock/beijing11/repo.go index b77ebb3..26285aa 100644 --- a/third_party/interlock/beijing11/repo.go +++ b/third_party/interlock/beijing11/repo.go @@ -2,8 +2,8 @@ package beijing11 // StationDeviceIndexTable 联锁站设备索引表 type StationDeviceIndexTable struct { - StationName string //地图数据中车站的Code属性 - InterlockCode uint16 //通信数据中的“联锁编号” + //StationName string //地图数据中车站的Code属性 + //InterlockCode uint16 //通信数据中的“联锁编号” TurnoutMap map[uint16]*Row //key-联锁编号 PsdMap map[uint16]*Row //key-联锁编号 EsbMap map[uint16]*Row //key-联锁编号 @@ -17,10 +17,10 @@ type StationDeviceIndexTable struct { XcjMap map[uint16]*Row //key-联锁编号 } -func NewStationDeviceIndexTable(stationName string, interlockIndex uint16) *StationDeviceIndexTable { +func NewStationDeviceIndexTable( /*stationName string, interlockIndex uint16*/ ) *StationDeviceIndexTable { return &StationDeviceIndexTable{ - StationName: stationName, - InterlockCode: 0x3C00 + interlockIndex, + //StationName: stationName, + //InterlockCode: 0x3C00 + interlockIndex, TurnoutMap: make(map[uint16]*Row), PsdMap: make(map[uint16]*Row), EsbMap: make(map[uint16]*Row), @@ -36,6 +36,7 @@ func NewStationDeviceIndexTable(stationName string, interlockIndex uint16) *Stat } type Row struct { + interlockCode uint16 //所属联锁站编号 commonId uint32 //地图中设备的ID uid string //模型仓库中的设备模型ID index uint16 //联锁通信中的设备ID diff --git a/third_party/interlock/beijing11/service.go b/third_party/interlock/beijing11/service.go index 059aad5..247d928 100644 --- a/third_party/interlock/beijing11/service.go +++ b/third_party/interlock/beijing11/service.go @@ -33,12 +33,13 @@ var ( ) type serviceContext struct { - cancelFunc context.CancelFunc //用来结束各个协程的函数 - ioAddr *net.UDPAddr //向联锁发送数据的客户端 - server udp.UdpServer //接收联锁数据的服务端(同时也是向联锁发送数据的udp客户端) - sim *memory.VerifySimulation //启动服务所使用的仿真 - iConfig config.InterlockConfig //启动服务使用的联锁配置 - deviceTable *StationDeviceIndexTable //联锁站的设备ID表,key-车站名 + cancelFunc context.CancelFunc //用来结束各个协程的函数 + ioAddr *net.UDPAddr //向联锁发送数据的客户端 + server udp.UdpServer //接收联锁数据的服务端(同时也是向联锁发送数据的udp客户端) + sim *memory.VerifySimulation //启动服务所使用的仿真 + iConfig config.InterlockConfig //启动服务使用的联锁配置 + deviceTable *StationDeviceIndexTable //联锁站的设备ID表,key-车站名 + toInterlockFrames []*ToInterlockFrame //发给联锁的消息,因为需要按车站划分范围、排序,故将数据提前整理好,仅替换设备状态 } func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimulation) { @@ -48,7 +49,7 @@ func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimu mu.Lock() defer mu.Unlock() //制表 - table := makeTable(simulation, interlockConfig.Code) + table, toInterlockFrames := preprocessingData(simulation, interlockConfig.Code) if table == nil { //当前仿真内没有11号线联锁通信所需数据 return } @@ -64,11 +65,12 @@ func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimu ctx, cancelFunc := context.WithCancel(context.Background()) serviceCtx = &serviceContext{ - cancelFunc: cancelFunc, - ioAddr: ioAddr, - sim: simulation, - iConfig: interlockConfig, - deviceTable: table, + cancelFunc: cancelFunc, + ioAddr: ioAddr, + sim: simulation, + iConfig: interlockConfig, + deviceTable: table, + toInterlockFrames: toInterlockFrames, } //UDP服务端 server := udp.NewServer(fmt.Sprintf(":%d", interlockConfig.LocalPort), serviceCtx.handleDriveMsg) @@ -94,9 +96,9 @@ func (s *serviceContext) handleDriveMsg(data []byte) { wd := entity.GetWorldData(s.sim.World) for _, cmd := range frame.TurnoutData.CmdList { uid := s.deviceTable.TurnoutMap[cmd.Id].uid - if cmd.Cmd == 0x55 { + if cmd.Cmd == 0x01 { err = fi.DriveTurnoutDCOn(s.sim.World, uid) - } else if cmd.Cmd == 0xaa { + } else if cmd.Cmd == 0x02 { err = fi.DriveTurnoutFCOn(s.sim.World, uid) } else { err = fi.DriveTurnoutDCOff(s.sim.World, uid) @@ -109,7 +111,6 @@ func (s *serviceContext) handleDriveMsg(data []byte) { row := s.deviceTable.PsdMap[cmd.Id] entry := wd.EntityMap[row.uid] circuit := component.PsdCircuitType.Get(entry) - logger().Info(fmt.Sprintf("屏蔽门命令:%x", cmd.Cmd)) switch cmd.Cmd { case 0xAA: //短编组开门 wd.SetQdBit(row.relateDeviceMap[S], true) @@ -267,10 +268,22 @@ func (s *serviceContext) handleDriveMsg(data []byte) { default: logger().Error(fmt.Sprintf("信号机[%s]无法开放[%x]信号", uid, cmd.Cmd)) } + } else { logger().Error(fmt.Sprintf("信号机[%s]的型号未知", uid)) } } + { //采集状态赋值 + signalAspectMap := make(map[uint16]byte) + for _, cmd := range frame.SignalData.CmdList { + signalAspectMap[cmd.Id] = cmd.Cmd + } + for _, interlockFrame := range s.toInterlockFrames { + for _, state := range interlockFrame.SignalStates { + state.State = signalAspectMap[state.Id] + } + } + } for _, cmd := range frame.AxleSectionData.CmdList { if cmd.Cmd == 0x80 { uid := s.deviceTable.AxleSectionMap[cmd.Id].uid @@ -309,7 +322,7 @@ func Stop(stationCode string) { } } -func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceIndexTable { +func preprocessingData(sim *memory.VerifySimulation, stationCode string) (*StationDeviceIndexTable, []*ToInterlockFrame) { for _, mapId := range sim.MapIds { giType := memory.QueryGiType(mapId) if giType != data_proto.PictureType_StationLayout { @@ -320,22 +333,23 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI continue } - uids := memory.QueryUidStructure[*memory.StationUidStructure](mapId) - var table *StationDeviceIndexTable - for _, station := range stationGi.Stations { - if station.StationName != stationCode { - continue + frameMap := make(map[uint16]*ToInterlockFrame) + frameSlice := make([]*ToInterlockFrame, 0, 2) + getFrame := func(interlockCode uint16) *ToInterlockFrame { + frame := frameMap[interlockCode] + if frame == nil { + frame = &ToInterlockFrame{InterlockCode: interlockCode, WaysideCode: waysideCode} + frameMap[interlockCode] = frame + frameSlice = append(frameSlice, frame) } - for _, lianSuoIndexData := range stationGi.LianSuoData.Stations { - if lianSuoIndexData.Id == station.Common.Id { - table = NewStationDeviceIndexTable(station.StationName, uint16(lianSuoIndexData.Index)) - break - } - } - break + return frame } - if table == nil { - panic(fmt.Sprintf("联锁配置车站[%s]在地图中没有对应的车站或联锁编号数据", stationCode)) + + uids := memory.QueryUidStructure[*memory.StationUidStructure](mapId) + table := NewStationDeviceIndexTable() + stationMap := make(map[uint32]uint16) + for _, station := range stationGi.LianSuoData.Stations { + stationMap[station.Id] = uint16(0x3c00 + station.Index) } //道岔 for _, data := range stationGi.LianSuoData.Switchs { @@ -343,8 +357,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI continue } for _, station := range uids.TurnoutIds[data.Id].CentralizedStations { - if station.StationName == stationCode { + interlockCode := stationMap[station.Common.Id] + if interlockCode != 0 { + frame := getFrame(interlockCode) + frame.TurnoutStates = append(frame.TurnoutStates, &TurnoutState{Id: uint16(data.Index)}) table.TurnoutMap[uint16(data.Index)] = &Row{ + interlockCode: interlockCode, commonId: data.Id, uid: uids.TurnoutIds[data.Id].Uid, index: uint16(data.Index), @@ -377,7 +395,10 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI relateDeviceMap[S] = sRelayId relateDeviceMap[L] = lRelayId for _, station := range uids.PsdIds[data.Id].CentralizedStations { - if station.StationName == stationCode { + interlockCode := stationMap[station.Common.Id] + if interlockCode != 0 { + frame := getFrame(interlockCode) + frame.PsdStates = append(frame.PsdStates, &PSDState{Id: uint16(data.Index)}) for _, mkx := range sim.Repo.MkxList() { if mkx.Psd().Id() == uids.PsdIds[data.Id].Uid { relateDeviceMap[POB] = mkx.Pobj().Id() @@ -386,6 +407,7 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI } } table.PsdMap[uint16(data.Index)] = &Row{ + interlockCode: interlockCode, commonId: data.Id, uid: uids.PsdIds[data.Id].Uid, index: uint16(data.Index), @@ -400,8 +422,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI continue } for _, station := range uids.EsbIds[data.Id].CentralizedStations { - if station.StationName == stationCode { + interlockCode := stationMap[station.Common.Id] + if interlockCode != 0 { + frame := getFrame(interlockCode) + frame.ESBStates = append(frame.ESBStates, &ESBState{Id: uint16(data.Index)}) table.EsbMap[uint16(data.Index)] = &Row{ + interlockCode: interlockCode, commonId: data.Id, uid: uids.EsbIds[data.Id].Uid, index: uint16(data.Index), @@ -417,8 +443,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI continue } for _, station := range uids.SignalIds[data.Id].CentralizedStations { - if station.StationName == stationCode { + interlockCode := stationMap[station.Common.Id] + if interlockCode != 0 { + frame := getFrame(interlockCode) + frame.SignalStates = append(frame.SignalStates, &SignalState{Id: uint16(data.Index)}) table.SignalMap[uint16(data.Index)] = &Row{ + interlockCode: interlockCode, commonId: data.Id, uid: uids.SignalIds[data.Id].Uid, index: uint16(data.Index), @@ -427,6 +457,17 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI } } } + { //临时补充一个信号机 + table.SignalMap[40] = &Row{ + interlockCode: 0x3c02, + commonId: 0, + uid: "", + index: 40, + relateDeviceMap: nil, + } + frame := getFrame(0x3c02) + frame.SignalStates = append(frame.SignalStates, &SignalState{Id: 40}) + } //计轴区段 for _, data := range stationGi.LianSuoData.AcSections { if data.Index <= 0 { @@ -434,8 +475,13 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI } sectionModule := sim.Repo.FindAxleCountingSection(uids.AxleCountingSectionIds[data.Id].Uid) for _, station := range sectionModule.PhysicalSection().CentralizedStation() { - if station.GetCode() == stationCode { + //目前没发现一个计轴区段属于两个联锁区的情况,暂不处理 + interlockCode := stationMap[sim.UidMap[station.Id()].CommonId] + if interlockCode != 0 { + frame := getFrame(interlockCode) + frame.AxleSectionStates = append(frame.AxleSectionStates, &AxleSectionState{Id: uint16(data.Index)}) table.AxleSectionMap[uint16(data.Index)] = &Row{ + interlockCode: interlockCode, commonId: data.Id, uid: uids.AxleCountingSectionIds[data.Id].Uid, index: uint16(data.Index), @@ -452,8 +498,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI continue } for _, station := range uids.SpksIds[data.Id].CentralizedStations { - if station.StationName == stationCode { + interlockCode := stationMap[station.Common.Id] + if interlockCode != 0 { + frame := getFrame(interlockCode) + frame.SPKSStates = append(frame.SPKSStates, &SPKSState{Id: uint16(data.Index)}) table.SpksMap[uint16(data.Index)] = &Row{ + interlockCode: interlockCode, commonId: data.Id, uid: uids.SpksIds[data.Id].Uid, index: uint16(data.Index), @@ -464,9 +514,31 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI } //车库门,实际数据中数量为0 //洗车机,实际数据中没有 - return table + //按设备id大小排序 + for _, frame := range frameSlice { + sort.Slice(frame.TurnoutStates, func(i, j int) bool { + return frame.TurnoutStates[i].Id < frame.TurnoutStates[j].Id + }) + sort.Slice(frame.PsdStates, func(i, j int) bool { + return frame.PsdStates[i].Id < frame.PsdStates[j].Id + }) + sort.Slice(frame.ESBStates, func(i, j int) bool { + return frame.ESBStates[i].Id < frame.ESBStates[j].Id + }) + sort.Slice(frame.SignalStates, func(i, j int) bool { + return frame.SignalStates[i].Id < frame.SignalStates[j].Id + }) + sort.Slice(frame.AxleSectionStates, func(i, j int) bool { + return frame.AxleSectionStates[i].Id < frame.AxleSectionStates[j].Id + }) + sort.Slice(frame.SPKSStates, func(i, j int) bool { + return frame.SPKSStates[i].Id < frame.SPKSStates[j].Id + }) + } + + return table, frameSlice } - return nil + return nil, nil } func (s *serviceContext) runCollectTask(ctx context.Context) { @@ -482,178 +554,152 @@ func (s *serviceContext) runCollectTask(ctx context.Context) { case <-ctx.Done(): return default: - frame := s.collectDeviceState() - data := frame.encode() - _, err := s.server.WriteToUdp(data, s.ioAddr) - if err != nil { - logger().Error("向联锁发送数据失败", "error", err) - } else { - logger().Info(fmt.Sprintf("向联锁发送数据:%x", data)) + s.collectDeviceState() + for _, frame := range s.toInterlockFrames { + data := frame.encode() + _, err := s.server.WriteToUdp(data, s.ioAddr) + if err != nil { + logger().Error("向联锁发送数据失败", "error", err) + } else { + logger().Info(fmt.Sprintf("向联锁发送数据:%x", data)) + } } } } }() } -func (s *serviceContext) collectDeviceState() *ToInterlockFrame { +func (s *serviceContext) collectDeviceState() { wd := entity.GetWorldData(s.sim.World) - frame := &ToInterlockFrame{} - frame.WaysideCode = waysideCode - frame.InterlockCode = s.deviceTable.InterlockCode - //道岔 - for _, row := range s.deviceTable.TurnoutMap { - entry := wd.EntityMap[row.uid] - tp := component.TurnoutPositionType.Get(entry) - var stateByte byte - if entry.HasComponent(component.TurnoutFaultCiqdType) { - stateByte = 0xff - } else { - if tp.Dw { - stateByte = 0x01 - } else if tp.Fw { + for _, frame := range s.toInterlockFrames { + //道岔 + for _, state := range frame.TurnoutStates { + row := s.deviceTable.TurnoutMap[state.Id] + entry := wd.EntityMap[row.uid] + tp := component.TurnoutPositionType.Get(entry) + var stateByte byte + if entry.HasComponent(component.TurnoutFaultCiqdType) { + stateByte = 0xff + } else { + if tp.Dw { + stateByte = 0x01 + } else if tp.Fw { + stateByte = 0x02 + } else { + stateByte = 0x08 + } + } + + state.State = stateByte + } + //屏蔽门 + for _, state := range frame.PsdStates { + row := s.deviceTable.PsdMap[state.Id] + entry := wd.EntityMap[row.uid] + psdState := component.PsdStateType.Get(entry) + mkxBytes := make([]byte, 0, 3) + for _, mkxRelayUid := range []string{row.relateDeviceMap[POB], row.relateDeviceMap[PCB], row.relateDeviceMap[DPB]} { + if mkxRelayUid == "" { + continue + } + mkxBytes = append(mkxBytes, GetStateByte(component.BitStateType.Get(wd.EntityMap[mkxRelayUid]).Val)) + } + var stateByte byte + if psdState.Close { stateByte = 0x02 } else { - stateByte = 0x08 - } - } - frame.TurnoutStates = append(frame.TurnoutStates, &TurnoutState{ - Id: row.index, - State: stateByte, - }) - } - sort.Slice(frame.TurnoutStates, func(i, j int) bool { - return frame.TurnoutStates[i].Id < frame.TurnoutStates[j].Id - }) - //屏蔽门 - for _, row := range s.deviceTable.PsdMap { - entry := wd.EntityMap[row.uid] - psdState := component.PsdStateType.Get(entry) - mkxBytes := make([]byte, 0, 3) - for _, mkxRelayUid := range []string{row.relateDeviceMap[POB], row.relateDeviceMap[PCB], row.relateDeviceMap[DPB]} { - if mkxRelayUid == "" { - continue - } - mkxBytes = append(mkxBytes, GetStateByte(component.BitStateType.Get(wd.EntityMap[mkxRelayUid]).Val)) - } - var state byte - if psdState.Close { - state = 0x02 - } else { - state = 0x01 - } - var hsjc byte - if psdState.InterlockRelease { - hsjc = 0xff - } else { - hsjc = 0xee - } - frame.PsdStates = append(frame.PsdStates, &PSDState{ - Id: row.index, - State: state, - Hsjc: hsjc, - PCB: mkxBytes[0], - POB: mkxBytes[1], - DPB: mkxBytes[2], - }) - } - sort.Slice(frame.PsdStates, func(i, j int) bool { - return frame.PsdStates[i].Id < frame.PsdStates[j].Id - }) - //紧急停车 - for _, row := range s.deviceTable.EsbMap { - esb := s.sim.Repo.FindEsb(row.uid) - relay := wd.EntityMap[esb.RelayId()] - pla := wd.EntityMap[esb.PlaId()] - frame.ESBStates = append(frame.ESBStates, &ESBState{ - Id: row.index, - State: GetStateByte(!component.BitStateType.Get(relay).Val), - PlState: GetStateByte(component.BitStateType.Get(pla).Val), - //PlState: 0x00, - }) - } - sort.Slice(frame.ESBStates, func(i, j int) bool { - return frame.ESBStates[i].Id < frame.ESBStates[j].Id - }) - //信号机 - for _, row := range s.deviceTable.SignalMap { - entry := wd.EntityMap[row.uid] - lights := component.SignalLightsType.Get(entry) - isL := false - isH := false - isU := false - isA := false - isB := false - for _, light := range lights.Lights { - switch { - case light.HasComponent(component.LdTag): - isL = component.BitStateType.Get(light).Val - case light.HasComponent(component.HdTag): - isH = component.BitStateType.Get(light).Val - case light.HasComponent(component.UdTag): - isU = component.BitStateType.Get(light).Val - case light.HasComponent(component.BdTag): - isB = component.BitStateType.Get(light).Val - case light.HasComponent(component.AdTag): - isA = component.BitStateType.Get(light).Val - } - } - var stateByte byte - if isH && isU { - stateByte = 0x03 - } else { - switch { - case isL: - stateByte = 0x04 - case isH: stateByte = 0x01 - case isU: - stateByte = 0x02 - case isB: - stateByte = 0x08 - case isA: - stateByte = 0x09 } + var hsjc byte + if psdState.InterlockRelease { + hsjc = 0xff + } else { + hsjc = 0xee + } + + state.State = stateByte + state.Hsjc = hsjc + state.PCB = mkxBytes[0] + state.POB = mkxBytes[1] + state.DPB = mkxBytes[2] } - frame.SignalStates = append(frame.SignalStates, &SignalState{ - Id: row.index, - State: stateByte, - }) - } - sort.Slice(frame.SignalStates, func(i, j int) bool { - return frame.SignalStates[i].Id < frame.SignalStates[j].Id - }) - //计轴区段 - for _, row := range s.deviceTable.AxleSectionMap { - entry := wd.EntityMap[row.uid] - sectionState := component.AxleCountingSectionStateType.Get(entry) - var stateByte byte = 0x00 - if sectionState.Occupied { - stateByte = 0x40 + //紧急停车 + for _, state := range frame.ESBStates { + row := s.deviceTable.EsbMap[state.Id] + esb := s.sim.Repo.FindEsb(row.uid) + relay := wd.EntityMap[esb.RelayId()] + pla := wd.EntityMap[esb.PlaId()] + + state.State = GetStateByte(!component.BitStateType.Get(relay).Val) + state.PlState = GetStateByte(component.BitStateType.Get(pla).Val) + } + ////信号机 + //for _, state := range frame.SignalStates { + // row := s.deviceTable.SignalMap[state.Id] + // entry := wd.EntityMap[row.uid] + // lights := component.SignalLightsType.Get(entry) + // isL := false + // isH := false + // isU := false + // isA := false + // isB := false + // for _, light := range lights.Lights { + // switch { + // case light.HasComponent(component.LdTag): + // isL = component.BitStateType.Get(light).Val + // case light.HasComponent(component.HdTag): + // isH = component.BitStateType.Get(light).Val + // case light.HasComponent(component.UdTag): + // isU = component.BitStateType.Get(light).Val + // case light.HasComponent(component.BdTag): + // isB = component.BitStateType.Get(light).Val + // case light.HasComponent(component.AdTag): + // isA = component.BitStateType.Get(light).Val + // } + // } + // var stateByte byte + // if isH && isU { + // stateByte = 0x03 + // } else { + // switch { + // case isL: + // stateByte = 0x04 + // case isH: + // stateByte = 0x01 + // case isU: + // stateByte = 0x02 + // case isB: + // stateByte = 0x08 + // case isA: + // stateByte = 0x09 + // } + // } + // + // state.State = stateByte + //} + //计轴区段 + for _, state := range frame.AxleSectionStates { + row := s.deviceTable.AxleSectionMap[state.Id] + entry := wd.EntityMap[row.uid] + sectionState := component.AxleCountingSectionStateType.Get(entry) + var stateByte byte = 0x00 + if sectionState.Occupied { + stateByte = 0x40 + } + + state.State = stateByte + } + //SPKS + for _, state := range frame.SPKSStates { + row := s.deviceTable.SpksMap[state.Id] + spks := s.sim.Repo.FindSpks(row.uid) + relay := wd.EntityMap[spks.Relay()] + pla := wd.EntityMap[spks.PlaId()] + + state.State = GetStateByte(!component.BitStateType.Get(relay).Val) + state.PlState = GetStateByte(component.BitStateType.Get(pla).Val) } - frame.AxleSectionStates = append(frame.AxleSectionStates, &AxleSectionState{ - Id: row.index, - State: stateByte, - }) } - sort.Slice(frame.AxleSectionStates, func(i, j int) bool { - return frame.AxleSectionStates[i].Id < frame.AxleSectionStates[j].Id - }) - //SPKS - for _, row := range s.deviceTable.SpksMap { - spks := s.sim.Repo.FindSpks(row.uid) - relay := wd.EntityMap[spks.Relay()] - pla := wd.EntityMap[spks.PlaId()] - frame.SPKSStates = append(frame.SPKSStates, &SPKSState{ - Id: row.index, - State: GetStateByte(!component.BitStateType.Get(relay).Val), - PlState: GetStateByte(component.BitStateType.Get(pla).Val), - //PlState: 0xff, - }) - } - sort.Slice(frame.SPKSStates, func(i, j int) bool { - return frame.SPKSStates[i].Id < frame.SPKSStates[j].Id - }) - return frame } func logger() *slog.Logger { diff --git a/ts/test_simulation_manage.go b/ts/test_simulation_manage.go index ca21e90..aac934c 100644 --- a/ts/test_simulation_manage.go +++ b/ts/test_simulation_manage.go @@ -9,10 +9,12 @@ import ( "joylink.club/bj-rtsts-server/third_party/interlock/beijing12" "joylink.club/bj-rtsts-server/third_party/radar" "joylink.club/bj-rtsts-server/third_party/train_pc_sim" + "joylink.club/rtsssimulation/fi" "log/slog" "runtime" "strconv" "sync" + "time" "joylink.club/bj-rtsts-server/third_party/can_btm" cidcmodbus "joylink.club/bj-rtsts-server/third_party/cidc_modbus" @@ -58,24 +60,26 @@ func CreateSimulation(projectId int32, mapIds []int32, runConfig *dto.ProjectRun return "", err } verifySimulation.SimulationId = simulationId + verifySimulation.ProjectCode = project.Code // world构建 err = initWorld(verifySimulation) if err != nil { return "", err } + // verifySimulation.Start() + // 全部成功,启动仿真 + verifySimulation.World.StartUp() + // 初始化设备状态 + initDeviceStatus(verifySimulation) + // 启动仿真消息服务 + message_server.Start(verifySimulation) // 第三方服务处理 err = runThirdParty(verifySimulation) if err != nil { verifySimulation.World.Close() return "", err } - verifySimulation.ProjectCode = project.Code simulationMap.Store(simulationId, verifySimulation) - // verifySimulation.Start() - // 全部成功,启动仿真 - verifySimulation.World.StartUp() - // 启动仿真消息服务 - message_server.Start(verifySimulation) } return simulationId, nil } @@ -98,6 +102,22 @@ func DestroySimulation(simulationId string) { stopThirdParty(simulationInfo) } +func initDeviceStatus(simulation *memory.VerifySimulation) { + for _, turnout := range simulation.Repo.TurnoutList() { + err := fi.DriveTurnoutDCOn(simulation.World, turnout.Id()) + if err != nil { + slog.Error("初始驱动道岔到定位失败", "error", err) + } + } + time.Sleep(200 * time.Millisecond) + for _, turnout := range simulation.Repo.TurnoutList() { + err := fi.DriveTurnoutDCOff(simulation.World, turnout.Id()) + if err != nil { + slog.Error("取消驱动道岔到定位失败", "error", err) + } + } +} + // 创建world func initWorld(s *memory.VerifySimulation) error { //创建仿真