列车pc仿真调整
This commit is contained in:
parent
29fc4e265b
commit
4666c84860
106
third_party/message/can_btm_rsp.go
vendored
106
third_party/message/can_btm_rsp.go
vendored
@ -2,16 +2,17 @@ package message
|
||||
|
||||
import "log/slog"
|
||||
|
||||
//BTM与ATP之间为双向通信,ATP(主)定时发送请求帧,BTM(从)在未接收到应答器报文时回复状态应答器帧和时间同步帧,在接收到应答器报文时回复所有帧
|
||||
|
||||
// CreateBtmRspFramesData 数据帧与状态应答帧同时发送给ATP
|
||||
// CreateBtmRspFramesData BTM与ATP之间为双向通信,ATP(主)定时发送请求帧,BTM(从)在未接收到应答器报文时回复状态应答器帧和时间同步帧,在接收到应答器报文时回复所有帧
|
||||
//
|
||||
// 数据帧与状态应答帧同时发送给ATP
|
||||
//
|
||||
// 共17帧,17X12个字节,每个帧12字节
|
||||
// msg - 应答器报文
|
||||
// msgPackError - true BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
||||
func CreateBtmRspFramesData(statusRsp *BtmStatusRspFrame, msg []byte, msgPackError bool, msgTimeA uint32, msgTimeB uint32, tkTimeB uint32, isTrainPcSim bool) ([]byte, bool) {
|
||||
if len(msg) > 104 { //数据帧最多存储13*8个字节
|
||||
/* if len(msg) > 104 { //数据帧最多存储13*8个字节
|
||||
return nil, false
|
||||
}
|
||||
}*/
|
||||
//最近一次ATP查询请求序列号
|
||||
sn := statusRsp.FId.ID4
|
||||
//13个BtmDataMessageFrame [0x00,0x0c]
|
||||
@ -93,6 +94,101 @@ func CreateBtmRspFramesData(statusRsp *BtmStatusRspFrame, msg []byte, msgPackErr
|
||||
rt = append(rt, dtACf.Encode()...)
|
||||
rt = append(rt, dtBCf.Encode()...)
|
||||
rt = append(rt, endCf.Encode()...)
|
||||
if isTrainPcSim && len(rt) != 221 {
|
||||
|
||||
} else if len(rt) != 221 {
|
||||
slog.Warn("len(rt)!=221")
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return rt, true
|
||||
}
|
||||
|
||||
func CreateBtmRspFramesDataForPcSim(statusRsp *BtmStatusRspFrame, msg []byte, msgPackError bool, msgTimeA uint32, msgTimeB uint32, tkTimeB uint32, isTrainPcSim bool) ([]byte, bool) {
|
||||
if len(msg) > 128 { //数据帧最多存储13*8个字节
|
||||
return nil, false
|
||||
}
|
||||
//最近一次ATP查询请求序列号
|
||||
sn := statusRsp.FId.ID4
|
||||
//13个BtmDataMessageFrame [0x00,0x0c]
|
||||
//数据
|
||||
dms := make([]*BtmDataMessageFrame, 14)
|
||||
for mr := 0x00; mr <= 0x0E; mr++ {
|
||||
dms[mr] = NewBtmDataMessageFrame(sn, byte(mr), isTrainPcSim)
|
||||
dms[mr].Message = make([]byte, 8) //8字节数组,默认值0
|
||||
//
|
||||
if !msgPackError {
|
||||
mi := mr * 8
|
||||
if mi < len(msg) { //数据帧中有<=8个字节数据
|
||||
if mi+7 < len(msg) {
|
||||
dms[mr].Message = msg[mi : mi+8]
|
||||
} else {
|
||||
for i, d := range msg[mi:] {
|
||||
dms[mr].Message[i] = d
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
||||
for c := 0; c < 8; c++ {
|
||||
dms[mr].Message[c] = 0xff
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
dtA := NewBtmDataMessageTimeAFrame(sn, isTrainPcSim)
|
||||
//dtA.TimeA = msgTimeA
|
||||
//if !msgPackError {
|
||||
// var crc32AData []byte
|
||||
// crc32AData = append(crc32AData, msg...)
|
||||
// crc32AData = append(crc32AData, canTimeToBytes(dtA.TimeA)...)
|
||||
// dtA.Crc32A = Can_Crc32(crc32AData) //CRC32A的校验范围是:报文+时间戳A
|
||||
//} else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
||||
// dtA.Crc32A = 0xff_ff_ff_ff
|
||||
//}
|
||||
//
|
||||
dtB := NewBtmDataMessageTimeBFrame(sn, isTrainPcSim)
|
||||
dtB.TimeB = msgTimeB
|
||||
if !msgPackError {
|
||||
var crc32BData []byte
|
||||
crc32BData = append(crc32BData, msg...)
|
||||
crc32BData = append(crc32BData, canTimeToBytes(dtB.TimeB)...)
|
||||
dtB.Crc32B = Can_Crc32(crc32BData) //CRC32B的校验范围是:报文+时间戳B
|
||||
} else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
||||
dtB.Crc32B = 0xff_ff_ff_ff
|
||||
}
|
||||
//
|
||||
end := NewBtmDataMessageEndFrame(sn, isTrainPcSim)
|
||||
end.TkB = tkTimeB
|
||||
//
|
||||
statusCf := statusRsp.Encode()
|
||||
dmsCfs := make([]*CanetFrame, 0, 13)
|
||||
for _, dm := range dms {
|
||||
dmsCfs = append(dmsCfs, dm.Encode())
|
||||
}
|
||||
dtACf := dtA.Encode()
|
||||
dtBCf := dtB.Encode()
|
||||
//
|
||||
crc32cData := make([]byte, 0, 132)
|
||||
crc32cData = append(crc32cData, statusCf.CanData...)
|
||||
for _, dmCf := range dmsCfs {
|
||||
crc32cData = append(crc32cData, dmCf.CanData...)
|
||||
}
|
||||
crc32cData = append(crc32cData, dtACf.CanData...)
|
||||
crc32cData = append(crc32cData, dtBCf.CanData...)
|
||||
crc32cData = append(crc32cData, canTimeToBytes(end.TkB)...)
|
||||
//
|
||||
end.Crc32C = Can_Crc32(crc32cData)
|
||||
//
|
||||
endCf := end.Encode()
|
||||
//
|
||||
rt := make([]byte, 0, 221) //17*13
|
||||
rt = append(rt, statusCf.Encode()...)
|
||||
for _, dmCf := range dmsCfs {
|
||||
rt = append(rt, dmCf.Encode()...)
|
||||
}
|
||||
rt = append(rt, dtACf.Encode()...)
|
||||
rt = append(rt, dtBCf.Encode()...)
|
||||
rt = append(rt, endCf.Encode()...)
|
||||
if len(rt) != 221 {
|
||||
slog.Warn("len(rt)!=221")
|
||||
return nil, false
|
||||
|
9
third_party/message/can_net.go
vendored
9
third_party/message/can_net.go
vendored
@ -49,16 +49,17 @@ func (p *CanetFrame) Encode() []byte {
|
||||
}
|
||||
|
||||
func (p *CanetFrame) Decode(buf []byte) {
|
||||
if len(buf) != 13 {
|
||||
panic("len(buf)!=13")
|
||||
}
|
||||
|
||||
//
|
||||
if !p.IsTrainPcSim {
|
||||
if len(buf) != 13 {
|
||||
panic("len(buf)!=13")
|
||||
}
|
||||
p.FF = buf[0]&0x80 == 0x80
|
||||
p.RTR = buf[0]&0x40 == 0x40
|
||||
p.CanLen = buf[0] & 0x0f
|
||||
}
|
||||
|
||||
p.CanLen = buf[0] & 0x0f
|
||||
//1 2 3 4
|
||||
p.CanId.ID1 = buf[1]
|
||||
p.CanId.ID2 = buf[2]
|
||||
|
19
third_party/message/train_pc_sim_message.go
vendored
19
third_party/message/train_pc_sim_message.go
vendored
@ -28,7 +28,6 @@ func (tp *TrainPcSimBaseMessage) Encode() []byte {
|
||||
binary.Write(dataBufs, binary.BigEndian, tp.Data)
|
||||
data := dataBufs.Bytes()
|
||||
pack = append(pack, data...)
|
||||
|
||||
pack = binary.BigEndian.AppendUint16(pack, uint16(crc.CalculateCRC(crc.CRC16, data)))
|
||||
return pack
|
||||
}
|
||||
@ -109,6 +108,24 @@ func (tp *TrainSpeedPlaceReportMsg) Encode(runDir bool, s1, s2 uint32) []byte {
|
||||
return data
|
||||
}
|
||||
|
||||
func (tp *TrainSpeedPlaceReportMsg) Decode(d []byte) {
|
||||
buf := bytes.NewBuffer(d)
|
||||
var runDir uint16
|
||||
binary.Read(buf, binary.BigEndian, &runDir)
|
||||
var s1 uint32
|
||||
binary.Read(buf, binary.BigEndian, &s1)
|
||||
var s2 uint32
|
||||
binary.Read(buf, binary.BigEndian, &s2)
|
||||
var c1 uint32
|
||||
binary.Read(buf, binary.BigEndian, &c1)
|
||||
var c2 uint32
|
||||
binary.Read(buf, binary.BigEndian, &c2)
|
||||
var ts uint32
|
||||
binary.Read(buf, binary.BigEndian, &ts)
|
||||
fmt.Println(runDir, s1, s2, c1, c2, ts)
|
||||
|
||||
}
|
||||
|
||||
// 轨旁向列车pc仿真发送的命令码
|
||||
const (
|
||||
//钥匙开关状态
|
||||
|
10
third_party/tcp/tcp_client.go
vendored
10
third_party/tcp/tcp_client.go
vendored
@ -41,7 +41,7 @@ func StartTcpClient(rAddr string, handler func(n int, data []byte), readErr func
|
||||
}
|
||||
if err == io.EOF {
|
||||
slog.Warn(fmt.Sprintf("TCP客户端[rAddr:%s]断开连接:", rAddr))
|
||||
break
|
||||
readErr(err)
|
||||
}
|
||||
}
|
||||
handler(l, data)
|
||||
@ -57,15 +57,15 @@ func (c *TcpClient) Close() {
|
||||
c.conn = nil
|
||||
}
|
||||
}
|
||||
func (c *TcpClient) Send(data []byte) {
|
||||
func (c *TcpClient) Send(data []byte) error {
|
||||
if c.conn == nil {
|
||||
slog.Error("tcp client send error,conn is nil")
|
||||
return
|
||||
return fmt.Errorf("TCP未连接车载PC仿真")
|
||||
}
|
||||
_, err := c.conn.Write(data)
|
||||
if err != nil {
|
||||
slog.Error("tcp client send error", "error", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
145
third_party/train_pc_sim/example/main.go
vendored
145
third_party/train_pc_sim/example/main.go
vendored
@ -1,12 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
||||
"log/slog"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TcpConnHandler = func(conn net.Conn)
|
||||
@ -33,14 +35,14 @@ func tcpRunAcceptTask(listen net.Listener, port int, connHandler TcpConnHandler,
|
||||
|
||||
func tcpRunReadTask(conn net.Conn, port int, msgHandler TcpMsgHandler) {
|
||||
go func() {
|
||||
defer func() {
|
||||
/* defer func() {
|
||||
if err := recover(); err != nil {
|
||||
slog.Error(fmt.Sprintf("TCP服务端[port:%d]读数据任务异常:", port), err)
|
||||
serConn.Close()
|
||||
serConn = nil
|
||||
|
||||
}
|
||||
}()
|
||||
}()*/
|
||||
for {
|
||||
data := make([]byte, 1024)
|
||||
l, err := conn.Read(data)
|
||||
@ -87,6 +89,72 @@ func changeDoorMode() *message.TrainPcSimBaseMessage {
|
||||
return msg
|
||||
}
|
||||
|
||||
func boolsToByte(flags [8]bool) byte {
|
||||
var result uint8
|
||||
for index, b := range flags {
|
||||
if b {
|
||||
result = result + (1 << index)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func pcSimInfoOut() *message.TrainPcSimBaseMessage {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Type = train_pc_sim.RECIVE_TRAIN_INTERFACE_CABINET_OUTR
|
||||
data := make([]byte, 0)
|
||||
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
||||
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
||||
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
||||
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
||||
data = append(data, boolsToByte([8]bool{true, false, false, false, false, false, false, false}))
|
||||
msg.Data = data
|
||||
return msg
|
||||
}
|
||||
func pcSimInfoOutReport() *message.TrainPcSimBaseMessage {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Type = train_pc_sim.RECIVE_TRAIN_INTERFACE_CABINET_OUTR_BACK
|
||||
data := make([]byte, 0)
|
||||
data = append(data, boolsToByte([8]bool{true, true, false, false, false, false, false, false}))
|
||||
msg.Data = data
|
||||
return msg
|
||||
}
|
||||
|
||||
var autoIncNo = 0
|
||||
|
||||
func queryBtm() *message.TrainPcSimBaseMessage {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Type = train_pc_sim.RECIVE_TRAIN_QUERY_STATUS
|
||||
autoIncNo = autoIncNo + 1
|
||||
data := make([]byte, 0)
|
||||
data = append(data, 0x62)
|
||||
data = append(data, 0x81)
|
||||
data = append(data, 0x02)
|
||||
data = append(data, byte(autoIncNo)<<3)
|
||||
|
||||
data = append(data, boolsToByte([8]bool{true, true, false, false, false, false, false, false}))
|
||||
data = append(data, 0) //速度低位
|
||||
data = append(data, 0) //当前时间高位
|
||||
data = append(data, 0) //当前时间
|
||||
data = append(data, 0) //当前时间
|
||||
data = append(data, 0) //当前时间低位
|
||||
data = append(data, 0) //当前时间低位
|
||||
data = append(data, 0) //CRC16-H(MSB
|
||||
data = append(data, 0) //CRC16-L(LSB)
|
||||
msg.Data = data
|
||||
return msg
|
||||
}
|
||||
|
||||
func pcSimNumReportOut() *message.TrainPcSimBaseMessage {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Type = train_pc_sim.RECIVE_TRAIN_MOCK_DATA
|
||||
sd := uint16(1234)
|
||||
data := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(data, sd)
|
||||
msg.Data = data
|
||||
return msg
|
||||
}
|
||||
|
||||
// 测试创建连接
|
||||
/*func TestConn(t *testing.T) {
|
||||
createServer(func(n int, data []byte) {
|
||||
@ -99,16 +167,68 @@ func main() {
|
||||
|
||||
createServer(func(n int, data []byte) {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Decode(data)
|
||||
d := data[:n]
|
||||
msg.Decode(d)
|
||||
pd := fmt.Sprintf("%X", d)
|
||||
|
||||
if msg.Type == train_pc_sim.SENDER_TRAIN_TC_ACTIVE {
|
||||
fmt.Println("接收驾驶端激活")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.SENDER_TRAIN_TC_NOT_ACTIVE {
|
||||
fmt.Println("接收驾驶端未激活")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.SENDER_TRAIN_OUTR_INFO {
|
||||
fmt.Println("接受列车输出数字量", msg.Data[0], msg.Data[1])
|
||||
fmt.Println(pd)
|
||||
t := msg.Data[0]
|
||||
s := msg.Data[1]
|
||||
tt := strconv.Itoa(int(t))
|
||||
switch t {
|
||||
case 0:
|
||||
tt = "驾驶台"
|
||||
case 1:
|
||||
tt = "手柄向前"
|
||||
case 2:
|
||||
tt = "手柄向后"
|
||||
case 14:
|
||||
tt = "手柄归零"
|
||||
case 4:
|
||||
tt = "制动状态"
|
||||
}
|
||||
fmt.Println("接受列车输出数字量", tt, s)
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE {
|
||||
fmt.Println("创建或删除列车")
|
||||
}
|
||||
state := msg.Data[0]
|
||||
if state == 0x01 {
|
||||
fmt.Println("创建列车")
|
||||
} else if state == 0x00 {
|
||||
fmt.Println("删除列车")
|
||||
}
|
||||
fmt.Println(pd)
|
||||
|
||||
} else if msg.Type == train_pc_sim.SENDER_TRAIN_HAND_KEY_FORWARD {
|
||||
fmt.Println("列车手柄向前")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD {
|
||||
fmt.Println("列车手柄取消向前")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_BACKWARD {
|
||||
fmt.Println("列车手柄向后")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD {
|
||||
fmt.Println("列车手柄取消向后")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_BTM_HAS_DATA {
|
||||
fmt.Println("有数据应答")
|
||||
fmt.Println(pd)
|
||||
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_BTM_NOT_DATA {
|
||||
|
||||
} /*else if msg.Type == train_pc_sim.SENDER_TRAIN_LOCATION_INFO {
|
||||
fmt.Println("列车速度位置报告")
|
||||
fmt.Println(pd)
|
||||
mp := message.TrainSpeedPlaceReportMsg{}
|
||||
mp.Decode(msg.Data)
|
||||
|
||||
}*/
|
||||
|
||||
})
|
||||
//reader := bufio.NewReader(os.Stdin)
|
||||
@ -129,6 +249,19 @@ func main() {
|
||||
} else if command == "door-mode" {
|
||||
msg := changeDoorMode()
|
||||
serConn.Write(msg.Encode())
|
||||
} else if command == "info-out" {
|
||||
msg := pcSimInfoOut()
|
||||
serConn.Write(msg.Encode())
|
||||
} else if command == "info-out-report" {
|
||||
msg := pcSimInfoOutReport()
|
||||
serConn.Write(msg.Encode())
|
||||
} else if command == "query-btm" {
|
||||
msg := queryBtm()
|
||||
serConn.Write(msg.Encode())
|
||||
} else if command == "num-out" {
|
||||
msg := pcSimNumReportOut()
|
||||
serConn.Write(msg.Encode())
|
||||
|
||||
}
|
||||
command = ""
|
||||
/*content, _ := reader.ReadString('\n')
|
||||
|
90
third_party/train_pc_sim/train_pc_sim.go
vendored
90
third_party/train_pc_sim/train_pc_sim.go
vendored
@ -10,6 +10,7 @@ import (
|
||||
"joylink.club/bj-rtsts-server/third_party/tpapi"
|
||||
"joylink.club/ecs"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -27,7 +28,7 @@ type TrainPcSim interface {
|
||||
//发送驾驶端激活
|
||||
SendDriverActive(tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
|
||||
//发送牵引制动手柄
|
||||
SendHandleSwitch(oldTraction, oldBrakeForce int64, isBrake bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
|
||||
SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
|
||||
//列车运行方向
|
||||
//因文档说明不清楚,在调用的时候目前是注释状态,现场调试可能会用到
|
||||
SendTrainDirection(trainForward, trainBackward bool)
|
||||
@ -38,7 +39,7 @@ type TrainPcSim interface {
|
||||
|
||||
CreateOrRemoveSpeedPLace(train *state_proto.TrainState)
|
||||
|
||||
CreateOrRemoveTrain(msgType byte, data []byte)
|
||||
CreateOrRemoveTrain(msgType byte, data []byte) error
|
||||
tpapi.ThirdPartyApiService
|
||||
}
|
||||
|
||||
@ -102,18 +103,29 @@ func (d *trainPcSimService) readError(err error) {
|
||||
}
|
||||
func (d *trainPcSimService) connTrainPcSim() {
|
||||
reconnIndex := 0
|
||||
for {
|
||||
client, err := tcp.StartTcpClient(fmt.Sprintf("%v:%v", d.config.PcSimIp, d.config.PcSimPort), d.reivceData, d.readError)
|
||||
if err != nil {
|
||||
reconnIndex++
|
||||
slog.Error("连接车载pc平台失败,尝试=", reconnIndex, err)
|
||||
d.updateState(tpapi.ThirdPartyState_Broken)
|
||||
} else {
|
||||
d.pcSimClient = client
|
||||
return
|
||||
ctx, ctxFun := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
for {
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
client, err := tcp.StartTcpClient(fmt.Sprintf("%v:%v", d.config.PcSimIp, d.config.PcSimPort), d.reivceData, d.readError)
|
||||
if err != nil {
|
||||
reconnIndex++
|
||||
slog.Error("连接车载pc平台失败,尝试=", strconv.Itoa(reconnIndex), err)
|
||||
d.updateState(tpapi.ThirdPartyState_Broken)
|
||||
} else {
|
||||
d.pcSimClient = client
|
||||
ctxFun()
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
func (d *trainPcSimService) Start(wd ecs.World, pcSimManage TrainPcSimManage) {
|
||||
config := pcSimManage.GetTrainPcSimConfig()
|
||||
@ -127,7 +139,7 @@ func (d *trainPcSimService) Start(wd ecs.World, pcSimManage TrainPcSimManage) {
|
||||
d.cancleContext = ctxFun
|
||||
d.trainPcSimManage = pcSimManage
|
||||
|
||||
FireTrainControlEventType.Subscribe(wd, d.trainControlEventHandle)
|
||||
//FireTrainControlEventType.Subscribe(wd, d.trainControlEventHandle)
|
||||
d.updateState(tpapi.ThirdPartyState_Normal)
|
||||
go d.sendTrainLocationAndSpeedTask(ctx)
|
||||
|
||||
@ -153,9 +165,10 @@ func (d *trainPcSimService) CreateOrRemoveSpeedPLace(train *state_proto.TrainSta
|
||||
d.speedPlace = nil
|
||||
}
|
||||
}
|
||||
func (d *trainPcSimService) CreateOrRemoveTrain(msgType byte, data []byte) {
|
||||
func (d *trainPcSimService) CreateOrRemoveTrain(msgType byte, data []byte) error {
|
||||
msg := &message.TrainPcSimBaseMessage{Data: data, Type: uint16(msgType)}
|
||||
d.pcSimClient.Send(msg.Encode())
|
||||
return d.pcSimClient.Send(msg.Encode())
|
||||
|
||||
}
|
||||
|
||||
// 依据文档80ms发送列车速度位置
|
||||
@ -167,7 +180,8 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
||||
default:
|
||||
}
|
||||
train := d.trainPcSimManage.GetConnTrain()
|
||||
if train != nil && train.ConnState.Conn {
|
||||
if train != nil && train.ConnState.Conn && train.PluseCount != nil {
|
||||
|
||||
s1, s2 := train.PluseCount.PulseCount1, train.PluseCount.PulseCount2
|
||||
d.speedPlace.ParsePulseCount1(s1, s2)
|
||||
data := d.speedPlace.Encode(train.RunDirection, s1, s2)
|
||||
@ -193,26 +207,34 @@ func (d *trainPcSimService) SendDriverActive(tc *state_proto.TrainConnState, vob
|
||||
d.pcSimClient.Send(msg.Encode())
|
||||
}
|
||||
}
|
||||
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, isBrake bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
|
||||
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
|
||||
if tc.Conn && tc.ConnType == state_proto.TrainConnState_PC_SIM {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
newTraction := vobc.TractionForce
|
||||
newBrake := vobc.BrakeForce
|
||||
if isBrake {
|
||||
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 {
|
||||
if newTraction < oldTraction && newTraction == 0 {
|
||||
newBrake := -vobc.BrakeForce
|
||||
newOldBrakeForce := -oldBrakeForce
|
||||
if tractionState {
|
||||
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 {
|
||||
//手柄前进
|
||||
msg.Type = SENDER_TRAIN_HAND_KEY_FORWARD
|
||||
}
|
||||
|
||||
} else {
|
||||
if newBrake >= newOldBrakeForce && newBrake == 0 {
|
||||
//手柄取消后退
|
||||
msg.Type = RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD
|
||||
} else if newBrake < newOldBrakeForce {
|
||||
//手柄后退
|
||||
msg.Type = RECIVE_TRAIN_HAND_KEY_BACKWARD
|
||||
} else {
|
||||
//手柄后退
|
||||
msg.Type = RECIVE_TRAIN_HAND_KEY_BACKWARD
|
||||
}
|
||||
}
|
||||
d.pcSimClient.Send(msg.Encode())
|
||||
@ -238,6 +260,8 @@ func (d *trainPcSimService) SendBaliseData(msgType uint16, data []byte) {
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Type = msgType
|
||||
msg.Data = data
|
||||
//fmt.Println(fmt.Sprintf("%X", msg.Encode()))
|
||||
|
||||
d.pcSimClient.Send(msg.Encode())
|
||||
}
|
||||
|
||||
@ -254,7 +278,13 @@ func (d *trainPcSimService) PublishTrainControlEvent(world ecs.World, events []T
|
||||
return
|
||||
}
|
||||
for _, event := range events {
|
||||
FireTrainControlEventType.Publish(world, &event)
|
||||
msg := &message.TrainPcSimBaseMessage{}
|
||||
msg.Type = SENDER_TRAIN_OUTR_INFO
|
||||
data := []byte{event.Command, event.Status}
|
||||
msg.Data = data
|
||||
d.pcSimClient.Send(msg.Encode())
|
||||
//FireTrainControlEventType.Publish(world, &event)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"joylink.club/bj-rtsts-server/dto/common_proto"
|
||||
"joylink.club/bj-rtsts-server/service"
|
||||
"joylink.club/bj-rtsts-server/third_party/can_btm"
|
||||
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
||||
"log/slog"
|
||||
"math"
|
||||
"reflect"
|
||||
@ -149,11 +150,15 @@ func TrainConnTypeUpdate(vs *VerifySimulation, ct *dto.TrainConnThirdDto) {
|
||||
return true
|
||||
})
|
||||
}
|
||||
if ct.ConnType == state_proto.TrainConnState_PC_SIM {
|
||||
err := TrainPcSimConnOrRemoveHandle(train)
|
||||
if err != nil {
|
||||
panic(sys_error.New("连接车载PC仿真失败"))
|
||||
}
|
||||
train_pc_sim.Default().SendDriverActive(train.ConnState, train.VobcState)
|
||||
}
|
||||
train.ConnState.Conn = true
|
||||
train.ConnState.ConnType = ct.ConnType
|
||||
if train.ConnState.ConnType == state_proto.TrainConnState_PC_SIM {
|
||||
TrainPcSimConnOrRemoveHandle(train)
|
||||
}
|
||||
}
|
||||
|
||||
// 列车断开三方连接
|
||||
@ -168,8 +173,13 @@ func TrainUnConn(vs *VerifySimulation, trainId string) {
|
||||
train.ConnState.Conn = false
|
||||
train.ConnState.ConnType = state_proto.TrainConnState_NONE
|
||||
if oldType == state_proto.TrainConnState_PC_SIM {
|
||||
TrainPcSimConnOrRemoveHandle(train)
|
||||
err := TrainPcSimConnOrRemoveHandle(train)
|
||||
if err != nil {
|
||||
panic(sys_error.New("未连接车载PC仿真,无法断开连接"))
|
||||
}
|
||||
}
|
||||
train.ConnState.Conn = false
|
||||
train.ConnState.ConnType = state_proto.TrainConnState_NONE
|
||||
}
|
||||
func createOrUpdateStateDynamicConfig(trainState *state_proto.TrainState, configTrainData dto.ConfigTrainData, trainEndsA dto.ConfigTrainEnds,
|
||||
trainEndsB dto.ConfigTrainEnds) {
|
||||
@ -334,24 +344,30 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
||||
const RECEIVE_DYNAMIC_DATA_RATE = 15
|
||||
|
||||
func formatSpeedTime(s int32) int32 {
|
||||
d3, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", s), 64)
|
||||
return int32(math.Abs(math.Round(d3)))
|
||||
//d3, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", s), 64)
|
||||
return int32(math.Abs(math.Round(float64(s))))
|
||||
}
|
||||
func pluseCount(sta *state_proto.TrainState) {
|
||||
if sta.PluseCount == nil {
|
||||
return
|
||||
}
|
||||
if sta.RunDirection {
|
||||
p1 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
p2 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
if sta.TrainEndsA.SpeedSensorEnableA {
|
||||
sta.PluseCount.PulseCount1 += uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
} else if sta.TrainEndsA.SpeedSensorEnableB {
|
||||
sta.PluseCount.PulseCount2 += uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
sta.PluseCount.PulseCount1 = sta.PluseCount.PulseCount1 + p1
|
||||
}
|
||||
if sta.TrainEndsA.SpeedSensorEnableB {
|
||||
sta.PluseCount.PulseCount2 = sta.PluseCount.PulseCount2 + p2
|
||||
}
|
||||
} else {
|
||||
t1 := uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
t2 := uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
if sta.TrainEndsB.SpeedSensorEnableA {
|
||||
sta.PluseCount.PulseCount1 += uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
} else if sta.TrainEndsB.SpeedSensorEnableB {
|
||||
sta.PluseCount.PulseCount2 += uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||
sta.PluseCount.PulseCount1 = sta.PluseCount.PulseCount1 + t1
|
||||
}
|
||||
if sta.TrainEndsB.SpeedSensorEnableB {
|
||||
sta.PluseCount.PulseCount2 = sta.PluseCount.PulseCount2 + t2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ func ControlTrainUpdate(s *VerifySimulation, ct *request_proto.TrainControl) {
|
||||
} else if ct.ControlType == request_proto.TrainControl_HANDLER {
|
||||
oldTraction := sta.VobcState.TractionForce
|
||||
oldBrakeForce := sta.VobcState.BrakeForce
|
||||
isBrake := ct.Handler.Val < 0 //是否制动
|
||||
isTraction := ct.Handler.Val > 0 //是否制动
|
||||
tce = trainControlHandle(sta, ct.Handler, ct.DeviceId, tccGraphicData)
|
||||
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isBrake, sta.ConnState, sta.VobcState)
|
||||
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isTraction, sta.ConnState, sta.VobcState)
|
||||
}
|
||||
|
||||
if sta.ConnState.Conn && sta.ConnState.ConnType == state_proto.TrainConnState_PC_SIM && tce != nil {
|
||||
@ -96,7 +96,10 @@ func trainControlDirKey(trainState *state_proto.TrainState, request *request_pro
|
||||
} else {
|
||||
trainState.Tcc.DirKey.Val = request.Val
|
||||
}
|
||||
return nil
|
||||
tce := make([]train_pc_sim.TrainControlEvent, 0)
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: message.IsTrue(trainState.VobcState.DirectionForward)})
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: message.IsTrue(trainState.VobcState.DirectionBackward)})
|
||||
return tce
|
||||
}
|
||||
|
||||
// 列车驾驶端激活
|
||||
@ -141,17 +144,18 @@ func trainControlHandle(trainState *state_proto.TrainState, request *request_pro
|
||||
trainState.VobcState.BrakeForce = 0
|
||||
trainState.VobcState.MaintainBrakeStatus = false
|
||||
tce := make([]train_pc_sim.TrainControlEvent, 0)
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 0})
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 0})
|
||||
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 0})
|
||||
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 0})
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_TO_ZERO, Status: 0})
|
||||
if request.Val > 0 {
|
||||
trainState.VobcState.TractionStatus = true
|
||||
trainState.VobcState.TractionForce = int64(request.Val * 180)
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 1})
|
||||
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 1})
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 0})
|
||||
} else if request.Val < 0 {
|
||||
trainState.VobcState.BrakingStatus = true
|
||||
trainState.VobcState.BrakeForce = int64(-request.Val * 180)
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 1})
|
||||
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 1})
|
||||
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 1})
|
||||
} else {
|
||||
|
||||
@ -372,13 +376,17 @@ func (s *VerifySimulation) TrainPcSimDigitalReportHandle(data []byte) {
|
||||
}
|
||||
|
||||
// 创建/删除列车
|
||||
func TrainPcSimConnOrRemoveHandle(train *state_proto.TrainState) {
|
||||
func TrainPcSimConnOrRemoveHandle(train *state_proto.TrainState) error {
|
||||
var data byte = 0x01
|
||||
if train.ConnState.Conn == false {
|
||||
data = 0x00
|
||||
}
|
||||
train_pc_sim.Default().CreateOrRemoveTrain(train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE, []byte{data})
|
||||
crErr := train_pc_sim.Default().CreateOrRemoveTrain(train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE, []byte{data})
|
||||
if crErr != nil {
|
||||
return crErr
|
||||
}
|
||||
train_pc_sim.Default().CreateOrRemoveSpeedPLace(train)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 门模式
|
||||
|
Loading…
Reference in New Issue
Block a user