列车pc仿真调整
This commit is contained in:
parent
a13a01f99f
commit
20f9ac94c9
@ -250,6 +250,10 @@ type TrainEndsState struct {
|
||||
AccOutSpeed int32 `protobuf:"varint,9,opt,name=accOutSpeed,proto3" json:"accOutSpeed,omitempty"`
|
||||
// 雷达速度输出(米/秒)
|
||||
RadarOutSpeed int32 `protobuf:"varint,10,opt,name=radarOutSpeed,proto3" json:"radarOutSpeed,omitempty"`
|
||||
// 记录雷达设置检测时间的时间点,用于计算周期内的数字
|
||||
RadarCheckTimeOverAt int64 `protobuf:"varint,11,opt,name=radarCheckTimeOverAt,proto3" json:"radarCheckTimeOverAt,omitempty"`
|
||||
// 记录加速度计设置检测时间的时间点,用于计算周期内的数字
|
||||
AccCheckTimeOverAt int64 `protobuf:"varint,12,opt,name=accCheckTimeOverAt,proto3" json:"accCheckTimeOverAt,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TrainEndsState) Reset() {
|
||||
@ -354,6 +358,20 @@ func (x *TrainEndsState) GetRadarOutSpeed() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TrainEndsState) GetRadarCheckTimeOverAt() int64 {
|
||||
if x != nil {
|
||||
return x.RadarCheckTimeOverAt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TrainEndsState) GetAccCheckTimeOverAt() int64 {
|
||||
if x != nil {
|
||||
return x.AccCheckTimeOverAt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_common_data_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_common_data_proto_rawDesc = []byte{
|
||||
@ -398,7 +416,7 @@ var file_common_data_proto_rawDesc = []byte{
|
||||
0x73, 0x74, 0x6f, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x6c, 0x69, 0x64,
|
||||
0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x6c, 0x69, 0x64, 0x65, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x09, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0xa4, 0x03, 0x0a,
|
||||
0x05, 0x52, 0x09, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x88, 0x04, 0x0a,
|
||||
0x0e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x45, 0x6e, 0x64, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
|
||||
0x2e, 0x0a, 0x12, 0x73, 0x70, 0x65, 0x65, 0x64, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x45, 0x6e,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x41, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x70, 0x65,
|
||||
@ -425,10 +443,16 @@ var file_common_data_proto_rawDesc = []byte{
|
||||
0x52, 0x0b, 0x61, 0x63, 0x63, 0x4f, 0x75, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x24, 0x0a,
|
||||
0x0d, 0x72, 0x61, 0x64, 0x61, 0x72, 0x4f, 0x75, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x0a,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x61, 0x64, 0x61, 0x72, 0x4f, 0x75, 0x74, 0x53, 0x70,
|
||||
0x65, 0x65, 0x64, 0x42, 0x2f, 0x5a, 0x2d, 0x6a, 0x6f, 0x79, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x63,
|
||||
0x6c, 0x75, 0x62, 0x2f, 0x62, 0x6a, 0x2d, 0x72, 0x74, 0x73, 0x74, 0x73, 0x2d, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x2f, 0x64, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x72, 0x61, 0x64, 0x61, 0x72, 0x43, 0x68, 0x65, 0x63,
|
||||
0x6b, 0x54, 0x69, 0x6d, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x41, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x14, 0x72, 0x61, 0x64, 0x61, 0x72, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x4f, 0x76, 0x65, 0x72, 0x41, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x43, 0x68,
|
||||
0x65, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x41, 0x74, 0x18, 0x0c, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x12, 0x61, 0x63, 0x63, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x4f, 0x76, 0x65, 0x72, 0x41, 0x74, 0x42, 0x2f, 0x5a, 0x2d, 0x6a, 0x6f, 0x79, 0x6c, 0x69,
|
||||
0x6e, 0x6b, 0x2e, 0x63, 0x6c, 0x75, 0x62, 0x2f, 0x62, 0x6a, 0x2d, 0x72, 0x74, 0x73, 0x74, 0x73,
|
||||
0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x64, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -107,6 +107,7 @@ type ConfigTrainEnds struct {
|
||||
AccCheckTime int32 `json:"accCheckTime"` // 加速计储蓄时间
|
||||
AccOutSpeed int32 `json:"accOutSpeed"` // 速传速度输出
|
||||
RadarOutSpeed int32 `json:"radarOutSpeed"` // 雷达速度输出
|
||||
|
||||
}
|
||||
type ConfigTrainData struct {
|
||||
//Mass int32 `json:"mass" form:"mass"` // 列车的质量(100=1ton)
|
||||
|
@ -1537,7 +1537,7 @@ func (x *TrainDynamicState) GetDisplacement() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// vobc发过来的列车信息
|
||||
// vobc发过来的列车信息 包括 (驾驶台和车载)
|
||||
type TrainVobcState struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit acbfbf8b92d3702a9c0e6434f26fd6db2f57292d
|
||||
Subproject commit 56e1948393aa51e0bf16d754292a211f348df161
|
4
third_party/acc/acc_server_test.go
vendored
4
third_party/acc/acc_server_test.go
vendored
@ -11,7 +11,7 @@ import (
|
||||
func TestAccUdp(t *testing.T) {
|
||||
|
||||
fmt.Println("准备启动ACC服务...")
|
||||
addr := fmt.Sprintf("%v:%v", "127.0.0.1", "8899")
|
||||
addr := fmt.Sprintf("%v:%v", "127.0.0.1", "9998")
|
||||
server := udp.NewServer(addr, handle)
|
||||
server.Listen()
|
||||
select {}
|
||||
@ -23,6 +23,6 @@ func handle(d []byte) {
|
||||
if err == nil {
|
||||
|
||||
jsonD, _ := json.Marshal(ri)
|
||||
fmt.Println(string(jsonD))
|
||||
fmt.Println("接受数据:", string(jsonD))
|
||||
}
|
||||
}
|
||||
|
21
third_party/acc/acc_vobc.go
vendored
21
third_party/acc/acc_vobc.go
vendored
@ -7,14 +7,13 @@ import (
|
||||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AccVobc interface {
|
||||
Start(accManager AccVobcManager)
|
||||
Stop()
|
||||
SendAcc(acc *message.Accelerometer)
|
||||
}
|
||||
|
||||
type AccVobcManager interface {
|
||||
@ -27,10 +26,10 @@ var (
|
||||
singleObj *accVobcService
|
||||
)
|
||||
|
||||
const (
|
||||
/*const (
|
||||
accInterval = 15
|
||||
accSpeedUnit = 9.8
|
||||
)
|
||||
)*/
|
||||
|
||||
func Default() AccVobc {
|
||||
defer initLock.Unlock()
|
||||
@ -52,13 +51,17 @@ func (acc *accVobcService) Start(accManager AccVobcManager) {
|
||||
if config.RemoteIp == "" || config.RemotePort <= 0 || !config.Open {
|
||||
}
|
||||
acc.vobcClient = udp.NewClient(fmt.Sprintf("%v:%v", config.RemoteIp, config.RemotePort))
|
||||
ctx, cancleFunc := context.WithCancel(context.Background())
|
||||
acc.controlContext = cancleFunc
|
||||
//ctx, cancleFunc := context.WithCancel(context.Background())
|
||||
//acc.controlContext = cancleFunc
|
||||
acc.radarVobcManager = accManager
|
||||
go acc.sendTask(ctx)
|
||||
//go acc.sendTask(ctx)
|
||||
}
|
||||
|
||||
func (acc *accVobcService) sendTask(ctx context.Context) {
|
||||
func (avs *accVobcService) SendAcc(acc *message.Accelerometer) {
|
||||
avs.vobcClient.Send(acc.Encode())
|
||||
}
|
||||
|
||||
/*func (acc *accVobcService) sendTask(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@ -74,7 +77,7 @@ func (acc *accVobcService) sendTask(ctx context.Context) {
|
||||
}
|
||||
time.Sleep(time.Millisecond * accInterval)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
func (acc *accVobcService) Stop() {
|
||||
if acc.controlContext != nil {
|
||||
|
1
third_party/dynamics/dynamics.go
vendored
1
third_party/dynamics/dynamics.go
vendored
@ -209,6 +209,7 @@ func (d *dynamics) TrainOperationConfig(req *message.TrainOperationConfig) error
|
||||
return nil
|
||||
}
|
||||
data, _ := json.Marshal(req)
|
||||
//fmt.Println(string(data))
|
||||
url := d.buildUrl("/api/config/")
|
||||
resp, err := d.httpClient.Post(url, "application/json", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
|
@ -57,7 +57,10 @@ func (s *electricalMachineryImpl) SendElectricMachineryMessage(info *message.Ele
|
||||
if s.electricalMachineryUdpClient == nil {
|
||||
return
|
||||
}
|
||||
s.electricalMachineryUdpClient.Send(info.Encode())
|
||||
err := s.electricalMachineryUdpClient.Send(info.Encode())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *electricalMachineryImpl) initElectricalMachinery() {
|
||||
|
18
third_party/electrical_machinery/electrical_machinery_test.go
vendored
Normal file
18
third_party/electrical_machinery/electrical_machinery_test.go
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package electrical_machinery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
udpServer := udp.NewServer(fmt.Sprintf("127.0.0.1:%d", 9999), handleCanetFrames)
|
||||
udpServer.Listen()
|
||||
select {}
|
||||
}
|
||||
func handleCanetFrames(d []byte) {
|
||||
msg := &message.ElectricMachinery{}
|
||||
msg.Decode(d)
|
||||
}
|
42
third_party/message/accelerometer.go
vendored
42
third_party/message/accelerometer.go
vendored
@ -1,9 +1,8 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -12,18 +11,33 @@ const (
|
||||
)
|
||||
|
||||
type Accelerometer struct {
|
||||
Acc uint32
|
||||
Acc float32
|
||||
Aux byte
|
||||
}
|
||||
|
||||
const (
|
||||
FullScaleG = 0x80000000 // 1g的Q31表示
|
||||
DataMask = 0xC0 // 最高2位是数据位
|
||||
ReadingMask = 0xFFFFC000 // 屏蔽标志位和编码位
|
||||
)
|
||||
|
||||
func (acc *Accelerometer) Encode() []byte {
|
||||
accData := uint32(math.Round(float64(acc.Acc) * float64(FullScaleG)))
|
||||
d2 := byte(accData >> 16)
|
||||
d1 := byte(accData >> 8)
|
||||
D0 := byte(accData) & 0xFF
|
||||
D0 |= byte((accData >> 18) & DataMask)
|
||||
data := make([]byte, 0)
|
||||
data = append(data, accHeader)
|
||||
data = append(data, uaidDefault)
|
||||
acc.Acc = acc.Acc | 0x0000FF
|
||||
data = binary.LittleEndian.AppendUint32(data, acc.Acc)
|
||||
data = append(data, D0)
|
||||
data = append(data, d1)
|
||||
data = append(data, d2)
|
||||
data = append(data, acc.Aux)
|
||||
cs := checkSum(data)
|
||||
data = append(data, ^cs+1)
|
||||
return data
|
||||
|
||||
}
|
||||
|
||||
func checkSum(data []byte) byte {
|
||||
@ -34,16 +48,16 @@ func checkSum(data []byte) byte {
|
||||
return sum
|
||||
}
|
||||
|
||||
func (acc *Accelerometer) Decode(data []byte) error {
|
||||
if len(data) < 7 {
|
||||
func (acc *Accelerometer) Decode(Packet []byte) error {
|
||||
if len(Packet) < 7 {
|
||||
return fmt.Errorf("")
|
||||
}
|
||||
buf := bytes.NewBuffer(data)
|
||||
_, _ = buf.ReadByte()
|
||||
_, _ = buf.ReadByte()
|
||||
var dataInt uint32 = 0
|
||||
binary.Read(buf, binary.LittleEndian, &dataInt)
|
||||
//newData := math.Float32frombits(dataInt & 0xffffc000)
|
||||
acc.Acc = dataInt & 0xffffc000
|
||||
data := uint32(Packet[4])<<16 | uint32(Packet[3])<<8 | uint32(Packet[2])
|
||||
// 应用屏蔽以移除标志位和编码位
|
||||
data &= ReadingMask
|
||||
// 将Q31值转换为float32加速度值(g)
|
||||
acceleration := float32(float32(data) * (1.0 / float32(FullScaleG)))
|
||||
|
||||
fmt.Println(acceleration)
|
||||
return nil
|
||||
}
|
||||
|
22
third_party/message/electrical_machinery.go
vendored
22
third_party/message/electrical_machinery.go
vendored
@ -2,6 +2,7 @@ package message
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
@ -17,16 +18,33 @@ type ElectricMachinery struct {
|
||||
|
||||
func (t *ElectricMachinery) Encode() []byte {
|
||||
b := []byte{0x01, 0x10, 0x60, 0xff, 0x00, 0x02, 0x04}
|
||||
//hx := fmt.Sprintf("%X", b)
|
||||
rotarySpeed := t.Speed * 60 / (float32(math.Pi) * float32(t.WheelDiameter) / 1000)
|
||||
var rotarySpeedData uint32
|
||||
if t.IsBack {
|
||||
b = binary.BigEndian.AppendUint32(b, uint32(0-rotarySpeed))
|
||||
//b = binary.BigEndian.AppendUint32(b, uint32(0-rotarySpeed))
|
||||
rotarySpeedData = uint32(0 - rotarySpeed)
|
||||
} else {
|
||||
b = binary.BigEndian.AppendUint32(b, uint32(rotarySpeed))
|
||||
//b = binary.BigEndian.AppendUint32(b, uint32(rotarySpeed))
|
||||
rotarySpeedData = uint32(rotarySpeed)
|
||||
}
|
||||
b = binary.BigEndian.AppendUint32(b, rotarySpeedData)
|
||||
crc := chkcrc(b) // crc校验码
|
||||
b = binary.BigEndian.AppendUint16(b, crc)
|
||||
//fmt.Println("发送:", hx, rotarySpeedData, crc)
|
||||
return b
|
||||
}
|
||||
func (t *ElectricMachinery) Decode(d []byte) error {
|
||||
if len(d) != 13 {
|
||||
return fmt.Errorf("")
|
||||
}
|
||||
h := d[:7]
|
||||
data := binary.BigEndian.Uint32(d[7:11])
|
||||
crc := binary.BigEndian.Uint16(d[11:13])
|
||||
hx := fmt.Sprintf("%X", h)
|
||||
fmt.Println("接收", hx, data, crc)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 生成crc
|
||||
func chkcrc(data []byte) uint16 {
|
||||
|
145
third_party/message/radar.go
vendored
145
third_party/message/radar.go
vendored
@ -4,8 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -13,7 +12,11 @@ const (
|
||||
radar_head2 byte = 0xFC
|
||||
)
|
||||
|
||||
var autoInc = atomic.Int32{}
|
||||
var autoInc byte = 0
|
||||
var (
|
||||
fixed_speed = 0.009155
|
||||
driftDefaultVal = 0.1
|
||||
)
|
||||
|
||||
// 雷达与VOBC接口-雷达通讯协议
|
||||
type RadarInfo struct {
|
||||
@ -27,49 +30,62 @@ type RadarInfo struct {
|
||||
Tail byte
|
||||
}
|
||||
|
||||
func NewRadarSender(speed float32, forward bool, displacement uint16) *RadarInfo {
|
||||
state := &RadarState{SwModel1: 1, SwModel0: 1, calculateBit: 1, signalQualityBit: 1, BlackoutBit: 0, DirectionState: 1, Direction: IsTrue(forward)}
|
||||
ri := &RadarInfo{State: state}
|
||||
ri.RealSpeed = uint16(math.Abs(float64(speed*3.6) / fixed_speed))
|
||||
if float64(displacement/10) > 9999 {
|
||||
ri.DriftCounterS1 = 9999
|
||||
} else {
|
||||
ri.DriftCounterS1 = displacement / 10
|
||||
}
|
||||
if (float64(displacement) / 1000000) > 9999 {
|
||||
ri.DriftCounterS2 = 9999
|
||||
} else {
|
||||
ri.DriftCounterS2 = uint16(float64(displacement) / 1000000)
|
||||
}
|
||||
return ri
|
||||
}
|
||||
|
||||
type RadarState struct {
|
||||
SourceState byte //原数据
|
||||
Model string // 天线模式
|
||||
SyntheticalState string //综合状态
|
||||
DirState string //方向状态
|
||||
Dir byte //方向
|
||||
SwModel1 byte
|
||||
SwModel0 byte
|
||||
calculateBit byte //计算状态位
|
||||
signalQualityBit byte //信号质量标志位
|
||||
BlackoutBit byte //Blackout标志位
|
||||
innerBit byte //内部使用
|
||||
DirectionState byte //方向状态 1:行驶方向有效 0:行驶方向无效
|
||||
Direction byte //行驶方向 1:前向 0:反向
|
||||
|
||||
}
|
||||
|
||||
func (r *RadarState) Encode() byte {
|
||||
var state byte
|
||||
state = setBit(state, 7, r.SwModel1)
|
||||
state = setBit(state, 6, r.SwModel0)
|
||||
state = setBit(state, 5, r.calculateBit)
|
||||
state = setBit(state, 4, r.signalQualityBit)
|
||||
state = setBit(state, 3, r.BlackoutBit)
|
||||
state = setBit(state, 1, r.DirectionState)
|
||||
state = setBit(state, 0, r.Direction)
|
||||
return state
|
||||
}
|
||||
|
||||
func (r RadarInfo) Encode() []byte {
|
||||
buf := make([]byte, 0)
|
||||
buf = append(buf, radar_head1)
|
||||
buf = append(buf, radar_head2)
|
||||
if tmp := autoInc.Add(1); tmp >= 256 {
|
||||
autoInc.Store(0)
|
||||
buf = append(buf, 0)
|
||||
} else {
|
||||
buf = append(buf, byte(tmp))
|
||||
}
|
||||
autoInc = autoInc + 1
|
||||
buf = append(buf, autoInc)
|
||||
|
||||
buf = binary.LittleEndian.AppendUint16(buf, r.RealSpeed)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, r.DriftCounterS1)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, r.DriftCounterS2)
|
||||
//buf = append(buf, byte(r.RealSpeed>>8))
|
||||
//buf = append(buf, byte(r.RealSpeed&0x00FF))
|
||||
//buf = append(buf, byte(r.DriftCounterS1>>8))
|
||||
//buf = append(buf, byte(r.DriftCounterS1&0x00FF))
|
||||
//buf = append(buf, byte(r.DriftCounterS2>>8))
|
||||
//buf = append(buf, byte(r.DriftCounterS2&0x00FF))
|
||||
|
||||
buf = append(buf, 0)
|
||||
buf = append(buf, 0)
|
||||
//6,7位 11
|
||||
//3,4,5位 011
|
||||
// 1位 1
|
||||
//0位 1
|
||||
var state byte
|
||||
state = setBit(state, 7, 1)
|
||||
state = setBit(state, 6, 1)
|
||||
state = setBit(state, 5, 1)
|
||||
state = setBit(state, 4, 1)
|
||||
state = setBit(state, 3, 0)
|
||||
state = setBit(state, 1, 0)
|
||||
state = setBit(state, 0, byte(r.State.Dir))
|
||||
buf = append(buf, state)
|
||||
|
||||
buf = append(buf, r.State.Encode())
|
||||
var sum = 0
|
||||
for _, d := range buf {
|
||||
sum += int(d)
|
||||
@ -105,58 +121,19 @@ func (r *RadarInfo) Decode(data []byte) error {
|
||||
if !(r.Tail == r.createTail()) {
|
||||
return fmt.Errorf("数据解析完成,但协议效验不通过")
|
||||
}
|
||||
state.parseState()
|
||||
|
||||
return nil
|
||||
}
|
||||
func (s *RadarState) parseState() {
|
||||
//第7位 == SW_Mode0, 第6位 == SW_Mode1
|
||||
// 11:两个天线和双通道都OK
|
||||
// 10:DRS05_Single-Mode 40度,50度的天线或通道故障
|
||||
// 01:DRS05_Single-Mode 50度,40度的天线或通道故障
|
||||
// 00:错误模式 双侧天线或通道都故障
|
||||
// 模式的工作差别:工作在11.模式时效果最好。单模式10或01时可信度下降。
|
||||
arr := s.getBitsStateArr()
|
||||
s.Model = bitStateStr(arr[6:])
|
||||
// 第5位=计算状态位,第4位=信号质量标志位,第3位=Black5out标志位
|
||||
// 110:计算状态,高质量
|
||||
// 地面信号反射良好,高精度的信号计算
|
||||
// 100: 计算状态,低质量
|
||||
// 地面信号反射一般,信号计算可能会有缺陷
|
||||
// 001: 处于Blackout 状态
|
||||
// 车辆行驶时无地面反射信号,无法进行信号计算
|
||||
// 000: 信号搜寻状态
|
||||
// 在整个频率范围内搜寻多普勒信号,此时的速度和位移信息无效,当频率搜寻正确后,会转为计算模式。
|
||||
s.SyntheticalState = bitStateStr(arr[3:6])
|
||||
// 第1位 =方向状态
|
||||
// 1:行驶方向有效
|
||||
// 0:行驶方向无效
|
||||
s.DirState = bitStateStr(arr[1:2])
|
||||
// 第0位 =行驶方向
|
||||
// 1:前向
|
||||
// 0:反向
|
||||
s.Dir = arr[0:1][0]
|
||||
func (s *RadarState) Decode(d byte) {
|
||||
s.SwModel1 = GetBit(d, 7)
|
||||
s.SwModel0 = GetBit(d, 6)
|
||||
s.calculateBit = GetBit(d, 5)
|
||||
s.signalQualityBit = GetBit(d, 4)
|
||||
s.BlackoutBit = GetBit(d, 3)
|
||||
s.DirectionState = GetBit(d, 1)
|
||||
s.Direction = GetBit(d, 0)
|
||||
}
|
||||
|
||||
func (s *RadarState) getBitsStateArr() [8]byte {
|
||||
//bits := make([]byte, 8)
|
||||
var bits2 [8]byte = [8]byte{}
|
||||
for i := 0; i < 8; i++ {
|
||||
bit := s.SourceState >> uint(i) & 1
|
||||
bits2[i] = bit
|
||||
}
|
||||
return bits2
|
||||
}
|
||||
|
||||
func bitStateStr(data []byte) string {
|
||||
var build = strings.Builder{}
|
||||
for i := len(data) - 1; i >= 0; i-- {
|
||||
build.WriteString(fmt.Sprintf("%v", data[i]))
|
||||
}
|
||||
/*for _, d := range data {
|
||||
build.WriteString(fmt.Sprintf("%v", d))
|
||||
}*/
|
||||
return build.String()
|
||||
}
|
||||
func culDataSize(d uint16) int {
|
||||
return int(d>>8) + int(d&0x00FF)
|
||||
}
|
||||
@ -169,7 +146,7 @@ func (r *RadarInfo) createTail() byte {
|
||||
sum += culDataSize(r.DriftCounterS2)
|
||||
sum += int(r.InnerCheck1)
|
||||
sum += int(r.InnerCheck2)
|
||||
sum += int(r.State.SourceState)
|
||||
sum += int(r.State.Encode())
|
||||
return byte(^sum + 1)
|
||||
}
|
||||
|
||||
@ -213,7 +190,9 @@ func readRadarState(buf *bytes.Buffer) *RadarState {
|
||||
return nil, fmt.Errorf("")
|
||||
}*/
|
||||
state, _ := buf.ReadByte()
|
||||
return &RadarState{SourceState: state}
|
||||
s := &RadarState{}
|
||||
s.Decode(state)
|
||||
return s
|
||||
}
|
||||
|
||||
func driftCounter(buf *bytes.Buffer) (uint16, error) {
|
||||
|
62
third_party/radar/radar_vobc.go
vendored
62
third_party/radar/radar_vobc.go
vendored
@ -4,23 +4,21 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
"log/slog"
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RadarVobc interface {
|
||||
Start(radar RadarVobcManager)
|
||||
Stop()
|
||||
SendMsg(ri *message.RadarInfo)
|
||||
}
|
||||
|
||||
type RadarVobcManager interface {
|
||||
GetRunRadarConfig() config.RadarConfig
|
||||
FindRadarTrain() *state_proto.TrainState
|
||||
//FindRadarTrain() *state_proto.TrainState
|
||||
}
|
||||
|
||||
const radar_interval = 15
|
||||
@ -55,45 +53,47 @@ func (rv *radarVobc) Start(radar RadarVobcManager) {
|
||||
}
|
||||
|
||||
rv.vobcClient = udp.NewClient(fmt.Sprintf("%v:%v", config.RemoteIp, config.RemotePort))
|
||||
ctx, cancleFunc := context.WithCancel(context.Background())
|
||||
rv.radarVobcTaskContext = cancleFunc
|
||||
//ctx, cancleFunc := context.WithCancel(context.Background())
|
||||
//rv.radarVobcTaskContext = cancleFunc
|
||||
rv.radarVobcManager = radar
|
||||
go rv.sendRadarInfo(ctx)
|
||||
//go rv.sendRadarInfo(ctx)
|
||||
}
|
||||
|
||||
// sendRadarInfo 发送速度,位移计数 给vobc
|
||||
func (rv *radarVobc) SendMsg(ri *message.RadarInfo) {
|
||||
rv.vobcClient.Send(ri.Encode())
|
||||
} // sendRadarInfo 发送速度,位移计数 给vobc
|
||||
/*
|
||||
func (rv *radarVobc) sendRadarInfo(ctx context.Context) {
|
||||
/*defer func() {
|
||||
slog.Error("")
|
||||
}()*/
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
trainStatus := rv.radarVobcManager.FindRadarTrain()
|
||||
if trainStatus != nil {
|
||||
hourSpeed := float64(trainStatus.DynamicState.Speed / 100)
|
||||
trainDift := trainStatus.DynamicState.Displacement
|
||||
td := float64(trainDift / 1000)
|
||||
s1 := uint16(math.Round(td / driftDefaultVal))
|
||||
s2 := uint16(math.Round(td / 1000 / driftDefaultVal))
|
||||
|
||||
ri := message.RadarInfo{RealSpeed: uint16(math.Round(hourSpeed / fixed_speed)), DriftCounterS1: s1, DriftCounterS2: s2}
|
||||
ri.State = &message.RadarState{Dir: message.IsTrue(trainStatus.RunDirection)}
|
||||
rv.vobcClient.SendMsg(ri)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
trainStatus := rv.radarVobcManager.FindRadarTrain()
|
||||
if trainStatus != nil {
|
||||
hourSpeed := float64(trainStatus.DynamicState.Speed / 100)
|
||||
trainDift := trainStatus.DynamicState.Displacement
|
||||
td := float64(trainDift / 1000)
|
||||
s1 := uint16(math.Round(td / driftDefaultVal))
|
||||
s2 := uint16(math.Round(td / 1000 / driftDefaultVal))
|
||||
|
||||
ri := message.RadarInfo{RealSpeed: uint16(math.Round(hourSpeed / fixed_speed)), DriftCounterS1: s1, DriftCounterS2: s2}
|
||||
ri.State = &message.RadarState{Dir: message.IsTrue(trainStatus.RunDirection)}
|
||||
rv.vobcClient.SendMsg(ri)
|
||||
}
|
||||
time.Sleep(time.Millisecond * radar_interval)
|
||||
}
|
||||
time.Sleep(time.Millisecond * radar_interval)
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
func (rv *radarVobc) Stop() {
|
||||
|
||||
if rv.radarVobcTaskContext != nil {
|
||||
/* if rv.radarVobcTaskContext != nil {
|
||||
rv.radarVobcTaskContext()
|
||||
rv.radarVobcTaskContext = nil
|
||||
}
|
||||
}*/
|
||||
if rv.vobcClient != nil {
|
||||
rv.vobcClient.Close()
|
||||
rv.vobcClient = nil
|
||||
|
@ -223,6 +223,23 @@ func UpdateConfigTrain(vs *VerifySimulation, ct *dto.ConfigTrainReqDto) {
|
||||
trainState.TrainLength = ct.Length
|
||||
trainState.WheelDiameter = ct.WheelDiameter
|
||||
requestDynamicConfig(ct)
|
||||
|
||||
if ct.TrainEndsA.RadarCheckTime > 0 {
|
||||
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsA.RadarCheckTime)).Unix()
|
||||
trainState.TrainEndsA.RadarCheckTimeOverAt = timeAt
|
||||
}
|
||||
if ct.TrainEndsB.RadarCheckTime > 0 {
|
||||
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsA.RadarCheckTime)).Unix()
|
||||
trainState.TrainEndsB.RadarCheckTimeOverAt = timeAt
|
||||
}
|
||||
if ct.TrainEndsA.AccCheckTime > 0 {
|
||||
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsA.AccCheckTime)).Unix()
|
||||
trainState.TrainEndsA.AccCheckTimeOverAt = timeAt
|
||||
}
|
||||
if ct.TrainEndsB.AccCheckTime > 0 {
|
||||
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsB.AccCheckTime)).Unix()
|
||||
trainState.TrainEndsB.AccCheckTimeOverAt = timeAt
|
||||
}
|
||||
}
|
||||
|
||||
func requestDynamicConfig(ct *dto.ConfigTrainReqDto) {
|
||||
@ -328,6 +345,7 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
||||
sta.DynamicState.RampResistance = float32(info.SlopeResistance) / 1000
|
||||
sta.DynamicState.CurveResistance = float32(info.CurveResistance) / 1000
|
||||
sta.DynamicState.Speed = speedParse(info.Speed)
|
||||
|
||||
sta.DynamicState.HeadSensorSpeed1 = speedParse(info.HeadSpeed1)
|
||||
sta.DynamicState.HeadSensorSpeed2 = speedParse(info.HeadSpeed2)
|
||||
sta.DynamicState.TailSensorSpeed1 = speedParse(info.TailSpeed1)
|
||||
@ -335,6 +353,7 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
||||
sta.DynamicState.HeadRadarSpeed = speedParse(info.HeadRadarSpeed)
|
||||
sta.DynamicState.TailRadarSpeed = speedParse(info.TailRadarSpeed)
|
||||
sta.DynamicState.Acceleration = info.Acceleration
|
||||
|
||||
sta.DynamicState.Displacement = int32(info.Displacement)
|
||||
pluseCount(sta)
|
||||
return sta
|
||||
|
@ -4,12 +4,16 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/dto/common_proto"
|
||||
"joylink.club/bj-rtsts-server/third_party/acc"
|
||||
"joylink.club/bj-rtsts-server/third_party/radar"
|
||||
"log/slog"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"joylink.club/bj-rtsts-server/dto"
|
||||
@ -287,12 +291,123 @@ func (s *VerifySimulation) HandleDynamicsTrainInfo(info *message.DynamicsTrainIn
|
||||
}
|
||||
// 更新列车状态
|
||||
trainState := UpdateTrainStateByDynamics(s, trainId, info)
|
||||
// 更新电机转速
|
||||
electrical_machinery.Default().SendElectricMachineryMessage(&message.ElectricMachinery{
|
||||
Speed: info.Speed,
|
||||
WheelDiameter: trainState.WheelDiameter,
|
||||
IsBack: trainState.VobcState.DirectionBackward,
|
||||
})
|
||||
sendElectricalMachinery(info, trainState)
|
||||
sendRadar(info, trainState)
|
||||
sendAcc(info, trainState)
|
||||
}
|
||||
|
||||
// 发送电机控制命令
|
||||
func sendElectricalMachinery(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) {
|
||||
speed := info.Speed
|
||||
sendMachinery := false
|
||||
if trainState.VobcState.DirectionForward {
|
||||
if trainState.TrainEndsA.SpeedSensorEnableA || trainState.TrainEndsA.SpeedSensorEnableB {
|
||||
sendMachinery = true
|
||||
speed = info.HeadSpeed2
|
||||
if trainState.TrainEndsA.AccOutSpeed > 0 {
|
||||
speed = float32(trainState.TrainEndsA.AccOutSpeed)
|
||||
} else if trainState.TrainEndsA.SpeedSensorEnableA {
|
||||
speed = info.HeadSpeed1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if trainState.TrainEndsB.SpeedSensorEnableA || trainState.TrainEndsB.SpeedSensorEnableB {
|
||||
sendMachinery = true
|
||||
speed = info.TailSpeed2
|
||||
if trainState.TrainEndsB.AccOutSpeed > 0 {
|
||||
speed = float32(trainState.TrainEndsB.AccOutSpeed)
|
||||
} else if trainState.TrainEndsB.SpeedSensorEnableA {
|
||||
speed = info.TailSpeed1
|
||||
}
|
||||
}
|
||||
}
|
||||
if sendMachinery {
|
||||
// 更新电机转速
|
||||
electrical_machinery.Default().SendElectricMachineryMessage(&message.ElectricMachinery{
|
||||
Speed: speed,
|
||||
WheelDiameter: trainState.WheelDiameter,
|
||||
IsBack: trainState.VobcState.DirectionBackward,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 发送雷达数据
|
||||
func sendRadar(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) {
|
||||
if trainState.VobcState.DirectionForward && trainState.TrainEndsA.RadarEnable {
|
||||
s := parseRadarSpeedData(info.Speed, trainState.TrainEndsA)
|
||||
radar.Default().SendMsg(message.NewRadarSender(s, true, info.Displacement))
|
||||
} else if trainState.VobcState.DirectionBackward && trainState.TrainEndsB.RadarEnable {
|
||||
s := parseRadarSpeedData(info.Speed, trainState.TrainEndsB)
|
||||
radar.Default().SendMsg(message.NewRadarSender(s, false, info.Displacement))
|
||||
} else {
|
||||
slog.Error("列车行驶方向不确定或两端的雷达均未启用", "列车前进=", trainState.VobcState.DirectionForward, "雷达启用A=", trainState.TrainEndsA.RadarEnable, "列车后退=", trainState.VobcState.DirectionBackward, "雷达启用B=", trainState.TrainEndsB.RadarEnable)
|
||||
}
|
||||
}
|
||||
func parseRadarSpeedData(radarSpeed float32, trainEndState *common_proto.TrainEndsState) float32 {
|
||||
//如果差值速度和速度输出都填写,那么就以速度输出为优先
|
||||
//如果动力学速度-差值速度小于0,呢么输出的就是0(不能小于0)
|
||||
timeOver := false
|
||||
if time.Now().Unix() > trainEndState.RadarCheckTimeOverAt && trainEndState.RadarCheckTimeOverAt != 0 {
|
||||
//判断雷达检测时间是否到期
|
||||
timeOver = true
|
||||
}
|
||||
|
||||
if trainEndState.RadarCheckSpeedDiff > 0 && trainEndState.RadarOutSpeed > 0 {
|
||||
if timeOver {
|
||||
//超时以动力学雷达速度为主
|
||||
return radarSpeed
|
||||
} else {
|
||||
//如果雷达检测速度差值和速度输出都填写,那么就以速度输出为优先
|
||||
return float32(trainEndState.RadarOutSpeed)
|
||||
}
|
||||
} else if trainEndState.RadarCheckSpeedDiff > 0 {
|
||||
if timeOver {
|
||||
return radarSpeed
|
||||
} else {
|
||||
//如果雷达检测速度差值填写,那么就以速度差值为主
|
||||
return float32(math.Max(float64(radarSpeed)-float64(trainEndState.RadarCheckSpeedDiff), 0))
|
||||
}
|
||||
} else if trainEndState.RadarOutSpeed > 0 {
|
||||
if timeOver {
|
||||
return radarSpeed
|
||||
} else {
|
||||
//如果雷达速度输出填写,那么就以速度输出为主
|
||||
return float32(trainEndState.RadarOutSpeed)
|
||||
}
|
||||
} else {
|
||||
return radarSpeed
|
||||
}
|
||||
}
|
||||
|
||||
func sendAcc(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) {
|
||||
if trainState.VobcState.DirectionForward && trainState.TrainEndsA.AccEnable {
|
||||
s := parseAccSpeedData(info.Acceleration, trainState.TrainEndsA)
|
||||
acc.Default().SendAcc(&message.Accelerometer{Acc: s})
|
||||
} else if trainState.VobcState.DirectionBackward && trainState.TrainEndsB.AccEnable {
|
||||
s := parseAccSpeedData(info.Acceleration, trainState.TrainEndsB)
|
||||
acc.Default().SendAcc(&message.Accelerometer{Acc: s})
|
||||
} else {
|
||||
slog.Error("列车行驶方向不确定或两端的雷达均未启用", "列车前进=", trainState.VobcState.DirectionForward, "雷达启用A=", trainState.TrainEndsA.RadarEnable, "列车后退=", trainState.VobcState.DirectionBackward, "雷达启用B=", trainState.TrainEndsB.RadarEnable)
|
||||
}
|
||||
}
|
||||
func parseAccSpeedData(accSpeed float32, trainEndState *common_proto.TrainEndsState) float32 {
|
||||
//如果差值速度和速度输出都填写,那么就以速度输出为优先
|
||||
//如果动力学速度-差值速度小于0,呢么输出的就是0(不能小于0)
|
||||
timeOver := false
|
||||
if time.Now().Unix() > trainEndState.AccCheckTimeOverAt && trainEndState.AccCheckTimeOverAt != 0 {
|
||||
//判断雷达检测时间是否到期
|
||||
timeOver = true
|
||||
}
|
||||
if trainEndState.AccCheckSpeedDiff > 0 {
|
||||
if timeOver {
|
||||
return accSpeed
|
||||
} else {
|
||||
//如果雷达检测速度差值填写,那么就以速度差值为主
|
||||
return float32(math.Max(float64(accSpeed)-float64(trainEndState.AccCheckSpeedDiff), 0))
|
||||
}
|
||||
} else {
|
||||
return accSpeed
|
||||
}
|
||||
}
|
||||
|
||||
// 获取动力学配置信息
|
||||
@ -581,7 +696,7 @@ func (s *VerifySimulation) GetRunAccConfig() config.AccConfig {
|
||||
}
|
||||
|
||||
// FindRadarTrain 查找一个列车 只有1端雷达开启啊
|
||||
func (s *VerifySimulation) FindRadarTrain() *state_proto.TrainState {
|
||||
/*func (s *VerifySimulation) FindRadarTrain() *state_proto.TrainState {
|
||||
var trainStatus *state_proto.TrainState
|
||||
s.Memory.Status.TrainStateMap.Range(func(k any, v any) bool {
|
||||
val, ok := v.(*state_proto.TrainState)
|
||||
@ -590,18 +705,11 @@ func (s *VerifySimulation) FindRadarTrain() *state_proto.TrainState {
|
||||
trainStatus = val
|
||||
return false
|
||||
}
|
||||
/*if val.TrainEndsA.RadarEnable && val.TrainEndsB.RadarEnable {
|
||||
|
||||
return true
|
||||
} else if val.TrainEndsA.RadarEnable || val.TrainEndsB.RadarEnable {
|
||||
trainStatus = val
|
||||
return false
|
||||
}*/
|
||||
}
|
||||
return true
|
||||
})
|
||||
return trainStatus
|
||||
}
|
||||
}*/
|
||||
|
||||
// FindRadarTrain 查找一个列车 只有1端雷达开启啊
|
||||
func (s *VerifySimulation) FindAccTrain() *state_proto.TrainState {
|
||||
|
Loading…
Reference in New Issue
Block a user