【半实物仿真处理】

This commit is contained in:
weizhihong 2023-08-23 15:33:07 +08:00
parent 7579200104
commit dd81eedecd
12 changed files with 1496 additions and 699 deletions

File diff suppressed because it is too large Load Diff

View File

@ -483,6 +483,8 @@ type TrainState struct {
PointTo bool `protobuf:"varint,28,opt,name=pointTo,proto3" json:"pointTo,omitempty"` PointTo bool `protobuf:"varint,28,opt,name=pointTo,proto3" json:"pointTo,omitempty"`
// 运行上下行(公里标 上行:小 -> 大,下行:大 -> 小) // 运行上下行(公里标 上行:小 -> 大,下行:大 -> 小)
RunDirection bool `protobuf:"varint,29,opt,name=runDirection,proto3" json:"runDirection,omitempty"` RunDirection bool `protobuf:"varint,29,opt,name=runDirection,proto3" json:"runDirection,omitempty"`
// 列车车头方向
HeadDirection bool `protobuf:"varint,30,opt,name=headDirection,proto3" json:"headDirection,omitempty"`
} }
func (x *TrainState) Reset() { func (x *TrainState) Reset() {
@ -720,6 +722,269 @@ func (x *TrainState) GetRunDirection() bool {
return false return false
} }
func (x *TrainState) GetHeadDirection() bool {
if x != nil {
return x.HeadDirection
}
return false
}
// vobc发过来的列车信息
type TrainVobcState struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// 生命信号 每个周期+1
LifeSignal int32 `protobuf:"varint,1,opt,name=lifeSignal,proto3" json:"lifeSignal,omitempty"`
// TC1激活状态 1=激活
Tc1Active bool `protobuf:"varint,2,opt,name=tc1Active,proto3" json:"tc1Active,omitempty"`
// TC2激活状态 1=激活
Tc2Active bool `protobuf:"varint,3,opt,name=tc2Active,proto3" json:"tc2Active,omitempty"`
// 列车方向向前 1=方向向前
DirectionForward bool `protobuf:"varint,4,opt,name=directionForward,proto3" json:"directionForward,omitempty"`
// 列车方向向后 1=方向向后
DirectionBackward bool `protobuf:"varint,5,opt,name=directionBackward,proto3" json:"directionBackward,omitempty"`
// 列车牵引状态 1=牵引
TractionStatus bool `protobuf:"varint,6,opt,name=tractionStatus,proto3" json:"tractionStatus,omitempty"`
// 列车制动状态 1=制动
BrakingStatus bool `protobuf:"varint,7,opt,name=brakingStatus,proto3" json:"brakingStatus,omitempty"`
// 列车紧急制动状态 1=紧急制动
EmergencyBrakingStatus bool `protobuf:"varint,8,opt,name=emergencyBrakingStatus,proto3" json:"emergencyBrakingStatus,omitempty"`
// 列车折返状态AR 1=折返
TurnbackStatus bool `protobuf:"varint,9,opt,name=turnbackStatus,proto3" json:"turnbackStatus,omitempty"`
// 跳跃状态 1=跳跃
JumpStatus bool `protobuf:"varint,10,opt,name=jumpStatus,proto3" json:"jumpStatus,omitempty"`
// ATO模式 1=ATO模式
Ato bool `protobuf:"varint,11,opt,name=ato,proto3" json:"ato,omitempty"`
// FAM模式 1=FAM模式
Fam bool `protobuf:"varint,12,opt,name=fam,proto3" json:"fam,omitempty"`
// CAM模式 1=CAM模式
Cam bool `protobuf:"varint,13,opt,name=cam,proto3" json:"cam,omitempty"`
// 牵引安全回路 1=牵引安全切除
TractionSafetyCircuit bool `protobuf:"varint,14,opt,name=tractionSafetyCircuit,proto3" json:"tractionSafetyCircuit,omitempty"`
// 停放制动状态 1=停放施加
ParkingBrakeStatus bool `protobuf:"varint,15,opt,name=parkingBrakeStatus,proto3" json:"parkingBrakeStatus,omitempty"`
// 保持制动状态 1=保持制动施加
MaintainBrakeStatus bool `protobuf:"varint,16,opt,name=maintainBrakeStatus,proto3" json:"maintainBrakeStatus,omitempty"`
// 列车牵引力 100=1KN
TractionForce int64 `protobuf:"varint,17,opt,name=tractionForce,proto3" json:"tractionForce,omitempty"`
// 列车制动力 100=1KN
BrakeForce int64 `protobuf:"varint,18,opt,name=brakeForce,proto3" json:"brakeForce,omitempty"`
// 【列车载荷 100=1ton
TrainLoad int64 `protobuf:"varint,19,opt,name=trainLoad,proto3" json:"trainLoad,omitempty"`
// 列车开左门指令 1=开门
LeftDoorOpenCommand bool `protobuf:"varint,20,opt,name=leftDoorOpenCommand,proto3" json:"leftDoorOpenCommand,omitempty"`
// 列车开右门指令 1=开门
RightDoorOpenCommand bool `protobuf:"varint,21,opt,name=rightDoorOpenCommand,proto3" json:"rightDoorOpenCommand,omitempty"`
// 列车关左门指令 1=关门
LeftDoorCloseCommand bool `protobuf:"varint,22,opt,name=leftDoorCloseCommand,proto3" json:"leftDoorCloseCommand,omitempty"`
// 列车关右门指令 1=关门
RightDoorCloseCommand bool `protobuf:"varint,23,opt,name=rightDoorCloseCommand,proto3" json:"rightDoorCloseCommand,omitempty"`
// 整列车门关好 1=门关好
AllDoorClose bool `protobuf:"varint,24,opt,name=allDoorClose,proto3" json:"allDoorClose,omitempty"`
}
func (x *TrainVobcState) Reset() {
*x = TrainVobcState{}
if protoimpl.UnsafeEnabled {
mi := &file_device_state_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TrainVobcState) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TrainVobcState) ProtoMessage() {}
func (x *TrainVobcState) ProtoReflect() protoreflect.Message {
mi := &file_device_state_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TrainVobcState.ProtoReflect.Descriptor instead.
func (*TrainVobcState) Descriptor() ([]byte, []int) {
return file_device_state_proto_rawDescGZIP(), []int{7}
}
func (x *TrainVobcState) GetLifeSignal() int32 {
if x != nil {
return x.LifeSignal
}
return 0
}
func (x *TrainVobcState) GetTc1Active() bool {
if x != nil {
return x.Tc1Active
}
return false
}
func (x *TrainVobcState) GetTc2Active() bool {
if x != nil {
return x.Tc2Active
}
return false
}
func (x *TrainVobcState) GetDirectionForward() bool {
if x != nil {
return x.DirectionForward
}
return false
}
func (x *TrainVobcState) GetDirectionBackward() bool {
if x != nil {
return x.DirectionBackward
}
return false
}
func (x *TrainVobcState) GetTractionStatus() bool {
if x != nil {
return x.TractionStatus
}
return false
}
func (x *TrainVobcState) GetBrakingStatus() bool {
if x != nil {
return x.BrakingStatus
}
return false
}
func (x *TrainVobcState) GetEmergencyBrakingStatus() bool {
if x != nil {
return x.EmergencyBrakingStatus
}
return false
}
func (x *TrainVobcState) GetTurnbackStatus() bool {
if x != nil {
return x.TurnbackStatus
}
return false
}
func (x *TrainVobcState) GetJumpStatus() bool {
if x != nil {
return x.JumpStatus
}
return false
}
func (x *TrainVobcState) GetAto() bool {
if x != nil {
return x.Ato
}
return false
}
func (x *TrainVobcState) GetFam() bool {
if x != nil {
return x.Fam
}
return false
}
func (x *TrainVobcState) GetCam() bool {
if x != nil {
return x.Cam
}
return false
}
func (x *TrainVobcState) GetTractionSafetyCircuit() bool {
if x != nil {
return x.TractionSafetyCircuit
}
return false
}
func (x *TrainVobcState) GetParkingBrakeStatus() bool {
if x != nil {
return x.ParkingBrakeStatus
}
return false
}
func (x *TrainVobcState) GetMaintainBrakeStatus() bool {
if x != nil {
return x.MaintainBrakeStatus
}
return false
}
func (x *TrainVobcState) GetTractionForce() int64 {
if x != nil {
return x.TractionForce
}
return 0
}
func (x *TrainVobcState) GetBrakeForce() int64 {
if x != nil {
return x.BrakeForce
}
return 0
}
func (x *TrainVobcState) GetTrainLoad() int64 {
if x != nil {
return x.TrainLoad
}
return 0
}
func (x *TrainVobcState) GetLeftDoorOpenCommand() bool {
if x != nil {
return x.LeftDoorOpenCommand
}
return false
}
func (x *TrainVobcState) GetRightDoorOpenCommand() bool {
if x != nil {
return x.RightDoorOpenCommand
}
return false
}
func (x *TrainVobcState) GetLeftDoorCloseCommand() bool {
if x != nil {
return x.LeftDoorCloseCommand
}
return false
}
func (x *TrainVobcState) GetRightDoorCloseCommand() bool {
if x != nil {
return x.RightDoorCloseCommand
}
return false
}
func (x *TrainVobcState) GetAllDoorClose() bool {
if x != nil {
return x.AllDoorClose
}
return false
}
// 仿真运行时状态变化量,当前时刻与上一时刻比较得到 // 仿真运行时状态变化量,当前时刻与上一时刻比较得到
type VariationStatus struct { type VariationStatus struct {
state protoimpl.MessageState state protoimpl.MessageState
@ -739,7 +1004,7 @@ type VariationStatus struct {
func (x *VariationStatus) Reset() { func (x *VariationStatus) Reset() {
*x = VariationStatus{} *x = VariationStatus{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_device_state_proto_msgTypes[7] mi := &file_device_state_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -752,7 +1017,7 @@ func (x *VariationStatus) String() string {
func (*VariationStatus) ProtoMessage() {} func (*VariationStatus) ProtoMessage() {}
func (x *VariationStatus) ProtoReflect() protoreflect.Message { func (x *VariationStatus) ProtoReflect() protoreflect.Message {
mi := &file_device_state_proto_msgTypes[7] mi := &file_device_state_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -765,7 +1030,7 @@ func (x *VariationStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use VariationStatus.ProtoReflect.Descriptor instead. // Deprecated: Use VariationStatus.ProtoReflect.Descriptor instead.
func (*VariationStatus) Descriptor() ([]byte, []int) { func (*VariationStatus) Descriptor() ([]byte, []int) {
return file_device_state_proto_rawDescGZIP(), []int{7} return file_device_state_proto_rawDescGZIP(), []int{8}
} }
func (x *VariationStatus) GetUpdatedTrain() []*TrainState { func (x *VariationStatus) GetUpdatedTrain() []*TrainState {
@ -813,7 +1078,7 @@ type AllDevicesStatus struct {
func (x *AllDevicesStatus) Reset() { func (x *AllDevicesStatus) Reset() {
*x = AllDevicesStatus{} *x = AllDevicesStatus{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_device_state_proto_msgTypes[8] mi := &file_device_state_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -826,7 +1091,7 @@ func (x *AllDevicesStatus) String() string {
func (*AllDevicesStatus) ProtoMessage() {} func (*AllDevicesStatus) ProtoMessage() {}
func (x *AllDevicesStatus) ProtoReflect() protoreflect.Message { func (x *AllDevicesStatus) ProtoReflect() protoreflect.Message {
mi := &file_device_state_proto_msgTypes[8] mi := &file_device_state_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -839,7 +1104,7 @@ func (x *AllDevicesStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use AllDevicesStatus.ProtoReflect.Descriptor instead. // Deprecated: Use AllDevicesStatus.ProtoReflect.Descriptor instead.
func (*AllDevicesStatus) Descriptor() ([]byte, []int) { func (*AllDevicesStatus) Descriptor() ([]byte, []int) {
return file_device_state_proto_rawDescGZIP(), []int{8} return file_device_state_proto_rawDescGZIP(), []int{9}
} }
func (x *AllDevicesStatus) GetTrainState() []*TrainState { func (x *AllDevicesStatus) GetTrainState() []*TrainState {
@ -881,7 +1146,7 @@ type PushedDevicesStatus struct {
func (x *PushedDevicesStatus) Reset() { func (x *PushedDevicesStatus) Reset() {
*x = PushedDevicesStatus{} *x = PushedDevicesStatus{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_device_state_proto_msgTypes[9] mi := &file_device_state_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -894,7 +1159,7 @@ func (x *PushedDevicesStatus) String() string {
func (*PushedDevicesStatus) ProtoMessage() {} func (*PushedDevicesStatus) ProtoMessage() {}
func (x *PushedDevicesStatus) ProtoReflect() protoreflect.Message { func (x *PushedDevicesStatus) ProtoReflect() protoreflect.Message {
mi := &file_device_state_proto_msgTypes[9] mi := &file_device_state_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -907,7 +1172,7 @@ func (x *PushedDevicesStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use PushedDevicesStatus.ProtoReflect.Descriptor instead. // Deprecated: Use PushedDevicesStatus.ProtoReflect.Descriptor instead.
func (*PushedDevicesStatus) Descriptor() ([]byte, []int) { func (*PushedDevicesStatus) Descriptor() ([]byte, []int) {
return file_device_state_proto_rawDescGZIP(), []int{9} return file_device_state_proto_rawDescGZIP(), []int{10}
} }
func (x *PushedDevicesStatus) GetAll() bool { func (x *PushedDevicesStatus) GetAll() bool {
@ -956,7 +1221,7 @@ var file_device_state_proto_rawDesc = []byte{
0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1e, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1e, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xf0, 0x07, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x69, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x96, 0x08, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x69,
0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01,
0x28, 0x08, 0x52, 0x02, 0x75, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x4c, 0x69, 0x28, 0x08, 0x52, 0x02, 0x75, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x4c, 0x69,
@ -1019,52 +1284,114 @@ var file_device_state_proto_rawDesc = []byte{
0x70, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70,
0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x44, 0x69, 0x72, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x44, 0x69, 0x72,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x75, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x75,
0x6e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe7, 0x01, 0x0a, 0x0f, 0x56, 0x6e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x65,
0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x61, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1e, 0x20, 0x01, 0x28,
0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x08, 0x52, 0x0d, 0x68, 0x65, 0x61, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x22, 0xba, 0x07, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x56, 0x6f, 0x62, 0x63, 0x53, 0x74,
0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x66, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61,
0x54, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6c, 0x69, 0x66, 0x65, 0x53, 0x69, 0x67,
0x54, 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x63, 0x31, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x63, 0x31, 0x41, 0x63, 0x74, 0x69, 0x76,
0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x18, 0x03, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x63, 0x32, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x63, 0x32, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12,
0x2a, 0x0a, 0x10, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x77,
0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x69, 0x72, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x64,
0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64,
0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x42, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x72, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
0x08, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x62, 0x72, 0x61, 0x6b, 0x69, 0x6e,
0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x65, 0x6d, 0x65, 0x72, 0x67,
0x65, 0x6e, 0x63, 0x79, 0x42, 0x72, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x42, 0x72, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x26, 0x0a, 0x0e, 0x74, 0x75, 0x72, 0x6e, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x75, 0x72, 0x6e, 0x62, 0x61, 0x63,
0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6a, 0x75, 0x6d, 0x70, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6a, 0x75, 0x6d,
0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x74, 0x6f, 0x18, 0x0b,
0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x74, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x61, 0x6d,
0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x66, 0x61, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x63,
0x61, 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x63, 0x61, 0x6d, 0x12, 0x34, 0x0a,
0x15, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x66, 0x65, 0x74, 0x79, 0x43,
0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x74, 0x72,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x66, 0x65, 0x74, 0x79, 0x43, 0x69, 0x72, 0x63,
0x75, 0x69, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x70, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x42, 0x72,
0x61, 0x6b, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52,
0x12, 0x70, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x42, 0x72, 0x61, 0x6b, 0x65, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x42,
0x72, 0x61, 0x6b, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08,
0x52, 0x13, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x42, 0x72, 0x61, 0x6b, 0x65, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x62,
0x72, 0x61, 0x6b, 0x65, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52,
0x0a, 0x62, 0x72, 0x61, 0x6b, 0x65, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74,
0x72, 0x61, 0x69, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6c, 0x65, 0x66,
0x74, 0x44, 0x6f, 0x6f, 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x6c, 0x65, 0x66, 0x74, 0x44, 0x6f, 0x6f, 0x72,
0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x72,
0x69, 0x67, 0x68, 0x74, 0x44, 0x6f, 0x6f, 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x69, 0x67, 0x68, 0x74,
0x44, 0x6f, 0x6f, 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12,
0x32, 0x0a, 0x14, 0x6c, 0x65, 0x66, 0x74, 0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x6c,
0x65, 0x66, 0x74, 0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x12, 0x34, 0x0a, 0x15, 0x72, 0x69, 0x67, 0x68, 0x74, 0x44, 0x6f, 0x6f, 0x72,
0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x17, 0x20, 0x01,
0x28, 0x08, 0x52, 0x15, 0x72, 0x69, 0x67, 0x68, 0x74, 0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6c, 0x6f,
0x73, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x6c, 0x6c,
0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0c, 0x61, 0x6c, 0x6c, 0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0xe7, 0x01,
0x0a, 0x0f, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x12, 0x35, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69,
0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e,
0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61,
0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64,
0x12, 0x38, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x77, 0x69, 0x74, 0x63,
0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e,
0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x64, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x3b, 0x0a, 0x0e, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb4, 0x01, 0x0a, 0x10, 0x41, 0x6c, 0x6c, 0x44,
0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x0a,
0x74, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74,
0x61, 0x74, 0x65, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
0x34, 0x0a, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x77, 0x69, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x77, 0x69,
0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68,
0x64, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x3b, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x65, 0x64, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74,
0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65,
0x74, 0x61, 0x74, 0x65, 0x52, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x65, 0x63, 0x52, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x94,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb4, 0x01, 0x0a, 0x10, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x01, 0x0a, 0x13, 0x50, 0x75, 0x73, 0x68, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73,
0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20,
0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x34, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x53,
0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74,
0x52, 0x0a, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x61, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61,
0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x74, 0x75, 0x73, 0x52, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35,
0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76,
0x74, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x53,
0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0x37, 0x0a, 0x0b, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x10, 0x00, 0x12, 0x08, 0x0a,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x04, 0x41, 0x78, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x63,
0x50, 0x75, 0x73, 0x68, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x10, 0x03, 0x42, 0x54,
0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x0a, 0x25, 0x63, 0x6c, 0x75, 0x62, 0x2e, 0x6a, 0x6f, 0x79, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62,
0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x34, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x6a, 0x72, 0x74, 0x73, 0x73, 0x2e, 0x61, 0x74, 0x73, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79,
0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x42, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53,
0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x19, 0x2e, 0x2f, 0x61, 0x74, 0x73,
0x52, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73,
0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x2a, 0x37, 0x0a, 0x0b, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70,
0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x78,
0x6c, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x10, 0x02, 0x12,
0x0a, 0x0a, 0x06, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x10, 0x03, 0x42, 0x54, 0x0a, 0x25, 0x63,
0x6c, 0x75, 0x62, 0x2e, 0x6a, 0x6f, 0x79, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62, 0x6a, 0x72, 0x74,
0x73, 0x73, 0x2e, 0x61, 0x74, 0x73, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x73, 0x42, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x19, 0x2e, 0x2f, 0x61, 0x74, 0x73, 0x2f, 0x76, 0x65,
0x72, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74,
0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -1080,7 +1407,7 @@ func file_device_state_proto_rawDescGZIP() []byte {
} }
var file_device_state_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_device_state_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_device_state_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_device_state_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_device_state_proto_goTypes = []interface{}{ var file_device_state_proto_goTypes = []interface{}{
(SectionType)(0), // 0: state.SectionType (SectionType)(0), // 0: state.SectionType
(*LinkState)(nil), // 1: state.LinkState (*LinkState)(nil), // 1: state.LinkState
@ -1090,25 +1417,26 @@ var file_device_state_proto_goTypes = []interface{}{
(*PlatformState)(nil), // 5: state.PlatformState (*PlatformState)(nil), // 5: state.PlatformState
(*StationState)(nil), // 6: state.StationState (*StationState)(nil), // 6: state.StationState
(*TrainState)(nil), // 7: state.TrainState (*TrainState)(nil), // 7: state.TrainState
(*VariationStatus)(nil), // 8: state.VariationStatus (*TrainVobcState)(nil), // 8: state.TrainVobcState
(*AllDevicesStatus)(nil), // 9: state.AllDevicesStatus (*VariationStatus)(nil), // 9: state.VariationStatus
(*PushedDevicesStatus)(nil), // 10: state.PushedDevicesStatus (*AllDevicesStatus)(nil), // 10: state.AllDevicesStatus
(*PushedDevicesStatus)(nil), // 11: state.PushedDevicesStatus
} }
var file_device_state_proto_depIdxs = []int32{ var file_device_state_proto_depIdxs = []int32{
0, // 0: state.SectionState.type:type_name -> state.SectionType 0, // 0: state.SectionState.type:type_name -> state.SectionType
7, // 1: state.VariationStatus.updatedTrain:type_name -> state.TrainState 7, // 1: state.VariationStatus.updatedTrain:type_name -> state.TrainState
3, // 2: state.VariationStatus.updatedSwitch:type_name -> state.SwitchState 3, // 2: state.VariationStatus.updatedSwitch:type_name -> state.SwitchState
2, // 3: state.VariationStatus.updatedSection:type_name -> state.SectionState 2, // 3: state.VariationStatus.updatedSection:type_name -> state.SectionState
7, // 4: state.AllDevicesStatus.trainState:type_name -> state.TrainState 7, // 4: state.AllDevicesStatus.trainState:type_name -> state.TrainState
3, // 5: state.AllDevicesStatus.switchState:type_name -> state.SwitchState 3, // 5: state.AllDevicesStatus.switchState:type_name -> state.SwitchState
2, // 6: state.AllDevicesStatus.sectionState:type_name -> state.SectionState 2, // 6: state.AllDevicesStatus.sectionState:type_name -> state.SectionState
8, // 7: state.PushedDevicesStatus.varStatus:type_name -> state.VariationStatus 9, // 7: state.PushedDevicesStatus.varStatus:type_name -> state.VariationStatus
9, // 8: state.PushedDevicesStatus.allStatus:type_name -> state.AllDevicesStatus 10, // 8: state.PushedDevicesStatus.allStatus:type_name -> state.AllDevicesStatus
9, // [9:9] is the sub-list for method output_type 9, // [9:9] is the sub-list for method output_type
9, // [9:9] is the sub-list for method input_type 9, // [9:9] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name 9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee 9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name 0, // [0:9] is the sub-list for field type_name
} }
func init() { file_device_state_proto_init() } func init() { file_device_state_proto_init() }
@ -1202,7 +1530,7 @@ func file_device_state_proto_init() {
} }
} }
file_device_state_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { file_device_state_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*VariationStatus); i { switch v := v.(*TrainVobcState); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -1214,7 +1542,7 @@ func file_device_state_proto_init() {
} }
} }
file_device_state_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { file_device_state_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllDevicesStatus); i { switch v := v.(*VariationStatus); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -1226,6 +1554,18 @@ func file_device_state_proto_init() {
} }
} }
file_device_state_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { file_device_state_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllDevicesStatus); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_device_state_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PushedDevicesStatus); i { switch v := v.(*PushedDevicesStatus); i {
case 0: case 0:
return &v.state return &v.state
@ -1244,7 +1584,7 @@ func file_device_state_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_device_state_proto_rawDesc, RawDescriptor: file_device_state_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 10, NumMessages: 11,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -1,6 +1,7 @@
package simulation package simulation
import ( import (
"encoding/binary"
"net" "net"
"strings" "strings"
@ -37,14 +38,39 @@ var simulationId_prefix = (func() string {
})() })()
func init() { func init() {
vobc.RegisterTrainInfoHandler(func(info *vobc.ReceiveTrainInfo) { // vobc 发来的列车信息
vobc.RegisterTrainInfoHandler(func(info []byte) {
zap.S().Debug("接到列车信息", info) zap.S().Debug("接到列车信息", info)
for _, simulation := range GetSimulationArr() {
simulation.Memory.Status.TrainStateMap.Range(func(key, value any) bool {
train := value.(*state.TrainState)
if train.Show { // 上线列车
// 拼接列车ID
trainId, err := strconv.Atoi(train.Id)
if err != nil {
panic(err)
}
// 发送给动力学
dynamics.SendDynamicsTrainMsg(append(info, uint8(trainId)))
// 存放至仿真中
simulation.Memory.Status.VobcTrainStateMap.Store(train.Id, decoderVobcTrainState(info))
}
return false
})
}
}) })
dynamics.RegisterTrainInfoHandler(func(info *dynamics.TrainInfo) { dynamics.RegisterTrainInfoHandler(func(info *dynamics.TrainInfo) {
for _, simulation := range GetSimulationArr() { for _, simulation := range GetSimulationArr() {
sta, ok := simulation.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number))) sta, ok := simulation.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number)))
if ok { if ok {
memory.UpdateTrainState(simulation, convert(info, sta.(*state.TrainState), memory.QueryMapVerifyStructure(simulation.MapId))) trainState := sta.(*state.TrainState)
// 给半实物仿真发送速度
vobc.SendTrainSpeedTask(info.Speed * 36)
// 处理列车车头方向
handlerTrainHeadDirection(simulation, info, trainState)
// 更新列车状态
memory.UpdateTrainState(simulation, convert(info, trainState, memory.QueryMapVerifyStructure(simulation.MapId)))
break break
} }
} }
@ -252,3 +278,49 @@ func buildLineBaseInfo(vs *memory.VerifyStructure) *dynamics.LineBaseInfo {
CurveList: curves, CurveList: curves,
} }
} }
// 解析VOBC列车信息
func decoderVobcTrainState(buf []byte) *state.TrainVobcState {
trainVobcInfo := &state.TrainVobcState{}
trainVobcInfo.LifeSignal = int32(binary.BigEndian.Uint16(buf[0:2]))
b2 := buf[2]
trainVobcInfo.Tc1Active = (b2 & (1 << 7)) != 0
trainVobcInfo.Tc2Active = (b2 & (1 << 6)) != 0
trainVobcInfo.DirectionForward = (b2 & (1 << 5)) != 0
trainVobcInfo.DirectionBackward = (b2 & (1 << 4)) != 0
trainVobcInfo.TractionStatus = (b2 & (1 << 3)) != 0
trainVobcInfo.BrakingStatus = (b2 & (1 << 2)) != 0
trainVobcInfo.EmergencyBrakingStatus = (b2 & (1 << 1)) != 0
trainVobcInfo.TurnbackStatus = (b2 & 1) != 0
b3 := buf[3]
trainVobcInfo.JumpStatus = (b3 & (1 << 7)) != 0
trainVobcInfo.Ato = (b3 & (1 << 6)) != 0
trainVobcInfo.Fam = (b3 & (1 << 5)) != 0
trainVobcInfo.Cam = (b3 & (1 << 4)) != 0
trainVobcInfo.TractionSafetyCircuit = (b3 & (1 << 3)) != 0
trainVobcInfo.ParkingBrakeStatus = (b3 & (1 << 2)) != 0
trainVobcInfo.MaintainBrakeStatus = (b3 & (1 << 1)) != 0
trainVobcInfo.TractionForce = int64(binary.BigEndian.Uint16(buf[4:6]))
trainVobcInfo.BrakeForce = int64(binary.BigEndian.Uint16(buf[6:8]))
trainVobcInfo.TrainLoad = int64(binary.BigEndian.Uint16(buf[8:10]))
b4 := buf[15]
trainVobcInfo.LeftDoorOpenCommand = (b4 & (1 << 7)) != 0
trainVobcInfo.RightDoorOpenCommand = (b4 & (1 << 6)) != 0
trainVobcInfo.LeftDoorCloseCommand = (b4 & (1 << 5)) != 0
trainVobcInfo.RightDoorCloseCommand = (b4 & (1 << 4)) != 0
trainVobcInfo.AllDoorClose = (b4 & (1 << 3)) != 0
return trainVobcInfo
}
// 处理列车车头逻辑
func handlerTrainHeadDirection(simulation *memory.VerifySimulation, info *dynamics.TrainInfo, status *state.TrainState) {
v, ok := simulation.Memory.Status.VobcTrainStateMap.Load(status.Id)
if ok {
vobcState := v.(*state.TrainVobcState)
if (vobcState.Tc1Active || vobcState.Tc2Active) && (vobcState.DirectionBackward || vobcState.DirectionForward) { // 有激活端
// info.Up 运行link方向
//vobcState.DirectionForward
}
}
}

View File

@ -22,6 +22,8 @@ type VerifyStatus struct {
LogicSectionStateMap sync.Map LogicSectionStateMap sync.Map
//信号机状态key为信号机id,即索引 state.SignalState //信号机状态key为信号机id,即索引 state.SignalState
SignalStateMap sync.Map SignalStateMap sync.Map
//vobc发来的列车状态,索引为列车id
VobcTrainStateMap sync.Map
} }
// 轨旁仿真模型状态(变更) // 轨旁仿真模型状态(变更)

@ -1 +1 @@
Subproject commit ab41f6836f96e8a06ff6edfee202f0bf0c7aecf5 Subproject commit 8cb151ed76afd59832edd044253ed1d8a8325016

View File

@ -9,7 +9,13 @@ dynamics:
ip: 10.60.1.121 ip: 10.60.1.121
udpLocalPort: 4000 udpLocalPort: 4000
udpRemotePort: 3000 udpRemotePort: 3000
udpRemoteTrainPort: 3001
httpPort: 7800 httpPort: 7800
# VOBC
vobc:
ip: 10.60.1.52
localPort: 10000
remotePort: 4000
# 数据源 # 数据源
datasource: datasource:

View File

@ -45,10 +45,11 @@ type centrifugo struct {
Address string Address string
} }
type dynamics struct { type dynamics struct {
Ip string Ip string
UdpLocalPort int UdpLocalPort int
UdpRemotePort int UdpRemotePort int
HttpPort int UdpRemoteTrainPort int
HttpPort int
} }
type vobc struct { type vobc struct {
Ip string Ip string

View File

@ -6,9 +6,10 @@ server:
port: 9091 port: 9091
# 动力学端口配置 # 动力学端口配置
dynamics: dynamics:
ip: 192.168.3.222 ip: 192.168.3.37
udpLocalPort: 4000 udpLocalPort: 4000
udpRemotePort: 3000 udpRemotePort: 3000
udpRemoteTrainPort: 3001
httpPort: 7800 httpPort: 7800
# VOBC # VOBC
vobc: vobc:

View File

@ -9,6 +9,7 @@ dynamics:
ip: 192.168.3.94 ip: 192.168.3.94
udpLocalPort: 4000 udpLocalPort: 4000
udpRemotePort: 3000 udpRemotePort: 3000
udpRemoteTrainPort: 3001
httpPort: 7800 httpPort: 7800
# VOBC # VOBC
vobc: vobc:

View File

@ -154,6 +154,30 @@ func sendDynamicsMsg(buf []byte) error {
return err return err
} }
// 给动力学发送列车信息
func SendDynamicsTrainMsg(buf []byte) error {
defer func() {
if r := recover(); r != nil {
zap.S().Error("发送道岔信息失败", r)
}
}()
addr := fmt.Sprintf("%v:%v", config.Config.Dynamics.Ip, config.Config.Dynamics.UdpRemoteTrainPort)
remoteAddr, _ := net.ResolveUDPAddr("udp", addr)
conn, err := net.DialUDP("udp", nil, remoteAddr)
if err != nil {
zap.S().Error("UDP通信失败", err)
return err
}
defer func(conn *net.UDPConn) {
err := conn.Close()
if err != nil {
zap.S().Error(err)
}
}(conn)
_, err = conn.Write(buf)
return err
}
// 发送道岔状态任务 // 发送道岔状态任务
func runSendTurnoutStateTask(tiFunc TurnoutInfoFunc) error { func runSendTurnoutStateTask(tiFunc TurnoutInfoFunc) error {
if running { if running {

View File

@ -16,11 +16,11 @@ import (
var ( var (
running bool running bool
mutex sync.Mutex mutex sync.Mutex
receiveTrainLifeSignal uint16 //接收列车消息生命信号 receiveTrainLifeSignal uint16 //接收列车消息生命信号
sendTrainLifeSignal uint16 //发送的列车消息生命信号 sendTrainLifeSignal uint16 //发送的列车消息生命信号
trainLifeSignalInit bool //列车生命信号是否初始化 trainLifeSignalInit bool //列车生命信号是否初始化
limit uint16 = 10000 //用于处理生命信号循环使用产生的各种特殊处理 limit uint16 = 10000 //用于处理生命信号循环使用产生的各种特殊处理
trainInfoChan chan *ReceiveTrainInfo = make(chan *ReceiveTrainInfo) //列车消息队列 vobcMsgInfoChan chan []byte = make(chan []byte) //列车消息队列
//处理方法列表 //处理方法列表
handlerList list.List handlerList list.List
) )
@ -28,7 +28,7 @@ var (
func init() { func init() {
go func() { go func() {
for { for {
info := <-trainInfoChan info := <-vobcMsgInfoChan
for e := handlerList.Front(); e != nil; e = e.Next() { for e := handlerList.Front(); e != nil; e = e.Next() {
func() { func() {
defer func() { defer func() {
@ -37,7 +37,7 @@ func init() {
zap.S().Errorf("列车信息处理函数报错") zap.S().Errorf("列车信息处理函数报错")
} }
}() }()
handler := e.Value.(TrainInfoHandler) handler := e.Value.(VobcDataHandler)
handler(info) handler(info)
}() }()
} }
@ -45,7 +45,7 @@ func init() {
}() }()
} }
type TrainInfoHandler func(info *ReceiveTrainInfo) type VobcDataHandler func([]byte)
type udpServer struct { type udpServer struct {
gnet.BuiltinEventEngine gnet.BuiltinEventEngine
@ -90,14 +90,14 @@ func (server *udpServer) OnTraffic(c gnet.Conn) gnet.Action {
} }
} }
receiveTrainLifeSignal = lifeSignal receiveTrainLifeSignal = lifeSignal
trainInfo := decoderVobcTrainInfo(buf) // trainInfo := decoderVobcTrainInfo(buf)
//列车消息队列 //消息队列
trainInfoChan <- trainInfo vobcMsgInfoChan <- buf
return gnet.None return gnet.None
} }
// 注册处理vobc处理方法 // 注册处理vobc处理方法
func RegisterTrainInfoHandler(handler TrainInfoHandler) { func RegisterTrainInfoHandler(handler VobcDataHandler) {
handlerList.PushBack(handler) handlerList.PushBack(handler)
} }
@ -119,7 +119,7 @@ func SendTrainSpeedTask(speed float32) error {
LifeSignal: sendTrainLifeSignal, LifeSignal: sendTrainLifeSignal,
Speed: uint16(speed), Speed: uint16(speed),
} }
err := sendDynamicsMsg(encoderVobcTrainInfo(trainInfo)) err := sendVobcMsg(encoderVobcTrainInfo(trainInfo))
if err != nil { if err != nil {
zap.S().Error(err) zap.S().Error(err)
} }
@ -135,7 +135,7 @@ func Stop() {
} }
// Vobc 消息发送消息 // Vobc 消息发送消息
func sendDynamicsMsg(buf []byte) error { func sendVobcMsg(buf []byte) error {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
zap.S().Error("发送列车速度信息失败", r) zap.S().Error("发送列车速度信息失败", r)
@ -158,39 +158,6 @@ func sendDynamicsMsg(buf []byte) error {
return err return err
} }
// 解析VOBC列车信息
func decoderVobcTrainInfo(buf []byte) *ReceiveTrainInfo {
trainInfo := &ReceiveTrainInfo{}
trainInfo.LifeSignal = binary.BigEndian.Uint16(buf[0:2])
b2 := buf[2]
trainInfo.Tc1Active = (b2 & (1 << 7)) != 0
trainInfo.Tc2Active = (b2 & (1 << 6)) != 0
trainInfo.DirectionForward = (b2 & (1 << 5)) != 0
trainInfo.DirectionBackward = (b2 & (1 << 4)) != 0
trainInfo.TractionStatus = (b2 & (1 << 3)) != 0
trainInfo.BrakingStatus = (b2 & (1 << 2)) != 0
trainInfo.EmergencyBrakingStatus = (b2 & (1 << 1)) != 0
trainInfo.TurnbackStatus = (b2 & 1) != 0
b3 := buf[3]
trainInfo.JumpStatus = (b3 & (1 << 7)) != 0
trainInfo.ATO = (b3 & (1 << 6)) != 0
trainInfo.FAM = (b3 & (1 << 5)) != 0
trainInfo.CAM = (b3 & (1 << 4)) != 0
trainInfo.TractionSafetyCircuit = (b3 & (1 << 3)) != 0
trainInfo.ParkingBrakeStatus = (b3 & (1 << 2)) != 0
trainInfo.MaintainBrakeStatus = (b3 & (1 << 1)) != 0
trainInfo.TractionForce = binary.BigEndian.Uint16(buf[4:6])
trainInfo.BrakeForce = binary.BigEndian.Uint16(buf[6:8])
trainInfo.TrainLoad = binary.BigEndian.Uint16(buf[8:10])
b4 := buf[15]
trainInfo.LeftDoorOpenCommand = (b4 & (1 << 7)) != 0
trainInfo.RightDoorOpenCommand = (b4 & (1 << 6)) != 0
trainInfo.LeftDoorCloseCommand = (b4 & (1 << 5)) != 0
trainInfo.RightDoorCloseCommand = (b4 & (1 << 4)) != 0
trainInfo.AllDoorClose = (b4 & (1 << 3)) != 0
return trainInfo
}
// 将道岔转为动力学的消息 // 将道岔转为动力学的消息
func encoderVobcTrainInfo(info *SendTrainInfo) []byte { func encoderVobcTrainInfo(info *SendTrainInfo) []byte {
var data []byte var data []byte

View File

@ -1,5 +1,7 @@
package vobc package vobc
import "encoding/binary"
// 接收到的列车信息 // 接收到的列车信息
type ReceiveTrainInfo struct { type ReceiveTrainInfo struct {
//【0 1】两个字节 //【0 1】两个字节
@ -56,6 +58,38 @@ type ReceiveTrainInfo struct {
AllDoorClose bool AllDoorClose bool
} }
// 解析VOBC列车信息
func (r *ReceiveTrainInfo) DecoderVobcTrainInfo(buf []byte) *ReceiveTrainInfo {
r.LifeSignal = binary.BigEndian.Uint16(buf[0:2])
b2 := buf[2]
r.Tc1Active = (b2 & (1 << 7)) != 0
r.Tc2Active = (b2 & (1 << 6)) != 0
r.DirectionForward = (b2 & (1 << 5)) != 0
r.DirectionBackward = (b2 & (1 << 4)) != 0
r.TractionStatus = (b2 & (1 << 3)) != 0
r.BrakingStatus = (b2 & (1 << 2)) != 0
r.EmergencyBrakingStatus = (b2 & (1 << 1)) != 0
r.TurnbackStatus = (b2 & 1) != 0
b3 := buf[3]
r.JumpStatus = (b3 & (1 << 7)) != 0
r.ATO = (b3 & (1 << 6)) != 0
r.FAM = (b3 & (1 << 5)) != 0
r.CAM = (b3 & (1 << 4)) != 0
r.TractionSafetyCircuit = (b3 & (1 << 3)) != 0
r.ParkingBrakeStatus = (b3 & (1 << 2)) != 0
r.MaintainBrakeStatus = (b3 & (1 << 1)) != 0
r.TractionForce = binary.BigEndian.Uint16(buf[4:6])
r.BrakeForce = binary.BigEndian.Uint16(buf[6:8])
r.TrainLoad = binary.BigEndian.Uint16(buf[8:10])
b4 := buf[15]
r.LeftDoorOpenCommand = (b4 & (1 << 7)) != 0
r.RightDoorOpenCommand = (b4 & (1 << 6)) != 0
r.LeftDoorCloseCommand = (b4 & (1 << 5)) != 0
r.RightDoorCloseCommand = (b4 & (1 << 4)) != 0
r.AllDoorClose = (b4 & (1 << 3)) != 0
return r
}
// 发送列车信息 // 发送列车信息
type SendTrainInfo struct { type SendTrainInfo struct {
// 生命信号 每个周期+1 // 生命信号 每个周期+1