iscs pscada 一次图 电力传递实现
This commit is contained in:
parent
17cafe3946
commit
a9b3c09415
@ -83,9 +83,18 @@ type VoltageTransformer struct {
|
|||||||
|
|
||||||
// PowerPipe 电力母线
|
// PowerPipe 电力母线
|
||||||
type PowerPipe struct {
|
type PowerPipe struct {
|
||||||
Voltage uint32 //母线当前电压
|
Voltage uint32 //母线当前电压
|
||||||
Ac bool //true-交流电;false-直流电
|
Ac bool //true-交流电;false-直流电
|
||||||
Sources map[string]ElePower //key-电源PowerSource实体id
|
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 传输中的电力
|
// ElePower 传输中的电力
|
||||||
|
@ -46,8 +46,3 @@ func LoadIscs(w ecs.World) error {
|
|||||||
//
|
//
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
PipeFittingMap map[string]*PipeFitting //ISCS 管件
|
|
||||||
*/
|
|
||||||
|
@ -112,6 +112,7 @@ func NewPowerPipeEntity(w ecs.World, id string) *ecs.Entry {
|
|||||||
if !ok {
|
if !ok {
|
||||||
e := w.Entry(w.Create(component.UidType, component.PowerPipeType))
|
e := w.Entry(w.Create(component.UidType, component.PowerPipeType))
|
||||||
component.UidType.SetValue(e, component.Uid{Id: id})
|
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
|
||||||
|
@ -568,7 +568,7 @@ message HandcartSwitch{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//整流器
|
//整流器
|
||||||
//PSCADA中整流器有两个交流输入端分别为A和B;直流输出端口有两个分别为直流正极端口C和直流负极端口D
|
//PSCADA中整流器有两个交流输入端分别为A(火线L)和B(零线N);直流输出端口有两个分别为直流正极端口C(+正极)和直流负极端口D(-负极)
|
||||||
message Rectifier{
|
message Rectifier{
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string code = 2;
|
string code = 2;
|
||||||
|
@ -75,6 +75,16 @@ 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
|
||||||
@ -201,14 +211,14 @@ func (p *HandcartSwitchPort) Device() PortedDevice {
|
|||||||
|
|
||||||
// Rectifier 整流器模型
|
// Rectifier 整流器模型
|
||||||
//
|
//
|
||||||
// PSCADA中整流器有两个交流输入端分别为A和B;直流输出端口有两个分别为直流正极端口C和直流负极端口D
|
// PSCADA中整流器有两个交流输入端分别为A(火线L)和B(零线N);直流输出端口有两个分别为直流正极端口C(+正极)和直流负极端口D(-负极)
|
||||||
type Rectifier struct {
|
type Rectifier struct {
|
||||||
Identity
|
Identity
|
||||||
Code string
|
Code string
|
||||||
PortA *PipePort //整流器A端口连接的管线
|
PortA *PipePort //整流器A端口连接的管线,交流L(火线)
|
||||||
PortB *PipePort //整流器B端口连接的管线
|
PortB *PipePort //整流器B端口连接的管线,交流N(零线)
|
||||||
PortC *PipePort //整流器C端口连接的管线
|
PortC *PipePort //整流器C端口连接的管线,直流+
|
||||||
PortD *PipePort //整流器D端口连接的管线
|
PortD *PipePort //整流器D端口连接的管线,直流-
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRectifier(id string, code string) *Rectifier {
|
func NewRectifier(id string, code string) *Rectifier {
|
||||||
|
@ -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
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,11 +1,283 @@
|
|||||||
package iscs_sys
|
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 {
|
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) {
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user