Merge branch 'master' of https://git.code.tencent.com/beijing-rtss-test/bj-rtsts-server-go
This commit is contained in:
commit
2387b9e90a
@ -3,7 +3,6 @@ package config
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"joylink.club/bj-rtsts-server/third_party/axle_device"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
@ -57,7 +56,7 @@ type ThridPartyConfig struct {
|
|||||||
Dynamics DynamicsConfig `json:"dynamics" description:"动力学配置"`
|
Dynamics DynamicsConfig `json:"dynamics" description:"动力学配置"`
|
||||||
Vobc VobcConfig `json:"vobc" description:"半实物配置"`
|
Vobc VobcConfig `json:"vobc" description:"半实物配置"`
|
||||||
Interlocks []InterlockConfig `json:"interlock" description:"联锁配置"`
|
Interlocks []InterlockConfig `json:"interlock" description:"联锁配置"`
|
||||||
RsspAxle RsspAxleConfig `json:"rsspAxle" description:"计轴RSSP-I配置"`
|
RsspAxleCfgs []RsspAxleConfig `json:"rsspAxleCfgs" description:"所有联锁集中站计轴RSSP-I配置"`
|
||||||
}
|
}
|
||||||
type DynamicsConfig struct {
|
type DynamicsConfig struct {
|
||||||
Ip string `json:"ip" description:"IP配置"`
|
Ip string `json:"ip" description:"IP配置"`
|
||||||
@ -80,11 +79,49 @@ type InterlockConfig struct {
|
|||||||
Open bool `json:"open" description:"是否开启"`
|
Open bool `json:"open" description:"是否开启"`
|
||||||
Code string `json:"code" description:"所属集中站"`
|
Code string `json:"code" description:"所属集中站"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RsspAxleConfig 计轴区段与联锁安全通信配置
|
||||||
type RsspAxleConfig struct {
|
type RsspAxleConfig struct {
|
||||||
MasterRssp axle_device.RsspConfig `json:"masterRssp" description:"主安全通道配置"`
|
City string `json:"city" description:"所属城市"`
|
||||||
SlaveRssp axle_device.RsspConfig `json:"slaveRssp" description:"备安全通道配置"`
|
LineId string `json:"lineId" description:"所属线路"`
|
||||||
|
CentralizedStation string `json:"centralizedStation" description:"所属集中站"`
|
||||||
|
RsspCfgs []RsspConfig `json:"rsspCfgs" description:"主备安全通道配置"`
|
||||||
|
SendingPeriod uint32 `json:"sendingPeriod" description:"发送周期值"` //接收方每个安全通信会话对应的发送周期值,单位ms
|
||||||
|
SsrRsspTimeout uint32 `json:"ssrRsspTimeout" description:"等待SSR回应的定时器超时值"` //等待SSR回应的定时器超时值,为RsspTimer时间,1=SendingPeriod
|
||||||
|
Mtv uint32 `json:"mtv" description:"最大时序偏差"` //每个安全通信会话可容忍的最大时序偏差,即当前接收的RSD的序列号与上一次RSD的序列号最大允许差值
|
||||||
|
Udl uint32 `json:"udl" description:"RSD应用数据长度配置值"` //每个安全通信会话RSD应用数据长度发送和接收的配置值(支持固定长度和可变长度);0-可变长度,大于0即固定长度
|
||||||
|
DeviceA bool `json:"deviceA" description:"true-A机;false-B机"` //true-A机;false-B机
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RsspConfig CI系统与计轴设备的安全通信协议配置参数
|
||||||
|
// 计轴设备(管理一个集中站的所有计轴器)配置
|
||||||
|
type RsspConfig struct {
|
||||||
|
SrcAddr uint16 `json:"srcAddr" description:"16位源地址,本地地址"` //16位源地址,本地地址
|
||||||
|
DstAddr uint16 `json:"dstAddr" description:"16位目的地址,远程地址"` //16位目的地址,远程地址
|
||||||
|
DataVer1 uint32 `json:"dataVer1" description:"通道1数据版本"` //通道1数据版本
|
||||||
|
DataVer2 uint32 `json:"dataVer2" description:"通道2数据版本"` //通道2数据版本
|
||||||
|
SID1 uint32 `json:"sID1" description:"通道1源标识"` //通道1源标识
|
||||||
|
SID2 uint32 `json:"sID2" description:"通道2源标识"` //通道2源标识
|
||||||
|
SINIT1 uint32 `json:"sINIT1" description:"通道1序列初始"` //通道1序列初始
|
||||||
|
SINIT2 uint32 `json:"sINIT2" description:"通道2序列初始"` //通道2序列初始
|
||||||
|
SendingPeriod uint32 //接收方每个安全通信会话对应的发送周期值,单位ms
|
||||||
|
SsrRsspTimeout uint32 //等待SSR回应的定时器超时值,为RsspTimer时间,1=SendingPeriod
|
||||||
|
Mtv uint32 //每个安全通信会话可容忍的最大时序偏差,即当前接收的RSD的序列号与上一次RSD的序列号最大允许差值
|
||||||
|
Udl uint32 //每个安全通信会话RSD应用数据长度发送和接收的配置值(支持固定长度和可变长度);0-可变长度,大于0即固定长度
|
||||||
|
DeviceA bool //true-A机;false-B机
|
||||||
|
PicType byte `json:"picType" description:"协议交互类别"` //协议交互类别,message.PicType
|
||||||
|
RemoteIp string `json:"remoteIp" description:"远程服务器ip"` //远程服务器ip
|
||||||
|
RemoteUdpPort int `json:"remoteUdpPort" description:"远程服务器端口"` //远程服务器端口
|
||||||
|
LocalUdpPort int `json:"localUdpPort" description:"本地服务器端口"` //本地服务器端口
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckAddress 检测目标源地址目的地址是否在配置中
|
||||||
|
func (c *RsspConfig) CheckAddress(srcAddr uint16, dstAddr uint16) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var Config AppConfig
|
var Config AppConfig
|
||||||
|
|
||||||
var SimulationId_prefix = (func() string {
|
var SimulationId_prefix = (func() string {
|
||||||
|
32
third_party/axle_device/config.go
vendored
32
third_party/axle_device/config.go
vendored
@ -1,32 +0,0 @@
|
|||||||
package axle_device
|
|
||||||
|
|
||||||
import "joylink.club/bj-rtsts-server/third_party/message"
|
|
||||||
|
|
||||||
// RsspConfig CI系统与计轴设备的安全通信协议配置参数
|
|
||||||
// 计轴设备(管理一个集中站的所有计轴器)配置
|
|
||||||
type RsspConfig struct {
|
|
||||||
SrcAddr uint16 `json:"SrcAddr" description:"16位源地址,本地地址"` //16位源地址,本地地址
|
|
||||||
DstAddr uint16 `json:"DstAddr" description:"16位目的地址,远程地址"` //16位目的地址,远程地址
|
|
||||||
DataVer1 uint32 `json:"DataVer1" description:"通道1数据版本"` //通道1数据版本
|
|
||||||
DataVer2 uint32 `json:"DataVer2" description:"通道2数据版本"` //通道2数据版本
|
|
||||||
SID1 uint32 `json:"SID1" description:"通道1源标识"` //通道1源标识
|
|
||||||
SID2 uint32 `json:"SID2" description:"通道2源标识"` //通道2源标识
|
|
||||||
SINIT1 uint32 `json:"SINIT1" description:"通道1序列初始"` //通道1序列初始
|
|
||||||
SINIT2 uint32 `json:"SINIT2" description:"通道2序列初始"` //通道2序列初始
|
|
||||||
SendingPeriod uint32 `json:"SendingPeriod" description:"发送周期值"` //接收方每个安全通信会话对应的发送周期值,单位ms
|
|
||||||
SsrRsspTimeout uint32 `json:"SsrRsspTimeout" description:"等待SSR回应的定时器超时值"` //等待SSR回应的定时器超时值,为RsspTimer时间,1=SendingPeriod
|
|
||||||
Mtv uint32 `json:"Mtv" description:"最大时序偏差"` //每个安全通信会话可容忍的最大时序偏差,即当前接收的RSD的序列号与上一次RSD的序列号最大允许差值
|
|
||||||
Udl uint32 `json:"Udl" description:"RSD应用数据长度配置值"` //每个安全通信会话RSD应用数据长度发送和接收的配置值(支持固定长度和可变长度);0-可变长度,大于0即固定长度
|
|
||||||
|
|
||||||
PicType message.PicType `json:"PicType" description:"协议交互类别"` //协议交互类别
|
|
||||||
DeviceA bool `json:"DeviceA" description:"true-A机;false-B机"` //true-A机;false-B机
|
|
||||||
|
|
||||||
RemoteIp string `json:"RemoteIp" description:"远程服务器ip"` //远程服务器ip
|
|
||||||
RemoteUdpPort int `json:"RemoteUdpPort" description:"远程服务器端口"` //远程服务器端口
|
|
||||||
LocalUdpPort int `json:"LocalUdpPort" description:"本地服务器端口"` //本地服务器端口
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckAddress 检测目标源地址目的地址是否在配置中
|
|
||||||
func (c *RsspConfig) CheckAddress(srcAddr uint16, dstAddr uint16) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
63
third_party/axle_device/rssp_axle.go
vendored
63
third_party/axle_device/rssp_axle.go
vendored
@ -2,9 +2,12 @@ package axle_device
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/config"
|
||||||
"joylink.club/bj-rtsts-server/third_party/message"
|
"joylink.club/bj-rtsts-server/third_party/message"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//计轴设备与联锁系统安全通信应用层实现
|
//计轴设备与联锁系统安全通信应用层实现
|
||||||
@ -16,13 +19,6 @@ type RsspAxle interface {
|
|||||||
Stop()
|
Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
type AxleMessageManager interface {
|
|
||||||
//HandleSectionCmdMsg 计轴设备接收到联锁发送来的控制命令
|
|
||||||
HandleSectionCmdMsg(city string, lineId string, centralizedStation string, msg *message.SectionCmdMsgPack)
|
|
||||||
//CollectSectionStatus 收集仿真中计轴区段状态
|
|
||||||
CollectSectionStatus(city string, lineId string, centralizedStation string) ([]*message.SectionStatusMsg, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type rsspAxle struct {
|
type rsspAxle struct {
|
||||||
//所属城市
|
//所属城市
|
||||||
city string
|
city string
|
||||||
@ -30,6 +26,8 @@ type rsspAxle struct {
|
|||||||
lineId string
|
lineId string
|
||||||
//所属集中站
|
//所属集中站
|
||||||
centralizedStation string
|
centralizedStation string
|
||||||
|
//接收方每个安全通信会话对应的发送周期值,单位ms
|
||||||
|
sendingPeriod uint32
|
||||||
//主安全通道
|
//主安全通道
|
||||||
masterRssp *RsspChannel
|
masterRssp *RsspChannel
|
||||||
//备安全通道
|
//备安全通道
|
||||||
@ -40,12 +38,42 @@ type rsspAxle struct {
|
|||||||
cancelSendStatus context.CancelFunc
|
cancelSendStatus context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRsspAxle(masterConfig *RsspConfig, slaveConfig *RsspConfig) RsspAxle {
|
func InitRsspAxle(cfg *config.RsspAxleConfig) RsspAxle {
|
||||||
mr := &RsspChannel{}
|
ra := &rsspAxle{}
|
||||||
mr.Init(masterConfig)
|
//
|
||||||
lr := &RsspChannel{}
|
ra.city = cfg.City
|
||||||
lr.Init(slaveConfig)
|
ra.lineId = cfg.LineId
|
||||||
return &rsspAxle{masterRssp: mr, slaveRssp: lr}
|
ra.centralizedStation = cfg.CentralizedStation
|
||||||
|
ra.sendingPeriod = cfg.SendingPeriod
|
||||||
|
//
|
||||||
|
cfgLen := len(cfg.RsspCfgs)
|
||||||
|
var masterConfig, slaveConfig *config.RsspConfig
|
||||||
|
if cfgLen >= 1 {
|
||||||
|
masterConfig = &cfg.RsspCfgs[0]
|
||||||
|
masterConfig.SendingPeriod = cfg.SendingPeriod
|
||||||
|
masterConfig.SsrRsspTimeout = cfg.SsrRsspTimeout
|
||||||
|
masterConfig.Mtv = cfg.Mtv
|
||||||
|
masterConfig.Udl = cfg.Udl
|
||||||
|
masterConfig.DeviceA = cfg.DeviceA
|
||||||
|
}
|
||||||
|
if cfgLen >= 2 {
|
||||||
|
slaveConfig = &cfg.RsspCfgs[1]
|
||||||
|
slaveConfig.SendingPeriod = cfg.SendingPeriod
|
||||||
|
slaveConfig.SsrRsspTimeout = cfg.SsrRsspTimeout
|
||||||
|
slaveConfig.Mtv = cfg.Mtv
|
||||||
|
slaveConfig.Udl = cfg.Udl
|
||||||
|
slaveConfig.DeviceA = cfg.DeviceA
|
||||||
|
}
|
||||||
|
if masterConfig != nil {
|
||||||
|
mrc := &RsspChannel{}
|
||||||
|
ra.masterRssp = mrc.Init(masterConfig)
|
||||||
|
}
|
||||||
|
if slaveConfig != nil {
|
||||||
|
src := &RsspChannel{}
|
||||||
|
ra.slaveRssp = src.Init(slaveConfig)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return ra
|
||||||
}
|
}
|
||||||
|
|
||||||
// rssp 安全层执行
|
// rssp 安全层执行
|
||||||
@ -83,12 +111,15 @@ func (s *rsspAxle) Stop() {
|
|||||||
if s.cancelSendStatus != nil {
|
if s.cancelSendStatus != nil {
|
||||||
s.cancelSendStatus()
|
s.cancelSendStatus()
|
||||||
}
|
}
|
||||||
|
if s.cancelSendStatus != nil {
|
||||||
|
s.cancelSendStatus()
|
||||||
|
}
|
||||||
s.messageManager = nil
|
s.messageManager = nil
|
||||||
}
|
}
|
||||||
func (s *rsspAxle) doTaskSendStatus(sendContext context.Context) {
|
func (s *rsspAxle) doTaskSendStatus(sendContext context.Context) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
slog.Error("定时发送计轴区段状态任务异常", "error", e, "stack", string(debug.Stack()))
|
slog.Error(fmt.Sprintf("[%s-%s-%s]定时发送计轴区段状态任务异常", s.city, s.lineId, s.centralizedStation), "error", e, "stack", string(debug.Stack()))
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -99,7 +130,7 @@ func (s *rsspAxle) doTaskSendStatus(sendContext context.Context) {
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if s.messageManager == nil {
|
if s.messageManager == nil {
|
||||||
slog.Warn("定时发送计轴区段状态任务因messageManager不存在退出")
|
slog.Warn(fmt.Sprintf("[%s-%s-%s]定时发送计轴区段状态任务因messageManager不存在退出", s.city, s.lineId, s.centralizedStation))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//收集区段状态
|
//收集区段状态
|
||||||
@ -114,6 +145,8 @@ func (s *rsspAxle) doTaskSendStatus(sendContext context.Context) {
|
|||||||
} else {
|
} else {
|
||||||
slog.Debug(e.Error())
|
slog.Debug(e.Error())
|
||||||
}
|
}
|
||||||
|
//todo
|
||||||
|
time.Sleep(time.Duration(s.sendingPeriod) * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
third_party/axle_device/rssp_axle_manage.go
vendored
Normal file
29
third_party/axle_device/rssp_axle_manage.go
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package axle_device
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/config"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/message"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
//联锁集中站计轴与联锁通信管理
|
||||||
|
|
||||||
|
type AxleMessageManager interface {
|
||||||
|
GetLineAllRsspAxleCfgs() []config.RsspAxleConfig
|
||||||
|
//HandleSectionCmdMsg 计轴设备接收到联锁发送来的控制命令
|
||||||
|
HandleSectionCmdMsg(city string, lineId string, centralizedStation string, msg *message.SectionCmdMsgPack)
|
||||||
|
//CollectSectionStatus 收集仿真中计轴区段状态
|
||||||
|
CollectSectionStatus(city string, lineId string, centralizedStation string) ([]*message.SectionStatusMsg, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartLineAllRsspAxleServices(ram AxleMessageManager) {
|
||||||
|
cfgs := ram.GetLineAllRsspAxleCfgs()
|
||||||
|
for _, cfg := range cfgs {
|
||||||
|
if len(cfg.RsspCfgs) > 0 {
|
||||||
|
InitRsspAxle(&cfg).Start(ram)
|
||||||
|
} else {
|
||||||
|
slog.Debug(fmt.Sprintf(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
third_party/axle_device/rssp_channel.go
vendored
6
third_party/axle_device/rssp_channel.go
vendored
@ -2,6 +2,7 @@ package axle_device
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/config"
|
||||||
"joylink.club/bj-rtsts-server/third_party/message"
|
"joylink.club/bj-rtsts-server/third_party/message"
|
||||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@ -21,7 +22,7 @@ type RsspChannel struct {
|
|||||||
//回调应用层
|
//回调应用层
|
||||||
handleUserData HandleUserData
|
handleUserData HandleUserData
|
||||||
//rssp安全通信配置
|
//rssp安全通信配置
|
||||||
config *RsspConfig
|
config *config.RsspConfig
|
||||||
//rssp时钟
|
//rssp时钟
|
||||||
rsspTimer *RsspTimer
|
rsspTimer *RsspTimer
|
||||||
//批次编号,发送序列号
|
//批次编号,发送序列号
|
||||||
@ -40,12 +41,13 @@ type RsspChannel struct {
|
|||||||
sendSseRecord *SseFireRecord
|
sendSseRecord *SseFireRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RsspChannel) Init(config *RsspConfig) {
|
func (s *RsspChannel) Init(config *config.RsspConfig) *RsspChannel {
|
||||||
s.config = config
|
s.config = config
|
||||||
s.rsspTimer = &RsspTimer{t: 0}
|
s.rsspTimer = &RsspTimer{t: 0}
|
||||||
s.sn = message.NewRsspSn(1)
|
s.sn = message.NewRsspSn(1)
|
||||||
s.ch1Ts = message.NewRsspLFSR(message.RsspTsC1, 32, s.config.SID1, false)
|
s.ch1Ts = message.NewRsspLFSR(message.RsspTsC1, 32, s.config.SID1, false)
|
||||||
s.ch2Ts = message.NewRsspLFSR(message.RsspTsC2, 32, s.config.SID2, false)
|
s.ch2Ts = message.NewRsspLFSR(message.RsspTsC2, 32, s.config.SID2, false)
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start 启动安全通道
|
// Start 启动安全通道
|
||||||
|
4
third_party/third_party.go
vendored
4
third_party/third_party.go
vendored
@ -1,5 +1,7 @@
|
|||||||
package third_party
|
package third_party
|
||||||
|
|
||||||
func Init() {
|
import "joylink.club/bj-rtsts-server/third_party/message"
|
||||||
|
|
||||||
|
func Init() {
|
||||||
|
message.InitRsspCrcTable()
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ func findCalcLinkIdAndOffset(sim *VerifySimulation, link *repository.Link, offse
|
|||||||
if tp == nil {
|
if tp == nil {
|
||||||
panic(sys_error.New("列车偏移超出link位置"))
|
panic(sys_error.New("列车偏移超出link位置"))
|
||||||
}
|
}
|
||||||
nextPort := getTurnoutNextPort(sim, tp)
|
nextPort := getTurnoutNextPort(sim, tp.Device().Id(), tp.Port().String())
|
||||||
if nextPort == proto2.Port_None {
|
if nextPort == proto2.Port_None {
|
||||||
panic(sys_error.New("列车偏移超出link位置"))
|
panic(sys_error.New("列车偏移超出link位置"))
|
||||||
}
|
}
|
||||||
@ -209,37 +209,37 @@ func findCalcLinkIdAndOffset(sim *VerifySimulation, link *repository.Link, offse
|
|||||||
// 根据当前link端,寻找下一个link连接端端口
|
// 根据当前link端,寻找下一个link连接端端口
|
||||||
// 入参:仿真、道岔端口
|
// 入参:仿真、道岔端口
|
||||||
// 输出:道岔端口
|
// 输出:道岔端口
|
||||||
func getTurnoutNextPort(sim *VerifySimulation, tp *repository.TurnoutPort) proto2.Port {
|
func getTurnoutNextPort(sim *VerifySimulation, turnoutId string, port string) proto2.Port {
|
||||||
entry, ok := entity.GetEntityByUid(sim.World, tp.Device().Id())
|
entry, ok := entity.GetEntityByUid(sim.World, turnoutId)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(sys_error.New(fmt.Sprintf("道岔不存在: World id=%d,道岔id=%s", sim.World.Id(), tp.Device().Id())))
|
panic(sys_error.New(fmt.Sprintf("道岔不存在: World id=%d,道岔id=%s", sim.World.Id(), turnoutId)))
|
||||||
}
|
}
|
||||||
if !entry.HasComponent(component.TurnoutPositionType) {
|
if !entry.HasComponent(component.TurnoutPositionType) {
|
||||||
panic(sys_error.New(fmt.Sprintf("道岔没有TurnoutPosition组件: World id=%d,道岔id=%s", sim.World.Id(), tp.Device().Id())))
|
panic(sys_error.New(fmt.Sprintf("道岔没有TurnoutPosition组件: World id=%d,道岔id=%s", sim.World.Id(), turnoutId)))
|
||||||
}
|
}
|
||||||
// 获取定反数据
|
// 获取定反数据
|
||||||
pos := component.TurnoutPositionType.Get(entry)
|
pos := component.TurnoutPositionType.Get(entry)
|
||||||
switch tp.Port() {
|
switch port {
|
||||||
case proto2.Port_A:
|
case "A":
|
||||||
if pos.Dw {
|
if pos.Dw {
|
||||||
return proto2.Port_B
|
return proto2.Port_B
|
||||||
} else {
|
} else {
|
||||||
return proto2.Port_C
|
return proto2.Port_C
|
||||||
}
|
}
|
||||||
case proto2.Port_B:
|
case "B":
|
||||||
if pos.Dw {
|
if pos.Dw {
|
||||||
return proto2.Port_A
|
return proto2.Port_A
|
||||||
} else {
|
} else {
|
||||||
return proto2.Port_None
|
return proto2.Port_None
|
||||||
}
|
}
|
||||||
case proto2.Port_C:
|
case "C":
|
||||||
if pos.Dw {
|
if pos.Dw {
|
||||||
return proto2.Port_None
|
return proto2.Port_None
|
||||||
} else {
|
} else {
|
||||||
return proto2.Port_A
|
return proto2.Port_A
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic(sys_error.New(fmt.Sprintf("非法端口:端口=%s", tp.Port().String())))
|
panic(sys_error.New(fmt.Sprintf("非法端口:端口=%s", port)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算link offset 在道岔上的位置
|
// 计算link offset 在道岔上的位置
|
||||||
@ -542,3 +542,60 @@ func turnoutOffsetToKilometer(repo *repository.Repository, uid string, runDirect
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据起始与末尾端查找经过的设备ID列表
|
||||||
|
// 入参:起始设备uid、起始设备端口、终点设备uid、在区段(a->b)或道岔(->岔心)上的找寻方向
|
||||||
|
// 输出:占用物理区段的ID
|
||||||
|
func QueryDeviceRoutePath(sim *VerifySimulation, startUid, endUid, startPort string, pointTo bool) []string {
|
||||||
|
suid, euid, port, direction := startUid, endUid, startPort, pointTo
|
||||||
|
var paths []string
|
||||||
|
for {
|
||||||
|
device := sim.Repo.FindById(suid)
|
||||||
|
var nextRelation repository.DevicePort
|
||||||
|
switch device.Type() {
|
||||||
|
case proto2.DeviceType_DeviceType_PhysicalSection: // 区段
|
||||||
|
d := device.(*repository.PhysicalSection)
|
||||||
|
paths = append(paths, d.Id())
|
||||||
|
nextRelation = d.ARelation()
|
||||||
|
if direction {
|
||||||
|
nextRelation = d.BRelation()
|
||||||
|
}
|
||||||
|
case proto2.DeviceType_DeviceType_Turnout: // 道岔
|
||||||
|
d := device.(*repository.Turnout)
|
||||||
|
if d.GetPhysicalSection() == nil {
|
||||||
|
panic(sys_error.New(fmt.Sprintf("道岔%s没有绑定物理区段", device.Id())))
|
||||||
|
}
|
||||||
|
paths = append(paths, d.GetPhysicalSection().Id())
|
||||||
|
var nextPort proto2.Port
|
||||||
|
switch port {
|
||||||
|
case "A":
|
||||||
|
nextPort = proto2.Port_A
|
||||||
|
case "B":
|
||||||
|
nextPort = proto2.Port_B
|
||||||
|
case "C":
|
||||||
|
nextPort = proto2.Port_C
|
||||||
|
}
|
||||||
|
if pointTo { // -> 岔心
|
||||||
|
nextPort = getTurnoutNextPort(sim, d.Id(), port)
|
||||||
|
}
|
||||||
|
nextRelation = d.GindDevicePortByPort(nextPort)
|
||||||
|
default:
|
||||||
|
panic(sys_error.New(fmt.Sprintf("查找路径设备类型%s无处理处理", device.Type().String())))
|
||||||
|
}
|
||||||
|
if nextRelation == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if suid == euid {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
suid = nextRelation.Device().Id() // 下一个设备ID
|
||||||
|
port = nextRelation.Port().String() // 下一个道岔端
|
||||||
|
switch nextRelation.Device().Type() { // 查找方向
|
||||||
|
case proto2.DeviceType_DeviceType_PhysicalSection:
|
||||||
|
direction = nextRelation.Port() == proto2.Port_A
|
||||||
|
case proto2.DeviceType_DeviceType_Turnout:
|
||||||
|
direction = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
@ -147,6 +147,9 @@ func (s *VerifySimulation) GetComIdByUid(uid string) string {
|
|||||||
}
|
}
|
||||||
return es[uid].CommonId
|
return es[uid].CommonId
|
||||||
}
|
}
|
||||||
|
func (s *VerifySimulation) GetLineAllRsspAxleCfgs() []config.RsspAxleConfig {
|
||||||
|
return s.runConfig.RsspAxleCfgs
|
||||||
|
}
|
||||||
|
|
||||||
// CollectSectionStatus 收集仿真中计轴区段状态
|
// CollectSectionStatus 收集仿真中计轴区段状态
|
||||||
func (s *VerifySimulation) CollectSectionStatus(city string, lineId string, centralizedStation string) ([]*message.SectionStatusMsg, error) {
|
func (s *VerifySimulation) CollectSectionStatus(city string, lineId string, centralizedStation string) ([]*message.SectionStatusMsg, error) {
|
||||||
@ -282,9 +285,19 @@ func convert(info *message.DynamicsTrainInfo, sta *state.TrainState, simulation
|
|||||||
delayTime := time.Now().UnixMilli() - sta.VobcState.UpdateTime
|
delayTime := time.Now().UnixMilli() - sta.VobcState.UpdateTime
|
||||||
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
||||||
slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
||||||
_, id, port, _, offset, kilometer := CalcInitializeLink(simulation, strconv.Itoa(int(info.Link)), int64(info.LinkOffset), info.Up)
|
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
||||||
|
outLinkId, id, port, outLinkOffset, offset, kilometer := CalcInitializeLink(simulation, inLinkId, inLinkOffset, info.Up)
|
||||||
runDirection, pointTo := QueryDirectionAndABByDevice(simulation.Repo, id, port, info.Up)
|
runDirection, pointTo := QueryDirectionAndABByDevice(simulation.Repo, id, port, info.Up)
|
||||||
slog.Debug("处理动力学转换后的消息", "number", info.Number, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo)
|
slog.Debug("处理动力学转换后的消息", "number", info.Number, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo)
|
||||||
|
// 车尾相对车头link的偏移量
|
||||||
|
var calctailOffset int64
|
||||||
|
if info.Up {
|
||||||
|
calctailOffset = outLinkOffset - sta.TrainLength
|
||||||
|
} else {
|
||||||
|
calctailOffset = outLinkOffset + sta.TrainLength
|
||||||
|
}
|
||||||
|
tailLinkId, tailDeviceId, tailDevicePort, tailLinkOffset, tailDeviceOffset, _ := CalcInitializeLink(simulation, outLinkId, calctailOffset, info.Up)
|
||||||
|
slog.Debug("车未位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
||||||
sta.HeadDeviceId = simulation.GetComIdByUid(id)
|
sta.HeadDeviceId = simulation.GetComIdByUid(id)
|
||||||
sta.DevicePort = port
|
sta.DevicePort = port
|
||||||
sta.HeadOffset = offset
|
sta.HeadOffset = offset
|
||||||
@ -305,8 +318,10 @@ func convert(info *message.DynamicsTrainInfo, sta *state.TrainState, simulation
|
|||||||
}
|
}
|
||||||
// 赋值动力学信息
|
// 赋值动力学信息
|
||||||
sta.DynamicState.Heartbeat = int32(info.LifeSignal)
|
sta.DynamicState.Heartbeat = int32(info.LifeSignal)
|
||||||
sta.DynamicState.HeadLinkId = strconv.Itoa(int(info.Link))
|
sta.DynamicState.HeadLinkId = outLinkId
|
||||||
sta.DynamicState.HeadLinkOffset = int64(info.LinkOffset)
|
sta.DynamicState.HeadLinkOffset = outLinkOffset
|
||||||
|
sta.DynamicState.TailLinkId = tailLinkId
|
||||||
|
sta.DynamicState.TailLinkOffset = tailLinkOffset
|
||||||
sta.DynamicState.Slope = int32(info.Slope)
|
sta.DynamicState.Slope = int32(info.Slope)
|
||||||
sta.DynamicState.Upslope = info.UpSlope
|
sta.DynamicState.Upslope = info.UpSlope
|
||||||
sta.DynamicState.RunningUp = info.Up
|
sta.DynamicState.RunningUp = info.Up
|
||||||
|
@ -2,6 +2,7 @@ package ts
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/axle_device"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -110,6 +111,8 @@ func runThirdParty(s *memory.VerifySimulation) error {
|
|||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
interlock.Default(c).Start(s)
|
interlock.Default(c).Start(s)
|
||||||
}
|
}
|
||||||
|
// 计轴RSSP启动
|
||||||
|
axle_device.StartLineAllRsspAxleServices(s)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user