Merge branch 'master' of https://git.code.tencent.com/beijing-rtss-test/bj-rtsts-server-go
This commit is contained in:
commit
897c5b9085
@ -203,10 +203,11 @@ func addTrain(c *gin.Context) {
|
||||
}
|
||||
id := strconv.Itoa(i)
|
||||
rsp := &state.TrainState{
|
||||
Id: id,
|
||||
HeadLinkId: req.HeadLinkId,
|
||||
HeadLinkOffset: req.HeadLinkOffset,
|
||||
Up: req.Up,
|
||||
Id: id,
|
||||
HeadDeviceId: req.Id,
|
||||
HeadOffset: req.HeadOffset,
|
||||
DevicePort: req.DevicePort,
|
||||
RunDirection: req.RunDirection,
|
||||
}
|
||||
memory.AddTrainState(simulation, rsp)
|
||||
c.JSON(http.StatusOK, &rsp)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -473,6 +473,16 @@ type TrainState struct {
|
||||
TrainLength int64 `protobuf:"varint,23,opt,name=trainLength,proto3" json:"trainLength,omitempty"`
|
||||
// 列车是否显示
|
||||
Show bool `protobuf:"varint,24,opt,name=show,proto3" json:"show,omitempty"`
|
||||
// 列车车头所在设备ID
|
||||
HeadDeviceId string `protobuf:"bytes,25,opt,name=headDeviceId,proto3" json:"headDeviceId,omitempty"`
|
||||
// 列车车头所在设备偏移量
|
||||
HeadOffset int64 `protobuf:"varint,26,opt,name=headOffset,proto3" json:"headOffset,omitempty"`
|
||||
// 设备端口
|
||||
DevicePort string `protobuf:"bytes,27,opt,name=devicePort,proto3" json:"devicePort,omitempty"`
|
||||
// 运行方向指向(区段:A-B,道岔:-> 岔心)
|
||||
PointTo bool `protobuf:"varint,28,opt,name=pointTo,proto3" json:"pointTo,omitempty"`
|
||||
// 运行上下行(公里标 上行:小 -> 大,下行:大 -> 小)
|
||||
RunDirection bool `protobuf:"varint,29,opt,name=runDirection,proto3" json:"runDirection,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TrainState) Reset() {
|
||||
@ -675,6 +685,41 @@ func (x *TrainState) GetShow() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *TrainState) GetHeadDeviceId() string {
|
||||
if x != nil {
|
||||
return x.HeadDeviceId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TrainState) GetHeadOffset() int64 {
|
||||
if x != nil {
|
||||
return x.HeadOffset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TrainState) GetDevicePort() string {
|
||||
if x != nil {
|
||||
return x.DevicePort
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TrainState) GetPointTo() bool {
|
||||
if x != nil {
|
||||
return x.PointTo
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *TrainState) GetRunDirection() bool {
|
||||
if x != nil {
|
||||
return x.RunDirection
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 仿真运行时状态变化量,当前时刻与上一时刻比较得到
|
||||
type VariationStatus struct {
|
||||
state protoimpl.MessageState
|
||||
@ -911,7 +956,7 @@ var file_device_state_proto_rawDesc = []byte{
|
||||
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,
|
||||
0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xce, 0x06, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x69,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xf0, 0x07, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x69,
|
||||
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, 0x08, 0x52, 0x02, 0x75, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x4c, 0x69,
|
||||
@ -964,52 +1009,62 @@ var file_device_state_proto_rawDesc = []byte{
|
||||
0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74,
|
||||
0x68, 0x18, 0x17, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x65,
|
||||
0x6e, 0x67, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x18, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, 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, 0x74, 0x63, 0x68, 0x53, 0x74,
|
||||
0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65,
|
||||
0x12, 0x37, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65,
|
||||
0x18, 0x03, 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, 0x0c, 0x73, 0x65, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x50, 0x75,
|
||||
0x73, 0x68, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03,
|
||||
0x61, 0x6c, 0x6c, 0x12, 0x34, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x56,
|
||||
0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09,
|
||||
0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x6c, 0x6c,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 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,
|
||||
0x28, 0x08, 0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x64,
|
||||
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x68, 0x65, 0x61, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a,
|
||||
0x68, 0x65, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a,
|
||||
0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07,
|
||||
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,
|
||||
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,
|
||||
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, 0x74, 0x63, 0x68,
|
||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61,
|
||||
0x74, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61,
|
||||
0x74, 0x65, 0x18, 0x03, 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, 0x0c, 0x73,
|
||||
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13,
|
||||
0x50, 0x75, 0x73, 0x68, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x34, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||
0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x61,
|
||||
0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
|
||||
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 (
|
||||
|
@ -5,13 +5,14 @@ import (
|
||||
"strings"
|
||||
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"joylink.club/bj-rtsts-server/dynamics"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/memory"
|
||||
"joylink.club/bj-rtsts-server/dto"
|
||||
@ -39,7 +40,7 @@ func init() {
|
||||
for _, simulation := range GetSimulationArr() {
|
||||
sta, ok := simulation.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number)))
|
||||
if ok {
|
||||
memory.UpdateTrainState(simulation, convert(info, *sta.(*state.TrainState)))
|
||||
memory.UpdateTrainState(simulation, convert(info, sta.(*state.TrainState), memory.QueryMapVerifyStructure(simulation.MapId)))
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -54,15 +55,14 @@ func CreateSimulation(mapId int32) string {
|
||||
simulationId := createSimulationId(mapId)
|
||||
_, e := simulationMap.Load(simulationId)
|
||||
if !e {
|
||||
////通知动力学
|
||||
//httpCode, _, err := dynamics.SendSimulationStartReq()
|
||||
//if httpCode != http.StatusOK || err != nil {
|
||||
// panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
|
||||
//}
|
||||
verifySimulation := memory.CreateSimulation(mapId, simulationId)
|
||||
//通知动力学
|
||||
httpCode, _, err := dynamics.SendSimulationStartReq(buildLineBaseInfo(memory.QueryMapVerifyStructure(verifySimulation.MapId)))
|
||||
if httpCode != http.StatusOK || err != nil {
|
||||
panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
|
||||
}
|
||||
simulationMap.Store(simulationId, verifySimulation)
|
||||
//道岔状态发送
|
||||
startSendTurnoutInfo(simulationId, verifySimulation)
|
||||
dynamicsRun(verifySimulation)
|
||||
}
|
||||
return simulationId
|
||||
}
|
||||
@ -70,7 +70,7 @@ func CreateSimulation(mapId int32) string {
|
||||
// 删除仿真对象
|
||||
func DestroySimulation(simulationId string) {
|
||||
//移除道岔状态发送
|
||||
dynamics.RemoveTurnoutInfoSource(simulationId)
|
||||
dynamics.Stop()
|
||||
//通知动力学
|
||||
httpCode, _, err := dynamics.SendSimulationEndReq()
|
||||
if httpCode != http.StatusOK || err != nil {
|
||||
@ -118,9 +118,47 @@ func GetSimulationArr() []*memory.VerifySimulation {
|
||||
return result
|
||||
}
|
||||
|
||||
func convert(info *dynamics.TrainInfo, sta state.TrainState) *state.TrainState {
|
||||
func convert(info *dynamics.TrainInfo, sta *state.TrainState, vs *memory.VerifyStructure) *state.TrainState {
|
||||
zap.S().Debugf("原始消息:[%d-%d-%d]", info.Number, info.Link, info.LinkOffset)
|
||||
sta.HeadLinkId = strconv.Itoa(int(info.Link))
|
||||
sta.HeadLinkOffset = int64(info.LinkOffset * 10)
|
||||
sta.HeadLinkOffset = int64(info.LinkOffset)
|
||||
id, port, offset, runDirection, pointTo := memory.QueryDeviceByCalcLink(vs, int32(info.Link), sta.HeadLinkOffset, sta.Up, sta.RunDirection)
|
||||
zap.S().Debugf("转换后的消息:[%d-车头:%s-偏移:%d-上行:%v-是否ab:%v]", info.Number, id, offset, runDirection, pointTo)
|
||||
sta.HeadDeviceId = id
|
||||
sta.DevicePort = port
|
||||
sta.HeadOffset = offset
|
||||
sta.PointTo = pointTo
|
||||
sta.RunDirection = runDirection
|
||||
/*
|
||||
modeller := vs.LinkModelMap[int32(info.Link)]
|
||||
model := modeller.(*device.LinkModel)
|
||||
for i, dp := range model.DevicePositions {
|
||||
if uint32(dp.Offset) >= info.LinkOffset {
|
||||
var minLinkRef *graphicData.RelatedRef
|
||||
var minOffset int32
|
||||
var maxOffset int32
|
||||
if i == 0 {
|
||||
minLinkRef = model.SectionLinkMap[dp.Device.GetGraphicId()]
|
||||
minOffset = dp.Offset
|
||||
maxOffset = model.DevicePositions[i+1].Offset
|
||||
} else {
|
||||
minLinkRef = model.SectionLinkMap[model.DevicePositions[i-1].Device.GetGraphicId()]
|
||||
minOffset = model.DevicePositions[i-1].Offset
|
||||
maxOffset = dp.Offset
|
||||
}
|
||||
switch minLinkRef.DevicePort {
|
||||
case 0:
|
||||
sta.HeadLinkId = minLinkRef.GetId()
|
||||
sta.HeadLinkOffset = int64(info.LinkOffset - uint32(minOffset))
|
||||
case 1:
|
||||
sta.HeadLinkId = minLinkRef.GetId()
|
||||
sta.HeadLinkOffset = int64(uint32(maxOffset) - info.LinkOffset)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
zap.S().Debugf("转换后的消息:[%d-%s-%d]", info.Number, sta.HeadLinkId, sta.HeadLinkOffset)
|
||||
*/
|
||||
sta.Slope = int32(info.Slope)
|
||||
sta.Upslope = info.UpSlope
|
||||
sta.RunningUp = info.Up
|
||||
@ -135,11 +173,11 @@ func convert(info *dynamics.TrainInfo, sta state.TrainState) *state.TrainState {
|
||||
sta.TailSensorSpeed2 = info.TailSpeed2 * 3.6
|
||||
sta.HeadRadarSpeed = info.HeadRadarSpeed * 3.6
|
||||
sta.TailRadarSpeed = info.TailRadarSpeed * 3.6
|
||||
return &sta
|
||||
return sta
|
||||
}
|
||||
|
||||
func startSendTurnoutInfo(simulationId string, verifySimulation *memory.VerifySimulation) {
|
||||
dynamics.AddTurnoutInfoSource(simulationId, func() []*dynamics.TurnoutInfo {
|
||||
func dynamicsRun(verifySimulation *memory.VerifySimulation) {
|
||||
_ = dynamics.Run(func() []*dynamics.TurnoutInfo {
|
||||
stateSlice := memory.GetAllTurnoutState(verifySimulation)
|
||||
var turnoutInfoSlice []*dynamics.TurnoutInfo
|
||||
for _, sta := range stateSlice {
|
||||
@ -157,3 +195,55 @@ func startSendTurnoutInfo(simulationId string, verifySimulation *memory.VerifySi
|
||||
return turnoutInfoSlice
|
||||
})
|
||||
}
|
||||
|
||||
func buildLineBaseInfo(vs *memory.VerifyStructure) *dynamics.LineBaseInfo {
|
||||
var links []*dynamics.Link
|
||||
var slopes []*dynamics.Slope
|
||||
var curves []*dynamics.Curve
|
||||
for _, link := range vs.LinkModelMap {
|
||||
id, _ := strconv.Atoi(link.Index)
|
||||
var aTurnoutId int
|
||||
if link.ARelatedSwitchRef.SwitchDevice != nil {
|
||||
aTurnoutId, _ = strconv.Atoi(link.ARelatedSwitchRef.SwitchDevice.GetIndex())
|
||||
}
|
||||
var bTurnoutId int
|
||||
if link.BRelatedSwitchRef.SwitchDevice != nil {
|
||||
bTurnoutId, _ = strconv.Atoi(link.BRelatedSwitchRef.SwitchDevice.GetIndex())
|
||||
}
|
||||
links = append(links, &dynamics.Link{
|
||||
ID: int32(id),
|
||||
Len: link.Length,
|
||||
ARelTurnoutId: int32(aTurnoutId),
|
||||
ARelTurnoutPoint: link.ARelatedSwitchRef.Port.Name(),
|
||||
BRelTurnoutId: int32(bTurnoutId),
|
||||
BRelTurnoutPoint: link.BRelatedSwitchRef.Port.Name(),
|
||||
})
|
||||
}
|
||||
for _, slope := range vs.SlopeModelMap {
|
||||
id, _ := strconv.Atoi(slope.Index)
|
||||
slopes = append(slopes, &dynamics.Slope{
|
||||
ID: int32(id),
|
||||
StartLinkId: slope.StartLinkIndex,
|
||||
StartLinkOffset: slope.StartLinkOffset,
|
||||
EndLinkId: slope.EndLinkIndex,
|
||||
EndLinkOffset: slope.EndLinkOffset,
|
||||
DegreeTrig: slope.DegreeTrig,
|
||||
})
|
||||
}
|
||||
for _, curve := range vs.CurveModelMap {
|
||||
id, _ := strconv.Atoi(curve.Index)
|
||||
curves = append(curves, &dynamics.Curve{
|
||||
ID: int32(id),
|
||||
StartLinkId: curve.StartLinkIndex,
|
||||
StartLinkOffset: curve.StartLinkOffset,
|
||||
EndLinkId: curve.EndLinkIndex,
|
||||
EndLinkOffset: curve.EndLinkOffset,
|
||||
Curvature: curve.Curvature,
|
||||
})
|
||||
}
|
||||
return &dynamics.LineBaseInfo{
|
||||
LinkList: links,
|
||||
SlopeList: slopes,
|
||||
CurveList: curves,
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
package face
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//设备模型基类
|
||||
// 设备模型基类
|
||||
type DeviceModel struct {
|
||||
//图形id,即由前端作图时生成,且全局唯一
|
||||
GraphicId string
|
||||
@ -10,29 +13,55 @@ type DeviceModel struct {
|
||||
Index string
|
||||
}
|
||||
|
||||
//判断是否同一个设备
|
||||
// 判断是否同一个设备
|
||||
func (dm *DeviceModel) IsSame(other *DeviceModel) bool {
|
||||
return strings.EqualFold(dm.GraphicId, other.GraphicId)
|
||||
}
|
||||
|
||||
//模型图形id
|
||||
// 模型图形id
|
||||
func (dm *DeviceModel) GetGraphicId() string {
|
||||
return dm.GraphicId
|
||||
}
|
||||
|
||||
//模型索引
|
||||
// 模型索引
|
||||
func (dm *DeviceModel) GetIndex() string {
|
||||
return dm.Index
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
//设备端口枚举定义
|
||||
// 设备端口枚举定义
|
||||
type PortEnum int8
|
||||
|
||||
//设备端口枚举值
|
||||
func (pe PortEnum) Name() string {
|
||||
switch pe {
|
||||
case A:
|
||||
return "A"
|
||||
case B:
|
||||
return "B"
|
||||
case C:
|
||||
return "C"
|
||||
default:
|
||||
panic(fmt.Sprintf("未知的PortEnum:%d", pe))
|
||||
}
|
||||
}
|
||||
|
||||
// 设备端口枚举值
|
||||
const (
|
||||
A PortEnum = iota
|
||||
B
|
||||
C
|
||||
)
|
||||
|
||||
func GetPortEnum(i int8) PortEnum {
|
||||
switch i {
|
||||
case int8(A):
|
||||
return A
|
||||
case int8(B):
|
||||
return B
|
||||
case int8(C):
|
||||
return C
|
||||
default:
|
||||
panic(fmt.Sprintf("未知的PortEnum:%d", i))
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package memory
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
@ -13,6 +12,8 @@ import (
|
||||
"joylink.club/bj-rtsts-server/dto"
|
||||
)
|
||||
|
||||
// 参与计算的坡度与曲度均为正线公里标,如果有其他坐标系需要转换
|
||||
|
||||
// 参与计算结构体信息
|
||||
type buildCalcStruct struct {
|
||||
AxlePointMap map[string]*graphicData.AxleCounting
|
||||
@ -22,18 +23,24 @@ type buildCalcStruct struct {
|
||||
|
||||
// 参与计算link时的区段结构体
|
||||
type buildCalcSectionStruct struct {
|
||||
Data *graphicData.Section
|
||||
APoint *graphicData.AxleCounting // a点计轴
|
||||
BPoint *graphicData.AxleCounting // b点计轴
|
||||
Data *graphicData.Section
|
||||
axlePoints map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting // 关联计轴map
|
||||
stopPositions []*graphicData.StopPosition // 停车位
|
||||
transponders []*graphicData.Transponder // 应答器
|
||||
signals []*graphicData.Signal // 信号机
|
||||
slopes map[string]*graphicData.KilometerSystem // 坡度公里标
|
||||
curvatures map[string]*graphicData.KilometerSystem // 曲度公里标
|
||||
}
|
||||
|
||||
// 参与计算的
|
||||
type buildCalcTurnoutStruct struct {
|
||||
Data *graphicData.Turnout
|
||||
APoint *graphicData.AxleCounting //a点计轴
|
||||
BPoint *graphicData.AxleCounting //b点计轴
|
||||
CPoint *graphicData.AxleCounting //c点计轴
|
||||
CrossKilometerSystem *graphicData.KilometerSystem // 道岔岔心位置
|
||||
axlePoints map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting // 关联计轴map
|
||||
CrossKilometerSystem *graphicData.KilometerSystem // 道岔岔心位置
|
||||
transponders map[graphicData.RelatedRef_DevicePort][]*graphicData.Transponder // 应答器
|
||||
signals map[graphicData.RelatedRef_DevicePort]*graphicData.Signal // 对应位置信号机
|
||||
slopes map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem // 坡度公里标
|
||||
curvatures map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem // 曲度公里标
|
||||
}
|
||||
|
||||
// 根据地图信息生成calcLink数据
|
||||
@ -48,6 +55,7 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
|
||||
Common: &graphicData.CommonInfo{},
|
||||
Index: int32(id),
|
||||
Points: []*graphicData.Point{},
|
||||
Length: 0,
|
||||
DevicePositions: []*graphicData.CalculateLink_DevicePosition{},
|
||||
}
|
||||
allTurnout := true
|
||||
@ -60,20 +68,14 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
|
||||
// 计算长度
|
||||
item.Length = item.Length + calcGraphicLenBySection(section)
|
||||
// 放入设备偏移
|
||||
offset, prevKm = getGraphicSectionRefDevices(devicePosistionMap, section, offset, prevKm)
|
||||
// 区段时,A点取小端,B点取大端,没有的话赋值 refVal
|
||||
if index == 0 {
|
||||
item.ARelatedRef = getGraphicSectionPointRef(section, true, refVal)
|
||||
} else {
|
||||
item.BRelatedRef = getGraphicSectionPointRef(section, false, refVal)
|
||||
}
|
||||
offset, prevKm = getGraphicSectionRefDevices(refVal, devicePosistionMap, section, offset, prevKm)
|
||||
} else {
|
||||
allTurnout = allTurnout && true
|
||||
turnout := gm.TurnoutMap[refVal.Id]
|
||||
// 计算长度
|
||||
item.Length = item.Length + calcGraphicLenByTurnout(turnout, refVal.DevicePort)
|
||||
// 放入设备偏移
|
||||
offset, prevKm = getGraphicTurnoutRefDevices(devicePosistionMap, turnout, offset, prevKm)
|
||||
offset, prevKm = getGraphicTurnoutRefDevices(refVal, devicePosistionMap, turnout, offset, prevKm)
|
||||
// 道岔时左右端直接赋值
|
||||
if index == 0 {
|
||||
item.ARelatedRef = refVal
|
||||
@ -85,11 +87,14 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
|
||||
for _, v := range devicePosistionMap {
|
||||
item.DevicePositions = append(item.DevicePositions, v)
|
||||
}
|
||||
sort.SliceStable(item.DevicePositions, func(i, j int) bool {
|
||||
return item.DevicePositions[i].Offset < item.DevicePositions[j].Offset
|
||||
})
|
||||
// 如果全部为道岔,则长度使用岔心减岔心
|
||||
if allTurnout {
|
||||
tk1 := gm.TurnoutMap[pathArr[0].Id].CrossKilometerSystem.Kilometer
|
||||
tk2 := gm.TurnoutMap[pathArr[len(pathArr)-1].Id].CrossKilometerSystem.Kilometer
|
||||
item.Length = int32(tk2 - tk1)
|
||||
item.Length = int32(math.Abs(float64(tk2 - tk1)))
|
||||
}
|
||||
resultArr = append(resultArr, item)
|
||||
}
|
||||
@ -98,98 +103,197 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
|
||||
|
||||
// 计算区段长度
|
||||
func calcGraphicLenBySection(section *buildCalcSectionStruct) int32 {
|
||||
if section.APoint == nil || section.BPoint == nil {
|
||||
if len(section.axlePoints) != 2 {
|
||||
zap.S().Warnf("区段【%s】端点位置缺失\n", section.Data.Common.Id)
|
||||
return 0
|
||||
}
|
||||
start := section.BPoint.KilometerSystem.Kilometer
|
||||
end := section.APoint.KilometerSystem.Kilometer
|
||||
if end > start {
|
||||
return int32(end - start)
|
||||
} else {
|
||||
return int32(start - end)
|
||||
var length int64 // 两端公里标相减即可
|
||||
for _, a := range section.axlePoints {
|
||||
if !judgeKilometerIsVaild(a.KilometerSystem) {
|
||||
return 0
|
||||
}
|
||||
length = a.KilometerSystem.Kilometer - length
|
||||
}
|
||||
return int32(math.Abs(float64(length)))
|
||||
}
|
||||
|
||||
// 计算道岔端长度
|
||||
func calcGraphicLenByTurnout(turnout *buildCalcTurnoutStruct, p graphicData.RelatedRef_DevicePort) int32 {
|
||||
var endPoint *graphicData.AxleCounting
|
||||
switch p {
|
||||
case graphicData.RelatedRef_A:
|
||||
endPoint = turnout.APoint
|
||||
case graphicData.RelatedRef_B:
|
||||
endPoint = turnout.BPoint
|
||||
case graphicData.RelatedRef_C:
|
||||
endPoint = turnout.CPoint
|
||||
default:
|
||||
zap.S().Warnf("道岔【%s】对应端口【%s】数据错误", turnout.Data.Common.Id, p.String())
|
||||
endPoint := turnout.axlePoints[p]
|
||||
if endPoint == nil || !judgeKilometerIsVaild(endPoint.KilometerSystem) {
|
||||
zap.S().Warnf("道岔【%s】对应端口【%s】数据无计轴", turnout.Data.Common.Id, p.String())
|
||||
return 0
|
||||
}
|
||||
if turnout.CrossKilometerSystem == nil {
|
||||
if !judgeKilometerIsVaild(turnout.CrossKilometerSystem) {
|
||||
zap.S().Warnf("道岔【%s】数据错误,岔心公里标为空", turnout.Data.Common.Id)
|
||||
return 0
|
||||
}
|
||||
if endPoint == nil {
|
||||
zap.S().Warnf("道岔【%s】数据错误,无计轴", turnout.Data.Common.Id)
|
||||
return 0
|
||||
}
|
||||
start := turnout.CrossKilometerSystem.Kilometer
|
||||
end := endPoint.KilometerSystem.Kilometer
|
||||
if end > start {
|
||||
return int32(end - start)
|
||||
} else {
|
||||
return int32(start - end)
|
||||
}
|
||||
return int32(math.Abs(float64(end - start)))
|
||||
}
|
||||
|
||||
// 获取关于区段的设备信息
|
||||
func getGraphicSectionRefDevices(deviceMap map[string]*graphicData.CalculateLink_DevicePosition, section *buildCalcSectionStruct, offset int32, prevKm int64) (int32, int64) {
|
||||
// 目前只放入区段两端的信息
|
||||
if section.APoint != nil && deviceMap[section.APoint.Common.Id] == nil {
|
||||
offset = offset + int32(section.APoint.KilometerSystem.Kilometer-prevKm)
|
||||
prevKm = section.APoint.KilometerSystem.Kilometer
|
||||
deviceMap[section.APoint.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: section.APoint.Common.Id,
|
||||
Offset: offset,
|
||||
func getGraphicSectionRefDevices(refVal *graphicData.RelatedRef, deviceMap map[string]*graphicData.CalculateLink_DevicePosition,
|
||||
section *buildCalcSectionStruct, offset int32, prevKm int64) (int32, int64) {
|
||||
dealFunc := func(p *graphicData.AxleCounting, d map[string]*graphicData.CalculateLink_DevicePosition, o int32, pk int64) (int32, int64) {
|
||||
if p != nil && deviceMap[p.Common.Id] == nil {
|
||||
resultOff := o + int32(math.Abs(float64(p.KilometerSystem.Kilometer-pk)))
|
||||
resultPK := p.KilometerSystem.Kilometer
|
||||
deviceMap[p.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: p.Common.Id,
|
||||
Offset: resultOff,
|
||||
DeviceType: graphicData.RelatedRef_AxleCounting.String(),
|
||||
}
|
||||
return resultOff, resultPK
|
||||
}
|
||||
return o, pk
|
||||
}
|
||||
// 查看连接点
|
||||
point := section.axlePoints[refVal.DevicePort]
|
||||
offsetCalc, prevKmCalc := offset, prevKm
|
||||
offsetCalc, prevKmCalc = dealFunc(point, deviceMap, offsetCalc, prevKmCalc)
|
||||
// 获取另一个连接点
|
||||
nextPoint := graphicData.RelatedRef_B
|
||||
if refVal.DevicePort == nextPoint {
|
||||
nextPoint = graphicData.RelatedRef_A
|
||||
}
|
||||
point = section.axlePoints[nextPoint]
|
||||
offsetCalc, prevKmCalc = dealFunc(point, deviceMap, offsetCalc, prevKmCalc)
|
||||
// 处理区段上的设备
|
||||
startPoint := section.axlePoints[refVal.DevicePort]
|
||||
if startPoint != nil {
|
||||
sppk := startPoint.KilometerSystem.Kilometer // 相对起点的公里标
|
||||
spof := deviceMap[startPoint.Common.Id].Offset // 相对的起点offset
|
||||
// 信号机信息
|
||||
for _, s := range section.signals {
|
||||
if judgeKilometerIsVaild(s.KilometerSystem) && deviceMap[s.Common.Id] == nil {
|
||||
deviceMap[s.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: s.Common.Id,
|
||||
Offset: spof + int32(math.Abs(float64(s.KilometerSystem.Kilometer-sppk))),
|
||||
DeviceType: "Signal",
|
||||
}
|
||||
}
|
||||
}
|
||||
// 停车标信息
|
||||
for _, s := range section.stopPositions {
|
||||
if judgeKilometerIsVaild(s.KilometerSystem) && deviceMap[s.Common.Id] == nil {
|
||||
deviceMap[s.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: s.Common.Id,
|
||||
Offset: spof + int32(math.Abs(float64(s.KilometerSystem.Kilometer-sppk))),
|
||||
DeviceType: "StopPosition",
|
||||
}
|
||||
}
|
||||
}
|
||||
// 应答器信息
|
||||
for _, t := range section.transponders {
|
||||
if judgeKilometerIsVaild(t.KilometerSystem) && deviceMap[t.Common.Id] == nil {
|
||||
deviceMap[t.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: t.Common.Id,
|
||||
Offset: spof + int32(math.Abs(float64(t.KilometerSystem.Kilometer-sppk))),
|
||||
DeviceType: "Transponder",
|
||||
}
|
||||
}
|
||||
}
|
||||
// 坡度
|
||||
for id, s := range section.slopes {
|
||||
if judgeKilometerIsVaild(s) && deviceMap[id] == nil {
|
||||
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: id,
|
||||
Offset: spof + int32(math.Abs(float64(s.Kilometer-sppk))),
|
||||
DeviceType: "slopes",
|
||||
}
|
||||
}
|
||||
}
|
||||
// 曲度
|
||||
for id, c := range section.curvatures {
|
||||
if judgeKilometerIsVaild(c) && deviceMap[id] == nil {
|
||||
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: id,
|
||||
Offset: spof + int32(math.Abs(float64(c.Kilometer-sppk))),
|
||||
DeviceType: "curvatures",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if section.BPoint != nil && deviceMap[section.BPoint.Common.Id] == nil {
|
||||
offset = offset + int32(section.BPoint.KilometerSystem.Kilometer-prevKm)
|
||||
prevKm = section.BPoint.KilometerSystem.Kilometer
|
||||
deviceMap[section.BPoint.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: section.BPoint.Common.Id,
|
||||
Offset: offset,
|
||||
}
|
||||
}
|
||||
return offset, prevKm
|
||||
return offsetCalc, prevKmCalc
|
||||
}
|
||||
|
||||
// 获取关于道岔的设备信息
|
||||
func getGraphicTurnoutRefDevices(deviceMap map[string]*graphicData.CalculateLink_DevicePosition, turnout *buildCalcTurnoutStruct, offset int32, prevKm int64) (int32, int64) {
|
||||
func getGraphicTurnoutRefDevices(refVal *graphicData.RelatedRef, deviceMap map[string]*graphicData.CalculateLink_DevicePosition, turnout *buildCalcTurnoutStruct, offset int32, prevKm int64) (int32, int64) {
|
||||
// 目前只放入岔心位置
|
||||
if turnout.CrossKilometerSystem != nil && deviceMap[turnout.Data.Common.Id] == nil {
|
||||
offset = offset + int32(turnout.CrossKilometerSystem.Kilometer-prevKm)
|
||||
prevKm = turnout.CrossKilometerSystem.Kilometer
|
||||
offsetCalc := offset + int32(math.Abs(float64(turnout.CrossKilometerSystem.Kilometer-prevKm)))
|
||||
prevKmCalc := turnout.CrossKilometerSystem.Kilometer
|
||||
deviceMap[turnout.Data.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: turnout.Data.Common.Id,
|
||||
Offset: offset,
|
||||
DeviceId: turnout.Data.Common.Id,
|
||||
Offset: offsetCalc,
|
||||
DeviceType: graphicData.RelatedRef_Turnout.String(),
|
||||
}
|
||||
// 查看是否存在连接计轴
|
||||
point := turnout.axlePoints[refVal.DevicePort]
|
||||
if point != nil && judgeKilometerIsVaild(point.KilometerSystem) && deviceMap[point.Common.Id] == nil {
|
||||
deviceMap[point.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: point.Common.Id,
|
||||
Offset: offset + int32(math.Abs(float64(point.KilometerSystem.Kilometer-prevKm))),
|
||||
DeviceType: graphicData.RelatedRef_AxleCounting.String(),
|
||||
}
|
||||
}
|
||||
// 处理道岔上的信号机
|
||||
signal := turnout.signals[refVal.DevicePort]
|
||||
if signal != nil && judgeKilometerIsVaild(signal.KilometerSystem) && deviceMap[signal.Common.Id] == nil {
|
||||
deviceMap[signal.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: signal.Common.Id,
|
||||
Offset: offset + int32(math.Abs(float64(signal.KilometerSystem.Kilometer-prevKm))),
|
||||
DeviceType: "Signal",
|
||||
}
|
||||
}
|
||||
// 处理道岔上的应答器
|
||||
transponders := turnout.transponders[refVal.DevicePort]
|
||||
if transponders != nil {
|
||||
for _, t := range transponders {
|
||||
if judgeKilometerIsVaild(t.KilometerSystem) && deviceMap[t.Common.Id] == nil {
|
||||
deviceMap[t.Common.Id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: t.Common.Id,
|
||||
Offset: offset + int32(math.Abs(float64(t.KilometerSystem.Kilometer-prevKm))),
|
||||
DeviceType: "Transponder",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 坡度
|
||||
sm := turnout.slopes[refVal.DevicePort]
|
||||
if sm != nil {
|
||||
for id, s := range sm {
|
||||
if judgeKilometerIsVaild(s) && deviceMap[id] == nil {
|
||||
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: id,
|
||||
Offset: offset + int32(math.Abs(float64(s.Kilometer-prevKm))),
|
||||
DeviceType: "slopes",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 曲度
|
||||
cm := turnout.curvatures[refVal.DevicePort]
|
||||
if cm != nil {
|
||||
for id, c := range cm {
|
||||
if judgeKilometerIsVaild(c) && deviceMap[id] == nil {
|
||||
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
|
||||
DeviceId: id,
|
||||
Offset: offset + int32(math.Abs(float64(c.Kilometer-prevKm))),
|
||||
DeviceType: "curvatures",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return offsetCalc, prevKmCalc
|
||||
}
|
||||
return offset, prevKm
|
||||
}
|
||||
|
||||
// 获取区段的对应端
|
||||
func getGraphicSectionPointRef(section *buildCalcSectionStruct, b bool, defaultRelateRef *graphicData.RelatedRef) *graphicData.RelatedRef {
|
||||
if section.APoint == nil || section.BPoint == nil {
|
||||
return defaultRelateRef
|
||||
}
|
||||
if section.APoint.KilometerSystem.Kilometer < section.BPoint.KilometerSystem.Kilometer && b {
|
||||
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_Section, Id: section.Data.Common.Id, DevicePort: graphicData.RelatedRef_A}
|
||||
} else {
|
||||
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_Section, Id: section.Data.Common.Id, DevicePort: graphicData.RelatedRef_B}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取link的起始点和包装数据结构方便查找,以道岔的各分支的连接点为起点
|
||||
func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStruct, *list.List) {
|
||||
gm := &buildCalcStruct{
|
||||
@ -202,7 +306,7 @@ func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStru
|
||||
for _, t := range gd.Turnouts {
|
||||
var op *graphicData.KilometerSystem
|
||||
for _, k := range t.KilometerSystem {
|
||||
if k.CoordinateSystem == "MAIN_LINE" && k.Kilometer != 0 {
|
||||
if judgeKilometerIsVaild(k) {
|
||||
op = k
|
||||
}
|
||||
}
|
||||
@ -215,34 +319,115 @@ func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStru
|
||||
if t.PcRef != nil {
|
||||
startPoints.PushBack(t.PcRef)
|
||||
}
|
||||
gm.TurnoutMap[t.Common.Id] = &buildCalcTurnoutStruct{Data: t, CrossKilometerSystem: op}
|
||||
gm.TurnoutMap[t.Common.Id] = &buildCalcTurnoutStruct{
|
||||
Data: t,
|
||||
CrossKilometerSystem: op,
|
||||
axlePoints: make(map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting),
|
||||
transponders: make(map[graphicData.RelatedRef_DevicePort][]*graphicData.Transponder),
|
||||
signals: make(map[graphicData.RelatedRef_DevicePort]*graphicData.Signal),
|
||||
slopes: make(map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem),
|
||||
curvatures: make(map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem),
|
||||
}
|
||||
}
|
||||
// 区段列表
|
||||
for _, s := range gd.Section {
|
||||
gm.SectionMap[s.Common.Id] = &buildCalcSectionStruct{Data: s}
|
||||
gm.SectionMap[s.Common.Id] = &buildCalcSectionStruct{
|
||||
Data: s,
|
||||
axlePoints: make(map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting),
|
||||
slopes: make(map[string]*graphicData.KilometerSystem),
|
||||
curvatures: make(map[string]*graphicData.KilometerSystem),
|
||||
}
|
||||
}
|
||||
// 计轴点关联到对应的区段,道岔上
|
||||
for _, a := range gd.AxleCountings {
|
||||
gm.AxlePointMap[a.Common.Id] = a
|
||||
for _, r := range a.AxleCountingRef {
|
||||
if r.DeviceType == graphicData.RelatedRef_Section {
|
||||
section := gm.SectionMap[r.Id]
|
||||
if r.DevicePort == graphicData.RelatedRef_A {
|
||||
section.APoint = a
|
||||
} else if r.DevicePort == graphicData.RelatedRef_B {
|
||||
section.BPoint = a
|
||||
}
|
||||
gm.SectionMap[r.Id].axlePoints[r.DevicePort] = a
|
||||
} else if r.DeviceType == graphicData.RelatedRef_Turnout {
|
||||
if r.DevicePort == graphicData.RelatedRef_A {
|
||||
gm.TurnoutMap[r.Id].APoint = a
|
||||
} else if r.DevicePort == graphicData.RelatedRef_B {
|
||||
gm.TurnoutMap[r.Id].BPoint = a
|
||||
} else {
|
||||
gm.TurnoutMap[r.Id].CPoint = a
|
||||
}
|
||||
gm.TurnoutMap[r.Id].axlePoints[r.DevicePort] = a
|
||||
}
|
||||
}
|
||||
}
|
||||
// 信号机关联到对应区段或道岔上
|
||||
for _, s := range gd.Signals {
|
||||
// 过滤掉没有公里标数据的信号机
|
||||
if !judgeKilometerIsVaild(s.KilometerSystem) {
|
||||
continue
|
||||
}
|
||||
switch s.RefDev.DeviceType {
|
||||
case graphicData.RelatedRef_Section:
|
||||
gm.SectionMap[s.RefDev.Id].signals = append(gm.SectionMap[s.RefDev.Id].signals, s)
|
||||
case graphicData.RelatedRef_Turnout:
|
||||
gm.TurnoutMap[s.RefDev.Id].signals[s.RefDev.DevicePort] = s
|
||||
}
|
||||
}
|
||||
// 应答器关联到对应区段或道岔
|
||||
for _, t := range gd.Transponders {
|
||||
// 过滤掉没有公里标数据的应答器
|
||||
if !judgeKilometerIsVaild(t.KilometerSystem) {
|
||||
continue
|
||||
}
|
||||
switch t.TransponderRef.DeviceType {
|
||||
case graphicData.RelatedRef_Section:
|
||||
gm.SectionMap[t.TransponderRef.Id].transponders = append(gm.SectionMap[t.TransponderRef.Id].transponders, t)
|
||||
case graphicData.RelatedRef_Turnout:
|
||||
gm.TurnoutMap[t.TransponderRef.Id].transponders[t.TransponderRef.DevicePort] = append(gm.TurnoutMap[t.TransponderRef.Id].transponders[t.TransponderRef.DevicePort], t)
|
||||
}
|
||||
}
|
||||
// 停车标关联到对应区段或道岔
|
||||
for _, s := range gd.StopPositions {
|
||||
// 过滤掉没有公里标数据的停车标
|
||||
if !judgeKilometerIsVaild(s.KilometerSystem) {
|
||||
continue
|
||||
}
|
||||
switch s.RefDev.DeviceType {
|
||||
case graphicData.RelatedRef_Section:
|
||||
gm.SectionMap[s.RefDev.Id].stopPositions = append(gm.SectionMap[s.RefDev.Id].stopPositions, s)
|
||||
}
|
||||
}
|
||||
// 坡度Map
|
||||
slopeMap := make(map[graphicData.Direction]map[string]*graphicData.KilometerSystem)
|
||||
for _, s := range gd.SlopeKiloMarker {
|
||||
handleSlopeCurvaturesMap(s.Common.Id, s.KilometerSystem, slopeMap)
|
||||
}
|
||||
// 曲度Map
|
||||
curvatureMap := make(map[graphicData.Direction]map[string]*graphicData.KilometerSystem)
|
||||
for _, c := range gd.CurvatureKiloMarker {
|
||||
handleSlopeCurvaturesMap(c.Common.Id, c.KilometerSystem, curvatureMap)
|
||||
}
|
||||
|
||||
if len(slopeMap) != 0 || len(curvatureMap) != 0 {
|
||||
for _, s := range gm.SectionMap {
|
||||
handleSectionSlopeCurvaturesMap(s, slopeMap, func(sec *buildCalcSectionStruct) map[string]*graphicData.KilometerSystem { return sec.slopes })
|
||||
handleSectionSlopeCurvaturesMap(s, curvatureMap, func(sec *buildCalcSectionStruct) map[string]*graphicData.KilometerSystem { return sec.curvatures })
|
||||
}
|
||||
for _, t := range gm.TurnoutMap {
|
||||
if !judgeKilometerIsVaild(t.CrossKilometerSystem) {
|
||||
continue
|
||||
}
|
||||
// A点坡度
|
||||
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_A, t, slopeMap,
|
||||
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
|
||||
return sw.slopes
|
||||
})
|
||||
// B点坡度
|
||||
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_B, t, slopeMap,
|
||||
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
|
||||
return sw.slopes
|
||||
})
|
||||
// A点曲度
|
||||
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_A, t, curvatureMap,
|
||||
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
|
||||
return sw.curvatures
|
||||
})
|
||||
// B点曲度
|
||||
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_B, t, curvatureMap,
|
||||
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
|
||||
return sw.curvatures
|
||||
})
|
||||
}
|
||||
}
|
||||
return gm, startPoints
|
||||
}
|
||||
|
||||
@ -257,9 +442,11 @@ func getGraphicLinkPath(gm *buildCalcStruct, startPointQueue *list.List) map[int
|
||||
var refInfo *graphicData.RelatedRef
|
||||
var axleInfo *graphicData.AxleCounting
|
||||
if relatedRef.DeviceType == graphicData.RelatedRef_Section {
|
||||
refInfo, axleInfo = getRelatePointInfo(reflect.ValueOf(gm.SectionMap[relatedRef.Id]).Elem(), relatedRef.DevicePort)
|
||||
axleInfo = gm.SectionMap[relatedRef.Id].axlePoints[relatedRef.DevicePort]
|
||||
refInfo = getRelatePointInfo(reflect.ValueOf(gm.SectionMap[relatedRef.Id]).Elem(), relatedRef.DevicePort)
|
||||
} else {
|
||||
refInfo, axleInfo = getRelatePointInfo(reflect.ValueOf(gm.TurnoutMap[relatedRef.Id]).Elem(), relatedRef.DevicePort)
|
||||
axleInfo = gm.TurnoutMap[relatedRef.Id].axlePoints[relatedRef.DevicePort]
|
||||
refInfo = getRelatePointInfo(reflect.ValueOf(gm.TurnoutMap[relatedRef.Id]).Elem(), relatedRef.DevicePort)
|
||||
}
|
||||
// 查看是否已经被处理过的ID,计轴信息为空时表示道岔,将ID排序后存入
|
||||
var handleId string
|
||||
@ -274,37 +461,23 @@ func getGraphicLinkPath(gm *buildCalcStruct, startPointQueue *list.List) map[int
|
||||
continue
|
||||
}
|
||||
handleMap[handleId] = true
|
||||
// 追加函数存在问题,表示数据存在问题
|
||||
appendFunc := getRelateAppendMethod(gm, refInfo, relatedRef)
|
||||
if appendFunc == nil {
|
||||
zap.S().Warnf("link设备【%s】追加方式不确定", relatedRef.Id)
|
||||
continue
|
||||
}
|
||||
pathRefArr := []*graphicData.RelatedRef{refInfo}
|
||||
// 循环查找结束点
|
||||
loopRelateRef := relatedRef
|
||||
for loopRelateRef != nil {
|
||||
pathRefArr = appendFunc(loopRelateRef, pathRefArr)
|
||||
pathRefArr = append(pathRefArr, loopRelateRef)
|
||||
switch loopRelateRef.DeviceType {
|
||||
case graphicData.RelatedRef_Section:
|
||||
section := gm.SectionMap[loopRelateRef.Id]
|
||||
axleInfo = section.axlePoints[loopRelateRef.DevicePort]
|
||||
if loopRelateRef.DevicePort == graphicData.RelatedRef_A {
|
||||
axleInfo = section.BPoint
|
||||
loopRelateRef = section.Data.PbRef
|
||||
} else {
|
||||
axleInfo = section.APoint
|
||||
loopRelateRef = section.Data.PaRef
|
||||
}
|
||||
case graphicData.RelatedRef_Turnout:
|
||||
turnout := gm.TurnoutMap[loopRelateRef.Id]
|
||||
switch loopRelateRef.DevicePort {
|
||||
case graphicData.RelatedRef_A:
|
||||
axleInfo = turnout.APoint
|
||||
case graphicData.RelatedRef_B:
|
||||
axleInfo = turnout.BPoint
|
||||
case graphicData.RelatedRef_C:
|
||||
axleInfo = turnout.CPoint
|
||||
}
|
||||
axleInfo = turnout.axlePoints[loopRelateRef.DevicePort]
|
||||
loopRelateRef = nil
|
||||
}
|
||||
if axleInfo != nil { // 放入处理的计轴,防止倒过来重复处理
|
||||
@ -314,77 +487,22 @@ func getGraphicLinkPath(gm *buildCalcStruct, startPointQueue *list.List) map[int
|
||||
resultMap[id] = pathRefArr
|
||||
id++ // ID自增
|
||||
}
|
||||
fmt.Println(resultMap)
|
||||
return resultMap
|
||||
}
|
||||
|
||||
// 获取本连接点上一个连接信息以及计轴信息
|
||||
func getRelatePointInfo(v reflect.Value, p graphicData.RelatedRef_DevicePort) (*graphicData.RelatedRef, *graphicData.AxleCounting) {
|
||||
func getRelatePointInfo(v reflect.Value, p graphicData.RelatedRef_DevicePort) *graphicData.RelatedRef {
|
||||
var relateInfo reflect.Value
|
||||
var axlePoint reflect.Value
|
||||
// 放入计轴点
|
||||
switch p {
|
||||
case graphicData.RelatedRef_A:
|
||||
relateInfo = v.FieldByName("Data").Elem().FieldByName("PaRef")
|
||||
axlePoint = v.FieldByName("APoint")
|
||||
case graphicData.RelatedRef_B:
|
||||
relateInfo = v.FieldByName("Data").Elem().FieldByName("PbRef")
|
||||
axlePoint = v.FieldByName("BPoint")
|
||||
case graphicData.RelatedRef_C:
|
||||
relateInfo = v.FieldByName("Data").Elem().FieldByName("PcRef")
|
||||
axlePoint = v.FieldByName("CPoint")
|
||||
}
|
||||
return relateInfo.Interface().(*graphicData.RelatedRef), axlePoint.Interface().(*graphicData.AxleCounting)
|
||||
}
|
||||
|
||||
// 确定接点追加方法
|
||||
func getRelateAppendMethod(gm *buildCalcStruct, sRef, eRef *graphicData.RelatedRef) func(*graphicData.RelatedRef, []*graphicData.RelatedRef) []*graphicData.RelatedRef {
|
||||
start, sOK := handleFunc(gm, sRef)
|
||||
if !sOK {
|
||||
return nil
|
||||
}
|
||||
end, eOk := handleFunc(gm, eRef)
|
||||
if !eOk {
|
||||
return nil
|
||||
}
|
||||
if start > end {
|
||||
return func(refInfo *graphicData.RelatedRef, linkArr []*graphicData.RelatedRef) []*graphicData.RelatedRef {
|
||||
return append([]*graphicData.RelatedRef{refInfo}, linkArr...)
|
||||
}
|
||||
} else {
|
||||
return func(refInfo *graphicData.RelatedRef, linkArr []*graphicData.RelatedRef) []*graphicData.RelatedRef {
|
||||
return append(linkArr, refInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理函数
|
||||
func handleFunc(gm *buildCalcStruct, ref *graphicData.RelatedRef) (int, bool) {
|
||||
switch ref.DeviceType {
|
||||
case graphicData.RelatedRef_Section:
|
||||
section := gm.SectionMap[ref.Id]
|
||||
if ref.DevicePort == graphicData.RelatedRef_A {
|
||||
if section.APoint == nil || section.APoint.KilometerSystem == nil {
|
||||
zap.S().Warnf("区段【%s】A端缺少关联计轴信息", ref.Id)
|
||||
} else {
|
||||
return int(section.APoint.KilometerSystem.Kilometer), true
|
||||
}
|
||||
} else {
|
||||
if section.BPoint == nil || section.BPoint.KilometerSystem == nil {
|
||||
zap.S().Warnf("区段【%s】B端缺少关联计轴信息", ref.Id)
|
||||
} else {
|
||||
return int(section.BPoint.KilometerSystem.Kilometer), true
|
||||
}
|
||||
}
|
||||
case graphicData.RelatedRef_Turnout:
|
||||
turnout := gm.TurnoutMap[ref.Id]
|
||||
if turnout.CrossKilometerSystem == nil {
|
||||
zap.S().Warnf("道岔【%s】缺少岔心公里标数据", ref.Id)
|
||||
} else {
|
||||
return int(turnout.CrossKilometerSystem.Kilometer), true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
return relateInfo.Interface().(*graphicData.RelatedRef)
|
||||
}
|
||||
|
||||
// 获取起始端的
|
||||
@ -392,25 +510,97 @@ func getStartKilometer(gm *buildCalcStruct, ref *graphicData.RelatedRef) (int64,
|
||||
switch ref.DeviceType {
|
||||
case graphicData.RelatedRef_Section:
|
||||
section := gm.SectionMap[ref.Id]
|
||||
var aKilometer = int64(math.MaxInt64)
|
||||
if section.APoint != nil {
|
||||
aKilometer = section.APoint.KilometerSystem.Kilometer
|
||||
var resultKilometer = int64(math.MaxInt64)
|
||||
for _, p := range section.axlePoints {
|
||||
if resultKilometer > p.KilometerSystem.Kilometer {
|
||||
resultKilometer = p.KilometerSystem.Kilometer
|
||||
}
|
||||
}
|
||||
var bKilometer = int64(math.MaxInt64)
|
||||
if section.BPoint != nil {
|
||||
bKilometer = section.APoint.KilometerSystem.Kilometer
|
||||
}
|
||||
if aKilometer > bKilometer {
|
||||
return bKilometer, 0
|
||||
} else {
|
||||
return bKilometer, 0
|
||||
if resultKilometer == math.MaxInt64 {
|
||||
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: "区段公里标数据出错"})
|
||||
}
|
||||
return resultKilometer, 0
|
||||
case graphicData.RelatedRef_Turnout:
|
||||
turnout := gm.TurnoutMap[ref.Id]
|
||||
if turnout.CrossKilometerSystem == nil {
|
||||
if !judgeKilometerIsVaild(turnout.CrossKilometerSystem) {
|
||||
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: "道岔岔心无公里标"})
|
||||
}
|
||||
return turnout.CrossKilometerSystem.Kilometer, 0
|
||||
}
|
||||
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: "错误的设备类型类型"})
|
||||
}
|
||||
|
||||
// 判断公里标是否有效
|
||||
func judgeKilometerIsVaild(k *graphicData.KilometerSystem) bool {
|
||||
return k != nil && k.CoordinateSystem == "MAIN_LINE" && k.Kilometer != 0
|
||||
}
|
||||
|
||||
// 判断公里标k1 是否在这k2,k3个范围内
|
||||
func judgeKilometerInRange(k1, k2, k3 *graphicData.KilometerSystem) bool {
|
||||
if judgeKilometerIsVaild(k1) && judgeKilometerIsVaild(k2) && judgeKilometerIsVaild(k3) {
|
||||
start, end := k2, k3
|
||||
if k2.Kilometer > k3.Kilometer {
|
||||
start, end = k3, k2
|
||||
}
|
||||
return k1.Kilometer > start.Kilometer && k1.Kilometer < end.Kilometer
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 处理道岔坡度、曲度信息
|
||||
func handleSlopeCurvaturesMap(id string, kms []*graphicData.KilometerSystem, m map[graphicData.Direction]map[string]*graphicData.KilometerSystem) {
|
||||
for _, k := range kms {
|
||||
if judgeKilometerIsVaild(k) {
|
||||
kmMap := m[k.Direction]
|
||||
if kmMap == nil {
|
||||
kmMap = make(map[string]*graphicData.KilometerSystem)
|
||||
m[k.Direction] = kmMap
|
||||
}
|
||||
kmMap[id] = k
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleTurnoutSlopeCurvaturesMap(port graphicData.RelatedRef_DevicePort,
|
||||
t *buildCalcTurnoutStruct,
|
||||
scmap map[graphicData.Direction]map[string]*graphicData.KilometerSystem,
|
||||
f func(*buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem) {
|
||||
point := t.axlePoints[port]
|
||||
if point != nil {
|
||||
m := f(t)
|
||||
m[port] = make(map[string]*graphicData.KilometerSystem)
|
||||
kmMap := scmap[point.KilometerSystem.Direction]
|
||||
idArr := []string{}
|
||||
for k, v := range kmMap {
|
||||
if judgeKilometerInRange(v, point.KilometerSystem, t.CrossKilometerSystem) {
|
||||
m[port][k] = v
|
||||
idArr = append(idArr, k)
|
||||
}
|
||||
}
|
||||
for _, id := range idArr {
|
||||
delete(kmMap, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleSectionSlopeCurvaturesMap(s *buildCalcSectionStruct,
|
||||
scmap map[graphicData.Direction]map[string]*graphicData.KilometerSystem,
|
||||
f func(*buildCalcSectionStruct) map[string]*graphicData.KilometerSystem) {
|
||||
pointA := s.axlePoints[graphicData.RelatedRef_A]
|
||||
pointB := s.axlePoints[graphicData.RelatedRef_B]
|
||||
if pointA == nil || pointB == nil {
|
||||
return
|
||||
}
|
||||
m := f(s)
|
||||
kmMap := scmap[pointA.KilometerSystem.Direction]
|
||||
idArr := []string{}
|
||||
for k, v := range kmMap {
|
||||
if judgeKilometerInRange(v, pointA.KilometerSystem, pointB.KilometerSystem) {
|
||||
m[k] = v
|
||||
idArr = append(idArr, k)
|
||||
}
|
||||
}
|
||||
for _, id := range idArr {
|
||||
delete(kmMap, id)
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package memory
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
@ -13,13 +15,15 @@ import (
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/device"
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/ref"
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/section"
|
||||
"joylink.club/bj-rtsts-server/db/dbquery"
|
||||
"joylink.club/bj-rtsts-server/db/model"
|
||||
"joylink.club/bj-rtsts-server/dto"
|
||||
)
|
||||
|
||||
// 仿真存储集合 ID
|
||||
var graphicDataMap sync.Map
|
||||
|
||||
// 轨旁仿真模型结构,注意:这里的key 为 Index!!!
|
||||
// VerifyStructure 轨旁仿真模型结构
|
||||
type VerifyStructure struct {
|
||||
//计轴检测点设备模型集合,key为索引编号
|
||||
AxlePointDeviceModelMap map[string]face.AxlePointDeviceModeller
|
||||
@ -35,18 +39,37 @@ type VerifyStructure struct {
|
||||
LogicalSectionModelMap map[string]face.LogicalSectionModeller
|
||||
//信号机模型集合,key为索引编号
|
||||
SignalDeviceModelMap map[string]face.SignalDeviceModeller
|
||||
//Link模型集合,key为索引编号
|
||||
LinkModelMap map[int32]*device.LinkModel
|
||||
//坡度模型集合,key为id
|
||||
SlopeModelMap map[string]*section.SlopeModel
|
||||
//曲线模型集合,key为id
|
||||
CurveModelMap map[string]*section.CurveModel
|
||||
//点模型集合,key为id
|
||||
PointMap map[string]*device.PointModel
|
||||
}
|
||||
|
||||
// 设备地图ID对应map结构体(建立关系时便于查找使用),注意:这里的key 为 Common.Id !!!
|
||||
// GraphicInfoMapStructure 设备地图ID对应map结构体(建立关系时便于查找使用)
|
||||
type GraphicInfoMapStructure struct {
|
||||
AxlePointMap map[string]*graphicData.AxleCounting
|
||||
TurnoutMap map[string]*graphicData.Turnout
|
||||
LinkMap map[string]*graphicData.SectionLink
|
||||
SectionLinkMap map[string]*graphicData.SectionLink
|
||||
AxleSectionMap map[string]*graphicData.AxleCountingSection
|
||||
PhysicalSectionMap map[string]*graphicData.Section
|
||||
LogicSectionMap map[string]*graphicData.LogicSection
|
||||
SignalMap map[string]*graphicData.Signal
|
||||
CalcLinkMap map[string]*graphicData.CalculateLink
|
||||
//key-index
|
||||
CalcLinkMap map[int32]*graphicData.CalculateLink
|
||||
//设备在link上的位置。key-设备id
|
||||
DevicePositionMap map[string]*ref.DevicePosition
|
||||
}
|
||||
|
||||
// 计算link、物理区段、道岔相互转换时用到的结构体
|
||||
type calcLinkPositionStruct struct {
|
||||
index string // 地图元素的Index
|
||||
deviceType int // 1 计轴, 2 道岔
|
||||
kilometer *graphicData.KilometerSystem // 元素对应的公里标
|
||||
position *ref.DevicePosition // 元素在link上对应的偏移量
|
||||
}
|
||||
|
||||
// 将发布的地图数据放入内存中
|
||||
@ -60,24 +83,29 @@ func PublishMapVerifyStructure(graphic *model.PublishedGi) *VerifyStructure {
|
||||
PhysicalSectionModelMap: make(map[string]face.PhysicalSectionModeller),
|
||||
LogicalSectionModelMap: make(map[string]face.LogicalSectionModeller),
|
||||
SignalDeviceModelMap: make(map[string]face.SignalDeviceModeller),
|
||||
LinkModelMap: make(map[int32]*device.LinkModel),
|
||||
SlopeModelMap: make(map[string]*section.SlopeModel),
|
||||
CurveModelMap: make(map[string]*section.CurveModel),
|
||||
PointMap: make(map[string]*device.PointModel),
|
||||
}
|
||||
// 地图数据转为map存储,建立关系时方便使用
|
||||
graphicInfoMap := &GraphicInfoMapStructure{
|
||||
AxlePointMap: make(map[string]*graphicData.AxleCounting),
|
||||
TurnoutMap: make(map[string]*graphicData.Turnout),
|
||||
LinkMap: make(map[string]*graphicData.SectionLink),
|
||||
SectionLinkMap: make(map[string]*graphicData.SectionLink),
|
||||
AxleSectionMap: make(map[string]*graphicData.AxleCountingSection),
|
||||
PhysicalSectionMap: make(map[string]*graphicData.Section),
|
||||
LogicSectionMap: make(map[string]*graphicData.LogicSection),
|
||||
SignalMap: make(map[string]*graphicData.Signal),
|
||||
CalcLinkMap: make(map[string]*graphicData.CalculateLink),
|
||||
CalcLinkMap: make(map[int32]*graphicData.CalculateLink),
|
||||
DevicePositionMap: make(map[string]*ref.DevicePosition),
|
||||
}
|
||||
graphicStorage := &graphicData.RtssGraphicStorage{}
|
||||
proto.Unmarshal(graphic.Proto, graphicStorage)
|
||||
// 初始化地图结构
|
||||
initGraphicStructure(graphicStorage, verifyStructure, graphicInfoMap)
|
||||
// 构建设备间的关联关系(8.8 注释掉构建逻辑)
|
||||
// buildDeviceRef(graphicInfoMap, verifyStructure)
|
||||
buildDeviceRef(graphicInfoMap, verifyStructure)
|
||||
graphicDataMap.Store(graphic.ID, verifyStructure)
|
||||
return verifyStructure
|
||||
}
|
||||
@ -93,7 +121,229 @@ func QueryMapVerifyStructure(mapId int32) *VerifyStructure {
|
||||
if ok {
|
||||
return d.(*VerifyStructure)
|
||||
}
|
||||
panic(fmt.Sprintf("地图【id:%d】不存在", mapId))
|
||||
mapData, _ := dbquery.PublishedGi.Where(dbquery.PublishedGi.ID.Eq(mapId), dbquery.PublishedGi.Status.Eq(1)).First()
|
||||
if mapData != nil {
|
||||
return PublishMapVerifyStructure(mapData)
|
||||
} else {
|
||||
panic(fmt.Sprintf("地图【id:%d】不存在", mapId))
|
||||
}
|
||||
}
|
||||
|
||||
// 根据区段,道岔偏移量返回linkID和link相对偏移量
|
||||
func QueryMapCalcLinkByDeviceInfo(mapId int32, id string, devicePort string, offset int64, runDirection bool) (int32, int64, bool, bool) {
|
||||
vm := QueryMapVerifyStructure(mapId)
|
||||
if devicePort == "" {
|
||||
return sectionMapToLink(vm, id, offset, runDirection)
|
||||
} else {
|
||||
return turnoutMapToLink(vm, id, devicePort, offset, runDirection)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据物理区段上的偏移量(基于区段A端),找到所在link的linkId与偏移量
|
||||
func sectionMapToLink(vm *VerifyStructure, id string, offset int64, runDirection bool) (int32, int64, bool, bool) {
|
||||
sm := vm.PhysicalSectionModelMap[id]
|
||||
if sm == nil {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在区段【index:%s】", id)})
|
||||
}
|
||||
sectionModel := sm.(*section.PhysicalSectionModel)
|
||||
// 确定link信息
|
||||
var linkId int32
|
||||
// 获取计轴信息
|
||||
axlePointPositionMap := make(map[string]*ref.DevicePosition)
|
||||
for k, lm := range vm.LinkModelMap {
|
||||
for _, p := range lm.DevicePositions {
|
||||
_, ok := p.Device.(*device.AxlePointDeviceModel)
|
||||
if ok && sectionModel.AxlePoints[p.Device.GetIndex()] != nil {
|
||||
axlePointPositionMap[p.Device.GetIndex()] = p
|
||||
}
|
||||
}
|
||||
// 如果已经找到计轴则退出
|
||||
if len(axlePointPositionMap) > 0 {
|
||||
linkId = k
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(axlePointPositionMap) == 0 { // 无计轴信息
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到区段【id:%s,index:%s】所在link", sectionModel.GraphicId, id)})
|
||||
}
|
||||
pointA := sectionModel.PortAxlePoints[face.A.Name()] // 获取A计轴点
|
||||
if pointA != nil {
|
||||
ap := axlePointPositionMap[pointA.GetIndex()]
|
||||
if ap == nil {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("link【%d】缺失计轴【%s】", linkId, pointA.GetGraphicId())})
|
||||
}
|
||||
pointB := sectionModel.PortAxlePoints[face.B.Name()] // 获取B计轴点
|
||||
abDirection := pointB == nil
|
||||
ak := (pointA.(*device.AxlePointDeviceModel)).KilometerSystem // 获取a点公里标
|
||||
ao, bo := ap.Offset, int32(math.MaxInt32) // a,b的偏移量,默认B点比A点大
|
||||
var bp *ref.DevicePosition // 定义b点偏移对象
|
||||
var bk *graphicData.KilometerSystem // 定义b点公里标
|
||||
if !abDirection && axlePointPositionMap[pointB.GetIndex()] != nil {
|
||||
bp = axlePointPositionMap[pointB.GetIndex()]
|
||||
bo = bp.Offset
|
||||
bk = (pointB.(*device.AxlePointDeviceModel)).KilometerSystem
|
||||
abDirection = convertPointTo(ak, bk, runDirection)
|
||||
}
|
||||
up := convertRunDirectionToUp(ak, bk, ap, bp, runDirection)
|
||||
if ao < bo {
|
||||
return linkId, int64(ao) + offset, up, abDirection
|
||||
} else {
|
||||
return linkId, int64(ao) - offset, up, abDirection
|
||||
}
|
||||
} else {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("link【%d】缺失区段【id:%s,index:%s】A点缺失计轴", linkId, sectionModel.GraphicId, id)})
|
||||
}
|
||||
}
|
||||
|
||||
// 根据道岔上的偏移量(基于岔心位置),找到所在link的linkId与偏移量
|
||||
func turnoutMapToLink(vm *VerifyStructure, id string, port string, offset int64, runDirection bool) (int32, int64, bool, bool) {
|
||||
tm := vm.SwitchDeviceModelMap[id]
|
||||
if tm == nil {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【index:%s】", id)})
|
||||
}
|
||||
turnoutModel := tm.(*device.SwitchDeviceModel)
|
||||
var link *device.LinkModel
|
||||
var linkId int32
|
||||
var isStart bool
|
||||
Outter:
|
||||
for i, lm := range vm.LinkModelMap {
|
||||
linkId = i
|
||||
if lm.ARelatedSwitchRef.SwitchDevice != nil && lm.ARelatedSwitchRef.SwitchDevice.GetIndex() == turnoutModel.Index && lm.ARelatedSwitchRef.Port.Name() == port {
|
||||
isStart = true
|
||||
link = lm
|
||||
} else if lm.BRelatedSwitchRef.SwitchDevice != nil && lm.BRelatedSwitchRef.SwitchDevice.GetIndex() == turnoutModel.Index && lm.BRelatedSwitchRef.Port.Name() == port {
|
||||
link = lm
|
||||
}
|
||||
if link != nil {
|
||||
break Outter
|
||||
}
|
||||
}
|
||||
if link == nil {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到道岔【id:%s,index:%s】端口【%s】所在link", turnoutModel.GraphicId, id, port)})
|
||||
}
|
||||
calcPositionArr := convertPositionToCalcPosition(link)
|
||||
var vp *calcLinkPositionStruct
|
||||
var index int
|
||||
for i, v := range calcPositionArr {
|
||||
if v.index == turnoutModel.GetIndex() {
|
||||
vp = v
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if vp != nil && len(calcPositionArr) > 1 {
|
||||
var np *calcLinkPositionStruct
|
||||
if index+1 < len(calcPositionArr) {
|
||||
np = calcPositionArr[index+1]
|
||||
} else {
|
||||
np = calcPositionArr[index-1]
|
||||
}
|
||||
up := convertRunDirectionToUp(vp.kilometer, np.kilometer, vp.position, np.position, runDirection)
|
||||
pointTo := convertPointTo(vp.kilometer, np.kilometer, runDirection)
|
||||
if isStart {
|
||||
return linkId, int64(vp.position.Offset) + offset, up, pointTo
|
||||
} else {
|
||||
return linkId, int64(vp.position.Offset) - offset, up, pointTo
|
||||
}
|
||||
}
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("link【%d】缺失道岔【id:%s,index:%s】端口【%s】偏移量", linkId, turnoutModel.GraphicId, id, port)})
|
||||
}
|
||||
|
||||
// 根据linkID和link相对偏移量返回区段,道岔偏移量
|
||||
// 设备ID、端口、偏移量、上下行、AB走向
|
||||
func QueryDeviceByCalcLink(vm *VerifyStructure, id int32, offset int64, up, defaultRunDirection bool) (string, string, int64, bool, bool) {
|
||||
linkModel := vm.LinkModelMap[id]
|
||||
if linkModel == nil {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到link【%d】", id)})
|
||||
}
|
||||
if offset > int64(linkModel.Length) {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("偏移超出link范围【%d】", id)})
|
||||
}
|
||||
calcPositionArr := convertPositionToCalcPosition(linkModel) // 转换位置对象
|
||||
var devicePosition, calcPosition *calcLinkPositionStruct // 获取当前、下一个节点,偏移量在这个范围中
|
||||
for _, v := range calcPositionArr {
|
||||
if v.position.Offset > int32(offset) {
|
||||
calcPosition = v
|
||||
break
|
||||
} else {
|
||||
devicePosition = v
|
||||
}
|
||||
}
|
||||
// 运行方向
|
||||
var runDirection bool
|
||||
if calcPosition != nil {
|
||||
runDirection = (calcPosition.kilometer.Kilometer >= devicePosition.kilometer.Kilometer) == up
|
||||
} else {
|
||||
runDirection = defaultRunDirection
|
||||
}
|
||||
isSwitch := (devicePosition.deviceType == 2) // 道岔
|
||||
// 获取另一个端点
|
||||
if calcPosition != nil {
|
||||
isSwitch = isSwitch || calcPosition.deviceType == 2 // 道岔
|
||||
}
|
||||
if isSwitch {
|
||||
var sid string
|
||||
var op int64
|
||||
if devicePosition.deviceType == 2 {
|
||||
sid = devicePosition.index
|
||||
op = int64(devicePosition.position.Offset)
|
||||
|
||||
} else {
|
||||
sid = calcPosition.index
|
||||
op = int64(calcPosition.position.Offset)
|
||||
}
|
||||
tm := vm.SwitchDeviceModelMap[sid]
|
||||
if tm == nil {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【index:%s】", sid)})
|
||||
}
|
||||
if linkModel.ARelatedSwitchRef.SwitchDevice != nil && linkModel.ARelatedSwitchRef.SwitchDevice.GetIndex() == sid { // 起始点
|
||||
return sid, linkModel.ARelatedSwitchRef.Port.Name(), offset - op, runDirection, up == false
|
||||
} else if linkModel.BRelatedSwitchRef.SwitchDevice != nil && linkModel.BRelatedSwitchRef.SwitchDevice.GetIndex() == sid { // 结束点
|
||||
return sid, linkModel.BRelatedSwitchRef.Port.Name(), op - offset, runDirection, up == true
|
||||
} else {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【index:%s】", devicePosition.index)})
|
||||
}
|
||||
} else {
|
||||
sectionModel, ok := linkOffsetQuerySection(vm, devicePosition, calcPosition)
|
||||
if ok {
|
||||
isEnd := (calcPosition == nil) && (offset == int64(linkModel.Length)) // 是否已经走到尽头
|
||||
pointA := sectionModel.PortAxlePoints[face.A.Name()]
|
||||
var bk *graphicData.KilometerSystem
|
||||
if calcPosition != nil {
|
||||
bk = calcPosition.kilometer
|
||||
}
|
||||
if devicePosition.index == pointA.GetIndex() {
|
||||
return sectionModel.Index, "", offset - int64(devicePosition.position.Offset), runDirection, convertPointTo(devicePosition.kilometer, bk, runDirection)
|
||||
} else if calcPosition != nil {
|
||||
return sectionModel.Index, "", int64(calcPosition.position.Offset) - offset, runDirection, convertPointTo(bk, devicePosition.kilometer, runDirection)
|
||||
} else {
|
||||
for _, v := range calcPositionArr {
|
||||
if v.deviceType == 1 && v.index == pointA.GetIndex() { // 计轴
|
||||
if isEnd {
|
||||
return sectionModel.Index, "", offset - int64(v.position.Offset), runDirection, convertPointTo(v.kilometer, nil, runDirection)
|
||||
} else {
|
||||
return sectionModel.Index, "", int64(v.position.Offset) - offset, runDirection, convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("区段【%s】A端计轴缺失", sectionModel.GraphicId)})
|
||||
}
|
||||
} else {
|
||||
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到区段【index:%s-index:%s】", devicePosition.index, calcPosition.index)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func linkOffsetQuerySection(vm *VerifyStructure, devicePosition, calcPosition *calcLinkPositionStruct) (*section.PhysicalSectionModel, bool) {
|
||||
var sectionModel *section.PhysicalSectionModel
|
||||
for _, s := range vm.PhysicalSectionModelMap {
|
||||
sectionModel = s.(*section.PhysicalSectionModel)
|
||||
if sectionModel.AxlePoints[devicePosition.index] != nil && (calcPosition == nil || sectionModel.AxlePoints[calcPosition.index] != nil) {
|
||||
return sectionModel, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 初始化地图结构
|
||||
@ -112,8 +362,134 @@ func initGraphicStructure(graphicData *graphicData.RtssGraphicStorage, verifyStr
|
||||
initGraphicLogicSections(graphicData.LogicSections, verifyStructure, graphicDataMap)
|
||||
// 初始化信号机信息
|
||||
initGraphicSignal(graphicData.Signals, verifyStructure, graphicDataMap)
|
||||
// 初始化计算link数据
|
||||
initCalcLink(graphicData.CalculateLink, verifyStructure, graphicDataMap)
|
||||
// 初始化Link信息
|
||||
initLinks(graphicData.CalculateLink, verifyStructure, graphicDataMap)
|
||||
// 初始化坡度和曲线端点
|
||||
// initPoints(graphicData, verifyStructure, graphicDataMap)
|
||||
// 初始化坡度
|
||||
// initSlopes(graphicData.Slopes, verifyStructure, graphicDataMap)
|
||||
// 初始化曲线
|
||||
// initCurves(graphicData.Curvatures, verifyStructure, graphicDataMap)
|
||||
}
|
||||
|
||||
func initCurves(curves []*graphicData.Curvature, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
|
||||
for _, curve := range curves {
|
||||
startDp := dataMap.DevicePositionMap[curve.RefDeviceId[0]]
|
||||
endDp := dataMap.DevicePositionMap[curve.RefDeviceId[1]]
|
||||
startIndex, _ := strconv.Atoi(startDp.Device.GetIndex())
|
||||
endIndex, _ := strconv.Atoi(endDp.Device.GetIndex())
|
||||
vs.CurveModelMap[curve.Common.Id] = §ion.CurveModel{
|
||||
DeviceModel: face.DeviceModel{
|
||||
GraphicId: curve.GetCommon().GetId(),
|
||||
Index: curve.GetCommon().GetId(),
|
||||
},
|
||||
StartLinkIndex: int32(startIndex),
|
||||
StartLinkOffset: startDp.Offset,
|
||||
EndLinkIndex: int32(endIndex),
|
||||
EndLinkOffset: endDp.Offset,
|
||||
Curvature: curve.CurvatureNumber,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initSlopes(slopes []*graphicData.Slope, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
|
||||
for _, slope := range slopes {
|
||||
startDp := dataMap.DevicePositionMap[slope.RefDeviceId[0]]
|
||||
endDp := dataMap.DevicePositionMap[slope.RefDeviceId[1]]
|
||||
startIndex, _ := strconv.Atoi(startDp.Device.GetIndex())
|
||||
endIndex, _ := strconv.Atoi(endDp.Device.GetIndex())
|
||||
vs.SlopeModelMap[slope.Common.Id] = §ion.SlopeModel{
|
||||
DeviceModel: face.DeviceModel{
|
||||
GraphicId: slope.GetCommon().GetId(),
|
||||
Index: slope.GetCommon().GetId(),
|
||||
},
|
||||
StartLinkIndex: int32(startIndex),
|
||||
StartLinkOffset: startDp.Offset,
|
||||
EndLinkIndex: int32(endIndex),
|
||||
EndLinkOffset: endDp.Offset,
|
||||
DegreeTrig: slope.SlopeNumber,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initPoints(storage *graphicData.RtssGraphicStorage, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
|
||||
for _, slopeKm := range storage.SlopeKiloMarker {
|
||||
vs.PointMap[slopeKm.Common.Id] = &device.PointModel{
|
||||
DeviceModel: face.DeviceModel{
|
||||
GraphicId: slopeKm.Common.Id,
|
||||
Index: slopeKm.Common.Id,
|
||||
},
|
||||
Kms: slopeKm.KilometerSystem,
|
||||
}
|
||||
}
|
||||
for _, curvatureKm := range storage.CurvatureKiloMarker {
|
||||
vs.PointMap[curvatureKm.Common.Id] = &device.PointModel{
|
||||
DeviceModel: face.DeviceModel{
|
||||
GraphicId: curvatureKm.Common.Id,
|
||||
Index: curvatureKm.Common.Id,
|
||||
},
|
||||
Kms: curvatureKm.KilometerSystem,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initLinks(links []*graphicData.CalculateLink, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
|
||||
deviceIdMap := make(map[string]face.DeviceModeller)
|
||||
for _, modeller := range vs.AxlePointDeviceModelMap {
|
||||
deviceIdMap[modeller.GetGraphicId()] = modeller
|
||||
}
|
||||
for _, modeller := range vs.SwitchDeviceModelMap {
|
||||
deviceIdMap[modeller.GetGraphicId()] = modeller
|
||||
}
|
||||
for _, pointModel := range vs.PointMap {
|
||||
deviceIdMap[pointModel.GetGraphicId()] = pointModel
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
linkModel := &device.LinkModel{
|
||||
DeviceModel: face.DeviceModel{
|
||||
GraphicId: link.Common.Id,
|
||||
Index: strconv.Itoa(int(link.Index)),
|
||||
},
|
||||
Length: link.Length,
|
||||
}
|
||||
if link.ARelatedRef != nil {
|
||||
linkModel.ARelatedSwitchRef = ref.SwitchRef{
|
||||
SwitchDevice: deviceIdMap[link.ARelatedRef.Id],
|
||||
Port: face.GetPortEnum(int8(link.ARelatedRef.DevicePort)),
|
||||
}
|
||||
}
|
||||
if link.BRelatedRef != nil {
|
||||
linkModel.BRelatedSwitchRef = ref.SwitchRef{
|
||||
SwitchDevice: deviceIdMap[link.BRelatedRef.Id],
|
||||
Port: face.GetPortEnum(int8(link.BRelatedRef.DevicePort)),
|
||||
}
|
||||
}
|
||||
vs.LinkModelMap[link.Index] = linkModel
|
||||
dataMap.CalcLinkMap[link.Index] = link
|
||||
//构建DevicePosition(DP)切片(暂时仅计轴和道岔)
|
||||
var dps []*ref.DevicePosition
|
||||
for _, dp := range link.DevicePositions {
|
||||
modeller := deviceIdMap[dp.DeviceId]
|
||||
if modeller == nil {
|
||||
continue
|
||||
}
|
||||
dps = append(dps, &ref.DevicePosition{
|
||||
Device: modeller,
|
||||
Offset: dp.Offset,
|
||||
})
|
||||
dataMap.DevicePositionMap[dp.DeviceId] = &ref.DevicePosition{
|
||||
Device: linkModel,
|
||||
Offset: dp.Offset,
|
||||
}
|
||||
}
|
||||
//对DP切片按Offset排序
|
||||
sort.Slice(dps, func(i, j int) bool {
|
||||
return dps[i].Offset < dps[j].Offset
|
||||
})
|
||||
//赋值
|
||||
linkModel.DevicePositions = dps
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化计轴信息
|
||||
@ -126,7 +502,7 @@ func initGraphicAxlePoints(axlePoints []*graphicData.AxleCounting, data *VerifyS
|
||||
GraphicId: a.Common.Id,
|
||||
Index: id,
|
||||
},
|
||||
KilometerSystem: *a.GetKilometerSystem(),
|
||||
KilometerSystem: a.GetKilometerSystem(),
|
||||
SwitchDevices: make(map[string]*ref.SwitchRef),
|
||||
AreaPhysicalSections: make(map[string]face.PhysicalSectionModeller),
|
||||
}
|
||||
@ -144,6 +520,7 @@ func initGraphicTurnout(turnouts []*graphicData.Turnout, data *VerifyStructure,
|
||||
Index: id,
|
||||
},
|
||||
KilometerSystems: t.GetKilometerSystem(),
|
||||
AxlePoints: make(map[string]*device.AxlePointDeviceModel),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,7 +528,7 @@ func initGraphicTurnout(turnouts []*graphicData.Turnout, data *VerifyStructure,
|
||||
// 初始化link信息
|
||||
func initGraphicLink(links []*graphicData.SectionLink, data *VerifyStructure, graphicDataMap *GraphicInfoMapStructure) {
|
||||
for _, s := range links {
|
||||
graphicDataMap.LinkMap[s.Common.Id] = s
|
||||
graphicDataMap.SectionLinkMap[s.Common.Id] = s
|
||||
id := strconv.Itoa(int(s.Index))
|
||||
data.LinkSectionModelMap[id] = §ion.LinkSectionModel{
|
||||
DeviceModel: face.DeviceModel{
|
||||
@ -189,9 +566,10 @@ func initGraphicPhysicalSections(physicalSections []*graphicData.Section, data *
|
||||
GraphicId: s.Common.Id,
|
||||
Index: id,
|
||||
},
|
||||
SwitchArea: len(s.AxleCountings) > 2,
|
||||
AxlePoints: make(map[string]face.AxlePointDeviceModeller),
|
||||
AxleSections: make(map[string]face.AxleSectionModeller),
|
||||
SwitchArea: len(s.AxleCountings) > 2,
|
||||
AxlePoints: make(map[string]face.AxlePointDeviceModeller),
|
||||
AxleSections: make(map[string]face.AxleSectionModeller),
|
||||
PortAxlePoints: make(map[string]face.AxlePointDeviceModeller),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,10 +610,7 @@ func initGraphicSignal(signals []*graphicData.Signal, data *VerifyStructure, gra
|
||||
|
||||
// 初始化计算link数据
|
||||
func initCalcLink(calculateLinks []*graphicData.CalculateLink, verifyStructure *VerifyStructure, graphicDataMap *GraphicInfoMapStructure) {
|
||||
for _, l := range calculateLinks {
|
||||
id := strconv.Itoa(int(l.Index))
|
||||
graphicDataMap.CalcLinkMap[id] = l
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 构建设备间的关系
|
||||
@ -258,7 +633,7 @@ func buildDeviceRef(graphicData *GraphicInfoMapStructure, verifyStructure *Verif
|
||||
|
||||
// 构建link的关联关系(端点间的轨道)
|
||||
func buildLinkDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
|
||||
for _, v := range mapData.LinkMap {
|
||||
for _, v := range mapData.SectionLinkMap {
|
||||
link := (verifyStructure.LinkSectionModelMap[strconv.Itoa(int(v.Index))]).(*section.LinkSectionModel)
|
||||
// 轨道A端端点
|
||||
linkSimRefBuildCommMethod(v.Common.Id, v.ASimRef, mapData, verifyStructure, func(f face.AxlePointDeviceModeller) {
|
||||
@ -319,7 +694,7 @@ func linkRefBuildCommMethod(v *graphicData.SectionLink, mapData *GraphicInfoMapS
|
||||
if r != nil {
|
||||
switch r.DeviceType {
|
||||
case graphicData.RelatedRef_SectionLink:
|
||||
d := mapData.LinkMap[r.Id]
|
||||
d := mapData.SectionLinkMap[r.Id]
|
||||
if d != nil {
|
||||
ls := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(d.Index))]
|
||||
lr(&ref.LinkRef{LinkSection: ls, Port: face.PortEnum(r.DevicePort)})
|
||||
@ -346,6 +721,7 @@ func buildTurnoutDeviceRef(verifyStructure *VerifyStructure) {
|
||||
buildTurnoutCommMethod(s, s.SwitchRefA, face.A)
|
||||
buildTurnoutCommMethod(s, s.SwitchRefB, face.B)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func buildTurnoutCommMethod(s *section.LinkSectionModel, linkSwitch *ref.SwitchRef, p face.PortEnum) {
|
||||
@ -462,11 +838,16 @@ func buildAxlePointDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *
|
||||
zap.S().Warnf("id为[%s]的计轴检测点关联的道岔[%s]不存在", id, relatedRef.Id)
|
||||
}
|
||||
switchDeviceModel := (verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]).(*device.SwitchDeviceModel)
|
||||
// 道岔端口对应的计轴
|
||||
switchDeviceModel.AxlePoints[relatedRef.DevicePort.String()] = axlePointDeviceModel
|
||||
axlePointDeviceModel.SwitchDevices[switchDeviceModel.Index] = &ref.SwitchRef{
|
||||
SwitchDevice: switchDeviceModel,
|
||||
Port: face.PortEnum(relatedRef.DevicePort),
|
||||
}
|
||||
case graphicData.RelatedRef_Section:
|
||||
if relatedRef.Id == "4" {
|
||||
fmt.Println("")
|
||||
}
|
||||
s := mapData.PhysicalSectionMap[relatedRef.Id]
|
||||
if s == nil {
|
||||
zap.S().Warnf("id为[%s]的计轴检测点关联的物理区段[%s]不存在", id, relatedRef.Id)
|
||||
@ -475,6 +856,7 @@ func buildAxlePointDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *
|
||||
if physicalSectionModel.SwitchArea {
|
||||
zap.S().Warnf("id为[%s]的计轴检测点proto数据关联岔区物理区段[%s]不存在", id, relatedRef.Id)
|
||||
}
|
||||
physicalSectionModel.PortAxlePoints[relatedRef.DevicePort.String()] = axlePointDeviceModel
|
||||
switch relatedRef.DevicePort {
|
||||
case graphicData.RelatedRef_A:
|
||||
axlePointDeviceModel.LinePhysicalSectionA = physicalSectionModel
|
||||
@ -496,3 +878,50 @@ func buildPhysicalAxlePointDeviceRef(verifyStructure *VerifyStructure) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将linkPosition转换为计算对象
|
||||
func convertPositionToCalcPosition(link *device.LinkModel) []*calcLinkPositionStruct {
|
||||
result := []*calcLinkPositionStruct{}
|
||||
for _, p := range link.DevicePositions {
|
||||
s, sok := p.Device.(*device.SwitchDeviceModel)
|
||||
if sok {
|
||||
result = append(result, &calcLinkPositionStruct{
|
||||
index: p.Device.GetIndex(),
|
||||
deviceType: 2,
|
||||
position: p,
|
||||
kilometer: s.KilometerSystems[0],
|
||||
})
|
||||
} else {
|
||||
a, aok := p.Device.(*device.AxlePointDeviceModel)
|
||||
if aok {
|
||||
result = append(result, &calcLinkPositionStruct{
|
||||
index: p.Device.GetIndex(),
|
||||
deviceType: 1,
|
||||
position: p,
|
||||
kilometer: a.KilometerSystem,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 判断上下行与link方向是否一直
|
||||
func convertRunDirectionToUp(ak, bk *graphicData.KilometerSystem, ap, bp *ref.DevicePosition, direction bool) bool {
|
||||
if bk == nil {
|
||||
return direction
|
||||
}
|
||||
if (ak.Kilometer > bk.Kilometer) == (ap.Offset > bp.Offset) {
|
||||
return direction
|
||||
} else {
|
||||
return !direction
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否是否从A端到B端
|
||||
func convertPointTo(ak, bk *graphicData.KilometerSystem, direction bool) bool {
|
||||
if bk == nil {
|
||||
return true == direction
|
||||
}
|
||||
return (ak.Kilometer < bk.Kilometer) == direction
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"joylink.club/bj-rtsts-server/dto"
|
||||
"joylink.club/bj-rtsts-server/dynamics"
|
||||
|
||||
@ -25,14 +27,19 @@ func AddTrainState(simulation *VerifySimulation, status *state.TrainState) {
|
||||
status.Show = true
|
||||
//向动力学发送初始化请求
|
||||
trainIndex, _ := strconv.ParseUint(status.Id, 10, 16)
|
||||
linkIndex, _ := strconv.ParseUint(status.HeadLinkId, 10, 16)
|
||||
// 映射link、偏移量、运行方向
|
||||
linkId, loffset, up, pointTo := QueryMapCalcLinkByDeviceInfo(simulation.MapId, status.HeadDeviceId, status.DevicePort, status.HeadOffset, status.RunDirection)
|
||||
status.Up = up
|
||||
status.PointTo = pointTo
|
||||
httpCode, _, err := dynamics.SendInitTrainReq(&dynamics.InitTrainInfo{
|
||||
TrainIndex: uint16(trainIndex),
|
||||
LinkIndex: uint16(linkIndex),
|
||||
LinkOffset: uint16(status.HeadLinkOffset / 10),
|
||||
LinkIndex: uint16(linkId),
|
||||
LinkOffset: uint32(loffset),
|
||||
Speed: uint16(math.Round(float64(status.Speed * 10))),
|
||||
Up: status.Up,
|
||||
})
|
||||
zap.S().Debugf("添加列车:[%d-%s-%d]", trainIndex, status.HeadLinkId, status.HeadLinkOffset)
|
||||
zap.S().Debugf("列车初始化:[%d-%d-%d]", trainIndex, linkId, loffset)
|
||||
if err != nil || httpCode != http.StatusOK {
|
||||
panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
|
||||
}
|
||||
@ -54,6 +61,8 @@ func UpdateTrainState(simulation *VerifySimulation, status *state.TrainState) {
|
||||
t.Up = status.Up
|
||||
t.Upslope = status.Upslope
|
||||
t.RunningUp = status.RunningUp
|
||||
t.RunDirection = status.RunDirection
|
||||
t.PointTo = status.PointTo
|
||||
// 合并其他信息
|
||||
proto.Merge(t, status)
|
||||
// 更新全量信息
|
||||
@ -68,6 +77,13 @@ func RemoveTrainState(simulation *VerifySimulation, id string) {
|
||||
d, ok := allTrainMap.Load(id)
|
||||
if ok {
|
||||
t := d.(*state.TrainState)
|
||||
trainIndex, _ := strconv.ParseUint(id, 10, 16)
|
||||
httpCode, _, err := dynamics.SendRemoveTrainReq(&dynamics.InitTrainInfo{
|
||||
TrainIndex: uint16(trainIndex),
|
||||
})
|
||||
if err != nil || httpCode != http.StatusOK {
|
||||
panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
|
||||
}
|
||||
// 从仿真内存中移除列车
|
||||
t.Show = false
|
||||
allTrainMap.Store(id, t)
|
||||
|
@ -11,7 +11,7 @@ type AxlePointDeviceModel struct {
|
||||
//计轴检测点基本信息
|
||||
face.DeviceModel
|
||||
//端点的公里标,单位为mm
|
||||
KilometerSystem graphicData.KilometerSystem
|
||||
KilometerSystem *graphicData.KilometerSystem
|
||||
//与该计轴点关联的道岔
|
||||
//key为图形id
|
||||
SwitchDevices map[string]*ref.SwitchRef
|
||||
|
@ -0,0 +1,18 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/ref"
|
||||
)
|
||||
|
||||
type LinkModel struct {
|
||||
face.DeviceModel
|
||||
//长度
|
||||
Length int32
|
||||
//A端连接的道岔端点
|
||||
ARelatedSwitchRef ref.SwitchRef
|
||||
//B端连接的道岔端点
|
||||
BRelatedSwitchRef ref.SwitchRef
|
||||
//Link上的设备及位置(包括A、B端的设备)(按offset排序)
|
||||
DevicePositions []*ref.DevicePosition
|
||||
}
|
12
ats/verify/simulation/wayside/model/device/point.go
Normal file
12
ats/verify/simulation/wayside/model/device/point.go
Normal file
@ -0,0 +1,12 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
|
||||
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
|
||||
)
|
||||
|
||||
// PointModel 线上某一点(本来是想添加坡度和曲线端点,但是他俩数据没有区别,故合为一个通用概念)
|
||||
type PointModel struct {
|
||||
face.DeviceModel
|
||||
Kms []*graphicData.KilometerSystem
|
||||
}
|
@ -19,6 +19,8 @@ type SwitchDeviceModel struct {
|
||||
LinkRefB *ref.LinkRef
|
||||
//道岔C端连接的link
|
||||
LinkRefC *ref.LinkRef
|
||||
// 道岔相连的计轴信息
|
||||
AxlePoints map[string]*AxlePointDeviceModel
|
||||
}
|
||||
|
||||
// 获取道岔端口关联的轨道
|
||||
|
@ -0,0 +1,8 @@
|
||||
package ref
|
||||
|
||||
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
|
||||
|
||||
type DevicePosition struct {
|
||||
Device face.DeviceModeller
|
||||
Offset int32
|
||||
}
|
13
ats/verify/simulation/wayside/model/section/curve_model.go
Normal file
13
ats/verify/simulation/wayside/model/section/curve_model.go
Normal file
@ -0,0 +1,13 @@
|
||||
package section
|
||||
|
||||
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
|
||||
|
||||
type CurveModel struct {
|
||||
face.DeviceModel
|
||||
StartLinkIndex int32
|
||||
StartLinkOffset int32
|
||||
EndLinkIndex int32
|
||||
EndLinkOffset int32
|
||||
//曲率(半径)mm
|
||||
Curvature int32
|
||||
}
|
@ -14,6 +14,8 @@ type PhysicalSectionModel struct {
|
||||
//该物理区段中包含的所有计轴区段
|
||||
//key-图形id
|
||||
AxleSections map[string]face.AxleSectionModeller
|
||||
// 端口对应的计轴信息
|
||||
PortAxlePoints map[string]face.AxlePointDeviceModeller
|
||||
}
|
||||
|
||||
// 添加计轴检测点
|
||||
|
13
ats/verify/simulation/wayside/model/section/slope_model.go
Normal file
13
ats/verify/simulation/wayside/model/section/slope_model.go
Normal file
@ -0,0 +1,13 @@
|
||||
package section
|
||||
|
||||
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
|
||||
|
||||
type SlopeModel struct {
|
||||
face.DeviceModel
|
||||
StartLinkIndex int32
|
||||
StartLinkOffset int32
|
||||
EndLinkIndex int32
|
||||
EndLinkOffset int32
|
||||
//坡度角的三角函数(应该是sin)*1000
|
||||
DegreeTrig int32
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 9830db4a12bdf1018b89ea5d86fff0832a4a8eb0
|
||||
Subproject commit ab41f6836f96e8a06ff6edfee202f0bf0c7aecf5
|
@ -6,7 +6,7 @@ server:
|
||||
port: 9091
|
||||
# 动力学端口配置
|
||||
dynamics:
|
||||
ip: 192.168.3.94
|
||||
ip: 192.168.3.222
|
||||
udpLocalPort: 4000
|
||||
udpRemotePort: 3000
|
||||
httpPort: 7800
|
||||
|
@ -32,6 +32,7 @@ func newCategory(db *gorm.DB, opts ...gen.DOOption) category {
|
||||
_category.Config = field.NewString(tableName, "config")
|
||||
_category.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_category.UpdateAt = field.NewTime(tableName, "update_at")
|
||||
_category.Code = field.NewString(tableName, "code")
|
||||
|
||||
_category.fillFieldMap()
|
||||
|
||||
@ -47,6 +48,7 @@ type category struct {
|
||||
Config field.String // 厂家配置
|
||||
CreatedAt field.Time // 创建时间
|
||||
UpdateAt field.Time // 修改时间
|
||||
Code field.String // 编码
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@ -68,6 +70,7 @@ func (c *category) updateTableName(table string) *category {
|
||||
c.Config = field.NewString(table, "config")
|
||||
c.CreatedAt = field.NewTime(table, "created_at")
|
||||
c.UpdateAt = field.NewTime(table, "update_at")
|
||||
c.Code = field.NewString(table, "code")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
@ -84,12 +87,13 @@ func (c *category) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (c *category) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 5)
|
||||
c.fieldMap = make(map[string]field.Expr, 6)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["name"] = c.Name
|
||||
c.fieldMap["config"] = c.Config
|
||||
c.fieldMap["created_at"] = c.CreatedAt
|
||||
c.fieldMap["update_at"] = c.UpdateAt
|
||||
c.fieldMap["code"] = c.Code
|
||||
}
|
||||
|
||||
func (c category) clone(db *gorm.DB) category {
|
||||
|
@ -33,7 +33,7 @@ func newDrafting(db *gorm.DB, opts ...gen.DOOption) drafting {
|
||||
_drafting.CreatorID = field.NewInt32(tableName, "creator_id")
|
||||
_drafting.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_drafting.UpdateAt = field.NewTime(tableName, "update_at")
|
||||
_drafting.Category = field.NewInt32(tableName, "category")
|
||||
_drafting.Category = field.NewString(tableName, "category")
|
||||
|
||||
_drafting.fillFieldMap()
|
||||
|
||||
@ -50,7 +50,7 @@ type drafting struct {
|
||||
CreatorID field.Int32 // 创建人id
|
||||
CreatedAt field.Time // 创建时间
|
||||
UpdateAt field.Time // 修改时间
|
||||
Category field.Int32 // 厂家id
|
||||
Category field.String // 厂家编码
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (d *drafting) updateTableName(table string) *drafting {
|
||||
d.CreatorID = field.NewInt32(table, "creator_id")
|
||||
d.CreatedAt = field.NewTime(table, "created_at")
|
||||
d.UpdateAt = field.NewTime(table, "update_at")
|
||||
d.Category = field.NewInt32(table, "category")
|
||||
d.Category = field.NewString(table, "category")
|
||||
|
||||
d.fillFieldMap()
|
||||
|
||||
|
@ -32,7 +32,7 @@ func newPublishedGi(db *gorm.DB, opts ...gen.DOOption) publishedGi {
|
||||
_publishedGi.Proto = field.NewBytes(tableName, "proto")
|
||||
_publishedGi.UserID = field.NewInt32(tableName, "user_id")
|
||||
_publishedGi.PublishAt = field.NewTime(tableName, "publish_at")
|
||||
_publishedGi.Category = field.NewInt32(tableName, "category")
|
||||
_publishedGi.Category = field.NewString(tableName, "category")
|
||||
_publishedGi.Note = field.NewString(tableName, "note")
|
||||
_publishedGi.Status = field.NewInt32(tableName, "status")
|
||||
|
||||
@ -50,7 +50,7 @@ type publishedGi struct {
|
||||
Proto field.Bytes // 图形界面数据
|
||||
UserID field.Int32 // 发布用户id
|
||||
PublishAt field.Time // 发布时间
|
||||
Category field.Int32 // 厂家信息
|
||||
Category field.String // 厂家信息
|
||||
Note field.String // 发布描述
|
||||
Status field.Int32 // 显示状态
|
||||
|
||||
@ -74,7 +74,7 @@ func (p *publishedGi) updateTableName(table string) *publishedGi {
|
||||
p.Proto = field.NewBytes(table, "proto")
|
||||
p.UserID = field.NewInt32(table, "user_id")
|
||||
p.PublishAt = field.NewTime(table, "publish_at")
|
||||
p.Category = field.NewInt32(table, "category")
|
||||
p.Category = field.NewString(table, "category")
|
||||
p.Note = field.NewString(table, "note")
|
||||
p.Status = field.NewInt32(table, "status")
|
||||
|
||||
|
@ -17,6 +17,7 @@ type Category struct {
|
||||
Config string `gorm:"column:config;comment:厂家配置" json:"config"` // 厂家配置
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdateAt time.Time `gorm:"column:update_at;comment:修改时间" json:"update_at"` // 修改时间
|
||||
Code string `gorm:"column:code;comment:编码" json:"code"` // 编码
|
||||
}
|
||||
|
||||
// TableName Category's table name
|
||||
|
@ -18,7 +18,7 @@ type Drafting struct {
|
||||
CreatorID int32 `gorm:"column:creator_id;not null;comment:创建人id" json:"creator_id"` // 创建人id
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdateAt time.Time `gorm:"column:update_at;comment:修改时间" json:"update_at"` // 修改时间
|
||||
Category int32 `gorm:"column:category;comment:厂家id" json:"category"` // 厂家id
|
||||
Category string `gorm:"column:category;comment:厂家编码" json:"category"` // 厂家编码
|
||||
}
|
||||
|
||||
// TableName Drafting's table name
|
||||
|
@ -17,7 +17,7 @@ type PublishedGi struct {
|
||||
Proto []byte `gorm:"column:proto;not null;comment:图形界面数据" json:"proto"` // 图形界面数据
|
||||
UserID int32 `gorm:"column:user_id;not null;comment:发布用户id" json:"user_id"` // 发布用户id
|
||||
PublishAt time.Time `gorm:"column:publish_at;not null;comment:发布时间" json:"publish_at"` // 发布时间
|
||||
Category int32 `gorm:"column:category;comment:厂家信息" json:"category"` // 厂家信息
|
||||
Category string `gorm:"column:category;comment:厂家信息" json:"category"` // 厂家信息
|
||||
Note string `gorm:"column:note;comment:发布描述" json:"note"` // 发布描述
|
||||
Status int32 `gorm:"column:status;default:1;comment:显示状态" json:"status"` // 显示状态
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ type PageCategoryReqDto struct {
|
||||
|
||||
type CategoryDto struct {
|
||||
Id int `json:"id" form:"id"`
|
||||
Code string `json:"code" form:"code"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Config string `json:"config" form:"config"`
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ type PageDraftingReqDto struct {
|
||||
type DraftingDto struct {
|
||||
Id int `json:"id" form:"id"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Category int32 `json:"category" form:"category"`
|
||||
Category string `json:"category" form:"category"`
|
||||
Proto []byte `json:"proto" from:"proto"`
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,17 @@ type AddTrainReqDto struct {
|
||||
//仿真id
|
||||
SimulationId string `json:"simulationId" form:"simulationId"`
|
||||
//列车方向,true-上行,false-下行
|
||||
Up bool `json:"up" form:"up"`
|
||||
RunDirection bool `json:"up" form:"up"`
|
||||
//车头所在link的索引
|
||||
HeadLinkId string `json:"headLinkId" form:"headLinkId"`
|
||||
//车头所在link内的偏移量,单位为mm
|
||||
HeadLinkOffset int64 `json:"headLinkOffset" form:"headLinkOffset"`
|
||||
//物理区段、道岔ID
|
||||
Id string `json:"id" form:"id"`
|
||||
//道岔端口
|
||||
DevicePort string `json:"devicePort" form:"devicePort"`
|
||||
//车头所在link内的偏移量,单位为mm
|
||||
HeadOffset int64 `json:"headOffset" form:"headOffset"`
|
||||
}
|
||||
|
||||
// 为仿真添加测试车请求
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"joylink.club/bj-rtsts-server/config"
|
||||
)
|
||||
|
||||
func SendInitTrainReq(info *InitTrainInfo) (int, *[]byte, error) {
|
||||
@ -13,7 +15,32 @@ func SendInitTrainReq(info *InitTrainInfo) (int, *[]byte, error) {
|
||||
uri := "/api/aerodynamics/init/train/"
|
||||
url := baseUrl + uri
|
||||
data, _ := json.Marshal(info)
|
||||
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
|
||||
client := http.Client{
|
||||
Timeout: time.Second * 5,
|
||||
}
|
||||
resp, err := client.Post(url, "application/json", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
s := err.Error()
|
||||
println(s)
|
||||
return 0, nil, err
|
||||
}
|
||||
var buf []byte
|
||||
_, err = resp.Body.Read(buf)
|
||||
if err != nil {
|
||||
return resp.StatusCode, nil, err
|
||||
}
|
||||
return resp.StatusCode, &buf, resp.Body.Close()
|
||||
}
|
||||
|
||||
func SendRemoveTrainReq(info *InitTrainInfo) (int, *[]byte, error) {
|
||||
baseUrl := getUrlBase()
|
||||
uri := "/api/aerodynamics/remove/train/"
|
||||
url := baseUrl + uri
|
||||
data, _ := json.Marshal(info)
|
||||
client := http.Client{
|
||||
Timeout: time.Second * 5,
|
||||
}
|
||||
resp, err := client.Post(url, "application/json", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
s := err.Error()
|
||||
println(s)
|
||||
@ -48,7 +75,7 @@ func SendSimulationStartReq(base *LineBaseInfo) (int, *[]byte, error) {
|
||||
|
||||
func SendSimulationEndReq() (int, *[]byte, error) {
|
||||
baseUrl := getUrlBase()
|
||||
uri := "/api/end"
|
||||
uri := "/api/end/"
|
||||
url := baseUrl + uri
|
||||
resp, err := http.Post(url, "application/json", nil)
|
||||
if err != nil {
|
||||
|
@ -3,7 +3,7 @@ package dynamics
|
||||
type InitTrainInfo struct {
|
||||
TrainIndex uint16 `json:"trainIndex"`
|
||||
LinkIndex uint16 `json:"linkIndex"`
|
||||
LinkOffset uint16 `json:"linkOffset"`
|
||||
LinkOffset uint32 `json:"linkOffset"`
|
||||
//单位0.1km/h
|
||||
Speed uint16 `json:"speed"`
|
||||
Up bool `json:"up"`
|
||||
@ -11,9 +11,9 @@ type InitTrainInfo struct {
|
||||
|
||||
// LineBaseInfo 线路基础信息,提供给动力学作为计算依据
|
||||
type LineBaseInfo struct {
|
||||
LinkList []Link `json:"linkList"`
|
||||
SlopeList []Slope `json:"slopeList"`
|
||||
CurveList []Curve `json:"curveList"`
|
||||
LinkList []*Link `json:"linkList"`
|
||||
SlopeList []*Slope `json:"slopeList"`
|
||||
CurveList []*Curve `json:"curveList"`
|
||||
}
|
||||
|
||||
type Link struct {
|
||||
|
157
dynamics/udp.go
157
dynamics/udp.go
@ -3,6 +3,7 @@ package dynamics
|
||||
import (
|
||||
"container/list"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
"go.uber.org/zap"
|
||||
@ -14,43 +15,72 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
runSendTurnoutStateTask()
|
||||
}
|
||||
|
||||
var (
|
||||
m sync.Map
|
||||
)
|
||||
|
||||
type TurnoutInfoFunc func() []*TurnoutInfo
|
||||
|
||||
func runSendTurnoutStateTask() {
|
||||
go func() {
|
||||
tick := time.Tick(50 * time.Millisecond)
|
||||
for range tick {
|
||||
m.Range(func(key, value any) bool {
|
||||
slice := value.(TurnoutInfoFunc)()
|
||||
for _, turnoutInfo := range slice {
|
||||
err := SendTurnoutInfo(turnoutInfo)
|
||||
if err != nil {
|
||||
zap.S().Error(err)
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
for true {
|
||||
info := <-trainInfoChan
|
||||
for e := handlerList.Front(); e != nil; e = e.Next() {
|
||||
func() {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r != nil {
|
||||
zap.S().Errorf("列车信息处理函数报错")
|
||||
}
|
||||
}()
|
||||
handler := e.Value.(TrainInfoHandler)
|
||||
handler(info)
|
||||
}()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func AddTurnoutInfoSource(simId string, tiFunc TurnoutInfoFunc) {
|
||||
m.Store(simId, tiFunc)
|
||||
type TurnoutInfoFunc func() []*TurnoutInfo
|
||||
|
||||
var (
|
||||
running bool
|
||||
mutex sync.Mutex
|
||||
turnoutInfoFunc TurnoutInfoFunc
|
||||
//道岔消息生命信号
|
||||
turnoutLifeSignal uint16
|
||||
//列车消息生命信号
|
||||
trainLifeSignal uint16
|
||||
//列车生命信号是否初始化
|
||||
trainLifeSignalInit bool
|
||||
//用于处理生命信号循环使用产生的各种特殊处理
|
||||
limit uint16 = 10000
|
||||
//列车消息队列
|
||||
trainInfoChan chan *TrainInfo = make(chan *TrainInfo)
|
||||
)
|
||||
|
||||
func Run(tiFunc TurnoutInfoFunc) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
trainLifeSignalInit = false
|
||||
return runSendTurnoutStateTask(tiFunc)
|
||||
}
|
||||
|
||||
func RemoveTurnoutInfoSource(simId string) {
|
||||
m.Delete(simId)
|
||||
func Stop() {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
turnoutInfoFunc = nil
|
||||
}
|
||||
|
||||
// SendTurnoutInfo 发送道岔信息
|
||||
func SendTurnoutInfo(info *TurnoutInfo) error {
|
||||
var handlerList list.List
|
||||
|
||||
type TrainInfoHandler func(info *TrainInfo)
|
||||
|
||||
func RegisterTrainInfoHandler(handler TrainInfoHandler) {
|
||||
handlerList.PushBack(handler)
|
||||
}
|
||||
|
||||
func RunUdpServer() {
|
||||
server := &udpServer{addr: fmt.Sprintf("udp://:%d", config.Config.Dynamics.UdpLocalPort), multicore: false}
|
||||
err := gnet.Run(server, server.addr, gnet.WithMulticore(server.multicore))
|
||||
zap.L().Fatal("udp服务启动失败", zap.Error(err))
|
||||
}
|
||||
|
||||
// sendTurnoutInfo 发送道岔信息
|
||||
func sendTurnoutInfo(info *TurnoutInfo) error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
zap.S().Error("发送道岔信息失败", r)
|
||||
@ -70,6 +100,7 @@ func SendTurnoutInfo(info *TurnoutInfo) error {
|
||||
}
|
||||
}(conn)
|
||||
var data []byte
|
||||
data = binary.BigEndian.AppendUint16(data, info.lifeSignal)
|
||||
data = binary.BigEndian.AppendUint16(data, info.Code)
|
||||
var b byte
|
||||
if info.NPosition {
|
||||
@ -105,12 +136,32 @@ func (server *udpServer) OnBoot(eng gnet.Engine) gnet.Action {
|
||||
func (server *udpServer) OnTraffic(c gnet.Conn) gnet.Action {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
zap.S().Error("udp服务数据解析异常", r)
|
||||
zap.L().Error("udp服务数据解析异常", zap.Any("panic", r))
|
||||
}
|
||||
}()
|
||||
buf, _ := c.Next(-1)
|
||||
trainInfo := TrainInfo{}
|
||||
trainInfo.LifeSignal = binary.BigEndian.Uint16(buf[0:2])
|
||||
if !trainLifeSignalInit {
|
||||
trainLifeSignalInit = true
|
||||
trainLifeSignal = trainInfo.LifeSignal
|
||||
} else if trainLifeSignal < limit {
|
||||
if trainInfo.LifeSignal < trainLifeSignal || trainInfo.LifeSignal > trainLifeSignal-limit {
|
||||
zap.S().Debugf("丢弃列车信息[%d-%d]", trainInfo.LifeSignal, trainLifeSignal)
|
||||
return gnet.None
|
||||
}
|
||||
} else if trainLifeSignal < math.MaxUint16-10000 {
|
||||
if trainInfo.LifeSignal < trainLifeSignal {
|
||||
zap.S().Debugf("丢弃列车信息[%d-%d]", trainInfo.LifeSignal, trainLifeSignal)
|
||||
return gnet.None
|
||||
}
|
||||
} else {
|
||||
if trainInfo.LifeSignal < trainLifeSignal && trainInfo.LifeSignal > trainLifeSignal+10000 {
|
||||
zap.S().Debugf("丢弃列车信息[%d-%d]", trainInfo.LifeSignal, trainLifeSignal)
|
||||
return gnet.None
|
||||
}
|
||||
}
|
||||
trainLifeSignal = trainInfo.LifeSignal
|
||||
trainInfo.Number = buf[2]
|
||||
trainInfo.Len = binary.BigEndian.Uint16(buf[3:5])
|
||||
trainInfo.Link = buf[5]
|
||||
@ -131,24 +182,40 @@ func (server *udpServer) OnTraffic(c gnet.Conn) gnet.Action {
|
||||
trainInfo.HeadRadarSpeed = math.Float32frombits(binary.BigEndian.Uint32(buf[50:54]))
|
||||
trainInfo.TailRadarSpeed = math.Float32frombits(binary.BigEndian.Uint32(buf[54:58]))
|
||||
|
||||
for e := handlerList.Front(); e != nil; e = e.Next() {
|
||||
handler := e.Value.(TrainInfoHandler)
|
||||
handler(&trainInfo)
|
||||
}
|
||||
trainInfoChan <- &trainInfo
|
||||
|
||||
return gnet.None
|
||||
}
|
||||
|
||||
var handlerList list.List
|
||||
|
||||
type TrainInfoHandler func(info *TrainInfo)
|
||||
|
||||
func RegisterTrainInfoHandler(handler TrainInfoHandler) {
|
||||
handlerList.PushBack(handler)
|
||||
}
|
||||
|
||||
func RunUdpServer() {
|
||||
server := &udpServer{addr: fmt.Sprintf("udp://:%d", config.Config.Dynamics.UdpLocalPort), multicore: false}
|
||||
err := gnet.Run(server, server.addr, gnet.WithMulticore(server.multicore))
|
||||
zap.L().Fatal("udp服务启动失败", zap.Error(err))
|
||||
func runSendTurnoutStateTask(tiFunc TurnoutInfoFunc) error {
|
||||
if running {
|
||||
return nil
|
||||
}
|
||||
if tiFunc == nil {
|
||||
return errors.New("tiFunc不能为空")
|
||||
}
|
||||
turnoutInfoFunc = tiFunc
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("Recovered from panic:", r)
|
||||
}
|
||||
}()
|
||||
tick := time.Tick(50 * time.Millisecond)
|
||||
for range tick {
|
||||
if turnoutInfoFunc == nil {
|
||||
continue
|
||||
}
|
||||
slice := turnoutInfoFunc()
|
||||
for _, turnoutInfo := range slice {
|
||||
turnoutInfo.lifeSignal = turnoutLifeSignal
|
||||
err := sendTurnoutInfo(turnoutInfo)
|
||||
if err != nil {
|
||||
zap.S().Error(err)
|
||||
}
|
||||
}
|
||||
turnoutLifeSignal++
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package dynamics
|
||||
|
||||
type TurnoutInfo struct {
|
||||
Code uint16
|
||||
NPosition bool
|
||||
RPosition bool
|
||||
lifeSignal uint16
|
||||
Code uint16
|
||||
NPosition bool
|
||||
RPosition bool
|
||||
}
|
||||
|
||||
type TrainInfo struct {
|
||||
@ -21,7 +22,7 @@ type TrainInfo struct {
|
||||
Slope uint16
|
||||
//列车所在位置坡度走势(上/下坡)
|
||||
UpSlope bool
|
||||
//列车当前运行方向(上/下行)
|
||||
//列车当前运行方向(偏移量增大/减小方向)
|
||||
Up bool
|
||||
//实际运行阻力(总)(N)
|
||||
TotalResistance uint32
|
||||
|
@ -29,7 +29,7 @@ func TestSendTurnoutInfo(t *testing.T) {
|
||||
tick := time.Tick(50 * time.Millisecond)
|
||||
for range tick {
|
||||
for i := 1; i <= 9; i++ {
|
||||
SendTurnoutInfo(&TurnoutInfo{
|
||||
sendTurnoutInfo(&TurnoutInfo{
|
||||
Code: uint16(i),
|
||||
NPosition: true,
|
||||
RPosition: false,
|
||||
|
@ -16,7 +16,7 @@ func PageCategoryQuery(query *dto.PageCategoryReqDto) (*dto.PageDto, error) {
|
||||
if query.Name != "" {
|
||||
dq = dq.Where(d.Name.Like(fmt.Sprintf("%%%s%%", query.Name)))
|
||||
}
|
||||
records, total, err := dq.Debug().Select(d.ID, d.Name, d.UpdateAt, d.CreatedAt).FindByPage(query.Offset(), query.Size)
|
||||
records, total, err := dq.Debug().Select(d.ID, d.Code, d.Name, d.UpdateAt, d.CreatedAt).FindByPage(query.Offset(), query.Size)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -30,7 +30,7 @@ func ListCategoryQuery(query *dto.PageCategoryReqDto) ([]*model.Category, error)
|
||||
if query.Name != "" {
|
||||
dq = dq.Where(d.Name.Like(fmt.Sprintf("%%%s%%", query.Name)))
|
||||
}
|
||||
records, err := dq.Debug().Select(d.ID, d.Name, d.UpdateAt, d.CreatedAt).Find()
|
||||
records, err := dq.Debug().Select(d.ID, d.Code, d.Name, d.UpdateAt, d.CreatedAt).Find()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -39,11 +39,12 @@ func ListCategoryQuery(query *dto.PageCategoryReqDto) ([]*model.Category, error)
|
||||
|
||||
// 创建草稿
|
||||
func CreateCategory(dto *dto.CategoryDto) (*model.Category, error) {
|
||||
if err := checkCategoryInfo(dto.Name); err != nil {
|
||||
if err := checkCategoryInfo(dto.Name, dto.Code, 0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d := model.Category{
|
||||
Name: dto.Name,
|
||||
Code: dto.Code,
|
||||
Config: dto.Config,
|
||||
CreatedAt: time.Now(),
|
||||
UpdateAt: time.Now(),
|
||||
@ -64,11 +65,17 @@ func QueryCategory(id int32) *model.Category {
|
||||
}
|
||||
|
||||
func UpdateCategory(id int32, dto *dto.CategoryDto) bool {
|
||||
if err := checkCategoryInfo(dto.Name, dto.Code, id); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
findOldQuery := dbquery.Category
|
||||
oldD, err := findOldQuery.Where(findOldQuery.ID.Eq(id)).Debug().First()
|
||||
if oldD == nil || err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if dto.Code != "" {
|
||||
oldD.Code = dto.Code
|
||||
}
|
||||
if dto.Config != "" {
|
||||
oldD.Config = dto.Config
|
||||
}
|
||||
@ -87,14 +94,29 @@ func DeleteCategoryById(id int) {
|
||||
_, _ = dbquery.Category.Debug().Where(dbquery.Category.ID.Eq(int32(id))).Delete()
|
||||
}
|
||||
|
||||
func checkCategoryInfo(name string) error {
|
||||
func checkCategoryInfo(name string, code string, id int32) error {
|
||||
findNameQuery := dbquery.Category
|
||||
count, err := findNameQuery.Where(findNameQuery.Name.Eq(name)).Debug().Count()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
w := findNameQuery.Where()
|
||||
if id != 0 {
|
||||
w = w.Where(findNameQuery.ID.Eq(id))
|
||||
}
|
||||
if count > 0 {
|
||||
panic("名称已存在")
|
||||
if name != "" {
|
||||
count, err := w.Where(findNameQuery.Name.Eq(name)).Debug().Count()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if count > 0 {
|
||||
panic("名称已存在")
|
||||
}
|
||||
}
|
||||
return err
|
||||
if code != "" {
|
||||
count, err := w.Where(findNameQuery.Code.Eq(code)).Debug().Count()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if count > 0 {
|
||||
panic("编码已存在")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user