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.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.31.0
// protoc v4.23.1
// source: component/ci.proto

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,37 +2,128 @@ package component
import "joylink.club/ecs"
// FluidPipe 流体管线
type FluidPipe struct {
Direction PipeFlowDirection //管线内综合流动方向
FlowSpeed float32 //管线内综合流量m3/h
Sources []*SourceFlow //该管线内所有流体源投射的分量
}
///////////////////////////////////////////
//组合空调柜AHU-A01 二通阀MOV-A01
//回排风机RAF-A01 风阀MDD-A03
//排烟风机SEF-A01 风阀MDD-A04
//排风阀MDA-A02
//回风阀MDA-A03
//小新风阀MDA-A01
//空调柜MDD-A02
//防烟防火SFD-A01
// SourceFlow 流体源进入管线的流体描述
type SourceFlow struct {
Direction PipeFlowDirection
FlowSpeed float32
}
// PipeFlowDirection 管线内流体流动方向定义
type PipeFlowDirection int8
// PipeMatter 管线中传输的物质类型
type PipeMatter uint8
const (
PipeFlowNon PipeFlowDirection = iota //流体未流动
PipeFlowAb //流体从管线的A->B
PipeFlowBa //流体从管线的B->A
PmtNon PipeMatter = iota //未知或没有
PmtWater
PmtElectricity //电
PmtAir //正常空气
PmtSmoke //含有有害烟的空气(如火灾时的烟气)
PmtOil //油
)
func (d *PipeFlowDirection) IsFlowAb() bool {
return *d == PipeFlowAb
func (m *PipeMatter) IsNon() bool {
return *m == PmtNon
}
func (d *PipeFlowDirection) IsFlowBa() bool {
return *d == PipeFlowBa
func (m *PipeMatter) IsEle() bool {
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 流体驱动器
type FluidDriver struct {
@ -40,6 +131,5 @@ type FluidDriver struct {
}
var (
FluidPipeType = ecs.NewComponentType[FluidPipe]() //流体管线
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 电力母线当前电压等级定义
type PscadaVoltageLevel uint8
@ -139,12 +113,6 @@ const (
PscadaVoltageDc1500V //1500V直流
)
// PowerSource 电源(国家电网)
type PowerSource struct {
Voltage uint32 //电压
Ac bool //true-交流电false-直流电
}
//////////////////////////////////////////////////////////////////////////////////
var (
@ -156,8 +124,6 @@ var (
LightningArresterType = ecs.NewComponentType[LightningArrester]() //避雷器
RectifierType = ecs.NewComponentType[Rectifier]() //整流器
VoltageTransformerType = ecs.NewComponentType[VoltageTransformer]() //变压器
PowerPipeType = ecs.NewComponentType[PowerPipe]() //电力母线
PowerSourceType = ecs.NewComponentType[PowerSource]() //电源
EarthingDeviceType = ecs.NewComponentType[EarthingDevice]() //接地装置
)

View File

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

View File

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

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

View File

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

View File

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

View File

@ -10,14 +10,13 @@ import (
// Pipe 管线模型
type Pipe struct {
Identity
Code string
PipeType proto.Pipe_Type
PortA DevicePort //管线的A端连接的设备
PortB DevicePort //管线的B端连接的设备
Code string
PortA DevicePort //管线的A端连接的设备
PortB DevicePort //管线的B端连接的设备
}
func NewPipe(id string, code string, pipeType proto.Pipe_Type) *Pipe {
return &Pipe{Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_Pipe}, Code: code, PipeType: pipeType}
func NewPipe(id string, code string) *Pipe {
return &Pipe{Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_Pipe}, Code: code}
}
func (p *Pipe) PortNum() int {
return 2
@ -105,16 +104,6 @@ func (p *PipeFitting) Ports() []*PipePort {
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 管件端口
//
// implement DevicePort
@ -365,16 +354,18 @@ type PowerSource struct {
Identity
Code string
PortA *PipePort //电源A端口连接的管线
Ac bool //true-交流false-直流
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{
Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_PowerSource},
Code: code,
Ac: ac,
Voltage: voltage,
Sx: sx,
Ac: ac,
}
}
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 {
//ISCS管线
for _, protoData := range source.Pipes {
m := NewPipe(protoData.Id, protoData.Code, protoData.PipeType)
m := NewPipe(protoData.Id, protoData.Code)
repository.PipeMap[m.Id()] = m
}
//ISCS管件
@ -46,7 +46,7 @@ func buildIscsModels(source *proto.Repository, repository *Repository) error {
}
//ISCS电源
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
}
//ISCS避雷器

View File

@ -23,7 +23,7 @@ type FluidDriverSystem struct {
func NewFluidDriverSystem() *FluidDriverSystem {
return &FluidDriverSystem{
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
}
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) {
//断路器A端连接的管线
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端连接的管线
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
for portAPipePsId, portAPipePs := range breakerPortAPipe.Sources { //A
portBPipePs, ok := breakerPortBPipe.Sources[portAPipePsId] //B
@ -58,15 +65,15 @@ func towPipePortsTransPower(
*breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs
breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1
if !closed {
breakerPortBPipe.Sources[portAPipePsId].Voltage = 0
breakerPortBPipe.Sources[portAPipePsId].SetOut0()
}
}
} else {
breakerPortBPipe.Sources[portAPipePsId] = &component.ElePower{}
breakerPortBPipe.Sources[portAPipePsId] = component.NewElectricitySource()
*breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs
breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1
if !closed {
breakerPortBPipe.Sources[portAPipePsId].Voltage = 0
breakerPortBPipe.Sources[portAPipePsId].SetOut0()
}
}
}
@ -78,15 +85,15 @@ func towPipePortsTransPower(
*breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs
breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1
if !closed {
breakerPortAPipe.Sources[portBPipePsId].Voltage = 0
breakerPortAPipe.Sources[portBPipePsId].SetOut0()
}
}
} else {
breakerPortAPipe.Sources[portBPipePsId] = &component.ElePower{}
breakerPortAPipe.Sources[portBPipePsId] = component.NewElectricitySource()
*breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs
breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1
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)
if edModel.PortA != nil {
edPipeEntry := wd.EntityMap[edModel.PortA.Device().Id()]
edPipe := component.PowerPipeType.Get(edPipeEntry)
ed.Voltage = edPipe.Voltage
if !edPipeEntry.HasComponent(component.PipeElectricityType) {
edPipeEntry.AddComponent(component.PipeElectricityType)
}
edPipe := component.PipeElectricityType.Get(edPipeEntry)
ed.Voltage = edPipe.U
} else {
ed.Voltage = 1 //零电压
ed.Voltage = 0 //零电压
}
})
}

View File

@ -1,9 +1,12 @@
package iscs_sys
import (
"fmt"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/entity"
"joylink.club/rtsssimulation/repository"
"log/slog"
)
type PipeFittingSystem struct {
@ -13,47 +16,128 @@ func NewPipeFittingSystem() *PipeFittingSystem {
return &PipeFittingSystem{}
}
// Update 母线管件电能传递
// Update in world
func (s *PipeFittingSystem) Update(w ecs.World) {
wd := entity.GetWorldData(w)
for _, pf := range wd.Repo.PipeFittingMap {
if pf.IsEle() {
//与管件连接的所有管线
pipes := pf.Ports()
if s.initPipeFitting(wd, pf) && s.isPipeFittingEle(wd, pf) {
//筛选出相对电源
pipePsMap := make(map[string]*component.ElePower)
for _, pipePort := range pipes {
pipeEntry := wd.EntityMap[pipePort.Device().Id()]
powerPipe := component.PowerPipeType.Get(pipeEntry)
for epId, ep := range powerPipe.Sources {
pipePs, ok := pipePsMap[epId]
if ok {
if ep.Fresh > pipePs.Fresh {
pipePsMap[epId] = ep
}
} else {
pipePsMap := s.findEleSourcePipe(wd, pf)
//管件连接的管线间电能传递
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()]
if pipeEntry.HasComponent(component.PipeElectricityType) {
powerPipe := component.PipeElectricityType.Get(pipeEntry)
for epId, ep := range powerPipe.Sources {
pipePs, ok := pipePsMap[epId]
if ok {
if ep.Fresh > pipePs.Fresh {
pipePsMap[epId] = ep
}
}
}
//管件连接的管线间电能传递
for _, pipePort := range pipes {
for pipePsId, pipePs := range pipePsMap { //相对电源
pipeEntry := wd.EntityMap[pipePort.Device().Id()]
powerPipe := component.PowerPipeType.Get(pipeEntry)
pipePortPs, ok := powerPipe.Sources[pipePsId]
if ok {
if pipePs.Fresh > pipePortPs.Fresh {
*powerPipe.Sources[pipePsId] = *pipePs
powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性
}
} else {
powerPipe.Sources[pipePsId] = &component.ElePower{}
*powerPipe.Sources[pipePsId] = *pipePs
powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性
}
} else {
pipePsMap[epId] = ep
}
}
}
}
return pipePsMap
}
// 管件连接的管线间电能传递
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 { //相对电源
pipeEntry := wd.EntityMap[pipePort.Device().Id()]
powerPipe := component.PipeElectricityType.Get(pipeEntry)
pipePortPs, ok := powerPipe.Sources[pipePsId]
if ok {
if pipePs.Fresh > pipePortPs.Fresh {
*powerPipe.Sources[pipePsId] = *pipePs
powerPipe.Sources[pipePsId].Fresh -= 1 //保证相对性
}
} else {
powerPipe.Sources[pipePsId] = &component.ElectricitySource{}
*powerPipe.Sources[pipePsId] = *pipePs
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"
)
// PowerPipeSystem 电力
type PowerPipeSystem struct {
query *ecs.Query
}
func NewPowerPipeSystem() *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) {
s.query.Each(w, func(entry *ecs.Entry) {
pipe := component.PowerPipeType.Get(entry)
pipe := component.PipeElectricityType.Get(entry)
voltage := uint32(0)
ac := false
sx := false
for _, power := range pipe.Sources {
if power.Voltage > voltage {
voltage = power.Voltage
if power.U > voltage {
voltage = power.U
ac = power.Ac
sx = power.Sx
}
}
//
pipe.Voltage = voltage
pipe.U = voltage
pipe.Ac = ac
pipe.Sx = sx
})
}

View File

@ -9,26 +9,43 @@ import (
"time"
)
// PowerSourceSystem 国网
type PowerSourceSystem struct {
query *ecs.Query
}
func NewPowerSourceSystem() *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) {
wd := entity.GetWorldData(w)
s.query.Each(w, func(entry *ecs.Entry) {
psId := component.UidType.Get(entry).Id
ps := component.PowerSourceType.Get(entry)
ps := component.ElectricitySourceType.Get(entry)
//
psModel := (wd.Repo.FindById(psId)).(*repository.PowerSource)
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]
powerPipe := component.PowerPipeType.Get(pipeEntry)
powerPipe.TransPower(psId, &component.ElePower{Ac: ps.Ac, Voltage: ps.Voltage, Fresh: time.Now().UnixMilli()})
s.transPower(wd, pipeId, ps, psId)
})
}
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 //直负
//
portLPipeEntry := wd.EntityMap[portL.Device().Id()]
portLPipe := component.PowerPipeType.Get(portLPipeEntry)
portLPipe := component.PipeElectricityType.Get(portLPipeEntry)
//
portZPipeEntry := wd.EntityMap[portZ.Device().Id()]
portZPipe := component.PowerPipeType.Get(portZPipeEntry)
portZPipe := component.PipeElectricityType.Get(portZPipeEntry)
portFPipeEntry := wd.EntityMap[portF.Device().Id()]
portFPipe := component.PowerPipeType.Get(portFPipeEntry)
portFPipe := component.PipeElectricityType.Get(portFPipeEntry)
//L->Z、F
for lpsId, lps := range portLPipe.Sources {
if lps.Ac {
dcVoltage := uint32(float64(lps.Voltage) * 0.9) //交流电压转直流电压
dcVoltage := uint32(float64(lps.U) * 0.9) //交流电压转直流电压
//L->Z
zps, zpsOk := portZPipe.Sources[lpsId]
if zpsOk {
zps.Voltage = dcVoltage
zps.U = dcVoltage
zps.Fresh = lps.Fresh - 1
zps.Ac = false
zps.Sx = false
} 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
fps, fpsOk := portFPipe.Sources[lpsId]
@ -71,11 +72,12 @@ func (s *RectifierSystem) rectifierTransPower(wd *component.WorldData, entry *ec
dcFVoltage = 1
}
if fpsOk {
fps.Voltage = dcFVoltage
fps.U = dcFVoltage
fps.Fresh = lps.Fresh - 1
fps.Ac = false
fps.Sx = false
} 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
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 {
vtPortB := vtModel.PortB
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 {
vtPortC := vtModel.PortC
vtPortCEntry := wd.EntityMap[vtPortC.Device().Id()]
vtPortCPipe = component.PowerPipeType.Get(vtPortCEntry)
vtPortCPipe = getPipeElectricity(vtPortCEntry)
}
//变压比
rate := float64(vtModel.E2) / float64(vtModel.E1)
//A->B、C ,电能从一次侧向二次侧传递
for psId, ps := range vtPortAPipe.Sources {
//二次侧输出电压
outV := uint32(rate * float64(ps.Voltage))
outV := uint32(rate * float64(ps.U))
if vtPortBPipe != nil { //二次侧火线
portBPs, ok := vtPortBPipe.Sources[psId]
if ok {
portBPs.Voltage = outV
portBPs.U = outV
portBPs.Ac = ps.Ac
portBPs.Sx = ps.Sx
portBPs.Fresh = ps.Fresh - 1
} 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 { //二次侧零线
portCPs, ok := vtPortCPipe.Sources[psId]
cV := uint32(0)
if outV > 0 { //当二次火线电压大于零时二次侧零线电压值1表示零电位
cV = 1
}
if ok {
portCPs.Voltage = cV
portCPs.U = cV
portCPs.Ac = ps.Ac
portCPs.Sx = ps.Sx
portCPs.Fresh = ps.Fresh - 1
} 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}
}
}
}