rts-sim-testing-service/ts/simulation/wayside/memory/wayside_simulation_train_pc.go
tiger_zhou d1504e7bf0
All checks were successful
local-test分支打包构建docker并发布运行 / Docker-Build (push) Successful in 2m5s
列车12号线操控调整
2024-08-29 16:09:07 +08:00

970 lines
41 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/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"
"math"
"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 baseMsg []message.TrainPcSimBaseMessage = nil
if ct.ControlType == request_proto.TrainControl_EMERGENT_BUTTON {
baseMsg = trainControlButton(vobc, tcc.Buttons, ct.DeviceId, ct.ControlButton.Active, tccGraphicData)
} else if ct.ControlType == request_proto.TrainControl_DRIVER_KEY_SWITCH {
baseMsg = trainControlDriverKey(sta, ct.DriverKey, ct.DeviceId, tccGraphicData)
train_pc_sim.Default().SendDriverActive(sta)
} else if ct.ControlType == request_proto.TrainControl_DIRECTION_KEY_SWITCH {
baseMsg = trainControlDirKey(sta.DynamicState.Speed, vobc, tcc, ct.SwitchKey, 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 {
if !vobc.Tc1Active && !vobc.Tc2Active {
panic(sys_error.New("TC1和TC2都未激活不能搬动牵引制动手柄 "))
}
if vobc.TractionSafetyCircuit {
panic(sys_error.New("牵引切除,不能进行列车控制"))
}
oldTraction := sta.VobcState.TractionForce
oldBrakeForce := sta.VobcState.BrakeForce
isTraction := ct.Handler.Val > 0 //是否制动
baseMsg = trainControlHandle(sta.DynamicState.Speed, vobc, tcc, ct.Handler, ct.DeviceId, tccGraphicData)
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isTraction, sta)
} else if ct.ControlType == request_proto.TrainControl_TRAIN_DOOR_MODE_CHANGE {
baseMsg = trainDoorModeChangeHandle(vobc, tcc, ct.SwitchKey, ct.DeviceId, tccGraphicData)
}
if vobc.DirectionForward && vobc.TractionForce == 0 {
baseMsg = append(baseMsg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DIR_ZERO_FORWARD, 1}})
} else {
baseMsg = append(baseMsg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DIR_ZERO_FORWARD, 0}})
}
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) && baseMsg != nil {
train_pc_sim.Default().SendTrainControlMsg(sta, baseMsg)
}
}
func trainControlButton(vobc *state_proto.TrainVobcState, buttonMap map[string]*state_proto.TrainControlState_ControlButton, deviceId uint32, active bool, tccGraphic *data_proto.TccGraphicStorage) []message.TrainPcSimBaseMessage {
if graphicBtn, ok := findTrainTccGraphicDataButton(tccGraphic, deviceId); ok {
btn := buttonMap[graphicBtn.Code]
if btn == nil {
slog.Error("未找到对应的车载摁钮code:", graphicBtn.Code, "设备id:", deviceId)
return nil
}
switch graphicBtn.Code {
case JJZD: // 紧急制动
return controlEBBtn(vobc, active, btn)
case ATPQCKG: //atp切除
return controlAtpBtn(vobc, active, btn)
case KZM, KYM: //开左门按钮
return controlDoorOpenBtn(vobc, active, btn, graphicBtn.Code == KZM)
case GZM, GYM: //关左门按钮
return controlDoorCloseBtn(vobc, active, btn, graphicBtn.Code == GZM)
case ZF: //折返按钮
return controlReverseBtn(vobc, active, btn)
case QZMYX: //强制门允许
return controlDoorAllowBtn(vobc, active, btn)
case MSJJ: //模式降级按钮
return controlModeDownBtn(vobc, active, btn)
case MSSJ: //模式升级按钮
return controlModeUpBtn(vobc, active, btn)
case MSQR: //模式确认按钮
return controlModeConfirmBtn(vobc, active, btn)
case ZAWTGJC: //障碍物/脱轨检测
return controlObstacleDetectionBtn(vobc, active, btn)
case ZDZGZ: //制动重故障
return controlBrakeHeavyBtn(vobc, active, btn)
case ATPSD: //ATP上电按钮
return controlAtpPowerBtn(vobc, active, btn)
case HX: //唤醒按钮
return controlWakeUpBtn(vobc, active, btn)
case JX: //检修按钮
return controlOverhaulBtn(vobc, active, btn)
case XM: //休眠按钮
return controlSleepBtn(vobc, active, btn)
case ATOQD:
return controlAtoSenderBtn(vobc, active, btn)
default:
return nil
}
} else {
return nil
}
}
// 应急摁钮
func controlEBBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
if !active {
return nil
}
tccBtn.Passed = active
vobc.TractionStatus = false
vobc.EmergencyBrakingStatus = true
vobc.TractionForce = 0
vobc.BrakeForce = trainBraking(vobc.TrainLoad, 100) / 1000 * 100
vobc.BrakingStatus = true
return []message.TrainPcSimBaseMessage{
{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OUTER_EMERGENCY_BRAKE, 0}},
{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.TRAIN_BRAKE_STATE, 1}}}
}
// atp 切除
func controlAtpBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
vobc.AtpCutSwitch = active
tccBtn.Passed = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.ATP_CUT, status}}}
}
func controlDoorCloseBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton, isLeft bool) []message.TrainPcSimBaseMessage {
status := message.IsTrue(active)
tccBtn.Passed = active
var doorAct byte = message.CLOSE_LEFT_DOOR
var doorState byte = message.LEFT_DOOR_STATE
msg := make([]message.TrainPcSimBaseMessage, 0)
if isLeft {
vobc.LeftDoorCloseCommand = active
} else {
vobc.RightDoorCloseCommand = active
doorAct = message.CLOSE_RIGHT_DOOR
doorState = message.RIGHT_DOOR_STATE
}
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{doorAct, status}})
if vobc.LeftDoorCloseCommand && vobc.RightDoorCloseCommand {
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_LOCK_STATE, 1}})
}
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{doorState, 0}})
//msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{doorAct, 0}})
return msg
}
// 开车门
func controlDoorOpenBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton, isLeft bool) []message.TrainPcSimBaseMessage {
status := message.IsTrue(active)
msg := make([]message.TrainPcSimBaseMessage, 0)
tccBtn.Passed = active
var doorAct byte = message.LEFT_OPEN_DOOR
var doorState byte = message.LEFT_DOOR_STATE
if isLeft {
vobc.LeftDoorOpenCommand = active
vobc.LeftDoorCloseCommand = false
} else {
vobc.RightDoorOpenCommand = active
vobc.RightDoorCloseCommand = false
doorAct = message.OPEN_RIGHT_DOOR
doorState = message.RIGHT_DOOR_STATE
}
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{doorAct, status}})
if active {
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_LOCK_STATE, 0}})
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{doorState, status}})
}
return msg
}
// 折返
func controlReverseBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
//vobc.RightDoorCloseCommand = active
vobc.TurnbackStatus = active
tccBtn.Passed = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.TURN_BACK, status}}}
}
// 强制门允许
func controlDoorAllowBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.ForceDoorAllow = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.FORCE_DOOR_ALLOW, status}}}
}
// 模式降级按钮
func controlModeDownBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.ModeLevelDownBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.TRAIN_MODE_DOWN, status}}}
}
// 模式升级按钮
func controlModeUpBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.ModeLevelUpBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.TRAIN_MODE_UP, status}}}
}
// 模式确认按钮
func controlModeConfirmBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.ConfirmBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.CONFIRM, status}}}
}
// 障碍物/脱轨检测
func controlObstacleDetectionBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.ObstacleCheckBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OBSTACLE_CHECK, status}}}
}
// 制动重故障
func controlBrakeHeavyBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.BrakeHeavyFault = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.BRAKE_HEAVY_FAULT, status}}}
}
// ATP上电按钮
func controlAtpPowerBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.AtpPowerOnBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.ATP_POWER_ON, status}}}
}
// 唤醒按钮
func controlWakeUpBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.WakeUpBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.WAKE_UP, status}}}
}
// 检修按钮
func controlOverhaulBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.OverhaulBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OVERHAUL, status}}}
}
// 休眠按钮
func controlSleepBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.SleepBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.SLEEP, status}}}
}
func controlAtoSenderBtn(vobc *state_proto.TrainVobcState, active bool, tccBtn *state_proto.TrainControlState_ControlButton) []message.TrainPcSimBaseMessage {
var status byte = 0
if active {
status = 1
}
tccBtn.Passed = active
vobc.AtoSendTrainBtn = active
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.ATO_SEND_TRAIN, status}}}
}
// 列车方向
func trainControlDirKey(trainSpeed int32, vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, request *request_proto.TrainControl_SwitchKeyChange, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []message.TrainPcSimBaseMessage {
dirKey, find := findTrainTccGraphicDataKey(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的列车方向键deviceId:", deviceId)
panic(sys_error.New("未找到对应的列车方向键"))
}
direction := request_proto.TrainControl_KeyLocation(request.Val)
if trainSpeed > 0 {
panic(sys_error.New("列车未停稳时,不能变更方向"))
}
vobc.DirectionBackward = false
vobc.DirectionForward = false
if direction == request_proto.TrainControl_KL_FONT {
vobc.DirectionForward = true
} else if direction == request_proto.TrainControl_KL_END {
vobc.DirectionBackward = true
}
tcc.SwitchKeyMap[dirKey.Code].Val = request.Val
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.HANDLE_BACKWORD, message.IsTrue(vobc.DirectionBackward)}},
{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.HANDLE_FORWORD, message.IsTrue(vobc.DirectionForward)}}}
}
// 列车驾驶端激活
func trainControlDriverKey(train *state_proto.TrainState, request *request_proto.TrainControl_DriverKeySwitch, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []message.TrainPcSimBaseMessage {
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 []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.KEY_STATE, message.IsTrue(request.Val)}}}
}
func trainDoorModeChangeHandle(vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, request *request_proto.TrainControl_SwitchKeyChange, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []message.TrainPcSimBaseMessage {
sk, find := findTrainTccGraphicDataKey(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的牵引制动手柄设备deviceId:", deviceId)
return nil
}
msg := make([]message.TrainPcSimBaseMessage, 0)
kl := request_proto.TrainControl_KeyLocation(request.Val)
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_MODE_AA, 0}})
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_MODE_AM, 0}})
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_MODE_MM, 0}})
switch kl {
case request_proto.TrainControl_KL_END:
vobc.DoorModeMM = true
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_MODE_MM, 1}})
case request_proto.TrainControl_KL_CENTER:
vobc.DoorModeAM = true
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_MODE_AM, 1}})
case request_proto.TrainControl_KL_FONT:
msg = append(msg, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DOOR_MODE_AA, 1}})
vobc.DoorModeAA = true
}
tcc.SwitchKeyMap[sk.Code].Val = request.Val
return msg
}
func trainBraking(trainLoad int64, handleVal int32) int64 {
tl := trainLoad * 10 //列车初始化已经 * 100再*10 就是对应的kg
//F=ma 单位 F单位牛顿m单位千克a单位米/秒²
totalPower := float64(tl) * DEFAULT_BRAKE_FORCE
n := int64(math.Abs(float64(handleVal)) / 100 * totalPower)
return n
}
func trainTractionPower(trainLoad int64, handleVal int32, speedKM int32) int64 {
//f(牛) = m(质量) * (加速度* 牵引杆%* (1 - 速度(米/秒)/(最大速度(米/秒) * 牵引杆%)))
//
m := trainLoad * 10
speedM := float64(speedKM) / 3.6 / 100
acc := math.Abs(float64(handleVal)) / 100 * DEFAULT_TRAIN_TRACTION_ACC
sp := math.Abs(float64(handleVal)) / 100 * DEFAULT_TRAIN_STARTED_SPEED
if speedM > sp {
return 0
}
f := float64(m) * (acc * (1 - speedM/sp))
return int64(f)
}
// 列车牵引控制
func trainControlHandle(speed int32, vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, request *request_proto.TrainControl_PushHandler, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []message.TrainPcSimBaseMessage {
_, find := findTrainTccGraphicDataHandler(tccGraphic, deviceId)
if !find {
slog.Error("未找到对应的牵引制动手柄设备deviceId:", deviceId)
return nil
}
jjzdBtn := tcc.Buttons[JJZD]
vobc.TractionStatus = false
vobc.TractionForce = 0
vobc.BrakingStatus = false
vobc.BrakeForce = 0
vobc.MaintainBrakeStatus = false
notBreak := byte(0)
var zeroState byte = 0
var brakeState byte = 0
//var traction byte = 0
if request.Val > 0 {
vobc.TractionStatus = true
vobc.TractionForce = trainTractionPower(vobc.TrainLoad, request.Val, speed) / 1000 * 100
notBreak = 1
//traction = 1
} else if request.Val < 0 {
vobc.BrakingStatus = true
vobc.BrakeForce = trainBraking(vobc.TrainLoad, request.Val) / 1000 * 100
vobc.EmergencyBrakingStatus = false
jjzdBtn.Passed = false
brakeState = 1
} else {
zeroState = 1
brakeState = 1
}
if tcc.PushHandler == nil {
tcc.PushHandler = &state_proto.TrainControlState_PushHandler{Id: deviceId}
}
tcc.PushHandler.Val = request.Val
return []message.TrainPcSimBaseMessage{{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.HANDLE_TO_ZERO, zeroState}},
{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.TRAIN_BRAKE_STATE, brakeState}},
/*{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OUTER_EMERGENCY_BRAKE, 1}},*/
{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.NOT_BREAK, notBreak}},
/*{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{38, traction}}*/}
}
func (s *VerifySimulation) GetConnTrain2() []*state_proto.TrainState {
return s.findConnTrain2(state_proto.TrainConnState_PC_SIM)
}
func (s *VerifySimulation) findConnTrain2(ct1 ...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
finded := index(ct1, connState.ConnType)
if finded >= 0 {
trains = append(trains, train)
}
}
return true
})
return trains
}
func index(arr []state_proto.TrainConnState_TrainConnType, search state_proto.TrainConnState_TrainConnType) int {
for i, v := range arr {
if v == search {
return i
}
}
return -1
}
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
}
// 反馈atp输出数字量数据
func (s *VerifySimulation) reportTrainMockInitMsg(train *state_proto.TrainState, data1, data3 byte) {
vobc := train.VobcState
tcc := train.Tcc
tce := make([]message.TrainPcSimBaseMessage, 0)
tcc.Line12ConnErr = false
//initResult := trainInit
if vobc.Tc1Active || vobc.Tc2Active {
state := message.GetBit(data1, 3)
//if trainInit {
if vobc.TrainConnInitComplate {
if data1 == 0 {
tcc.Line12ConnErr = true
}
if state == 0 {
jjzdBtn := tcc.Buttons[JJZD]
ebTce := controlEBBtn(vobc, true, jjzdBtn)
tce = append(tce, ebTce...)
} else if message.GetBit(data1, 0) == 0 {
jjzdBtn := tcc.Buttons[JJZD]
ebTce := controlEBBtn(vobc, true, jjzdBtn)
tce = append(tce, ebTce...)
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.TRAIN_TRACTION_CUTED, 1}})
}
} else {
//initResult = false
vobc.TrainConnInitComplate = true
if tcc.LineInitTimeStamp12 <= 0 {
tcc.LineInitTimeStamp12 = time.Now().Add(time.Second * 6).Unix()
}
if tcc.LineInitTimeStamp12 > time.Now().Unix() {
tce = append(tce, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.OUTER_EMERGENCY_BRAKE, state}})
initData := s.ObtainTrainDigitalMockDataForStatus(train)
tce = append(tce, initData...)
//initResult = false
vobc.TrainConnInitComplate = false
}
}
//驾驶室激活反馈
if message.GetBit(data3, 3) == 0 {
tce = append(tce, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.DRIVER_ACTIVE_REPORT, 1}})
}
tce = append(tce, message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_OUTR_INFO, Data: []byte{message.TRAIN_INTEGRITY, 1}})
}
train_pc_sim.Default().SendTrainControlMsg(train, tce)
//return initResult
}
const (
ATO_LEVEL_NONE = iota
ATO_LEVEL_1
ATO_LEVEL_2
ATO_LEVEL_3
ATO_LEVEL_4
ATO_LEVEL_5
ATO_LEVEL_6
ATO_LEVEL_7
)
func trainAtoLevel(ato3, ato2, ato1 byte) int32 {
switch {
case ato3 == 0 && ato2 == 0 && ato1 == 1:
return ATO_LEVEL_1
case ato3 == 0 && ato2 == 1 && ato1 == 1:
return ATO_LEVEL_2
case ato3 == 0 && ato2 == 1 && ato1 == 0:
return ATO_LEVEL_3
case ato3 == 1 && ato2 == 1 && ato1 == 0:
return ATO_LEVEL_4
case ato3 == 1 && ato2 == 0 && ato1 == 0:
return ATO_LEVEL_5
case ato3 == 1 && ato2 == 0 && ato1 == 1:
return ATO_LEVEL_6
case ato3 == 1 && ato2 == 1 && ato1 == 1:
return ATO_LEVEL_7
default:
return ATO_LEVEL_NONE
}
}
// 4.4.1. 车载输出数字量信息报文内容
func (s *VerifySimulation) TrainPcSimDigitalOutInfoHandle(train *state_proto.TrainState, data []byte) {
slog.Info("开始接受atp输出模拟量==============")
for i, d := range data {
dd := &strings.Builder{}
for j := 0; j < 8; j++ {
dd.WriteString(fmt.Sprintf(" bit%v val:%v , ", j, message.GetBit(d, uint(j))))
}
slog.Info(fmt.Sprintf("接受atp模拟量id:%v,data:%b,bits:%v", i, d, dd.String()))
}
slog.Info("结束接受atp输出模拟量eeeeeeeeeeeeeeeeee")
s.reportTrainMockInitMsg(train, data[4], data[1])
vobc := train.VobcState
trainPcSimDigitalOutInfoHandleCode7_0(data[4], vobc)
trainPcSimDigitalOutInfoHandleCode15_8(data[3], vobc)
trainPcSimDigitalOutInfoHandleCode23_16(data[2], vobc)
trainPcSimDigitalOutInfoHandleCode31_24(data[1], vobc)
trainPcSimDigitalOutInfoHandleCode39_32(data[0], vobc)
//return initResult
}
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关左门
/* 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.LightDriverActive = 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.LightDir1 = message.IsTrueForByte(message.GetBit(d, 0)) //列车方向1
vobc.LightDir2 = message.IsTrueForByte(message.GetBit(d, 1)) //列车方向1
//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.LightAtoSend = 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.AtpLowPowerByte(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.LeftDoorState = message.IsTrueForByte(message.GetBit(d, 4)) //开左门允许
vobc.RightDoorState = message.IsTrueForByte(message.GetBit(d, 5)) //开右门允许
vobc.AtoCloseRightDoor = message.IsTrueForByte(message.GetBit(d, 6)) //ATO关右门
vobc.AllDoorClose = message.IsTrueForByte(message.GetBit(d, 7)) //车门保持关闭
vobc.LightTractionSafetyCircuit = vobc.TractionSafetyCircuit //切牵引
vobc.LightEmergencyBrakingStatus = vobc.EmergencyBrakingStatus //紧急制动
}
// 4.4.2. 车载输出数字反馈量信息报文内容
func (s *VerifySimulation) TrainPcSimDigitalReportHandle(train *state_proto.TrainState, data []byte) {
slog.Info(fmt.Sprintf("车载输出数字量反馈信息", hex.EncodeToString(data)))
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 {
crErr := train_pc_sim.Default().CreateOrRemoveTrain(train, create)
//train_pc_sim.Default().CreateOrRemoveSpeedPLace(train)
if crErr != nil {
return crErr
}
} 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(train *state_proto.TrainState, 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) TrainBtmQuery2(train *state_proto.TrainState, data []byte) {
ts := time.Now().UnixMilli()
if len(data) < 12 {
slog.Error("列车btm查询报文长度错误:", len(data))
return
}
trainAtm := message.NewBtmHeadFrame(data)
atpReq := &message.AtpRequestFrame{}
if !atpReq.Decode2(trainAtm) {
slog.Warn("列车pc驾驶模拟-CanetFrame解码成AtpRequestFrame失败", "CanetFrame", trainAtm.String())
return
}
var balise *state_proto.BTMState
var dsn, bc, mc byte
if atpReq.IsResend() {
balise, dsn, bc, mc = can_btm.Default().FindBaliseResend(train)
} else {
balise, dsn, bc, mc = can_btm.Default().FindBaliseByNotSend(train)
}
balise, dsn, bc, mc = can_btm.Default().FindBaliseByNotSend(train)
cl := clock(atpReq)
btmRepFrame := createBtmStatus(trainAtm.CanId.ID4, balise, atpReq, cl, dsn, bc, mc)
timeSyncF := message.NewBtmTimeSyncCheckFrame(trainAtm.CanId.ID4)
timeSyncF.T2 = cl.BtmTk
timeSyncF.T3 = cl.TkNow()
if balise == nil {
queryData := make([]byte, 0)
queryData = append(queryData, btmRepFrame.EncodeBtmAtp().Encode()...)
queryData = append(queryData, timeSyncF.EncodeBtmAtp().Encode()...)
train_pc_sim.Default().SendBaliseData(train, message.RECIVE_TRAIN_BTM_NOT_DATA, queryData)
//slog.Info(fmt.Sprintf("接受应答器查询:%x发送无应答器数据,id:%v,数据:%X", data, trainAtm.CanId.ID4, queryData))
} else {
logstr := ""
if atpReq.IsResend() {
logstr = fmt.Sprintf("准备重新发送应答id:%v,接受时间:%v,发送时间:%v , 数据:%v 经过:%v,解报文:%v,接受应答器报文:%X", balise.BaliseId, ts, time.Now().UnixMilli(), balise.Telegram, bc, mc, data)
} else if !balise.IsSend {
balise.IsSend = true
logstr = fmt.Sprintf("准备发送应答id:%v,接受时间:%v,发送时间:%v , 数据:%v 经过:%v,解报文:%v,接受应答器报文:%X", balise.BaliseId, ts, time.Now().UnixMilli(), balise.Telegram, bc, mc, data)
} else {
return
}
slog.Info(logstr)
aliseData, _ := hex.DecodeString(balise.Telegram)
stateRepFrame := btmRepFrame.EncodeBtmAtp()
statusDataCf, statusDataCfOk := message.CreateBtmAtpDataRspFramesData(stateRepFrame, aliseData, false, balise.HasData, cl.BtmTk, cl.BtmTk, cl.BtmTk)
if statusDataCfOk {
timeSyncF.T2 = cl.BtmTk
timeSyncF.T3 = cl.TkNow()
queryData := make([]byte, 0)
queryData = append(queryData, stateRepFrame.Encode()...)
queryData = append(queryData, timeSyncF.EncodeBtmAtp().Encode()...)
queryData = append(queryData, statusDataCf...) //数据帧包含结束帧
balise.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, dsn, baliseCount, messageCount byte) *message.BtmStatusRspFrame {
statusF := message.NewBtmStatusRspFrame(canIdSn)
statusF.PowerAmplifierOn = true
statusF.PowerAmplifierFailure = false
statusF.AtpReqCrcCheckWrong = !atpReq.Crc16CheckOk
statusF.AntennaFault = false
statusF.BaliseCounter = baliseCount
statusF.MessageCounter = messageCount
//statusF.TkTimeA = cl.TkNow()
statusF.TkTimeA = cl.BtmTk
statusF.DetailedCode = 0
if btmState != nil && btmState.AboveBalise {
statusF.DetailedCode = 0x07
}
//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) ObtainTrainDigitalMockDataForStatus(train *state_proto.TrainState) []message.TrainPcSimBaseMessage {
msgArr := make([]message.TrainPcSimBaseMessage, 0)
vs := train.VobcState
if vs.Tc1Active || vs.Tc2Active {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.KEY_STATE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //钥匙激活
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DRIVER_ACTIVE_REPORT, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //列车完整性
} else {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DRIVER_ACTIVE_REPORT, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //列车完整性
}
if vs.BrakeForce == 0 {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.HANDLE_TO_ZERO, 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, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //紧急制动
}
if vs.DirectionForward {
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 vs.DirectionForward {
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.HANDLE_BACKWORD, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //方向手柄向前控制
}
/* if vs.RightDoorCloseCommand {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.CLOSE_RIGHT_DOOR, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //关右门按钮
}
if vs.LeftDoorCloseCommand {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.CLOSE_LEFT_DOOR, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //关左门按钮
}
if vs.AllDoorClose {
}*/
if vs.ObstacleCheckBtn {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.OBSTACLE_CHECK, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //障碍物检测按钮
}
if vs.BrakeHeavyFault {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.BRAKE_HEAVY_FAULT, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //制动重故障
}
if vs.AtpCutSwitch {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.ATP_CUT, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //atp切除
}
if vs.AtpPowerOnBtn {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.ATP_POWER_ON, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //atp上电
}
if vs.TurnbackStatus {
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.TURN_BACK, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //atp上电
}
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.EMERGENT_HANDLE_DOWN, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //紧急手柄拉下
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.TRAIN_TRACTION_CUTED, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //紧急手柄拉下
return msgArr
}
func (s *VerifySimulation) ObtainTrainDigitalMockData(train *state_proto.TrainState) []message.TrainPcSimBaseMessage {
msgArr := make([]message.TrainPcSimBaseMessage, 0)
vs := train.VobcState
stateArr := s.ObtainTrainDigitalMockDataForStatus(train)
msgArr = append(msgArr, stateArr...)
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.ATO_SEND_TRAIN, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //ATO发车按钮
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.LEFT_DOOR_STATE, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //左门状态按钮
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.RIGHT_DOOR_STATE, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //列车完整性
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.CONFIRM, 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.NOT_BREAK, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //非制动
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{38, 0}, 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{message.DOOR_LOCK_STATE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}) //车门锁闭状态
var modeAA, modeAM, modeMM byte = 0, 0, 0
if vs.DoorModeAA {
modeAA = 1
}
if vs.DoorModeAM {
modeAM = 1
}
if vs.DoorModeMM {
modeMM = 1
}
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DOOR_MODE_AA, modeAA}, Type: message.SENDER_TRAIN_OUTR_INFO})
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DOOR_MODE_AM, modeAM}, Type: message.SENDER_TRAIN_OUTR_INFO})
msgArr = append(msgArr, message.TrainPcSimBaseMessage{Data: []byte{message.DOOR_MODE_MM, modeMM}, Type: message.SENDER_TRAIN_OUTR_INFO})
train.BtmState = nil
return msgArr
}