rts-sim-testing-service/third_party/message/train_pc_sim_message.go

259 lines
5.9 KiB
Go
Raw Normal View History

2024-04-09 08:55:33 +08:00
package message
import (
"bytes"
"encoding/binary"
"fmt"
"strconv"
"time"
)
const PC_SIM_HEADER = 0xEB
type TrainPcSimBaseMessage struct {
2024-06-13 18:13:21 +08:00
Type byte
2024-04-09 08:55:33 +08:00
DataLen byte
Data []byte
Crc uint16 // 校验码
}
// 编码
func (tp *TrainPcSimBaseMessage) Encode() []byte {
pack := make([]byte, 0)
pack = append(pack, PC_SIM_HEADER)
2024-06-13 18:13:21 +08:00
pack = append(pack, tp.Type)
pack = append(pack, byte(len(tp.Data)+1+1+1+2))
if len(tp.Data) > 0 {
2024-06-18 17:10:21 +08:00
pack = append(pack, tp.Data...)
//dataBufs := bytes.NewBuffer(nil)
//binary.Write(dataBufs, binary.BigEndian, tp.Data)
//data := dataBufs.Bytes()
//pack = append(pack, data...)
2024-06-13 18:13:21 +08:00
}
2024-06-27 10:37:52 +08:00
pack = binary.BigEndian.AppendUint16(pack, uint16(0xffff))
//pack = binary.BigEndian.AppendUint16(pack, uint16(crc.CalculateCRC(crc.CRC16, pack[1:])))
2024-04-09 08:55:33 +08:00
return pack
}
2024-06-27 10:37:52 +08:00
func TrainPcSimDecode(data []byte) []*TrainPcSimBaseMessage {
bms := make([]*TrainPcSimBaseMessage, 0)
buf := bytes.NewBuffer(data)
//hexData := hex.EncodeToString(data)
for {
if buf.Len() < 3 {
return bms /*, fmt.Errorf("解析仿真pc数据失败数据长度小于3")*/
}
header, _ := buf.ReadByte()
if header != PC_SIM_HEADER {
return bms /*, fmt.Errorf("数据包头错误,数据头为%v", hexData)*/
}
msgType, _ := buf.ReadByte()
dataLen, _ := buf.ReadByte()
dataLen = dataLen - 3 - 2
if buf.Len() < int(dataLen) {
return bms /*, fmt.Errorf("数据长度不够,数据类型为%v,需要长度:%v,实际长度:%v", msgType, dataLen, buf.Len())*/
}
sourceData := make([]byte, dataLen)
buf.Read(sourceData)
var crc uint16
binary.Read(buf, binary.BigEndian, &crc)
bms = append(bms, &TrainPcSimBaseMessage{Type: msgType, DataLen: dataLen - 2, Data: sourceData, Crc: crc})
}
return bms
}
2024-04-09 08:55:33 +08:00
// 解码
func (tp *TrainPcSimBaseMessage) Decode(data []byte) error {
if len(data) < 3 {
return fmt.Errorf("")
}
buf := bytes.NewBuffer(data)
h, _ := buf.ReadByte()
if h != PC_SIM_HEADER {
return fmt.Errorf("")
}
2024-06-13 18:13:21 +08:00
var pcType byte
pcType, _ = buf.ReadByte()
dataLen, _ := buf.ReadByte()
2024-06-18 17:10:21 +08:00
dataLen = dataLen - 3
if buf.Len() < int(dataLen) {
2024-04-09 08:55:33 +08:00
return fmt.Errorf("")
}
2024-06-18 17:10:21 +08:00
var dd = make([]byte, dataLen-2)
2024-04-09 08:55:33 +08:00
binary.Read(buf, binary.BigEndian, &dd)
var crcCode uint16
binary.Read(buf, binary.BigEndian, &crcCode)
tp.Type = pcType
2024-06-13 18:13:21 +08:00
tp.DataLen = dataLen
2024-04-09 08:55:33 +08:00
tp.Data = dd
tp.Crc = crcCode
return nil
//crc.CalculateCRC(crc.CRC16, data)
}
func IsTrue(d bool) byte {
if d {
return 1
}
return 0
}
func IsTrueForByte(d byte) bool {
if d == 1 {
return true
}
return false
}
// 确定、否定是你软件里的概念吧比如ATP输出量---紧急我们就认为是低电平有效。即0代表有紧急1代表无紧急
// 比如ATP的输入量---钥匙我们认为是高电平有效即1代表上钥匙0代表下钥匙。
func AtpLowPowerByte(d byte) bool {
if d == 0 {
return true
}
return false
}
2024-04-09 08:55:33 +08:00
// 列车速度位置报告
type TrainSpeedPlaceReportMsg struct {
PulseCount1 uint32
PulseCount2 uint32
}
func (tp *TrainSpeedPlaceReportMsg) ParsePulseCount1(s1, s2 uint32) {
tp.PulseCount1 += s1
tp.PulseCount2 += s2
}
func (tp *TrainSpeedPlaceReportMsg) Encode(runDir bool, s1, s2 uint32) []byte {
data := make([]byte, 0)
2024-04-16 17:26:37 +08:00
data = binary.BigEndian.AppendUint16(data, uint16(IsTrue(runDir)))
data = binary.BigEndian.AppendUint32(data, s1)
data = binary.BigEndian.AppendUint32(data, s2)
data = binary.BigEndian.AppendUint32(data, tp.PulseCount1)
data = binary.BigEndian.AppendUint32(data, tp.PulseCount2)
2024-04-09 08:55:33 +08:00
now := time.Now().UTC()
// 将时间转换为毫秒
millis := now.UnixNano() / int64(time.Millisecond)
millisStr := strconv.Itoa(int(millis))
strs := []rune(millisStr)
second, _ := strconv.Atoi(string(strs[:len(strs)-3]))
mm, _ := strconv.Atoi(string(strs[len(strs)-3:]))
2024-04-16 17:26:37 +08:00
data = binary.BigEndian.AppendUint32(data, uint32(second))
data = binary.BigEndian.AppendUint16(data, uint16(mm))
2024-04-09 08:55:33 +08:00
return data
}
2024-04-18 11:14:05 +08:00
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)
2024-06-27 10:37:52 +08:00
var mts uint16
binary.Read(buf, binary.BigEndian, &mts)
fmt.Println(fmt.Sprintf("列车方向:%v,1路脉冲数:%v,2路脉冲数:%v,1路累计数:%v,2路累计数:%v,时间:%v,时间(毫秒):%v", runDir, s1, s2, c1, c2, ts, mts))
2024-04-18 11:14:05 +08:00
}
2024-04-09 08:55:33 +08:00
// 轨旁向列车pc仿真发送的命令码
const (
2024-06-27 10:37:52 +08:00
//手柄零位方向向前
DIR_ZERO_FORWARD = 0x2d
2024-04-09 08:55:33 +08:00
//钥匙开关状态
2024-06-27 10:37:52 +08:00
KEY_STATE = iota - 1
2024-04-09 08:55:33 +08:00
//手柄向前控制
HANDLE_FORWORD
//手柄向后控制
HANDLE_BACKWORD
//外部紧急制动反馈
OUTER_EMERGENCY_BRAKE
//列车制动状态
TRAIN_BRAKE_STATE
//开左门
LEFT_OPEN_DOOR
//关右门
CLOSE_RIGHT_DOOR
//关左门
CLOSE_LEFT_DOOR
//开右门
OPEN_RIGHT_DOOR
//折返按钮
TURN_BACK
//强制门允许
FORCE_DOOR_ALLOW
//模式降级按钮
TRAIN_MODE_DOWN
//确认按钮
CONFIRM
//模式升级按钮
TRAIN_MODE_UP
//牵引制动手柄零位
HANDLE_TO_ZERO
//ATO发车按钮
ATO_SEND_TRAIN
//列车完整性
TRAIN_INTEGRITY
//车载ATP/ATO旁路状态
ATP_ATO_BYPASS_STATe
//车辆牵引已切除状态
TRAIN_TRACTION_CUTED
//障碍物检测按钮
OBSTACLE_CHECK
//驾驶室激活反馈按钮
DRIVER_ACTIVE_REPORT
//制动重故障按钮
BRAKE_HEAVY_FAULT
//左门状态按钮
LEFT_DOOR_STATE
//右门状态按钮
RIGHT_DOOR_STATE
//唤醒按钮
WAKE_UP
//检修按钮
OVERHAUL
//欠压按钮
UNDERVOLTAGE
//休眠按钮
SLEEP
_
//紧急手柄拉下
EMERGENT_HANDLE_DOWN
//车门锁闭状态
DOOR_LOCK_STATE
//逃生门状态
LIFE_DOOR
//车辆低压上电状态
TRAIN_LOW_POWER
//ATP上电按钮
ATP_POWER_ON
//atp切除
ATP_CUT
2024-04-09 08:55:33 +08:00
//AA自动开关门
DOOR_MODE_AA
//AM自开人关
DOOR_MODE_AM
//MM人开人关
DOOR_MODE_MM
2024-07-11 14:58:34 +08:00
_
NOT_BREAK
2024-04-09 08:55:33 +08:00
)