iscs bas 大系统

This commit is contained in:
xzb 2024-01-05 11:30:39 +08:00
parent 3cb6678a19
commit 7a4ad7d1bb
24 changed files with 792 additions and 810 deletions

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.31.0
// protoc v4.23.1 // protoc v4.23.1
// source: component/ci.proto // source: component/ci.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.31.0
// protoc v4.23.1 // protoc v4.23.1
// source: component/common.proto // source: component/common.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.31.0
// protoc v4.23.1 // protoc v4.23.1
// source: component/points.proto // source: component/points.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.31.0
// protoc v4.23.1 // protoc v4.23.1
// source: component/psd.proto // source: component/psd.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.31.0
// protoc v4.23.1 // protoc v4.23.1
// source: component/signal.proto // source: component/signal.proto

View File

@ -10,7 +10,7 @@ type AirConditioning struct {
var ( var (
AirConditioningType = ecs.NewComponentType[AirConditioning]() //空调 AirConditioningType = ecs.NewComponentType[AirConditioning]() //空调
CombinationAirConditionerTag = ecs.NewTag() //组合式空调 CombinationAirConditionerTag = ecs.NewTag() //组合式空调(变频空调)
AirConditioningGroupTag = ecs.NewTag() //空调群控系统 AirConditioningGroupTag = ecs.NewTag() //空调群控系统
AirConditionerTag = ecs.NewTag() //空调器 AirConditionerTag = ecs.NewTag() //空调器
) )

View File

@ -2,37 +2,128 @@ package component
import "joylink.club/ecs" import "joylink.club/ecs"
// FluidPipe 流体管线 ///////////////////////////////////////////
type FluidPipe struct { //组合空调柜AHU-A01 二通阀MOV-A01
Direction PipeFlowDirection //管线内综合流动方向 //回排风机RAF-A01 风阀MDD-A03
FlowSpeed float32 //管线内综合流量m3/h //排烟风机SEF-A01 风阀MDD-A04
Sources []*SourceFlow //该管线内所有流体源投射的分量 //排风阀MDA-A02
} //回风阀MDA-A03
//小新风阀MDA-A01
//空调柜MDD-A02
//防烟防火SFD-A01
// SourceFlow 流体源进入管线的流体描述 // PipeMatter 管线中传输的物质类型
type SourceFlow struct { type PipeMatter uint8
Direction PipeFlowDirection
FlowSpeed float32
}
// PipeFlowDirection 管线内流体流动方向定义
type PipeFlowDirection int8
const ( const (
PipeFlowNon PipeFlowDirection = iota //流体未流动 PmtNon PipeMatter = iota //未知或没有
PipeFlowAb //流体从管线的A->B PmtWater
PipeFlowBa //流体从管线的B->A PmtElectricity //电
PmtAir //正常空气
PmtSmoke //含有有害烟的空气(如火灾时的烟气)
PmtOil //油
) )
func (d *PipeFlowDirection) IsFlowAb() bool { func (m *PipeMatter) IsNon() bool {
return *d == PipeFlowAb return *m == PmtNon
} }
func (d *PipeFlowDirection) IsFlowBa() bool { func (m *PipeMatter) IsEle() bool {
return *d == PipeFlowBa return *m == PmtElectricity
} }
func (d *PipeFlowDirection) IsFlowNon() bool {
return *d == PipeFlowNon // PipeDirection 管线中物质传输方向定义
type PipeDirection uint8
const (
PdNon PipeDirection = iota //无方向
PdAb //方向A=>B
PdBa //方向B=>A
)
func (d *PipeDirection) IsAb() bool {
return *d == PdAb
} }
func (d *PipeDirection) IsBa() bool {
return *d == PdBa
}
func (d *PipeDirection) IsNon() bool {
return *d == PdNon
}
// Pipe 管线一般状态定义
type Pipe struct {
Matter PipeMatter //管线中物质类型
Direction PipeDirection //管线中物质运动方向
}
// PipeElectricity 电线(三相交流,一般单相交流,直流)
// 如果是三相电,则简化认为每相电压电流一样
type PipeElectricity struct {
U uint32 //电压
I uint32 //电流
Sx bool //true-三相交流电此时Ac无效false-一般单相电此时Ua Ia Ac有效
Ac bool //true-交流false-直流
Sources map[string]*ElectricitySource //key-电源实体id,value-电源投影
}
func NewPipeElectricity() *PipeElectricity {
return &PipeElectricity{Sources: make(map[string]*ElectricitySource)}
}
func (p *PipeElectricity) FromElectricitySource(es *ElectricitySource) {
p.U = es.U
p.Sx = es.Sx
p.Ac = es.Ac
}
func (p *PipeElectricity) TransPower(powerSourceId string, power *ElectricitySource) {
ep, ok := p.Sources[powerSourceId]
if ok {
*ep = *power
ep.Fresh -= 1
} else {
p.Sources[powerSourceId] = &ElectricitySource{}
*p.Sources[powerSourceId] = *power
p.Sources[powerSourceId].Fresh -= 1
}
}
// ElectricitySource 电源(三相交流,一般单相交流,直流)
type ElectricitySource struct {
Fresh int64 //该电力值更新的时间戳
U uint32 //电压
I uint32 //电流
Sx bool //true-三相交流电此时Ac无效false-一般单相电此时Ua Ia Ac有效
Ac bool //true-交流false-直流
}
func NewElectricitySource() *ElectricitySource {
return &ElectricitySource{}
}
// SetOut0 设置0输出
func (s *ElectricitySource) SetOut0() {
s.U = 0
s.I = 0
}
// PipeFluid 流体(液体气体)管线
type PipeFluid struct {
T float32 //温度
}
func NewPipeFluid() *PipeFluid {
return &PipeFluid{}
}
var (
PipeType = ecs.NewComponentType[Pipe]() //电线
PipeElectricityType = ecs.NewComponentType[PipeElectricity]() //电线电力
PipeFluidType = ecs.NewComponentType[PipeFluid]() //管线流体
ElectricitySourceType = ecs.NewComponentType[ElectricitySource]() //电源
)
/////////////////////////////////////////////////////////////////////////
// FluidDriver 流体驱动器 // FluidDriver 流体驱动器
type FluidDriver struct { type FluidDriver struct {
@ -40,6 +131,5 @@ type FluidDriver struct {
} }
var ( var (
FluidPipeType = ecs.NewComponentType[FluidPipe]() //流体管线
FluidDriverType = ecs.NewComponentType[FluidDriver]() //流体驱动器 FluidDriverType = ecs.NewComponentType[FluidDriver]() //流体驱动器
) )

View File

@ -102,32 +102,6 @@ type EarthingDevice struct {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// PowerPipe 电力母线
type PowerPipe struct {
Voltage uint32 //母线当前电压
Ac bool //true-交流电false-直流电
Sources map[string]*ElePower //key-电源PowerSource实体id
}
func (p *PowerPipe) TransPower(powerSourceId string, power *ElePower) {
ep, ok := p.Sources[powerSourceId]
if ok {
*ep = *power
ep.Fresh -= 1
} else {
p.Sources[powerSourceId] = &ElePower{}
*p.Sources[powerSourceId] = *power
p.Sources[powerSourceId].Fresh -= 1
}
}
// ElePower 传输中的电力
type ElePower struct {
Fresh int64 //该电力值更新的时间戳
Voltage uint32 //电压
Ac bool //true-交流电false-直流电
}
// PscadaVoltageLevel 电力母线当前电压等级定义 // PscadaVoltageLevel 电力母线当前电压等级定义
type PscadaVoltageLevel uint8 type PscadaVoltageLevel uint8
@ -139,12 +113,6 @@ const (
PscadaVoltageDc1500V //1500V直流 PscadaVoltageDc1500V //1500V直流
) )
// PowerSource 电源(国家电网)
type PowerSource struct {
Voltage uint32 //电压
Ac bool //true-交流电false-直流电
}
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
var ( var (
@ -156,8 +124,6 @@ var (
LightningArresterType = ecs.NewComponentType[LightningArrester]() //避雷器 LightningArresterType = ecs.NewComponentType[LightningArrester]() //避雷器
RectifierType = ecs.NewComponentType[Rectifier]() //整流器 RectifierType = ecs.NewComponentType[Rectifier]() //整流器
VoltageTransformerType = ecs.NewComponentType[VoltageTransformer]() //变压器 VoltageTransformerType = ecs.NewComponentType[VoltageTransformer]() //变压器
PowerPipeType = ecs.NewComponentType[PowerPipe]() //电力母线
PowerSourceType = ecs.NewComponentType[PowerSource]() //电源
EarthingDeviceType = ecs.NewComponentType[EarthingDevice]() //接地装置 EarthingDeviceType = ecs.NewComponentType[EarthingDevice]() //接地装置
) )

View File

@ -2,7 +2,6 @@ package entity
import ( import (
"joylink.club/ecs" "joylink.club/ecs"
"joylink.club/rtsssimulation/repository/model/proto"
) )
// LoadIscs 加载ISCS相关设备实体 // LoadIscs 加载ISCS相关设备实体
@ -10,10 +9,7 @@ func LoadIscs(w ecs.World) error {
data := GetWorldData(w) data := GetWorldData(w)
//电力母线实体 //电力母线实体
for _, pipe := range data.Repo.PipeMap { for _, pipe := range data.Repo.PipeMap {
switch pipe.PipeType { NewPipeEntity(w, pipe.Id())
case proto.Pipe_ElectricPower:
NewPowerPipeEntity(w, pipe.Id())
}
} }
//断路器 //断路器
for _, circuitBreaker := range data.Repo.CircuitBreakerMap { for _, circuitBreaker := range data.Repo.CircuitBreakerMap {
@ -41,7 +37,7 @@ func LoadIscs(w ecs.World) error {
} }
//电源 //电源
for _, ps := range data.Repo.PowerSourceMap { for _, ps := range data.Repo.PowerSourceMap {
NewPowerSourceEntity(w, ps.Id(), ps.Ac, ps.Voltage) NewPowerSourceEntity(w, ps.Id())
} }
//避雷器 //避雷器
for _, la := range data.Repo.LightningArresterMap { for _, la := range data.Repo.LightningArresterMap {

View File

@ -107,27 +107,23 @@ func NewVoltageTransformerEntity(w ecs.World, id string) *ecs.Entry {
return e return e
} }
// NewPowerPipeEntity 创建PSCADA电力母线实体 func NewPipeEntity(w ecs.World, id string) *ecs.Entry {
func NewPowerPipeEntity(w ecs.World, id string) *ecs.Entry {
wd := GetWorldData(w) wd := GetWorldData(w)
e, ok := wd.EntityMap[id] e, ok := wd.EntityMap[id]
if !ok { if !ok {
e = w.Entry(w.Create(component.UidType, component.PowerPipeType)) e = w.Entry(w.Create(component.UidType, component.PipeType))
component.UidType.SetValue(e, component.Uid{Id: id})
component.PowerPipeType.Set(e, &component.PowerPipe{Sources: make(map[string]*component.ElePower)})
wd.EntityMap[id] = e wd.EntityMap[id] = e
} }
return e return e
} }
// NewPowerSourceEntity 创建PSCADA电源实体 // NewPowerSourceEntity 创建PSCADA电源实体
func NewPowerSourceEntity(w ecs.World, id string, ac bool, voltage uint32) *ecs.Entry { func NewPowerSourceEntity(w ecs.World, id string) *ecs.Entry {
wd := GetWorldData(w) wd := GetWorldData(w)
e, ok := wd.EntityMap[id] e, ok := wd.EntityMap[id]
if !ok { if !ok {
e = w.Entry(w.Create(component.UidType, component.PowerSourceType)) e = w.Entry(w.Create(component.UidType, component.ElectricitySourceType))
component.UidType.SetValue(e, component.Uid{Id: id}) component.UidType.SetValue(e, component.Uid{Id: id})
component.PowerSourceType.Set(e, &component.PowerSource{Ac: ac, Voltage: voltage})
wd.EntityMap[id] = e wd.EntityMap[id] = e
} }
return e return e

@ -1 +1 @@
Subproject commit e83feb89dd84e3456aafebb7d6dbe179675344e8 Subproject commit bd947baa4edadb6b7bd059f6e324fb20f8171f8f

View File

@ -607,11 +607,6 @@ message Pipe{
string code = 2; string code = 2;
DevicePort portA = 3;//线A端连接的设备 DevicePort portA = 3;//线A端连接的设备
DevicePort portB = 4;//线B端连接的设备 DevicePort portB = 4;//线B端连接的设备
enum Type{
Fluid = 0;//()
ElectricPower = 1;//线线
}
Type pipeType = 5; //线
} }
// //
//A B C D //A B C D
@ -668,12 +663,13 @@ message VoltageTransformer{
message PowerSource{ message PowerSource{
string id = 1; string id = 1;
string code = 2; string code = 2;
//true-false-
bool sx = 3;
//true-false- //true-false-
bool ac = 3; bool ac = 4;
// //
uint32 voltage = 4; uint32 voltage = 5;
} }
// //
message LightningArrester{ message LightningArrester{
string id = 1; string id = 1;

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.31.0
// protoc v4.23.1 // protoc v4.23.1
// source: cg_repo.proto // source: cg_repo.proto

View File

@ -11,13 +11,12 @@ import (
type Pipe struct { type Pipe struct {
Identity Identity
Code string Code string
PipeType proto.Pipe_Type
PortA DevicePort //管线的A端连接的设备 PortA DevicePort //管线的A端连接的设备
PortB DevicePort //管线的B端连接的设备 PortB DevicePort //管线的B端连接的设备
} }
func NewPipe(id string, code string, pipeType proto.Pipe_Type) *Pipe { func NewPipe(id string, code string) *Pipe {
return &Pipe{Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_Pipe}, Code: code, PipeType: pipeType} return &Pipe{Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_Pipe}, Code: code}
} }
func (p *Pipe) PortNum() int { func (p *Pipe) PortNum() int {
return 2 return 2
@ -105,16 +104,6 @@ func (p *PipeFitting) Ports() []*PipePort {
return ports return ports
} }
// IsEle true-管件为电力管件
func (p *PipeFitting) IsEle() bool {
for _, port := range p.Ports() {
if port.pipe.PipeType != proto.Pipe_ElectricPower {
return false
}
}
return true
}
// PipeFittingPort 管件端口 // PipeFittingPort 管件端口
// //
// implement DevicePort // implement DevicePort
@ -365,16 +354,18 @@ type PowerSource struct {
Identity Identity
Code string Code string
PortA *PipePort //电源A端口连接的管线 PortA *PipePort //电源A端口连接的管线
Ac bool //true-交流false-直流
Voltage uint32 //电压单位V Voltage uint32 //电压单位V
Sx bool //true-三相交流电false-单相
Ac bool //true-交流false-直流
} }
func NewPowerSource(id string, code string, ac bool, voltage uint32) *PowerSource { func NewPowerSource(id string, code string, voltage uint32, sx bool, ac bool) *PowerSource {
return &PowerSource{ return &PowerSource{
Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_PowerSource}, Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_PowerSource},
Code: code, Code: code,
Ac: ac,
Voltage: voltage, Voltage: voltage,
Sx: sx,
Ac: ac,
} }
} }
func (p *PowerSource) PortNum() int { func (p *PowerSource) PortNum() int {

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ import "joylink.club/rtsssimulation/repository/model/proto"
func buildIscsModels(source *proto.Repository, repository *Repository) error { func buildIscsModels(source *proto.Repository, repository *Repository) error {
//ISCS管线 //ISCS管线
for _, protoData := range source.Pipes { for _, protoData := range source.Pipes {
m := NewPipe(protoData.Id, protoData.Code, protoData.PipeType) m := NewPipe(protoData.Id, protoData.Code)
repository.PipeMap[m.Id()] = m repository.PipeMap[m.Id()] = m
} }
//ISCS管件 //ISCS管件
@ -46,7 +46,7 @@ func buildIscsModels(source *proto.Repository, repository *Repository) error {
} }
//ISCS电源 //ISCS电源
for _, protoData := range source.PowerSources { for _, protoData := range source.PowerSources {
m := NewPowerSource(protoData.Id, protoData.Code, protoData.Ac, protoData.Voltage) m := NewPowerSource(protoData.Id, protoData.Code, protoData.Voltage, protoData.Sx, protoData.Ac)
repository.PowerSourceMap[m.Id()] = m repository.PowerSourceMap[m.Id()] = m
} }
//ISCS避雷器 //ISCS避雷器

View File

@ -23,7 +23,7 @@ type FluidDriverSystem struct {
func NewFluidDriverSystem() *FluidDriverSystem { func NewFluidDriverSystem() *FluidDriverSystem {
return &FluidDriverSystem{ return &FluidDriverSystem{
query: ecs.NewQuery(filter.Contains(component.UidType, component.FluidDriverType)), query: ecs.NewQuery(filter.Contains(component.UidType, component.FluidDriverType)),
queryFluidPipe: ecs.NewQuery(filter.Contains(component.UidType, component.FluidPipeType)), queryFluidPipe: ecs.NewQuery(filter.Contains(component.UidType, component.PipeFluidType)),
} }
} }
@ -38,125 +38,7 @@ func (s *FluidDriverSystem) findFluidPath(fromDevice repository.Identity, fromDe
return sp return sp
} }
func (s *FluidDriverSystem) Update(w ecs.World) { func (s *FluidDriverSystem) Update(w ecs.World) {
wd := entity.GetWorldData(w)
s.query.Each(w, func(entry *ecs.Entry) {
fdId := component.UidType.Get(entry).Id
fd := component.FluidDriverType.Get(entry)
fluidDriverOn := fd.On
fdModel := wd.Repo.FindById(fdId)
if fdModel == nil {
fmt.Printf("==>>FluidDriver[%s]模型不存在\n", fdId)
} else {
switch fdModel.Type() {
case proto.DeviceType_DeviceType_Fan: //风机
{
fanModel := fdModel.(*repository.Fan)
fanOutPort := *fanModel.PortA
fanInPort := *fanModel.PortB
fanOutPath := s.findFluidPath(fanModel, fanOutPort, true)
fanInPath := s.findFluidPath(fanModel, fanInPort, false)
//
s.calculateFluid(w, fluidDriverOn, fanOutPath, fanInPath)
}
case proto.DeviceType_DeviceType_AirPavilion: //风亭,其中送风亭为动力源
{
apModel := fdModel.(*repository.AirPavilion)
if apModel.PavilionType == proto.AirPavilion_AirSupplyPavilion {
apOutPort := *apModel.PortA
apOutPath := s.findFluidPath(apModel, apOutPort, true)
s.calculateFluid(w, fluidDriverOn, apOutPath, nil)
}
}
}
}
})
//
s.queryFluidPipe.Each(w, func(entry *ecs.Entry) {
pipe := component.FluidPipeType.Get(entry)
if len(pipe.Sources) > 0 {
directionAb := int8(0)
for _, ps := range pipe.Sources {
if ps.Direction.IsFlowAb() {
directionAb++
}
if ps.Direction.IsFlowBa() {
directionAb--
}
}
if directionAb > 0 {
pipe.Direction = component.PipeFlowAb
} else if directionAb < 0 {
pipe.Direction = component.PipeFlowBa
} else {
pipe.Direction = component.PipeFlowNon
}
} else {
pipe.Direction = component.PipeFlowNon
pipe.FlowSpeed = 0
}
})
}
// 计算流体在管线中的流动参数
func (s *FluidDriverSystem) calculateFluid(w ecs.World, fluidDriverOn bool, outPath []*SearchedPath, inPath []*SearchedPath) {
for _, out := range outPath {
s.clearFluidPathSources(w, out)
}
for _, in := range inPath {
s.clearFluidPathSources(w, in)
}
//
if fluidDriverOn {
var validOutPath, validInPath []*SearchedPath
for _, out := range outPath {
if s.isFluidPathUnblocked(out, w) {
validOutPath = append(validOutPath, out)
}
}
for _, in := range inPath {
if s.isFluidPathUnblocked(in, w) {
validInPath = append(validInPath, in)
}
}
isValid := len(outPath) > 0 && len(inPath) > 0 && len(validInPath) > 0 && len(validOutPath) > 0 || len(outPath) > 0 && len(inPath) == 0 && len(inPath) > 0
if isValid {
wd := entity.GetWorldData(w)
for _, outSp := range validOutPath {
for _, outPipe := range outSp.ViaPipes {
pipeEntry := wd.EntityMap[outPipe.Device().Id()]
fluidPipe := component.FluidPipeType.Get(pipeEntry)
fluidPipe.Sources = append(fluidPipe.Sources, &component.SourceFlow{Direction: convertFlowDirection(outPipe)})
}
}
for _, inSp := range validInPath {
for _, inPipe := range inSp.ViaPipes {
pipeEntry := wd.EntityMap[inPipe.Device().Id()]
fluidPipe := component.FluidPipeType.Get(pipeEntry)
fluidPipe.Sources = append(fluidPipe.Sources, &component.SourceFlow{Direction: convertFlowDirection(inPipe)})
}
}
}
}
}
func convertFlowDirection(sp repository.PipePort) component.PipeFlowDirection {
switch sp.Port() {
case proto.Port_A:
return component.PipeFlowAb
case proto.Port_B:
return component.PipeFlowBa
default:
return component.PipeFlowNon
}
}
// 清空管线流体源
func (s *FluidDriverSystem) clearFluidPathSources(w ecs.World, path *SearchedPath) {
wd := entity.GetWorldData(w)
for _, pipe := range path.ViaPipes {
pipeEntry := wd.EntityMap[pipe.Device().Id()]
fluidPipe := component.FluidPipeType.Get(pipeEntry)
fluidPipe.Sources = fluidPipe.Sources[0:0]
}
} }
// 判断路径是否畅通 // 判断路径是否畅通

View File

@ -46,10 +46,17 @@ func towPipePortsTransPower(
breakerPortB *repository.PipePort) { breakerPortB *repository.PipePort) {
//断路器A端连接的管线 //断路器A端连接的管线
breakerPortAPipeEntry := wd.EntityMap[breakerPortA.Device().Id()] breakerPortAPipeEntry := wd.EntityMap[breakerPortA.Device().Id()]
breakerPortAPipe := component.PowerPipeType.Get(breakerPortAPipeEntry) if !breakerPortAPipeEntry.HasComponent(component.PipeElectricityType) {
breakerPortAPipeEntry.AddComponent(component.PipeElectricityType)
}
breakerPortAPipe := component.PipeElectricityType.Get(breakerPortAPipeEntry)
//断路器B端连接的管线 //断路器B端连接的管线
breakerPortBPipeEntry := wd.EntityMap[breakerPortB.Device().Id()] breakerPortBPipeEntry := wd.EntityMap[breakerPortB.Device().Id()]
breakerPortBPipe := component.PowerPipeType.Get(breakerPortBPipeEntry) if !breakerPortBPipeEntry.HasComponent(component.PipeElectricityType) {
breakerPortBPipeEntry.AddComponent(component.PipeElectricityType)
}
breakerPortBPipe := component.PipeElectricityType.Get(breakerPortBPipeEntry)
//A->B //A->B
for portAPipePsId, portAPipePs := range breakerPortAPipe.Sources { //A for portAPipePsId, portAPipePs := range breakerPortAPipe.Sources { //A
portBPipePs, ok := breakerPortBPipe.Sources[portAPipePsId] //B portBPipePs, ok := breakerPortBPipe.Sources[portAPipePsId] //B
@ -58,15 +65,15 @@ func towPipePortsTransPower(
*breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs *breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs
breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1 breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1
if !closed { if !closed {
breakerPortBPipe.Sources[portAPipePsId].Voltage = 0 breakerPortBPipe.Sources[portAPipePsId].SetOut0()
} }
} }
} else { } else {
breakerPortBPipe.Sources[portAPipePsId] = &component.ElePower{} breakerPortBPipe.Sources[portAPipePsId] = component.NewElectricitySource()
*breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs *breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs
breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1 breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1
if !closed { if !closed {
breakerPortBPipe.Sources[portAPipePsId].Voltage = 0 breakerPortBPipe.Sources[portAPipePsId].SetOut0()
} }
} }
} }
@ -78,15 +85,15 @@ func towPipePortsTransPower(
*breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs *breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs
breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1 breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1
if !closed { if !closed {
breakerPortAPipe.Sources[portBPipePsId].Voltage = 0 breakerPortAPipe.Sources[portBPipePsId].SetOut0()
} }
} }
} else { } else {
breakerPortAPipe.Sources[portBPipePsId] = &component.ElePower{} breakerPortAPipe.Sources[portBPipePsId] = component.NewElectricitySource()
*breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs *breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs
breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1 breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1
if !closed { if !closed {
breakerPortAPipe.Sources[portBPipePsId].Voltage = 0 breakerPortAPipe.Sources[portBPipePsId].SetOut0()
} }
} }
} }

View File

@ -28,10 +28,13 @@ func (s *EarthingDeviceSystem) Update(w ecs.World) {
edModel := (wd.Repo.FindById(edId)).(*repository.EarthingDevice) edModel := (wd.Repo.FindById(edId)).(*repository.EarthingDevice)
if edModel.PortA != nil { if edModel.PortA != nil {
edPipeEntry := wd.EntityMap[edModel.PortA.Device().Id()] edPipeEntry := wd.EntityMap[edModel.PortA.Device().Id()]
edPipe := component.PowerPipeType.Get(edPipeEntry) if !edPipeEntry.HasComponent(component.PipeElectricityType) {
ed.Voltage = edPipe.Voltage edPipeEntry.AddComponent(component.PipeElectricityType)
}
edPipe := component.PipeElectricityType.Get(edPipeEntry)
ed.Voltage = edPipe.U
} else { } else {
ed.Voltage = 1 //零电压 ed.Voltage = 0 //零电压
} }
}) })
} }

View File

@ -1,9 +1,12 @@
package iscs_sys package iscs_sys
import ( import (
"fmt"
"joylink.club/ecs" "joylink.club/ecs"
"joylink.club/rtsssimulation/component" "joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/entity" "joylink.club/rtsssimulation/entity"
"joylink.club/rtsssimulation/repository"
"log/slog"
) )
type PipeFittingSystem struct { type PipeFittingSystem struct {
@ -13,18 +16,27 @@ func NewPipeFittingSystem() *PipeFittingSystem {
return &PipeFittingSystem{} return &PipeFittingSystem{}
} }
// Update 母线管件电能传递 // Update in world
func (s *PipeFittingSystem) Update(w ecs.World) { func (s *PipeFittingSystem) Update(w ecs.World) {
wd := entity.GetWorldData(w) wd := entity.GetWorldData(w)
for _, pf := range wd.Repo.PipeFittingMap { for _, pf := range wd.Repo.PipeFittingMap {
if pf.IsEle() { if s.initPipeFitting(wd, pf) && s.isPipeFittingEle(wd, pf) {
//与管件连接的所有管线
pipes := pf.Ports()
//筛选出相对电源 //筛选出相对电源
pipePsMap := make(map[string]*component.ElePower) pipePsMap := s.findEleSourcePipe(wd, pf)
for _, pipePort := range pipes { //管件连接的管线间电能传递
s.transEle(wd, pf, pipePsMap)
}
}
}
// 筛选出相对电源
func (s *PipeFittingSystem) findEleSourcePipe(wd *component.WorldData, pf *repository.PipeFitting) map[string]*component.ElectricitySource {
//筛选出相对电源
pipePsMap := make(map[string]*component.ElectricitySource)
for _, pipePort := range pf.Ports() {
pipeEntry := wd.EntityMap[pipePort.Device().Id()] pipeEntry := wd.EntityMap[pipePort.Device().Id()]
powerPipe := component.PowerPipeType.Get(pipeEntry) if pipeEntry.HasComponent(component.PipeElectricityType) {
powerPipe := component.PipeElectricityType.Get(pipeEntry)
for epId, ep := range powerPipe.Sources { for epId, ep := range powerPipe.Sources {
pipePs, ok := pipePsMap[epId] pipePs, ok := pipePsMap[epId]
if ok { if ok {
@ -36,11 +48,16 @@ func (s *PipeFittingSystem) Update(w ecs.World) {
} }
} }
} }
}
return pipePsMap
}
// 管件连接的管线间电能传递 // 管件连接的管线间电能传递
for _, pipePort := range pipes { func (s *PipeFittingSystem) transEle(wd *component.WorldData, pf *repository.PipeFitting, pipePsMap map[string]*component.ElectricitySource) {
for _, pipePort := range pf.Ports() {
for pipePsId, pipePs := range pipePsMap { //相对电源 for pipePsId, pipePs := range pipePsMap { //相对电源
pipeEntry := wd.EntityMap[pipePort.Device().Id()] pipeEntry := wd.EntityMap[pipePort.Device().Id()]
powerPipe := component.PowerPipeType.Get(pipeEntry) powerPipe := component.PipeElectricityType.Get(pipeEntry)
pipePortPs, ok := powerPipe.Sources[pipePsId] pipePortPs, ok := powerPipe.Sources[pipePsId]
if ok { if ok {
if pipePs.Fresh > pipePortPs.Fresh { if pipePs.Fresh > pipePortPs.Fresh {
@ -48,12 +65,79 @@ func (s *PipeFittingSystem) Update(w ecs.World) {
powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性 powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性
} }
} else { } else {
powerPipe.Sources[pipePsId] = &component.ElePower{} powerPipe.Sources[pipePsId] = &component.ElectricitySource{}
*powerPipe.Sources[pipePsId] = *pipePs *powerPipe.Sources[pipePsId] = *pipePs
powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性 powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性
} }
} }
} }
} }
// 判断该管件是否为连接电线
func (s *PipeFittingSystem) isPipeFittingEle(wd *component.WorldData, pf *repository.PipeFitting) bool {
for _, pipePort := range pf.Ports() {
pipeEntry := wd.EntityMap[pipePort.Device().Id()]
pipe := component.PipeType.Get(pipeEntry)
if pipe.Matter.IsEle() {
return true
} }
} }
return false
}
// 由于初始的管线是无性质的,现根据管件的某个已有性质的管线来初始化管件其他的管线
func (s *PipeFittingSystem) initPipeFitting(wd *component.WorldData, pf *repository.PipeFitting) bool {
pipeMatter := component.PmtNon
for _, pipePort := range pf.Ports() {
pipeEntry := wd.EntityMap[pipePort.Device().Id()]
pipe := component.PipeType.Get(pipeEntry)
if !pipe.Matter.IsNon() {
pipeMatter = pipe.Matter
break
}
}
//
if pipeMatter.IsNon() {
return false
}
//
for _, pipePort := range pf.Ports() {
pipeEntry := wd.EntityMap[pipePort.Device().Id()]
pipe := component.PipeType.Get(pipeEntry)
pipe.Matter = pipeMatter
switch pipe.Matter {
case component.PmtElectricity:
{
if !pipeEntry.HasComponent(component.PipeElectricityType) {
pipeEntry.AddComponent(component.PipeElectricityType)
component.PipeElectricityType.Set(pipeEntry, component.NewPipeElectricity())
}
}
case component.PmtAir:
fallthrough
case component.PmtOil:
fallthrough
case component.PmtSmoke:
fallthrough
case component.PmtWater:
{
if !pipeEntry.HasComponent(component.PipeFluidType) {
pipeEntry.AddComponent(component.PipeFluidType)
component.PipeFluidType.Set(pipeEntry, component.NewPipeFluid())
}
}
default:
slog.Warn(fmt.Sprintf("PipeFittingSystem.initPipeFitting 未处理的管道物质[%d]", pipe.Matter))
}
}
//
return true
}
// 从电线实体获取电线
func getPipeElectricity(pipeEntry *ecs.Entry) *component.PipeElectricity {
if !pipeEntry.HasComponent(component.PipeElectricityType) {
pipeEntry.AddComponent(component.PipeElectricityType)
}
return component.PipeElectricityType.Get(pipeEntry)
}

View File

@ -6,30 +6,34 @@ import (
"joylink.club/rtsssimulation/component" "joylink.club/rtsssimulation/component"
) )
// PowerPipeSystem 电力
type PowerPipeSystem struct { type PowerPipeSystem struct {
query *ecs.Query query *ecs.Query
} }
func NewPowerPipeSystem() *PowerPipeSystem { func NewPowerPipeSystem() *PowerPipeSystem {
return &PowerPipeSystem{ return &PowerPipeSystem{
query: ecs.NewQuery(filter.Contains(component.PowerPipeType)), query: ecs.NewQuery(filter.Contains(component.PipeElectricityType)),
} }
} }
// Update 电力母线中电力计算 // Update 电线中电力计算
func (s *PowerPipeSystem) Update(w ecs.World) { func (s *PowerPipeSystem) Update(w ecs.World) {
s.query.Each(w, func(entry *ecs.Entry) { s.query.Each(w, func(entry *ecs.Entry) {
pipe := component.PowerPipeType.Get(entry) pipe := component.PipeElectricityType.Get(entry)
voltage := uint32(0) voltage := uint32(0)
ac := false ac := false
sx := false
for _, power := range pipe.Sources { for _, power := range pipe.Sources {
if power.Voltage > voltage { if power.U > voltage {
voltage = power.Voltage voltage = power.U
ac = power.Ac ac = power.Ac
sx = power.Sx
} }
} }
// //
pipe.Voltage = voltage pipe.U = voltage
pipe.Ac = ac pipe.Ac = ac
pipe.Sx = sx
}) })
} }

View File

@ -9,26 +9,43 @@ import (
"time" "time"
) )
// PowerSourceSystem 国网
type PowerSourceSystem struct { type PowerSourceSystem struct {
query *ecs.Query query *ecs.Query
} }
func NewPowerSourceSystem() *PowerSourceSystem { func NewPowerSourceSystem() *PowerSourceSystem {
return &PowerSourceSystem{ return &PowerSourceSystem{
query: ecs.NewQuery(filter.Contains(component.UidType, component.PowerSourceType)), query: ecs.NewQuery(filter.Contains(component.UidType, component.ElectricitySourceType)),
} }
} }
func (s *PowerSourceSystem) Update(w ecs.World) { func (s *PowerSourceSystem) Update(w ecs.World) {
wd := entity.GetWorldData(w) wd := entity.GetWorldData(w)
s.query.Each(w, func(entry *ecs.Entry) { s.query.Each(w, func(entry *ecs.Entry) {
psId := component.UidType.Get(entry).Id psId := component.UidType.Get(entry).Id
ps := component.PowerSourceType.Get(entry) ps := component.ElectricitySourceType.Get(entry)
// //
psModel := (wd.Repo.FindById(psId)).(*repository.PowerSource) psModel := (wd.Repo.FindById(psId)).(*repository.PowerSource)
pipeId := psModel.PortA.Device().Id() pipeId := psModel.PortA.Device().Id()
//
ps.Fresh = time.Now().UnixMilli()
ps.Sx = psModel.Sx
ps.Ac = psModel.Ac
ps.U = psModel.Voltage
//电源传递电力给母线 //电源传递电力给母线
pipeEntry := wd.EntityMap[pipeId] s.transPower(wd, pipeId, ps, psId)
powerPipe := component.PowerPipeType.Get(pipeEntry)
powerPipe.TransPower(psId, &component.ElePower{Ac: ps.Ac, Voltage: ps.Voltage, Fresh: time.Now().UnixMilli()})
}) })
} }
func (s *PowerSourceSystem) transPower(wd *component.WorldData, pipeId string, ps *component.ElectricitySource, psId string) {
pipeEntry := wd.EntityMap[pipeId]
if !pipeEntry.HasComponent(component.PipeElectricityType) {
pipeEntry.AddComponent(component.PipeElectricityType)
component.PipeElectricityType.Set(pipeEntry, component.NewPipeElectricity())
}
pipe := component.PipeType.Get(pipeEntry)
pipe.Matter = component.PmtElectricity
//
powerPipe := component.PipeElectricityType.Get(pipeEntry)
powerPipe.TransPower(psId, ps)
}

View File

@ -45,24 +45,25 @@ func (s *RectifierSystem) rectifierTransPower(wd *component.WorldData, entry *ec
portF := rectifierModel.PortD //直负 portF := rectifierModel.PortD //直负
// //
portLPipeEntry := wd.EntityMap[portL.Device().Id()] portLPipeEntry := wd.EntityMap[portL.Device().Id()]
portLPipe := component.PowerPipeType.Get(portLPipeEntry) portLPipe := component.PipeElectricityType.Get(portLPipeEntry)
// //
portZPipeEntry := wd.EntityMap[portZ.Device().Id()] portZPipeEntry := wd.EntityMap[portZ.Device().Id()]
portZPipe := component.PowerPipeType.Get(portZPipeEntry) portZPipe := component.PipeElectricityType.Get(portZPipeEntry)
portFPipeEntry := wd.EntityMap[portF.Device().Id()] portFPipeEntry := wd.EntityMap[portF.Device().Id()]
portFPipe := component.PowerPipeType.Get(portFPipeEntry) portFPipe := component.PipeElectricityType.Get(portFPipeEntry)
//L->Z、F //L->Z、F
for lpsId, lps := range portLPipe.Sources { for lpsId, lps := range portLPipe.Sources {
if lps.Ac { if lps.Ac {
dcVoltage := uint32(float64(lps.Voltage) * 0.9) //交流电压转直流电压 dcVoltage := uint32(float64(lps.U) * 0.9) //交流电压转直流电压
//L->Z //L->Z
zps, zpsOk := portZPipe.Sources[lpsId] zps, zpsOk := portZPipe.Sources[lpsId]
if zpsOk { if zpsOk {
zps.Voltage = dcVoltage zps.U = dcVoltage
zps.Fresh = lps.Fresh - 1 zps.Fresh = lps.Fresh - 1
zps.Ac = false zps.Ac = false
zps.Sx = false
} else { } else {
portZPipe.Sources[lpsId] = &component.ElePower{Ac: false, Voltage: dcVoltage, Fresh: lps.Fresh - 1} portZPipe.Sources[lpsId] = &component.ElectricitySource{Ac: false, Sx: false, U: dcVoltage, Fresh: lps.Fresh - 1}
} }
//L->F //L->F
fps, fpsOk := portFPipe.Sources[lpsId] fps, fpsOk := portFPipe.Sources[lpsId]
@ -71,11 +72,12 @@ func (s *RectifierSystem) rectifierTransPower(wd *component.WorldData, entry *ec
dcFVoltage = 1 dcFVoltage = 1
} }
if fpsOk { if fpsOk {
fps.Voltage = dcFVoltage fps.U = dcFVoltage
fps.Fresh = lps.Fresh - 1 fps.Fresh = lps.Fresh - 1
fps.Ac = false fps.Ac = false
fps.Sx = false
} else { } else {
portFPipe.Sources[lpsId] = &component.ElePower{Ac: false, Voltage: dcFVoltage, Fresh: lps.Fresh - 1} portFPipe.Sources[lpsId] = &component.ElectricitySource{Ac: false, Sx: false, U: dcFVoltage, Fresh: lps.Fresh - 1}
} }
} }
} }

View File

@ -37,49 +37,48 @@ func (s *VoltageTransformerSystem) voltageTransformerTransPower(wd *component.Wo
// //
vtPortA := vtModel.PortA vtPortA := vtModel.PortA
vtPortAEntry := wd.EntityMap[vtPortA.Device().Id()] vtPortAEntry := wd.EntityMap[vtPortA.Device().Id()]
vtPortAPipe := component.PowerPipeType.Get(vtPortAEntry) //变压器一次侧连接的管线 vtPortAPipe := getPipeElectricity(vtPortAEntry) //变压器一次侧连接的管线
// //
var vtPortBPipe *component.PowerPipe = nil var vtPortBPipe *component.PipeElectricity = nil
if vtModel.PortB != nil { if vtModel.PortB != nil {
vtPortB := vtModel.PortB vtPortB := vtModel.PortB
vtPortBEntry := wd.EntityMap[vtPortB.Device().Id()] vtPortBEntry := wd.EntityMap[vtPortB.Device().Id()]
vtPortBPipe = component.PowerPipeType.Get(vtPortBEntry) vtPortBPipe = getPipeElectricity(vtPortBEntry)
} }
// //
var vtPortCPipe *component.PowerPipe = nil var vtPortCPipe *component.PipeElectricity = nil
if vtModel.PortC != nil { if vtModel.PortC != nil {
vtPortC := vtModel.PortC vtPortC := vtModel.PortC
vtPortCEntry := wd.EntityMap[vtPortC.Device().Id()] vtPortCEntry := wd.EntityMap[vtPortC.Device().Id()]
vtPortCPipe = component.PowerPipeType.Get(vtPortCEntry) vtPortCPipe = getPipeElectricity(vtPortCEntry)
} }
//变压比 //变压比
rate := float64(vtModel.E2) / float64(vtModel.E1) rate := float64(vtModel.E2) / float64(vtModel.E1)
//A->B、C ,电能从一次侧向二次侧传递 //A->B、C ,电能从一次侧向二次侧传递
for psId, ps := range vtPortAPipe.Sources { for psId, ps := range vtPortAPipe.Sources {
//二次侧输出电压 //二次侧输出电压
outV := uint32(rate * float64(ps.Voltage)) outV := uint32(rate * float64(ps.U))
if vtPortBPipe != nil { //二次侧火线 if vtPortBPipe != nil { //二次侧火线
portBPs, ok := vtPortBPipe.Sources[psId] portBPs, ok := vtPortBPipe.Sources[psId]
if ok { if ok {
portBPs.Voltage = outV portBPs.U = outV
portBPs.Ac = ps.Ac portBPs.Ac = ps.Ac
portBPs.Sx = ps.Sx
portBPs.Fresh = ps.Fresh - 1 portBPs.Fresh = ps.Fresh - 1
} else { } else {
vtPortBPipe.Sources[psId] = &component.ElePower{Ac: ps.Ac, Voltage: outV, Fresh: ps.Fresh - 1} vtPortBPipe.Sources[psId] = &component.ElectricitySource{Ac: ps.Ac, Sx: ps.Sx, U: outV, Fresh: ps.Fresh - 1}
} }
} }
if vtPortCPipe != nil { //二次侧零线 if vtPortCPipe != nil { //二次侧零线
portCPs, ok := vtPortCPipe.Sources[psId] portCPs, ok := vtPortCPipe.Sources[psId]
cV := uint32(0) cV := uint32(0)
if outV > 0 { //当二次火线电压大于零时二次侧零线电压值1表示零电位
cV = 1
}
if ok { if ok {
portCPs.Voltage = cV portCPs.U = cV
portCPs.Ac = ps.Ac portCPs.Ac = ps.Ac
portCPs.Sx = ps.Sx
portCPs.Fresh = ps.Fresh - 1 portCPs.Fresh = ps.Fresh - 1
} else { } else {
vtPortCPipe.Sources[psId] = &component.ElePower{Ac: ps.Ac, Voltage: cV, Fresh: ps.Fresh - 1} vtPortCPipe.Sources[psId] = &component.ElectricitySource{Ac: ps.Ac, Sx: ps.Sx, U: cV, Fresh: ps.Fresh - 1}
} }
} }
} }