From 846b48ee20536a4142fdc64f2ab686c365cb04f4 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Mon, 6 Nov 2023 14:35:32 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E8=AE=A1=E8=BD=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{axle_device.go => physical_section.go} | 106 ++++++++---------- component/singleton.go | 2 + entity/fadc_axle.go | 64 ++++------- fi/section.go | 85 ++++++-------- sys/device_sys/fadc_axle_device.go | 105 ++++++++--------- 5 files changed, 157 insertions(+), 205 deletions(-) rename component/{axle_device.go => physical_section.go} (56%) diff --git a/component/axle_device.go b/component/physical_section.go similarity index 56% rename from component/axle_device.go rename to component/physical_section.go index 6a44b54..80e1372 100644 --- a/component/axle_device.go +++ b/component/physical_section.go @@ -12,54 +12,20 @@ import ( //当CI系统给计轴设备发送计轴直接复零/预复零命令时,连续发送一定时间(具体发送时间调试后确定)的复零/预复零命令。 //当RAC,RJO,RJT任意一个不为0时,终止发送复零/预复零命令。 -// AxleSection 计轴物理区段状态 -type AxleSection struct { +// PhysicalSectionState 物理区段 +type PhysicalSectionState struct { //true-占用,false-出清 Occ bool } -// AxleSectionFault 计轴区段故障 -type AxleSectionFault struct { - //true-设置区段故障占用,false-取消区段故障占用 - SectionFault bool -} - -// AxleCounter 计轴区段计轴器 -type AxleCounter struct { +// AxlePhysicalSection 计轴物理区段 +type AxlePhysicalSection struct { //计轴区段内车轴数 Count int //记录Count变化波形 countPulse uint8 } - -func NewAxleCounter() *AxleCounter { - return &AxleCounter{Count: 0, countPulse: 0} -} -func (c *AxleCounter) UpdateCount(count int) { - cp := to1(c.Count) - np := to1(count) - // - if cp != np { - c.countPulse <<= 1 - if np > 0 { - c.countPulse |= np - } - } - c.Count = count -} -func (c *AxleCounter) ResetCountPulse() { - c.countPulse = 0x00 -} -func (c *AxleCounter) ShowCountWave() string { - return fmt.Sprintf("%08b", c.countPulse) -} - -// IsCount010Pulse true-车进入计轴区段后出清计轴区段 -func (c *AxleCounter) IsCount010Pulse() bool { - return c.countPulse&0x01 == 0 && c.countPulse&0x02 > 0 && c.countPulse&0x04 == 0 -} - -type AxleCounterRuntime struct { +type AxleDeviceRuntime struct { //true-计轴复位反馈,表示计轴设备已收到CI系统发送的直接复零/预复零命令。 Rac bool //true-运营原因拒绝计轴复位,如区段空闲时下发复位命令;或车轮压住传感器时收到复位命令。 @@ -76,34 +42,56 @@ type AxleCounterRuntime struct { DoingPdrst bool } -// FaDcAxleDevice 车站计轴管理设备 -type FaDcAxleDevice struct { - //区段计轴器列表,实体(AxleCounterType,AxleCounterRuntimeType,AxleSectionFlag) - Counters []*ecs.Entry - //计轴区段实体列表,实体(AxleSectionType,AxleSectionFaultType) - Sections []*ecs.Entry - //key-section id ,value-counter - CounterMap map[string]*ecs.Entry +func NewAxleDeviceRuntime() *AxleDeviceRuntime { + return &AxleDeviceRuntime{} } -func (f *FaDcAxleDevice) AddAxleSection(counter *ecs.Entry, section *ecs.Entry) { - f.Counters = append(f.Counters, counter) - f.Sections = append(f.Sections, section) - f.CounterMap[AxleSectionFlag.Get(counter).Id] = counter +// AxleManageDevice 计轴管理设备 +type AxleManageDevice struct { + CentralizedStation string //所属集中站 + Adrs map[string]*AxleDeviceRuntime //key-sectionId } -func (f *FaDcAxleDevice) GetAxleCounterEntry(sectionId string) *ecs.Entry { - return f.CounterMap[sectionId] + +func NewAxleManageDevice(centralizedStation string) *AxleManageDevice { + return &AxleManageDevice{CentralizedStation: centralizedStation, Adrs: make(map[string]*AxleDeviceRuntime)} } var ( - FaDcAxleDeviceType = ecs.NewComponentType[FaDcAxleDevice]() - AxleSectionFaultType = ecs.NewComponentType[AxleSectionFault]() - AxleSectionType = ecs.NewComponentType[AxleSection]() - AxleCounterType = ecs.NewComponentType[AxleCounter]() - AxleCounterRuntimeType = ecs.NewComponentType[AxleCounterRuntime]() - AxleSectionFlag = ecs.NewComponentType[Uid]() //计轴区段id + PhysicalSectionStateType = ecs.NewComponentType[PhysicalSectionState]() + AxlePhysicalSectionType = ecs.NewComponentType[AxlePhysicalSection]() + AxleSectionFaultTag = ecs.NewTag() + AxleManageDeviceType = ecs.NewComponentType[AxleManageDevice]() ) +/////////////////////////////AxlePhysicalSection///////////////////////////////// + +func NewAxlePhysicalSection() *AxlePhysicalSection { + return &AxlePhysicalSection{Count: 0, countPulse: 0} +} +func (c *AxlePhysicalSection) UpdateCount(count int) { + cp := to1(c.Count) + np := to1(count) + // + if cp != np { + c.countPulse <<= 1 + if np > 0 { + c.countPulse |= np + } + } + c.Count = count +} +func (c *AxlePhysicalSection) ResetCountPulse() { + c.countPulse = 0x00 +} +func (c *AxlePhysicalSection) ShowCountWave() string { + return fmt.Sprintf("%08b", c.countPulse) +} + +// IsCount010Pulse true-车进入计轴区段后出清计轴区段 +func (c *AxlePhysicalSection) IsCount010Pulse() bool { + return c.countPulse&0x01 == 0 && c.countPulse&0x02 > 0 && c.countPulse&0x04 == 0 +} + // 归1 func to1(c int) uint8 { if c > 0 { diff --git a/component/singleton.go b/component/singleton.go index 674b725..efad786 100644 --- a/component/singleton.go +++ b/component/singleton.go @@ -21,6 +21,8 @@ type WorldData struct { EntityMap map[string]*ecs.Entry // 联锁驱采卡实体 CiQcEntities []*ecs.Entry + // 集中站计轴管理设备实体 + AxleManageDeviceEntities []*ecs.Entry } // 是否在驱动码表中 diff --git a/entity/fadc_axle.go b/entity/fadc_axle.go index e36c4f4..43ef38e 100644 --- a/entity/fadc_axle.go +++ b/entity/fadc_axle.go @@ -8,6 +8,13 @@ import ( "strings" ) +func newAxleManageDevice(w ecs.World, data *component.WorldData, centralizedStation string) *ecs.Entry { + entry := w.Entry(w.Create(component.AxleManageDeviceType)) + component.AxleManageDeviceType.Set(entry, component.NewAxleManageDevice(centralizedStation)) + data.AxleManageDeviceEntities = append(data.AxleManageDeviceEntities, entry) + return entry +} + // LoadAxlePhysicalSections 加载计轴区段 func LoadAxlePhysicalSections(w ecs.World) error { data := GetWorldData(w) @@ -17,35 +24,24 @@ func LoadAxlePhysicalSections(w ecs.World) error { if len(strings.TrimSpace(section.CentralizedStation())) == 0 { return fmt.Errorf("区段[%s]未设置所属集中站", section.Id()) } - //fmt.Println("=====>>>>>计轴区段:", section.Id()) - fadcDeviceId := CreateFaDcAxleDeviceId(section.CentralizedStation()) - fadcDeviceEntry, find := data.EntityMap[fadcDeviceId] - if !find { - fadcDeviceEntry = createFadcDeviceEntity(w, section, data) - data.EntityMap[fadcDeviceId] = fadcDeviceEntry - } - fadcDevice := component.FaDcAxleDeviceType.Get(fadcDeviceEntry) - counter := createAxleCounterEntity(w, section, data) - axleSec := createAxleSectionEntity(w, section, data) - fadcDevice.AddAxleSection(counter, axleSec) + amdEntry := newAxleManageDevice(w, data, section.CentralizedStation()) + amd := component.AxleManageDeviceType.Get(amdEntry) + // + createAxleSectionEntity(w, section, data) + // + amd.Adrs[section.Id()] = component.NewAxleDeviceRuntime() } } return nil } - -// 联锁集中站计轴管理设备实体 -func createFadcDeviceEntity(w ecs.World, axleSection *repository.PhysicalSection, worldData *component.WorldData) *ecs.Entry { - uid := CreateFaDcAxleDeviceId(axleSection.CentralizedStation()) - entry, ok := worldData.EntityMap[uid] - if !ok { - entry = w.Entry(w.Create(component.UidType, component.FaDcAxleDeviceType)) - // - component.UidType.SetValue(entry, component.Uid{Id: uid}) - component.FaDcAxleDeviceType.Set(entry, &component.FaDcAxleDevice{CounterMap: make(map[string]*ecs.Entry)}) - // - worldData.EntityMap[uid] = entry +func FindAxleManageDevice(data *component.WorldData, centralizedStation string) *ecs.Entry { + for _, entry := range data.AxleManageDeviceEntities { + amd := component.AxleManageDeviceType.Get(entry) + if amd != nil && amd.CentralizedStation == centralizedStation { + return entry + } } - return entry + return nil } // 计轴区段实体 @@ -53,27 +49,13 @@ func createAxleSectionEntity(w ecs.World, axleSection *repository.PhysicalSectio uid := axleSection.Id() entry, ok := worldData.EntityMap[uid] if !ok { - entry = w.Entry(w.Create(component.UidType, component.AxleSectionType, component.AxleSectionFaultType)) + entry = w.Entry(w.Create(component.UidType, component.PhysicalSectionStateType, component.AxlePhysicalSectionType)) // component.UidType.SetValue(entry, component.Uid{Id: uid}) - component.AxleSectionType.Set(entry, &component.AxleSection{Occ: false}) - component.AxleSectionFaultType.Set(entry, &component.AxleSectionFault{SectionFault: false}) + component.PhysicalSectionStateType.Set(entry, &component.PhysicalSectionState{Occ: false}) + component.AxlePhysicalSectionType.Set(entry, component.NewAxlePhysicalSection()) // worldData.EntityMap[uid] = entry } return entry } - -// 计轴器实体 -func createAxleCounterEntity(w ecs.World, axleSection *repository.PhysicalSection, worldData *component.WorldData) *ecs.Entry { - entry := w.Entry(w.Create(component.AxleCounterType, component.AxleCounterRuntimeType, component.AxleSectionFlag)) - component.AxleCounterType.Set(entry, component.NewAxleCounter()) - component.AxleCounterRuntimeType.Set(entry, &component.AxleCounterRuntime{Rac: false, Rjo: false, Rjt: false, Drst: false, Pdrst: false, DoingPdrst: false}) - component.AxleSectionFlag.SetValue(entry, component.Uid{Id: axleSection.Id()}) - return entry -} - -// CreateFaDcAxleDeviceId 设备集中站计轴管理设备id(通过联锁集中站centralizedStation来构建) -func CreateFaDcAxleDeviceId(centralizedStation string) string { - return fmt.Sprintf("fadc-axle-device-%s", centralizedStation) -} diff --git a/fi/section.go b/fi/section.go index d321762..fea5f75 100644 --- a/fi/section.go +++ b/fi/section.go @@ -18,17 +18,16 @@ func AxleSectionDrstDrive(w ecs.World, sectionId string, set bool) error { return ecs.NewErrResult(fmt.Errorf("区段模型[%s]不存实体", sectionId)) } // - faDcAxleDeviceId := entity.CreateFaDcAxleDeviceId(sectionModel.CentralizedStation()) - faDcAxleDeviceEntry, ok := wd.EntityMap[faDcAxleDeviceId] + faDcAxleDeviceEntry := entity.FindAxleManageDevice(wd, sectionModel.CentralizedStation()) + + if faDcAxleDeviceEntry == nil { + return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]实体不存在", sectionModel.CentralizedStation())) + } + faDcAxleDevice := component.AxleManageDeviceType.Get(faDcAxleDeviceEntry) + axleRuntime, ok := faDcAxleDevice.Adrs[sectionId] if !ok { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]不存实体", faDcAxleDeviceId)) + return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]中不存在区段[%s]的计轴设备", sectionModel.CentralizedStation(), sectionId)) } - // - axleCounterEntry := component.FaDcAxleDeviceType.Get(faDcAxleDeviceEntry).GetAxleCounterEntry(sectionId) - if axleCounterEntry == nil { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]中不存在区段[%s]的计轴器实体", faDcAxleDeviceId, sectionId)) - } - axleRuntime := component.AxleCounterRuntimeType.Get(axleCounterEntry) axleRuntime.Drst = set // return ecs.NewOkEmptyResult() @@ -47,17 +46,16 @@ func AxleSectionPdrstDrive(w ecs.World, sectionId string, set bool) error { return ecs.NewErrResult(fmt.Errorf("区段模型[%s]不存实体", sectionId)) } // - faDcAxleDeviceId := entity.CreateFaDcAxleDeviceId(sectionModel.CentralizedStation()) - faDcAxleDeviceEntry, ok := wd.EntityMap[faDcAxleDeviceId] + faDcAxleDeviceEntry := entity.FindAxleManageDevice(wd, sectionModel.CentralizedStation()) + + if faDcAxleDeviceEntry == nil { + return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]实体不存在", sectionModel.CentralizedStation())) + } + faDcAxleDevice := component.AxleManageDeviceType.Get(faDcAxleDeviceEntry) + axleRuntime, ok := faDcAxleDevice.Adrs[sectionId] if !ok { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]不存实体", faDcAxleDeviceId)) + return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]中不存在区段[%s]的计轴设备", sectionModel.CentralizedStation(), sectionId)) } - // - axleCounterEntry := component.FaDcAxleDeviceType.Get(faDcAxleDeviceEntry).GetAxleCounterEntry(sectionId) - if axleCounterEntry == nil { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]中不存在区段[%s]的计轴器实体", faDcAxleDeviceId, sectionId)) - } - axleRuntime := component.AxleCounterRuntimeType.Get(axleCounterEntry) axleRuntime.Pdrst = set // return ecs.NewOkEmptyResult() @@ -76,26 +74,21 @@ func AxleSectionFaultOccDrive(w ecs.World, sectionId string, set bool) error { return ecs.NewErrResult(fmt.Errorf("区段模型[%s]不存实体", sectionId)) } // - faDcAxleDeviceId := entity.CreateFaDcAxleDeviceId(sectionModel.CentralizedStation()) - faDcAxleDeviceEntry, ok := wd.EntityMap[faDcAxleDeviceId] - if !ok { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]不存实体", faDcAxleDeviceId)) + sectionEntry := wd.EntityMap[sectionId] + if sectionEntry == nil { + return ecs.NewErrResult(fmt.Errorf("区段[%s]实体不存在", sectionId)) } - // - axleCounterEntry := component.FaDcAxleDeviceType.Get(faDcAxleDeviceEntry).GetAxleCounterEntry(sectionId) - axleCounter := component.AxleCounterType.Get(axleCounterEntry) - // - sectionEntry, ok := wd.EntityMap[sectionId] - if !ok { - return ecs.NewErrResult(fmt.Errorf("计轴区段[%s]不存实体", sectionId)) - } - sectionFault := component.AxleSectionFaultType.Get(sectionEntry) - //计轴故障设置 - sectionFault.SectionFault = set - if set { - axleCounter.UpdateCount(1) - } else { - axleCounter.UpdateCount(0) + axleDevice := component.AxlePhysicalSectionType.Get(sectionEntry) + if set { //计轴故障设置 + if !sectionEntry.HasComponent(component.AxleSectionFaultTag) { + sectionEntry.AddComponent(component.AxleSectionFaultTag) + } + axleDevice.UpdateCount(1) + } else { //计轴故障取消 + if sectionEntry.HasComponent(component.AxleSectionFaultTag) { + sectionEntry.RemoveComponent(component.AxleSectionFaultTag) + } + axleDevice.UpdateCount(0) } // return ecs.NewOkEmptyResult() @@ -114,21 +107,15 @@ func AxleSectionTrainDrive(w ecs.World, sectionId string, trainIn bool) error { return ecs.NewErrResult(fmt.Errorf("区段模型[%s]不存实体", sectionId)) } // - faDcAxleDeviceId := entity.CreateFaDcAxleDeviceId(sectionModel.CentralizedStation()) - faDcAxleDeviceEntry, ok := wd.EntityMap[faDcAxleDeviceId] - if !ok { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]不存实体", faDcAxleDeviceId)) + sectionEntry := wd.EntityMap[sectionId] + if sectionEntry == nil { + return ecs.NewErrResult(fmt.Errorf("区段[%s]实体不存在", sectionId)) } - // - axleCounterEntry := component.FaDcAxleDeviceType.Get(faDcAxleDeviceEntry).GetAxleCounterEntry(sectionId) - if axleCounterEntry == nil { - return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]中不存在区段[%s]的计轴器实体", faDcAxleDeviceId, sectionId)) - } - axleCounter := component.AxleCounterType.Get(axleCounterEntry) + axleDevice := component.AxlePhysicalSectionType.Get(sectionEntry) if trainIn { - axleCounter.UpdateCount(1) + axleDevice.UpdateCount(1) } else { - axleCounter.UpdateCount(0) + axleDevice.UpdateCount(0) } // return ecs.NewOkEmptyResult() diff --git a/sys/device_sys/fadc_axle_device.go b/sys/device_sys/fadc_axle_device.go index e01ccf9..564c8c3 100644 --- a/sys/device_sys/fadc_axle_device.go +++ b/sys/device_sys/fadc_axle_device.go @@ -5,6 +5,7 @@ import ( "joylink.club/ecs" "joylink.club/ecs/filter" "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/entity" "log/slog" ) @@ -15,92 +16,84 @@ type FaDcAxleDeviceSystem struct { func NewFaDcAxleDeviceSystem() *FaDcAxleDeviceSystem { return &FaDcAxleDeviceSystem{ - query: ecs.NewQuery(filter.Contains(component.FaDcAxleDeviceType)), + query: ecs.NewQuery(filter.Contains(component.AxleManageDeviceType)), } } func (s *FaDcAxleDeviceSystem) Update(w ecs.World) { + data := entity.GetWorldData(w) s.query.Each(w, func(entry *donburi.Entry) { - faDcDevice := component.FaDcAxleDeviceType.Get(entry) - for _, axleSectionEntry := range faDcDevice.Sections { - axleSectionId := component.UidType.Get(axleSectionEntry).Id - axleCounterEntry := faDcDevice.CounterMap[axleSectionId] + faDcDevice := component.AxleManageDeviceType.Get(entry) + for axleSectionId, axleRuntime := range faDcDevice.Adrs { + axleSectionEntry := data.EntityMap[axleSectionId] + sectionState := component.PhysicalSectionStateType.Get(axleSectionEntry) + axleDevice := component.AxlePhysicalSectionType.Get(axleSectionEntry) // - s.calculateHf(axleCounterEntry, axleSectionEntry) - s.calculateDrst(axleCounterEntry) - s.calculatePdrst(axleCounterEntry) - s.calculateSectionState(axleCounterEntry, axleSectionEntry) - s.calculateAxleCount(axleCounterEntry, axleSectionEntry) + s.calculateHf(axleSectionEntry, sectionState, axleDevice, axleRuntime) + s.calculateDrst(sectionState, axleDevice, axleRuntime) + s.calculatePdrst(sectionState, axleDevice, axleRuntime) + s.calculateSectionState(sectionState, axleDevice, axleRuntime) + s.calculateAxleCount(sectionState, axleDevice, axleRuntime) - if "北京_12_酒仙桥_12G" == axleSectionId && false { - section := component.AxleSectionType.Get(axleSectionEntry) - counter := component.AxleCounterType.Get(axleCounterEntry) - counterRt := component.AxleCounterRuntimeType.Get(axleCounterEntry) - sectionFault := component.AxleSectionFaultType.Get(axleSectionEntry) + if "北京_12_酒仙桥_12G" == axleSectionId && true { + sectionFault := axleSectionEntry.HasComponent(component.AxleSectionFaultTag) slog.Info(axleSectionId, - "Drst", counterRt.Drst, - "Pdrst", counterRt.Pdrst, - "DoingPdrst", counterRt.DoingPdrst, - "Rac", counterRt.Rac, - "Rjo", counterRt.Rjo, - "Rjt", counterRt.Rjt, - "SectionFault", sectionFault.SectionFault, - "Occ", section.Occ, - "Count", counter.Count, - "Wave", counter.ShowCountWave()) + "Drst", axleRuntime.Drst, + "Pdrst", axleRuntime.Pdrst, + "DoingPdrst", axleRuntime.DoingPdrst, + "Rac", axleRuntime.Rac, + "Rjo", axleRuntime.Rjo, + "Rjt", axleRuntime.Rjt, + "SectionFault", sectionFault, + "Occ", sectionState.Occ, + "Count", axleDevice.Count, + "Wave", axleDevice.ShowCountWave()) } - } }) } // 计算计轴区段内车轴数 // 目前通过查看有哪些车在该计轴区段内实现,定性 -func (s *FaDcAxleDeviceSystem) calculateAxleCount(axleCounterEntry *donburi.Entry, axleSectionEntry *donburi.Entry) { +func (s *FaDcAxleDeviceSystem) calculateAxleCount(sectionState *component.PhysicalSectionState, axleDevice *component.AxlePhysicalSection, axleRuntime *component.AxleDeviceRuntime) { //检查该区段内有没有车 // ...todo } // 计算计轴区段状态 -func (s *FaDcAxleDeviceSystem) calculateSectionState(axleCounterEntry *donburi.Entry, axleSectionEntry *donburi.Entry) { - section := component.AxleSectionType.Get(axleSectionEntry) - counter := component.AxleCounterType.Get(axleCounterEntry) - counterRt := component.AxleCounterRuntimeType.Get(axleCounterEntry) - isIdle := counter.Count <= 0 && !counterRt.DoingPdrst //区段空闲:区段内车轴数为零且没有预复位 - section.Occ = !isIdle +func (s *FaDcAxleDeviceSystem) calculateSectionState(sectionState *component.PhysicalSectionState, axleDevice *component.AxlePhysicalSection, axleRuntime *component.AxleDeviceRuntime) { + + isIdle := axleDevice.Count <= 0 && !axleRuntime.DoingPdrst //区段空闲:区段内车轴数为零且没有预复位 + sectionState.Occ = !isIdle } // 计轴直接复位 -func (s *FaDcAxleDeviceSystem) calculateDrst(axleCounterEntry *donburi.Entry) { - counter := component.AxleCounterType.Get(axleCounterEntry) - counterRt := component.AxleCounterRuntimeType.Get(axleCounterEntry) - if counterRt.Drst && !counterRt.Rjo && !counterRt.Rjt { //直接复位且没有拒绝原因 - counter.UpdateCount(0) - counter.ResetCountPulse() - counterRt.DoingPdrst = false +func (s *FaDcAxleDeviceSystem) calculateDrst(sectionState *component.PhysicalSectionState, axleDevice *component.AxlePhysicalSection, axleRuntime *component.AxleDeviceRuntime) { + + if axleRuntime.Drst && !axleRuntime.Rjo && !axleRuntime.Rjt { //直接复位且没有拒绝原因 + axleDevice.UpdateCount(0) + axleDevice.ResetCountPulse() + axleRuntime.DoingPdrst = false } } // 计轴预复位 -func (s *FaDcAxleDeviceSystem) calculatePdrst(axleCounterEntry *donburi.Entry) { - counter := component.AxleCounterType.Get(axleCounterEntry) - counterRt := component.AxleCounterRuntimeType.Get(axleCounterEntry) - if counterRt.Pdrst && !counterRt.Rjo && !counterRt.Rjt && !counterRt.DoingPdrst { //预复位且没有拒绝原因 - counter.UpdateCount(0) - counter.ResetCountPulse() - counterRt.DoingPdrst = true +func (s *FaDcAxleDeviceSystem) calculatePdrst(sectionState *component.PhysicalSectionState, axleDevice *component.AxlePhysicalSection, axleRuntime *component.AxleDeviceRuntime) { + + if axleRuntime.Pdrst && !axleRuntime.Rjo && !axleRuntime.Rjt && !axleRuntime.DoingPdrst { //预复位且没有拒绝原因 + axleDevice.UpdateCount(0) + axleDevice.ResetCountPulse() + axleRuntime.DoingPdrst = true } //压道车通过该计轴区段,完成计轴预复位 - if counter.IsCount010Pulse() { - counterRt.DoingPdrst = false + if axleDevice.IsCount010Pulse() { + axleRuntime.DoingPdrst = false } } // 复位回复运算 -func (s *FaDcAxleDeviceSystem) calculateHf(axleCounterEntry *donburi.Entry, axleSectionEntry *donburi.Entry) { - section := component.AxleSectionType.Get(axleSectionEntry) - sectionFault := component.AxleSectionFaultType.Get(axleSectionEntry) - counterRt := component.AxleCounterRuntimeType.Get(axleCounterEntry) - counterRt.Rac = counterRt.Drst || counterRt.Pdrst - counterRt.Rjo = counterRt.Rac && !section.Occ && !counterRt.DoingPdrst //空闲拒绝复位(排除预复位过程中) - counterRt.Rjt = counterRt.Rac && sectionFault.SectionFault // 技术原因拒绝复位 +func (s *FaDcAxleDeviceSystem) calculateHf(axleSectionEntry *ecs.Entry, sectionState *component.PhysicalSectionState, axleDevice *component.AxlePhysicalSection, axleRuntime *component.AxleDeviceRuntime) { + sectionFault := axleSectionEntry.HasComponent(component.AxleSectionFaultTag) + axleRuntime.Rac = axleRuntime.Drst || axleRuntime.Pdrst + axleRuntime.Rjo = axleRuntime.Rac && !sectionState.Occ && !axleRuntime.DoingPdrst //空闲拒绝复位(排除预复位过程中) + axleRuntime.Rjt = axleRuntime.Rac && sectionFault // 技术原因拒绝复位 } From 618af297ae8eac4c39a2dc1d6371f4db4b956008 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Mon, 6 Nov 2023 15:30:57 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E8=AE=A1=E8=BD=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- component/physical_section.go | 3 +++ entity/fadc_axle.go | 5 ++++- fi/section.go | 4 ++-- sys/device_sys/fadc_axle_device.go | 3 +-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/component/physical_section.go b/component/physical_section.go index 80e1372..30c0003 100644 --- a/component/physical_section.go +++ b/component/physical_section.go @@ -52,6 +52,9 @@ type AxleManageDevice struct { Adrs map[string]*AxleDeviceRuntime //key-sectionId } +func (d *AxleManageDevice) FindAdr(sectionId string) *AxleDeviceRuntime { + return d.Adrs[sectionId] +} func NewAxleManageDevice(centralizedStation string) *AxleManageDevice { return &AxleManageDevice{CentralizedStation: centralizedStation, Adrs: make(map[string]*AxleDeviceRuntime)} } diff --git a/entity/fadc_axle.go b/entity/fadc_axle.go index 43ef38e..f8e2bd1 100644 --- a/entity/fadc_axle.go +++ b/entity/fadc_axle.go @@ -24,7 +24,10 @@ func LoadAxlePhysicalSections(w ecs.World) error { if len(strings.TrimSpace(section.CentralizedStation())) == 0 { return fmt.Errorf("区段[%s]未设置所属集中站", section.Id()) } - amdEntry := newAxleManageDevice(w, data, section.CentralizedStation()) + amdEntry := FindAxleManageDevice(data, section.CentralizedStation()) + if amdEntry == nil { + amdEntry = newAxleManageDevice(w, data, section.CentralizedStation()) + } amd := component.AxleManageDeviceType.Get(amdEntry) // createAxleSectionEntity(w, section, data) diff --git a/fi/section.go b/fi/section.go index fea5f75..f02fc46 100644 --- a/fi/section.go +++ b/fi/section.go @@ -24,8 +24,8 @@ func AxleSectionDrstDrive(w ecs.World, sectionId string, set bool) error { return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]实体不存在", sectionModel.CentralizedStation())) } faDcAxleDevice := component.AxleManageDeviceType.Get(faDcAxleDeviceEntry) - axleRuntime, ok := faDcAxleDevice.Adrs[sectionId] - if !ok { + axleRuntime := faDcAxleDevice.FindAdr(sectionId) + if axleRuntime == nil { return ecs.NewErrResult(fmt.Errorf("计轴管理设备[%s]中不存在区段[%s]的计轴设备", sectionModel.CentralizedStation(), sectionId)) } axleRuntime.Drst = set diff --git a/sys/device_sys/fadc_axle_device.go b/sys/device_sys/fadc_axle_device.go index 564c8c3..5a935c9 100644 --- a/sys/device_sys/fadc_axle_device.go +++ b/sys/device_sys/fadc_axle_device.go @@ -34,7 +34,7 @@ func (s *FaDcAxleDeviceSystem) Update(w ecs.World) { s.calculateSectionState(sectionState, axleDevice, axleRuntime) s.calculateAxleCount(sectionState, axleDevice, axleRuntime) - if "北京_12_酒仙桥_12G" == axleSectionId && true { + if "北京_12_酒仙桥_12G" == axleSectionId && false { sectionFault := axleSectionEntry.HasComponent(component.AxleSectionFaultTag) slog.Info(axleSectionId, "Drst", axleRuntime.Drst, @@ -61,7 +61,6 @@ func (s *FaDcAxleDeviceSystem) calculateAxleCount(sectionState *component.Physic // 计算计轴区段状态 func (s *FaDcAxleDeviceSystem) calculateSectionState(sectionState *component.PhysicalSectionState, axleDevice *component.AxlePhysicalSection, axleRuntime *component.AxleDeviceRuntime) { - isIdle := axleDevice.Count <= 0 && !axleRuntime.DoingPdrst //区段空闲:区段内车轴数为零且没有预复位 sectionState.Occ = !isIdle } From 46507159c54691430dcec9f0ae9cb09ea66e2e7d Mon Sep 17 00:00:00 2001 From: walker Date: Mon, 6 Nov 2023 17:32:34 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=B0=86=E9=9B=B6=E6=95=A3=E7=BB=84?= =?UTF-8?q?=E5=90=88=E7=9A=84=E7=BB=A7=E7=94=B5=E5=99=A8=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E8=BF=9B=E4=BB=BF=E7=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/ci_qc.go | 1 + entity/init.go | 1 + entity/station.go | 9 +++++++++ fi/ci_qc.go | 5 +++++ repository/repository_manager.go | 18 +++++++++++++++++- repository/station.go | 9 +++++++-- sys/bind.go | 1 + 7 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 fi/ci_qc.go diff --git a/entity/ci_qc.go b/entity/ci_qc.go index 027e04d..608cee6 100644 --- a/entity/ci_qc.go +++ b/entity/ci_qc.go @@ -23,6 +23,7 @@ func LoadCiQC(w ecs.World) error { // if len(csr.QdList) == 0 { // return fmt.Errorf("加载联锁驱采卡实体失败,车站'%s'无驱动码表数据", csr.StationId) // } + // 加载联锁驱采卡实体 if len(csr.CjList) == 0 || len(csr.QdList) == 0 { slog.Warn("加载联锁驱采卡实体失败,无驱动/采集码表数据", "车站", csr.StationId) continue diff --git a/entity/init.go b/entity/init.go index fa8aa36..6be3570 100644 --- a/entity/init.go +++ b/entity/init.go @@ -9,6 +9,7 @@ import ( func Load(w ecs.World, repo *repository.Repository) error { // 初始化世界数据单例组件 LoadWorldData(w, repo) + // 加载联锁驱采卡相关实体 err := LoadCiQC(w) if err != nil { return err diff --git a/entity/station.go b/entity/station.go index 5e357d2..d62adc6 100644 --- a/entity/station.go +++ b/entity/station.go @@ -3,12 +3,21 @@ package entity import ( "joylink.club/ecs" "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/repository" ) func LoadStations(w ecs.World) error { data := GetWorldData(w) stations := data.Repo.StationList() + // 加载零散组合继电器 for _, station := range stations { + for _, ecg := range station.ComponentGroups() { + if ecg.Code() == "LS" { + for _, ele := range ecg.Components() { + NewRelayEntity(w, ele.(*repository.Relay), data.EntityMap) + } + } + } entry := NewStationEntity(w, station.Id(), data) if station.GetIbpSpk() != nil { // 人员防护 LoadSPKEntity(w, entry, station.GetIbpSpk(), data) diff --git a/fi/ci_qc.go b/fi/ci_qc.go new file mode 100644 index 0000000..6750648 --- /dev/null +++ b/fi/ci_qc.go @@ -0,0 +1,5 @@ +package fi + +func GetCiQcState() { + +} diff --git a/repository/repository_manager.go b/repository/repository_manager.go index fc15136..bd81334 100644 --- a/repository/repository_manager.go +++ b/repository/repository_manager.go @@ -862,8 +862,24 @@ func buildStationRelationShip(source *proto.Repository, repo *Repository) error bindIbpDevice(repo, ref.Components, station.GetIbpEmp()) case "SPKS": bindIbpDevice(repo, ref.Components, station.GetIbpSpk()) + case "LS": + { + var components []IGroupedElectronicComponent + for _, cmp := range ref.Components { + switch cmp.DeviceType { + case proto.DeviceType_DeviceType_Relay: + components = append(components, repo.relayMap[cmp.Id]) + default: + return fmt.Errorf("集中站'%s'的LS组合数据异常,包含非继电器设备: type=%s, id=%s", station.Id(), cmp.DeviceType, cmp.Id) + } + } + station.componentGroups = append(station.componentGroups, &ElectronicComponentGroup{ + code: ref.Code, + components: components, + }) + } default: - slog.Warn("车站实体未实现【%s】绑定逻辑", ref.Code) + slog.Warn("未知的车站组合", "组合code", ref.Code) } } } diff --git a/repository/station.go b/repository/station.go index 1b5fd87..fcfa22f 100644 --- a/repository/station.go +++ b/repository/station.go @@ -4,8 +4,9 @@ import "joylink.club/rtsssimulation/repository/model/proto" type Station struct { Identity - code string - ibp *IBP + code string + ibp *IBP + componentGroups []*ElectronicComponentGroup } func NewStation(id, code string) *Station { @@ -27,3 +28,7 @@ func (s *Station) GetIbpEmp() *IBPRefMap { func (s *Station) GetIbpSpk() *IBPRefMap { return s.ibp.Spk } + +func (s *Station) ComponentGroups() []*ElectronicComponentGroup { + return s.componentGroups +} diff --git a/sys/bind.go b/sys/bind.go index cd6a8d9..9985c31 100644 --- a/sys/bind.go +++ b/sys/bind.go @@ -17,6 +17,7 @@ func BindSystem(w ecs.World) { device_sys.NewDBQSys(), device_sys.NewZzjSys(), device_sys.NewTurnoutSys(), + device_sys.NewCiQcSys(), circuit_sys.NewZdj9TwoDragSys(), circuit_sys.NewSignal2XH1System(), circuit_sys.NewSignal3XH1System(), From 51203ce53c5f2b9932ee9faef6a56eabda921b51 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Tue, 7 Nov 2023 13:22:39 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E8=AE=A1=E8=BD=B4rssp=20=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fi/section.go | 101 ++++++++++++++++++++++++++++++++++++++++++ proto/src/model.proto | 8 ++++ 2 files changed, 109 insertions(+) diff --git a/fi/section.go b/fi/section.go index f02fc46..f7f9b03 100644 --- a/fi/section.go +++ b/fi/section.go @@ -5,6 +5,7 @@ import ( "joylink.club/ecs" "joylink.club/rtsssimulation/component" "joylink.club/rtsssimulation/entity" + "strings" ) // AxleSectionDrstDrive 计轴直接复位操作 @@ -122,3 +123,103 @@ func AxleSectionTrainDrive(w ecs.World, sectionId string, trainIn bool) error { }) return r.Err } + +// FindAxleSectionsStatus 获取计轴区段的相关状态 +func FindAxleSectionsStatus(w ecs.World, sectionIds []string) ([]*AxleSectionState, error) { + r := <-ecs.Request[[]*AxleSectionState](w, func() ecs.Result[[]*AxleSectionState] { + wd := entity.GetWorldData(w) + var msg []*AxleSectionState + var esb = strings.Builder{} //收集未找到的区段的id + for _, sectionId := range sectionIds { + find := false + sectionModel := wd.Repo.FindPhysicalSection(sectionId) + if sectionModel != nil { + faDcAxleDeviceEntry := entity.FindAxleManageDevice(wd, sectionModel.CentralizedStation()) + if faDcAxleDeviceEntry != nil { + faDcAxleDevice := component.AxleManageDeviceType.Get(faDcAxleDeviceEntry) + axleDevice := faDcAxleDevice.FindAdr(sectionId) + if axleDevice != nil { + sectionEntry, _ := entity.GetEntityByUid(w, sectionId) + if sectionEntry != nil { + if sectionEntry.HasComponent(component.AxlePhysicalSectionType) { //计轴物理区段实体 + as := &AxleSectionState{} + state := component.PhysicalSectionStateType.Get(sectionEntry) + as.Clr = !state.Occ + as.Occ = state.Occ + as.Rac = axleDevice.Rac + as.Rjt = axleDevice.Rjt + as.Rjo = axleDevice.Rjo + // + msg = append(msg, as) + find = true + } + } + } + } + } + // + if !find { + esb.WriteString(fmt.Sprintf("%s,", sectionId)) + } + } //for + if esb.Len() > 0 { + return ecs.NewResult(msg, fmt.Errorf("区段非计轴区段或计轴区段状态不存在:[%s]", esb.String())) + } else { + return ecs.NewResult(msg, nil) + } + }) + return r.Val, r.Err +} + +type AxleSectionState struct { + //0-bit7 计轴出清 + Clr bool + //0-bit6 计轴占用 + Occ bool + //1-bit6 计轴复位反馈 + Rac bool + //1-bit5 运营原因拒绝计轴复位 + Rjo bool + //1-bit4 技术原因拒绝计轴复位 + Rjt bool +} + +// AxleSectionRstDrive 复位(直接复位、预复位) +func AxleSectionRstDrive(w ecs.World, cmds []*AxleSectionCmd) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + var esb = strings.Builder{} //收集未找到的区段的id + find := false + for _, cmd := range cmds { + sectionId := cmd.SectionId + sectionModel := wd.Repo.FindPhysicalSection(sectionId) + if sectionModel != nil { + faDcAxleDeviceEntry := entity.FindAxleManageDevice(wd, sectionModel.CentralizedStation()) + if faDcAxleDeviceEntry != nil { + faDcAxleDevice := component.AxleManageDeviceType.Get(faDcAxleDeviceEntry) + axleRuntime := faDcAxleDevice.FindAdr(sectionId) + if axleRuntime != nil { + axleRuntime.Pdrst = cmd.Pdrst + axleRuntime.Drst = cmd.Drst + find = true + } + } + } + if !find { + esb.WriteString(fmt.Sprintf("%s,", sectionId)) + } + } //for + if esb.Len() > 0 { + return ecs.NewErrResult(fmt.Errorf("计轴区段复位操作,失败列表[%s]", esb.String())) + } else { + return ecs.NewOkEmptyResult() + } + }) + return r.Err +} + +type AxleSectionCmd struct { + SectionId string + Drst bool + Pdrst bool +} diff --git a/proto/src/model.proto b/proto/src/model.proto index 6b1c610..e3b6d77 100644 --- a/proto/src/model.proto +++ b/proto/src/model.proto @@ -300,6 +300,8 @@ message CentralizedStationRef { repeated CjData cjList = 3; // 采集继电器配置信息 repeated QdData qdList = 4; // 驱动继电器配置信息 + + repeated CiSectionCodePoint sectionCodePoints = 5;//物理区段码表 } message CjData { @@ -325,3 +327,9 @@ message AsdGroup { int32 start = 2; //起始子门索引 int32 end = 3; //终止子门索引 } + +//联锁物理区段码位 +message CiSectionCodePoint{ + int32 row = 1;//所在行 + string sectionId = 2;//物理区段id +} \ No newline at end of file From 3b13603d65292c8802afa1a285fdd73fd6701a4f Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Tue, 7 Nov 2023 13:26:29 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E8=AE=A1=E8=BD=B4rssp=20=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- repository/model/proto/model.pb.go | 237 ++++++++++++++++++++--------- 1 file changed, 162 insertions(+), 75 deletions(-) diff --git a/repository/model/proto/model.pb.go b/repository/model/proto/model.pb.go index 6cc7a80..52ef8ad 100644 --- a/repository/model/proto/model.pb.go +++ b/repository/model/proto/model.pb.go @@ -2390,10 +2390,11 @@ type CentralizedStationRef struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StationId string `protobuf:"bytes,1,opt,name=stationId,proto3" json:"stationId,omitempty"` // 集中站ID - TransponderId []string `protobuf:"bytes,2,rep,name=transponderId,proto3" json:"transponderId,omitempty"` // 应答器ID - CjList []*CjData `protobuf:"bytes,3,rep,name=cjList,proto3" json:"cjList,omitempty"` // 采集继电器配置信息 - QdList []*QdData `protobuf:"bytes,4,rep,name=qdList,proto3" json:"qdList,omitempty"` // 驱动继电器配置信息 + StationId string `protobuf:"bytes,1,opt,name=stationId,proto3" json:"stationId,omitempty"` // 集中站ID + TransponderId []string `protobuf:"bytes,2,rep,name=transponderId,proto3" json:"transponderId,omitempty"` // 应答器ID + CjList []*CjData `protobuf:"bytes,3,rep,name=cjList,proto3" json:"cjList,omitempty"` // 采集继电器配置信息 + QdList []*QdData `protobuf:"bytes,4,rep,name=qdList,proto3" json:"qdList,omitempty"` // 驱动继电器配置信息 + SectionCodePoints []*CiSectionCodePoint `protobuf:"bytes,5,rep,name=sectionCodePoints,proto3" json:"sectionCodePoints,omitempty"` //物理区段码表 } func (x *CentralizedStationRef) Reset() { @@ -2456,6 +2457,13 @@ func (x *CentralizedStationRef) GetQdList() []*QdData { return nil } +func (x *CentralizedStationRef) GetSectionCodePoints() []*CiSectionCodePoint { + if x != nil { + return x.SectionCodePoints + } + return nil +} + type CjData struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2701,6 +2709,62 @@ func (x *AsdGroup) GetEnd() int32 { return 0 } +// 联锁物理区段码位 +type CiSectionCodePoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Row int32 `protobuf:"varint,1,opt,name=row,proto3" json:"row,omitempty"` //所在行 + SectionId string `protobuf:"bytes,2,opt,name=sectionId,proto3" json:"sectionId,omitempty"` //物理区段id +} + +func (x *CiSectionCodePoint) Reset() { + *x = CiSectionCodePoint{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CiSectionCodePoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CiSectionCodePoint) ProtoMessage() {} + +func (x *CiSectionCodePoint) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CiSectionCodePoint.ProtoReflect.Descriptor instead. +func (*CiSectionCodePoint) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{29} +} + +func (x *CiSectionCodePoint) GetRow() int32 { + if x != nil { + return x.Row + } + return 0 +} + +func (x *CiSectionCodePoint) GetSectionId() string { + if x != nil { + return x.SectionId + } + return "" +} + var File_model_proto protoreflect.FileDescriptor var file_model_proto_rawDesc = []byte{ @@ -3004,7 +3068,7 @@ var file_model_proto_rawDesc = []byte{ 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x65, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x04, 0x67, 0x65, 0x61, 0x72, 0x22, 0xa9, 0x01, 0x0a, 0x15, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, + 0x04, 0x67, 0x65, 0x61, 0x72, 0x22, 0xf2, 0x01, 0x0a, 0x15, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a, @@ -3015,68 +3079,77 @@ var file_model_proto_rawDesc = []byte{ 0x74, 0x61, 0x52, 0x06, 0x63, 0x6a, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x71, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x51, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x71, 0x64, 0x4c, 0x69, 0x73, - 0x74, 0x22, 0x5d, 0x0a, 0x06, 0x43, 0x6a, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72, - 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x6f, 0x77, 0x12, 0x10, 0x0a, - 0x03, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x63, 0x6f, 0x6c, 0x12, - 0x2f, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x43, 0x6a, 0x44, 0x61, 0x74, - 0x61, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, - 0x22, 0x34, 0x0a, 0x0a, 0x43, 0x6a, 0x44, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x18, - 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x0a, 0x01, 0x71, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x01, 0x71, 0x22, 0x4a, 0x0a, 0x06, 0x51, 0x64, 0x44, 0x61, 0x74, 0x61, - 0x12, 0x10, 0x0a, 0x03, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, - 0x6f, 0x77, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x03, 0x63, 0x6f, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, - 0x79, 0x73, 0x22, 0x48, 0x0a, 0x08, 0x41, 0x73, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, - 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x2a, 0xfd, 0x03, 0x0a, - 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x5f, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x5f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x16, - 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x75, 0x72, - 0x6e, 0x6f, 0x75, 0x74, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x1a, 0x0a, - 0x16, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x6c, 0x6f, 0x70, 0x65, 0x10, 0x06, 0x12, - 0x21, 0x0a, 0x1d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x43, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x10, 0x09, - 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, - 0x65, 0x6c, 0x61, 0x79, 0x10, 0x0a, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x68, 0x61, 0x73, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x0b, 0x12, 0x15, 0x0a, 0x11, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74, 0x6f, - 0x6e, 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x5f, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x10, 0x0e, 0x12, - 0x12, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x73, - 0x64, 0x10, 0x0f, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x10, 0x12, 0x12, 0x0a, 0x0e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6b, 0x78, 0x10, 0x11, 0x12, - 0x12, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4b, 0x65, - 0x79, 0x10, 0x12, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x5f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0x13, 0x2a, 0x25, 0x0a, 0x04, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x05, - 0x0a, 0x01, 0x41, 0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x02, 0x12, 0x05, 0x0a, 0x01, - 0x43, 0x10, 0x03, 0x2a, 0x20, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x45, 0x46, 0x54, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x10, 0x01, 0x2a, 0x43, 0x0a, 0x0e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x6f, 0x75, 0x6e, 0x64, - 0x61, 0x72, 0x79, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x78, 0x6c, 0x65, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x65, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x75, 0x6c, 0x61, - 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x12, 0x47, 0x0a, 0x11, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x43, 0x69, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x64, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x11, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x64, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x5d, 0x0a, 0x06, 0x43, 0x6a, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x03, 0x72, 0x6f, 0x77, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x03, 0x63, 0x6f, 0x6c, 0x12, 0x2f, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x52, + 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x2e, 0x43, 0x6a, 0x44, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x09, + 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x22, 0x34, 0x0a, 0x0a, 0x43, 0x6a, 0x44, + 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, + 0x64, 0x12, 0x0c, 0x0a, 0x01, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x01, 0x71, 0x22, + 0x4a, 0x0a, 0x06, 0x51, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x6f, 0x77, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x6f, 0x77, 0x12, 0x10, 0x0a, 0x03, 0x63, + 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x63, 0x6f, 0x6c, 0x12, 0x1c, 0x0a, + 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x22, 0x48, 0x0a, 0x08, 0x41, + 0x73, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x43, 0x69, 0x53, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x72, + 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x6f, 0x77, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x2a, 0xfd, 0x03, 0x0a, 0x0a, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x16, 0x0a, + 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x75, 0x72, 0x6e, + 0x6f, 0x75, 0x74, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x6c, 0x6f, 0x70, 0x65, 0x10, 0x06, 0x12, 0x21, + 0x0a, 0x1d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x43, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, + 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x10, 0x09, 0x12, + 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x65, + 0x6c, 0x61, 0x79, 0x10, 0x0a, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x50, 0x68, 0x61, 0x73, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x0b, 0x12, 0x15, 0x0a, 0x11, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x10, 0x0e, 0x12, 0x12, + 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x73, 0x64, + 0x10, 0x0f, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x10, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6b, 0x78, 0x10, 0x11, 0x12, 0x12, + 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4b, 0x65, 0x79, + 0x10, 0x12, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0x13, 0x2a, 0x25, 0x0a, 0x04, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x05, 0x0a, + 0x01, 0x41, 0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x02, 0x12, 0x05, 0x0a, 0x01, 0x43, + 0x10, 0x03, 0x2a, 0x20, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x08, 0x0a, 0x04, 0x4c, 0x45, 0x46, 0x54, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x10, 0x01, 0x2a, 0x43, 0x0a, 0x0e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x61, + 0x72, 0x79, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x78, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x75, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x4a, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3092,7 +3165,7 @@ func file_model_proto_rawDescGZIP() []byte { } var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 9) -var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 29) +var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_model_proto_goTypes = []interface{}{ (DeviceType)(0), // 0: model.DeviceType (Port)(0), // 1: model.Port @@ -3132,6 +3205,7 @@ var file_model_proto_goTypes = []interface{}{ (*CjDataItem)(nil), // 35: model.CjDataItem (*QdData)(nil), // 36: model.QdData (*AsdGroup)(nil), // 37: model.AsdGroup + (*CiSectionCodePoint)(nil), // 38: model.CiSectionCodePoint } var file_model_proto_depIdxs = []int32{ 10, // 0: model.Repository.physicalSections:type_name -> model.PhysicalSection @@ -3187,12 +3261,13 @@ var file_model_proto_depIdxs = []int32{ 0, // 50: model.ElectronicComponent.deviceType:type_name -> model.DeviceType 34, // 51: model.CentralizedStationRef.cjList:type_name -> model.CjData 36, // 52: model.CentralizedStationRef.qdList:type_name -> model.QdData - 35, // 53: model.CjData.refRelays:type_name -> model.CjDataItem - 54, // [54:54] is the sub-list for method output_type - 54, // [54:54] is the sub-list for method input_type - 54, // [54:54] is the sub-list for extension type_name - 54, // [54:54] is the sub-list for extension extendee - 0, // [0:54] is the sub-list for field type_name + 38, // 53: model.CentralizedStationRef.sectionCodePoints:type_name -> model.CiSectionCodePoint + 35, // 54: model.CjData.refRelays:type_name -> model.CjDataItem + 55, // [55:55] is the sub-list for method output_type + 55, // [55:55] is the sub-list for method input_type + 55, // [55:55] is the sub-list for extension type_name + 55, // [55:55] is the sub-list for extension extendee + 0, // [0:55] is the sub-list for field type_name } func init() { file_model_proto_init() } @@ -3549,6 +3624,18 @@ func file_model_proto_init() { return nil } } + file_model_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CiSectionCodePoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -3556,7 +3643,7 @@ func file_model_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_model_proto_rawDesc, NumEnums: 9, - NumMessages: 29, + NumMessages: 30, NumExtensions: 0, NumServices: 0, }, From a6dfa6fffb7ecfe6630280a838092d208c0e3c1a Mon Sep 17 00:00:00 2001 From: joylink_zhangsai <1021828630@qq.com> Date: Tue, 7 Nov 2023 14:30:07 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9E=84=E5=BB=BAbug=EF=BC=9B=E5=B1=8F?= =?UTF-8?q?=E8=94=BD=E9=97=A8=E6=89=80=E6=9C=89=E7=BB=A7=E7=94=B5=E5=99=A8?= =?UTF-8?q?=E9=83=BD=E4=BC=9A=E6=9E=84=E5=BB=BA=E4=B8=BA=E5=AE=9E=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- component/psd.go | 2 ++ entity/psd.go | 2 ++ repository/platform.go | 13 ++++++++----- repository/repository_manager.go | 32 +++++++++++++++++++++++++++----- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/component/psd.go b/component/psd.go index a443862..17a6918 100644 --- a/component/psd.go +++ b/component/psd.go @@ -19,6 +19,8 @@ type PsdCircuit struct { //屏蔽门表示继电器 MGJ *ecs.Entry MPLJ *ecs.Entry + //一些不知道如何使用的继电器,为了使得采集、驱动逻辑正常,先构建出来 + UnusedJ []*ecs.Entry } var PsdInterlockDriveCircuitType = ecs.NewComponentType[PsdInterlockDriveCircuit]() diff --git a/entity/psd.go b/entity/psd.go index f963913..2f0db61 100644 --- a/entity/psd.go +++ b/entity/psd.go @@ -59,6 +59,8 @@ func loadPsdCircuit(world ecs.World, entry *ecs.Entry, psd *repository.Psd, entr circuit.MGJ = NewRelayEntity(world, relay, entryMap) case "XMPLJ", "SMPLJ": circuit.MPLJ = NewRelayEntity(world, relay, entryMap) + default: + circuit.UnusedJ = append(circuit.UnusedJ, NewRelayEntity(world, relay, entryMap)) } } } diff --git a/repository/platform.go b/repository/platform.go index 0c30117..a34c152 100644 --- a/repository/platform.go +++ b/repository/platform.go @@ -8,11 +8,14 @@ type Platform struct { station *Station } -func NewPlatform(id string) *Platform { - return &Platform{Identity: identity{ - id: id, - deviceType: proto.DeviceType_DeviceType_Platform, - }} +func NewPlatform(id string, code string) *Platform { + return &Platform{ + Identity: identity{ + id: id, + deviceType: proto.DeviceType_DeviceType_Platform, + }, + code: code, + } } func (p *Platform) Code() string { diff --git a/repository/repository_manager.go b/repository/repository_manager.go index bd81334..a043a18 100644 --- a/repository/repository_manager.go +++ b/repository/repository_manager.go @@ -3,12 +3,11 @@ package repository import ( "errors" "fmt" + "joylink.club/rtsssimulation/repository/model/proto" + "joylink.club/rtsssimulation/util/number" "log/slog" "math" "strconv" - - "joylink.club/rtsssimulation/repository/model/proto" - "joylink.club/rtsssimulation/util/number" ) var repositoryMap = make(map[string]*Repository) @@ -112,7 +111,6 @@ func buildModels(source *proto.Repository, repository *Repository) error { m := newPsd(protoData.Id, protoData.AsdAmount, protoData.AsdGroups) repository.psdMap[m.Id()] = m } - for _, protoData := range source.Lights { m := NewLight(protoData.Id, protoData.Code) repository.lightMap[m.Id()] = m @@ -121,7 +119,6 @@ func buildModels(source *proto.Repository, repository *Repository) error { m := NewAlarm(protoData.Id, protoData.Code) repository.alarmMap[m.Id()] = m } - for _, protoData := range source.Mkxs { m := NewMkx(protoData.Id) repository.mkxMap[m.Id()] = m @@ -130,6 +127,10 @@ func buildModels(source *proto.Repository, repository *Repository) error { m := NewKey(protoData.Id, protoData.Code, protoData.Gear) repository.keyMap[m.Id()] = m } + for _, protoData := range source.Platforms { + m := NewPlatform(protoData.Id, protoData.Code) + repository.platformMap[m.Id()] = m + } err := repository.generateCoordinateInfo(source.MainCoordinateSystem) for _, protoData := range source.CentralizedStationRefs { repository.centralizedMap[protoData.StationId] = protoData @@ -174,9 +175,25 @@ func buildModelRelationship(source *proto.Repository, repository *Repository) er if err != nil { return err } + err = buildPlatformRelationShip(source, repository) + if err != nil { + return err + } return err } +func buildPlatformRelationShip(source *proto.Repository, repo *Repository) error { + for _, protoData := range source.Platforms { + platform := repo.platformMap[protoData.Id] + station := repo.stationMap[protoData.StationId] + if station == nil { + return fmt.Errorf("站台[id:%s]关联的车站[id:%s]不存在", platform.Id(), protoData.StationId) + } + platform.station = station + } + return nil +} + func buildMkxRelationShip(source *proto.Repository, repo *Repository) error { for _, protoData := range source.Mkxs { mkx := repo.mkxMap[protoData.Id] @@ -194,6 +211,11 @@ func buildMkxRelationShip(source *proto.Repository, repo *Repository) error { func buildPsdRelationShip(source *proto.Repository, repo *Repository) error { for _, protoData := range source.Psds { psd := repo.psdMap[protoData.Id] + platform := repo.platformMap[protoData.PlatformId] + if platform == nil { + return fmt.Errorf("屏蔽门[id:%s]关联的站台[id:%s]不存在", psd.Id(), protoData.PlatformId) + } + psd.platform = platform for _, group := range protoData.ElectronicComponentGroups { var components []IGroupedElectronicComponent for _, id := range group.GetComponentIds() { From 45b4f4f0fe4eaf1eae6f31cca8d0b14237596bf1 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Tue, 7 Nov 2023 17:47:41 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E8=AE=A1=E8=BD=B4rssp=20=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fi/section.go | 3 +++ jl-ecs-go | 2 +- repository/repository.go | 4 +++- repository/repository_manager.go | 12 +++++++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/fi/section.go b/fi/section.go index f7f9b03..d596ceb 100644 --- a/fi/section.go +++ b/fi/section.go @@ -144,6 +144,7 @@ func FindAxleSectionsStatus(w ecs.World, sectionIds []string) ([]*AxleSectionSta if sectionEntry.HasComponent(component.AxlePhysicalSectionType) { //计轴物理区段实体 as := &AxleSectionState{} state := component.PhysicalSectionStateType.Get(sectionEntry) + as.Id = component.UidType.Get(sectionEntry).Id as.Clr = !state.Occ as.Occ = state.Occ as.Rac = axleDevice.Rac @@ -172,6 +173,8 @@ func FindAxleSectionsStatus(w ecs.World, sectionIds []string) ([]*AxleSectionSta } type AxleSectionState struct { + //uid + Id string //0-bit7 计轴出清 Clr bool //0-bit6 计轴占用 diff --git a/jl-ecs-go b/jl-ecs-go index e1a4fb8..3a98a65 160000 --- a/jl-ecs-go +++ b/jl-ecs-go @@ -1 +1 @@ -Subproject commit e1a4fb8476c783332fc58c9d44a670de85cd7261 +Subproject commit 3a98a65dada5738714a362fbdba0853cb73ae24b diff --git a/repository/repository.go b/repository/repository.go index 84ee0f8..1c98cda 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -190,7 +190,9 @@ func (repo *Repository) CiQcList() []*proto.CentralizedStationRef { } return list } - +func (repo *Repository) GetCentralizedStationRef(centralizedStationId string) *proto.CentralizedStationRef { + return repo.centralizedMap[centralizedStationId] +} func (repo *Repository) FindModel(deviceId string, deviceType proto.DeviceType) (Identity, error) { switch deviceType { case proto.DeviceType_DeviceType_PhysicalSection: diff --git a/repository/repository_manager.go b/repository/repository_manager.go index bd81334..740aa5e 100644 --- a/repository/repository_manager.go +++ b/repository/repository_manager.go @@ -174,9 +174,19 @@ func buildModelRelationship(source *proto.Repository, repository *Repository) er if err != nil { return err } + err = buildCentralizedStationRelationShip(source, repository) + if err != nil { + return err + } return err } - +func buildCentralizedStationRelationShip(source *proto.Repository, repo *Repository) error { + for _, stationRef := range source.CentralizedStationRefs { + stationId := stationRef.StationId + repo.centralizedMap[stationId] = stationRef + } + return nil +} func buildMkxRelationShip(source *proto.Repository, repo *Repository) error { for _, protoData := range source.Mkxs { mkx := repo.mkxMap[protoData.Id] From d05706b3e51b6d94ca6e5561fa093e88bf8bcfe2 Mon Sep 17 00:00:00 2001 From: joylink_zhangsai <1021828630@qq.com> Date: Thu, 9 Nov 2023 10:53:18 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=97=B4=E9=9A=99?= =?UTF-8?q?=E6=8E=A2=E6=B5=8B=E7=BB=A7=E7=94=B5=E5=99=A8=E5=8F=8A=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=80=BB=E8=BE=91=EF=BC=9B=E4=BF=AE=E6=94=B9=E5=B1=8F?= =?UTF-8?q?=E8=94=BD=E9=97=A8=E6=8E=A7=E5=88=B6=E9=80=BB=E8=BE=91=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- component/psd.go | 23 ++-- entity/psd.go | 9 +- fi/psd.go | 232 ++++++++++++++++++++++++++++++++++------- sys/circuit_sys/psd.go | 152 ++++++++++++++------------- 4 files changed, 296 insertions(+), 120 deletions(-) diff --git a/component/psd.go b/component/psd.go index 17a6918..2f444c1 100644 --- a/component/psd.go +++ b/component/psd.go @@ -19,20 +19,18 @@ type PsdCircuit struct { //屏蔽门表示继电器 MGJ *ecs.Entry MPLJ *ecs.Entry + //启动探测继电器 + QDTCJ *ecs.Entry + //停止探测继电器 + TZTCJ *ecs.Entry + //大概就是表示探测过程中出现异常 + ZAWJ *ecs.Entry + //间隙探测旁路继电器 + JXTCPLJ *ecs.Entry //一些不知道如何使用的继电器,为了使得采集、驱动逻辑正常,先构建出来 UnusedJ []*ecs.Entry } -var PsdInterlockDriveCircuitType = ecs.NewComponentType[PsdInterlockDriveCircuit]() - -// PsdInterlockDriveCircuit 屏蔽门联锁驱动电路 -type PsdInterlockDriveCircuit struct { - //屏蔽门驱动继电器接通状态 - GMJ bool - KMJ4 bool - KMJ8 bool -} - var AsdCannotOpenTag = ecs.NewTag() var AsdCannotCloseTag = ecs.NewTag() @@ -96,4 +94,9 @@ type Psc struct { MkxKM bool MkxGM bool MkxPL bool + + QDTC bool + TZTC bool + ZAW bool + JXTCPL bool } diff --git a/entity/psd.go b/entity/psd.go index 2f0db61..510191e 100644 --- a/entity/psd.go +++ b/entity/psd.go @@ -59,6 +59,14 @@ func loadPsdCircuit(world ecs.World, entry *ecs.Entry, psd *repository.Psd, entr circuit.MGJ = NewRelayEntity(world, relay, entryMap) case "XMPLJ", "SMPLJ": circuit.MPLJ = NewRelayEntity(world, relay, entryMap) + case "SQDTCJ", "XQDTCJ": + circuit.QDTCJ = NewRelayEntity(world, relay, entryMap) + case "STZTCJ", "XTZTCJ": + circuit.TZTCJ = NewRelayEntity(world, relay, entryMap) + case "SZAWJ", "XZAWJ": + circuit.ZAWJ = NewRelayEntity(world, relay, entryMap) + case "SJXTCPLJ", "XJXTCPLJ": + circuit.JXTCPLJ = NewRelayEntity(world, relay, entryMap) default: circuit.UnusedJ = append(circuit.UnusedJ, NewRelayEntity(world, relay, entryMap)) } @@ -66,7 +74,6 @@ func loadPsdCircuit(world ecs.World, entry *ecs.Entry, psd *repository.Psd, entr } entry.AddComponent(component.PsdCircuitType) component.PsdCircuitType.Set(entry, circuit) - entry.AddComponent(component.PsdInterlockDriveCircuitType) } func NewPsdEntry(world ecs.World, psd *repository.Psd, worldData *component.WorldData) *ecs.Entry { diff --git a/fi/psd.go b/fi/psd.go index e2319e1..4adfd6a 100644 --- a/fi/psd.go +++ b/fi/psd.go @@ -13,7 +13,10 @@ func SetInterlockKm4(world ecs.World, id string) error { wd := entity.GetWorldData(world) entry, ok := wd.EntityMap[id] if ok { - setPsdKm(entry, 4) + err := setInterlockKm(wd, entry, 4) + if err != nil { + return ecs.NewErrResult(err) + } } else { return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) } @@ -27,7 +30,10 @@ func CancelInterlockKm4(world ecs.World, id string) error { wd := entity.GetWorldData(world) entry, ok := wd.EntityMap[id] if ok { - cancelPsdKm(entry, 4) + err := cancelInterlockKm(wd, entry, 4) + if err != nil { + return ecs.NewErrResult(err) + } } else { return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) } @@ -41,7 +47,10 @@ func SetInterlockKm8(world ecs.World, id string) error { wd := entity.GetWorldData(world) entry, ok := wd.EntityMap[id] if ok { - setPsdKm(entry, 8) + err := setInterlockKm(wd, entry, 8) + if err != nil { + return ecs.NewErrResult(err) + } } else { return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) } @@ -55,7 +64,10 @@ func CancelInterlockKm8(world ecs.World, id string) error { wd := entity.GetWorldData(world) entry, ok := wd.EntityMap[id] if ok { - cancelPsdKm(entry, 8) + err := cancelInterlockKm(wd, entry, 8) + if err != nil { + return ecs.NewErrResult(err) + } } else { return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) } @@ -69,7 +81,10 @@ func SetInterlockGm(world ecs.World, id string) error { wd := entity.GetWorldData(world) entry, ok := wd.EntityMap[id] if ok { - setPsdGm(entry) + err := setInterlockGm(wd, entry) + if err != nil { + return ecs.NewErrResult(err) + } } else { return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) } @@ -83,7 +98,10 @@ func CancelInterlockGm(world ecs.World, id string) error { wd := entity.GetWorldData(world) entry, ok := wd.EntityMap[id] if ok { - cancelPsdGm(entry) + err := cancelInterlockGm(wd, entry) + if err != nil { + return ecs.NewErrResult(err) + } } else { return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) } @@ -134,14 +152,135 @@ func CancelPsdFault(world ecs.World, id string, fault component_proto.Psd_Fault, return result.Err } -func setPsdKm(psdEntry *ecs.Entry, group int) { - if psdEntry.HasComponent(component.PsdInterlockDriveCircuitType) { //有联锁区段电路 - driveCircuit := component.PsdInterlockDriveCircuitType.Get(psdEntry) +func SetQDTC(world ecs.World, id string) error { + result := <-ecs.Request[ecs.EmptyType](world, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(world) + entry, ok := wd.EntityMap[id] + if ok { + err := setQDTC(wd, entry) + if err != nil { + return ecs.NewErrResult(err) + } + } else { + return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) + } + return ecs.NewOkEmptyResult() + }) + return result.Err +} + +func CancelQDTC(world ecs.World, id string) error { + result := <-ecs.Request[ecs.EmptyType](world, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(world) + entry, ok := wd.EntityMap[id] + if ok { + err := cancelQDTC(wd, entry) + if err != nil { + return ecs.NewErrResult(err) + } + } else { + return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) + } + return ecs.NewOkEmptyResult() + }) + return result.Err +} + +func SetTZTC(world ecs.World, id string) error { + result := <-ecs.Request[ecs.EmptyType](world, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(world) + entry, ok := wd.EntityMap[id] + if ok { + err := setTZTC(wd, entry) + if err != nil { + return ecs.NewErrResult(err) + } + } else { + return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) + } + return ecs.NewOkEmptyResult() + }) + return result.Err +} + +func CancelTZTC(world ecs.World, id string) error { + result := <-ecs.Request[ecs.EmptyType](world, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(world) + entry, ok := wd.EntityMap[id] + if ok { + err := cancelTZTC(wd, entry) + if err != nil { + return ecs.NewErrResult(err) + } + } else { + return ecs.NewErrResult(fmt.Errorf("未找到id=%s的屏蔽门", id)) + } + return ecs.NewOkEmptyResult() + }) + return result.Err +} + +func cancelTZTC(wd *component.WorldData, psdEntry *ecs.Entry) error { + if psdEntry.HasComponent(component.PsdCircuitType) { + circuit := component.PsdCircuitType.Get(psdEntry) + return wd.SetQdBit(component.UidType.Get(circuit.TZTCJ).Id, false) + } else { + psc := component.PscType.Get(psdEntry) + psc.TZTC = false + } + return nil +} + +func setTZTC(wd *component.WorldData, psdEntry *ecs.Entry) error { + if psdEntry.HasComponent(component.PsdCircuitType) { + circuit := component.PsdCircuitType.Get(psdEntry) + return wd.SetQdBits([]*component.QdBitParam{ + component.NewQdBitParam(component.UidType.Get(circuit.QDTCJ).Id, false), + component.NewQdBitParam(component.UidType.Get(circuit.TZTCJ).Id, true), + }) + } else { + psc := component.PscType.Get(psdEntry) + psc.QDTC = false + psc.TZTC = true + } + return nil +} + +func cancelQDTC(wd *component.WorldData, psdEntry *ecs.Entry) error { + if psdEntry.HasComponent(component.PsdCircuitType) { + circuit := component.PsdCircuitType.Get(psdEntry) + return wd.SetQdBit(component.UidType.Get(circuit.QDTCJ).Id, false) + } else { + psc := component.PscType.Get(psdEntry) + psc.QDTC = false + } + return nil +} + +func setQDTC(wd *component.WorldData, psdEntry *ecs.Entry) error { + if psdEntry.HasComponent(component.PsdCircuitType) { + circuit := component.PsdCircuitType.Get(psdEntry) + return wd.SetQdBits([]*component.QdBitParam{ + component.NewQdBitParam(component.UidType.Get(circuit.QDTCJ).Id, true), + component.NewQdBitParam(component.UidType.Get(circuit.TZTCJ).Id, false), + }) + } else { + psc := component.PscType.Get(psdEntry) + psc.QDTC = true + psc.TZTC = false + } + return nil +} + +// 设置联锁开门 +func setInterlockKm(wd *component.WorldData, psdEntry *ecs.Entry, group int) error { + if psdEntry.HasComponent(component.PsdCircuitType) { //有联锁区段电路 + circuit := component.PsdCircuitType.Get(psdEntry) switch group { case 4: - setPsdDriveKm4(driveCircuit) + return setInterlockDriveKm4(wd, circuit) case 8: - setPsdDriveKm8(driveCircuit) + return setInterlockDriveKm8(wd, circuit) } } else { psc := component.PscType.Get(psdEntry) @@ -152,16 +291,18 @@ func setPsdKm(psdEntry *ecs.Entry, group int) { setPscKm8(psc) } } + return nil } -func cancelPsdKm(psdEntry *ecs.Entry, group int) { - if psdEntry.HasComponent(component.PsdInterlockDriveCircuitType) { //有联锁区段电路 - driveCircuit := component.PsdInterlockDriveCircuitType.Get(psdEntry) +// 取消联锁开门 +func cancelInterlockKm(wd *component.WorldData, psdEntry *ecs.Entry, group int) error { + if psdEntry.HasComponent(component.PsdCircuitType) { //有联锁区段电路 + circuit := component.PsdCircuitType.Get(psdEntry) switch group { case 4: - driveCircuit.KMJ4 = false + return wd.SetQdBit(component.UidType.Get(circuit.KMJ4).Id, false) case 8: - driveCircuit.KMJ8 = false + return wd.SetQdBit(component.UidType.Get(circuit.KMJ8).Id, false) } } else { psc := component.PscType.Get(psdEntry) @@ -172,56 +313,75 @@ func cancelPsdKm(psdEntry *ecs.Entry, group int) { psc.InterlockKM8 = false } } + return nil } -func setPsdGm(psdEntry *ecs.Entry) { - if psdEntry.HasComponent(component.PsdInterlockDriveCircuitType) { //有联锁区段电路 - driveCircuit := component.PsdInterlockDriveCircuitType.Get(psdEntry) - setPsdDriveGm(driveCircuit) +// 设置联锁关门 +func setInterlockGm(wd *component.WorldData, psdEntry *ecs.Entry) error { + if psdEntry.HasComponent(component.PsdCircuitType) { //有联锁区段电路 + circuit := component.PsdCircuitType.Get(psdEntry) + return setInterlockDriveGm(wd, circuit) } else { psc := component.PscType.Get(psdEntry) setPscGm(psc) } + return nil } -func cancelPsdGm(psdEntry *ecs.Entry) { - if psdEntry.HasComponent(component.PsdInterlockDriveCircuitType) { //有联锁区段电路 - driveCircuit := component.PsdInterlockDriveCircuitType.Get(psdEntry) - driveCircuit.GMJ = false +// 取消联锁关门 +func cancelInterlockGm(wd *component.WorldData, psdEntry *ecs.Entry) error { + if psdEntry.HasComponent(component.PsdCircuitType) { + circuit := component.PsdCircuitType.Get(psdEntry) + return wd.SetQdBit(component.UidType.Get(circuit.GMJ).Id, false) } else { psc := component.PscType.Get(psdEntry) psc.InterlockGM = false } + return nil } -func setPsdDriveKm4(driveCircuit *component.PsdInterlockDriveCircuit) { - driveCircuit.KMJ4 = true - driveCircuit.KMJ8 = false - driveCircuit.GMJ = false +// 联锁驱动4编组开门 +func setInterlockDriveKm4(wd *component.WorldData, circuit *component.PsdCircuit) error { + return wd.SetQdBits([]*component.QdBitParam{ + component.NewQdBitParam(component.UidType.Get(circuit.GMJ).Id, false), + component.NewQdBitParam(component.UidType.Get(circuit.KMJ4).Id, true), + component.NewQdBitParam(component.UidType.Get(circuit.KMJ8).Id, false), + }) } -func setPsdDriveKm8(driveCircuit *component.PsdInterlockDriveCircuit) { - driveCircuit.KMJ4 = false - driveCircuit.KMJ8 = true - driveCircuit.GMJ = false +// 联锁驱动8编组开门 +func setInterlockDriveKm8(wd *component.WorldData, circuit *component.PsdCircuit) error { + return wd.SetQdBits([]*component.QdBitParam{ + component.NewQdBitParam(component.UidType.Get(circuit.GMJ).Id, false), + component.NewQdBitParam(component.UidType.Get(circuit.KMJ4).Id, false), + component.NewQdBitParam(component.UidType.Get(circuit.KMJ8).Id, true), + }) } -func setPsdDriveGm(driveCircuit *component.PsdInterlockDriveCircuit) { - driveCircuit.KMJ4 = false - driveCircuit.KMJ8 = false - driveCircuit.GMJ = true +// 联锁驱动关门 +func setInterlockDriveGm(wd *component.WorldData, circuit *component.PsdCircuit) error { + return wd.SetQdBits([]*component.QdBitParam{ + component.NewQdBitParam(component.UidType.Get(circuit.GMJ).Id, true), + component.NewQdBitParam(component.UidType.Get(circuit.KMJ4).Id, false), + component.NewQdBitParam(component.UidType.Get(circuit.KMJ8).Id, false), + }) } +// 直接设置PSC的状态4编组开门。在无屏蔽门电路时使用 func setPscKm4(psc *component.Psc) { psc.InterlockKM4 = true psc.InterlockKM8 = false psc.InterlockGM = false } + +// 直接设置PSC的状态8编组开门。在无屏蔽门电路时使用 func setPscKm8(psc *component.Psc) { psc.InterlockKM4 = false psc.InterlockKM8 = true psc.InterlockGM = false } + +// 直接设置PSC的状态关门。在无屏蔽门电路时使用 func setPscGm(psc *component.Psc) { psc.InterlockKM4 = false psc.InterlockKM8 = false diff --git a/sys/circuit_sys/psd.go b/sys/circuit_sys/psd.go index d212439..0703890 100644 --- a/sys/circuit_sys/psd.go +++ b/sys/circuit_sys/psd.go @@ -4,8 +4,6 @@ import ( "joylink.club/ecs" "joylink.club/ecs/filter" "joylink.club/rtsssimulation/component" - "joylink.club/rtsssimulation/component/component_proto" - "joylink.club/rtsssimulation/consts" "joylink.club/rtsssimulation/entity" "strings" ) @@ -21,34 +19,45 @@ func NewPsdSys() *PsdSys { } func (p *PsdSys) Update(world ecs.World) { + worldData := entity.GetWorldData(world) p.query.Each(world, func(entry *ecs.Entry) { psc := component.PscType.Get(entry) //更新屏蔽门电路及PSC相关状态 asdList := component.AsdListType.Get(entry) + psdState := component.PsdStateType.Get(entry) if entry.HasComponent(component.PsdCircuitType) { //有屏蔽门电路 - psdDrive := component.PsdInterlockDriveCircuitType.Get(entry) psdCircuit := component.PsdCircuitType.Get(entry) - p.exciteByDrive(psdCircuit, psdDrive) if psdCircuit.GMJ != nil { - p.exciteGMJ(psdCircuit, psdDrive) + p.exciteGMJ(worldData, psdCircuit) psc.InterlockGM = component.BitStateType.Get(psdCircuit.GMJ).Val } if psdCircuit.KMJ4 != nil { - p.exciteKMJ4(psdCircuit, psdDrive) + p.exciteKMJ4(worldData, psdCircuit) psc.InterlockKM4 = component.BitStateType.Get(psdCircuit.KMJ4).Val } if psdCircuit.KMJ8 != nil { - p.exciteKMJ8(psdCircuit, psdDrive) + p.exciteKMJ8(worldData, psdCircuit) psc.InterlockKM8 = component.BitStateType.Get(psdCircuit.KMJ8).Val } if psdCircuit.MGJ != nil { p.exciteMGJ(psdCircuit, asdList) + psdState.Close = component.BitStateType.Get(psdCircuit.MGJ).Val } - p.exciteMPLJ(world, psdCircuit, component.UidType.Get(entry)) - psc.InterlockMPL = component.BitStateType.Get(psdCircuit.MPLJ).Val + if psdCircuit.MPLJ != nil { + p.exciteMPLJ(world, psdCircuit, component.UidType.Get(entry)) + psc.InterlockMPL = component.BitStateType.Get(psdCircuit.MPLJ).Val + } + if psdCircuit.QDTCJ != nil { + p.exciteQDTCJ(worldData, psdCircuit) + psc.QDTC = component.BitStateType.Get(psdCircuit.QDTCJ).Val + } + if psdCircuit.TZTCJ != nil { + p.exciteTZTCJ(worldData, psdCircuit) + psc.TZTC = component.BitStateType.Get(psdCircuit.TZTCJ).Val + } + } else { + psdState.Close = p.isAllAsdMotorClosed(asdList) } - psdState := component.PsdStateType.Get(entry) - p.updatePsdState(psdState, asdList) //更新站台门控箱电路及PSC相关状态 pmc := component.PlatformMkxCircuitType.Get(entry) var pcbTd bool @@ -114,92 +123,67 @@ func (p *PsdSys) gm(asdList *component.AsdList) { } } -func (p *PsdSys) exciteByDrive(psd *component.PsdCircuit, drive *component.PsdInterlockDriveCircuit) { - if drive.GMJ { - component.RelayDriveType.Get(psd.GMJ).Td = true - component.BitStateType.Get(psd.GMJ).Val = true - } - if drive.KMJ4 { - component.RelayDriveType.Get(psd.KMJ4).Td = true - component.BitStateType.Get(psd.KMJ4).Val = true - } - if drive.KMJ8 { - component.RelayDriveType.Get(psd.KMJ8).Td = true - component.BitStateType.Get(psd.KMJ8).Val = true - } -} - -func (p *PsdSys) exciteGMJ(psd *component.PsdCircuit, psdDrive *component.PsdInterlockDriveCircuit) { - gmj := component.BitStateType.Get(psd.GMJ) - kmj4 := component.BitStateType.Get(psd.KMJ4) - kmj8 := component.BitStateType.Get(psd.KMJ8) - if psdDrive.GMJ { //驱动电路接通 - component.RelayDriveType.Get(psd.GMJ).Td = true - gmj.Val = true - } else if gmj.Val { +func (p *PsdSys) exciteGMJ(data *component.WorldData, circuit *component.PsdCircuit) { + gmj := component.BitStateType.Get(circuit.GMJ) + kmj4 := component.BitStateType.Get(circuit.KMJ4) + kmj8 := component.BitStateType.Get(circuit.KMJ8) + bit := data.GetQdBit(component.UidType.Get(circuit.GMJ).Id) + if bit { //驱动 + component.RelayDriveType.Get(circuit.GMJ).Td = true + } else if gmj.Val { //自保持 if !kmj4.Val && !kmj8.Val { - component.RelayDriveType.Get(psd.GMJ).Td = true + component.RelayDriveType.Get(circuit.GMJ).Td = true } else { - component.RelayDriveType.Get(psd.GMJ).Td = false - gmj.Val = false + component.RelayDriveType.Get(circuit.GMJ).Td = false } } } -func (p *PsdSys) exciteKMJ4(psd *component.PsdCircuit, psdDrive *component.PsdInterlockDriveCircuit) { - kmj4 := component.BitStateType.Get(psd.KMJ4) - gmj := component.BitStateType.Get(psd.GMJ) - kmj8 := component.BitStateType.Get(psd.KMJ8) - if psdDrive.KMJ4 { - component.RelayDriveType.Get(psd.KMJ4).Td = true - kmj4.Val = true - } else if kmj4.Val { +func (p *PsdSys) exciteKMJ4(data *component.WorldData, circuit *component.PsdCircuit) { + kmj4 := component.BitStateType.Get(circuit.KMJ4) + gmj := component.BitStateType.Get(circuit.GMJ) + kmj8 := component.BitStateType.Get(circuit.KMJ8) + bit := data.GetQdBit(component.UidType.Get(circuit.KMJ4).Id) + if bit { //驱动 + component.RelayDriveType.Get(circuit.KMJ4).Td = true + } else if kmj4.Val { //自保持 if !gmj.Val && !kmj8.Val { - component.RelayDriveType.Get(psd.KMJ4).Td = true + component.RelayDriveType.Get(circuit.KMJ4).Td = true } else { - component.RelayDriveType.Get(psd.KMJ4).Td = false - kmj4.Val = false + component.RelayDriveType.Get(circuit.KMJ4).Td = false } } } -func (p *PsdSys) exciteKMJ8(psd *component.PsdCircuit, psdDrive *component.PsdInterlockDriveCircuit) { - kmj8 := component.BitStateType.Get(psd.KMJ8) - gmj := component.BitStateType.Get(psd.GMJ) - kmj4 := component.BitStateType.Get(psd.KMJ4) - if psdDrive.KMJ4 { - component.RelayDriveType.Get(psd.KMJ8).Td = true - kmj8.Val = true - } else if kmj8.Val { +func (p *PsdSys) exciteKMJ8(data *component.WorldData, circuit *component.PsdCircuit) { + kmj8 := component.BitStateType.Get(circuit.KMJ8) + gmj := component.BitStateType.Get(circuit.GMJ) + kmj4 := component.BitStateType.Get(circuit.KMJ4) + bit := data.GetQdBit(component.UidType.Get(circuit.KMJ8).Id) + if bit { //驱动 + component.RelayDriveType.Get(circuit.KMJ8).Td = true + } else if kmj8.Val { //自保持 if !gmj.Val && !kmj4.Val { - component.RelayDriveType.Get(psd.KMJ8).Td = true + component.RelayDriveType.Get(circuit.KMJ8).Td = true } else { - component.RelayDriveType.Get(psd.KMJ8).Td = false - kmj8.Val = false + component.RelayDriveType.Get(circuit.KMJ8).Td = false } } } func (p *PsdSys) exciteMGJ(psdCircuit *component.PsdCircuit, asdList *component.AsdList) { - for _, asdEntry := range asdList.List { - asdMotor := component.AsdMotorStateType.Get(asdEntry) - if asdMotor.KM { - component.BitStateType.Get(psdCircuit.MGJ).Val = false - return - } - } - component.BitStateType.Get(psdCircuit.MGJ).Val = true + component.BitStateType.Get(psdCircuit.MGJ).Val = p.isAllAsdMotorClosed(asdList) } -func (p *PsdSys) updatePsdState(psdState *component_proto.PsdState, asdList *component.AsdList) { +// 是否所有滑动门电机都是关闭状态(继电器表示) +func (p *PsdSys) isAllAsdMotorClosed(asdList *component.AsdList) bool { for _, asdEntry := range asdList.List { - position := component.TwoPositionTransformType.Get(asdEntry) - if position.GetPos() != consts.TwoPosMin { - psdState.Close = false - return + asdMotor := component.AsdMotorStateType.Get(asdEntry) + if !asdMotor.MG { + return false } } - psdState.Close = true + return true } func (p *PsdSys) exciteMPLJ(world ecs.World, circuit *component.PsdCircuit, uid *component.Uid) { @@ -227,3 +211,25 @@ func (p *PsdSys) exciteMPLJ(world ecs.World, circuit *component.PsdCircuit, uid component.RelayDriveType.Get(circuit.MPLJ).Td = component.BitStateType.Get(btnEntry).Val } } + +func (p *PsdSys) exciteQDTCJ(data *component.WorldData, circuit *component.PsdCircuit) { + qdtcj := component.BitStateType.Get(circuit.QDTCJ) + tztcj := component.BitStateType.Get(circuit.TZTCJ) + bit := data.GetQdBit(component.UidType.Get(circuit.QDTCJ).Id) + if bit { //驱动 + component.RelayDriveType.Get(circuit.QDTCJ).Td = true + } else if qdtcj.Val { //自保持 + component.RelayDriveType.Get(circuit.QDTCJ).Td = !tztcj.Val + } +} + +func (p *PsdSys) exciteTZTCJ(data *component.WorldData, circuit *component.PsdCircuit) { + tztcj := component.BitStateType.Get(circuit.TZTCJ) + qdtcj := component.BitStateType.Get(circuit.QDTCJ) + bit := data.GetQdBit(component.UidType.Get(circuit.TZTCJ).Id) + if bit { //驱动 + component.RelayDriveType.Get(circuit.TZTCJ).Td = true + } else if tztcj.Val { //自保持 + component.RelayDriveType.Get(circuit.TZTCJ).Td = !qdtcj.Val + } +}