528 lines
18 KiB
Go
528 lines
18 KiB
Go
package train_pc_sim
|
|
|
|
import (
|
|
"context"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"joylink.club/bj-rtsts-server/config"
|
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
|
"joylink.club/bj-rtsts-server/third_party/tcp"
|
|
"joylink.club/bj-rtsts-server/third_party/tpapi"
|
|
"log/slog"
|
|
"math"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type TrainControlEvent struct {
|
|
Command byte
|
|
Status byte
|
|
}
|
|
|
|
//var FireTrainControlEventType = ecs.NewEventType[TrainControlEvent]()
|
|
|
|
type TrainPcSim interface {
|
|
tpapi.ThirdPartyApiService
|
|
Start(pcSimManage TrainPcSimManage)
|
|
Stop()
|
|
|
|
// SendDriverActive Deprecated 发送驾驶端激活
|
|
SendDriverActive(train *state_proto.TrainState)
|
|
// SendHandleSwitch 发送牵引制动手柄
|
|
SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, train *state_proto.TrainState)
|
|
// SendTrainDirection 列车运行方向
|
|
//因文档说明不清楚,在调用的时候目前是注释状态,现场调试可能会用到
|
|
SendTrainDirection(train *state_proto.TrainState, trainForward, trainBackward bool)
|
|
//发送应答器信息数据
|
|
SendBaliseData(train *state_proto.TrainState, msgType byte, data []byte)
|
|
SendBaliseData2(train *state_proto.TrainState, msgType byte, data []string)
|
|
//发布列车控制的相关事件
|
|
PublishTrainControlEvent(train *state_proto.TrainState, events []TrainControlEvent)
|
|
// CreateOrRemoveSpeedPLace 创建或删除速度位置信息
|
|
CreateOrRemoveSpeedPLace(train *state_proto.TrainState)
|
|
// CreateOrRemoveTrain 创建或删除列车
|
|
CreateOrRemoveTrain(train *state_proto.TrainState, isCreate bool) error
|
|
|
|
//TestSendData(train *state_proto.TrainState, data []byte)
|
|
TrainPluseCount(sta *state_proto.TrainState, h1, h2, t1, t2 float32)
|
|
}
|
|
|
|
type TrainPcSimManage interface {
|
|
GetTrainPcSimConfig() []config.VehiclePCSimConfig
|
|
//GetConnTrain() *state_proto.TrainState
|
|
GetConnTrain2() []*state_proto.TrainState
|
|
//获取列车模拟量数据
|
|
ObtainTrainDigitalMockData(train *state_proto.TrainState) []message.TrainPcSimBaseMessage
|
|
// TrainPcSimDigitalOutInfoHandle 4.4.1. 车载输出数字量信息报文内容
|
|
TrainPcSimDigitalOutInfoHandle(connType state_proto.TrainConnState_TrainConnType, data []byte)
|
|
// TrainPcSimDigitalReportHandle 4.4.2. 车载输出数字反馈量信息报文内容
|
|
TrainPcSimDigitalReportHandle(connType state_proto.TrainConnState_TrainConnType, data []byte)
|
|
FindConnTrain(ct state_proto.TrainConnState_TrainConnType) *state_proto.TrainState
|
|
// TrainPcSimMockInfo 门模式
|
|
//TrainDoorModeHandle(state byte)
|
|
//处理列车pc仿真模拟量数据
|
|
TrainPcSimMockInfo(connType state_proto.TrainConnState_TrainConnType, data []byte)
|
|
// TrainBtmQuery 处理列车btm查询
|
|
TrainBtmQuery(connType state_proto.TrainConnState_TrainConnType, data []byte)
|
|
}
|
|
|
|
const Name = "车载pc仿真"
|
|
|
|
func FindTrainPcSimClientKey(t *state_proto.TrainState) string {
|
|
if t.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_A {
|
|
return "A"
|
|
} else if t.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_B {
|
|
return "B"
|
|
}
|
|
return ""
|
|
}
|
|
func (d *trainPcSimService) Name() string {
|
|
return Name
|
|
}
|
|
func (d *trainPcSimService) State() tpapi.ThirdPartyApiServiceState {
|
|
return d.state
|
|
}
|
|
func (d *trainPcSimService) updateState(state tpapi.ThirdPartyApiServiceState) {
|
|
d.state = state
|
|
}
|
|
|
|
var (
|
|
initLock = &sync.Mutex{}
|
|
singleObj *trainPcSimService
|
|
)
|
|
|
|
func Default() TrainPcSim {
|
|
defer initLock.Unlock()
|
|
initLock.Lock()
|
|
if singleObj == nil {
|
|
singleObj = &trainPcSimService{}
|
|
}
|
|
return singleObj
|
|
}
|
|
func pluseCountSpeed(wheelDiameter int32, speedMeter float32) uint32 {
|
|
s1 := speedMeter * 1000
|
|
pluseCountData := s1 * 200 / math.Pi / float32(wheelDiameter)
|
|
fmt.Println(fmt.Sprintf("----------------------%v", pluseCountData))
|
|
return uint32(pluseCountData)
|
|
}
|
|
|
|
func (s *trainPcSimService) TrainPluseCount(sta *state_proto.TrainState, h1, h2, t1, t2 float32) {
|
|
defer initLock.Unlock()
|
|
initLock.Lock()
|
|
if sta.TrainRunUp {
|
|
if sta.TrainEndsA.SpeedSensorEnableA {
|
|
sta.PluseCount.PulseCount1 = pluseCountSpeed(sta.WheelDiameter, h1)
|
|
}
|
|
if sta.TrainEndsA.SpeedSensorEnableB {
|
|
sta.PluseCount.PulseCount2 = pluseCountSpeed(sta.WheelDiameter, h2)
|
|
}
|
|
} else {
|
|
if sta.TrainEndsB.SpeedSensorEnableA {
|
|
sta.PluseCount.PulseCount1 = pluseCountSpeed(sta.WheelDiameter, t1)
|
|
}
|
|
if sta.TrainEndsB.SpeedSensorEnableB {
|
|
sta.PluseCount.PulseCount2 = pluseCountSpeed(sta.WheelDiameter, t2)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *trainPcSimService) TrainPluseCountReset(sta *state_proto.TrainState) {
|
|
defer initLock.Unlock()
|
|
initLock.Lock()
|
|
sta.PluseCount.PulseCount1 = 0
|
|
sta.PluseCount.PulseCount2 = 0
|
|
}
|
|
|
|
type trainPcSimService struct {
|
|
state tpapi.ThirdPartyApiServiceState
|
|
newPcSimclientMap map[string]*trainPcReciverData
|
|
cancleContext context.CancelFunc
|
|
trainPcSimManage TrainPcSimManage
|
|
speedPlace *message.TrainSpeedPlaceReportMsg
|
|
configs []config.VehiclePCSimConfig
|
|
}
|
|
|
|
// 接受来自pc仿真的消息
|
|
func (d *trainPcSimService) readError(err error) {
|
|
slog.Error("连接车载pc仿真tcp服务断开", err)
|
|
d.updateState(tpapi.ThirdPartyState_Broken)
|
|
}
|
|
func (d *trainPcSimService) newCloseAllConn() {
|
|
trains := d.trainPcSimManage.GetConnTrain2()
|
|
for _, train := range trains {
|
|
d.CreateOrRemoveTrain(train, false)
|
|
}
|
|
|
|
}
|
|
|
|
func (d *trainPcSimService) newCloseConn(clientKey string) {
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
if rd != nil {
|
|
rd.tcpClient.Close()
|
|
rd.tcpClient = nil
|
|
}
|
|
}
|
|
|
|
func (d *trainPcSimService) findConfig(tcChar string) (*config.VehiclePCSimConfig, error) {
|
|
configFlag := false
|
|
if tcChar == "A" {
|
|
configFlag = true
|
|
} else if tcChar == "B" {
|
|
configFlag = false
|
|
} else {
|
|
return nil, fmt.Errorf(fmt.Sprintf("未知车载pc连接标识:%v", tcChar))
|
|
}
|
|
for _, cfg := range d.configs {
|
|
if cfg.Open && cfg.TrainEnds == configFlag {
|
|
return &cfg, nil
|
|
}
|
|
|
|
}
|
|
return nil, fmt.Errorf("未找到对应的车载pc连接配置")
|
|
}
|
|
func (d *trainPcSimService) connTrainPcSim(ctx context.Context) {
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
d.newCloseAllConn()
|
|
return
|
|
default:
|
|
}
|
|
trains := d.trainPcSimManage.GetConnTrain2()
|
|
if len(trains) > 0 {
|
|
for _, t := range trains {
|
|
clientKey := FindTrainPcSimClientKey(t)
|
|
if clientKey == "" {
|
|
slog.Error("未找到对应的pc仿真连接,trainId:", t.Id, "删除对应客户端")
|
|
d.newCloseConn(clientKey)
|
|
continue
|
|
}
|
|
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
if rd == nil {
|
|
d.newPcSimclientMap[clientKey] = &trainPcReciverData{pcSimManage: d.trainPcSimManage, clientKey: clientKey, tcpClient: &tcp.TcpClient{}}
|
|
}
|
|
if !rd.tcpClient.IsConning() {
|
|
d.newCloseConn(clientKey)
|
|
d.initConn(clientKey)
|
|
}
|
|
}
|
|
}
|
|
time.Sleep(time.Second)
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (d *trainPcSimService) initConn(clientKey string) {
|
|
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
if rd != nil && rd.tcpClient != nil && rd.tcpClient.IsConning() {
|
|
return
|
|
}
|
|
rd = &trainPcReciverData{pcSimManage: d.trainPcSimManage, clientKey: clientKey, tcpClient: &tcp.TcpClient{}}
|
|
d.newPcSimclientMap[clientKey] = rd
|
|
cfg, _ := d.findConfig(clientKey)
|
|
addr := fmt.Sprintf("%v:%v", cfg.PcSimIp, cfg.PcSimPort)
|
|
|
|
client2, err := tcp.StartTcpClient(addr, rd.receiverDataHandle, d.readError)
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("车载pc连接失败 clientKey:%v,error:%v", clientKey, err.Error()))
|
|
d.updateState(tpapi.ThirdPartyState_Broken)
|
|
} else {
|
|
rd.tcpClient = client2
|
|
}
|
|
|
|
}
|
|
func (d *trainPcSimService) Start(pcSimManage TrainPcSimManage) {
|
|
configs := pcSimManage.GetTrainPcSimConfig()
|
|
d.newPcSimclientMap = make(map[string]*trainPcReciverData)
|
|
if len(configs) <= 0 {
|
|
slog.Info("车载pc仿真配置未开启")
|
|
return
|
|
}
|
|
closedCount := 0
|
|
for _, c := range configs {
|
|
if !c.Open {
|
|
closedCount++
|
|
}
|
|
}
|
|
|
|
if closedCount == len(configs) {
|
|
slog.Error("车载pc仿真配置未开启")
|
|
return
|
|
}
|
|
d.configs = configs
|
|
ctx, ctxFun := context.WithCancel(context.Background())
|
|
d.cancleContext = ctxFun
|
|
d.trainPcSimManage = pcSimManage
|
|
d.connTrainPcSim(ctx)
|
|
d.updateState(tpapi.ThirdPartyState_Normal)
|
|
go d.sendTrainLocationAndSpeedTask(ctx)
|
|
}
|
|
|
|
func (d *trainPcSimService) Stop() {
|
|
|
|
d.updateState(tpapi.ThirdPartyState_Closed)
|
|
if d.cancleContext != nil {
|
|
d.cancleContext()
|
|
d.cancleContext = nil
|
|
}
|
|
|
|
d.newCloseAllConn()
|
|
}
|
|
func (d *trainPcSimService) CreateOrRemoveSpeedPLace(train *state_proto.TrainState) {
|
|
if train.ConnState.Conn && (train.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_A || train.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_B) {
|
|
train.PluseCount = &state_proto.SensorSpeedPulseCount{}
|
|
d.speedPlace = &message.TrainSpeedPlaceReportMsg{TrainId: train.Id}
|
|
} else {
|
|
train.PluseCount = nil
|
|
d.speedPlace = nil
|
|
}
|
|
}
|
|
func (d *trainPcSimService) CreateOrRemoveTrain(train *state_proto.TrainState, isCreate bool) error {
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
d.initConn(clientKey)
|
|
data := []byte{message.FLAG_CAMMAND_REMOVE_TRAIN}
|
|
if isCreate {
|
|
data[0] = message.FLAG_CAMMAND_CREATE_TRAIN
|
|
}
|
|
msg := &message.TrainPcSimBaseMessage{Data: data, Type: message.RECIVE_TRAIN_CREATE_REMOVE}
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
if rd != nil {
|
|
initTrainErr := d.initTrain(rd, train, isCreate, msg)
|
|
if !isCreate {
|
|
d.newCloseConn(clientKey)
|
|
}
|
|
if initTrainErr != nil {
|
|
return initTrainErr
|
|
}
|
|
|
|
}
|
|
return nil
|
|
}
|
|
func (d *trainPcSimService) initTrain(rd *trainPcReciverData, train *state_proto.TrainState, isCreate bool, trains *message.TrainPcSimBaseMessage) error {
|
|
msgs := make([]message.TrainPcSimBaseMessage, 0)
|
|
sendMsg := make([]byte, 0)
|
|
if isCreate {
|
|
tmpMsgs := d.trainPcSimManage.ObtainTrainDigitalMockData(train)
|
|
msgs = append(msgs, tmpMsgs...)
|
|
} else {
|
|
train.VobcState.Tc1Active = false
|
|
train.VobcState.Tc2Active = false
|
|
tcc := train.Tcc
|
|
for _, key := range tcc.DriverKey {
|
|
key.Val = false
|
|
}
|
|
msgs = append(msgs, message.TrainPcSimBaseMessage{Data: []byte{message.TRAIN_BRAKE_STATE, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //驾驶室激活
|
|
msgs = append(msgs, message.TrainPcSimBaseMessage{Data: []byte{message.KEY_STATE, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}) //驾驶室激活
|
|
msgs = append(msgs, message.TrainPcSimBaseMessage{Data: []byte{}, Type: message.SENDER_TRAIN_TC_NOT_ACTIVE}) //驾驶室激活
|
|
}
|
|
for _, msg := range msgs {
|
|
data := msg.Encode()
|
|
sendMsg = append(sendMsg, data...)
|
|
}
|
|
sendMsg = append(sendMsg, trains.Encode()...)
|
|
|
|
hexData := hex.EncodeToString(sendMsg)
|
|
slog.Info(fmt.Sprintf("发送列车初始化消息:%v", hexData))
|
|
rd.tcpClient.Send(sendMsg)
|
|
return nil
|
|
}
|
|
|
|
// 依据文档80ms发送列车速度位置
|
|
func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
default:
|
|
}
|
|
trains := d.trainPcSimManage.GetConnTrain2()
|
|
for _, train := range trains {
|
|
if train.ConnState.Conn && train.PluseCount != nil {
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
|
|
s1, s2 := train.PluseCount.PulseCount1, train.PluseCount.PulseCount2
|
|
d.speedPlace.ParsePulseCount1(s1, s2)
|
|
data := d.speedPlace.Encode(train.TrainRunUp, s1, s2)
|
|
bm := &message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_LOCATION_INFO, Data: data}
|
|
d.TrainPluseCountReset(train)
|
|
dataCode := bm.Encode()
|
|
slog.Info(fmt.Sprintf("发送列车速度位置,列车:%v,s1: %v,s2: %v,c2: %v,c2: %v,发送数据:%v", train.Id, s1, s2, d.speedPlace.PulseCount1, d.speedPlace.PulseCount2, hex.EncodeToString(dataCode)))
|
|
err := rd.tcpClient.Send(dataCode)
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("发送列车速度位置失败,列车:%v,发送数据:%v", train.Id, hex.EncodeToString(dataCode)))
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
time.Sleep(time.Millisecond * 80)
|
|
}
|
|
}
|
|
|
|
// SendDriverActive Deprecated 发送驾驶激活
|
|
func (d *trainPcSimService) SendDriverActive(train *state_proto.TrainState) {
|
|
vobc := train.VobcState
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
defulatBuf := make([]byte, 0)
|
|
msg := &message.TrainPcSimBaseMessage{Data: defulatBuf}
|
|
if train.TrainRunUp {
|
|
if vobc.Tc1Active {
|
|
msg.Type = message.SENDER_TRAIN_TC_ACTIVE
|
|
} else if vobc.Tc1Active == false {
|
|
msg.Type = message.SENDER_TRAIN_TC_NOT_ACTIVE
|
|
}
|
|
} else if !train.TrainRunUp {
|
|
if vobc.Tc2Active {
|
|
msg.Type = message.SENDER_TRAIN_TC_ACTIVE
|
|
} else if vobc.Tc2Active == false {
|
|
msg.Type = message.SENDER_TRAIN_TC_NOT_ACTIVE
|
|
}
|
|
}
|
|
msgs := make([]byte, 0)
|
|
if msg.Type == message.SENDER_TRAIN_TC_ACTIVE {
|
|
dd3 := message.TrainPcSimBaseMessage{Data: []byte{message.KEY_STATE, 1}, Type: message.SENDER_TRAIN_OUTR_INFO}
|
|
msgs = append(msgs, dd3.Encode()...)
|
|
} else {
|
|
dd3 := message.TrainPcSimBaseMessage{Data: []byte{message.KEY_STATE, 0}, Type: message.SENDER_TRAIN_OUTR_INFO}
|
|
msgs = append(msgs, dd3.Encode()...)
|
|
}
|
|
msgs = append(msgs, msg.Encode()...)
|
|
hexData := hex.EncodeToString(msgs)
|
|
slog.Info(fmt.Sprintf("发送驾驶激活列车id:%v,数据:%v", train.Id, hexData))
|
|
err := rd.tcpClient.Send(msgs)
|
|
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("发送驾驶激活失败列车id:%v,数据:%v,err:%v", train.Id, hexData, err.Error()))
|
|
}
|
|
}
|
|
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, train *state_proto.TrainState) {
|
|
tc := train.ConnState
|
|
if tc.Conn {
|
|
vobc := train.VobcState
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
|
|
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("发送列车手柄消息", "clientKey", clientKey, "msg", hex.EncodeToString(da))
|
|
err := rd.tcpClient.Send(da)
|
|
//err := client.Send(da)
|
|
if err != nil {
|
|
slog.Error("发送列车手柄消息失败", "clientKey", clientKey, "msg", hex.EncodeToString(da))
|
|
}
|
|
}
|
|
}
|
|
func (d *trainPcSimService) SendTrainDirection(train *state_proto.TrainState, trainForward, trainBackward bool) {
|
|
|
|
baseMsgs := make([]*message.TrainPcSimBaseMessage, 0)
|
|
if !trainForward && !trainBackward {
|
|
baseMsgs = append(baseMsgs, &message.TrainPcSimBaseMessage{Type: message.RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD})
|
|
baseMsgs = append(baseMsgs, &message.TrainPcSimBaseMessage{Type: message.RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD})
|
|
} else if trainForward {
|
|
baseMsgs = append(baseMsgs, &message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_HAND_KEY_FORWARD})
|
|
} else if trainBackward {
|
|
baseMsgs = append(baseMsgs, &message.TrainPcSimBaseMessage{Type: message.RECIVE_TRAIN_HAND_KEY_BACKWARD})
|
|
}
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
//client := d.pcSimClientMap[clientKey]
|
|
for _, msg := range baseMsgs {
|
|
da := msg.Encode()
|
|
slog.Info(fmt.Sprintf("发送列车方向列车:%v ,数据:%v", train.Id, hex.EncodeToString(da)))
|
|
err := rd.tcpClient.Send(da)
|
|
//err := client.Send(da)
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("发送列车方向失败列车:%v ,数据:%v,err:%v", train.Id, hex.EncodeToString(da), err.Error()))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *trainPcSimService) SendBaliseData2(train *state_proto.TrainState, msgType byte, data []string) {
|
|
for _, hexData := range data {
|
|
dd, _ := hex.DecodeString(hexData)
|
|
msg := &message.TrainPcSimBaseMessage{Type: msgType, Data: dd}
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
da := msg.Encode()
|
|
//slog.Info(fmt.Sprintf("发送列车PC仿真应答器信息,数据类型:0x%X,数据:%v", msgType, hex.EncodeToString(da)))
|
|
err := rd.tcpClient.Send(da)
|
|
if err != nil {
|
|
slog.Info(fmt.Sprintf("发送列车PC仿真应答器信息失败,数据:%v", hex.EncodeToString(da)))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *trainPcSimService) SendBaliseData(train *state_proto.TrainState, msgType byte, data []byte) {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = msgType
|
|
msg.Data = data
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
da := msg.Encode()
|
|
//slog.Info(fmt.Sprintf("发送列车PC仿真应答器信息,无应答器:%v,数据:%v", msgType == message.RECIVE_TRAIN_BTM_NOT_DATA, hex.EncodeToString(da)))
|
|
err := rd.tcpClient.Send(da)
|
|
if err != nil {
|
|
slog.Info(fmt.Sprintf("发送列车PC仿真应答器信息失败,数据:%v", hex.EncodeToString(da)))
|
|
}
|
|
}
|
|
|
|
func (d *trainPcSimService) PublishTrainControlEvent(train *state_proto.TrainState, events []TrainControlEvent) {
|
|
if len(events) <= 0 {
|
|
slog.Warn("发布事件数量为空")
|
|
return
|
|
}
|
|
clientKey := FindTrainPcSimClientKey(train)
|
|
rd := d.newPcSimclientMap[clientKey]
|
|
msgs := make([]byte, 0)
|
|
for _, event := range events {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = message.SENDER_TRAIN_OUTR_INFO
|
|
data := []byte{event.Command, event.Status}
|
|
msg.Data = data
|
|
code := msg.Encode()
|
|
msgs = append(msgs, code...)
|
|
/*hexCode := hex.EncodeToString(code)
|
|
slog.Info(fmt.Sprintf("输出列车控制输出量,命令码位:%v 对应状态:%v,发送数据:%v", event.Command, event.Status, hexCode))
|
|
err := rd.tcpClient.Send(code)
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("输出列车控制输出量发送失败,命令码位:%v 对应状态:%v,发送数据:%v", event.Command, event.Status, hexCode))
|
|
}*/
|
|
}
|
|
hexCode := hex.EncodeToString(msgs)
|
|
slog.Info(fmt.Sprintf("列车初始化发送数字量:%v", hexCode))
|
|
err := rd.tcpClient.Send(msgs)
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("1111111111111111111"))
|
|
}
|
|
}
|