2023-10-19 09:33:40 +08:00
|
|
|
package message
|
2023-08-18 16:20:40 +08:00
|
|
|
|
2023-10-19 14:44:10 +08:00
|
|
|
import (
|
|
|
|
"encoding/binary"
|
2024-01-11 10:24:56 +08:00
|
|
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
2023-10-19 14:44:10 +08:00
|
|
|
"math"
|
2024-04-09 08:55:33 +08:00
|
|
|
"strconv"
|
2023-10-19 14:44:10 +08:00
|
|
|
"time"
|
|
|
|
)
|
2023-08-23 15:33:07 +08:00
|
|
|
|
2023-10-19 09:33:40 +08:00
|
|
|
// 接收到的列车控制信息
|
|
|
|
type TrainControlMsg struct {
|
2024-01-11 10:24:56 +08:00
|
|
|
ControlInfo *state_proto.TrainVobcState
|
2024-04-09 08:55:33 +08:00
|
|
|
TrainId string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *TrainControlMsg) Encode() []byte {
|
|
|
|
data := make([]byte, 0)
|
|
|
|
data = binary.BigEndian.AppendUint16(data, uint16(r.ControlInfo.LifeSignal))
|
|
|
|
var b2 byte
|
|
|
|
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))
|
|
|
|
var b3 byte
|
|
|
|
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))
|
|
|
|
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, 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))
|
|
|
|
data = append(data, b4)
|
|
|
|
data = binary.BigEndian.AppendUint16(data, uint16(0)) //预留
|
|
|
|
data = append(data, 0) //预留
|
|
|
|
data = append(data, 0) //预留
|
|
|
|
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列车信息
|
2023-10-19 14:44:10 +08:00
|
|
|
func (r *TrainControlMsg) Decode(buf []byte) error {
|
2024-01-11 10:24:56 +08:00
|
|
|
t := &state_proto.TrainVobcState{}
|
2023-10-19 14:44:10 +08:00
|
|
|
t.LifeSignal = int32(binary.BigEndian.Uint16(buf[0:2]))
|
2023-08-23 15:33:07 +08:00
|
|
|
b2 := buf[2]
|
2023-10-19 14:44:10 +08:00
|
|
|
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]
|
2023-10-19 14:44:10 +08:00
|
|
|
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]
|
2023-10-19 14:44:10 +08:00
|
|
|
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
|
|
|
// 发送列车信息
|
2023-10-19 09:33:40 +08:00
|
|
|
type TrainSpeedMsg struct {
|
2023-08-18 16:20:40 +08:00
|
|
|
// 生命信号 每个周期+1
|
2023-10-19 14:44:10 +08:00
|
|
|
lifeSignal uint16
|
2023-08-18 16:20:40 +08:00
|
|
|
// 列车速度 10=1km/h
|
2023-10-19 14:44:10 +08:00
|
|
|
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
|
|
|
}
|