rts-sim-testing-service/ts/simulation/wayside/memory/wayside_simulation_train_pc.go
2024-07-04 09:26:37 +08:00

531 lines
25 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/electrical_machinery"
"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.PcSimConfigs
}
// 列车控制
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)
vobc := sta.VobcState
tcc := sta.Tcc
var tce []train_pc_sim.TrainControlEvent = nil
if ct.ControlType == request_proto.TrainControl_EMERGENT_BUTTON {
tce = trainControlEB(vobc, tcc, 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)
} else if ct.ControlType == request_proto.TrainControl_DIRECTION_KEY_SWITCH {
tce = trainControlDirKey(sta.DynamicState.Speed, vobc, tcc, ct.DirKey, ct.DeviceId, tccGraphicData)
//此处先注释,根据现场调试情况 2024-4-16
train_pc_sim.Default().SendTrainDirection(sta, sta.VobcState.DirectionForward, sta.VobcState.DirectionBackward)
} else if ct.ControlType == request_proto.TrainControl_HANDLER {
oldTraction := sta.VobcState.TractionForce
oldBrakeForce := sta.VobcState.BrakeForce
isTraction := ct.Handler.Val > 0 //是否制动
tce = trainControlHandle(vobc, tcc, ct.Handler, ct.DeviceId, tccGraphicData)
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isTraction, sta)
}
if !vobc.DirectionForward && !vobc.DirectionBackward {
vobc.TractionStatus = false
vobc.TractionForce = 0
}
if vobc.EmergencyBrakingStatus {
vobc.TractionForce = 0
}
if sta.ConnState.Conn && (sta.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_A || sta.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_B) && tce != nil {
train_pc_sim.Default().PublishTrainControlEvent(sta, tce)
}
}
func trainControlEB(vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, request *request_proto.TrainControl_EmergentButton, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
if !request.Active {
return nil
}
if tcc.Ebutton != nil && tcc.Ebutton.Passed {
return nil
}
_, find := findTrainTccGraphicDataButton(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的紧急停车摁钮,deviceId:", deviceId)
return nil
}
if tcc.Ebutton == nil {
tcc.Ebutton = &state_proto.TrainControlState_EmergentButton{Id: deviceId}
}
tcc.Ebutton.Passed = request.Active
vobc.EmergencyBrakingStatus = true
vobc.TractionForce = 0
vobc.BrakeForce = DEFAULT_BRAKE_FORCE
return []train_pc_sim.TrainControlEvent{{Command: message.OUTER_EMERGENCY_BRAKE, Status: 1}, {Command: message.TRAIN_BRAKE_STATE, Status: 1}} //紧急制动
//return []train_pc_sim.TrainControlEvent{{Command: message.CONFIRM, Status: 1}} //紧急制动
}
// 列车方向
func trainControlDirKey(trainSpeed int32, vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, 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)
panic(sys_error.New("未找到对应的列车方向键"))
}
if tcc.DirKey == nil {
tcc.DirKey = &state_proto.TrainControlState_DirectionKeySwitch{Id: deviceId}
}
direction := request_proto.TrainControl_Direction(request.Val)
if trainSpeed > 0 {
panic(sys_error.New("列车未停稳时,不能变更方向"))
}
vobc.DirectionBackward = false
vobc.DirectionForward = false
if direction == request_proto.TrainControl_FORWARD {
vobc.DirectionForward = true
} else if direction == request_proto.TrainControl_BACKWARD {
vobc.DirectionBackward = true
}
tcc.DirKey.Val = request.Val
tce := make([]train_pc_sim.TrainControlEvent, 0)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: message.IsTrue(vobc.DirectionBackward)})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: message.IsTrue(vobc.DirectionForward)})
if vobc.DirectionForward {
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.DIR_ZERO_FORWARD, Status: 1})
} else {
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.DIR_ZERO_FORWARD, Status: 0})
}
return tce
}
// 列车驾驶端激活
func trainControlDriverKey(train *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 train.DynamicState.Speed != 0 {
panic(sys_error.New("因列车未停稳,不支持此操作"))
}
vobc := train.VobcState
tcc := train.Tcc
if obj.Code == SKQYS1 {
vobc.Tc1Active = request.Val
} else if obj.Code == SKQYS2 {
vobc.Tc2Active = request.Val
}
if vobc.Tc1Active && vobc.Tc2Active {
if obj.Code == SKQYS1 {
vobc.Tc1Active = false
} else if obj.Code == SKQYS2 {
vobc.Tc2Active = false
}
panic(sys_error.New("驾驶端不能同时激活"))
}
var addNew = true
for _, k := range tcc.DriverKey {
if k.Id == deviceId {
k.Id = deviceId
k.Val = request.Val
addNew = false
break
}
}
if addNew {
tcc.DriverKey = append(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(vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, 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
}
vobc.TractionStatus = false
vobc.TractionForce = 0
vobc.BrakingStatus = false
vobc.BrakeForce = 0
vobc.MaintainBrakeStatus = false
tce := make([]train_pc_sim.TrainControlEvent, 0)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_TO_ZERO, Status: 0})
if request.Val > 0 {
vobc.TractionStatus = true
vobc.TractionForce = int64(request.Val * 180)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 0})
} else if request.Val < 0 {
vobc.BrakingStatus = true
vobc.BrakeForce = int64(-request.Val * 180)
vobc.EmergencyBrakingStatus = false
if tcc.Ebutton != nil {
tcc.Ebutton.Passed = false
}
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 1})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.OUTER_EMERGENCY_BRAKE, Status: 0})
} else {
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_TO_ZERO, Status: 1})
}
if tcc.PushHandler == nil {
tcc.PushHandler = &state_proto.TrainControlState_PushHandler{Id: deviceId}
}
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) GetConnTrain2() []*state_proto.TrainState {
return s.findConnTrain2(state_proto.TrainConnState_PC_SIM_A, state_proto.TrainConnState_PC_SIM_B)
}
func (s *VerifySimulation) findConnTrain2(ct1, ct2 state_proto.TrainConnState_TrainConnType) []*state_proto.TrainState {
var trains = make([]*state_proto.TrainState, 0)
s.Memory.Status.TrainStateMap.Range(func(k, v any) bool {
train := v.(*state_proto.TrainState)
if train.Show {
connState := train.ConnState
if connState.ConnType == ct1 || connState.ConnType == ct2 {
trains = append(trains, train)
}
}
return true
})
return trains
}
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(connType state_proto.TrainConnState_TrainConnType, data []byte) {
slog.Info(fmt.Sprintf("处理车载输出数字量信息报文内容:%v", hex.EncodeToString(data)))
train := s.FindConnTrain(connType)
if train == nil {
slog.Error("车载输出数字量未找到连接车载pc仿真的列车")
return
}
if !train.ConnState.Conn {
slog.Error("车载输出数字量,,列车未连接车载pc仿真")
return
}
vobc := train.VobcState
trainPcSimDigitalOutInfoHandleCode39_32(data[4], vobc)
trainPcSimDigitalOutInfoHandleCode31_24(connType, data[3], vobc)
trainPcSimDigitalOutInfoHandleCode23_16(data[2], vobc)
trainPcSimDigitalOutInfoHandleCode15_8(data[1], vobc)
trainPcSimDigitalOutInfoHandleCode7_0(data[0], vobc)
}
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(connType state_proto.TrainConnState_TrainConnType, 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关左门
if connType == state_proto.TrainConnState_PC_SIM_A {
vobc.Tc1Active = message.IsTrueForByte(message.GetBit(d, 3))
} else {
vobc.Tc2Active = 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.AtpLowPowerByte(message.GetBit(d, 0)) //切牵引
vobc.TrainDoorOutLed = message.IsTrueForByte(message.GetBit(d, 1)) //? 车门外指示灯
vobc.ParkingBrakeStatus = message.IsTrueForByte(message.GetBit(d, 2)) //停放制动施加
vobc.EmergencyBrakingStatus = message.AtpLowPowerByte(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(connType state_proto.TrainConnState_TrainConnType, data []byte) {
slog.Info(fmt.Sprintf("车载输出数字量反馈信息", hex.EncodeToString(data)))
train := s.FindConnTrain(connType)
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, create bool) error {
connState := train.ConnState
if connState.ConnType == state_proto.TrainConnState_PC_SIM_A || connState.ConnType == state_proto.TrainConnState_PC_SIM_B {
crErr := train_pc_sim.Default().CreateOrRemoveTrain(train, create)
if crErr != nil {
return crErr
}
train_pc_sim.Default().CreateOrRemoveSpeedPLace(train)
} else if connState.ConnType == state_proto.TrainConnState_VOBC {
electrical_machinery.Default().ClearOrRemoveTrain(train)
}
return nil
}
// 门模式
/*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(connType state_proto.TrainConnState_TrainConnType, data []byte) {
train := s.FindConnTrain(connType)
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(connType state_proto.TrainConnState_TrainConnType, data []byte) {
slog.Info(fmt.Sprintf("收到车载输出BTM查询同步帧报文内容:%v", hex.EncodeToString(data)))
if len(data) < 12 {
slog.Error("列车btm查询报文长度错误:", len(data))
return
}
train := s.FindConnTrain(connType)
if train == nil {
slog.Error("车载输出btm查询,未找到连接车载pc仿真的列车")
return
}
if !train.ConnState.Conn {
slog.Error("车载输出btm查询,列车未连接车载pc仿真")
return
}
trainAtm := message.NewCanetFrame2(data, true)
atpReq := &message.AtpRequestFrame{IsTrainPcSim: true}
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, message.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 {
//无数据
queryDataStr := make([]string, 0)
queryDataStr = append(queryDataStr, hex.EncodeToString(btmRepFrame.Encode().Encode2()))
queryDataStr = append(queryDataStr, hex.EncodeToString(timeSyncF.Encode().Encode2()))
train_pc_sim.Default().SendBaliseData2(train, message.RECIVE_TRAIN_BTM_NOT_DATA, queryDataStr)
/* queryData := make([]byte, 0)
queryData = append(queryData, btmRepFrame.Encode().Encode()...)
queryData = append(queryData, timeSyncF.Encode().Encode()...)
train_pc_sim.Default().SendBaliseData(train, message.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().Encode2()...)
queryData = append(queryData, timeSyncF.Encode().Encode2()...)
queryData = append(queryData, statusDataCf...) //数据帧包含结束帧
train.BtmState.BaliseTelegramForPcSimResend = fmt.Sprintf("%X", statusDataCf)
train_pc_sim.Default().SendBaliseData(train, message.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, atpReq.IsTrainPcSim)
//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
}
dsn := byte(btmState.DataSerialNumber) + 1
btmState.DataSerialNumber = uint32(dsn)
statusF.Dsn = dsn
return statusF
}
func clock(atpReq *message.AtpRequestFrame) can_btm.BtmClock {
now := time.Now()
return can_btm.BtmClock{BtmTk: atpReq.Time, SysTk: now}
}
func (s *VerifySimulation) ObtainTrainDigitalMockData(train *state_proto.TrainState) []message.TrainPcSimBaseMessage {
msgArr := make([]message.TrainPcSimBaseMessage, 0)
vs := train.VobcState
tcc := train.Tcc
if vs.Tc1Active || vs.Tc2Active {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.KEY_STATE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //钥匙激活
}
if vs.BrakingStatus {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.TRAIN_BRAKE_STATE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //列车制动状态
}
if vs.EmergencyBrakingStatus {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.OUTER_EMERGENCY_BRAKE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //紧急制动
}
dir := request_proto.TrainControl_Direction(tcc.DirKey.Val)
if dir == request_proto.TrainControl_FORWARD {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DIR_ZERO_FORWARD, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //手柄零位方向向前
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.HANDLE_FORWORD, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //方向手柄向前控制
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.HANDLE_BACKWORD, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //方向手柄向前控制
} else if dir == request_proto.TrainControl_BACKWARD {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.HANDLE_FORWORD, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //方向手柄向前控制
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DIR_ZERO_FORWARD, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //手柄零位方向向前
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.HANDLE_BACKWORD, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //方向手柄向前控制
}
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.CLOSE_RIGHT_DOOR, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //关右门按钮
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.CLOSE_LEFT_DOOR, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //关左门按钮
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.TRAIN_INTEGRITY, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //列车完整性
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DOOR_LOCK_STATE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //车门锁闭状态
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.OBSTACLE_CHECK, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //障碍物检测按钮
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.BRAKE_HEAVY_FAULT, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //制动重故障
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.EMERGENT_HANDLE_DOWN, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //紧急手柄拉下
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.LIFE_DOOR, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //逃生门状态
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.ATP_CUT, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //atp切除
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{39, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //非制动
//msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{40, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //本端机械钩
//msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{41, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //对端机械钩
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{}, Type: message.RECIVE_TRAIN_BTN_CLEAR_ALL_PRE_DATA}) //清空应答器
train.BtmState = nil
return msgArr
}