Merge branch 'master' of https://git.code.tencent.com/jl-framework/rtss_simulation
This commit is contained in:
commit
07248c0fec
@ -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
51
component/motor.go
Normal 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]() //电机变频器
|
||||
)
|
@ -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:
|
||||
|
@ -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 气体环境(正常空气+有害烟雾)
|
||||
|
@ -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
91
sys/device_sys/motor.go
Normal 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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user