Compare commits

...

2 Commits

7 changed files with 249 additions and 5 deletions

View File

@ -293,6 +293,14 @@ func handlerSectionState(w ecs.World, uid string) *state_proto.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
}

@ -1 +1 @@
Subproject commit 8ccd46aa6c97a933fd12c7b308da929115c9aa8e
Subproject commit 90003ec9429c7db26c43dd381277800d0dfd35fa

View 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 //下行流数据
}

View 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
View 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
}

View File

@ -1,4 +1,5 @@
package interlock
// Package beijing12 北京12号线联锁通信
package beijing12
import (
"context"

View File

@ -3,6 +3,7 @@ package ts
import (
"fmt"
"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/train_pc_sim"
"log/slog"
@ -20,7 +21,6 @@ import (
"joylink.club/bj-rtsts-server/mqtt"
"joylink.club/bj-rtsts-server/sys_error"
"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/ts/simulation/wayside/memory"
@ -120,7 +120,7 @@ func runThirdParty(s *memory.VerifySimulation) error {
semi_physical_train.Default().Start(s)
// 联锁启动
for _, c := range s.GetInterlockCodes() {
interlock.Default(c).Start(s)
beijing12.Default(c).Start(s)
}
// 计轴RSSP启动
axle_device.StartLineAllRsspAxleServices(s)
@ -149,7 +149,7 @@ func stopThirdParty(s *memory.VerifySimulation) {
semi_physical_train.Default().Stop()
// 联锁启动
for _, c := range s.GetInterlockCodes() {
interlock.Default(c).Stop()
beijing12.Default(c).Stop()
}
//计轴RSSP启动销毁
axle_device.StopLineAllRsspAxleServices()