Compare commits
2 Commits
a6119b890f
...
149678b3f0
Author | SHA1 | Date | |
---|---|---|---|
149678b3f0 | |||
509d06e39e |
@ -293,6 +293,14 @@ func handlerSectionState(w ecs.World, uid string) *state_proto.SectionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sectionState
|
return sectionState
|
||||||
|
} else if entry.HasComponent(component.TrackCircuitType) { //轨道电路
|
||||||
|
sectionState := &state_proto.SectionState{
|
||||||
|
Occupied: component.BitStateType.Get(component.TrackCircuitType.Get(entry).GJ).Val,
|
||||||
|
AxleFault: false,
|
||||||
|
AxleDrst: false,
|
||||||
|
AxlePdrst: false,
|
||||||
|
}
|
||||||
|
return sectionState
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8ccd46aa6c97a933fd12c7b308da929115c9aa8e
|
Subproject commit 90003ec9429c7db26c43dd381277800d0dfd35fa
|
23
third_party/interlock/beijing11/beijing11_const.go
vendored
Normal file
23
third_party/interlock/beijing11/beijing11_const.go
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package beijing11
|
||||||
|
|
||||||
|
var (
|
||||||
|
FrameHead byte = 0x0E //帧头
|
||||||
|
FrameTail byte = 0x0E //帧尾
|
||||||
|
ControlWord = controlWord{
|
||||||
|
HeartBeat: 0x00,
|
||||||
|
ReadRegister: 0x01,
|
||||||
|
WriteRegister: 0x02,
|
||||||
|
Response: 0x03,
|
||||||
|
Upstream: 0x06,
|
||||||
|
DownStream: 0x07,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type controlWord struct {
|
||||||
|
HeartBeat byte //心跳
|
||||||
|
ReadRegister byte //读寄存器
|
||||||
|
WriteRegister byte //写寄存器
|
||||||
|
Response byte //回复
|
||||||
|
Upstream byte //上行流数据
|
||||||
|
DownStream byte //下行流数据
|
||||||
|
}
|
126
third_party/interlock/beijing11/interlock.go
vendored
Normal file
126
third_party/interlock/beijing11/interlock.go
vendored
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// Package beijing11 北京11号线联锁通信
|
||||||
|
package beijing11
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/config"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||||
|
"log/slog"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
initMutex = sync.Mutex{}
|
||||||
|
interlockMap = make(map[string]*InterlockProxy)
|
||||||
|
logTag = "[北京11号线联锁通信]"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetInstant(c *config.InterlockConfig, msgManager MsgManager) *InterlockProxy {
|
||||||
|
initMutex.Lock()
|
||||||
|
defer initMutex.Unlock()
|
||||||
|
if interlockMap[c.Code] == nil {
|
||||||
|
interlockMap[c.Code] = &InterlockProxy{runConfig: c, msgManager: msgManager}
|
||||||
|
}
|
||||||
|
return interlockMap[c.Code]
|
||||||
|
}
|
||||||
|
|
||||||
|
type MsgManager interface {
|
||||||
|
HandleReadRegisterMsg(req *ReadRegisterReq) (*ReadRegisterRes, error)
|
||||||
|
HandleWriteRegisterMsg(req *WriteRegisterReq) error
|
||||||
|
HandleDownstreamMsg(data []byte) error
|
||||||
|
CollectUpstreamMsg() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type msgManager struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterlockProxy struct {
|
||||||
|
runConfig *config.InterlockConfig //联锁通信配置
|
||||||
|
msgManager MsgManager //消息获取与处理接口0
|
||||||
|
client udp.UdpClient //向上位机发送数据的UDP客户端
|
||||||
|
server udp.UdpServer //接收上位机数据的UDP服务端
|
||||||
|
running bool //此服务正在运行的标志
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InterlockProxy) Start() {
|
||||||
|
if i.runConfig == nil || i.runConfig.Ip == "" || !i.runConfig.Open {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if i.running {
|
||||||
|
panic("启动联锁消息服务错误: 存在正在运行的任务")
|
||||||
|
}
|
||||||
|
//UDP通信设施
|
||||||
|
i.server = udp.NewServer(fmt.Sprintf(":%d", i.runConfig.LocalPort), i.handleUpperData)
|
||||||
|
err := i.server.Listen()
|
||||||
|
if err != nil {
|
||||||
|
panic("启动联锁消息服务错误:无法启动UDP服务")
|
||||||
|
}
|
||||||
|
i.running = true
|
||||||
|
i.client = udp.NewClient(fmt.Sprintf("%v:%v", i.runConfig.Ip, i.runConfig.RemotePort))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理来自上位机的数据
|
||||||
|
func (i *InterlockProxy) handleUpperData(data []byte) {
|
||||||
|
baseData := &BaseStruct{}
|
||||||
|
err := baseData.Decode(data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "数据解析出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch baseData.ControlWord {
|
||||||
|
case ControlWord.ReadRegister:
|
||||||
|
req := &ReadRegisterReq{}
|
||||||
|
err := req.Decode(baseData.Data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "读寄存器数据解析出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := i.msgManager.HandleReadRegisterMsg(req)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "读寄存器数据处理出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resData := &BaseStruct{
|
||||||
|
ID: baseData.ID,
|
||||||
|
ControlWord: ControlWord.Response,
|
||||||
|
Data: res.Encode(),
|
||||||
|
}
|
||||||
|
i.SendToUpper(resData.Encode())
|
||||||
|
case ControlWord.WriteRegister:
|
||||||
|
req := &WriteRegisterReq{}
|
||||||
|
err := req.Decode(baseData.Data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "写寄存器数据解析出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = i.msgManager.HandleWriteRegisterMsg(req)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "写寄存器数据处理出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case ControlWord.DownStream:
|
||||||
|
err = i.msgManager.HandleDownstreamMsg(baseData.Data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "下行数据处理出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InterlockProxy) SendToUpper(data []byte) {
|
||||||
|
err := i.client.Send(data)
|
||||||
|
slog.Error(logTag + "向上位机发送数据失败:" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InterlockProxy) Stop() {
|
||||||
|
initMutex.Lock()
|
||||||
|
defer initMutex.Unlock()
|
||||||
|
delete(interlockMap, i.runConfig.Code)
|
||||||
|
if i.client != nil {
|
||||||
|
i.client.Close()
|
||||||
|
}
|
||||||
|
if i.server != nil {
|
||||||
|
i.server.Close()
|
||||||
|
}
|
||||||
|
i.running = false
|
||||||
|
}
|
86
third_party/interlock/beijing11/msg.go
vendored
Normal file
86
third_party/interlock/beijing11/msg.go
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package beijing11
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc32"
|
||||||
|
"joylink.club/bj-rtsts-server/sys_error"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseStruct struct {
|
||||||
|
ID byte
|
||||||
|
ControlWord byte
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *BaseStruct) Decode(buf []byte) error {
|
||||||
|
if buf[0] != FrameHead {
|
||||||
|
return sys_error.New(logTag + "帧头不正确:" + fmt.Sprintf("%02X", buf[0]))
|
||||||
|
}
|
||||||
|
if buf[len(buf)-1] != FrameTail {
|
||||||
|
return sys_error.New(logTag + "帧尾不正确:" + fmt.Sprintf("%02X", buf[len(buf)-1]))
|
||||||
|
}
|
||||||
|
crc := crc32.ChecksumIEEE(buf[1 : len(buf)-5])
|
||||||
|
if crc != binary.BigEndian.Uint32(buf[len(buf)-5:len(buf)-1]) {
|
||||||
|
return sys_error.New(logTag + "CRC校验失败")
|
||||||
|
}
|
||||||
|
m.ID = buf[1]
|
||||||
|
m.ControlWord = buf[2]
|
||||||
|
m.Data = buf[5 : len(buf)-5]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *BaseStruct) Encode() []byte {
|
||||||
|
var data []byte
|
||||||
|
data = append(data, FrameHead)
|
||||||
|
data = append(data, m.ID)
|
||||||
|
data = append(data, m.ControlWord)
|
||||||
|
data = binary.BigEndian.AppendUint16(data, uint16(len(m.Data)))
|
||||||
|
data = append(data, m.Data...)
|
||||||
|
crc := crc32.ChecksumIEEE(data[1:])
|
||||||
|
data = binary.BigEndian.AppendUint32(data, crc)
|
||||||
|
data = append(data, FrameTail)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReadRegisterReq struct {
|
||||||
|
RegisterAddr []uint16 //寄存器地址
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReadRegisterReq) Decode(buf []byte) error {
|
||||||
|
if len(buf)%2 != 0 {
|
||||||
|
return sys_error.New(logTag + "读寄存器数据字节长度不是2的倍数")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(buf); i += 2 {
|
||||||
|
r.RegisterAddr = append(r.RegisterAddr, binary.BigEndian.Uint16(buf[i:i+2]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReadRegisterRes struct {
|
||||||
|
RegisterData [][]byte //寄存器数据
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReadRegisterRes) Encode() []byte {
|
||||||
|
var data []byte
|
||||||
|
for _, datum := range r.RegisterData {
|
||||||
|
data = append(data, datum...)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
type WriteRegisterReq struct {
|
||||||
|
RegisterAddr []uint16 //寄存器地址
|
||||||
|
RegisterData [][]byte //寄存器数据
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WriteRegisterReq) Decode(buf []byte) error {
|
||||||
|
if len(buf)%6 != 0 {
|
||||||
|
return sys_error.New(logTag + "写寄存器数据字节长度不是6的倍数")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(buf); i += 6 {
|
||||||
|
w.RegisterAddr = append(w.RegisterAddr, binary.BigEndian.Uint16(buf[i:i+2]))
|
||||||
|
w.RegisterData = append(w.RegisterData, buf[i+2:i+6])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
package interlock
|
// Package beijing12 北京12号线联锁通信
|
||||||
|
package beijing12
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -3,6 +3,7 @@ package ts
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"joylink.club/bj-rtsts-server/third_party/acc"
|
"joylink.club/bj-rtsts-server/third_party/acc"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/interlock/beijing12"
|
||||||
"joylink.club/bj-rtsts-server/third_party/radar"
|
"joylink.club/bj-rtsts-server/third_party/radar"
|
||||||
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@ -20,7 +21,6 @@ import (
|
|||||||
"joylink.club/bj-rtsts-server/mqtt"
|
"joylink.club/bj-rtsts-server/mqtt"
|
||||||
"joylink.club/bj-rtsts-server/sys_error"
|
"joylink.club/bj-rtsts-server/sys_error"
|
||||||
"joylink.club/bj-rtsts-server/third_party/dynamics"
|
"joylink.club/bj-rtsts-server/third_party/dynamics"
|
||||||
"joylink.club/bj-rtsts-server/third_party/interlock"
|
|
||||||
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
||||||
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
|
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func runThirdParty(s *memory.VerifySimulation) error {
|
|||||||
semi_physical_train.Default().Start(s)
|
semi_physical_train.Default().Start(s)
|
||||||
// 联锁启动
|
// 联锁启动
|
||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
interlock.Default(c).Start(s)
|
beijing12.Default(c).Start(s)
|
||||||
}
|
}
|
||||||
// 计轴RSSP启动
|
// 计轴RSSP启动
|
||||||
axle_device.StartLineAllRsspAxleServices(s)
|
axle_device.StartLineAllRsspAxleServices(s)
|
||||||
@ -149,7 +149,7 @@ func stopThirdParty(s *memory.VerifySimulation) {
|
|||||||
semi_physical_train.Default().Stop()
|
semi_physical_train.Default().Stop()
|
||||||
// 联锁启动
|
// 联锁启动
|
||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
interlock.Default(c).Stop()
|
beijing12.Default(c).Stop()
|
||||||
}
|
}
|
||||||
//计轴RSSP启动销毁
|
//计轴RSSP启动销毁
|
||||||
axle_device.StopLineAllRsspAxleServices()
|
axle_device.StopLineAllRsspAxleServices()
|
||||||
|
Loading…
Reference in New Issue
Block a user