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

218 lines
7.9 KiB
Go
Raw Normal View History

package message
2023-08-18 16:20:40 +08:00
import (
"encoding/binary"
"joylink.club/bj-rtsts-server/dto/state_proto"
"math"
2024-04-09 08:55:33 +08:00
"strconv"
"time"
)
2023-08-23 15:33:07 +08:00
// 接收到的列车控制信息
type TrainControlMsg struct {
ControlInfo *state_proto.TrainVobcState
2024-04-09 08:55:33 +08:00
TrainId string
2024-04-13 09:40:25 +08:00
FromVobc bool
}
func boolsToByte2(flags [8]bool) byte {
var result uint8
for index, b := range flags {
if b {
result = result + (1 << index)
}
}
return result
2024-04-09 08:55:33 +08:00
}
func (r *TrainControlMsg) Encode() []byte {
2024-04-13 09:40:25 +08:00
if !r.FromVobc {
ls := r.ControlInfo.LifeSignal
r.ControlInfo.LifeSignal = ls + 1
2024-05-08 10:00:53 +08:00
r.ControlInfo.UpdateTime = time.Now().UnixMilli()
2024-04-13 09:40:25 +08:00
}
2024-04-15 08:44:37 +08:00
//data := make([]byte, 0)
//data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.LifeSignal))
//var b2 uint8
//b2 = setBit(b2, 0, IsTrue(r.ControlInfo.Tc1Active))
//b2 = setBit(b2, 1, IsTrue(r.ControlInfo.Tc2Active))
//b2 = setBit(b2, 2, IsTrue(r.ControlInfo.DirectionForward))
//b2 = setBit(b2, 3, IsTrue(r.ControlInfo.DirectionBackward))
//b2 = setBit(b2, 4, IsTrue(r.ControlInfo.TractionStatus))
//b2 = setBit(b2, 5, IsTrue(r.ControlInfo.BrakingStatus))
//b2 = setBit(b2, 6, IsTrue(r.ControlInfo.EmergencyBrakingStatus))
//b2 = setBit(b2, 7, IsTrue(r.ControlInfo.TurnbackStatus))
//fmt.Println(fmt.Sprintf("%b", b2))
//var b3 uint8
//b3 = setBit(b3, 0, IsTrue(r.ControlInfo.JumpStatus))
//b3 = setBit(b3, 1, IsTrue(r.ControlInfo.Ato))
//b3 = setBit(b3, 2, IsTrue(r.ControlInfo.Fam))
//b3 = setBit(b3, 3, IsTrue(r.ControlInfo.Cam))
//b3 = setBit(b3, 4, IsTrue(r.ControlInfo.TractionSafetyCircuit))
//b3 = setBit(b3, 5, IsTrue(r.ControlInfo.ParkingBrakeStatus))
//b3 = setBit(b3, 6, IsTrue(r.ControlInfo.MaintainBrakeStatus))
//b3 = setBit(b3, 7, IsTrue(true))
//data = append(data, b2)
//data = append(data, b3)
//data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.TractionForce))
//data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.BrakeForce))
//data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.TrainLoad))
//data = binary.BigEndian.AppendUint16(data, uint16(0)) //预留
//data = binary.BigEndian.AppendUint16(data, uint16(0)) //预留
//data = append(data, uint8(0)) //预留
//var b4 byte
//b4 = setBit(b4, 0, IsTrue(r.ControlInfo.LeftDoorOpenCommand))
//b4 = setBit(b4, 1, IsTrue(r.ControlInfo.RightDoorOpenCommand))
//b4 = setBit(b4, 2, IsTrue(r.ControlInfo.LeftDoorCloseCommand))
//b4 = setBit(b4, 3, IsTrue(r.ControlInfo.RightDoorCloseCommand))
//b4 = setBit(b4, 4, IsTrue(r.ControlInfo.AllDoorClose))
//b4 = setBit(b4, 5, IsTrue(false))
//b4 = setBit(b4, 6, IsTrue(false))
//b4 = setBit(b4, 7, IsTrue(false))
//data = append(data, b4)
//data = binary.BigEndian.AppendUint16(data, 0) //预留
//data = append(data, uint8(0)) //预留
//data = append(data, uint8(0)) //预留
//ti, _ := strconv.Atoi(r.TrainId)
//data = append(data, byte(ti))
//return data
var data []byte
2024-04-09 08:55:33 +08:00
data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.LifeSignal))
2024-04-15 08:44:37 +08:00
data = append(data, boolsToByte([8]bool{
r.ControlInfo.Tc1Active, r.ControlInfo.Tc2Active, r.ControlInfo.DirectionForward, r.ControlInfo.DirectionBackward,
r.ControlInfo.TractionStatus, r.ControlInfo.BrakingStatus, r.ControlInfo.EmergencyBrakingStatus, r.ControlInfo.TurnbackStatus,
}))
data = append(data, boolsToByte([8]bool{
r.ControlInfo.JumpStatus, r.ControlInfo.Ato, r.ControlInfo.Fam, r.ControlInfo.Cam,
r.ControlInfo.TractionSafetyCircuit, r.ControlInfo.ParkingBrakeStatus, r.ControlInfo.MaintainBrakeStatus, false,
}))
2024-04-09 08:55:33 +08:00
data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.TractionForce))
data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.BrakeForce))
data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.TrainLoad))
2024-04-15 08:44:37 +08:00
// 预留
data = binary.BigEndian.AppendUint16(data, 0)
data = binary.BigEndian.AppendUint16(data, 0)
// 预留
data = append(data, uint8(0))
data = append(data, boolsToByte([8]bool{
r.ControlInfo.LeftDoorOpenCommand, r.ControlInfo.RightDoorOpenCommand, r.ControlInfo.LeftDoorCloseCommand, r.ControlInfo.RightDoorCloseCommand,
r.ControlInfo.AllDoorClose, false, false, false,
}))
// 预留
data = binary.BigEndian.AppendUint16(data, 0)
data = append(data, uint8(0))
data = append(data, uint8(0))
2024-04-09 08:55:33 +08:00
ti, _ := strconv.Atoi(r.TrainId)
data = append(data, byte(ti))
return data
}
2024-04-11 08:55:12 +08:00
func GetBit(b byte, bitNum uint) byte {
return (b >> bitNum) & 1
}
2024-04-09 08:55:33 +08:00
func setBit(b byte, bitNum int, value byte) byte {
if value != 0 && value != 1 {
panic("value must be 0 or 1")
}
mask := byte(1 << uint(bitNum)) // 创建掩码
b &= ^(mask) // 清除位
b |= (mask & (value << uint(bitNum)))
return b
2023-08-18 16:20:40 +08:00
}
2023-08-23 15:33:07 +08:00
// 解析VOBC列车信息
func (r *TrainControlMsg) Decode(buf []byte) error {
t := &state_proto.TrainVobcState{}
t.LifeSignal = int32(binary.BigEndian.Uint16(buf[0:2]))
2023-08-23 15:33:07 +08:00
b2 := buf[2]
t.Tc1Active = (b2 & 1) != 0
t.Tc2Active = (b2 & (1 << 1)) != 0
t.DirectionForward = (b2 & (1 << 2)) != 0
t.DirectionBackward = (b2 & (1 << 3)) != 0
t.TractionStatus = (b2 & (1 << 4)) != 0
t.BrakingStatus = (b2 & (1 << 5)) != 0
t.EmergencyBrakingStatus = (b2 & (1 << 6)) != 0
2023-10-25 11:03:19 +08:00
t.TurnbackStatus = (b2 & (1 << 7)) != 0
2023-08-23 15:33:07 +08:00
b3 := buf[3]
t.JumpStatus = (b3 & 1) != 0
t.Ato = (b3 & (1 << 1)) != 0
t.Fam = (b3 & (1 << 2)) != 0
t.Cam = (b3 & (1 << 3)) != 0
t.TractionSafetyCircuit = (b3 & (1 << 4)) != 0
t.ParkingBrakeStatus = (b3 & (1 << 5)) != 0
t.MaintainBrakeStatus = (b3 & (1 << 6)) != 0
t.TractionForce = int64(binary.BigEndian.Uint16(buf[4:6]))
t.BrakeForce = int64(binary.BigEndian.Uint16(buf[6:8]))
t.TrainLoad = int64(binary.BigEndian.Uint16(buf[8:10]))
2023-08-23 15:33:07 +08:00
b4 := buf[15]
t.LeftDoorOpenCommand = (b4 & 1) != 0
t.RightDoorOpenCommand = (b4 & (1 << 1)) != 0
t.LeftDoorCloseCommand = (b4 & (1 << 2)) != 0
t.RightDoorCloseCommand = (b4 & (1 << 3)) != 0
t.AllDoorClose = (b4 & (1 << 4)) != 0
t.UpdateTime = time.Now().UnixMilli()
r.ControlInfo = t
return nil
2023-08-23 15:33:07 +08:00
}
2023-08-18 16:20:40 +08:00
// 发送列车信息
type TrainSpeedMsg struct {
2023-08-18 16:20:40 +08:00
// 生命信号 每个周期+1
lifeSignal uint16
2023-08-18 16:20:40 +08:00
// 列车速度 10=1km/h
speed uint16
// 上坡
upslope bool
// 坡度值 1= 1‰
slope uint16
// 加速度 100 = 1 m/s*s
acceleration uint8
// 减速度 100 = 1 m/s*s
deceleration uint8
// 实际运行阻力 100 = 1KN
totalResistance uint32
// 空气阻力 100 = 1KN
airResistance uint32
// 坡道阻力 100 = 1KN
slopeResistance uint32
// 曲线阻力 100 = 1KN
curveResistance uint32
}
func (t *TrainSpeedMsg) DynamicsDecode(info *DynamicsTrainInfo) {
t.lifeSignal = info.LifeSignal
t.speed = uint16(math.Abs(float64(info.Speed * 36)))
t.upslope = info.UpSlope
t.slope = uint16(info.Slope)
t.totalResistance = uint32(math.Abs(float64(info.TotalResistance / 10)))
t.airResistance = uint32(info.AirResistance / 10)
t.slopeResistance = uint32(math.Abs(float64(info.SlopeResistance / 10)))
t.curveResistance = uint32(info.CurveResistance / 10)
d := math.Abs(float64(info.Acceleration * 100))
if info.Acceleration > 0 {
t.acceleration = uint8(d)
} else {
t.deceleration = uint8(d)
}
}
func (t *TrainSpeedMsg) Encode() []byte {
var data []byte
data = binary.BigEndian.AppendUint16(data, t.lifeSignal)
data = binary.BigEndian.AppendUint16(data, t.speed)
if t.upslope {
data = append(data, 1)
} else {
data = append(data, 0)
}
// 中间预留一位
data = append(data, 0)
data = append(data, t.acceleration) // 加速度 100 = 1 m/s*s
data = append(data, t.deceleration) // 减速度 100 = 1 m/s*s
data = binary.BigEndian.AppendUint32(data, t.totalResistance) // 实际运行阻力 100 = 1KN
data = binary.BigEndian.AppendUint32(data, t.airResistance) // 空气阻力 100 = 1KN
data = binary.BigEndian.AppendUint32(data, t.slopeResistance) // 坡道阻力 100 = 1KN
data = binary.BigEndian.AppendUint32(data, t.curveResistance) // 曲线阻力 100 = 1KN
data = binary.BigEndian.AppendUint16(data, t.slope) // 坡度值 1= 1‰
return data
2023-08-18 16:20:40 +08:00
}