rts-sim-testing-service/ts/simulation/wayside/memory/wayside_simulation_train_pc.go
tiger_zhou 92d21d559f
All checks were successful
local-test分支打包构建docker并发布运行 / Docker-Build (push) Successful in 1m55s
列车pc仿真调整
2024-04-16 17:26:37 +08:00

499 lines
23 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package memory
import (
"encoding/binary"
"encoding/hex"
"fmt"
"joylink.club/bj-rtsts-server/config"
"joylink.club/bj-rtsts-server/const/balise_const"
"joylink.club/bj-rtsts-server/dto/data_proto"
"joylink.club/bj-rtsts-server/dto/request_proto"
"joylink.club/bj-rtsts-server/dto/state_proto"
"joylink.club/bj-rtsts-server/sys_error"
"joylink.club/bj-rtsts-server/third_party/can_btm"
"joylink.club/bj-rtsts-server/third_party/message"
train_pc_sim "joylink.club/bj-rtsts-server/third_party/train_pc_sim"
"log/slog"
"strings"
"time"
)
func (s *VerifySimulation) GetTrainPcSimConfig() config.VehiclePCSimConfig {
return s.runConfig.PcSimConfig
}
// 列车控制
func ControlTrainUpdate(s *VerifySimulation, ct *request_proto.TrainControl) {
allTrainMap := &s.Memory.Status.TrainStateMap
data, ok := allTrainMap.Load(ct.TrainId)
if !ok {
panic(sys_error.New(fmt.Sprintf("列车【%s】不存在", ct.TrainId)))
}
tccGraphicData := findTrainTccGraphicData(s)
if tccGraphicData == nil {
slog.Error("列车控制未找到TCC图形数据")
panic(sys_error.New("未找到TCC图形数据"))
}
sta := data.(*state_proto.TrainState)
var tce []train_pc_sim.TrainControlEvent = nil
if ct.ControlType == request_proto.TrainControl_EMERGENT_BUTTON {
tce = trainControlEB(sta, ct.Button, ct.DeviceId, tccGraphicData)
} else if ct.ControlType == request_proto.TrainControl_DRIVER_KEY_SWITCH {
tce = trainControlDriverKey(sta, ct.DriverKey, ct.DeviceId, tccGraphicData)
train_pc_sim.Default().SendDriverActive(sta.ConnState, sta.VobcState)
} else if ct.ControlType == request_proto.TrainControl_DIRECTION_KEY_SWITCH {
tce = trainControlDirKey(sta, ct.DirKey, ct.DeviceId, tccGraphicData)
} else if ct.ControlType == request_proto.TrainControl_HANDLER {
oldTraction := sta.VobcState.TractionForce
oldBrakeForce := sta.VobcState.BrakeForce
isBrake := ct.Handler.Val < 0 //是否制动
tce = trainControlHandle(sta, ct.Handler, ct.DeviceId, tccGraphicData)
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isBrake, sta.ConnState, sta.VobcState)
}
if sta.ConnState.Conn && sta.ConnState.ConnType == state_proto.TrainConnState_PC_SIM && tce != nil {
train_pc_sim.Default().PublishTrainControlEvent(s.World, tce)
}
}
func trainControlEB(trainState *state_proto.TrainState, request *request_proto.TrainControl_EmergentButton, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
_, find := findTrainTccGraphicDataButton(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的紧急停车摁钮,deviceId:", deviceId)
return nil
}
trainState.VobcState.EmergencyBrakingStatus = request.Active
if trainState.Tcc.Ebutton == nil {
trainState.Tcc.Ebutton = &state_proto.TrainControlState_EmergentButton{Id: deviceId, Passed: request.Active}
} else {
trainState.Tcc.Ebutton.Passed = request.Active
}
return nil
//return []train_pc_sim.TrainControlEvent{{Command: message.KEY_STATE, Status: message.IsTrue(request.Val)}}
}
// 列车方向
func trainControlDirKey(trainState *state_proto.TrainState, request *request_proto.TrainControl_DirectionKeySwitch, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
_, find := findTrainTccGraphicDataKey(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的列车方向键deviceId:", deviceId)
return nil
}
trainState.VobcState.DirectionForward = false
trainState.VobcState.DirectionBackward = false
if request.Val == 1 {
trainState.VobcState.DirectionForward = true
} else if request.Val == 0 {
trainState.VobcState.DirectionBackward = true
}
if trainState.Tcc.DirKey == nil {
trainState.Tcc.DirKey = &state_proto.TrainControlState_DirectionKeySwitch{Id: deviceId, Val: request.Val}
} else {
trainState.Tcc.DirKey.Val = request.Val
}
return nil
}
// 列车驾驶端激活
func trainControlDriverKey(trainState *state_proto.TrainState, request *request_proto.TrainControl_DriverKeySwitch, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
obj, find := findTrainTccGraphicDataKey(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的驾驶端激活设备deviceId:", deviceId)
return nil
}
if obj.Code == "SKQYS1" {
trainState.VobcState.Tc1Active = request.Val
} else if obj.Code == "SKQYS2" {
trainState.VobcState.Tc2Active = request.Val
}
var addNew = true
for _, k := range trainState.Tcc.DriverKey {
if k.Id == deviceId {
k.Id = deviceId
k.Val = request.Val
addNew = false
break
}
}
if addNew {
trainState.Tcc.DriverKey = append(trainState.Tcc.DriverKey, &state_proto.TrainControlState_DriverKeySwitch{Id: deviceId, Val: request.Val})
}
return []train_pc_sim.TrainControlEvent{{Command: message.KEY_STATE, Status: message.IsTrue(request.Val)}}
}
// 列车牵引控制
func trainControlHandle(trainState *state_proto.TrainState, request *request_proto.TrainControl_PushHandler, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
_, find := findTrainTccGraphicDataHandler(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的牵引制动手柄设备deviceId:", deviceId)
return nil
}
trainState.VobcState.TractionStatus = false
trainState.VobcState.TractionForce = 0
trainState.VobcState.BrakingStatus = false
trainState.VobcState.BrakeForce = 0
trainState.VobcState.MaintainBrakeStatus = false
tce := make([]train_pc_sim.TrainControlEvent, 0)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 0})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 0})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_TO_ZERO, Status: 0})
if request.Val > 0 {
trainState.VobcState.TractionStatus = true
trainState.VobcState.TractionForce = int64(request.Val * 180)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 1})
} else if request.Val < 0 {
trainState.VobcState.BrakingStatus = true
trainState.VobcState.BrakeForce = int64(-request.Val * 180)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 1})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 1})
} else {
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_TO_ZERO, Status: 1})
}
if trainState.Tcc.PushHandler == nil {
trainState.Tcc.PushHandler = &state_proto.TrainControlState_PushHandler{Id: deviceId, Val: request.Val}
} else {
trainState.Tcc.PushHandler.Val = request.Val
}
return tce
}
func (s *VerifySimulation) GetConnTrain() *state_proto.TrainState {
return s.findConnTrain(state_proto.TrainConnState_PC_SIM)
}
func (s *VerifySimulation) findConnTrain(ct state_proto.TrainConnState_TrainConnType) *state_proto.TrainState {
var findTrain *state_proto.TrainState
s.Memory.Status.TrainStateMap.Range(func(k, v any) bool {
train := v.(*state_proto.TrainState)
connState := train.ConnState
if connState.ConnType == ct {
findTrain = train
return false
}
return true
})
return findTrain
}
// 4.4.1. 车载输出数字量信息报文内容
func (s *VerifySimulation) TrainPcSimDigitalOutInfoHandle(data []byte) {
train := s.findConnTrain(state_proto.TrainConnState_PC_SIM)
if train == nil {
slog.Error("车载输出数字量未找到连接车载pc仿真的列车")
return
}
if !train.ConnState.Conn {
slog.Error("车载输出数字量,,列车未连接车载pc仿真")
return
}
//buf := bytes.NewBuffer(data)
vobc := train.VobcState
//cutTraction, _ := buf.ReadByte() //切牵引
//trainDoorOutLed, _ := buf.ReadByte() //车门外指示灯
//stopBrakeAppend, _ := buf.ReadByte() //停放制动施加
//emergentBrake, _ := buf.ReadByte() //紧急制动
//leftOpenDoor, _ := buf.ReadByte() //开左门允许
//rightOpenDoor, _ := buf.ReadByte() //开右门允许
//closeRightDoor, _ := buf.ReadByte() //关右门
//doorAlwaysClosed, _ := buf.ReadByte() //车门保持关闭
//localAtpControl, _ := buf.ReadByte() //本端ATP控车
//atoMode, _ := buf.ReadByte() //ATO模式
//atoTractionCommandOut, _ := buf.ReadByte() //ATO牵引命令输出
//atoTractionCommand1, _ := buf.ReadByte() //ATO牵引指令1
//atoTractionCommand2, _ := buf.ReadByte() //ATO牵引指令2
//atoTractionCommand3, _ := buf.ReadByte() //ATO牵引指令3
//atoBrakeCommand, _ := buf.ReadByte() //ATO制动命令输出
//skipCommand, _ := buf.ReadByte() //跳跃指令
//direction1, _ := buf.ReadByte() //列车方向1
//direction2, _ := buf.ReadByte() //列车方向2
//atoLazyCommandOut, _ := buf.ReadByte() //ATO惰行命令输出
//sleepCommand, _ := buf.ReadByte() //休眠指令
//wakeUpCommand, _ := buf.ReadByte() //唤醒指令
//toPullTrainLed, _ := buf.ReadByte() //ATO发车指示灯
//arLightCommand, _ := buf.ReadByte() //AR灯命令
//atoAlwaysBrake, _ := buf.ReadByte() //ATO保持制动
//atoOpenLeftDoor, _ := buf.ReadByte() //ATO开左门
//atoOpenRightDoor, _ := buf.ReadByte() //ATO开右门
//atoCloseLeftDoor, _ := buf.ReadByte() //ATO关左门
//ariverActive, _ := buf.ReadByte() //驾驶室激活
//noSpeedSigle, _ := buf.ReadByte() //零速信号
//famMode, _ := buf.ReadByte() //FAM模式
//camMode, _ := buf.ReadByte() //CAM模式
//trainStartedLed, _ := buf.ReadByte() //列车启动指示灯
//mostUseBrake, _ := buf.ReadByte() //常用制动
//splittingOut, _ := buf.ReadByte() //过分相输出
//modeRelay, _ := buf.ReadByte() //模式继电器
//tractionEffective, _ := buf.ReadByte() //牵引有效
//brakeEffective, _ := buf.ReadByte() //制动有效
//lifeDoorUsed, _ := buf.ReadByte() //逃生门使能
//brakeQuarantine, _ := buf.ReadByte() //制动隔离
//stopNotAllBrake, _ := buf.ReadByte() //停放制动缓解
//vobc.TractionSafetyCircuit = message.IsTrueForByte(cutTraction)
//vobc.TrainDoorOutLed = message.IsTrueForByte(trainDoorOutLed) //? 说明暂无此属性
//vobc.ParkingBrakeStatus = message.IsTrueForByte(stopBrakeAppend)
//vobc.EmergencyBrakingStatus = message.IsTrueForByte(emergentBrake)
//vobc.LeftDoorOpenCommand = message.IsTrueForByte(leftOpenDoor)
//vobc.RightDoorOpenCommand = message.IsTrueForByte(rightOpenDoor)
//vobc.RightDoorCloseCommand = message.IsTrueForByte(closeRightDoor)
//vobc.AllDoorClose = message.IsTrueForByte(doorAlwaysClosed)
//vobc.LocalAtpControl = message.IsTrueForByte(localAtpControl) //?
//vobc.Ato = message.IsTrueForByte(atoMode)
//vobc.AtoTractionCommandOut = message.IsTrueForByte(atoTractionCommandOut) //?
//vobc.AtoTractionCommand1 = message.IsTrueForByte(atoTractionCommand1) //?
//vobc.AtoTractionCommand2 = message.IsTrueForByte(atoTractionCommand2) //?
//vobc.AtoTractionCommand3 = message.IsTrueForByte(atoTractionCommand3) //?
//vobc.AtoBrakeCommand = message.IsTrueForByte(atoBrakeCommand) //?
//vobc.JumpStatus = message.IsTrueForByte(skipCommand)
//vobc.DirectionForward = message.IsTrueForByte(direction1)
//vobc.DirectionBackward = message.IsTrueForByte(direction2)
//vobc.AtoLazyCommandOut = message.IsTrueForByte(atoLazyCommandOut) //?
//vobc.SleepBtn = message.IsTrueForByte(sleepCommand)
//vobc.WakeUpBtn = message.IsTrueForByte(wakeUpCommand)
//vobc.AtoSendTrainBtn = message.IsTrueForByte(toPullTrainLed)
//vobc.TurnbackStatus = message.IsTrueForByte(arLightCommand) //?
//vobc.AtoAlwaysBrake = message.IsTrueForByte(atoAlwaysBrake) //?
//vobc.AtoOpenLeftDoor = message.IsTrueForByte(atoOpenLeftDoor) //?
//vobc.AtoOpenRightDoor = message.IsTrueForByte(atoOpenRightDoor) //?
//vobc.AtoCloseLeftDoor = message.IsTrueForByte(atoCloseLeftDoor) //?
//vobc.Tc1Active = message.IsTrueForByte(ariverActive)
//vobc.NoSpeedSigle = message.IsTrueForByte(noSpeedSigle) //?
//vobc.Fam = message.IsTrueForByte(famMode)
//vobc.Cam = message.IsTrueForByte(camMode)
//vobc.TrainStartedLed = message.IsTrueForByte(trainStartedLed) //?
//vobc.MostUseBrake = message.IsTrueForByte(mostUseBrake) //? //常用制动
//vobc.SplittingOut = message.IsTrueForByte(splittingOut) //? //过分相输出
//vobc.ModeRelay = message.IsTrueForByte(modeRelay) //? //模式继电器
//vobc.TractionEffective = message.IsTrueForByte(tractionEffective) //? //牵引有效
//vobc.BrakeEffective = message.IsTrueForByte(brakeEffective) //? //制动有效
//vobc.LifeDoorState = message.IsTrueForByte(lifeDoorUsed) //逃生门使能
//vobc.BrakeQuarantine = message.IsTrueForByte(brakeQuarantine) //? //制动隔离
//vobc.StopNotAllBrake = message.IsTrueForByte(stopNotAllBrake) //? //停放制动缓解
trainPcSimDigitalOutInfoHandleCode39_32(data[0], vobc)
trainPcSimDigitalOutInfoHandleCode31_24(data[1], vobc)
trainPcSimDigitalOutInfoHandleCode23_16(data[2], vobc)
trainPcSimDigitalOutInfoHandleCode15_8(data[3], vobc)
trainPcSimDigitalOutInfoHandleCode7_0(data[4], vobc)
//cm := &message.TrainControlMsg{TrainId: train.Id, ControlInfo: vobc}
//dynamics.Default().SendTrainControl(cm)
}
func trainPcSimDigitalOutInfoHandleCode39_32(d byte, vobc *state_proto.TrainVobcState) {
vobc.MostUseBrake = message.IsTrueForByte(message.GetBit(d, 0)) //? 常用制动
vobc.SplittingOut = message.IsTrueForByte(message.GetBit(d, 1)) //? 过分相输出
vobc.ModeRelay = message.IsTrueForByte(message.GetBit(d, 2)) //? 模式继电器
vobc.TractionEffective = message.IsTrueForByte(message.GetBit(d, 3)) //? 牵引有效
vobc.BrakeEffective = message.IsTrueForByte(message.GetBit(d, 4)) //? 制动有效
vobc.LifeDoorState = message.IsTrueForByte(message.GetBit(d, 5)) //?逃生门使能
vobc.BrakeQuarantine = message.IsTrueForByte(message.GetBit(d, 6)) //? 制动隔离
vobc.StopNotAllBrake = message.IsTrueForByte(message.GetBit(d, 7)) //? 停放制动缓解
}
func trainPcSimDigitalOutInfoHandleCode31_24(d byte, vobc *state_proto.TrainVobcState) {
vobc.AtoOpenLeftDoor = message.IsTrueForByte(message.GetBit(d, 0)) //?//ATO开左门
vobc.AtoOpenRightDoor = message.IsTrueForByte(message.GetBit(d, 1)) //?//ATO开右门
vobc.AtoCloseLeftDoor = message.IsTrueForByte(message.GetBit(d, 2)) //?//ATO关左门
vobc.Tc1Active = message.IsTrueForByte(message.GetBit(d, 3)) //驾驶室激活
vobc.NoSpeedSigle = message.IsTrueForByte(message.GetBit(d, 4)) //?//零速信号
vobc.Fam = message.IsTrueForByte(message.GetBit(d, 5)) //FAM模式
vobc.Cam = message.IsTrueForByte(message.GetBit(d, 6)) //CAM模式
vobc.TrainStartedLed = message.IsTrueForByte(message.GetBit(d, 7)) //?//列车启动指示灯
}
func trainPcSimDigitalOutInfoHandleCode23_16(d byte, vobc *state_proto.TrainVobcState) {
vobc.DirectionForward = message.IsTrueForByte(message.GetBit(d, 0)) //列车方向1
vobc.DirectionBackward = message.IsTrueForByte(message.GetBit(d, 1)) //列车方向2
vobc.AtoLazyCommandOut = message.IsTrueForByte(message.GetBit(d, 2)) //?ATO惰行命令输出
vobc.SleepBtn = message.IsTrueForByte(message.GetBit(d, 3)) //?休眠指令
vobc.WakeUpBtn = message.IsTrueForByte(message.GetBit(d, 4)) //?唤醒指令
vobc.AtoSendTrainBtn = message.IsTrueForByte(message.GetBit(d, 5)) //?ATO发车指示灯
vobc.TurnbackStatus = message.IsTrueForByte(message.GetBit(d, 6)) //?AR灯命令
vobc.AtoAlwaysBrake = message.IsTrueForByte(message.GetBit(d, 7)) //? ATO保持制动
}
func trainPcSimDigitalOutInfoHandleCode15_8(d byte, vobc *state_proto.TrainVobcState) {
vobc.LocalAtpControl = message.IsTrueForByte(message.GetBit(d, 0)) //?本端ATP控车
vobc.Ato = message.IsTrueForByte(message.GetBit(d, 1)) //ATO模式
vobc.AtoTractionCommandOut = message.IsTrueForByte(message.GetBit(d, 2)) //?ATO牵引命令输出
vobc.AtoTractionCommand1 = message.IsTrueForByte(message.GetBit(d, 3)) //?ATO牵引指令1
vobc.AtoTractionCommand2 = message.IsTrueForByte(message.GetBit(d, 4)) //?ATO牵引指令2
vobc.AtoTractionCommand3 = message.IsTrueForByte(message.GetBit(d, 5)) //?ATO牵引指令3
vobc.AtoBrakeCommand = message.IsTrueForByte(message.GetBit(d, 6)) //?ATO制动命令输出
vobc.JumpStatus = message.IsTrueForByte(message.GetBit(d, 7)) //跳跃指令
}
func trainPcSimDigitalOutInfoHandleCode7_0(d byte, vobc *state_proto.TrainVobcState) {
vobc.TractionSafetyCircuit = message.IsTrueForByte(message.GetBit(d, 0)) //切牵引
vobc.TrainDoorOutLed = message.IsTrueForByte(message.GetBit(d, 1)) //? 车门外指示灯
vobc.ParkingBrakeStatus = message.IsTrueForByte(message.GetBit(d, 2)) //停放制动施加
vobc.EmergencyBrakingStatus = message.IsTrueForByte(message.GetBit(d, 3)) //紧急制动
vobc.LeftDoorOpenCommand = message.IsTrueForByte(message.GetBit(d, 4)) //开左门允许
vobc.RightDoorOpenCommand = message.IsTrueForByte(message.GetBit(d, 5)) //开右门允许
vobc.RightDoorCloseCommand = message.IsTrueForByte(message.GetBit(d, 6)) //关右门
vobc.AllDoorClose = message.IsTrueForByte(message.GetBit(d, 7)) //车门保持关闭
}
// 4.4.2. 车载输出数字反馈量信息报文内容
func (s *VerifySimulation) TrainPcSimDigitalReportHandle(data []byte) {
train := s.findConnTrain(state_proto.TrainConnState_PC_SIM)
if train == nil {
slog.Error("车载输出数字反馈量信息,未找到连接车载pc仿真的列车")
return
}
if !train.ConnState.Conn {
slog.Error("车载输出数字反馈量信息,列车未连接车载pc仿真")
return
}
vobc := train.VobcState
//buf := bytes.NewBuffer(data)
//localEndAct, _ := buf.ReadByte()
//direction1, _ := buf.ReadByte()
//direction2, _ := buf.ReadByte()
//vobc.Tc1Active = message.IsTrueForByte(localEndAct) //本端驾驶室激活(钥匙)
//vobc.DirectionForward = message.IsTrueForByte(direction1) //方向手柄进位
//vobc.DirectionBackward = message.IsTrueForByte(direction2) //方向手柄退位
buf := data[0]
vobc.Tc1Active = message.IsTrueForByte(message.GetBit(buf, 0)) //本端驾驶室激活(钥匙)
vobc.DirectionForward = message.IsTrueForByte(message.GetBit(buf, 1)) //方向手柄进位
vobc.DirectionBackward = message.IsTrueForByte(message.GetBit(buf, 2)) //方向手柄退位
}
// 创建/删除列车
func TrainPcSimConnOrRemoveHandle(train *state_proto.TrainState) {
var data byte = 0x01
if train.ConnState.Conn == false {
data = 0x00
}
train_pc_sim.Default().CreateOrRemoveTrain(train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE, []byte{data})
train_pc_sim.Default().CreateOrRemoveSpeedPLace(train)
}
// 门模式
/*func TrainDoorModeHandle(train *state_proto.TrainState) {
if !train.ConnState.Conn {
slog.Error("车载pc仿真门模式,列车未连接车载pc仿真")
return
}
switch state {
case 0x00:
//0x00表示自开自关AA
train.VobcState.DoorModeAA = true
case 0x01:
//0x01表示自开人关AM
train.VobcState.DoorModeAM = true
case 0x02:
//0x02表示人开人关MM
train.VobcState.DoorModeMM = true
}
}*/
// 4.4.3. 车载输出模拟量信息报文内容(0x03)
func (s *VerifySimulation) TrainPcSimMockInfo(data []byte) {
train := s.findConnTrain(state_proto.TrainConnState_PC_SIM)
if train == nil {
slog.Error("车载输出模拟量,未找到连接车载pc仿真的列车")
return
}
if !train.ConnState.Conn {
slog.Error("车载输出模拟量,列车未连接车载pc仿真")
return
}
mockData := binary.BigEndian.Uint16(data)
train.VobcState.MockInfo = uint32(mockData)
}
// 4.4.4. 车载输出BTM查询同步帧报文内容0x04
func (s *VerifySimulation) TrainBtmQuery(data []byte) {
if len(data) < 12 {
slog.Error("列车btm查询报文长度错误:", len(data))
return
}
train := s.findConnTrain(state_proto.TrainConnState_PC_SIM)
if train == nil {
slog.Error("车载输出btm查询,未找到连接车载pc仿真的列车")
return
}
if !train.ConnState.Conn {
slog.Error("车载输出btm查询,列车未连接车载pc仿真")
return
}
trainAtm := message.NewCanetFrame(data, true)
atpReq := &message.AtpRequestFrame{}
if !atpReq.Decode(trainAtm) {
slog.Warn("列车pc驾驶模拟-CanetFrame解码成AtpRequestFrame失败", "CanetFrame", trainAtm.String())
return
}
cl := clock(atpReq)
btmRepFrame := createBtmStatus(trainAtm.CanId.ID4, train.BtmState, atpReq, cl)
if atpReq.ResendRequest == 2 {
//重新发送
if len(train.BtmState.BaliseTelegramForPcSimResend) > 0 {
dd, _ := hex.DecodeString(train.BtmState.BaliseTelegramForPcSimResend)
train_pc_sim.Default().SendBaliseData(train_pc_sim.RECIVE_TRAIN_BTM_HAS_DATA, dd)
}
} else {
timeSyncF := message.NewBtmTimeSyncCheckFrame(trainAtm.CanId.ID4, true)
timeSyncF.T2 = cl.BtmTk
timeSyncF.T3 = cl.TkNow()
telCount := strings.Count(train.BtmState.Telegram, "00")
if telCount >= balise_const.UserTelegramByteLen {
//无数据
queryData := make([]byte, 0)
queryData = append(queryData, btmRepFrame.Encode().Encode()...)
queryData = append(queryData, timeSyncF.Encode().Encode()...)
train_pc_sim.Default().SendBaliseData(train_pc_sim.RECIVE_TRAIN_BTM_NOT_DATA, queryData)
} else {
//有数据
aliseData, _ := hex.DecodeString(train.BtmState.Telegram)
statusDataCf, statusDataCfOk := message.CreateBtmRspFramesData(btmRepFrame, aliseData, false, cl.TkNow(), cl.TkNow(), cl.TkNow(), true)
if statusDataCfOk {
queryData := make([]byte, 0)
queryData = append(queryData, btmRepFrame.Encode().Encode()...)
queryData = append(queryData, timeSyncF.Encode().Encode()...)
queryData = append(queryData, statusDataCf...) //数据帧包含结束帧
train.BtmState.BaliseTelegramForPcSimResend = fmt.Sprintf("%X", statusDataCf)
train_pc_sim.Default().SendBaliseData(train_pc_sim.RECIVE_TRAIN_BTM_HAS_DATA, queryData)
} else {
slog.Error("列车pc仿真 BtmCanetClient应答帧、数据帧编码失败")
}
}
}
}
func createBtmStatus(canIdSn byte, btmState *state_proto.BTMState, atpReq *message.AtpRequestFrame, cl can_btm.BtmClock) *message.BtmStatusRspFrame {
statusF := message.NewBtmStatusRspFrame(canIdSn, true)
//btmStatus := aa(train, atpReq)
statusF.PowerAmplifierOn = true
statusF.PowerAmplifierFailure = false
statusF.AtpReqCrcCheckWrong = !atpReq.Crc16CheckOk
statusF.AntennaFault = false
statusF.BaliseCounter = byte(btmState.BaliseCount)
statusF.MessageCounter = byte(btmState.MessageCounter)
statusF.TkTimeA = cl.TkNow()
statusF.DetailedCode = 0
if btmState.AboveBalise {
statusF.DetailedCode = 0x07
}
statusF.Dsn = byte(btmState.DataSerialNumber)
return statusF
}
func clock(atpReq *message.AtpRequestFrame) can_btm.BtmClock {
now := time.Now()
return can_btm.BtmClock{BtmTk: atpReq.Time, SysTk: now}
}