This commit is contained in:
xzb 2023-11-09 14:59:41 +08:00
commit 7b44437fb1
13 changed files with 1032 additions and 564 deletions

43
component/ci_ls.go Normal file
View File

@ -0,0 +1,43 @@
package component
import "joylink.club/ecs"
// 零散设备组件(信号机故障报警仪、断路器、电源屏等)
var (
// 信号机故障报警仪tag
SFATag = ecs.NewTag()
// 信号机故障报警仪电子元件组件
SFAEccType = ecs.NewComponentType[SFAEcc]()
// 断路器tag
DLQTag = ecs.NewTag()
// 断路器电子元件组件
DLQEccType = ecs.NewComponentType[DLQEcc]()
// 电源屏tag
DYPTag = ecs.NewTag()
// 电源屏电子元件组件
DYPEccType = ecs.NewComponentType[DYPEcc]()
)
// 信号机故障报警仪电子元件组件
type SFAEcc struct {
// 灯丝报警继电器
DSBJ *ecs.Entry
}
// 断路器电子元件组件
type DLQEcc struct {
// 熔丝报警继电器
RSBJ *ecs.Entry
}
// 电源屏电子元件组件
type DYPEcc struct {
// 主电源继电器
ZDYJ *ecs.Entry
// 副电源继电器
FDYJ *ecs.Entry
// 电源报警继电器
DYBJ *ecs.Entry
}

View File

@ -57,7 +57,3 @@ func NewCiQcState(qlen int, clen int) *CiQcState {
},
}
}
func GetCiQdBitOfRelay(ci *ecs.Entry, uid string) (bool, error) {
return false, nil
}

110
entity/ci_ls.go Normal file
View File

@ -0,0 +1,110 @@
package entity
import (
"fmt"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/repository"
"joylink.club/rtsssimulation/repository/model/proto"
)
// 创建信号机故障报警仪实体
func NewSFAEntity(w ecs.World, station *repository.Station) error {
data := GetWorldData(w)
repo := data.Repo
for _, de := range station.DeviceEcc() {
if de.DeviceType == proto.DeviceType_DeviceType_SignalFaultAlarm {
var dsbj *ecs.Entry
for _, ecg := range de.Egs {
if ecg.Code == "LS" {
if len(ecg.ComponentIds) == 1 {
relay := repo.FindById(ecg.ComponentIds[0])
if relay == nil {
return fmt.Errorf("信号机故障报警仪构建错误: 找不到id=%s的继电器", ecg.ComponentIds[0])
}
dsbj = NewRelayEntity(w, relay.(*repository.Relay), data.EntityMap)
}
}
}
entry := w.Entry(w.Create(component.SFATag, component.SFAEccType))
component.SFAEccType.Set(entry, &component.SFAEcc{
DSBJ: dsbj,
})
}
}
return nil
}
// 创建断路器实体
func NewDLQEntity(w ecs.World, station *repository.Station) error {
data := GetWorldData(w)
repo := data.Repo
for _, de := range station.DeviceEcc() {
if de.DeviceType == proto.DeviceType_DeviceType_Breakers {
var rsbj *ecs.Entry
for _, ecg := range de.Egs {
if ecg.Code == "LS" {
if len(ecg.ComponentIds) == 1 {
relay := repo.FindById(ecg.ComponentIds[0])
if relay == nil {
return fmt.Errorf("断路器实体构建错误: 找不到id=%s的继电器", ecg.ComponentIds[0])
}
rsbj = NewRelayEntity(w, relay.(*repository.Relay), data.EntityMap)
}
}
}
entry := w.Entry(w.Create(component.DLQTag, component.DLQEccType))
component.DLQEccType.Set(entry, &component.DLQEcc{
RSBJ: rsbj,
})
}
}
return nil
}
// 创建电源屏实体
func NewDYPEntity(w ecs.World, station *repository.Station) error {
data := GetWorldData(w)
repo := data.Repo
for _, de := range station.DeviceEcc() {
if de.DeviceType == proto.DeviceType_DeviceType_PowerScreen {
var zdyj *ecs.Entry
var fdyj *ecs.Entry
var dybj *ecs.Entry
for _, ecg := range de.Egs {
if ecg.Code == "LS" {
if len(ecg.ComponentIds) == 3 {
for _, id := range ecg.ComponentIds {
d := repo.FindById(id)
if d == nil {
return fmt.Errorf("电源屏实体构建错误: 找不到id=%s的继电器", ecg.ComponentIds[0])
}
if d.Type() == proto.DeviceType_DeviceType_Relay {
relay := d.(*repository.Relay)
if relay.Code() == "ZDYJ" {
zdyj = NewRelayEntity(w, relay, data.EntityMap)
} else if relay.Code() == "FDYJ" {
fdyj = NewRelayEntity(w, relay, data.EntityMap)
} else if relay.Code() == "DYBJ" {
dybj = NewRelayEntity(w, relay, data.EntityMap)
} else {
return fmt.Errorf("电源屏实体构建错误: 未知的继电器编码'%s'", relay.Code())
}
} else {
return fmt.Errorf("电源屏实体构建错误: id=%s的设备不是继电器", ecg.ComponentIds[0])
}
}
}
}
}
entry := w.Entry(w.Create(component.DYPTag, component.DYPEccType))
component.DYPEccType.Set(entry, &component.DYPEcc{
ZDYJ: zdyj,
FDYJ: fdyj,
DYBJ: dybj,
})
}
}
return nil
}

View File

@ -3,7 +3,6 @@ package entity
import (
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/repository"
)
func LoadStations(w ecs.World) error {
@ -11,13 +10,19 @@ func LoadStations(w ecs.World) error {
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)
err := NewSFAEntity(w, station)
if err != nil {
return err
}
err = NewDLQEntity(w, station)
if err != nil {
return err
}
err = NewDYPEntity(w, station)
if err != nil {
return err
}
entry := NewStationEntity(w, station.Id(), data)
if station.GetIbpSpk() != nil { // 人员防护
LoadSPKEntity(w, entry, station.GetIbpSpk(), data)

@ -1 +1 @@
Subproject commit 3a98a65dada5738714a362fbdba0853cb73ae24b
Subproject commit 4171b05a7c23c3e40a755ccd7d08b4cfd6aa26a0

View File

@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
)
var (
@ -42,7 +43,7 @@ func main() {
func getProtoFiles() []string {
var protoFiles []string
err := filepath.WalkDir(protoFolder, func(path string, d fs.DirEntry, err error) error {
if !d.IsDir() {
if !d.IsDir() && strings.HasSuffix(path, ".proto") {
protoFiles = append(protoFiles, path)
}
return err

View File

@ -29,6 +29,24 @@ message Repository {
repeated CentralizedStationRef CentralizedStationRefs = 22;
}
//
message SignalLayout {
//
repeated PhysicalSection physicalSections = 3;
repeated CheckPoint checkPoints = 4;
repeated Turnout turnouts = 5;
repeated Signal signals = 6;
repeated Transponder transponders = 7;
repeated Slope slopes = 8;
repeated SectionalCurvature sectionalCurvatures = 9;
repeated KilometerConvert kilometerConverts = 10;
}
//
message RelayCombination {
}
//
message PhysicalSection {
string id = 1;

File diff suppressed because it is too large Load Diff

View File

@ -71,6 +71,21 @@ func (repo *Repository) FindById(id string) Identity {
if md, ok := repo.relayMap[id]; ok {
return md
}
if md, ok := repo.physicalSectionMap[id]; ok {
return md
}
if md, ok := repo.checkPointMap[id]; ok {
return md
}
if md, ok := repo.responderMap[id]; ok {
return md
}
if md, ok := repo.stationMap[id]; ok {
return md
}
if md, ok := repo.platformMap[id]; ok {
return md
}
return nil
}

View File

@ -3,11 +3,12 @@ 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)
@ -886,36 +887,22 @@ func buildStationRelationShip(source *proto.Repository, repo *Repository) error
if !ok {
return fmt.Errorf("缺失车站[%s]", protoData.Id)
}
if len(protoData.ElectronicGroup) == 0 {
continue
}
if len(protoData.ElectronicGroup) > 0 {
for _, ref := range protoData.ElectronicGroup {
switch ref.Code {
case "EMP":
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("未知的车站组合", "组合code", ref.Code)
}
}
}
if len(protoData.Deccs) > 0 { // 暂时让逻辑运行起来,后需重构
station.deviceEcc = protoData.Deccs
}
}
return nil
}

View File

@ -7,6 +7,7 @@ type Station struct {
code string
ibp *IBP
componentGroups []*ElectronicComponentGroup
deviceEcc []*proto.DeviceEcc
}
func NewStation(id, code string) *Station {
@ -32,3 +33,7 @@ func (s *Station) GetIbpSpk() *IBPRefMap {
func (s *Station) ComponentGroups() []*ElectronicComponentGroup {
return s.componentGroups
}
func (s *Station) DeviceEcc() []*proto.DeviceEcc {
return s.deviceEcc
}

View File

@ -283,6 +283,10 @@ func (t *Turnout) GetPhysicalSection() *PhysicalSection {
return t.section
}
func (t *Turnout) GindDevicePortByPort(port proto.Port) DevicePort {
return t.findDevicePortByPort(port)
}
type TurnoutPort struct {
turnout *Turnout
port proto.Port

View File

@ -27,16 +27,13 @@ func (p *PsdSys) Update(world ecs.World) {
psdState := component.PsdStateType.Get(entry)
if entry.HasComponent(component.PsdCircuitType) { //有屏蔽门电路
psdCircuit := component.PsdCircuitType.Get(entry)
if psdCircuit.GMJ != nil {
//屏蔽门驱动
if psdCircuit.GMJ != nil && psdCircuit.KMJ4 != nil && psdCircuit.KMJ8 != nil {
p.exciteGMJ(worldData, psdCircuit)
psc.InterlockGM = component.BitStateType.Get(psdCircuit.GMJ).Val
}
if psdCircuit.KMJ4 != nil {
p.exciteKMJ4(worldData, psdCircuit)
psc.InterlockKM4 = component.BitStateType.Get(psdCircuit.KMJ4).Val
}
if psdCircuit.KMJ8 != nil {
p.exciteKMJ8(worldData, psdCircuit)
psc.InterlockGM = component.BitStateType.Get(psdCircuit.GMJ).Val
psc.InterlockKM4 = component.BitStateType.Get(psdCircuit.KMJ4).Val
psc.InterlockKM8 = component.BitStateType.Get(psdCircuit.KMJ8).Val
}
if psdCircuit.MGJ != nil {
@ -47,12 +44,11 @@ func (p *PsdSys) Update(world ecs.World) {
p.exciteMPLJ(world, psdCircuit, component.UidType.Get(entry))
psc.InterlockMPL = component.BitStateType.Get(psdCircuit.MPLJ).Val
}
if psdCircuit.QDTCJ != nil {
//间隙探测
if psdCircuit.QDTCJ != nil && psdCircuit.TZTCJ != nil {
p.exciteQDTCJ(worldData, psdCircuit)
psc.QDTC = component.BitStateType.Get(psdCircuit.QDTCJ).Val
}
if psdCircuit.TZTCJ != nil {
p.exciteTZTCJ(worldData, psdCircuit)
psc.QDTC = component.BitStateType.Get(psdCircuit.QDTCJ).Val
psc.TZTC = component.BitStateType.Get(psdCircuit.TZTCJ).Val
}
} else {
@ -124,10 +120,13 @@ func (p *PsdSys) gm(asdList *component.AsdList) {
}
func (p *PsdSys) exciteGMJ(data *component.WorldData, circuit *component.PsdCircuit) {
bit, err := data.QueryQdBit(component.UidType.Get(circuit.GMJ).Id)
if err != nil {
return
}
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 { //自保持
@ -140,10 +139,13 @@ func (p *PsdSys) exciteGMJ(data *component.WorldData, circuit *component.PsdCirc
}
func (p *PsdSys) exciteKMJ4(data *component.WorldData, circuit *component.PsdCircuit) {
bit, err := data.QueryQdBit(component.UidType.Get(circuit.KMJ4).Id)
if err != nil {
return
}
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 { //自保持
@ -156,10 +158,13 @@ func (p *PsdSys) exciteKMJ4(data *component.WorldData, circuit *component.PsdCir
}
func (p *PsdSys) exciteKMJ8(data *component.WorldData, circuit *component.PsdCircuit) {
bit, err := data.QueryQdBit(component.UidType.Get(circuit.KMJ8).Id)
if err != nil {
return
}
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 { //自保持
@ -213,9 +218,12 @@ func (p *PsdSys) exciteMPLJ(world ecs.World, circuit *component.PsdCircuit, uid
}
func (p *PsdSys) exciteQDTCJ(data *component.WorldData, circuit *component.PsdCircuit) {
bit, err := data.QueryQdBit(component.UidType.Get(circuit.QDTCJ).Id)
if err != nil {
return
}
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 { //自保持
@ -224,9 +232,12 @@ func (p *PsdSys) exciteQDTCJ(data *component.WorldData, circuit *component.PsdCi
}
func (p *PsdSys) exciteTZTCJ(data *component.WorldData, circuit *component.PsdCircuit) {
bit, err := data.QueryQdBit(component.UidType.Get(circuit.TZTCJ).Id)
if err != nil {
return
}
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 { //自保持