rts-sim-module/fi/turnout.go
walker a0352ee5e8 实现联锁驱采卡系统功能
调整道岔驱动电路逻辑
2023-11-03 17:26:32 +08:00

217 lines
6.2 KiB
Go

package fi
import (
"fmt"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/component/component_proto"
"joylink.club/rtsssimulation/entity"
)
// 道岔功能接口
// 设置道岔故障
func SetTurnoutFault(w ecs.World, id string, fault component_proto.Turnout_Fault) error {
return updateTurnoutFault(w, id, fault, true)
}
// 取消道岔故障
func CancelTurnoutFault(w ecs.World, id string, fault component_proto.Turnout_Fault) error {
return updateTurnoutFault(w, id, fault, false)
}
func updateTurnoutFault(w ecs.World, id string, fault component_proto.Turnout_Fault, set bool) error {
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
wd := entity.GetWorldData(w)
entry, ok := wd.EntityMap[id]
if ok {
ct := component.GetTurnoutFaultType(fault)
switch fault {
case component_proto.Turnout_JC: // 挤岔故障
zzjs := component.TurnoutZzjType.Get(entry)
for _, e := range zzjs.ZzjList {
if set {
if !e.HasComponent(ct) {
e.AddComponent(ct)
}
} else {
e.RemoveComponent(ct)
}
}
default:
if set {
if !entry.HasComponent(ct) {
entry.AddComponent(ct)
}
} else {
entry.RemoveComponent(ct)
}
}
} else {
return ecs.NewErrResult(fmt.Errorf("未找到id=%s的道岔", id))
}
return ecs.NewOkEmptyResult()
})
return result.Err
}
// 驱动道岔转辙机
// id - 道岔uid
// dc - 定操/反操
// on - 设置/取消
func driveTurnoutZzj(w ecs.World, id string, dc bool, on bool) error {
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
defer func() {
if err := recover(); err != nil {
}
}()
wd := entity.GetWorldData(w)
entry, ok := wd.EntityMap[id]
if ok {
if entry.HasComponent(component.Zdj9TwoElectronicType) { // 有电路,驱动继电器
elec := component.Zdj9TwoElectronicType.Get(entry)
var err error
if on {
if dc {
err = wd.SetQdBits([]*component.QdBitParam{
component.NewQdBitParam(component.UidType.Get(elec.TDC_FCJ).Id, false),
component.NewQdBitParam(component.UidType.Get(elec.TDC_DCJ).Id, true),
component.NewQdBitParam(component.UidType.Get(elec.TDC_YCJ).Id, true),
})
} else {
err = wd.SetQdBits([]*component.QdBitParam{
component.NewQdBitParam(component.UidType.Get(elec.TDC_DCJ).Id, false),
component.NewQdBitParam(component.UidType.Get(elec.TDC_FCJ).Id, true),
component.NewQdBitParam(component.UidType.Get(elec.TDC_YCJ).Id, true),
})
}
} else {
err = wd.SetQdBits([]*component.QdBitParam{
component.NewQdBitParam(component.UidType.Get(elec.TDC_DCJ).Id, false),
component.NewQdBitParam(component.UidType.Get(elec.TDC_FCJ).Id, false),
component.NewQdBitParam(component.UidType.Get(elec.TDC_YCJ).Id, false),
})
}
if err != nil {
return ecs.NewErrResult(err)
}
} else { // 无电路,直接驱动转辙机
if entry.HasComponent(component.TurnoutFaultCiqdType) {
return ecs.NewOkEmptyResult()
}
tz := component.TurnoutZzjType.Get(entry)
for _, zzj := range tz.ZzjList {
state := component.ZzjStateType.Get(zzj)
state.Td = on
if dc {
state.Dw = true
} else {
state.Dw = false
}
}
}
} else {
return ecs.NewErrResult(fmt.Errorf("未找到id=%s的道岔", id))
}
return ecs.NewOkEmptyResult()
})
return result.Err
}
// 设置道岔转辙机定操
func DriveTurnoutDCOn(w ecs.World, id string) error {
return driveTurnoutZzj(w, id, true /* dc */, true /* on */)
}
// 取消道岔转辙机定操
func DriveTurnoutDCOff(w ecs.World, id string) error {
return driveTurnoutZzj(w, id, true /* dc */, false /* on */)
}
// 设置道岔转辙机反操
func DriveTurnoutFCOn(w ecs.World, id string) error {
return driveTurnoutZzj(w, id, false /* dc */, true /* on */)
}
// 取消道岔转辙机反操
func DriveTurnoutFCOff(w ecs.World, id string) error {
return driveTurnoutZzj(w, id, false /* dc */, false /* on */)
}
// 强制道岔定位
func ForceTurnoutDw(w ecs.World, id string) error {
return forceTurnout(w, id, TurnoutForceDw)
}
// 强制道岔反位
func ForceTurnoutFw(w ecs.World, id string) error {
return forceTurnout(w, id, TurnoutForceFw)
}
// 取消道岔强制
func CancelTurnoutForce(w ecs.World, id string) error {
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
wd := entity.GetWorldData(w)
entry, ok := wd.EntityMap[id]
if ok {
entry.RemoveComponent(component.TurnoutFaultCiqdType)
} else {
return ecs.NewErrResult(fmt.Errorf("未找到id=%s的道岔", id))
}
return ecs.NewOkEmptyResult()
})
return result.Err
}
type ForceTurnoutPos int
const (
// 强制定位
TurnoutForceDw ForceTurnoutPos = 0
// 强制反位
TurnoutForceFw ForceTurnoutPos = 1
// 强制失表
TurnoutForceSb ForceTurnoutPos = 2
)
func forceTurnout(w ecs.World, id string, pos ForceTurnoutPos) error {
result := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] {
wd := entity.GetWorldData(w)
entry, ok := wd.EntityMap[id]
if ok {
if !entry.HasComponent(component.TurnoutFaultCiqdType) {
entry.AddComponent(component.TurnoutFaultCiqdType)
}
if entry.HasComponent(component.Zdj9TwoElectronicType) { // 有电路,驱动继电器
elec := component.Zdj9TwoElectronicType.Get(entry)
if pos == TurnoutForceDw {
component.RelayDriveType.Get(elec.TDC_FCJ).Td = false
component.RelayDriveType.Get(elec.TDC_YCJ).Td = true
component.RelayDriveType.Get(elec.TDC_DCJ).Td = true
} else if pos == TurnoutForceFw {
component.RelayDriveType.Get(elec.TDC_DCJ).Td = false
component.RelayDriveType.Get(elec.TDC_YCJ).Td = true
component.RelayDriveType.Get(elec.TDC_FCJ).Td = true
}
} else { // 无电路,直接驱动转辙机
tz := component.TurnoutZzjType.Get(entry)
for _, zzj := range tz.ZzjList {
state := component.ZzjStateType.Get(zzj)
state.Td = true
if pos == TurnoutForceDw {
state.Dw = true
} else if pos == TurnoutForceFw {
state.Dw = false
}
}
}
} else {
return ecs.NewErrResult(fmt.Errorf("未找到id=%s的道岔", id))
}
return ecs.NewOkEmptyResult()
})
return result.Err
}