rts-sim-testing-service/third_party/train_pc_sim/train_pc_sim.go

262 lines
7.8 KiB
Go
Raw Normal View History

2024-04-02 18:20:10 +08:00
package train_pc_sim
import (
"context"
"fmt"
"joylink.club/bj-rtsts-server/config"
"joylink.club/bj-rtsts-server/dto/state_proto"
2024-04-09 08:55:33 +08:00
"joylink.club/bj-rtsts-server/third_party/message"
2024-04-02 18:20:10 +08:00
"joylink.club/bj-rtsts-server/third_party/tcp"
2024-04-13 09:40:25 +08:00
"joylink.club/bj-rtsts-server/third_party/tpapi"
2024-04-02 18:20:10 +08:00
"joylink.club/ecs"
"log/slog"
"sync"
"time"
)
2024-04-09 08:55:33 +08:00
type TrainControlEvent struct {
Command byte
Status byte
}
var FireTrainControlEventType = ecs.NewEventType[TrainControlEvent]()
2024-04-02 18:20:10 +08:00
type TrainPcSim interface {
2024-04-09 08:55:33 +08:00
Start(wd ecs.World, pcSimManage TrainPcSimManage)
2024-04-02 18:20:10 +08:00
Stop()
2024-04-09 08:55:33 +08:00
//发送驾驶端激活
2024-04-02 18:20:10 +08:00
SendDriverActive(tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
2024-04-09 08:55:33 +08:00
//发送牵引制动手柄
2024-04-02 18:20:10 +08:00
SendHandleSwitch(oldTraction, oldBrakeForce int64, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
2024-04-09 08:55:33 +08:00
//发送应答器信息数据
2024-04-02 18:20:10 +08:00
SendBaliseData(msgType uint16, data []byte)
2024-04-09 08:55:33 +08:00
//发布列车控制的相关事件
2024-04-02 18:20:10 +08:00
PublishTrainControlEvent(world ecs.World, events []TrainControlEvent)
2024-04-09 08:55:33 +08:00
CreateOrRemoveSpeedPLace(train *state_proto.TrainState)
2024-04-13 09:40:25 +08:00
CreateOrRemoveTrain(msgType byte, data []byte)
tpapi.ThirdPartyApiService
2024-04-02 18:20:10 +08:00
}
type TrainPcSimManage interface {
GetTrainPcSimConfig() config.VehiclePCSimConfig
2024-04-09 08:55:33 +08:00
GetConnTrain() *state_proto.TrainState
2024-04-02 18:20:10 +08:00
//4.4.1. 车载输出数字量信息报文内容
TrainPcSimDigitalOutInfoHandle(data []byte)
//4.4.2. 车载输出数字反馈量信息报文内容
TrainPcSimDigitalReportHandle(data []byte)
2024-04-13 09:40:25 +08:00
2024-04-02 18:20:10 +08:00
//门模式
2024-04-13 09:40:25 +08:00
//TrainDoorModeHandle(state byte)
2024-04-09 08:55:33 +08:00
//处理列车pc仿真模拟量数据
2024-04-02 18:20:10 +08:00
TrainPcSimMockInfo(data []byte)
2024-04-09 08:55:33 +08:00
//处理列车btm查询
2024-04-02 18:20:10 +08:00
TrainBtmQuery(data []byte)
}
2024-04-13 09:40:25 +08:00
const Name = "车载pc仿真"
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
}
2024-04-02 18:20:10 +08:00
var (
initLock = &sync.Mutex{}
singleObj *trainPcSimService
)
func Default() TrainPcSim {
defer initLock.Unlock()
initLock.Lock()
if singleObj == nil {
singleObj = &trainPcSimService{}
}
return singleObj
}
type trainPcSimService struct {
2024-04-13 09:40:25 +08:00
state tpapi.ThirdPartyApiServiceState
2024-04-02 18:20:10 +08:00
pcSimClient *tcp.TcpClient
cancleContext context.CancelFunc
trainPcSimManage TrainPcSimManage
2024-04-09 08:55:33 +08:00
speedPlace *message.TrainSpeedPlaceReportMsg
2024-04-02 18:20:10 +08:00
}
2024-04-13 09:40:25 +08:00
// 接受来自pc仿真的消息
func (d *trainPcSimService) readError(err error) {
slog.Error("连接车载pc仿真tcp服务断开", err)
d.updateState(tpapi.ThirdPartyState_Broken)
d.pcSimClient.Close()
}
func (d *trainPcSimService) Start(wd ecs.World, pcSimManage TrainPcSimManage) {
2024-04-02 18:20:10 +08:00
config := pcSimManage.GetTrainPcSimConfig()
if config.PcSimIp == "" || !config.Open {
slog.Info("车载pc仿真配置未开启")
return
}
2024-04-13 09:40:25 +08:00
client, err := tcp.StartTcpClient(fmt.Sprintf("%v:%v", config.PcSimIp, config.PcSimPort), d.reivceData, d.readError)
2024-04-02 18:20:10 +08:00
if err != nil {
slog.Error("连接车载pc平台失败", err)
2024-04-13 09:40:25 +08:00
d.updateState(tpapi.ThirdPartyState_Broken)
2024-04-02 18:20:10 +08:00
return
}
2024-04-13 09:40:25 +08:00
d.pcSimClient = client
2024-04-02 18:20:10 +08:00
ctx, ctxFun := context.WithCancel(context.Background())
2024-04-13 09:40:25 +08:00
d.cancleContext = ctxFun
d.trainPcSimManage = pcSimManage
2024-04-09 08:55:33 +08:00
2024-04-13 09:40:25 +08:00
FireTrainControlEventType.Subscribe(wd, d.trainControlEventHandle)
d.updateState(tpapi.ThirdPartyState_Normal)
go d.sendTrainLocationAndSpeedTask(ctx)
2024-04-02 18:20:10 +08:00
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) Stop() {
d.updateState(tpapi.ThirdPartyState_Closed)
if d.cancleContext != nil {
d.cancleContext()
2024-04-09 08:55:33 +08:00
2024-04-13 09:40:25 +08:00
d.cancleContext = nil
}
if d.pcSimClient != nil {
//d.pcSimClient.
d.pcSimClient.Close()
2024-04-09 08:55:33 +08:00
}
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) CreateOrRemoveSpeedPLace(train *state_proto.TrainState) {
2024-04-09 08:55:33 +08:00
if train.ConnState.Conn {
train.PluseCount = &state_proto.SensorSpeedPulseCount{}
2024-04-13 09:40:25 +08:00
d.speedPlace = &message.TrainSpeedPlaceReportMsg{TrainId: train.Id}
2024-04-09 08:55:33 +08:00
} else {
train.PluseCount = nil
2024-04-13 09:40:25 +08:00
d.speedPlace = nil
2024-04-09 08:55:33 +08:00
}
2024-04-02 18:20:10 +08:00
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) CreateOrRemoveTrain(msgType byte, data []byte) {
msg := &message.TrainPcSimBaseMessage{Data: data, Type: uint16(msgType)}
d.pcSimClient.Send(msg.Encode())
}
2024-04-02 18:20:10 +08:00
// 依据文档80ms发送列车速度位置
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
2024-04-02 18:20:10 +08:00
for {
select {
case <-ctx.Done():
return
default:
}
2024-04-13 09:40:25 +08:00
train := d.trainPcSimManage.GetConnTrain()
2024-04-09 08:55:33 +08:00
if train != nil && train.ConnState.Conn {
s1, s2 := train.PluseCount.PulseCount1, train.PluseCount.PulseCount2
2024-04-13 09:40:25 +08:00
d.speedPlace.ParsePulseCount1(s1, s2)
data := d.speedPlace.Encode(train.RunDirection, s1, s2)
2024-04-09 08:55:33 +08:00
bm := &message.TrainPcSimBaseMessage{Type: SENDER_TRAIN_LOCATION_INFO, Data: data}
train.PluseCount.PulseCount1 = 0
train.PluseCount.PulseCount2 = 0
2024-04-13 09:40:25 +08:00
d.pcSimClient.Send(bm.Encode())
} /*else {
2024-04-09 08:55:33 +08:00
m1 := "未找到对应连接车载pc仿真的列车"
if train != nil {
m1 = fmt.Sprintf("对应的列车没有连接上车载pc仿真列车ID%v", train.Id)
}
slog.Info(m1)
2024-04-13 09:40:25 +08:00
}*/
2024-04-02 18:20:10 +08:00
time.Sleep(time.Millisecond * 80)
}
}
2024-04-09 08:55:33 +08:00
// 发送驾驶激活
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) SendDriverActive(tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
2024-04-02 18:20:10 +08:00
if tc.Conn && tc.ConnType == state_proto.TrainConnState_PC_SIM {
defulatBuf := make([]byte, 0)
2024-04-09 08:55:33 +08:00
msg := &message.TrainPcSimBaseMessage{Data: defulatBuf}
2024-04-02 18:20:10 +08:00
if vobc.Tc1Active || vobc.Tc2Active {
msg.Type = SENDER_TRAIN_TC_ACTIVE
} else if vobc.Tc1Active == false && vobc.Tc2Active == false {
msg.Type = SENDER_TRAIN_TC_NOT_ACTIVE
}
2024-04-13 09:40:25 +08:00
d.pcSimClient.Send(msg.Encode())
2024-04-02 18:20:10 +08:00
}
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
2024-04-02 18:20:10 +08:00
if tc.Conn && tc.ConnType == state_proto.TrainConnState_PC_SIM {
2024-04-09 08:55:33 +08:00
msg := &message.TrainPcSimBaseMessage{}
2024-04-02 18:20:10 +08:00
newTraction := vobc.TractionForce
newBrake := vobc.BrakeForce
if newTraction <= oldTraction && newTraction == 0 {
//手柄取消前进
msg.Type = RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD
} else if newTraction > oldTraction {
//手柄前进
msg.Type = SENDER_TRAIN_HAND_KEY_FORWARD
} else if newBrake >= oldBrakeForce && newBrake == 0 {
//手柄取消后退
msg.Type = RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD
} else if newBrake < oldBrakeForce {
//手柄后退
msg.Type = RECIVE_TRAIN_HAND_KEY_BACKWARD
} else {
slog.Error("")
return
}
2024-04-13 09:40:25 +08:00
d.pcSimClient.Send(msg.Encode())
2024-04-02 18:20:10 +08:00
}
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) SendBaliseData(msgType uint16, data []byte) {
2024-04-09 08:55:33 +08:00
msg := &message.TrainPcSimBaseMessage{}
2024-04-02 18:20:10 +08:00
msg.Type = msgType
msg.Data = data
2024-04-13 09:40:25 +08:00
d.pcSimClient.Send(msg.Encode())
2024-04-02 18:20:10 +08:00
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) trainControlEventHandle(w ecs.World, event TrainControlEvent) {
2024-04-09 08:55:33 +08:00
fmt.Println(event.Status)
msg := &message.TrainPcSimBaseMessage{}
2024-04-02 18:20:10 +08:00
msg.Type = SENDER_TRAIN_OUTR_INFO
data := []byte{event.Command, event.Status}
msg.Data = data
2024-04-13 09:40:25 +08:00
d.pcSimClient.Send(msg.Encode())
2024-04-02 18:20:10 +08:00
}
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) PublishTrainControlEvent(world ecs.World, events []TrainControlEvent) {
2024-04-02 18:20:10 +08:00
if len(events) <= 0 {
2024-04-09 08:55:33 +08:00
slog.Warn("发布事件数量为空")
2024-04-02 18:20:10 +08:00
return
}
for _, event := range events {
FireTrainControlEventType.Publish(world, &event)
}
}
// 接受来自pc仿真的消息
2024-04-13 09:40:25 +08:00
func (d *trainPcSimService) reivceData(len int, data []byte) {
2024-04-09 08:55:33 +08:00
baseMsg := &message.TrainPcSimBaseMessage{}
2024-04-02 18:20:10 +08:00
err := baseMsg.Decode(data)
if err != nil {
slog.Error("车载pc仿真接受数据解析失败 ")
return
}
switch baseMsg.Type {
2024-04-13 09:40:25 +08:00
//case RECIVE_TRAIN_CREATE_REMOVE:
// pc.trainPcSimManage.TrainPcSimConnOrRemoveHandle(baseMsg.Data[0])
2024-04-02 18:20:10 +08:00
case RECIVE_TRAIN_INTERFACE_CABINET_OUTR:
2024-04-13 09:40:25 +08:00
d.trainPcSimManage.TrainPcSimDigitalOutInfoHandle(baseMsg.Data)
2024-04-02 18:20:10 +08:00
case RECIVE_TRAIN_INTERFACE_CABINET_OUTR_BACK:
2024-04-13 09:40:25 +08:00
d.trainPcSimManage.TrainPcSimDigitalReportHandle(baseMsg.Data)
2024-04-02 18:20:10 +08:00
case RECIVE_TRAIN_QUERY_STATUS:
2024-04-13 09:40:25 +08:00
d.trainPcSimManage.TrainBtmQuery(baseMsg.Data)
2024-04-02 18:20:10 +08:00
case RECIVE_TRAIN_MOCK_DATA:
2024-04-13 09:40:25 +08:00
d.trainPcSimManage.TrainPcSimMockInfo(baseMsg.Data)
//case RECIVE_TRAIN_DOOR_MODE:
// pc.trainPcSimManage.TrainDoorModeHandle(baseMsg.Data[0])
2024-04-02 18:20:10 +08:00
}
}