Compare commits
6 Commits
15bdc45892
...
81c36c6fb1
Author | SHA1 | Date | |
---|---|---|---|
81c36c6fb1 | |||
735423ca67 | |||
|
76183883da | ||
|
2463edd996 | ||
3a22950790 | |||
|
c6cfc42774 |
@ -420,7 +420,7 @@ func removeAllTrain(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
slog.Debug("ATS测试仿真-移除所有列车,请求:", rt)
|
slog.Debug("ATS测试仿真-移除所有列车,请求:", rt)
|
||||||
simulation := checkDeviceDataAndReturn(rt.SimulationId)
|
simulation := checkDeviceDataAndReturn(rt.SimulationId)
|
||||||
memory.RemoveAllTrain(simulation)
|
memory.RemoveAllTrain(simulation, false)
|
||||||
//TODO 后续调用列车删除操作
|
//TODO 后续调用列车删除操作
|
||||||
c.JSON(http.StatusOK, "ok")
|
c.JSON(http.StatusOK, "ok")
|
||||||
}
|
}
|
||||||
@ -448,7 +448,7 @@ func removeTrain(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
slog.Debug("ATS测试仿真-移除列车,请求:", rt)
|
slog.Debug("ATS测试仿真-移除列车,请求:", rt)
|
||||||
simulation := checkDeviceDataAndReturn(rt.SimulationId)
|
simulation := checkDeviceDataAndReturn(rt.SimulationId)
|
||||||
memory.RemoveTrainState(simulation, rt.TrainId)
|
memory.RemoveTrainState(simulation, rt.TrainId, false)
|
||||||
//TODO 后续调用列车删除操作
|
//TODO 后续调用列车删除操作
|
||||||
c.JSON(http.StatusOK, "ok")
|
c.JSON(http.StatusOK, "ok")
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit ef7ff5459cde3eced121d1908b192ee586a47c97
|
Subproject commit 150aa24307c42916cde8f6fbe629c9d100be8737
|
7
third_party/balisecodec/codec.go
vendored
7
third_party/balisecodec/codec.go
vendored
@ -4,7 +4,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 应答器数据编解码器
|
// 应答器数据编解码器
|
||||||
@ -84,8 +83,8 @@ func checkCb(bits1023 []byte) error {
|
|||||||
cb := getRange(bits1023, 109, 107)
|
cb := getRange(bits1023, 109, 107)
|
||||||
for i, v := range cb {
|
for i, v := range cb {
|
||||||
n := 109 - i
|
n := 109 - i
|
||||||
name := "b" + strconv.Itoa(109-i)
|
//name := "b" + strconv.Itoa(109-i)
|
||||||
slog.Info("cb", name, v)
|
//slog.Info("cb", name, v)
|
||||||
if n == 109 && v == 1 {
|
if n == 109 && v == 1 {
|
||||||
return buildError("控制位cb错误,b109应该为0,实际为1")
|
return buildError("控制位cb错误,b109应该为0,实际为1")
|
||||||
} else if n == 108 && v == 1 {
|
} else if n == 108 && v == 1 {
|
||||||
@ -131,7 +130,7 @@ func calculateS(sb []byte) uint32 {
|
|||||||
B := ToValLeftMsb(sb)
|
B := ToValLeftMsb(sb)
|
||||||
const A uint64 = 2801775573
|
const A uint64 = 2801775573
|
||||||
S := uint32((A * uint64(B)) % (1 << 32))
|
S := uint32((A * uint64(B)) % (1 << 32))
|
||||||
slog.Info("由12位加扰位计算得到整数S", "B", B, "S", S, "Sb", fmt.Sprintf("%032b", S))
|
//slog.Info("由12位加扰位计算得到整数S", "B", B, "S", S, "Sb", fmt.Sprintf("%032b", S))
|
||||||
return S
|
return S
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
third_party/balisecodec/decode.go
vendored
7
third_party/balisecodec/decode.go
vendored
@ -1,10 +1,5 @@
|
|||||||
package balisecodec
|
package balisecodec
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位(MSB)的无符号整数数组,除了第一个10位值,其余值求和,然后循环2的10次方次与其他值求和结果相加后模2的10次方,若结果和第一个10位值相同,则结束,此值即为原始的第一个10位值,将此值替换为第一个10位二进制数组,依然是左边为MSB
|
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位(MSB)的无符号整数数组,除了第一个10位值,其余值求和,然后循环2的10次方次与其他值求和结果相加后模2的10次方,若结果和第一个10位值相同,则结束,此值即为原始的第一个10位值,将此值替换为第一个10位二进制数组,依然是左边为MSB
|
||||||
func revertFirst10Bits(b []byte) []byte {
|
func revertFirst10Bits(b []byte) []byte {
|
||||||
if len(b) != 830 {
|
if len(b) != 830 {
|
||||||
@ -37,7 +32,7 @@ func revertFirst10Bits(b []byte) []byte {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slog.Info("还原第一个10位值", "sum", sum, "bits[0]", w10s[0], "bits[0]b", fmt.Sprintf("%010b", w10s[0]))
|
//slog.Info("还原第一个10位值", "sum", sum, "bits[0]", w10s[0], "bits[0]b", fmt.Sprintf("%010b", w10s[0]))
|
||||||
bits := make([]byte, 830)
|
bits := make([]byte, 830)
|
||||||
// 将整个10位数组转换为二进制数组,依然是MSB
|
// 将整个10位数组转换为二进制数组,依然是MSB
|
||||||
u0bits := ToBitsLeftMsb(int(w10s[0]), 10)
|
u0bits := ToBitsLeftMsb(int(w10s[0]), 10)
|
||||||
|
4
third_party/interlock/beijing11/msg_test.go
vendored
4
third_party/interlock/beijing11/msg_test.go
vendored
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFromInterlockFrame_Decode(t *testing.T) {
|
func TestFromInterlockFrame_Decode(t *testing.T) {
|
||||||
str := "58bea4c65e0e583f5bdedc310800450000bd030c0000801100003d0b0a0d3d0b7814413c40d800a9fcf182009a3c016301000600010000020000030000060000070000080000020001000005aa00020001aaaa0005aaaa00000008000401000501000601000701001801001901001a01001b010010000400000500000600000700000800000900000a00001d00001e00001f000020000021000022000023000024000025000000000000040001aaaa0002aaaa0003aaaa0004aaaa0000000000000000000000004c428d88"
|
str := "58bea4c65e0e583f5bdedc310800450000c9d0770000801100003d0b0a0d3d0b7814413c40d800b5fcfd8200a63c0363010003000400000500000900000200040000080000020004aaaa0008aaaa0000000f000d06000e01000f060010060021060023060011060012060026060027010013060014010022060024060025060010001300001400001500001600001700001800001900001a00002c00002d00002e00002f00003000003100003200003300000000000004000daaaa000eaaaa000faaaa0010aaaa00000000000000000000000058f24545"
|
||||||
data, err := hex.DecodeString(str)
|
data, err := hex.DecodeString(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -112,7 +112,7 @@ func TestFromInterlockFrame_Decode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestToInterlockFrame_Decode(t *testing.T) {
|
func TestToInterlockFrame_Decode(t *testing.T) {
|
||||||
str := "583f5bdedc3158bea4c65e0e0800450000f6dfe9400040115dd63d0b78143d0b0a0dd341413c00e2e8c88300d363013c0100060001010002010003010006010007010008010002000102eeaaaaaa000502eeaaaaaa00020001aa000005aa0000000011000101000201000301000401000501000601000701001501001601001701001801001901001a01001b01002901002a01002c010015000100000200000300000400000500000600000700000800000900000a00001b00001c00001d00001e00001f000020000021000022000023000024000025000000000000040001aaff0002aaff0003aaff0004aaff00000100000000000000000000000000000000f38414ee"
|
str := "583f5bdedc3158bea4c65e0e080045000172b52c4000401188173d0b78143d0b0a0d40d8413c015ebe7f83014f63013c0200030004010005010009020006000202eeaaaaaa000302eeaaaaaa000402eeaaaaaa000602eeaaaaaa000702eeaaaaaa000802eeaaaaaa00060002aaaa0003aaaa0004aaaa0006aaaa0007aaaa0008aaaa0000001b000800000900000a00000b00000c00000d06000e01000f06001006001106001206001306001401001c00001d00001e00001f00002000002106002206002306002406002506002606002701002800002b00001e000b00000c00000d00000e00000f00001000001100001200001300001400001500001600001700001800001900001a00002600002700002800002900002a00002b00002c00002d00002e00002f0000300000310000320000330000000000000c0005aaaa0006aaaa0007aaaa0008aaaa0009aaaa000aaaaa000baaaa000caaaa000daaaa000eaaaa000faaaa0010aaaa00000100000000000000000000000000000000328ef0af"
|
||||||
data, err := hex.DecodeString(str)
|
data, err := hex.DecodeString(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
11
third_party/interlock/beijing11/repo.go
vendored
11
third_party/interlock/beijing11/repo.go
vendored
@ -2,8 +2,8 @@ package beijing11
|
|||||||
|
|
||||||
// StationDeviceIndexTable 联锁站设备索引表
|
// StationDeviceIndexTable 联锁站设备索引表
|
||||||
type StationDeviceIndexTable struct {
|
type StationDeviceIndexTable struct {
|
||||||
StationName string //地图数据中车站的Code属性
|
//StationName string //地图数据中车站的Code属性
|
||||||
InterlockCode uint16 //通信数据中的“联锁编号”
|
//InterlockCode uint16 //通信数据中的“联锁编号”
|
||||||
TurnoutMap map[uint16]*Row //key-联锁编号
|
TurnoutMap map[uint16]*Row //key-联锁编号
|
||||||
PsdMap map[uint16]*Row //key-联锁编号
|
PsdMap map[uint16]*Row //key-联锁编号
|
||||||
EsbMap map[uint16]*Row //key-联锁编号
|
EsbMap map[uint16]*Row //key-联锁编号
|
||||||
@ -17,10 +17,10 @@ type StationDeviceIndexTable struct {
|
|||||||
XcjMap map[uint16]*Row //key-联锁编号
|
XcjMap map[uint16]*Row //key-联锁编号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStationDeviceIndexTable(stationName string, interlockIndex uint16) *StationDeviceIndexTable {
|
func NewStationDeviceIndexTable( /*stationName string, interlockIndex uint16*/ ) *StationDeviceIndexTable {
|
||||||
return &StationDeviceIndexTable{
|
return &StationDeviceIndexTable{
|
||||||
StationName: stationName,
|
//StationName: stationName,
|
||||||
InterlockCode: 0x3C00 + interlockIndex,
|
//InterlockCode: 0x3C00 + interlockIndex,
|
||||||
TurnoutMap: make(map[uint16]*Row),
|
TurnoutMap: make(map[uint16]*Row),
|
||||||
PsdMap: make(map[uint16]*Row),
|
PsdMap: make(map[uint16]*Row),
|
||||||
EsbMap: make(map[uint16]*Row),
|
EsbMap: make(map[uint16]*Row),
|
||||||
@ -36,6 +36,7 @@ func NewStationDeviceIndexTable(stationName string, interlockIndex uint16) *Stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Row struct {
|
type Row struct {
|
||||||
|
interlockCode uint16 //所属联锁站编号
|
||||||
commonId uint32 //地图中设备的ID
|
commonId uint32 //地图中设备的ID
|
||||||
uid string //模型仓库中的设备模型ID
|
uid string //模型仓库中的设备模型ID
|
||||||
index uint16 //联锁通信中的设备ID
|
index uint16 //联锁通信中的设备ID
|
||||||
|
337
third_party/interlock/beijing11/service.go
vendored
337
third_party/interlock/beijing11/service.go
vendored
@ -39,6 +39,7 @@ type serviceContext struct {
|
|||||||
sim *memory.VerifySimulation //启动服务所使用的仿真
|
sim *memory.VerifySimulation //启动服务所使用的仿真
|
||||||
iConfig config.InterlockConfig //启动服务使用的联锁配置
|
iConfig config.InterlockConfig //启动服务使用的联锁配置
|
||||||
deviceTable *StationDeviceIndexTable //联锁站的设备ID表,key-车站名
|
deviceTable *StationDeviceIndexTable //联锁站的设备ID表,key-车站名
|
||||||
|
toInterlockFrames []*ToInterlockFrame //发给联锁的消息,因为需要按车站划分范围、排序,故将数据提前整理好,仅替换设备状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimulation) {
|
func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimulation) {
|
||||||
@ -48,7 +49,7 @@ func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimu
|
|||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
//制表
|
//制表
|
||||||
table := makeTable(simulation, interlockConfig.Code)
|
table, toInterlockFrames := preprocessingData(simulation, interlockConfig.Code)
|
||||||
if table == nil { //当前仿真内没有11号线联锁通信所需数据
|
if table == nil { //当前仿真内没有11号线联锁通信所需数据
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -69,6 +70,7 @@ func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimu
|
|||||||
sim: simulation,
|
sim: simulation,
|
||||||
iConfig: interlockConfig,
|
iConfig: interlockConfig,
|
||||||
deviceTable: table,
|
deviceTable: table,
|
||||||
|
toInterlockFrames: toInterlockFrames,
|
||||||
}
|
}
|
||||||
//UDP服务端
|
//UDP服务端
|
||||||
server := udp.NewServer(fmt.Sprintf(":%d", interlockConfig.LocalPort), serviceCtx.handleDriveMsg)
|
server := udp.NewServer(fmt.Sprintf(":%d", interlockConfig.LocalPort), serviceCtx.handleDriveMsg)
|
||||||
@ -82,6 +84,19 @@ func Start(interlockConfig config.InterlockConfig, simulation *memory.VerifySimu
|
|||||||
serviceContextMap[interlockConfig.Code] = serviceCtx
|
serviceContextMap[interlockConfig.Code] = serviceCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Stop(stationCode string) {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
serviceContext := serviceContextMap[stationCode]
|
||||||
|
if serviceContext != nil {
|
||||||
|
serviceContext.cancelFunc()
|
||||||
|
if serviceContext.server != nil {
|
||||||
|
serviceContext.server.Close()
|
||||||
|
}
|
||||||
|
delete(serviceContextMap, stationCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *serviceContext) handleDriveMsg(data []byte) {
|
func (s *serviceContext) handleDriveMsg(data []byte) {
|
||||||
logger().Info(fmt.Sprintf("收到消息:%x", data))
|
logger().Info(fmt.Sprintf("收到消息:%x", data))
|
||||||
frame := &FromInterlockFrame{}
|
frame := &FromInterlockFrame{}
|
||||||
@ -94,9 +109,9 @@ func (s *serviceContext) handleDriveMsg(data []byte) {
|
|||||||
wd := entity.GetWorldData(s.sim.World)
|
wd := entity.GetWorldData(s.sim.World)
|
||||||
for _, cmd := range frame.TurnoutData.CmdList {
|
for _, cmd := range frame.TurnoutData.CmdList {
|
||||||
uid := s.deviceTable.TurnoutMap[cmd.Id].uid
|
uid := s.deviceTable.TurnoutMap[cmd.Id].uid
|
||||||
if cmd.Cmd == 0x55 {
|
if cmd.Cmd == 0x01 {
|
||||||
err = fi.DriveTurnoutDCOn(s.sim.World, uid)
|
err = fi.DriveTurnoutDCOn(s.sim.World, uid)
|
||||||
} else if cmd.Cmd == 0xaa {
|
} else if cmd.Cmd == 0x02 {
|
||||||
err = fi.DriveTurnoutFCOn(s.sim.World, uid)
|
err = fi.DriveTurnoutFCOn(s.sim.World, uid)
|
||||||
} else {
|
} else {
|
||||||
err = fi.DriveTurnoutDCOff(s.sim.World, uid)
|
err = fi.DriveTurnoutDCOff(s.sim.World, uid)
|
||||||
@ -109,7 +124,6 @@ func (s *serviceContext) handleDriveMsg(data []byte) {
|
|||||||
row := s.deviceTable.PsdMap[cmd.Id]
|
row := s.deviceTable.PsdMap[cmd.Id]
|
||||||
entry := wd.EntityMap[row.uid]
|
entry := wd.EntityMap[row.uid]
|
||||||
circuit := component.PsdCircuitType.Get(entry)
|
circuit := component.PsdCircuitType.Get(entry)
|
||||||
logger().Info(fmt.Sprintf("屏蔽门命令:%x", cmd.Cmd))
|
|
||||||
switch cmd.Cmd {
|
switch cmd.Cmd {
|
||||||
case 0xAA: //短编组开门
|
case 0xAA: //短编组开门
|
||||||
wd.SetQdBit(row.relateDeviceMap[S], true)
|
wd.SetQdBit(row.relateDeviceMap[S], true)
|
||||||
@ -267,10 +281,22 @@ func (s *serviceContext) handleDriveMsg(data []byte) {
|
|||||||
default:
|
default:
|
||||||
logger().Error(fmt.Sprintf("信号机[%s]无法开放[%x]信号", uid, cmd.Cmd))
|
logger().Error(fmt.Sprintf("信号机[%s]无法开放[%x]信号", uid, cmd.Cmd))
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger().Error(fmt.Sprintf("信号机[%s]的型号未知", uid))
|
logger().Error(fmt.Sprintf("信号机[%s]的型号未知", uid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{ //采集状态赋值
|
||||||
|
signalAspectMap := make(map[uint16]byte)
|
||||||
|
for _, cmd := range frame.SignalData.CmdList {
|
||||||
|
signalAspectMap[cmd.Id] = cmd.Cmd
|
||||||
|
}
|
||||||
|
for _, interlockFrame := range s.toInterlockFrames {
|
||||||
|
for _, state := range interlockFrame.SignalStates {
|
||||||
|
state.State = signalAspectMap[state.Id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, cmd := range frame.AxleSectionData.CmdList {
|
for _, cmd := range frame.AxleSectionData.CmdList {
|
||||||
if cmd.Cmd == 0x80 {
|
if cmd.Cmd == 0x80 {
|
||||||
uid := s.deviceTable.AxleSectionMap[cmd.Id].uid
|
uid := s.deviceTable.AxleSectionMap[cmd.Id].uid
|
||||||
@ -297,19 +323,7 @@ func (s *serviceContext) handleDriveMsg(data []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Stop(stationCode string) {
|
func preprocessingData(sim *memory.VerifySimulation, stationCode string) (*StationDeviceIndexTable, []*ToInterlockFrame) {
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
serviceContext := serviceContextMap[stationCode]
|
|
||||||
if serviceContext != nil {
|
|
||||||
if serviceContext.server != nil {
|
|
||||||
serviceContext.server.Close()
|
|
||||||
}
|
|
||||||
delete(serviceContextMap, stationCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceIndexTable {
|
|
||||||
for _, mapId := range sim.MapIds {
|
for _, mapId := range sim.MapIds {
|
||||||
giType := memory.QueryGiType(mapId)
|
giType := memory.QueryGiType(mapId)
|
||||||
if giType != data_proto.PictureType_StationLayout {
|
if giType != data_proto.PictureType_StationLayout {
|
||||||
@ -320,22 +334,23 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frameMap := make(map[uint16]*ToInterlockFrame)
|
||||||
|
frameSlice := make([]*ToInterlockFrame, 0, 2)
|
||||||
|
getFrame := func(interlockCode uint16) *ToInterlockFrame {
|
||||||
|
frame := frameMap[interlockCode]
|
||||||
|
if frame == nil {
|
||||||
|
frame = &ToInterlockFrame{InterlockCode: interlockCode, WaysideCode: waysideCode}
|
||||||
|
frameMap[interlockCode] = frame
|
||||||
|
frameSlice = append(frameSlice, frame)
|
||||||
|
}
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
|
||||||
uids := memory.QueryUidStructure[*memory.StationUidStructure](mapId)
|
uids := memory.QueryUidStructure[*memory.StationUidStructure](mapId)
|
||||||
var table *StationDeviceIndexTable
|
table := NewStationDeviceIndexTable()
|
||||||
for _, station := range stationGi.Stations {
|
stationMap := make(map[uint32]uint16)
|
||||||
if station.StationName != stationCode {
|
for _, station := range stationGi.LianSuoData.Stations {
|
||||||
continue
|
stationMap[station.Id] = uint16(0x3c00 + station.Index)
|
||||||
}
|
|
||||||
for _, lianSuoIndexData := range stationGi.LianSuoData.Stations {
|
|
||||||
if lianSuoIndexData.Id == station.Common.Id {
|
|
||||||
table = NewStationDeviceIndexTable(station.StationName, uint16(lianSuoIndexData.Index))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if table == nil {
|
|
||||||
panic(fmt.Sprintf("联锁配置车站[%s]在地图中没有对应的车站或联锁编号数据", stationCode))
|
|
||||||
}
|
}
|
||||||
//道岔
|
//道岔
|
||||||
for _, data := range stationGi.LianSuoData.Switchs {
|
for _, data := range stationGi.LianSuoData.Switchs {
|
||||||
@ -343,8 +358,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, station := range uids.TurnoutIds[data.Id].CentralizedStations {
|
for _, station := range uids.TurnoutIds[data.Id].CentralizedStations {
|
||||||
if station.StationName == stationCode {
|
interlockCode := stationMap[station.Common.Id]
|
||||||
|
if interlockCode != 0 {
|
||||||
|
frame := getFrame(interlockCode)
|
||||||
|
frame.TurnoutStates = append(frame.TurnoutStates, &TurnoutState{Id: uint16(data.Index)})
|
||||||
table.TurnoutMap[uint16(data.Index)] = &Row{
|
table.TurnoutMap[uint16(data.Index)] = &Row{
|
||||||
|
interlockCode: interlockCode,
|
||||||
commonId: data.Id,
|
commonId: data.Id,
|
||||||
uid: uids.TurnoutIds[data.Id].Uid,
|
uid: uids.TurnoutIds[data.Id].Uid,
|
||||||
index: uint16(data.Index),
|
index: uint16(data.Index),
|
||||||
@ -377,7 +396,10 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
relateDeviceMap[S] = sRelayId
|
relateDeviceMap[S] = sRelayId
|
||||||
relateDeviceMap[L] = lRelayId
|
relateDeviceMap[L] = lRelayId
|
||||||
for _, station := range uids.PsdIds[data.Id].CentralizedStations {
|
for _, station := range uids.PsdIds[data.Id].CentralizedStations {
|
||||||
if station.StationName == stationCode {
|
interlockCode := stationMap[station.Common.Id]
|
||||||
|
if interlockCode != 0 {
|
||||||
|
frame := getFrame(interlockCode)
|
||||||
|
frame.PsdStates = append(frame.PsdStates, &PSDState{Id: uint16(data.Index)})
|
||||||
for _, mkx := range sim.Repo.MkxList() {
|
for _, mkx := range sim.Repo.MkxList() {
|
||||||
if mkx.Psd().Id() == uids.PsdIds[data.Id].Uid {
|
if mkx.Psd().Id() == uids.PsdIds[data.Id].Uid {
|
||||||
relateDeviceMap[POB] = mkx.Pobj().Id()
|
relateDeviceMap[POB] = mkx.Pobj().Id()
|
||||||
@ -386,6 +408,7 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.PsdMap[uint16(data.Index)] = &Row{
|
table.PsdMap[uint16(data.Index)] = &Row{
|
||||||
|
interlockCode: interlockCode,
|
||||||
commonId: data.Id,
|
commonId: data.Id,
|
||||||
uid: uids.PsdIds[data.Id].Uid,
|
uid: uids.PsdIds[data.Id].Uid,
|
||||||
index: uint16(data.Index),
|
index: uint16(data.Index),
|
||||||
@ -400,8 +423,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, station := range uids.EsbIds[data.Id].CentralizedStations {
|
for _, station := range uids.EsbIds[data.Id].CentralizedStations {
|
||||||
if station.StationName == stationCode {
|
interlockCode := stationMap[station.Common.Id]
|
||||||
|
if interlockCode != 0 {
|
||||||
|
frame := getFrame(interlockCode)
|
||||||
|
frame.ESBStates = append(frame.ESBStates, &ESBState{Id: uint16(data.Index)})
|
||||||
table.EsbMap[uint16(data.Index)] = &Row{
|
table.EsbMap[uint16(data.Index)] = &Row{
|
||||||
|
interlockCode: interlockCode,
|
||||||
commonId: data.Id,
|
commonId: data.Id,
|
||||||
uid: uids.EsbIds[data.Id].Uid,
|
uid: uids.EsbIds[data.Id].Uid,
|
||||||
index: uint16(data.Index),
|
index: uint16(data.Index),
|
||||||
@ -417,8 +444,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, station := range uids.SignalIds[data.Id].CentralizedStations {
|
for _, station := range uids.SignalIds[data.Id].CentralizedStations {
|
||||||
if station.StationName == stationCode {
|
interlockCode := stationMap[station.Common.Id]
|
||||||
|
if interlockCode != 0 {
|
||||||
|
frame := getFrame(interlockCode)
|
||||||
|
frame.SignalStates = append(frame.SignalStates, &SignalState{Id: uint16(data.Index)})
|
||||||
table.SignalMap[uint16(data.Index)] = &Row{
|
table.SignalMap[uint16(data.Index)] = &Row{
|
||||||
|
interlockCode: interlockCode,
|
||||||
commonId: data.Id,
|
commonId: data.Id,
|
||||||
uid: uids.SignalIds[data.Id].Uid,
|
uid: uids.SignalIds[data.Id].Uid,
|
||||||
index: uint16(data.Index),
|
index: uint16(data.Index),
|
||||||
@ -427,6 +458,17 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{ //临时补充一个信号机
|
||||||
|
table.SignalMap[40] = &Row{
|
||||||
|
interlockCode: 0x3c02,
|
||||||
|
commonId: 0,
|
||||||
|
uid: "",
|
||||||
|
index: 40,
|
||||||
|
relateDeviceMap: nil,
|
||||||
|
}
|
||||||
|
frame := getFrame(0x3c02)
|
||||||
|
frame.SignalStates = append(frame.SignalStates, &SignalState{Id: 40})
|
||||||
|
}
|
||||||
//计轴区段
|
//计轴区段
|
||||||
for _, data := range stationGi.LianSuoData.AcSections {
|
for _, data := range stationGi.LianSuoData.AcSections {
|
||||||
if data.Index <= 0 {
|
if data.Index <= 0 {
|
||||||
@ -434,8 +476,13 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
}
|
}
|
||||||
sectionModule := sim.Repo.FindAxleCountingSection(uids.AxleCountingSectionIds[data.Id].Uid)
|
sectionModule := sim.Repo.FindAxleCountingSection(uids.AxleCountingSectionIds[data.Id].Uid)
|
||||||
for _, station := range sectionModule.PhysicalSection().CentralizedStation() {
|
for _, station := range sectionModule.PhysicalSection().CentralizedStation() {
|
||||||
if station.GetCode() == stationCode {
|
//目前没发现一个计轴区段属于两个联锁区的情况,暂不处理
|
||||||
|
interlockCode := stationMap[sim.UidMap[station.Id()].CommonId]
|
||||||
|
if interlockCode != 0 {
|
||||||
|
frame := getFrame(interlockCode)
|
||||||
|
frame.AxleSectionStates = append(frame.AxleSectionStates, &AxleSectionState{Id: uint16(data.Index)})
|
||||||
table.AxleSectionMap[uint16(data.Index)] = &Row{
|
table.AxleSectionMap[uint16(data.Index)] = &Row{
|
||||||
|
interlockCode: interlockCode,
|
||||||
commonId: data.Id,
|
commonId: data.Id,
|
||||||
uid: uids.AxleCountingSectionIds[data.Id].Uid,
|
uid: uids.AxleCountingSectionIds[data.Id].Uid,
|
||||||
index: uint16(data.Index),
|
index: uint16(data.Index),
|
||||||
@ -452,8 +499,12 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, station := range uids.SpksIds[data.Id].CentralizedStations {
|
for _, station := range uids.SpksIds[data.Id].CentralizedStations {
|
||||||
if station.StationName == stationCode {
|
interlockCode := stationMap[station.Common.Id]
|
||||||
|
if interlockCode != 0 {
|
||||||
|
frame := getFrame(interlockCode)
|
||||||
|
frame.SPKSStates = append(frame.SPKSStates, &SPKSState{Id: uint16(data.Index)})
|
||||||
table.SpksMap[uint16(data.Index)] = &Row{
|
table.SpksMap[uint16(data.Index)] = &Row{
|
||||||
|
interlockCode: interlockCode,
|
||||||
commonId: data.Id,
|
commonId: data.Id,
|
||||||
uid: uids.SpksIds[data.Id].Uid,
|
uid: uids.SpksIds[data.Id].Uid,
|
||||||
index: uint16(data.Index),
|
index: uint16(data.Index),
|
||||||
@ -464,9 +515,31 @@ func makeTable(sim *memory.VerifySimulation, stationCode string) *StationDeviceI
|
|||||||
}
|
}
|
||||||
//车库门,实际数据中数量为0
|
//车库门,实际数据中数量为0
|
||||||
//洗车机,实际数据中没有
|
//洗车机,实际数据中没有
|
||||||
return table
|
//按设备id大小排序
|
||||||
|
for _, frame := range frameSlice {
|
||||||
|
sort.Slice(frame.TurnoutStates, func(i, j int) bool {
|
||||||
|
return frame.TurnoutStates[i].Id < frame.TurnoutStates[j].Id
|
||||||
|
})
|
||||||
|
sort.Slice(frame.PsdStates, func(i, j int) bool {
|
||||||
|
return frame.PsdStates[i].Id < frame.PsdStates[j].Id
|
||||||
|
})
|
||||||
|
sort.Slice(frame.ESBStates, func(i, j int) bool {
|
||||||
|
return frame.ESBStates[i].Id < frame.ESBStates[j].Id
|
||||||
|
})
|
||||||
|
sort.Slice(frame.SignalStates, func(i, j int) bool {
|
||||||
|
return frame.SignalStates[i].Id < frame.SignalStates[j].Id
|
||||||
|
})
|
||||||
|
sort.Slice(frame.AxleSectionStates, func(i, j int) bool {
|
||||||
|
return frame.AxleSectionStates[i].Id < frame.AxleSectionStates[j].Id
|
||||||
|
})
|
||||||
|
sort.Slice(frame.SPKSStates, func(i, j int) bool {
|
||||||
|
return frame.SPKSStates[i].Id < frame.SPKSStates[j].Id
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return table, frameSlice
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceContext) runCollectTask(ctx context.Context) {
|
func (s *serviceContext) runCollectTask(ctx context.Context) {
|
||||||
@ -482,7 +555,8 @@ func (s *serviceContext) runCollectTask(ctx context.Context) {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
frame := s.collectDeviceState()
|
s.collectDeviceState()
|
||||||
|
for _, frame := range s.toInterlockFrames {
|
||||||
data := frame.encode()
|
data := frame.encode()
|
||||||
_, err := s.server.WriteToUdp(data, s.ioAddr)
|
_, err := s.server.WriteToUdp(data, s.ioAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -492,16 +566,16 @@ func (s *serviceContext) runCollectTask(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceContext) collectDeviceState() *ToInterlockFrame {
|
func (s *serviceContext) collectDeviceState() {
|
||||||
wd := entity.GetWorldData(s.sim.World)
|
wd := entity.GetWorldData(s.sim.World)
|
||||||
frame := &ToInterlockFrame{}
|
for _, frame := range s.toInterlockFrames {
|
||||||
frame.WaysideCode = waysideCode
|
|
||||||
frame.InterlockCode = s.deviceTable.InterlockCode
|
|
||||||
//道岔
|
//道岔
|
||||||
for _, row := range s.deviceTable.TurnoutMap {
|
for _, state := range frame.TurnoutStates {
|
||||||
|
row := s.deviceTable.TurnoutMap[state.Id]
|
||||||
entry := wd.EntityMap[row.uid]
|
entry := wd.EntityMap[row.uid]
|
||||||
tp := component.TurnoutPositionType.Get(entry)
|
tp := component.TurnoutPositionType.Get(entry)
|
||||||
var stateByte byte
|
var stateByte byte
|
||||||
@ -516,16 +590,12 @@ func (s *serviceContext) collectDeviceState() *ToInterlockFrame {
|
|||||||
stateByte = 0x08
|
stateByte = 0x08
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
frame.TurnoutStates = append(frame.TurnoutStates, &TurnoutState{
|
|
||||||
Id: row.index,
|
state.State = stateByte
|
||||||
State: stateByte,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
sort.Slice(frame.TurnoutStates, func(i, j int) bool {
|
|
||||||
return frame.TurnoutStates[i].Id < frame.TurnoutStates[j].Id
|
|
||||||
})
|
|
||||||
//屏蔽门
|
//屏蔽门
|
||||||
for _, row := range s.deviceTable.PsdMap {
|
for _, state := range frame.PsdStates {
|
||||||
|
row := s.deviceTable.PsdMap[state.Id]
|
||||||
entry := wd.EntityMap[row.uid]
|
entry := wd.EntityMap[row.uid]
|
||||||
psdState := component.PsdStateType.Get(entry)
|
psdState := component.PsdStateType.Get(entry)
|
||||||
mkxBytes := make([]byte, 0, 3)
|
mkxBytes := make([]byte, 0, 3)
|
||||||
@ -535,11 +605,11 @@ func (s *serviceContext) collectDeviceState() *ToInterlockFrame {
|
|||||||
}
|
}
|
||||||
mkxBytes = append(mkxBytes, GetStateByte(component.BitStateType.Get(wd.EntityMap[mkxRelayUid]).Val))
|
mkxBytes = append(mkxBytes, GetStateByte(component.BitStateType.Get(wd.EntityMap[mkxRelayUid]).Val))
|
||||||
}
|
}
|
||||||
var state byte
|
var stateByte byte
|
||||||
if psdState.Close {
|
if psdState.Close {
|
||||||
state = 0x02
|
stateByte = 0x02
|
||||||
} else {
|
} else {
|
||||||
state = 0x01
|
stateByte = 0x01
|
||||||
}
|
}
|
||||||
var hsjc byte
|
var hsjc byte
|
||||||
if psdState.InterlockRelease {
|
if psdState.InterlockRelease {
|
||||||
@ -547,113 +617,90 @@ func (s *serviceContext) collectDeviceState() *ToInterlockFrame {
|
|||||||
} else {
|
} else {
|
||||||
hsjc = 0xee
|
hsjc = 0xee
|
||||||
}
|
}
|
||||||
frame.PsdStates = append(frame.PsdStates, &PSDState{
|
|
||||||
Id: row.index,
|
state.State = stateByte
|
||||||
State: state,
|
state.Hsjc = hsjc
|
||||||
Hsjc: hsjc,
|
state.PCB = mkxBytes[0]
|
||||||
PCB: mkxBytes[0],
|
state.POB = mkxBytes[1]
|
||||||
POB: mkxBytes[1],
|
state.DPB = mkxBytes[2]
|
||||||
DPB: mkxBytes[2],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
sort.Slice(frame.PsdStates, func(i, j int) bool {
|
|
||||||
return frame.PsdStates[i].Id < frame.PsdStates[j].Id
|
|
||||||
})
|
|
||||||
//紧急停车
|
//紧急停车
|
||||||
for _, row := range s.deviceTable.EsbMap {
|
for _, state := range frame.ESBStates {
|
||||||
|
row := s.deviceTable.EsbMap[state.Id]
|
||||||
esb := s.sim.Repo.FindEsb(row.uid)
|
esb := s.sim.Repo.FindEsb(row.uid)
|
||||||
relay := wd.EntityMap[esb.RelayId()]
|
relay := wd.EntityMap[esb.RelayId()]
|
||||||
pla := wd.EntityMap[esb.PlaId()]
|
pla := wd.EntityMap[esb.PlaId()]
|
||||||
frame.ESBStates = append(frame.ESBStates, &ESBState{
|
|
||||||
Id: row.index,
|
state.State = GetStateByte(!component.BitStateType.Get(relay).Val)
|
||||||
State: GetStateByte(!component.BitStateType.Get(relay).Val),
|
state.PlState = GetStateByte(component.BitStateType.Get(pla).Val)
|
||||||
PlState: GetStateByte(component.BitStateType.Get(pla).Val),
|
|
||||||
//PlState: 0x00,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
sort.Slice(frame.ESBStates, func(i, j int) bool {
|
////信号机
|
||||||
return frame.ESBStates[i].Id < frame.ESBStates[j].Id
|
//for _, state := range frame.SignalStates {
|
||||||
})
|
// row := s.deviceTable.SignalMap[state.Id]
|
||||||
//信号机
|
// entry := wd.EntityMap[row.uid]
|
||||||
for _, row := range s.deviceTable.SignalMap {
|
// lights := component.SignalLightsType.Get(entry)
|
||||||
entry := wd.EntityMap[row.uid]
|
// isL := false
|
||||||
lights := component.SignalLightsType.Get(entry)
|
// isH := false
|
||||||
isL := false
|
// isU := false
|
||||||
isH := false
|
// isA := false
|
||||||
isU := false
|
// isB := false
|
||||||
isA := false
|
// for _, light := range lights.Lights {
|
||||||
isB := false
|
// switch {
|
||||||
for _, light := range lights.Lights {
|
// case light.HasComponent(component.LdTag):
|
||||||
switch {
|
// isL = component.BitStateType.Get(light).Val
|
||||||
case light.HasComponent(component.LdTag):
|
// case light.HasComponent(component.HdTag):
|
||||||
isL = component.BitStateType.Get(light).Val
|
// isH = component.BitStateType.Get(light).Val
|
||||||
case light.HasComponent(component.HdTag):
|
// case light.HasComponent(component.UdTag):
|
||||||
isH = component.BitStateType.Get(light).Val
|
// isU = component.BitStateType.Get(light).Val
|
||||||
case light.HasComponent(component.UdTag):
|
// case light.HasComponent(component.BdTag):
|
||||||
isU = component.BitStateType.Get(light).Val
|
// isB = component.BitStateType.Get(light).Val
|
||||||
case light.HasComponent(component.BdTag):
|
// case light.HasComponent(component.AdTag):
|
||||||
isB = component.BitStateType.Get(light).Val
|
// isA = component.BitStateType.Get(light).Val
|
||||||
case light.HasComponent(component.AdTag):
|
// }
|
||||||
isA = component.BitStateType.Get(light).Val
|
// }
|
||||||
}
|
// var stateByte byte
|
||||||
}
|
// if isH && isU {
|
||||||
var stateByte byte
|
// stateByte = 0x03
|
||||||
if isH && isU {
|
// } else {
|
||||||
stateByte = 0x03
|
// switch {
|
||||||
} else {
|
// case isL:
|
||||||
switch {
|
// stateByte = 0x04
|
||||||
case isL:
|
// case isH:
|
||||||
stateByte = 0x04
|
// stateByte = 0x01
|
||||||
case isH:
|
// case isU:
|
||||||
stateByte = 0x01
|
// stateByte = 0x02
|
||||||
case isU:
|
// case isB:
|
||||||
stateByte = 0x02
|
// stateByte = 0x08
|
||||||
case isB:
|
// case isA:
|
||||||
stateByte = 0x08
|
// stateByte = 0x09
|
||||||
case isA:
|
// }
|
||||||
stateByte = 0x09
|
// }
|
||||||
}
|
//
|
||||||
}
|
// state.State = stateByte
|
||||||
frame.SignalStates = append(frame.SignalStates, &SignalState{
|
//}
|
||||||
Id: row.index,
|
|
||||||
State: stateByte,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
sort.Slice(frame.SignalStates, func(i, j int) bool {
|
|
||||||
return frame.SignalStates[i].Id < frame.SignalStates[j].Id
|
|
||||||
})
|
|
||||||
//计轴区段
|
//计轴区段
|
||||||
for _, row := range s.deviceTable.AxleSectionMap {
|
for _, state := range frame.AxleSectionStates {
|
||||||
|
row := s.deviceTable.AxleSectionMap[state.Id]
|
||||||
entry := wd.EntityMap[row.uid]
|
entry := wd.EntityMap[row.uid]
|
||||||
sectionState := component.AxleCountingSectionStateType.Get(entry)
|
sectionState := component.AxleCountingSectionStateType.Get(entry)
|
||||||
var stateByte byte = 0x00
|
var stateByte byte = 0x00
|
||||||
if sectionState.Occupied {
|
if sectionState.Occupied {
|
||||||
stateByte = 0x40
|
stateByte = 0x40
|
||||||
}
|
}
|
||||||
frame.AxleSectionStates = append(frame.AxleSectionStates, &AxleSectionState{
|
|
||||||
Id: row.index,
|
state.State = stateByte
|
||||||
State: stateByte,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
sort.Slice(frame.AxleSectionStates, func(i, j int) bool {
|
|
||||||
return frame.AxleSectionStates[i].Id < frame.AxleSectionStates[j].Id
|
|
||||||
})
|
|
||||||
//SPKS
|
//SPKS
|
||||||
for _, row := range s.deviceTable.SpksMap {
|
for _, state := range frame.SPKSStates {
|
||||||
|
row := s.deviceTable.SpksMap[state.Id]
|
||||||
spks := s.sim.Repo.FindSpks(row.uid)
|
spks := s.sim.Repo.FindSpks(row.uid)
|
||||||
relay := wd.EntityMap[spks.Relay()]
|
relay := wd.EntityMap[spks.Relay()]
|
||||||
pla := wd.EntityMap[spks.PlaId()]
|
pla := wd.EntityMap[spks.PlaId()]
|
||||||
frame.SPKSStates = append(frame.SPKSStates, &SPKSState{
|
|
||||||
Id: row.index,
|
state.State = GetStateByte(!component.BitStateType.Get(relay).Val)
|
||||||
State: GetStateByte(!component.BitStateType.Get(relay).Val),
|
state.PlState = GetStateByte(component.BitStateType.Get(pla).Val)
|
||||||
PlState: GetStateByte(component.BitStateType.Get(pla).Val),
|
}
|
||||||
//PlState: 0xff,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
sort.Slice(frame.SPKSStates, func(i, j int) bool {
|
|
||||||
return frame.SPKSStates[i].Id < frame.SPKSStates[j].Id
|
|
||||||
})
|
|
||||||
return frame
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func logger() *slog.Logger {
|
func logger() *slog.Logger {
|
||||||
|
7
third_party/message/dynamics_http.go
vendored
7
third_party/message/dynamics_http.go
vendored
@ -21,8 +21,13 @@ type LineBaseInfo struct {
|
|||||||
LinkList []*Link `json:"linkList"`
|
LinkList []*Link `json:"linkList"`
|
||||||
SlopeList []*Slope `json:"slopeList"`
|
SlopeList []*Slope `json:"slopeList"`
|
||||||
CurveList []*Curve `json:"curveList"`
|
CurveList []*Curve `json:"curveList"`
|
||||||
|
StopPosition []*StopPosition `json:"stopPositionList"`
|
||||||
|
}
|
||||||
|
type StopPosition struct {
|
||||||
|
Id int32 `json:"id"`
|
||||||
|
LinkId int32 `json:"linkId"`
|
||||||
|
LinkOffset int32 `json:"linkOffset"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Link struct {
|
type Link struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
//长度 mm
|
//长度 mm
|
||||||
|
@ -20,10 +20,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type BtmVobcManage interface {
|
type BtmVobcManage interface {
|
||||||
|
SemiPhysicalBaseManager
|
||||||
GetBtmVobcConfig() config.BtmVobcConfig
|
GetBtmVobcConfig() config.BtmVobcConfig
|
||||||
|
|
||||||
GetAllTrain() []*state_proto.TrainState
|
//GetAllTrain() []*state_proto.TrainState
|
||||||
GetConnVobcTrain() *state_proto.TrainState
|
|
||||||
}
|
}
|
||||||
type BtmVobcService interface {
|
type BtmVobcService interface {
|
||||||
Start(btmVobcManage BtmVobcManage)
|
Start(btmVobcManage BtmVobcManage)
|
||||||
@ -57,13 +58,13 @@ func BtmDefault() BtmVobcService {
|
|||||||
func (b *BtmVobcClient) Start(btmVobcManage BtmVobcManage) {
|
func (b *BtmVobcClient) Start(btmVobcManage BtmVobcManage) {
|
||||||
cfg := btmVobcManage.GetBtmVobcConfig()
|
cfg := btmVobcManage.GetBtmVobcConfig()
|
||||||
if !cfg.Open {
|
if !cfg.Open {
|
||||||
slog.Info("11号线 btm vobc配置未开启...")
|
slog.Info("11号线 btm 配置未开启...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
udpServer := udp.NewServer(fmt.Sprintf("%v:%d", cfg.LocalUdpIp, cfg.LocalUdpPort), b.handleBtmVobcFrames)
|
udpServer := udp.NewServer(fmt.Sprintf("%v:%d", cfg.LocalUdpIp, cfg.LocalUdpPort), b.handleBtmVobcFrames)
|
||||||
err := udpServer.Listen()
|
err := udpServer.Listen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("11号线 btm VOBC 服务启动失败...")
|
slog.Error("11号线 btm 服务启动失败...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//
|
//
|
@ -2,6 +2,7 @@ package semi_physical_train
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"joylink.club/bj-rtsts-server/config"
|
"joylink.club/bj-rtsts-server/config"
|
||||||
@ -20,10 +21,14 @@ type SemiPhysicalTrain interface {
|
|||||||
// 发送列车控制消息
|
// 发送列车控制消息
|
||||||
SendTrainControlMessage(info *message.DynamicsTrainInfo)
|
SendTrainControlMessage(info *message.DynamicsTrainInfo)
|
||||||
}
|
}
|
||||||
|
type SemiPhysicalBaseManager interface {
|
||||||
|
GetConnVobcTrain() *state_proto.TrainState
|
||||||
|
}
|
||||||
type SemiPhysicalMessageManager interface {
|
type SemiPhysicalMessageManager interface {
|
||||||
|
SemiPhysicalBaseManager
|
||||||
// 处理半实物仿真列车控制消息
|
// 处理半实物仿真列车控制消息
|
||||||
HandleSemiPhysicalTrainControlMsg(b []byte)
|
HandleSemiPhysicalTrainControlMsg(b []byte)
|
||||||
|
HandleSemiPhysicalTrainControlMsg2(b []byte)
|
||||||
// 获取半实物启动参数
|
// 获取半实物启动参数
|
||||||
GetSemiPhysicalRunConfig() *config.VobcConfig
|
GetSemiPhysicalRunConfig() *config.VobcConfig
|
||||||
}
|
}
|
||||||
@ -88,6 +93,7 @@ func (s *semiPhysicalTrainImpl) Start(manager SemiPhysicalMessageManager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *semiPhysicalTrainImpl) Stop() {
|
func (s *semiPhysicalTrainImpl) Stop() {
|
||||||
|
|
||||||
initMutex.Lock()
|
initMutex.Lock()
|
||||||
defer initMutex.Unlock()
|
defer initMutex.Unlock()
|
||||||
s.udpDelayRecorder.Stop()
|
s.udpDelayRecorder.Stop()
|
||||||
|
95
third_party/train_pc_sim/train_pc_sim.go
vendored
95
third_party/train_pc_sim/train_pc_sim.go
vendored
@ -30,8 +30,7 @@ type TrainPcSim interface {
|
|||||||
|
|
||||||
// SendDriverActive Deprecated 发送驾驶端激活
|
// SendDriverActive Deprecated 发送驾驶端激活
|
||||||
//SendDriverActive(train *state_proto.TrainState)
|
//SendDriverActive(train *state_proto.TrainState)
|
||||||
// SendHandleSwitch 发送牵引制动手柄
|
|
||||||
SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, train *state_proto.TrainState)
|
|
||||||
// SendTrainDirection 列车运行方向
|
// SendTrainDirection 列车运行方向
|
||||||
//因文档说明不清楚,在调用的时候目前是注释状态,现场调试可能会用到
|
//因文档说明不清楚,在调用的时候目前是注释状态,现场调试可能会用到
|
||||||
SendTrainDirection(train *state_proto.TrainState, trainForward, trainBackward bool)
|
SendTrainDirection(train *state_proto.TrainState, trainForward, trainBackward bool)
|
||||||
@ -127,20 +126,9 @@ func (d *trainPcSimService) findTrainConnForPort2(sta *state_proto.TrainState, t
|
|||||||
return rd, nil
|
return rd, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("")
|
return nil, fmt.Errorf("未找到对应端口的列车 对应的端口:%v", trainClientPort.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *trainPcSimService) findTrainConn(sta *state_proto.TrainState) (*TrainPcReciverData, error) {
|
|
||||||
rds := d.newPcSimclientMap3[sta.ConnState.TypeName]
|
|
||||||
if rds == nil {
|
|
||||||
return nil, fmt.Errorf("")
|
|
||||||
}
|
|
||||||
if sta.VobcState.Tc1Active {
|
|
||||||
return rds[0], nil
|
|
||||||
} else {
|
|
||||||
return rds[1], nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (d *trainPcSimService) findTrainAllConn(sta *state_proto.TrainState) []*TrainPcReciverData {
|
func (d *trainPcSimService) findTrainAllConn(sta *state_proto.TrainState) []*TrainPcReciverData {
|
||||||
rds := d.newPcSimclientMap3[sta.ConnState.TypeName]
|
rds := d.newPcSimclientMap3[sta.ConnState.TypeName]
|
||||||
return rds
|
return rds
|
||||||
@ -190,14 +178,13 @@ func (d *trainPcSimService) TrainPluseCount(sta *state_proto.TrainState, h1, h2,
|
|||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
//slog.Info(fmt.Sprintf("接受列车速度:%v", h1))
|
||||||
for _, sd := range d.findTrainAllConn(sta) {
|
for _, sd := range d.findTrainAllConn(sta) {
|
||||||
if sd.speedPlace != nil {
|
if sd.speedPlace != nil {
|
||||||
sd.speedPlace.PulseCount1 += sta.DynamicState.Displacement
|
sd.speedPlace.PulseCount1 += sta.DynamicState.Displacement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, pc := range sta.PulseCountMap {
|
for _, pc := range sta.PulseCountMap {
|
||||||
|
|
||||||
if sta.TrainRunUp {
|
if sta.TrainRunUp {
|
||||||
if sta.TrainEndsA.SpeedSensorEnableA || sta.TrainEndsA.SpeedSensorEnableB {
|
if sta.TrainEndsA.SpeedSensorEnableA || sta.TrainEndsA.SpeedSensorEnableB {
|
||||||
pc.PulseCount1 = pluseCountSpeed(sta.WheelDiameter, h1)
|
pc.PulseCount1 = pluseCountSpeed(sta.WheelDiameter, h1)
|
||||||
@ -219,12 +206,15 @@ func (d *trainPcSimService) trainPluseCountReset(pc *state_proto.SensorSpeedPuls
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *trainPcSimService) newCloseAllConn() {
|
func (d *trainPcSimService) newCloseAllConn() {
|
||||||
|
if d.trainPcSimManage != nil {
|
||||||
trains := d.trainPcSimManage.GetConnTrain2()
|
trains := d.trainPcSimManage.GetConnTrain2()
|
||||||
for _, train := range trains {
|
for _, train := range trains {
|
||||||
d.CreateOrRemoveTrain(train, false)
|
d.CreateOrRemoveTrain(train, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (d *trainPcSimService) newCloseConn(clientKey string) {
|
func (d *trainPcSimService) newCloseConn(clientKey string) {
|
||||||
rds := d.newPcSimclientMap3[clientKey]
|
rds := d.newPcSimclientMap3[clientKey]
|
||||||
if rds != nil {
|
if rds != nil {
|
||||||
@ -271,7 +261,6 @@ func (d *trainPcSimService) initConn2(clientKey string) error {
|
|||||||
return sys_error.New(fmt.Sprintf("配置:%v 端口B连接失败", clientKey))
|
return sys_error.New(fmt.Sprintf("配置:%v 端口B连接失败", clientKey))
|
||||||
}
|
}
|
||||||
if rd1.success {
|
if rd1.success {
|
||||||
//rd1.aPort = true
|
|
||||||
rd1.RealTrainPort = state_proto.TrainState_PORT_A
|
rd1.RealTrainPort = state_proto.TrainState_PORT_A
|
||||||
}
|
}
|
||||||
if rd2.success {
|
if rd2.success {
|
||||||
@ -291,7 +280,6 @@ func (d *trainPcSimService) connServer(open bool, ip string, port uint32, rd *Tr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
addr := fmt.Sprintf("%v:%v", ip, port)
|
addr := fmt.Sprintf("%v:%v", ip, port)
|
||||||
//slog.Info(addr, "连接.,...")
|
|
||||||
client2, err := tcp.StartTcpClient(addr, rd.receiverDataHandle, rd.readError)
|
client2, err := tcp.StartTcpClient(addr, rd.receiverDataHandle, rd.readError)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sys_error.New(fmt.Sprintf("车载atp连接失败,add:%v ,message:%v", addr, err))
|
return sys_error.New(fmt.Sprintf("车载atp连接失败,add:%v ,message:%v", addr, err))
|
||||||
@ -305,7 +293,7 @@ func (d *trainPcSimService) connServer(open bool, ip string, port uint32, rd *Tr
|
|||||||
func (d *trainPcSimService) Start(pcSimManage TrainPcSimManage) {
|
func (d *trainPcSimService) Start(pcSimManage TrainPcSimManage) {
|
||||||
|
|
||||||
configs := pcSimManage.GetTrainPcSimConfig()
|
configs := pcSimManage.GetTrainPcSimConfig()
|
||||||
//d.newPcSimclientMap = make(map[string]*TrainPcReciverData)
|
|
||||||
d.newPcSimclientMap3 = make(map[string][]*TrainPcReciverData)
|
d.newPcSimclientMap3 = make(map[string][]*TrainPcReciverData)
|
||||||
if len(configs) <= 0 {
|
if len(configs) <= 0 {
|
||||||
slog.Info("车载pc仿真配置未开启")
|
slog.Info("车载pc仿真配置未开启")
|
||||||
@ -325,8 +313,6 @@ func (d *trainPcSimService) Start(pcSimManage TrainPcSimManage) {
|
|||||||
pcReceivers[i] = pcReciver
|
pcReceivers[i] = pcReciver
|
||||||
}
|
}
|
||||||
d.newPcSimclientMap3[ck] = pcReceivers
|
d.newPcSimclientMap3[ck] = pcReceivers
|
||||||
//d.newPcSimclientMap[ck] = pcReciver
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if closedCount == len(configs) {
|
if closedCount == len(configs) {
|
||||||
@ -370,22 +356,18 @@ func (d *trainPcSimService) CreateOrRemoveTrain(train *state_proto.TrainState, i
|
|||||||
}
|
}
|
||||||
msg := &message.TrainPcSimBaseMessage{Data: data, Type: message.RECIVE_TRAIN_CREATE_REMOVE}
|
msg := &message.TrainPcSimBaseMessage{Data: data, Type: message.RECIVE_TRAIN_CREATE_REMOVE}
|
||||||
rds := d.newPcSimclientMap3[clientKey]
|
rds := d.newPcSimclientMap3[clientKey]
|
||||||
if rds != nil {
|
|
||||||
for index, rd := range rds {
|
for index, rd := range rds {
|
||||||
|
slog.Info(fmt.Sprintf("index%v---rd client:%v clientnil :%v,succ:%v", index, rd.tcpClient, rd.tcpClient == nil, rd.success))
|
||||||
if rd != nil && rd.success {
|
if rd != nil && rd.success {
|
||||||
slog.Info(fmt.Sprintf("index%v---rd client:%v clientnil :%v", index, rd.tcpClient, rd.tcpClient == nil))
|
|
||||||
initTrainErr := d.initTrain(rd, train, isCreate, msg)
|
initTrainErr := d.initTrain(rd, train, isCreate, msg)
|
||||||
if !isCreate {
|
|
||||||
d.newCloseConn(clientKey)
|
|
||||||
}
|
|
||||||
if initTrainErr != nil {
|
if initTrainErr != nil {
|
||||||
return initTrainErr
|
return initTrainErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if !isCreate {
|
||||||
|
d.newCloseConn(clientKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (d *trainPcSimService) initTrain(rd *TrainPcReciverData, train *state_proto.TrainState, isCreate bool, trains *message.TrainPcSimBaseMessage) error {
|
func (d *trainPcSimService) initTrain(rd *TrainPcReciverData, train *state_proto.TrainState, isCreate bool, trains *message.TrainPcSimBaseMessage) error {
|
||||||
@ -438,10 +420,12 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
|||||||
|
|
||||||
trains := d.trainPcSimManage.GetConnTrain2()
|
trains := d.trainPcSimManage.GetConnTrain2()
|
||||||
for _, train := range trains {
|
for _, train := range trains {
|
||||||
if train.ConnState.Conn {
|
|
||||||
for numKey, pc := range train.PulseCountMap {
|
for numKey, pc := range train.PulseCountMap {
|
||||||
trainPort := state_proto.TrainState_TrainPort(numKey)
|
trainPort := state_proto.TrainState_TrainPort(numKey)
|
||||||
trainClient, _ := d.findTrainConnForPort2(train, trainPort)
|
trainClient, _ := d.findTrainConnForPort2(train, trainPort)
|
||||||
|
if trainClient == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if trainClient.success {
|
if trainClient.success {
|
||||||
if trainClient.speedPlace == nil || trainClient.tcpClient == nil {
|
if trainClient.speedPlace == nil || trainClient.tcpClient == nil {
|
||||||
slog.Error(fmt.Sprintf("pc仿真速度位置脉冲对象为空 列车id:%v", train.Id))
|
slog.Error(fmt.Sprintf("pc仿真速度位置脉冲对象为空 列车id:%v", train.Id))
|
||||||
@ -450,13 +434,18 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
|||||||
if trainClient.ConnError() {
|
if trainClient.ConnError() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
/*ds := &strings.Builder{}
|
||||||
|
for i, s := range pc.PulseCount3 {
|
||||||
|
ds.WriteString(fmt.Sprintf("i:%v,s:%v ", i, s))
|
||||||
|
}
|
||||||
|
slog.Info(fmt.Sprintf("列车速度统计 列车id:%v 列车方向:%v ,列车速度信息:%v", train.Id, trainClient.RealTrainPort.String(), ds.String()))*/
|
||||||
s1, speed := d.pluseSpeed(pc, train.WheelDiameter)
|
s1, speed := d.pluseSpeed(pc, train.WheelDiameter)
|
||||||
runDir := d.trainDirection(speed, train, trainClient.RealTrainPort)
|
runDir := d.trainDirection(speed, train, trainClient.RealTrainPort)
|
||||||
disPluse := pluseCountSpeed(train.WheelDiameter, trainClient.speedPlace.PulseCount1)
|
disPluse := pluseCountSpeed(train.WheelDiameter, trainClient.speedPlace.PulseCount1)
|
||||||
data := trainClient.speedPlace.Encode(runDir, s1, disPluse)
|
data := trainClient.speedPlace.Encode(runDir, s1, disPluse)
|
||||||
bm := &message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_LOCATION_INFO, Data: data}
|
bm := &message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_LOCATION_INFO, Data: data}
|
||||||
dataCode := bm.Encode()
|
dataCode := bm.Encode()
|
||||||
slog.Info(fmt.Sprintf("发送列车速度位置,列车:%v,列车服务端:%v,列车速度:%v,计数脉冲: %v,累计里程: %v ,发送数据:%X", train.Id, trainClient.RealTrainPort.String(), speed, s1, trainClient.speedPlace.PulseCount1, dataCode))
|
//slog.Info(fmt.Sprintf("发送列车速度位置,列车:%v,列车服务端:%v,列车速度:%v,计数脉冲: %v,累计里程: %v ,发送数据:%X", train.Id, trainClient.RealTrainPort.String(), speed, s1, trainClient.speedPlace.PulseCount1, dataCode))
|
||||||
err := trainClient.tcpClient.Send(dataCode)
|
err := trainClient.tcpClient.Send(dataCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("发送列车速度位置失败,列车:%v,发送数据:%v", train.Id, hex.EncodeToString(dataCode)))
|
slog.Error(fmt.Sprintf("发送列车速度位置失败,列车:%v,发送数据:%v", train.Id, hex.EncodeToString(dataCode)))
|
||||||
@ -466,7 +455,6 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (d *trainPcSimService) trainDirection(speed float32, train *state_proto.TrainState, clientPort state_proto.TrainState_TrainPort) uint16 {
|
func (d *trainPcSimService) trainDirection(speed float32, train *state_proto.TrainState, clientPort state_proto.TrainState_TrainPort) uint16 {
|
||||||
runDir := uint16(2)
|
runDir := uint16(2)
|
||||||
@ -490,50 +478,9 @@ func (d *trainPcSimService) trainDirection(speed float32, train *state_proto.Tra
|
|||||||
return runDir
|
return runDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, train *state_proto.TrainState) {
|
|
||||||
trainClient, trainDataErr := d.findTrainConn(train)
|
|
||||||
if trainDataErr != nil {
|
|
||||||
slog.Error(fmt.Sprintf("发送列车牵引失败,未找到对应的列车id:%v", train.Id))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tc := train.ConnState
|
|
||||||
if tc.Conn {
|
|
||||||
vobc := train.VobcState
|
|
||||||
msg := &message.TrainPcSimBaseMessage{}
|
|
||||||
newTraction := vobc.TractionForce
|
|
||||||
if tractionState {
|
|
||||||
if newTraction <= oldTraction && newTraction <= 0 {
|
|
||||||
//手柄取消前进
|
|
||||||
msg.Type = message.RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD
|
|
||||||
} else {
|
|
||||||
//手柄前进
|
|
||||||
msg.Type = message.SENDER_TRAIN_HAND_KEY_FORWARD
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/*if newBrake >= newOldBrakeForce && newBrake == 0 {
|
|
||||||
//手柄取消后退
|
|
||||||
msg.Type = message.RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD
|
|
||||||
} else if newBrake < newOldBrakeForce {
|
|
||||||
//手柄后退
|
|
||||||
msg.Type = message.RECIVE_TRAIN_HAND_KEY_BACKWARD
|
|
||||||
} else {
|
|
||||||
//手柄后退
|
|
||||||
msg.Type = message.RECIVE_TRAIN_HAND_KEY_BACKWARD
|
|
||||||
}*/
|
|
||||||
msg.Type = message.RECIVE_TRAIN_HAND_KEY_BACKWARD
|
|
||||||
}
|
|
||||||
da := msg.Encode()
|
|
||||||
//slog.Info("发送列车手柄消息", "msg", hex.EncodeToString(da))
|
|
||||||
err := trainClient.tcpClient.Send(da)
|
|
||||||
//err := client.Send(da)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("发送列车手柄消息失败", "msg", hex.EncodeToString(da))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (d *trainPcSimService) SendTrainDirection(train *state_proto.TrainState, trainForward, trainBackward bool) {
|
func (d *trainPcSimService) SendTrainDirection(train *state_proto.TrainState, trainForward, trainBackward bool) {
|
||||||
trainClient, trainDataErr := d.findTrainConn(train)
|
//trainClient, trainDataErr := d.findTrainConn(train)
|
||||||
|
trainClient, trainDataErr := d.findTrainConnForPort2(train, train.TrainPort)
|
||||||
if trainDataErr != nil {
|
if trainDataErr != nil {
|
||||||
slog.Error(fmt.Sprintf("发送列车方向失败,未找到列车连接,trainId:%s", train.Id))
|
slog.Error(fmt.Sprintf("发送列车方向失败,未找到列车连接,trainId:%s", train.Id))
|
||||||
return
|
return
|
||||||
|
@ -155,9 +155,10 @@ func TrainConnTypeUpdate(vs *VerifySimulation, ct *dto.TrainConnThirdDto) {
|
|||||||
allTrainMap.Range(func(k, v any) bool {
|
allTrainMap.Range(func(k, v any) bool {
|
||||||
tmpTrain := v.(*state_proto.TrainState)
|
tmpTrain := v.(*state_proto.TrainState)
|
||||||
connState := tmpTrain.ConnState
|
connState := tmpTrain.ConnState
|
||||||
if connState.Conn {
|
|
||||||
|
if connState.Conn && connState.TypeName == ct.TypeName {
|
||||||
connTypeName := "半实物"
|
connTypeName := "半实物"
|
||||||
if connState.ConnType == state_proto.TrainConnState_PC_SIM && connState.TypeName == ct.TypeName {
|
if connState.ConnType == state_proto.TrainConnState_PC_SIM {
|
||||||
connTypeName = fmt.Sprintf("车载pc仿真-%v", ct.TypeName)
|
connTypeName = fmt.Sprintf("车载pc仿真-%v", ct.TypeName)
|
||||||
}
|
}
|
||||||
panic(sys_error.New(fmt.Sprintf("列车[%s]已经连接 [%v],此列车无法连接", k, connTypeName)))
|
panic(sys_error.New(fmt.Sprintf("列车[%s]已经连接 [%v],此列车无法连接", k, connTypeName)))
|
||||||
@ -308,6 +309,7 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
|||||||
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)
|
||||||
|
//slog.Info("收到动力学原始速度信息", "速度:", info.Speed, "加速度:", info.Acceleration, "位移:", info.Displacement)
|
||||||
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
||||||
|
|
||||||
outLinkId, id, port, outLinkOffset, offset, kilometer, e1 := CalcInitializeLink(vs, inLinkId, inLinkOffset, info.Up)
|
outLinkId, id, port, outLinkOffset, offset, kilometer, e1 := CalcInitializeLink(vs, inLinkId, inLinkOffset, info.Up)
|
||||||
@ -336,6 +338,8 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
|||||||
}
|
}
|
||||||
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
||||||
// 修改world中的列车位置
|
// 修改world中的列车位置
|
||||||
|
|
||||||
|
//slog.Debug("处理动力学转换后的消息", "number", info.Number, "up", info.Up, "Link", info.Link, "车头位置", id, "偏移", offset, "车尾位置:", tailDeviceId, "车尾偏移:", tailOffset, "车头linkOffset:", outLinkOffset, "车位linkOffset:", tailLinkOffset)
|
||||||
handleTrainPositionFromDynamic(vs, info, sta, outLinkId, outLinkOffset, tailLinkId, tailLinkOffset)
|
handleTrainPositionFromDynamic(vs, info, sta, outLinkId, outLinkOffset, tailLinkId, tailLinkOffset)
|
||||||
//修改列车激活方向
|
//修改列车激活方向
|
||||||
updateTrainActiveDirFromDynamic(vs, info, sta, id, port, trainHeadActUp)
|
updateTrainActiveDirFromDynamic(vs, info, sta, id, port, trainHeadActUp)
|
||||||
@ -459,7 +463,7 @@ func pluseCount(sta *state_proto.TrainState, h1, h2, t1, t2 float32) {
|
|||||||
train_pc_sim.Default().TrainPluseCount(sta, h1, h2, t1, t2)
|
train_pc_sim.Default().TrainPluseCount(sta, h1, h2, t1, t2)
|
||||||
|
|
||||||
}
|
}
|
||||||
func RemoveAllTrain(vs *VerifySimulation) {
|
func RemoveAllTrain(vs *VerifySimulation, realRemove bool) {
|
||||||
allTrainMap := &vs.Memory.Status.TrainStateMap
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
||||||
if allTrainMap == nil {
|
if allTrainMap == nil {
|
||||||
slog.Info("当前没有列车不能执行")
|
slog.Info("当前没有列车不能执行")
|
||||||
@ -467,7 +471,7 @@ func RemoveAllTrain(vs *VerifySimulation) {
|
|||||||
}
|
}
|
||||||
allTrainMap.Range(func(k any, t any) bool {
|
allTrainMap.Range(func(k any, t any) bool {
|
||||||
id := k.(string)
|
id := k.(string)
|
||||||
RemoveTrainState(vs, id)
|
RemoveTrainState(vs, id, realRemove)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -499,18 +503,22 @@ func removeTrain(vs *VerifySimulation, trainId string, train *state_proto.TrainS
|
|||||||
return fi.RemoveTrainFromWorld(vs.World, trainId)
|
return fi.RemoveTrainFromWorld(vs.World, trainId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveTrainState(vs *VerifySimulation, id string) {
|
func RemoveTrainState(vs *VerifySimulation, id string, realRemove bool) {
|
||||||
allTrainMap := &vs.Memory.Status.TrainStateMap
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
||||||
d, ok := allTrainMap.Load(id)
|
d, ok := allTrainMap.Load(id)
|
||||||
if ok {
|
if ok {
|
||||||
t := d.(*state_proto.TrainState)
|
t := d.(*state_proto.TrainState)
|
||||||
err := removeTrain(vs, id, t)
|
err := removeTrain(vs, id, t)
|
||||||
t.VobcState.VobcBtmInfo = nil
|
t.VobcState.VobcBtmInfo = nil
|
||||||
//clearTrainVobcBtmState(vs, id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
|
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
|
||||||
}
|
}
|
||||||
|
if realRemove {
|
||||||
|
allTrainMap.Delete(id)
|
||||||
|
} else {
|
||||||
allTrainMap.Store(id, t)
|
allTrainMap.Store(id, t)
|
||||||
|
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("列车【%s】不存在", id))
|
panic(fmt.Sprintf("列车【%s】不存在", id))
|
||||||
}
|
}
|
||||||
@ -524,14 +532,3 @@ func calcTrailTailOffset(headerOffset, length int64, up bool) (calctailOffset in
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearTrainVobcBtmState(vs *VerifySimulation, id string) {
|
|
||||||
//allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
||||||
//d, ok := allTrainMap.Load(id)
|
|
||||||
//if !ok {
|
|
||||||
// slog.Error(fmt.Sprintf("vobc btm 清空操作 列车【%s】不存在", id))
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//t := d.(*state_proto.TrainState)
|
|
||||||
//t.VobcBtm.History = nil
|
|
||||||
}
|
|
||||||
|
@ -372,6 +372,13 @@ func (s *VerifySimulation) GetDynamicsRunRepository() *message.LineBaseInfo {
|
|||||||
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
|
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
|
||||||
curve.EndLinkId = int32(endLinkId)
|
curve.EndLinkId = int32(endLinkId)
|
||||||
}
|
}
|
||||||
|
for _, sp := range s.Repo.StopPosition {
|
||||||
|
id, _ := strconv.Atoi(sp.Id())
|
||||||
|
linkId, _ := strconv.Atoi(sp.LinkPosition().Link().Id())
|
||||||
|
linkOffset := sp.LinkPosition().Offset()
|
||||||
|
d := &message.StopPosition{Id: int32(id), LinkId: int32(linkId), LinkOffset: int32(linkOffset)}
|
||||||
|
info.StopPosition = append(info.StopPosition, d)
|
||||||
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,34 +387,6 @@ func speedParse(speed float32) int32 {
|
|||||||
return int32(math.Abs(float64(speed * 3.6 * 100)))
|
return int32(math.Abs(float64(speed * 3.6 * 100)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理半实物仿真列车控制消息
|
|
||||||
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg(b []byte) {
|
|
||||||
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
|
||||||
train := value.(*state_proto.TrainState)
|
|
||||||
if !train.Show { // 下线列车
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
connState := train.ConnState
|
|
||||||
if connState.Conn == true && connState.ConnType == state_proto.TrainConnState_VOBC {
|
|
||||||
/*trainId, err := strconv.Atoi(train.Id)
|
|
||||||
if err != nil {
|
|
||||||
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
|
||||||
}*/
|
|
||||||
// 存放至列车中
|
|
||||||
//接收半实物列车控制不单独发送动力学,由动力学统一发送
|
|
||||||
//d := append(b, uint8(trainId))
|
|
||||||
//dynamics.Default().SendTrainControlMessage(d)
|
|
||||||
controlMessage := &message.TrainControlMsg{}
|
|
||||||
controlMessage.Decode(b)
|
|
||||||
controlMessage.TrainId = train.Id
|
|
||||||
controlMessage.FromVobc = true
|
|
||||||
train.VobcState = controlMessage.ControlInfo
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg {
|
func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg {
|
||||||
cms := make([]message.TrainControlMsg, 0)
|
cms := make([]message.TrainControlMsg, 0)
|
||||||
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
||||||
@ -426,11 +405,6 @@ func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg
|
|||||||
return cms
|
return cms
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取半实物运行配置信息
|
|
||||||
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
|
|
||||||
return &s.runConfig.Vobc
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理接到的联锁消息
|
// 处理接到的联锁消息
|
||||||
func (s *VerifySimulation) HandleInterlockDriverInfo(code string, driveBytes []byte) {
|
func (s *VerifySimulation) HandleInterlockDriverInfo(code string, driveBytes []byte) {
|
||||||
wd := entity.GetWorldData(s.World)
|
wd := entity.GetWorldData(s.World)
|
||||||
@ -1151,6 +1125,17 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
}
|
}
|
||||||
repo.CheckPoints = append(repo.CheckPoints, cp)
|
repo.CheckPoints = append(repo.CheckPoints, cp)
|
||||||
}
|
}
|
||||||
|
//列车停车点
|
||||||
|
for _, sp := range storage.StopPositions {
|
||||||
|
id := GetMapElementId(sp.Common)
|
||||||
|
psp := &proto.StopPosition{Id: id, Km: convertKm(sp.KilometerSystem)}
|
||||||
|
|
||||||
|
switch sp.GetRefDev().DeviceType {
|
||||||
|
case data_proto.RelatedRef_Section:
|
||||||
|
psp.SectionId = uidsMap.PhysicalSectionIds[sp.GetRefDev().Id].Uid
|
||||||
|
}
|
||||||
|
repo.StopPosition = append(repo.StopPosition, psp)
|
||||||
|
}
|
||||||
//物理区段
|
//物理区段
|
||||||
for _, data := range storage.Section {
|
for _, data := range storage.Section {
|
||||||
var turnoutUids []string
|
var turnoutUids []string
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package memory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"joylink.club/bj-rtsts-server/config"
|
||||||
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 获取半实物运行配置信息
|
||||||
|
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
|
||||||
|
return &s.runConfig.Vobc
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理半实物仿真列车控制消息
|
||||||
|
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg(b []byte) {
|
||||||
|
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
||||||
|
train := value.(*state_proto.TrainState)
|
||||||
|
if !train.Show { // 下线列车
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
connState := train.ConnState
|
||||||
|
if connState.Conn == true && connState.ConnType == state_proto.TrainConnState_VOBC {
|
||||||
|
/*trainId, err := strconv.Atoi(train.Id)
|
||||||
|
if err != nil {
|
||||||
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
||||||
|
}*/
|
||||||
|
// 存放至列车中
|
||||||
|
//接收半实物列车控制不单独发送动力学,由动力学统一发送
|
||||||
|
//d := append(b, uint8(trainId))
|
||||||
|
//dynamics.Default().SendTrainControlMessage(d)
|
||||||
|
controlMessage := &message.TrainControlMsg{}
|
||||||
|
controlMessage.Decode(b)
|
||||||
|
controlMessage.TrainId = train.Id
|
||||||
|
controlMessage.FromVobc = true
|
||||||
|
train.VobcState = controlMessage.ControlInfo
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理半实物仿真列车控制消息
|
||||||
|
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg2(b []byte) {
|
||||||
|
//train := s.GetConnVobcTrain()
|
||||||
|
|
||||||
|
}
|
||||||
|
func aaByte1() {
|
||||||
|
|
||||||
|
}
|
@ -38,7 +38,7 @@ func ControlTrainUpdate(s *VerifySimulation, ct *request_proto.TrainControl) {
|
|||||||
sta := data.(*state_proto.TrainState)
|
sta := data.(*state_proto.TrainState)
|
||||||
vobc := sta.VobcState
|
vobc := sta.VobcState
|
||||||
tcc := sta.Tcc
|
tcc := sta.Tcc
|
||||||
if ct.ControlType != request_proto.TrainControl_DRIVER_KEY_SWITCH && vobc.Tc1Active == false && vobc.Tc2Active == false {
|
if ct.ControlType != request_proto.TrainControl_DRIVER_KEY_SWITCH && sta.TrainPort == state_proto.TrainState_PORT_NONE {
|
||||||
panic(sys_error.New("请先上驾驶端钥匙"))
|
panic(sys_error.New("请先上驾驶端钥匙"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +632,6 @@ func (s *VerifySimulation) reportTrainMockInitMsg2(driverActive, initConn bool,
|
|||||||
tce := make([]message.TrainPcSimBaseMessage, 0)
|
tce := make([]message.TrainPcSimBaseMessage, 0)
|
||||||
connErr := false
|
connErr := false
|
||||||
state := message.GetBit(data1, 3)
|
state := message.GetBit(data1, 3)
|
||||||
//slog.Info(fmt.Sprintf("act:%v ,t1:%v ,a1 :%v,t2:%v,a2:%v,init:%v,ts:%v", act, train.VobcState.Tc1Active, tcc.ActiveTrainA, train.VobcState.Tc2Active, tcc.ActiveTrainB, initConn, initTimeStamp), aport)
|
|
||||||
|
|
||||||
if message.GetBit(data3, 3) == 0 {
|
if message.GetBit(data3, 3) == 0 {
|
||||||
actt := byte(0)
|
actt := byte(0)
|
||||||
@ -671,11 +670,6 @@ func (s *VerifySimulation) reportTrainMockInitMsg2(driverActive, initConn bool,
|
|||||||
tce = append(tce, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OUTER_EMERGENCY_BRAKE, state}})
|
tce = append(tce, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OUTER_EMERGENCY_BRAKE, state}})
|
||||||
initData := s.ObtainTrainDigitalMockDataForStatus(train)
|
initData := s.ObtainTrainDigitalMockDataForStatus(train)
|
||||||
tce = append(tce, initData...)
|
tce = append(tce, initData...)
|
||||||
/* if trainClientPort == state_proto.TrainState_PORT_A {
|
|
||||||
tcc.ActiveTrainA = true
|
|
||||||
} else if trainClientPort == state_proto.TrainState_PORT_A {
|
|
||||||
tcc.ActiveTrainB = true
|
|
||||||
}*/
|
|
||||||
initConn = false
|
initConn = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,12 @@ import (
|
|||||||
"joylink.club/bj-rtsts-server/third_party/interlock/beijing12"
|
"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"
|
||||||
|
"joylink.club/rtsssimulation/fi"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"joylink.club/bj-rtsts-server/third_party/can_btm"
|
"joylink.club/bj-rtsts-server/third_party/can_btm"
|
||||||
cidcmodbus "joylink.club/bj-rtsts-server/third_party/cidc_modbus"
|
cidcmodbus "joylink.club/bj-rtsts-server/third_party/cidc_modbus"
|
||||||
@ -58,24 +60,26 @@ func CreateSimulation(projectId int32, mapIds []int32, runConfig *dto.ProjectRun
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
verifySimulation.SimulationId = simulationId
|
verifySimulation.SimulationId = simulationId
|
||||||
|
verifySimulation.ProjectCode = project.Code
|
||||||
// world构建
|
// world构建
|
||||||
err = initWorld(verifySimulation)
|
err = initWorld(verifySimulation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
// verifySimulation.Start()
|
||||||
|
// 全部成功,启动仿真
|
||||||
|
verifySimulation.World.StartUp()
|
||||||
|
// 初始化设备状态
|
||||||
|
initDeviceStatus(verifySimulation)
|
||||||
|
// 启动仿真消息服务
|
||||||
|
message_server.Start(verifySimulation)
|
||||||
// 第三方服务处理
|
// 第三方服务处理
|
||||||
err = runThirdParty(verifySimulation)
|
err = runThirdParty(verifySimulation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
verifySimulation.World.Close()
|
verifySimulation.World.Close()
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
verifySimulation.ProjectCode = project.Code
|
|
||||||
simulationMap.Store(simulationId, verifySimulation)
|
simulationMap.Store(simulationId, verifySimulation)
|
||||||
// verifySimulation.Start()
|
|
||||||
// 全部成功,启动仿真
|
|
||||||
verifySimulation.World.StartUp()
|
|
||||||
// 启动仿真消息服务
|
|
||||||
message_server.Start(verifySimulation)
|
|
||||||
}
|
}
|
||||||
return simulationId, nil
|
return simulationId, nil
|
||||||
}
|
}
|
||||||
@ -86,8 +90,9 @@ func DestroySimulation(simulationId string) {
|
|||||||
if !e {
|
if !e {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
simulationMap.Delete(simulationId)
|
|
||||||
simulationInfo := s.(*memory.VerifySimulation)
|
simulationInfo := s.(*memory.VerifySimulation)
|
||||||
|
memory.RemoveAllTrain(simulationInfo, true)
|
||||||
|
simulationMap.Delete(simulationId)
|
||||||
// simulationInfo.Destroy()
|
// simulationInfo.Destroy()
|
||||||
// 停止ecs world
|
// 停止ecs world
|
||||||
simulationInfo.World.Close()
|
simulationInfo.World.Close()
|
||||||
@ -98,6 +103,22 @@ func DestroySimulation(simulationId string) {
|
|||||||
stopThirdParty(simulationInfo)
|
stopThirdParty(simulationInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initDeviceStatus(simulation *memory.VerifySimulation) {
|
||||||
|
for _, turnout := range simulation.Repo.TurnoutList() {
|
||||||
|
err := fi.DriveTurnoutDCOn(simulation.World, turnout.Id())
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("初始驱动道岔到定位失败", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
for _, turnout := range simulation.Repo.TurnoutList() {
|
||||||
|
err := fi.DriveTurnoutDCOff(simulation.World, turnout.Id())
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("取消驱动道岔到定位失败", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 创建world
|
// 创建world
|
||||||
func initWorld(s *memory.VerifySimulation) error {
|
func initWorld(s *memory.VerifySimulation) error {
|
||||||
//创建仿真
|
//创建仿真
|
||||||
@ -172,7 +193,7 @@ func stopThirdParty(s *memory.VerifySimulation) {
|
|||||||
semi_physical_train.BtmDefault().Stop()
|
semi_physical_train.BtmDefault().Stop()
|
||||||
// 停止动力学接口功能
|
// 停止动力学接口功能
|
||||||
dynamics.Default().Stop()
|
dynamics.Default().Stop()
|
||||||
// 联锁启动
|
// 联锁通信服务停止
|
||||||
for _, c := range s.GetRunConfig().Interlocks {
|
for _, c := range s.GetRunConfig().Interlocks {
|
||||||
switch c.Line {
|
switch c.Line {
|
||||||
case "11":
|
case "11":
|
||||||
|
Loading…
Reference in New Issue
Block a user