ZDJ9双机道岔系统功能实现(未完)

This commit is contained in:
walker 2023-09-26 18:06:15 +08:00
parent ac8dcdbd18
commit 823fa82fad
12 changed files with 716 additions and 47 deletions

View File

@ -1,6 +1,9 @@
package component
import "joylink.club/ecs"
import (
"joylink.club/ecs"
"joylink.club/rtsssimulation/consts"
)
// 两位置转换组件
type TwoPositionTransform struct {
@ -8,8 +11,19 @@ type TwoPositionTransform struct {
Speed int
}
// 百分比值
func (tp *TwoPositionTransform) Percentage() float32 {
return float32(tp.Pos) / consts.TwoPosMax
}
var TwoPositionTransformType = ecs.NewComponentType[TwoPositionTransform]()
// 计算两位置动作的平均速度
// 总时间t和tick的单位都应该是ms
func CalculateTwoPositionAvgSpeed(t int, tick int) int {
return consts.TwoPosMax / (t / tick)
}
// 仅有两状态的组件
type BitState struct {
Val bool
@ -17,10 +31,18 @@ type BitState struct {
var BitStateType = ecs.NewComponentType[BitState]()
// 倒数组件
type CountDown struct {
// 倒数/倒计时组件
type CounterDown struct {
Val int // 当前值
Dv int // 每次递减的值
Step int // 步长
}
var CountDownType = ecs.NewComponentType[CountDown]()
var CounterDownType = ecs.NewComponentType[CounterDown]()
// 计数/计时组件
type Counter struct {
Val int // 当前值
Step int // 步长
}
var CounterType = ecs.NewComponentType[Counter]()

14
component/dbq.go Normal file
View File

@ -0,0 +1,14 @@
package component
import "joylink.club/ecs"
// 断相保护器标签
var DBQTag = ecs.NewTag()
// 断相保护器控制请求组件
type DBQ struct {
Td bool // 是否通电true通电
Dzkg bool // 电子开关状态true: 开
}
var DBQType = ecs.NewComponentType[DBQ]()

View File

@ -2,17 +2,28 @@ package component
import "joylink.club/ecs"
// 标签
var (
// 继电器
RelayTag = ecs.NewTag()
// 无极继电器
WjRelayTag = ecs.NewTag()
// 缓放继电器
HfRelayTag = ecs.NewTag()
// 有极
YjRelayTag = ecs.NewTag()
)
// 无极继电器和偏极继电器稳态为落下,也就是后接点(8组采集接点中的1,3接点1为中接点)吸气为前接点1,2接点
// 有极继电器是定位反位双稳态(有永久磁钢),前接点为定位,后接点为反位
// 有极继电器对于道岔中的2DQJ励磁接点12接通为反位34接通为定位
// 定义继电器状态时false表示落下/反位/后接点true表示吸起/定位/前接点
// 继电器标签
var RelayTag = ecs.NewTag()
// 继电器控制请求组件
type RelayActionRequest struct {
Xq bool // true吸起
// 缓动继电器指从通电或断电起至接点转接止所需时间在0.3s以上的继电器。可分为缓放继电器(如无极缓放继电器等)和缓吸继电器(如热力继电器和时间继电器等)。
// 偏极继电器:只有通过规定方向的电流时,才吸起
// 继电器驱动组件
type RelayDrive struct {
Td bool // 是否通电
Xq bool // 是否驱动到吸起位置true驱动吸起,false:驱动落下(此状态只对有极继电器有效)
}
var RelayActionRequestType = ecs.NewComponentType[RelayActionRequest]()
var RelayDriveType = ecs.NewComponentType[RelayDrive]()

View File

@ -17,6 +17,7 @@ type Zdj9_1_Electronic struct {
TDFJ_BHJ *ecs.Entry // 保护继电器
TDFJ_2DQJ *ecs.Entry // 二启动继电器
TDFJ_1DQJF *ecs.Entry // 一启动复示继电器
TDFJ_DBQ *ecs.Entry // 断相保护器
TDFJ_DBJ *ecs.Entry // 定位表示继电器
TDFJ_FBJ *ecs.Entry // 反位表示继电器
TDFJ_R1 *ecs.Entry // 电阻
@ -24,3 +25,52 @@ type Zdj9_1_Electronic struct {
// ZDJ9单机电路元器件组件类型
var Zdj9_1_ElectronicType = ecs.NewComponentType[Zdj9_1_Electronic]()
type Zdj9_2_Electronic struct {
TDC_DCJ *ecs.Entry // 定操继电器
TDC_FCJ *ecs.Entry // 反操继电器
TDC_YCJ *ecs.Entry // 允许操作继电器
TDC_ZDBJ *ecs.Entry // 总定表继电器
TDC_ZFBJ *ecs.Entry // 总反表继电器
// 一机
TDFJ1_1DQJ *ecs.Entry // 一启动继电器
TDFJ1_BHJ *ecs.Entry // 保护继电器
TDFJ1_2DQJ *ecs.Entry // 二启动继电器
TDFJ1_1DQJF *ecs.Entry // 一启动复示继电器
TDFJ1_DBQ *ecs.Entry // 断相保护器
TDFJ1_DBJ *ecs.Entry // 定位表示继电器
TDFJ1_FBJ *ecs.Entry // 反位表示继电器
TDFJ1_QDJ *ecs.Entry // 切断继电器
TDFJ1_ZBHJ *ecs.Entry // 总保护继电器
// 二机
TDFJ2_1DQJ *ecs.Entry // 一启动继电器
TDFJ2_BHJ *ecs.Entry // 保护继电器
TDFJ2_2DQJ *ecs.Entry // 二启动继电器
TDFJ2_1DQJF *ecs.Entry // 一启动复示继电器
TDFJ2_DBQ *ecs.Entry // 断相保护器
TDFJ2_DBJ *ecs.Entry // 定位表示继电器
TDFJ2_FBJ *ecs.Entry // 反位表示继电器
Zzj1 *ecs.Entry //转辙机一
Zzj2 *ecs.Entry //转辙机二
}
// ZDJ9双机电路元器件组件类型
var Zdj9_2_ElectronicType = ecs.NewComponentType[Zdj9_2_Electronic]()
type Zzj struct {
// 自动开闭器接点位置默认定位接通1/3排反位接通2/4排
// 由定位转反位1DQJ和1DQJF励磁吸起2DQJ在反位——即落下三相电路导通电机开始反转转辙机将第3排接点接通第4排到位锁闭后转辙机的自动开闭器拉簧将第1排接点拉到第2排接点到2排后三相电路断路
// 由反位转定位1DQJ和1DQJF励磁吸起2DQJ在定位——即吸起三相电路导通电机开始正转转辙机将第2排接点接通第1排到位锁闭后转辙机的自动开闭器拉簧将第4排接点拉到第3排接点到3排后三相电路断路
JD12 bool // 接点在1/2排的位置false-接点在1排true-接点在2排
JD34 bool // 接点在3/4排的位置false-接点在3排true-接点在4排
Td bool // 是否通电
Dw bool // 是否转动到定位
}
// 转辙机状态
var ZzjType = ecs.NewComponentType[Zzj]()

View File

@ -1,6 +1,11 @@
package consts
const (
PosMin = 0
PosMax = 10000
TwoPosMin = 0
TwoPosMax = 10000
// 断相保护器超时时间,单位ms
DBQTimeout = 13 * 1000
// 继电器缓放时间单位ms
RelayHf = 0.5 * 1000
)

View File

@ -1,16 +1,16 @@
// /ZDJ9单机转辙机电路系统
// ZDJ9单机转辙机电路系统
package circuit_sys
import (
"fmt"
"unsafe"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/system/device_sys"
)
// 系统定义
// ZDJ9单机转辙机电路系统
type ZDJ9_1 struct {
query *ecs.Query
}
@ -25,29 +25,90 @@ func (zdj9 *ZDJ9_1) Update(w ecs.World) {
fmt.Println("ZDJ9单机牵引控制电路更新")
zdj9.query.Each(w, func(entry *ecs.Entry) {
elec := component.Zdj9_1_ElectronicType.Get(entry)
// TDFJ_1DQJ励磁电路
exciteTDFJ_1DQJ(elec)
// TDFJ_1DQJ监控电路
// TDFJ_1DQJ及1DQJF励磁状态变更
zdj9.exciteTDFJ_1DQJ(elec)
// TDFJ_2DQJ励磁状态变更
zdj9.exciteTDFJ_2DQJ(elec)
// 限时断相保护器限时13秒
zdj9.exciteTDFJ_DBQ(elec)
// TDFJ_BHJ励磁状态控制
zdj9.exciteTDFJ_BHJ(elec)
})
}
// 断相保护器控制
func (zdj9 *ZDJ9_1) exciteTDFJ_DBQ(elec *component.Zdj9_1_Electronic) {
tdfj_1dqj := component.BitStateType.Get(elec.TDFJ_1DQJ)
tdfj_1dqjf := component.BitStateType.Get(elec.TDFJ_1DQJF)
dbq := component.DBQType.Get(elec.TDFJ_DBQ)
if tdfj_1dqj.Val && tdfj_1dqjf.Val && !dbq.Td { // 默认电源没有问题,电路导通
dbq.Td = true
} else if (!tdfj_1dqj.Val || !tdfj_1dqjf.Val) && dbq.Td {
dbq.Td = false
}
}
// TDFJ_BHJ保护继电器励磁状态控制
func (zdj9 *ZDJ9_1) exciteTDFJ_BHJ(elec *component.Zdj9_1_Electronic) {
dbq := component.DBQType.Get(elec.TDFJ_DBQ)
bhj := component.BitStateType.Get(elec.TDFJ_BHJ)
if dbq.Dzkg && !bhj.Val { // BHJ吸起
device_sys.HandleRelayLc(elec.TDFJ_BHJ, true)
} else if !dbq.Dzkg && bhj.Val { // BHJ落下
device_sys.HandleRelayLc(elec.TDFJ_BHJ, false)
}
}
// TDFJ_1DQJ励磁电路逻辑
func exciteTDFJ_1DQJ(elec *component.Zdj9_1_Electronic) {
func (zdj9 *ZDJ9_1) exciteTDFJ_1DQJ(elec *component.Zdj9_1_Electronic) {
// 暂时先实现非应急按钮操作
tdfj_1dqj := component.BitStateType.Get(elec.TDFJ_1DQJ)
if tdfj_1dqj.Val { // 已经吸起,结束
return
}
if elec.TDFJ_1DQJ.HasComponent(component.RelayActionRequestType) { // 如果正在吸起,结束
return
}
ycj := component.BitStateType.Get(elec.TDC_YCJ)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
tdfj_2dqj := component.BitStateType.Get(elec.TDFJ_2DQJ)
bhj := component.BitStateType.Get(elec.TDFJ_BHJ)
tdfj_1dqjf := component.BitStateType.Get(elec.TDFJ_1DQJF)
if tdfj_1dqj.Val { // 已经吸起
// 判定是否所有励磁电路断开(todo 暂不考虑应急按钮)
if !bhj.Val && !(ycj.Val && (fcj.Val || dcj.Val)) { // 电路断开1DQJ落下请求
device_sys.HandleRelayLc(elec.TDFJ_1DQJ, false)
}
// 1DQJF复示继电器
if !tdfj_1dqjf.Val { // 如果落下状态,1DQJF吸起请求
device_sys.HandleRelayLc(elec.TDFJ_1DQJF, true)
}
} else { // 在落下位置
if ycj.Val { // 允许操作继电器已经吸起
if (tdfj_2dqj.Val && fcj.Val) || (tdfj_2dqj.Val && dcj.Val) { // 电路导通,添加吸起请求
elec.TDFJ_1DQJ.AddComponent(component.RelayActionRequestType, unsafe.Pointer(&component.RelayActionRequest{Xq: true}))
if fcj.Val || dcj.Val { // 电路导通1DQJ吸起请求
device_sys.HandleRelayLc(elec.TDFJ_1DQJ, true)
}
}
// 1DQJF复示继电器
if tdfj_1dqjf.Val { // 如果吸起状态,1DQJF落下请求
device_sys.HandleRelayLc(elec.TDFJ_1DQJF, false)
}
}
}
// TDFJ_2DQJ励磁电路逻辑(暂时未考虑应急盘操作按钮电路)
func (zdj9 *ZDJ9_1) exciteTDFJ_2DQJ(elec *component.Zdj9_1_Electronic) {
tdfj_1dqjf := component.BitStateType.Get(elec.TDFJ_1DQJF)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
tdfj_2dqj := component.BitStateType.Get(elec.TDFJ_2DQJ)
if !(tdfj_1dqjf.Val && (dcj.Val || fcj.Val)) {
// 励磁电路断开
device_sys.HandleRelayLc(elec.TDFJ_2DQJ, false)
} else {
// 励磁电路导通
device_sys.HandleRelayLc(elec.TDFJ_2DQJ, true)
if tdfj_2dqj.Val && tdfj_1dqjf.Val && fcj.Val {
// 2DQJ定位但反操需打落
device_sys.HandleYjRelayXq(elec.TDFJ_2DQJ, false)
} else if !tdfj_2dqj.Val && tdfj_1dqjf.Val && dcj.Val {
// 2DQJ反位但定操需吸起
device_sys.HandleYjRelayXq(elec.TDFJ_2DQJ, true)
}
}
}

View File

@ -0,0 +1,339 @@
package circuit_sys
import (
"fmt"
"unsafe"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
)
// ZDJ9双机牵引道岔电路系统
type ZDJ9_2 struct {
query *ecs.Query
}
func NewZdj9_2() *ZDJ9_2 {
return &ZDJ9_2{
query: ecs.NewQuery(filter.Contains(component.Zdj9_2_ElectronicType, component.TwoPositionTransformType)),
}
}
func (zdj9 *ZDJ9_2) Update(w ecs.World) {
fmt.Println("ZDJ9双机牵引道岔电路系统")
zdj9.query.Each(w, func(entry *ecs.Entry) {
elec := component.Zdj9_2_ElectronicType.Get(entry)
// 转辙机一机电路相关动作
// 1DQJ励磁状态控制
zdj9.exciteM1_TDFJ_1DQJ(elec)
// 1DQJF励磁状态控制
zdj9.exciteM1_TDFJ_1DQJF(elec)
// TDFJ1_2DQJ励磁状态控制
zdj9.exciteM1_TDFJ_2DQJ(elec)
// 限时断相保护器
zdj9.exciteM1_TDFJ_DBQ(w, entry, elec)
// TDFJ1_BHJ励磁状态控制
zdj9.exciteM1_TDFJ_BHJ(elec)
// 总保护继电器
zdj9.exciteM1_TDFJ_ZBHJ(elec)
// 切断继电器
zdj9.exciteM1_TDFJ_QDJ(w, entry, elec)
// 定表/反表继电器
zdj9.exciteM1_TDFJ1_DFBJ(entry, elec)
// 转辙机二机电路相关动作
// 1DQJ励磁状态控制
zdj9.exciteM2_TDFJ_1DQJ(elec)
// 1DQJF励磁状态控制
zdj9.exciteM2_TDFJ_1DQJF(elec)
// TDFJ1_2DQJ励磁状态控制
zdj9.exciteM2_TDFJ_2DQJ(elec)
// 限时断相保护器
zdj9.exciteM2_TDFJ_DBQ(w, entry, elec)
// TDFJ1_BHJ励磁状态控制
zdj9.exciteM2_TDFJ_BHJ(elec)
// 定表/反表继电器
zdj9.exciteM2_TDFJ1_DFBJ(entry, elec)
// 总定表/反表继电器
})
}
// 转辙机一定表/反表继电器控制
func (zdj9 *ZDJ9_2) exciteM1_TDFJ1_DFBJ(entry *ecs.Entry, elec *component.Zdj9_2_Electronic) {
_1dqj := component.BitStateType.Get(elec.TDFJ1_1DQJ)
_2dqj := component.BitStateType.Get(elec.TDFJ1_2DQJ)
zzj := component.ZzjType.Get(elec.Zzj1)
dbj := component.BitStateType.Get(elec.TDFJ1_DBJ)
dbj_drive := component.RelayDriveType.Get(elec.TDFJ1_DBJ)
fbj := component.BitStateType.Get(elec.TDFJ1_FBJ)
fbj_drive := component.RelayDriveType.Get(elec.TDFJ1_DBJ)
// 默认BB道岔表示变压器正常
if !dbj.Val { // 定表继电器落下状态
if !_1dqj.Val && _2dqj.Val && !zzj.JD12 { // 1DQJ落下2DQJ定位开闭器接点在1排
dbj_drive.Td = true
}
} else { // 吸起状态
if !(!_1dqj.Val && _2dqj.Val && !zzj.JD12) { // 励磁电路断开
dbj_drive.Td = false
}
}
if !fbj.Val { // 反表继电器落下状态
if !_1dqj.Val && !_2dqj.Val && zzj.JD34 {
fbj_drive.Td = true
}
} else { //
}
}
// 转辙机二定表/反表继电器控制
func (zdj9 *ZDJ9_2) exciteM2_TDFJ1_DFBJ(entry *ecs.Entry, elec *component.Zdj9_2_Electronic) {
}
// 切断继电器延时缓放电路缓放时间单位ms
const QDJ_DELAY = 3 * 1000
// 切断继电器控制
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_QDJ(w ecs.World, entry *ecs.Entry, elec *component.Zdj9_2_Electronic) {
tdfj1_bhj := component.BitStateType.Get(elec.TDFJ1_BHJ)
tdfj2_bhj := component.BitStateType.Get(elec.TDFJ2_BHJ)
tdfj1_zbhj := component.BitStateType.Get(elec.TDFJ1_ZBHJ)
tdfj1_qdj := component.BitStateType.Get(elec.TDFJ1_QDJ)
drive := component.RelayDriveType.Get(elec.TDFJ1_QDJ)
if !tdfj1_qdj.Val { // 落下状态
if (!tdfj1_bhj.Val && !tdfj2_bhj.Val) || tdfj1_zbhj.Val { // 励磁电路导通
drive.Td = true
if entry.HasComponent(component.CounterDownType) {
entry.RemoveComponent(component.CounterDownType)
}
}
} else { // 吸起状态
if drive.Td && !tdfj1_zbhj.Val && !(tdfj1_bhj.Val && tdfj2_bhj.Val) { // 电路断开
// 延时电路
if entry.HasComponent(component.CounterDownType) {
cd := component.CounterDownType.Get(entry)
if cd.Val <= 0 {
drive.Td = false
entry.RemoveComponent(component.CounterDownType)
}
} else {
entry.AddComponent(component.CounterDownType, unsafe.Pointer(&component.CounterDown{
Val: QDJ_DELAY,
Step: w.Tick(),
}))
}
}
}
}
// 总保护继电器控制
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_ZBHJ(elec *component.Zdj9_2_Electronic) {
tdfj1_bhj := component.BitStateType.Get(elec.TDFJ1_BHJ)
tdfj2_bhj := component.BitStateType.Get(elec.TDFJ2_BHJ)
tdfj1_zbhj := component.RelayDriveType.Get(elec.TDFJ1_ZBHJ)
if !tdfj1_zbhj.Td { // 未通电
if tdfj1_bhj.Val && tdfj2_bhj.Val { // 励磁电路导通
tdfj1_zbhj.Td = true
}
} else { // 通电
if !tdfj1_bhj.Val && !tdfj2_bhj.Val { // 励磁电路断开
tdfj1_zbhj.Td = false
}
}
}
// 转辙机一断相保护器控制
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_DBQ(w ecs.World, entry *ecs.Entry, elec *component.Zdj9_2_Electronic) {
_1dqj := component.BitStateType.Get(elec.TDFJ1_1DQJ)
_1dqjf := component.BitStateType.Get(elec.TDFJ1_1DQJF)
_2dqj := component.BitStateType.Get(elec.TDFJ1_2DQJ)
zzj := component.ZzjType.Get(elec.Zzj1)
dbq := component.DBQType.Get(elec.TDFJ1_DBQ)
if dbq.Td { // 通电
if !(_1dqj.Val && _1dqjf.Val && !zzj.JD12 && !_2dqj.Val) &&
!(_1dqj.Val && _1dqjf.Val && zzj.JD34 && _2dqj.Val) { // 断开
dbq.Td = false
zzj.Td = false
}
} else { // 未通电
if _1dqj.Val && _1dqjf.Val && ((!zzj.JD12 && !_2dqj.Val) || (zzj.JD34 && _2dqj.Val)) { // 通电
dbq.Td = true
zzj.Td = true
zzj.Dw = _2dqj.Val
}
}
}
// 转辙机二断相保护器控制
func (zdj9 *ZDJ9_2) exciteM2_TDFJ_DBQ(w ecs.World, entry *ecs.Entry, elec *component.Zdj9_2_Electronic) {
_1dqj := component.BitStateType.Get(elec.TDFJ2_1DQJ)
_1dqjf := component.BitStateType.Get(elec.TDFJ2_1DQJF)
_2dqj := component.BitStateType.Get(elec.TDFJ2_2DQJ)
zzj := component.ZzjType.Get(elec.Zzj2)
dbq := component.DBQType.Get(elec.TDFJ2_DBQ)
if dbq.Td { // 通电
if !(_1dqj.Val && _1dqjf.Val && !zzj.JD12 && !_2dqj.Val) &&
!(_1dqj.Val && _1dqjf.Val && zzj.JD34 && _2dqj.Val) { // 断开
dbq.Td = false
zzj.Td = false
}
} else { // 未通电
if _1dqj.Val && _1dqjf.Val && ((!zzj.JD12 && !_2dqj.Val) || (zzj.JD34 && _2dqj.Val)) { // 通电
dbq.Td = true
zzj.Td = true
zzj.Dw = _2dqj.Val
}
}
}
// 转辙机一TDFJ_BHJ保护继电器励磁状态控制
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_BHJ(elec *component.Zdj9_2_Electronic) {
dbq := component.DBQType.Get(elec.TDFJ1_DBQ)
bhj := component.RelayDriveType.Get(elec.TDFJ1_BHJ)
if !bhj.Td && dbq.Dzkg { // BHJ励磁电路导通
bhj.Td = true
} else if bhj.Td && !dbq.Dzkg { // BHJ励磁电路断开
bhj.Td = false
}
}
// 转辙机二TDFJ_BHJ保护继电器励磁状态控制
func (zdj9 *ZDJ9_2) exciteM2_TDFJ_BHJ(elec *component.Zdj9_2_Electronic) {
dbq := component.DBQType.Get(elec.TDFJ2_DBQ)
bhj := component.RelayDriveType.Get(elec.TDFJ2_BHJ)
if !bhj.Td && dbq.Dzkg { // BHJ励磁电路导通
bhj.Td = true
} else if bhj.Td && !dbq.Dzkg { // BHJ励磁电路断开
bhj.Td = false
}
}
// 转辙机一TDFJ_1DQJF励磁电路逻辑
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_1DQJF(elec *component.Zdj9_2_Electronic) {
tdfj_1dqj := component.BitStateType.Get(elec.TDFJ1_1DQJ)
tdfj_1dqjf_drive := component.RelayDriveType.Get(elec.TDFJ1_1DQJF)
if tdfj_1dqjf_drive.Td { // 通电
if !tdfj_1dqj.Val {
tdfj_1dqjf_drive.Td = false
}
} else { // 未通电
if tdfj_1dqj.Val {
tdfj_1dqjf_drive.Td = true
}
}
}
// 转辙机二TDFJ_1DQJF励磁电路逻辑
func (zdj9 *ZDJ9_2) exciteM2_TDFJ_1DQJF(elec *component.Zdj9_2_Electronic) {
tdfj_1dqj := component.BitStateType.Get(elec.TDFJ2_1DQJ)
tdfj_1dqjf_drive := component.RelayDriveType.Get(elec.TDFJ2_1DQJF)
if tdfj_1dqjf_drive.Td { // 通电
if !tdfj_1dqj.Val {
tdfj_1dqjf_drive.Td = false
}
} else { // 未通电
if tdfj_1dqj.Val {
tdfj_1dqjf_drive.Td = true
}
}
}
// 转辙机一TDFJ_1DQJ励磁电路逻辑
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_1DQJ(elec *component.Zdj9_2_Electronic) {
// 暂时先实现非应急按钮操作
ycj := component.BitStateType.Get(elec.TDC_YCJ)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
bhj := component.BitStateType.Get(elec.TDFJ1_BHJ)
qdj := component.BitStateType.Get(elec.TDFJ1_QDJ)
drive := component.RelayDriveType.Get(elec.TDFJ1_1DQJ)
if drive.Td { // 通电
// 判定是否所有励磁电路断开(todo 暂不考虑应急按钮)
if !(qdj.Val && bhj.Val) && !(ycj.Val && (fcj.Val || dcj.Val)) { // 电路断开
drive.Td = false
}
} else { // 未通电
if ycj.Val && (fcj.Val || dcj.Val) { // 电路导通
drive.Td = true
}
}
}
// 转辙机二TDFJ_1DQJ励磁电路逻辑
func (zdj9 *ZDJ9_2) exciteM2_TDFJ_1DQJ(elec *component.Zdj9_2_Electronic) {
// 暂时先实现非应急按钮操作
ycj := component.BitStateType.Get(elec.TDC_YCJ)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
tdfj1_1dqj := component.BitStateType.Get(elec.TDFJ1_1DQJ)
bhj := component.BitStateType.Get(elec.TDFJ2_BHJ)
qdj := component.BitStateType.Get(elec.TDFJ1_QDJ)
drive := component.RelayDriveType.Get(elec.TDFJ2_1DQJ)
if drive.Td { // 通电
if !(qdj.Val && bhj.Val) && !(tdfj1_1dqj.Val && ycj.Val && (fcj.Val || dcj.Val)) { // 电路断开
drive.Td = false
}
} else { // 未通电
if tdfj1_1dqj.Val && ycj.Val && (fcj.Val || dcj.Val) { // 电路导通
drive.Td = true
}
}
}
// 转辙机一TDFJ_2DQJ励磁电路逻辑(暂时未考虑应急盘操作按钮电路)
func (zdj9 *ZDJ9_2) exciteM1_TDFJ_2DQJ(elec *component.Zdj9_2_Electronic) {
tdfj1_1dqjf := component.BitStateType.Get(elec.TDFJ1_1DQJF)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
drive := component.RelayDriveType.Get(elec.TDFJ1_2DQJ)
if drive.Td { // 通电
if !drive.Xq && tdfj1_1dqjf.Val && dcj.Val {
drive.Xq = true
} else if drive.Xq && tdfj1_1dqjf.Val && fcj.Val {
drive.Xq = false
} else if !(tdfj1_1dqjf.Val && (dcj.Val || fcj.Val)) { // 断电
drive.Td = false
}
} else { // 未通电
if tdfj1_1dqjf.Val {
if dcj.Val { // 通电,到吸起位
drive.Td = true
drive.Xq = true
} else if fcj.Val { // 通电,到落下位
drive.Td = true
drive.Xq = false
}
}
}
}
// 转辙机二TDFJ_2DQJ励磁电路逻辑(暂时未考虑应急盘操作按钮电路)
func (zdj9 *ZDJ9_2) exciteM2_TDFJ_2DQJ(elec *component.Zdj9_2_Electronic) {
tdfj2_1dqjf := component.BitStateType.Get(elec.TDFJ2_1DQJF)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
drive := component.RelayDriveType.Get(elec.TDFJ2_2DQJ)
if drive.Td { // 通电
if !drive.Xq && tdfj2_1dqjf.Val && dcj.Val {
drive.Xq = true
} else if drive.Xq && tdfj2_1dqjf.Val && fcj.Val {
drive.Xq = false
} else if !(tdfj2_1dqjf.Val && (dcj.Val || fcj.Val)) { // 断电
drive.Td = false
}
} else { // 未通电
if tdfj2_1dqjf.Val {
if dcj.Val { // 通电,到吸起位
drive.Td = true
drive.Xq = true
} else if fcj.Val { // 通电,到落下位
drive.Td = true
drive.Xq = false
}
}
}
}

View File

@ -0,0 +1,17 @@
package common_sys
import (
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
)
type CounterDown struct {
query *ecs.Query
}
func NewCounterDown() *CounterDown {
return &CounterDown{
query: ecs.NewQuery(filter.Contains(component.CounterDownType)),
}
}

45
system/device_sys/dbq.go Normal file
View File

@ -0,0 +1,45 @@
package device_sys
import (
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/consts"
)
// 断相保护器
type DBQ struct {
query *ecs.Query
}
func NewDBQ() *DBQ {
return &DBQ{
query: ecs.NewQuery(filter.Contains(component.DBQTag, component.DBQType)),
}
}
func (q *DBQ) Update(w ecs.World) {
q.query.Each(w, func(entry *ecs.Entry) {
// 电路是否通电
dbq := component.DBQType.Get(entry)
if dbq.Td && !dbq.Dzkg { // 通电但开关未开,启动
dbq.Dzkg = true
if entry.HasComponent(component.CounterType) {
// 定时器启动
counter := component.CounterType.Get(entry)
counter.Val = 0
counter.Step = w.Tick()
}
} else if dbq.Td && dbq.Dzkg { // 已经启动,判定延时切断
if entry.HasComponent(component.CounterType) {
// 判断定时器是否超时,如果超时,断开电子开关
counter := component.CounterType.Get(entry)
if counter.Val >= consts.DBQTimeout {
dbq.Dzkg = false
}
}
} else if !dbq.Td && dbq.Dzkg { // 无电,断开电子开关
dbq.Dzkg = false
}
})
}

View File

@ -1,9 +1,12 @@
package device_sys
import (
"unsafe"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/consts"
)
type RelaySys struct {
@ -12,22 +15,54 @@ type RelaySys struct {
func NewRelaySys() *RelaySys {
return &RelaySys{
query: ecs.NewQuery(filter.Contains(component.RelayTag, component.RelayActionRequestType, component.BitStateType)),
query: ecs.NewQuery(filter.Contains(component.RelayTag, component.RelayDriveType, component.BitStateType)),
}
}
func (rs *RelaySys) Update(w ecs.World) {
rs.query.Each(w, func(entry *ecs.Entry) {
// 查询实体是哪种继电器类型,根据继电器类型处理继电器吸起落下逻辑(暂时先简化直接处理)
req := component.RelayActionRequestType.Get(entry)
rd := component.RelayDriveType.Get(entry)
state := component.BitStateType.Get(entry)
if req.Xq {
if entry.HasComponent(component.WjRelayTag) { // 无极继电器
if rd.Td && !state.Val { // 通电吸起
state.Val = true
} else if state.Val && !rd.Td { // 断电落下
if entry.HasComponent(component.HfRelayTag) { // 缓放继电器
if entry.HasComponent(component.CounterDownType) { //
cd := component.CounterDownType.Get(entry)
if cd.Val <= 0 { //
state.Val = false
entry.RemoveComponent(component.CounterDownType) // 移除倒计时组件
}
} else {
entry.AddComponent(component.CounterDownType, unsafe.Pointer(&component.CounterDown{
Val: consts.RelayHf,
Step: w.Tick(),
}))
}
} else { // 落下
state.Val = false
}
}
} else if entry.HasComponent(component.YjRelayTag) { // 有极继电器
if rd.Td && rd.Xq && !state.Val { // 吸起
state.Val = true
} else if rd.Td && !rd.Xq && state.Val { // 落下
state.Val = false
}
if req.Xq == state.Val { // 执行完毕,删除请求组件
entry.RemoveComponent(component.RelayActionRequestType)
}
})
}
// 处理无极继电器励磁电路导通(励磁电路变化)
func HandleRelayLc(entry *ecs.Entry, lc bool) {
rd := component.RelayDriveType.Get(entry)
rd.Td = lc
}
// 处理有极继电器励磁电路导致的吸起/打落变化(励磁电路变化)
func HandleYjRelayXq(entry *ecs.Entry, xq bool) {
rd := component.RelayDriveType.Get(entry)
rd.Xq = xq
}

66
system/device_sys/zzj.go Normal file
View File

@ -0,0 +1,66 @@
package device_sys
import (
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/consts"
)
type Zzj struct {
query *ecs.Query
}
func NewZzj() *Zzj {
return &Zzj{
query: ecs.NewQuery(filter.Contains(component.ZzjType, component.TwoPositionTransformType)),
}
}
const (
// 转辙机从一个位置到另一个位置转动时间单位ms
TurnTime = 3 * 1000
// 自动开闭器解锁点位置百分比
KbqJsPercent = 0.05
)
func (z *Zzj) Update(w ecs.World) {
z.query.Each(w, func(entry *ecs.Entry) {
zzj := component.ZzjType.Get(entry)
tp := component.TwoPositionTransformType.Get(entry)
if zzj.Td { // 通电
if tp.Speed == 0 && tp.Pos > consts.TwoPosMin && zzj.Dw { // 转到定位
tp.Speed = -component.CalculateTwoPositionAvgSpeed(TurnTime, w.Tick())
} else if tp.Speed == 0 && tp.Pos < consts.TwoPosMax && !zzj.Dw { // 转到反位
tp.Speed = component.CalculateTwoPositionAvgSpeed(TurnTime, w.Tick())
}
} else { // 未通电
if tp.Speed != 0 { // 停止
tp.Speed = 0
}
}
if tp.Pos == consts.TwoPosMax { // 到反位
if !zzj.JD12 {
zzj.JD12 = true
}
if !zzj.JD34 {
zzj.JD34 = true
}
} else if tp.Pos == consts.TwoPosMin { // 到定位
if zzj.JD12 {
zzj.JD12 = false
}
if zzj.JD34 {
zzj.JD34 = false
}
} else if tp.Percentage() > KbqJsPercent && tp.Percentage() < (1-KbqJsPercent) { //中间位置
if zzj.JD12 {
zzj.JD12 = false
}
if !zzj.JD34 {
zzj.JD34 = true
}
}
})
}

View File

@ -22,11 +22,15 @@ func (tp *TwoPositionMovementSys) Update(w ecs.World) {
tp.query.Each(w, func(entry *ecs.Entry) {
position := component.TwoPositionTransformType.Get(entry)
if position.Speed != 0 {
position.Pos += position.Speed
if position.Pos < consts.PosMin {
position.Pos = consts.PosMin
} else if position.Pos > consts.PosMax {
position.Pos = consts.PosMax
pos := position.Pos + position.Speed
if pos < consts.TwoPosMin {
position.Pos = consts.TwoPosMin
position.Speed = 0
} else if pos > consts.TwoPosMax {
position.Pos = consts.TwoPosMax
position.Speed = 0
} else {
position.Pos = pos
}
}
})