iscs pscada 一次图 电力传递实现

This commit is contained in:
xzb 2023-12-21 15:36:02 +08:00
parent 17cafe3946
commit a9b3c09415
7 changed files with 304 additions and 53 deletions

View File

@ -83,9 +83,18 @@ type VoltageTransformer struct {
// PowerPipe 电力母线
type PowerPipe struct {
Voltage uint32 //母线当前电压
Ac bool //true-交流电false-直流电
Sources map[string]ElePower //key-电源PowerSource实体id
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
} else {
p.Sources[powerSourceId] = power
}
}
// ElePower 传输中的电力

View File

@ -46,8 +46,3 @@ func LoadIscs(w ecs.World) error {
//
return nil
}
/*
PipeFittingMap map[string]*PipeFitting //ISCS 管件
*/

View File

@ -112,6 +112,7 @@ func NewPowerPipeEntity(w ecs.World, id string) *ecs.Entry {
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)})
wd.EntityMap[id] = e
}
return e

View File

@ -568,7 +568,7 @@ message HandcartSwitch{
}
//
//PSCADA中整流器有两个交流输入端分别为A和B;C和直流负极端口D
//PSCADA中整流器有两个交流输入端分别为A(线L)B(线N);C(+)D(-)
message Rectifier{
string id = 1;
string code = 2;

View File

@ -75,6 +75,16 @@ 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
@ -201,14 +211,14 @@ func (p *HandcartSwitchPort) Device() PortedDevice {
// Rectifier 整流器模型
//
// PSCADA中整流器有两个交流输入端分别为A和B;直流输出端口有两个分别为直流正极端口C和直流负极端口D
// PSCADA中整流器有两个交流输入端分别为A(火线L)和B(零线N);直流输出端口有两个分别为直流正极端口C(+正极)和直流负极端口D(-负极)
type Rectifier struct {
Identity
Code string
PortA *PipePort //整流器A端口连接的管线
PortB *PipePort //整流器B端口连接的管线
PortC *PipePort //整流器C端口连接的管线
PortD *PipePort //整流器D端口连接的管线
PortA *PipePort //整流器A端口连接的管线,交流L(火线)
PortB *PipePort //整流器B端口连接的管线,交流N(零线)
PortC *PipePort //整流器C端口连接的管线,直流+
PortD *PipePort //整流器D端口连接的管线,直流-
}
func NewRectifier(id string, code string) *Rectifier {

View File

@ -1,36 +0,0 @@
package iscs_sys
import (
"joylink.club/ecs"
"joylink.club/ecs/filter"
"joylink.club/rtsssimulation/component"
"time"
)
// PowerPipeSystem 电力母线,计算母线中的电压
type PowerPipeSystem struct {
query *ecs.Query
}
func NewPowerPipeSystem() *PowerPipeSystem {
return &PowerPipeSystem{query: ecs.NewQuery(filter.Contains(component.PowerPipeType))}
}
func (s *PowerPipeSystem) Update(w ecs.World) {
//计算电力母线中的电压
s.query.Each(w, func(entry *ecs.Entry) {
pipe := component.PowerPipeType.Get(entry)
voltage := uint32(0)
ac := false
for _, power := range pipe.Sources {
if time.Now().UnixMilli()-power.Fresh <= int64(w.Tick()*2) {
if power.Voltage > voltage {
voltage = power.Voltage
ac = power.Ac
}
}
}
//
pipe.Voltage = voltage
pipe.Ac = ac
})
}

View File

@ -1,11 +1,283 @@
package iscs_sys
import "joylink.club/ecs"
import (
"joylink.club/ecs"
"joylink.club/ecs/filter"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/entity"
"joylink.club/rtsssimulation/repository"
"time"
)
// PowerTransmissionSystem 电力传递系统
// PowerTransmissionSystem 电力传递系统(电压传递)
type PowerTransmissionSystem struct {
queryPowerSource *ecs.Query //电力电源
queryPowerPipe *ecs.Query //电力母线
queryCircuitBreaker *ecs.Query //断路器
queryHandcart *ecs.Query //手车
queryDisconnector *ecs.Query //隔离开关
query3PositionSwitch *ecs.Query //三工位隔离开关
queryRectifier *ecs.Query //整流器
}
func NewPowerTransmissionSystem() *PowerTransmissionSystem {
return &PowerTransmissionSystem{
queryPowerSource: ecs.NewQuery(filter.Contains(component.UidType, component.PowerSourceType)),
queryPowerPipe: ecs.NewQuery(filter.Contains(component.PowerPipeType)),
queryCircuitBreaker: ecs.NewQuery(filter.Contains(component.UidType, component.CircuitBreakerType)),
queryHandcart: ecs.NewQuery(filter.Contains(component.UidType, component.HandcartSwitchType)),
queryDisconnector: ecs.NewQuery(filter.Contains(component.UidType, component.DisconnectorType)),
query3PositionSwitch: ecs.NewQuery(filter.Contains(component.UidType, component.ThreePositionSwitchType)),
queryRectifier: ecs.NewQuery(filter.Contains(component.UidType, component.RectifierType)),
}
}
func (s *PowerTransmissionSystem) Update(w ecs.World) {
s.powerSourceTransPower(w)
s.circuitBreakerTransPower(w)
s.handcartTransPower(w)
s.disconnectorTransPower(w)
s.threePositionSwitchTransPower(w)
s.pipeFittingTransPower(w)
s.rectifierTransPower(w)
s.powerPipePower(w)
}
// 整流器电能传递
// 当线路接通时零线和负极电压规定值为1当线路断开时零线和负极电压规定值为0
func (s *PowerTransmissionSystem) rectifierTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
s.queryRectifier.Each(w, func(entry *ecs.Entry) {
rectifierId := component.UidType.Get(entry).Id
rectifierModel := wd.Repo.FindById(rectifierId).(*repository.Rectifier)
//
portL := rectifierModel.PortA //交火
//portN := rectifierModel.PortB //交零
portZ := rectifierModel.PortC //直正
portF := rectifierModel.PortD //直负
//
portLPipeEntry := wd.EntityMap[portL.Device().Id()]
portLPipe := component.PowerPipeType.Get(portLPipeEntry)
//
portZPipeEntry := wd.EntityMap[portZ.Device().Id()]
portZPipe := component.PowerPipeType.Get(portZPipeEntry)
portFPipeEntry := wd.EntityMap[portF.Device().Id()]
portFPipe := component.PowerPipeType.Get(portFPipeEntry)
//L->Z、F
for lpsId, lps := range portLPipe.Sources {
if lps.Ac {
dcVoltage := uint32(float64(lps.Voltage) * 0.9) //交流电压转直流电压
//L->Z
zps, zpsOk := portZPipe.Sources[lpsId]
if zpsOk {
zps.Voltage = dcVoltage
zps.Fresh = lps.Fresh - 1
zps.Ac = false
} else {
portZPipe.Sources[lpsId] = &component.ElePower{Ac: false, Voltage: dcVoltage, Fresh: lps.Fresh - 1}
}
//L->F
fps, fpsOk := portFPipe.Sources[lpsId]
dcFVoltage := uint32(0)
if dcVoltage > 0 {
dcFVoltage = 1
}
if fpsOk {
fps.Voltage = dcFVoltage
fps.Fresh = lps.Fresh - 1
fps.Ac = false
} else {
portFPipe.Sources[lpsId] = &component.ElePower{Ac: false, Voltage: dcFVoltage, Fresh: lps.Fresh - 1}
}
}
}
})
}
// 三工位隔离开关传递电能
func (s *PowerTransmissionSystem) threePositionSwitchTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
s.query3PositionSwitch.Each(w, func(entry *ecs.Entry) {
breakerId := component.UidType.Get(entry).Id
closed := component.ThreePositionSwitchType.Get(entry).Position == component.StpClosedWorking
breakerModel := (wd.Repo.FindById(breakerId)).(*repository.ThreePositionSwitch)
breakerPortA := breakerModel.PortA
breakerPortB := breakerModel.PortB
s.towPipePortsTransPower(wd, closed, breakerPortA, breakerPortB)
})
}
// 隔离开关传递电能
func (s *PowerTransmissionSystem) disconnectorTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
s.queryHandcart.Each(w, func(entry *ecs.Entry) {
breakerId := component.UidType.Get(entry).Id
closed := component.DisconnectorType.Get(entry).Closed
breakerModel := (wd.Repo.FindById(breakerId)).(*repository.Disconnector)
breakerPortA := breakerModel.PortA
breakerPortB := breakerModel.PortB
s.towPipePortsTransPower(wd, closed, breakerPortA, breakerPortB)
})
}
// 手车传递电能
func (s *PowerTransmissionSystem) handcartTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
s.queryHandcart.Each(w, func(entry *ecs.Entry) {
breakerId := component.UidType.Get(entry).Id
closed := component.HandcartSwitchType.Get(entry).Position == component.HpClosed
breakerModel := (wd.Repo.FindById(breakerId)).(*repository.HandcartSwitch)
breakerPortA := breakerModel.PortA
breakerPortB := breakerModel.PortB
s.towPipePortsTransPower(wd, closed, breakerPortA, breakerPortB)
})
}
// 断路器传递电能
func (s *PowerTransmissionSystem) circuitBreakerTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
s.queryCircuitBreaker.Each(w, func(entry *ecs.Entry) {
breakerId := component.UidType.Get(entry).Id
closed := component.CircuitBreakerType.Get(entry).Closed
breakerModel := (wd.Repo.FindById(breakerId)).(*repository.CircuitBreaker)
//断路器A端连接的管线
breakerPortA := breakerModel.PortA
//断路器B端连接的管线
breakerPortB := breakerModel.PortB
//传递电能
s.towPipePortsTransPower(wd, closed, breakerPortA, breakerPortB)
})
}
// 电力母线中电力计算
func (s *PowerTransmissionSystem) powerPipePower(w ecs.World) {
s.queryPowerPipe.Each(w, func(entry *ecs.Entry) {
pipe := component.PowerPipeType.Get(entry)
voltage := uint32(0)
ac := false
for _, power := range pipe.Sources {
if power.Voltage > voltage {
voltage = power.Voltage
ac = power.Ac
}
}
//
pipe.Voltage = voltage
pipe.Ac = ac
})
}
// 电源传递电能
func (s *PowerTransmissionSystem) powerSourceTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
s.queryPowerSource.Each(w, func(entry *ecs.Entry) {
psId := component.UidType.Get(entry).Id
ps := component.PowerSourceType.Get(entry)
//
psModel := (wd.Repo.FindById(psId)).(*repository.PowerSource)
pipeId := psModel.PortA.Device().Id()
//电源传递电力给母线
pipeEntry := wd.EntityMap[pipeId]
powerPipe := component.PowerPipeType.Get(pipeEntry)
powerPipe.TransPower(psId, &component.ElePower{Ac: ps.Ac, Voltage: ps.Voltage, Fresh: time.Now().UnixMilli()})
})
}
// 母线管件传递电能
func (s *PowerTransmissionSystem) pipeFittingTransPower(w ecs.World) {
wd := entity.GetWorldData(w)
for _, pf := range wd.Repo.PipeFittingMap {
if pf.IsEle() {
//与管件连接的所有管线
pipes := pf.Ports()
//筛选出相对电源
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[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 //保证相对性
}
}
}
}
}
}
// 两位置开关传递电能(断路器、手车、隔离开关)
func (s *PowerTransmissionSystem) towPipePortsTransPower(
wd *component.WorldData,
closed bool,
breakerPortA *repository.PipePort,
breakerPortB *repository.PipePort) {
//断路器A端连接的管线
breakerPortAPipeEntry := wd.EntityMap[breakerPortA.Device().Id()]
breakerPortAPipe := component.PowerPipeType.Get(breakerPortAPipeEntry)
//断路器B端连接的管线
breakerPortBPipeEntry := wd.EntityMap[breakerPortB.Device().Id()]
breakerPortBPipe := component.PowerPipeType.Get(breakerPortBPipeEntry)
//A->B
for portAPipePsId, portAPipePs := range breakerPortAPipe.Sources { //A
portBPipePs, ok := breakerPortBPipe.Sources[portAPipePsId] //B
if ok {
if portAPipePs.Fresh > portBPipePs.Fresh {
*breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs
breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1
if !closed {
breakerPortBPipe.Sources[portAPipePsId].Voltage = 0
}
}
} else {
breakerPortBPipe.Sources[portAPipePsId] = &component.ElePower{}
*breakerPortBPipe.Sources[portAPipePsId] = *portAPipePs
breakerPortBPipe.Sources[portAPipePsId].Fresh -= 1
if !closed {
breakerPortBPipe.Sources[portAPipePsId].Voltage = 0
}
}
}
//B->A
for portBPipePsId, portBPipePs := range breakerPortBPipe.Sources { //B
portAPipePs, ok := breakerPortAPipe.Sources[portBPipePsId] //A
if ok {
if portBPipePs.Fresh > portAPipePs.Fresh {
*breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs
breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1
if !closed {
breakerPortAPipe.Sources[portBPipePsId].Voltage = 0
}
}
} else {
breakerPortAPipe.Sources[portBPipePsId] = &component.ElePower{}
*breakerPortAPipe.Sources[portBPipePsId] = *portBPipePs
breakerPortAPipe.Sources[portBPipePsId].Fresh -= 1
if !closed {
breakerPortAPipe.Sources[portBPipePsId].Voltage = 0
}
}
}
}