This commit is contained in:
walker 2023-12-27 09:15:29 +08:00
commit 07248c0fec
8 changed files with 237 additions and 127 deletions

View File

@ -2,63 +2,18 @@ package component
import "joylink.club/ecs"
// FanDevice 风机设备
// 正转即顺时针转-排风;反转即逆时针转-进风
type FanDevice struct {
Speed float32 //风机转速r/min
Forward bool //true-正转false-反转
Fs FanSwitch //风机开关
}
// FanSwitch 风机电源开关定义
type FanSwitch uint8
const (
Off FanSwitch = iota
OnForward //正转
OnReverse //反转
)
func (f *FanSwitch) Off() bool {
return *f == Off
}
func (f *FanSwitch) OnForward() bool {
return *f == OnForward
}
func (f *FanSwitch) OnReverse() bool {
return *f == OnReverse
}
func (f *FanSwitch) On() bool {
return *f == OnReverse || *f == OnForward
}
// FanFcUnit 风机变频器
// 电机转速与变频器频率关系 计算公式n=60f/p其中n是同步转速f是频率P是磁极对数
// 变频器的额定输出频率一般为0-100HZ
type FanFcUnit struct {
F uint16 //变频器频率(0-100HZ)
}
// FanBypassUnit 风机旁路装置
type FanBypassUnit struct {
Bypass bool //true-风机旁路已开启
}
// FanSoftStartUnit 风机软启装置
type FanSoftStartUnit struct {
SoftStart bool //true-风机软启已开启
}
// FanHighLowSpeedMode 风机双速模式控制
type FanHighLowSpeedMode struct {
HighMode bool //true-风机高速模式false-风机低速模式
}
var (
FanDeviceType = ecs.NewComponentType[FanDevice]() //风机设备
FanFcUnitType = ecs.NewComponentType[FanFcUnit]() //风机变频装置
FanBypassUnitType = ecs.NewComponentType[FanBypassUnit]() //风机旁路装置
FanSoftStartUnitType = ecs.NewComponentType[FanSoftStartUnit]() //风机软启装置
FanHighLowSpeedModeType = ecs.NewComponentType[FanHighLowSpeedMode]() //风机双速模式控制
CommonFanTag = ecs.NewTag() //一般风机

51
component/motor.go Normal file
View File

@ -0,0 +1,51 @@
package component
import "joylink.club/ecs"
// Motor 电机、马达
type Motor struct {
Speed float32 //电机转速r/min
Forward bool //true-正转false-反转
Ms MotorSwitch //电机开关
}
func (m *Motor) RunningForward() bool {
return m.Forward && m.Speed > 0
}
func (m *Motor) RunningReverse() bool {
return !m.Forward && m.Speed > 0
}
// MotorFc 电机变频器
// 电机转速与变频器频率关系 计算公式n=60f/p其中n是同步转速f是频率P是磁极对数
// 变频器的额定输出频率一般为0-100HZ
type MotorFc struct {
F uint16 //变频器频率(0-100HZ)
}
// MotorSwitch 电机电源开关定义
type MotorSwitch uint8
const (
MsOff MotorSwitch = iota //关闭
MsOnForward //正转
MsOnReverse //反转
)
func (f *MotorSwitch) Off() bool {
return *f == MsOff
}
func (f *MotorSwitch) OnForward() bool {
return *f == MsOnForward
}
func (f *MotorSwitch) OnReverse() bool {
return *f == MsOnReverse
}
func (f *MotorSwitch) On() bool {
return *f == MsOnReverse || *f == MsOnForward
}
var (
MotorType = ecs.NewComponentType[Motor]() //电机马达
MotorFcType = ecs.NewComponentType[MotorFc]() //电机变频器
)

View File

@ -59,7 +59,7 @@ func NewValveEntity(w ecs.World, id string, valveType proto.Valve_Type) *ecs.Ent
if !ok {
e = w.Entry(w.Create(component.UidType, component.ValveType, component.DeviceExceptionType))
component.UidType.SetValue(e, component.Uid{Id: id})
component.ValveType.Set(e, &component.Valve{OpenRate: 100, Closed: false, Opened: true, Moving: false})
component.ValveType.Set(e, &component.Valve{OpenRate: 100, Moving: false})
//
switch valveType {
case proto.Valve_ElectricControlValve:
@ -145,9 +145,9 @@ func NewFanEntity(w ecs.World, id string, fanType proto.Fan_Type) *ecs.Entry {
wd := GetWorldData(w)
e, ok := wd.EntityMap[id]
if !ok {
e = w.Entry(w.Create(component.UidType, component.FanDeviceType, component.DeviceExceptionType))
e = w.Entry(w.Create(component.UidType, component.MotorType, component.DeviceExceptionType))
component.UidType.SetValue(e, component.Uid{Id: id})
component.FanDeviceType.Set(e, &component.FanDevice{Speed: 0, Forward: true, Fs: component.Off})
component.MotorType.Set(e, &component.Motor{Speed: 0, Forward: true, Ms: component.MsOff})
//
switch fanType {
case proto.Fan_CommonFan:
@ -156,13 +156,12 @@ func NewFanEntity(w ecs.World, id string, fanType proto.Fan_Type) *ecs.Entry {
}
case proto.Fan_FcBypassFan:
{
e.AddComponent(component.FanFcUnitType)
e.AddComponent(component.MotorFcType)
e.AddComponent(component.FanBypassUnitType)
e.AddComponent(component.FcBypassFanTag)
}
case proto.Fan_SoftStartFan:
{
e.AddComponent(component.FanSoftStartUnitType)
e.AddComponent(component.SoftStartFanTag)
}
case proto.Fan_HighLowSpeedFan:

View File

@ -210,15 +210,17 @@ type Fan struct {
Identity
Code string
FanType proto.Fan_Type
PortA DevicePort //A端口连接的设备
PortB DevicePort //B端口连接的设备
*fanRunningModel
PortA DevicePort //A端口连接的设备
PortB DevicePort //B端口连接的设备
}
func NewFan(id string, code string, fanType proto.Fan_Type) *Fan {
return &Fan{
Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_Fan},
Code: code,
FanType: fanType,
Identity: &identity{id: id, deviceType: proto.DeviceType_DeviceType_Fan},
Code: code,
FanType: fanType,
fanRunningModel: newFanRunningModel(fanType),
}
}
func (p *Fan) PortNum() int {
@ -240,6 +242,32 @@ func (p *FanPort) Device() PortedDevice {
return p.device
}
type fanRunningModel struct {
maxSpeed float32
acTime uint16
}
func (m *fanRunningModel) MotorMaxSpeed() float32 {
return m.maxSpeed
}
func (m *fanRunningModel) MotorAcTime() uint16 {
return m.acTime
}
func newFanRunningModel(fanType proto.Fan_Type) *fanRunningModel {
switch fanType {
case proto.Fan_CommonFan:
return &fanRunningModel{maxSpeed: 3000, acTime: 2000}
case proto.Fan_HighLowSpeedFan:
return &fanRunningModel{maxSpeed: 6000, acTime: 4000}
case proto.Fan_FcBypassFan:
return &fanRunningModel{maxSpeed: 6000, acTime: 3000}
case proto.Fan_SoftStartFan:
return &fanRunningModel{maxSpeed: 100, acTime: 4000}
default:
return &fanRunningModel{maxSpeed: 3000, acTime: 2000}
}
}
////////////////////////////////////////////////
// GasEnvironment 气体环境(正常空气+有害烟雾)

View File

@ -63,6 +63,8 @@ func BindIscsSystem(w ecs.World) {
//
iscs_sys.NewNetworkSwitchSystem(),
iscs_sys.NewWireCabinetSystem(),
iscs_sys.NewFanSystem())
device_sys.NewMotorSystem(),
iscs_sys.NewFanSystem(),
iscs_sys.NewValveSystem())
}

91
sys/device_sys/motor.go Normal file
View File

@ -0,0 +1,91 @@
package device_sys
import (
"joylink.club/ecs"
"joylink.club/ecs/filter"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/entity"
)
// MotorSystem 电机马达
type MotorSystem struct {
query *ecs.Query
}
func NewMotorSystem() *MotorSystem {
return &MotorSystem{
query: ecs.NewQuery(filter.Contains(component.UidType, component.MotorType)),
}
}
func (s *MotorSystem) Update(w ecs.World) {
wd := entity.GetWorldData(w)
s.query.Each(w, func(entry *ecs.Entry) {
motorId := component.UidType.Get(entry).Id
motor := component.MotorType.Get(entry)
if motor.Ms.OnForward() { //正转电源
if !motor.Forward && motor.Speed == 0 {
motor.Forward = true
}
} else if motor.Ms.OnReverse() { //反转电源
if motor.Forward && motor.Speed == 0 {
motor.Forward = false
}
}
//
model, ok := wd.Repo.FindById(motorId).(motorModel)
if !ok {
model = motorImpl //默认工频
}
//
speed := motor.Speed + s.calculateAc(motor, model)*float32(w.Tick())
if speed <= 0 {
speed = 0
}
//变频器
if entry.HasComponent(component.MotorFcType) {
fc := component.MotorFcType.Get(entry)
SPEED := 60 * float32(fc.F) //当前频率目标转速
if speed > SPEED {
speed = SPEED
}
} else {
if speed > model.MotorMaxSpeed() {
speed = model.MotorMaxSpeed()
}
}
//
motor.Speed = speed
})
}
func (s *MotorSystem) calculateAc(motor *component.Motor, model motorModel) float32 {
//大于0加速小于0减速
ac := model.MotorMaxSpeed() / float32(model.MotorAcTime())
if motor.Ms.On() { //电源---正转或反转启动
if motor.Ms.OnForward() && motor.RunningReverse() || motor.Ms.OnReverse() && motor.RunningForward() {
ac = -ac
}
} else { //电源关闭
ac = -ac * 2 // r/ms
}
return ac
}
var motorImpl = &motorModelImpl{maxSpeed: 3000, acTime: 2000} //默认工频
type motorModel interface {
//MotorMaxSpeed 电机最大转速,r/min
MotorMaxSpeed() float32
//MotorAcTime 电机由静止加速到最大转速的时间ms
MotorAcTime() uint16
}
type motorModelImpl struct {
maxSpeed float32
acTime uint16
}
func (m *motorModelImpl) MotorMaxSpeed() float32 {
return m.maxSpeed
}
func (m *motorModelImpl) MotorAcTime() uint16 {
return m.acTime
}

View File

@ -1,6 +1,7 @@
package iscs_sys
import (
"fmt"
"joylink.club/ecs"
"joylink.club/ecs/filter"
"joylink.club/rtsssimulation/component"
@ -14,84 +15,42 @@ type FanSystem struct {
// NewFanSystem 风机系统
func NewFanSystem() *FanSystem {
return &FanSystem{
query: ecs.NewQuery(filter.Contains(component.UidType, component.FanDeviceType, component.DeviceExceptionType)),
query: ecs.NewQuery(filter.Contains(component.UidType, component.MotorType, component.DeviceExceptionType)),
}
}
func (s *FanSystem) Update(w ecs.World) {
s.query.Each(w, func(entry *ecs.Entry) {
//fanId := component.UidType.Get(entry).Id
fan := component.FanDeviceType.Get(entry)
fan.Forward = fan.Fs.OnForward()
//fmt.Printf("==>>风机[%s] forward=%t speed=%f fan-switch=%d\n", fanId, fan.Forward, fan.Speed, fan.Fs)
//
speed := fan.Speed + s.calculateAc(fan, entry)*float32(w.Tick())
//
if speed <= 0 {
fan.Speed = 0
} else {
switch {
case entry.HasComponent(component.CommonFanTag): //一般风机(3000 r/min)
{
if speed > 3000 {
speed = 3000
}
fanId := component.UidType.Get(entry).Id
fan := component.MotorType.Get(entry)
fmt.Printf("====>>>fanId = %s , forward = %t , speed = %f , ms = %d\n", fanId, fan.Forward, fan.Speed, fan.Ms)
fan.Ms = component.MsOnForward
if entry.HasComponent(component.MotorFcType) {
component.MotorFcType.Get(entry).F = 80
}
//一般风机(3000 r/min)
if entry.HasComponent(component.CommonFanTag) {
if fan.Speed > 3000 {
fan.Speed = 3000
}
}
//软启风机(100 r/min)
if entry.HasComponent(component.SoftStartFanTag) {
if fan.Speed > 100 {
fan.Speed = 100
}
}
//双速风机(Low 2000 r/min ; High 7000 r/min)
if entry.HasComponent(component.HighLowSpeedFanTag) {
highMode := component.FanHighLowSpeedModeType.Get(entry).HighMode
if highMode { //高速模式
if fan.Speed > 6000 {
fan.Speed = 6000
}
case entry.HasComponent(component.SoftStartFanTag): //软启风机(100 r/min)
{
if speed > 100 {
speed = 100
}
}
case entry.HasComponent(component.HighLowSpeedFanTag): //双速风机(Low 2000 r/min ; High 7000 r/min)
{
highMode := component.FanHighLowSpeedModeType.Get(entry).HighMode
if highMode { //高速模式
if speed > 7000 {
speed = 7000
}
} else { //低速模式
if speed > 2000 {
speed = 2000
}
}
}
case entry.HasComponent(component.FcBypassFanTag):
//变频旁路风机
//电机转速与变频器频率关系 计算公式n=60f/p其中n是同步转速f是频率P是磁极对数
//变频器的额定输出频率一般为0-100HZ
//假设风机磁极对数为1则n=60f
{
fcUnit := component.FanFcUnitType.Get(entry)
SPEED := 60 * float32(fcUnit.F) //当前频率目标转速
if speed > SPEED {
speed = SPEED
}
} else { //低速模式
if fan.Speed > 2000 {
fan.Speed = 2000
}
}
//
fan.Speed = speed
}
})
}
// 计算风机加速度
func (s *FanSystem) calculateAc(fan *component.FanDevice, fanEntry *ecs.Entry) float32 {
//大于0加速小于0减速
ac := float32(0)
//
softStart := false
if fanEntry.HasComponent(component.FanSoftStartUnitType) {
softStart = component.FanSoftStartUnitType.Get(fanEntry).SoftStart
}
//
if fan.Fs.On() { //电源---正转或反转启动
if softStart {
ac = 0.02 // r/ms
} else {
ac = 1.5 // r/ms
}
} else { //电源关闭
ac = -3 // r/ms
}
return ac
}

View File

@ -1 +1,26 @@
package iscs_sys
import (
"joylink.club/ecs"
"joylink.club/ecs/filter"
"joylink.club/rtsssimulation/component"
)
// ValveSystem 阀门
type ValveSystem struct {
query *ecs.Query
}
func NewValveSystem() *ValveSystem {
return &ValveSystem{
query: ecs.NewQuery(filter.Contains(component.UidType, component.ValveType, component.DeviceExceptionType)),
}
}
func (s *ValveSystem) Update(w ecs.World) {
s.query.Each(w, func(entry *ecs.Entry) {
valve := component.ValveType.Get(entry)
valve.Closed = valve.OpenRate == 0
valve.Opened = valve.OpenRate == 100
})
}