192 lines
5.6 KiB
Go
192 lines
5.6 KiB
Go
|
package train_pc_sim
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"fmt"
|
|||
|
"joylink.club/bj-rtsts-server/config"
|
|||
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
|||
|
"joylink.club/bj-rtsts-server/third_party/tcp"
|
|||
|
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
|
|||
|
"joylink.club/ecs"
|
|||
|
"log/slog"
|
|||
|
"sync"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
type TrainPcSim interface {
|
|||
|
Start(pcSimManage TrainPcSimManage)
|
|||
|
Stop()
|
|||
|
SendDriverActive(tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
|
|||
|
SendHandleSwitch(oldTraction, oldBrakeForce int64, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
|
|||
|
SendBaliseData(msgType uint16, data []byte)
|
|||
|
PublishTrainControlEvent(world ecs.World, events []TrainControlEvent)
|
|||
|
}
|
|||
|
|
|||
|
type TrainPcSimManage interface {
|
|||
|
GetTrainPcSimConfig() config.VehiclePCSimConfig
|
|||
|
//4.4.1. 车载输出数字量信息报文内容
|
|||
|
TrainPcSimDigitalOutInfoHandle(data []byte)
|
|||
|
//4.4.2. 车载输出数字反馈量信息报文内容
|
|||
|
TrainPcSimDigitalReportHandle(data []byte)
|
|||
|
//创建/删除列车
|
|||
|
TrainPcSimConnOrRemoveHandle(state byte)
|
|||
|
//门模式
|
|||
|
TrainDoorModeHandle(state byte)
|
|||
|
TrainPcSimMockInfo(data []byte)
|
|||
|
|
|||
|
TrainBtmQuery(data []byte)
|
|||
|
}
|
|||
|
|
|||
|
var (
|
|||
|
initLock = &sync.Mutex{}
|
|||
|
singleObj *trainPcSimService
|
|||
|
)
|
|||
|
|
|||
|
func Default() TrainPcSim {
|
|||
|
defer initLock.Unlock()
|
|||
|
initLock.Lock()
|
|||
|
if singleObj == nil {
|
|||
|
singleObj = &trainPcSimService{}
|
|||
|
}
|
|||
|
return singleObj
|
|||
|
}
|
|||
|
|
|||
|
type trainPcSimService struct {
|
|||
|
pcSimClient *tcp.TcpClient
|
|||
|
cancleContext context.CancelFunc
|
|||
|
trainPcSimManage TrainPcSimManage
|
|||
|
}
|
|||
|
|
|||
|
func (pc *trainPcSimService) Start(pcSimManage TrainPcSimManage) {
|
|||
|
config := pcSimManage.GetTrainPcSimConfig()
|
|||
|
if config.PcSimIp == "" || !config.Open {
|
|||
|
slog.Info("车载pc仿真配置未开启")
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
client, err := tcp.StartTcpClient(fmt.Sprintf("%v:%v", config.PcSimIp, config.PcSimPort), pc.reivceData)
|
|||
|
if err != nil {
|
|||
|
slog.Error("连接车载pc平台失败", err)
|
|||
|
return
|
|||
|
}
|
|||
|
pc.pcSimClient = client
|
|||
|
ctx, ctxFun := context.WithCancel(context.Background())
|
|||
|
pc.cancleContext = ctxFun
|
|||
|
pc.trainPcSimManage = pcSimManage
|
|||
|
vs := pcSimManage.(*memory.VerifySimulation)
|
|||
|
FireTrainControlEventType.Subscribe(vs.World, pc.trainControlEventHandle)
|
|||
|
|
|||
|
go pc.sendTrainLocationAndSpeedTask(ctx)
|
|||
|
}
|
|||
|
func (pc *trainPcSimService) Stop() {
|
|||
|
if pc.cancleContext != nil {
|
|||
|
pc.cancleContext()
|
|||
|
pc.cancleContext = nil
|
|||
|
}
|
|||
|
pc.pcSimClient.Close()
|
|||
|
}
|
|||
|
|
|||
|
// 依据文档80ms发送列车速度位置
|
|||
|
func (pc *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
|||
|
for {
|
|||
|
select {
|
|||
|
case <-ctx.Done():
|
|||
|
return
|
|||
|
default:
|
|||
|
}
|
|||
|
/* trainStatus := acc.radarVobcManager.FindAccTrain()
|
|||
|
if trainStatus != nil {
|
|||
|
speedAcc := trainStatus.DynamicState.Acceleration
|
|||
|
t := speedAcc / accSpeedUnit
|
|||
|
acc.vobcClient.SendMsg(&message.Accelerometer{Acc: math.Float32bits(t)})
|
|||
|
}*/
|
|||
|
time.Sleep(time.Millisecond * 80)
|
|||
|
}
|
|||
|
}
|
|||
|
func (pc *trainPcSimService) SendDriverActive(tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
|
|||
|
if tc.Conn && tc.ConnType == state_proto.TrainConnState_PC_SIM {
|
|||
|
defulatBuf := make([]byte, 0)
|
|||
|
msg := &TrainPcSimBaseMessage{Data: defulatBuf}
|
|||
|
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
|
|||
|
}
|
|||
|
pc.pcSimClient.Send(msg.Encode())
|
|||
|
}
|
|||
|
}
|
|||
|
func (pc *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
|
|||
|
if tc.Conn && tc.ConnType == state_proto.TrainConnState_PC_SIM {
|
|||
|
msg := &TrainPcSimBaseMessage{}
|
|||
|
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
|
|||
|
}
|
|||
|
pc.pcSimClient.Send(msg.Encode())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (pc *trainPcSimService) SendBaliseData(msgType uint16, data []byte) {
|
|||
|
msg := &TrainPcSimBaseMessage{}
|
|||
|
msg.Type = msgType
|
|||
|
msg.Data = data
|
|||
|
pc.pcSimClient.Send(msg.Encode())
|
|||
|
}
|
|||
|
|
|||
|
func (pc *trainPcSimService) trainControlEventHandle(w ecs.World, event TrainControlEvent) {
|
|||
|
msg := &TrainPcSimBaseMessage{}
|
|||
|
msg.Type = SENDER_TRAIN_OUTR_INFO
|
|||
|
data := []byte{event.Command, event.Status}
|
|||
|
msg.Data = data
|
|||
|
pc.pcSimClient.Send(msg.Encode())
|
|||
|
}
|
|||
|
func (pc *trainPcSimService) PublishTrainControlEvent(world ecs.World, events []TrainControlEvent) {
|
|||
|
if len(events) <= 0 {
|
|||
|
slog.Warn("")
|
|||
|
return
|
|||
|
}
|
|||
|
for _, event := range events {
|
|||
|
FireTrainControlEventType.Publish(world, &event)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 接受来自pc仿真的消息
|
|||
|
func (pc *trainPcSimService) reivceData(len int, data []byte) {
|
|||
|
baseMsg := &TrainPcSimBaseMessage{}
|
|||
|
err := baseMsg.Decode(data)
|
|||
|
if err != nil {
|
|||
|
slog.Error("车载pc仿真接受数据解析失败 ")
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
switch baseMsg.Type {
|
|||
|
case RECIVE_TRAIN_CREATE_REMOVE:
|
|||
|
pc.trainPcSimManage.TrainPcSimConnOrRemoveHandle(data[0])
|
|||
|
case RECIVE_TRAIN_INTERFACE_CABINET_OUTR:
|
|||
|
pc.trainPcSimManage.TrainPcSimDigitalOutInfoHandle(data)
|
|||
|
case RECIVE_TRAIN_INTERFACE_CABINET_OUTR_BACK:
|
|||
|
pc.trainPcSimManage.TrainPcSimDigitalReportHandle(data)
|
|||
|
case RECIVE_TRAIN_QUERY_STATUS:
|
|||
|
pc.trainPcSimManage.TrainBtmQuery(data)
|
|||
|
case RECIVE_TRAIN_MOCK_DATA:
|
|||
|
pc.trainPcSimManage.TrainPcSimMockInfo(data)
|
|||
|
case RECIVE_TRAIN_DOOR_MODE:
|
|||
|
pc.trainPcSimManage.TrainDoorModeHandle(data[0])
|
|||
|
}
|
|||
|
|
|||
|
}
|