Compare commits
5 Commits
a67b02c389
...
39f01066ad
Author | SHA1 | Date | |
---|---|---|---|
|
39f01066ad | ||
|
4901c00199 | ||
|
20f9ac94c9 | ||
|
a13a01f99f | ||
|
4666c84860 |
@ -61,17 +61,18 @@ type mqtt struct {
|
||||
|
||||
// 第三方配置结构
|
||||
type ThridPartyConfig struct {
|
||||
Id int32 `json:"id"`
|
||||
Dynamics DynamicsConfig `json:"dynamics" description:"动力学配置"`
|
||||
Vobc VobcConfig `json:"vobc" description:"半实物配置"`
|
||||
Interlocks []InterlockConfig `json:"interlock" description:"联锁配置"`
|
||||
RsspAxleCfgs []RsspAxleConfig `json:"rsspAxleCfgs" description:"所有联锁集中站计轴RSSP-I配置"`
|
||||
ElectricMachinery ElectricMachineryConfig `json:"electricMachinery" description:"电机配置"`
|
||||
BtmCanet BtmCanetConfig `json:"btmCanet" description:"BTM关联的网关设备CANET配置"`
|
||||
CidcModbus []CidcModbusConfig `json:"cidcModbus" description:"联锁驱采Modbus接口配置"`
|
||||
Radar RadarConfig `json:"radar" description:"车载雷达相关配置"`
|
||||
Acc AccConfig `json:"acc" description:"车载加速计"`
|
||||
PcSimConfig VehiclePCSimConfig `json:"pcSimConfig" description:"车载pc仿真平台通信"`
|
||||
Id int32 `json:"id"`
|
||||
Dynamics DynamicsConfig `json:"dynamics" description:"动力学配置"`
|
||||
Vobc VobcConfig `json:"vobc" description:"半实物配置"`
|
||||
Interlocks []InterlockConfig `json:"interlock" description:"联锁配置"`
|
||||
RsspAxleCfgs []RsspAxleConfig `json:"rsspAxleCfgs" description:"所有联锁集中站计轴RSSP-I配置"`
|
||||
//ElectricMachinery ElectricMachineryConfig `json:"electricMachinery" description:"电机配置"`
|
||||
ElectricMachinerys []ElectricMachineryConfig `json:"electricMachinerys" description:"电机配置"`
|
||||
BtmCanet BtmCanetConfig `json:"btmCanet" description:"BTM关联的网关设备CANET配置"`
|
||||
CidcModbus []CidcModbusConfig `json:"cidcModbus" description:"联锁驱采Modbus接口配置"`
|
||||
Radar RadarConfig `json:"radar" description:"车载雷达相关配置"`
|
||||
Acc AccConfig `json:"acc" description:"车载加速计"`
|
||||
PcSimConfig VehiclePCSimConfig `json:"pcSimConfig" description:"车载pc仿真平台通信"`
|
||||
}
|
||||
type RadarConfig struct {
|
||||
Open bool `json:"open" description:"是否开启"`
|
||||
@ -128,6 +129,7 @@ type ElectricMachineryConfig struct {
|
||||
Ip string `json:"ip" description:"IP配置"`
|
||||
RemotePort int `json:"remotePort" description:"远端接收信息端口"`
|
||||
Open bool `json:"open" description:"是否开启"`
|
||||
EndPointA bool `json:"endPointA" description:"一号电机"`
|
||||
}
|
||||
|
||||
// BtmCanetConfig BTM CANET网关设备配置
|
||||
|
@ -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 (
|
||||
|
@ -99,14 +99,15 @@ type ConfigTrainEnds struct {
|
||||
SpeedSensorEnableA bool `json:"speedSensorEnableA"` // 2端速度传感器是否有效
|
||||
SpeedSensorEnableB bool `json:"speedSensorEnableB"` // 2端速度传感器是否有效
|
||||
RadarEnable bool `json:"radarEnable"` // 雷达是否有效
|
||||
RadarCheckSpeedDiff float32 `json:"radarCheckSpeedDiff"` // 雷达测速数值
|
||||
RadarCheckSpeedDiff float32 `json:"radarCheckSpeedDiff"` // 雷达测速数值(千米/小时)
|
||||
RadarCheckTime int32 `json:"radarCheckTime"` // 雷达检测时间(秒)
|
||||
|
||||
AccEnable bool `json:"accEnable"` // 加速计是否有效
|
||||
AccCheckSpeedDiff float32 `json:"accCheckSpeedDiff"` // 加速计速度差
|
||||
AccCheckTime int32 `json:"accCheckTime"` // 加速计储蓄时间
|
||||
AccOutSpeed int32 `json:"accOutSpeed"` // 速传速度输出
|
||||
RadarOutSpeed int32 `json:"radarOutSpeed"` // 雷达速度输出
|
||||
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
|
||||
|
@ -511,9 +511,11 @@ func convertTrainState(v *state_proto.TrainState) *state_proto.TrainMapState {
|
||||
convertDynamicConfig(v.TrainDynamicConfig, t.TrainDynamicConfig)
|
||||
convertDynamicConfig(v.TrainEndsA, t.TrainEndsA)
|
||||
convertDynamicConfig(v.TrainEndsB, t.TrainEndsB)
|
||||
//now := time.Now().Unix()
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func convertDynamicConfig(config, dest interface{}) {
|
||||
configType := reflect.TypeOf(config).Elem()
|
||||
for index := 0; index < configType.NumField(); index++ {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit acbfbf8b92d3702a9c0e6434f26fd6db2f57292d
|
||||
Subproject commit 121134778a38df672562fd8d1acb1482a327702f
|
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))
|
||||
}
|
||||
}
|
||||
|
50
third_party/acc/acc_vobc.go
vendored
50
third_party/acc/acc_vobc.go
vendored
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"joylink.club/bj-rtsts-server/dto/common_proto"
|
||||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
@ -15,6 +16,8 @@ import (
|
||||
type AccVobc interface {
|
||||
Start(accManager AccVobcManager)
|
||||
Stop()
|
||||
SendAcc(acc *message.Accelerometer)
|
||||
TrainAccSender(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState)
|
||||
}
|
||||
|
||||
type AccVobcManager interface {
|
||||
@ -27,10 +30,10 @@ var (
|
||||
singleObj *accVobcService
|
||||
)
|
||||
|
||||
const (
|
||||
/*const (
|
||||
accInterval = 15
|
||||
accSpeedUnit = 9.8
|
||||
)
|
||||
)*/
|
||||
|
||||
func Default() AccVobc {
|
||||
defer initLock.Unlock()
|
||||
@ -52,13 +55,46 @@ 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
|
||||
acc.radarVobcManager = accManager
|
||||
go acc.sendTask(ctx)
|
||||
}
|
||||
|
||||
func (acc *accVobcService) sendTask(ctx context.Context) {
|
||||
func (avs *accVobcService) SendAcc(acc *message.Accelerometer) {
|
||||
avs.vobcClient.Send(acc.Encode())
|
||||
}
|
||||
func (avs *accVobcService) TrainAccSender(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) {
|
||||
if trainState.VobcState.Tc1Active && trainState.TrainEndsA.AccEnable {
|
||||
s := parseAccSpeedData(info.Acceleration, trainState.TrainEndsA)
|
||||
avs.SendAcc(&message.Accelerometer{Acc: s})
|
||||
} else if trainState.VobcState.Tc2Active && trainState.TrainEndsB.AccEnable {
|
||||
s := parseAccSpeedData(info.Acceleration, trainState.TrainEndsB)
|
||||
avs.SendAcc(&message.Accelerometer{Acc: s})
|
||||
} else {
|
||||
avs.SendAcc(&message.Accelerometer{Acc: 0})
|
||||
}
|
||||
}
|
||||
|
||||
func parseAccSpeedData(accSpeed float32, trainEndState *common_proto.TrainEndsState) float32 {
|
||||
//如果差值速度和速度输出都填写,那么就以速度输出为优先
|
||||
//如果动力学速度-差值速度小于0,呢么输出的就是0(不能小于0)
|
||||
|
||||
trainEndState.AccCheckTime = int32(trainEndState.AccCheckTimeOverAt - time.Now().Unix())
|
||||
if trainEndState.AccCheckTime <= 0 {
|
||||
//判断雷达检测时间是否到期
|
||||
trainEndState.AccCheckTime = 0
|
||||
if trainEndState.AccCheckTimeOverAt != 0 {
|
||||
trainEndState.AccCheckSpeedDiff = 0
|
||||
return accSpeed
|
||||
}
|
||||
}
|
||||
if trainEndState.AccCheckSpeedDiff > 0 {
|
||||
//如果雷达检测速度差值填写,那么就以速度差值为主
|
||||
return float32(math.Abs(float64(accSpeed - trainEndState.AccCheckSpeedDiff)))
|
||||
} else {
|
||||
return accSpeed
|
||||
}
|
||||
}
|
||||
|
||||
/*func (acc *accVobcService) sendTask(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@ -74,7 +110,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 {
|
||||
|
@ -2,6 +2,8 @@ package electrical_machinery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/dto/common_proto"
|
||||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||
"sync"
|
||||
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
@ -9,22 +11,30 @@ import (
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
)
|
||||
|
||||
const (
|
||||
PointA = iota + 1
|
||||
PointB
|
||||
)
|
||||
|
||||
// 电机转速UDP
|
||||
type ElectricMachinery interface {
|
||||
Start(manager ElectricMachineryMessageManager) // 启动电机转速UDP消息处理
|
||||
Stop() // 停止电机转速消息处理
|
||||
SendElectricMachineryMessage(info *message.ElectricMachinery) // 发送电机转速消息
|
||||
Start(manager ElectricMachineryMessageManager) // 启动电机转速UDP消息处理
|
||||
Stop() // 停止电机转速消息处理
|
||||
SendElectricMachineryMessage(emMap map[int]*message.ElectricMachinery) // 发送电机转速消息
|
||||
SendElectricMachineryMessage2(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) // 发送电机转速消息
|
||||
|
||||
}
|
||||
|
||||
type ElectricMachineryMessageManager interface {
|
||||
GetElectricMachineryRunConfig() *config.ElectricMachineryConfig // 获取电机转速参数
|
||||
GetElectricMachineryRunConfig() []config.ElectricMachineryConfig // 获取电机转速参数
|
||||
}
|
||||
|
||||
type electricalMachineryImpl struct {
|
||||
electricalMachineryUdpClient udp.UdpClient
|
||||
//electricalMachineryUdpClient udp.UdpClient
|
||||
|
||||
manager ElectricMachineryMessageManager
|
||||
runConfig *config.ElectricMachineryConfig
|
||||
electricalMachineryUdpClientMap map[int]udp.UdpClient
|
||||
manager ElectricMachineryMessageManager
|
||||
runConfig []config.ElectricMachineryConfig
|
||||
}
|
||||
|
||||
func (s *electricalMachineryImpl) Start(manager ElectricMachineryMessageManager) {
|
||||
@ -35,7 +45,13 @@ func (s *electricalMachineryImpl) Start(manager ElectricMachineryMessageManager)
|
||||
panic("启动电机转速消息服务错误: 存在正在运行的任务")
|
||||
}
|
||||
s.runConfig = manager.GetElectricMachineryRunConfig()
|
||||
if s.runConfig == nil || s.runConfig.Ip == "" || !s.runConfig.Open {
|
||||
allNotOpen := true
|
||||
for _, c := range s.runConfig {
|
||||
if &c == nil || c.Ip == "" || !c.Open {
|
||||
allNotOpen = false
|
||||
}
|
||||
}
|
||||
if allNotOpen {
|
||||
return
|
||||
}
|
||||
// 初始化客户端、服务端
|
||||
@ -47,21 +63,81 @@ func (s *electricalMachineryImpl) Stop() {
|
||||
initMutex.Lock()
|
||||
defer initMutex.Unlock()
|
||||
_default = nil
|
||||
if s.electricalMachineryUdpClient != nil {
|
||||
s.electricalMachineryUdpClient.Close()
|
||||
//if s.electricalMachineryUdpClient != nil {
|
||||
// s.electricalMachineryUdpClient.Close()
|
||||
//}
|
||||
for _, c := range s.electricalMachineryUdpClientMap {
|
||||
if &c != nil {
|
||||
c.Close()
|
||||
}
|
||||
}
|
||||
s.manager = nil
|
||||
}
|
||||
|
||||
func (s *electricalMachineryImpl) SendElectricMachineryMessage(info *message.ElectricMachinery) {
|
||||
if s.electricalMachineryUdpClient == nil {
|
||||
return
|
||||
func (s *electricalMachineryImpl) SendElectricMachineryMessage(emMap map[int]*message.ElectricMachinery) {
|
||||
for key, em := range emMap {
|
||||
client := s.electricalMachineryUdpClientMap[key]
|
||||
if client != nil {
|
||||
err := client.Send(em.Encode())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
s.electricalMachineryUdpClient.Send(info.Encode())
|
||||
}
|
||||
func (s *electricalMachineryImpl) SendElectricMachineryMessage2(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) {
|
||||
collectSpeedMap := initEMMsg(trainState)
|
||||
if trainState.VobcState.Tc1Active {
|
||||
collectSpeed(info.HeadSpeed1, info.HeadSpeed2, trainState.TrainEndsA, collectSpeedMap)
|
||||
|
||||
} else if trainState.VobcState.Tc2Active {
|
||||
collectSpeed(info.TailSpeed1, info.TailSpeed2, trainState.TrainEndsB, collectSpeedMap)
|
||||
}
|
||||
// 更新电机转速
|
||||
s.SendElectricMachineryMessage(collectSpeedMap)
|
||||
}
|
||||
func collectSpeed(speed1, speed2 float32, endP *common_proto.TrainEndsState, resultMap map[int]*message.ElectricMachinery) {
|
||||
pa := resultMap[PointA]
|
||||
pb := resultMap[PointB]
|
||||
if endP.SpeedSensorEnableA || endP.SpeedSensorEnableB {
|
||||
if endP.AccOutSpeed > 0 {
|
||||
pa.Speed = float32(endP.AccOutSpeed) / 3.6
|
||||
pb.Speed = float32(endP.AccOutSpeed) / 3.6
|
||||
} else {
|
||||
if endP.SpeedSensorEnableA {
|
||||
pa.Speed = speed1
|
||||
}
|
||||
if endP.SpeedSensorEnableB {
|
||||
pb.Speed = speed2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initEMMsg(trainState *state_proto.TrainState) map[int]*message.ElectricMachinery {
|
||||
|
||||
collectSpeedMap := map[int]*message.ElectricMachinery{
|
||||
PointA: {
|
||||
Speed: 0,
|
||||
WheelDiameter: trainState.WheelDiameter,
|
||||
IsBack: trainState.VobcState.DirectionBackward},
|
||||
PointB: {Speed: 0,
|
||||
WheelDiameter: trainState.WheelDiameter,
|
||||
IsBack: trainState.VobcState.DirectionBackward},
|
||||
}
|
||||
return collectSpeedMap
|
||||
}
|
||||
|
||||
func (s *electricalMachineryImpl) initElectricalMachinery() {
|
||||
s.electricalMachineryUdpClient = udp.NewClient(fmt.Sprintf("%v:%v", s.runConfig.Ip, s.runConfig.RemotePort))
|
||||
for _, c := range s.runConfig {
|
||||
if &c != nil && c.Ip != "" && c.Open {
|
||||
ep := PointA
|
||||
if !c.EndPointA {
|
||||
ep = PointB
|
||||
}
|
||||
s.electricalMachineryUdpClientMap[ep] = udp.NewClient(fmt.Sprintf("%v:%v", c.Ip, c.RemotePort))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _default ElectricMachinery
|
||||
|
25
third_party/electrical_machinery/electrical_machinery_test.go
vendored
Normal file
25
third_party/electrical_machinery/electrical_machinery_test.go
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package electrical_machinery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func TestOther(t *testing.T) {
|
||||
dd := 1714024680 - time.Now().Unix()
|
||||
fmt.Println(dd)
|
||||
fmt.Println(int32(dd))
|
||||
}
|
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
|
||||
}
|
||||
|
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]
|
||||
|
25
third_party/message/electrical_machinery.go
vendored
25
third_party/message/electrical_machinery.go
vendored
@ -2,11 +2,12 @@ package message
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// 速度转转速计算公式:
|
||||
// 转速=车速 ÷ 车轮周长
|
||||
// 转速=车速(米/秒) ÷ 车轮周长(米)
|
||||
// 车的轮径为d,车速为v1,电机转速为v2
|
||||
// 公式为:V2=V1÷(πd)×60
|
||||
type ElectricMachinery struct {
|
||||
@ -17,16 +18,34 @@ 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)
|
||||
//rotarySpeed := t.Speed / (float32(math.Pi) * float32(t.WheelDiameter) / 1000) * 60
|
||||
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 {
|
||||
|
148
third_party/message/radar.go
vendored
148
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,65 @@ 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))
|
||||
disMeter := float64(displacement / 100)
|
||||
disMeterKM := float64(disMeter / 100)
|
||||
|
||||
if disMeter > 9999 {
|
||||
ri.DriftCounterS1 = 9999
|
||||
} else {
|
||||
ri.DriftCounterS1 = uint16(disMeter)
|
||||
}
|
||||
if disMeterKM > 9999 {
|
||||
ri.DriftCounterS2 = 9999
|
||||
} else {
|
||||
ri.DriftCounterS2 = uint16(disMeterKM)
|
||||
}
|
||||
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 +124,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 +149,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 +193,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) {
|
||||
|
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 (
|
||||
//钥匙开关状态
|
||||
|
102
third_party/radar/radar_vobc.go
vendored
102
third_party/radar/radar_vobc.go
vendored
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"joylink.club/bj-rtsts-server/dto/common_proto"
|
||||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||
@ -16,11 +17,13 @@ import (
|
||||
type RadarVobc interface {
|
||||
Start(radar RadarVobcManager)
|
||||
Stop()
|
||||
SendMsg(ri *message.RadarInfo)
|
||||
TrainSpeedSender(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState)
|
||||
}
|
||||
|
||||
type RadarVobcManager interface {
|
||||
GetRunRadarConfig() config.RadarConfig
|
||||
FindRadarTrain() *state_proto.TrainState
|
||||
//FindRadarTrain() *state_proto.TrainState
|
||||
}
|
||||
|
||||
const radar_interval = 15
|
||||
@ -55,45 +58,90 @@ 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) 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))
|
||||
func (rv *radarVobc) SendMsg(ri *message.RadarInfo) {
|
||||
rv.vobcClient.Send(ri.Encode())
|
||||
}
|
||||
func (rv *radarVobc) TrainSpeedSender(info *message.DynamicsTrainInfo, trainState *state_proto.TrainState) {
|
||||
forward := trainState.VobcState.DirectionForward
|
||||
if trainState.VobcState.Tc1Active && trainState.TrainEndsA.RadarEnable {
|
||||
s := parseRadarSpeedData(info.Speed, trainState.TrainEndsA)
|
||||
rv.SendMsg(message.NewRadarSender(s, forward, info.Displacement))
|
||||
} else if trainState.VobcState.Tc2Active && trainState.TrainEndsB.RadarEnable {
|
||||
s := parseRadarSpeedData(info.Speed, trainState.TrainEndsB)
|
||||
rv.SendMsg(message.NewRadarSender(s, forward, info.Displacement))
|
||||
} else {
|
||||
rv.SendMsg(message.NewRadarSender(0, forward, 0))
|
||||
//slog.Error("列车行驶方向不确定或两端的雷达均未启用,发送雷达数据0", "列车前进=", trainState.VobcState.DirectionForward, "雷达启用A=", trainState.TrainEndsA.RadarEnable, "列车后退=", trainState.VobcState.DirectionBackward, "雷达启用B=", trainState.TrainEndsB.RadarEnable)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
func parseRadarSpeedData(radarSpeed float32, trainEndState *common_proto.TrainEndsState) float32 {
|
||||
//如果差值速度和速度输出都填写,那么就以速度输出为优先
|
||||
//如果动力学速度-差值速度小于0,呢么输出的就是0(不能小于0)
|
||||
|
||||
trainEndState.RadarCheckTime = int32(trainEndState.RadarCheckTimeOverAt - time.Now().Unix())
|
||||
if trainEndState.RadarCheckTime <= 0 {
|
||||
trainEndState.RadarCheckTime = 0
|
||||
if trainEndState.RadarCheckTimeOverAt != 0 {
|
||||
trainEndState.RadarCheckSpeedDiff = 0
|
||||
trainEndState.RadarOutSpeed = 0
|
||||
return radarSpeed
|
||||
}
|
||||
time.Sleep(time.Millisecond * radar_interval)
|
||||
}
|
||||
|
||||
if trainEndState.RadarCheckSpeedDiff > 0 && trainEndState.RadarOutSpeed > 0 {
|
||||
//如果雷达检测速度差值和速度输出都填写,那么就以速度输出为优先
|
||||
return float32(trainEndState.RadarOutSpeed)
|
||||
} else if trainEndState.RadarCheckSpeedDiff > 0 {
|
||||
//如果雷达检测速度差值填写,那么就以速度差值为主
|
||||
return float32(math.Abs(float64(radarSpeed - (trainEndState.RadarCheckSpeedDiff / 3.6))))
|
||||
} else if trainEndState.RadarOutSpeed > 0 {
|
||||
//如果雷达速度输出填写,那么就以速度输出为主
|
||||
return float32(trainEndState.RadarOutSpeed) / 3.6
|
||||
} else {
|
||||
return radarSpeed
|
||||
}
|
||||
}
|
||||
|
||||
// sendRadarInfo 发送速度,位移计数 给vobc
|
||||
/*
|
||||
func (rv *radarVobc) sendRadarInfo(ctx context.Context) {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
*/
|
||||
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
|
||||
|
13
third_party/tcp/tcp_client.go
vendored
13
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,16 @@ func (c *TcpClient) Close() {
|
||||
c.conn = nil
|
||||
}
|
||||
}
|
||||
func (c *TcpClient) Send(data []byte) {
|
||||
if c.conn == nil {
|
||||
func (c *TcpClient) Send(data []byte) error {
|
||||
|
||||
if c == nil || 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')
|
||||
|
91
third_party/train_pc_sim/train_pc_sim.go
vendored
91
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,30 @@ 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++
|
||||
d.updateState(tpapi.ThirdPartyState_Broken)
|
||||
if reconnIndex%10 == 0 {
|
||||
slog.Error("连接车载pc平台失败,尝试=", strconv.Itoa(reconnIndex), err)
|
||||
}
|
||||
} 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 +140,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 +166,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 +181,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 +208,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 +261,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 +279,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) {
|
||||
@ -189,14 +199,17 @@ func copyTrainEnds(trainState *state_proto.TrainState, fieldName string, configD
|
||||
}
|
||||
endsVal.SpeedSensorEnableA = configData.SpeedSensorEnableA
|
||||
endsVal.SpeedSensorEnableB = configData.SpeedSensorEnableB
|
||||
endsVal.AccOutSpeed = configData.AccOutSpeed
|
||||
|
||||
endsVal.RadarEnable = configData.RadarEnable
|
||||
endsVal.RadarCheckSpeedDiff = configData.RadarCheckSpeedDiff
|
||||
endsVal.RadarCheckTime = configData.RadarCheckTime
|
||||
|
||||
endsVal.RadarCheckSpeedDiff = configData.RadarCheckSpeedDiff
|
||||
endsVal.RadarOutSpeed = configData.RadarOutSpeed
|
||||
|
||||
endsVal.AccEnable = configData.AccEnable
|
||||
endsVal.AccCheckSpeedDiff = configData.AccCheckSpeedDiff
|
||||
endsVal.AccCheckTime = configData.AccCheckTime
|
||||
endsVal.AccOutSpeed = configData.AccOutSpeed
|
||||
endsVal.RadarOutSpeed = configData.RadarOutSpeed
|
||||
|
||||
}
|
||||
func UpdateConfigTrain(vs *VerifySimulation, ct *dto.ConfigTrainReqDto) {
|
||||
@ -213,6 +226,26 @@ func UpdateConfigTrain(vs *VerifySimulation, ct *dto.ConfigTrainReqDto) {
|
||||
trainState.TrainLength = ct.Length
|
||||
trainState.WheelDiameter = ct.WheelDiameter
|
||||
requestDynamicConfig(ct)
|
||||
trainState.TrainEndsA.RadarCheckTimeOverAt = 0
|
||||
trainState.TrainEndsB.RadarCheckTimeOverAt = 0
|
||||
trainState.TrainEndsA.AccCheckTimeOverAt = 0
|
||||
trainState.TrainEndsB.AccCheckTimeOverAt = 0
|
||||
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.TrainEndsB.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) {
|
||||
@ -318,6 +351,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)
|
||||
@ -325,6 +359,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
|
||||
@ -334,24 +369,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,20 +4,15 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"joylink.club/bj-rtsts-server/dto"
|
||||
"joylink.club/bj-rtsts-server/dto/data_proto"
|
||||
"joylink.club/bj-rtsts-server/dto/state_proto"
|
||||
"joylink.club/bj-rtsts-server/sys_error"
|
||||
"joylink.club/bj-rtsts-server/third_party/acc"
|
||||
"joylink.club/bj-rtsts-server/third_party/electrical_machinery"
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
"joylink.club/bj-rtsts-server/third_party/radar"
|
||||
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/component"
|
||||
@ -25,6 +20,12 @@ import (
|
||||
"joylink.club/rtsssimulation/fi"
|
||||
"joylink.club/rtsssimulation/repository"
|
||||
"joylink.club/rtsssimulation/repository/model/proto"
|
||||
"log/slog"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// 轨旁仿真定义
|
||||
@ -281,18 +282,14 @@ func (s *VerifySimulation) HandleDynamicsTrainInfo(info *message.DynamicsTrainIn
|
||||
return
|
||||
}
|
||||
train := t.(*state_proto.TrainState)
|
||||
if train.ConnState.Conn && train.ConnState.ConnType == state_proto.TrainConnState_VOBC {
|
||||
semi_physical_train.Default().SendTrainControlMessage(info)
|
||||
|
||||
}
|
||||
// 更新列车状态
|
||||
trainState := UpdateTrainStateByDynamics(s, trainId, info)
|
||||
// 更新电机转速
|
||||
electrical_machinery.Default().SendElectricMachineryMessage(&message.ElectricMachinery{
|
||||
Speed: info.Speed,
|
||||
WheelDiameter: trainState.WheelDiameter,
|
||||
IsBack: trainState.VobcState.DirectionBackward,
|
||||
})
|
||||
if train.ConnState.Conn && train.ConnState.ConnType == state_proto.TrainConnState_VOBC {
|
||||
semi_physical_train.Default().SendTrainControlMessage(info)
|
||||
electrical_machinery.Default().SendElectricMachineryMessage2(info, trainState)
|
||||
radar.Default().TrainSpeedSender(info, trainState)
|
||||
acc.Default().TrainAccSender(info, trainState)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取动力学配置信息
|
||||
@ -509,8 +506,8 @@ func (s *VerifySimulation) FindTrainConnTypes() []dto.TrainConnTypeConfigDto {
|
||||
}
|
||||
|
||||
// 获取电机转速参数
|
||||
func (s *VerifySimulation) GetElectricMachineryRunConfig() *config.ElectricMachineryConfig {
|
||||
return &s.runConfig.ElectricMachinery
|
||||
func (s *VerifySimulation) GetElectricMachineryRunConfig() []config.ElectricMachineryConfig {
|
||||
return s.runConfig.ElectricMachinerys
|
||||
}
|
||||
|
||||
// 初始化仿真运行配置
|
||||
@ -581,7 +578,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 +587,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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
// 列车驾驶端激活
|
||||
@ -106,11 +109,20 @@ func trainControlDriverKey(trainState *state_proto.TrainState, request *request_
|
||||
slog.Error("未找到对应的驾驶端激活设备deviceId:", deviceId)
|
||||
return nil
|
||||
}
|
||||
|
||||
if obj.Code == "SKQYS1" {
|
||||
trainState.VobcState.Tc1Active = request.Val
|
||||
} else if obj.Code == "SKQYS2" {
|
||||
trainState.VobcState.Tc2Active = request.Val
|
||||
}
|
||||
if trainState.VobcState.Tc1Active && trainState.VobcState.Tc2Active {
|
||||
if obj.Code == "SKQYS1" {
|
||||
trainState.VobcState.Tc1Active = false
|
||||
} else if obj.Code == "SKQYS2" {
|
||||
trainState.VobcState.Tc2Active = false
|
||||
}
|
||||
panic(sys_error.New("驾驶端不能同时激活"))
|
||||
}
|
||||
var addNew = true
|
||||
for _, k := range trainState.Tcc.DriverKey {
|
||||
if k.Id == deviceId {
|
||||
@ -141,17 +153,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 +385,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