直接存储Proto的Message;创建仿真时由仿真模块构建模型;发给动力学的数据从仿真模块返回的Repository构建

This commit is contained in:
joylink_zhangsai 2023-09-20 15:14:40 +08:00
parent 0fbec96ef6
commit 2d20cfbf45
16 changed files with 1338 additions and 429 deletions

View File

@ -1,163 +0,0 @@
package calculate
import (
"errors"
"fmt"
"math"
"strconv"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/memory"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/device"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/ref"
)
// CalculateLinkPositionAndDirection 根据起始link位置、偏移量、偏移方向计算偏移后的位置及方向。偏移方向上的剩余距离不够会返回error
func CalculateLinkPositionAndDirection(simulation *memory.VerifySimulation, linkIndex int32, linkOffset int32, up bool,
offset int32) (int32, int32, bool, error) {
vs := memory.QueryMapVerifyStructure(simulation.MapId)
direction := "下"
if up {
direction = "上"
}
var tempOffset int32
if up {
tempOffset = linkOffset + offset
linkModel := vs.LinkModelMap[linkIndex]
if tempOffset <= linkModel.Length {
return linkIndex, tempOffset, up, nil
}
if linkModel.BRelatedSwitchRef == nil {
return linkIndex, 0, up, errors.New(fmt.Sprintf("link位置[%d-%d]向[%s]偏移[%d]超出极限", linkIndex, linkOffset, direction, offset))
}
turnoutState := memory.GetTurnoutState(simulation, linkModel.ARelatedSwitchRef.SwitchDevice.GetIndex())
turnoutModel := linkModel.ARelatedSwitchRef.SwitchDevice.(*device.SwitchDeviceModel)
var linkPort *ref.DevicePort[*device.LinkModel]
if turnoutState.Normal {
switch linkModel.BRelatedSwitchRef.Port {
case face.A:
linkPort = turnoutModel.BLinkPort
case face.B:
linkPort = turnoutModel.ALinkPort
}
} else if turnoutState.Reverse {
switch linkModel.BRelatedSwitchRef.Port {
case face.A:
linkPort = turnoutModel.CLinkPort
case face.C:
linkPort = turnoutModel.ALinkPort
}
}
if linkPort != nil {
var newOffset int32
var newUp bool
i, _ := strconv.Atoi(linkPort.Device.Index)
switch linkPort.Port {
case face.A:
newOffset = 0
newUp = true
case face.B:
newOffset = linkPort.Device.Length
newUp = false
}
return CalculateLinkPositionAndDirection(simulation, int32(i), newOffset, newUp, tempOffset-linkModel.Length)
} else {
return linkIndex, 0, up, errors.New(fmt.Sprintf("link位置[%d-%d]向[%s]偏移[%d]超出极限", linkIndex, linkOffset, direction, offset))
}
} else {
tempOffset = linkOffset - offset
if tempOffset >= 0 {
return linkIndex, tempOffset, up, nil
}
linkModel := vs.LinkModelMap[linkIndex]
if linkModel.ARelatedSwitchRef == nil {
return linkIndex, 0, up, errors.New(fmt.Sprintf("link位置[%d-%d]向[%s]偏移[%d]超出极限", linkIndex, linkOffset, direction, offset))
}
turnoutState := memory.GetTurnoutState(simulation, linkModel.ARelatedSwitchRef.SwitchDevice.GetIndex())
turnoutModel := linkModel.ARelatedSwitchRef.SwitchDevice.(*device.SwitchDeviceModel)
var linkPort *ref.DevicePort[*device.LinkModel]
if turnoutState.Normal {
switch linkModel.ARelatedSwitchRef.Port {
case face.A:
linkPort = turnoutModel.BLinkPort
case face.B:
linkPort = turnoutModel.ALinkPort
}
} else if turnoutState.Reverse {
switch linkModel.ARelatedSwitchRef.Port {
case face.A:
linkPort = turnoutModel.CLinkPort
case face.C:
linkPort = turnoutModel.ALinkPort
}
}
if linkPort != nil {
var newOffset int32
var newUp bool
i, _ := strconv.Atoi(linkPort.Device.Index)
switch linkPort.Port {
case face.A:
newOffset = 0
newUp = true
case face.B:
newOffset = linkPort.Device.Length
newUp = false
}
return CalculateLinkPositionAndDirection(simulation, int32(i), newOffset, newUp, int32(math.Abs(float64(tempOffset))))
} else {
return linkIndex, 0, up, errors.New(fmt.Sprintf("link位置[%d-%d]向[%s]偏移[%d]超出极限", linkIndex, linkOffset, direction, offset))
}
}
}
// CalculateLen 计算两个link位置的间距
// @param up 优先向这个方向查找终点
func CalculateLen(start *ref.DevicePosition[*device.LinkModel], end *ref.DevicePosition[*device.LinkModel], up bool) (int, error) {
return calculateLen(start, end, up, 0)
}
//// CalculateDirection 计算以{link}为基准的dp方向
//// @param up 优先向这个方向查找link
//func CalculateDirection(dp *ref.DevicePort[*device.LinkModel], link *device.LinkModel, up bool) *ref.DevicePort[*device.LinkModel] {
// if link == dp.Device {
// return dp
// }
//
//}
func calculateLen(start *ref.DevicePosition[*device.LinkModel], end *ref.DevicePosition[*device.LinkModel],
up bool, l int) (int, error) {
if start.Device == end.Device {
return l + int(math.Abs(float64(start.Offset-end.Offset))), nil
}
var turnoutPort *ref.SwitchRef
if up {
l += int(start.Device.Length - start.Offset)
turnoutPort = start.Device.BRelatedSwitchRef
} else {
l += int(start.Offset)
turnoutPort = start.Device.ARelatedSwitchRef
}
var lps []*ref.DevicePosition[*device.LinkModel]
if turnoutPort != nil {
turnoutModel := start.Device.BRelatedSwitchRef.SwitchDevice.(*device.SwitchDeviceModel)
device.ConvertFromDevicePort(turnoutModel.BLinkPort)
switch turnoutPort.Port {
case face.A:
lps = append(lps, device.ConvertFromDevicePort(turnoutModel.BLinkPort))
lps = append(lps, device.ConvertFromDevicePort(turnoutModel.CLinkPort))
case face.B | face.C:
lps = append(lps, device.ConvertFromDevicePort(turnoutModel.ALinkPort))
}
}
for _, lp := range lps {
i, err := calculateLen(lp, end, lp.Offset == 0, l)
if err == nil {
return i, nil
}
}
return 0, errors.New(fmt.Sprintf("从[%s]到[%s]的间距无法计算", start.String(), end.String()))
}

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.31.0
// protoc v4.23.1
// source: picture.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.31.0
// protoc v4.23.1
// source: pslGraphics.proto

View File

@ -0,0 +1,526 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.23.1
// source: relayCabinetLayoutGraphics.proto
package graphicData
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type RelayCabinetGraphicStorage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Canvas *Canvas `protobuf:"bytes,1,opt,name=canvas,proto3" json:"canvas,omitempty"`
RelayCabinets []*RelayCabinet `protobuf:"bytes,2,rep,name=relayCabinets,proto3" json:"relayCabinets,omitempty"`
Relays []*Relay `protobuf:"bytes,3,rep,name=relays,proto3" json:"relays,omitempty"`
DeviceRelateRelayList []*DeviceRelateRelay `protobuf:"bytes,4,rep,name=deviceRelateRelayList,proto3" json:"deviceRelateRelayList,omitempty"`
BelongsConcentrationStation string `protobuf:"bytes,5,opt,name=belongsConcentrationStation,proto3" json:"belongsConcentrationStation,omitempty"` //继电器柜图所属集中站
}
func (x *RelayCabinetGraphicStorage) Reset() {
*x = RelayCabinetGraphicStorage{}
if protoimpl.UnsafeEnabled {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RelayCabinetGraphicStorage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RelayCabinetGraphicStorage) ProtoMessage() {}
func (x *RelayCabinetGraphicStorage) ProtoReflect() protoreflect.Message {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RelayCabinetGraphicStorage.ProtoReflect.Descriptor instead.
func (*RelayCabinetGraphicStorage) Descriptor() ([]byte, []int) {
return file_relayCabinetLayoutGraphics_proto_rawDescGZIP(), []int{0}
}
func (x *RelayCabinetGraphicStorage) GetCanvas() *Canvas {
if x != nil {
return x.Canvas
}
return nil
}
func (x *RelayCabinetGraphicStorage) GetRelayCabinets() []*RelayCabinet {
if x != nil {
return x.RelayCabinets
}
return nil
}
func (x *RelayCabinetGraphicStorage) GetRelays() []*Relay {
if x != nil {
return x.Relays
}
return nil
}
func (x *RelayCabinetGraphicStorage) GetDeviceRelateRelayList() []*DeviceRelateRelay {
if x != nil {
return x.DeviceRelateRelayList
}
return nil
}
func (x *RelayCabinetGraphicStorage) GetBelongsConcentrationStation() string {
if x != nil {
return x.BelongsConcentrationStation
}
return ""
}
type RelayCabinet struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Common *CommonInfo `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"`
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` //编号
}
func (x *RelayCabinet) Reset() {
*x = RelayCabinet{}
if protoimpl.UnsafeEnabled {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RelayCabinet) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RelayCabinet) ProtoMessage() {}
func (x *RelayCabinet) ProtoReflect() protoreflect.Message {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RelayCabinet.ProtoReflect.Descriptor instead.
func (*RelayCabinet) Descriptor() ([]byte, []int) {
return file_relayCabinetLayoutGraphics_proto_rawDescGZIP(), []int{1}
}
func (x *RelayCabinet) GetCommon() *CommonInfo {
if x != nil {
return x.Common
}
return nil
}
func (x *RelayCabinet) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
type Relay struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Common *CommonInfo `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"`
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` //编号
Model string `protobuf:"bytes,3,opt,name=model,proto3" json:"model,omitempty"` //型号
}
func (x *Relay) Reset() {
*x = Relay{}
if protoimpl.UnsafeEnabled {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Relay) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Relay) ProtoMessage() {}
func (x *Relay) ProtoReflect() protoreflect.Message {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Relay.ProtoReflect.Descriptor instead.
func (*Relay) Descriptor() ([]byte, []int) {
return file_relayCabinetLayoutGraphics_proto_rawDescGZIP(), []int{2}
}
func (x *Relay) GetCommon() *CommonInfo {
if x != nil {
return x.Common
}
return nil
}
func (x *Relay) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
func (x *Relay) GetModel() string {
if x != nil {
return x.Model
}
return ""
}
// 设备管理的继电器列表
type DeviceRelateRelay struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// int32 id = 1;//存储在列表中的id
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` //设备类型
Code string `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"` //设备编号
// repeated string refRelay = 4;//设备关联的继电器
Combinationtypes []*Combinationtype `protobuf:"bytes,5,rep,name=combinationtypes,proto3" json:"combinationtypes,omitempty"` //组合类型
}
func (x *DeviceRelateRelay) Reset() {
*x = DeviceRelateRelay{}
if protoimpl.UnsafeEnabled {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeviceRelateRelay) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeviceRelateRelay) ProtoMessage() {}
func (x *DeviceRelateRelay) ProtoReflect() protoreflect.Message {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeviceRelateRelay.ProtoReflect.Descriptor instead.
func (*DeviceRelateRelay) Descriptor() ([]byte, []int) {
return file_relayCabinetLayoutGraphics_proto_rawDescGZIP(), []int{3}
}
func (x *DeviceRelateRelay) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *DeviceRelateRelay) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
func (x *DeviceRelateRelay) GetCombinationtypes() []*Combinationtype {
if x != nil {
return x.Combinationtypes
}
return nil
}
type Combinationtype struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
RefRelays []string `protobuf:"bytes,2,rep,name=refRelays,proto3" json:"refRelays,omitempty"` //设备关联的继电器
}
func (x *Combinationtype) Reset() {
*x = Combinationtype{}
if protoimpl.UnsafeEnabled {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Combinationtype) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Combinationtype) ProtoMessage() {}
func (x *Combinationtype) ProtoReflect() protoreflect.Message {
mi := &file_relayCabinetLayoutGraphics_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Combinationtype.ProtoReflect.Descriptor instead.
func (*Combinationtype) Descriptor() ([]byte, []int) {
return file_relayCabinetLayoutGraphics_proto_rawDescGZIP(), []int{4}
}
func (x *Combinationtype) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
func (x *Combinationtype) GetRefRelays() []string {
if x != nil {
return x.RefRelays
}
return nil
}
var File_relayCabinetLayoutGraphics_proto protoreflect.FileDescriptor
var file_relayCabinetLayoutGraphics_proto_rawDesc = []byte{
0x0a, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x4c, 0x61,
0x79, 0x6f, 0x75, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x17, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74,
0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x1b, 0x73, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf2, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x6c,
0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63,
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x52, 0x06, 0x63, 0x61,
0x6e, 0x76, 0x61, 0x73, 0x12, 0x4b, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62,
0x69, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x65,
0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e,
0x65, 0x74, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74,
0x73, 0x12, 0x36, 0x0a, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74,
0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x61,
0x79, 0x52, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x12, 0x60, 0x0a, 0x15, 0x64, 0x65, 0x76,
0x69, 0x63, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4c, 0x69,
0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x44, 0x61,
0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x52,
0x65, 0x6c, 0x61, 0x79, 0x52, 0x15, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6c, 0x61,
0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x1b, 0x62,
0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x43, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
0x52, 0x1b, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x43, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x53, 0x0a,
0x0c, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x12, 0x2f, 0x0a,
0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x12, 0x12,
0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f,
0x64, 0x65, 0x22, 0x62, 0x0a, 0x05, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x2f, 0x0a, 0x06, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x72,
0x61, 0x70, 0x68, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04,
0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x22, 0x91, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63,
0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x63, 0x6f, 0x64, 0x65, 0x12, 0x54, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28,
0x2e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x47, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x0f, 0x43, 0x6f,
0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64,
0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x02,
0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x42,
0x21, 0x5a, 0x1f, 0x2e, 0x2f, 0x61, 0x74, 0x73, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x44, 0x61,
0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_relayCabinetLayoutGraphics_proto_rawDescOnce sync.Once
file_relayCabinetLayoutGraphics_proto_rawDescData = file_relayCabinetLayoutGraphics_proto_rawDesc
)
func file_relayCabinetLayoutGraphics_proto_rawDescGZIP() []byte {
file_relayCabinetLayoutGraphics_proto_rawDescOnce.Do(func() {
file_relayCabinetLayoutGraphics_proto_rawDescData = protoimpl.X.CompressGZIP(file_relayCabinetLayoutGraphics_proto_rawDescData)
})
return file_relayCabinetLayoutGraphics_proto_rawDescData
}
var file_relayCabinetLayoutGraphics_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_relayCabinetLayoutGraphics_proto_goTypes = []interface{}{
(*RelayCabinetGraphicStorage)(nil), // 0: relayCabinetGraphicData.RelayCabinetGraphicStorage
(*RelayCabinet)(nil), // 1: relayCabinetGraphicData.RelayCabinet
(*Relay)(nil), // 2: relayCabinetGraphicData.Relay
(*DeviceRelateRelay)(nil), // 3: relayCabinetGraphicData.DeviceRelateRelay
(*Combinationtype)(nil), // 4: relayCabinetGraphicData.Combinationtype
(*Canvas)(nil), // 5: graphicData.Canvas
(*CommonInfo)(nil), // 6: graphicData.CommonInfo
}
var file_relayCabinetLayoutGraphics_proto_depIdxs = []int32{
5, // 0: relayCabinetGraphicData.RelayCabinetGraphicStorage.canvas:type_name -> graphicData.Canvas
1, // 1: relayCabinetGraphicData.RelayCabinetGraphicStorage.relayCabinets:type_name -> relayCabinetGraphicData.RelayCabinet
2, // 2: relayCabinetGraphicData.RelayCabinetGraphicStorage.relays:type_name -> relayCabinetGraphicData.Relay
3, // 3: relayCabinetGraphicData.RelayCabinetGraphicStorage.deviceRelateRelayList:type_name -> relayCabinetGraphicData.DeviceRelateRelay
6, // 4: relayCabinetGraphicData.RelayCabinet.common:type_name -> graphicData.CommonInfo
6, // 5: relayCabinetGraphicData.Relay.common:type_name -> graphicData.CommonInfo
4, // 6: relayCabinetGraphicData.DeviceRelateRelay.combinationtypes:type_name -> relayCabinetGraphicData.Combinationtype
7, // [7:7] is the sub-list for method output_type
7, // [7:7] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_relayCabinetLayoutGraphics_proto_init() }
func file_relayCabinetLayoutGraphics_proto_init() {
if File_relayCabinetLayoutGraphics_proto != nil {
return
}
file_stationLayoutGraphics_proto_init()
if !protoimpl.UnsafeEnabled {
file_relayCabinetLayoutGraphics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RelayCabinetGraphicStorage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_relayCabinetLayoutGraphics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RelayCabinet); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_relayCabinetLayoutGraphics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Relay); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_relayCabinetLayoutGraphics_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeviceRelateRelay); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_relayCabinetLayoutGraphics_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Combinationtype); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_relayCabinetLayoutGraphics_proto_rawDesc,
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_relayCabinetLayoutGraphics_proto_goTypes,
DependencyIndexes: file_relayCabinetLayoutGraphics_proto_depIdxs,
MessageInfos: file_relayCabinetLayoutGraphics_proto_msgTypes,
}.Build()
File_relayCabinetLayoutGraphics_proto = out.File
file_relayCabinetLayoutGraphics_proto_rawDesc = nil
file_relayCabinetLayoutGraphics_proto_goTypes = nil
file_relayCabinetLayoutGraphics_proto_depIdxs = nil
}

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.31.0
// protoc v4.23.1
// source: stationLayoutGraphics.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.31.0
// protoc v4.23.1
// source: device_state.proto

View File

@ -3,6 +3,8 @@ package simulation
import (
"encoding/binary"
"encoding/hex"
"joylink.club/rtsssimulation/repository"
"joylink.club/rtsssimulation/repository/model/proto"
"math"
"time"
@ -88,24 +90,47 @@ func CreateSimulation(projectId int32, mapIds []int32) string {
panic(dto.ErrorDto{Code: dto.DataAlreadyExist, Message: "已有仿真在运行"})
}
if !e {
verifySimulation := memory.CreateSimulation(projectId, mapIds)
verifySimulation.SimulationId = simulationId
lineDataInfo := &dynamics.LineBaseInfo{}
for _, mapId := range mapIds {
b := buildLineBaseInfo(memory.QueryMapVerifyStructure(mapId))
lineDataInfo.CurveList = append(lineDataInfo.CurveList, b.CurveList...)
lineDataInfo.LinkList = append(lineDataInfo.LinkList, b.LinkList...)
lineDataInfo.SlopeList = append(lineDataInfo.SlopeList, b.SlopeList...)
verifySimulation, err := memory.CreateSimulation(projectId, mapIds)
if err != nil {
panic(fmt.Sprintf("创建仿真失败:%s", err.Error()))
}
verifySimulation.SimulationId = simulationId
//通知动力学
httpCode, _, err := dynamics.SendSimulationStartReq(lineDataInfo)
lineBaseInfo := buildLineBaseInfo(verifySimulation.Repo)
httpCode, _, err := dynamics.SendSimulationStartReq(lineBaseInfo)
if httpCode != http.StatusOK || err != nil {
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
}
simulationMap.Store(simulationId, verifySimulation)
dynamicsRun(verifySimulation)
}
return simulationId
//simulationId := createSimulationId(projectId)
//_, e := simulationMap.Load(simulationId)
//if !e && IsExistSimulation() {
// panic(dto.ErrorDto{Code: dto.DataAlreadyExist, Message: "已有仿真在运行"})
//}
//if !e {
// verifySimulation := memory.CreateSimulation(projectId, mapIds)
// verifySimulation.SimulationId = simulationId
// lineDataInfo := &dynamics.LineBaseInfo{}
// for _, mapId := range mapIds {
// b := buildLineBaseInfo(memory.QueryMapVerifyStructure(mapId))
// lineDataInfo.CurveList = append(lineDataInfo.CurveList, b.CurveList...)
// lineDataInfo.LinkList = append(lineDataInfo.LinkList, b.LinkList...)
// lineDataInfo.SlopeList = append(lineDataInfo.SlopeList, b.SlopeList...)
// }
// //通知动力学
// httpCode, _, err := dynamics.SendSimulationStartReq(lineDataInfo)
// if httpCode != http.StatusOK || err != nil {
// panic(dto.ErrorDto{Code: dto.DynamicsError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
// }
// simulationMap.Store(simulationId, verifySimulation)
// dynamicsRun(verifySimulation)
//}
//return simulationId
}
// 删除仿真对象
@ -161,55 +186,55 @@ func GetSimulationArr() []*memory.VerifySimulation {
}
func convert(info *dynamics.TrainInfo, sta *state.TrainState, simulation *memory.VerifySimulation) *state.TrainState {
var vs *memory.VerifyStructure
linkId := int32(info.Link)
for _, mapId := range simulation.MapIds {
vm := memory.QueryMapVerifyStructure(mapId)
if vm.LinkModelMap[linkId] == nil {
continue
}
vs = vm
break
}
zap.S().Debugf("原始消息:[%d-%d-%d]", info.Number, info.Link, info.LinkOffset)
id, port, offset, runDirection, pointTo, kilometer := memory.QueryDeviceByCalcLink(vs, linkId, int64(info.LinkOffset), info.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.TrainKilometer = kilometer
sta.RunDirection = runDirection
//判定车头方向
sta.HeadDirection = runDirection
if sta.VobcState != nil {
if sta.VobcState.DirectionForward {
sta.HeadDirection = runDirection
} else if sta.VobcState.DirectionBackward {
sta.HeadDirection = !runDirection
}
}
if info.Speed < 0 {
sta.RunDirection = !sta.RunDirection
}
// 赋值动力学信息
sta.DynamicState.Heartbeat = int32(info.LifeSignal)
sta.DynamicState.HeadLinkId = strconv.Itoa(int(info.Link))
sta.DynamicState.HeadLinkOffset = int64(info.LinkOffset)
sta.DynamicState.Slope = int32(info.Slope)
sta.DynamicState.Upslope = info.UpSlope
sta.DynamicState.RunningUp = info.Up
sta.DynamicState.RunningResistanceSum = float32(info.TotalResistance) / 1000
sta.DynamicState.AirResistance = float32(info.AirResistance) / 1000
sta.DynamicState.RampResistance = float32(info.SlopeResistance) / 1000
sta.DynamicState.CurveResistance = float32(info.CurveResistance) / 1000
sta.DynamicState.Speed = speedParse(info.Speed)
sta.DynamicState.HeadSensorSpeed1 = speedParse(info.HeadSpeed1)
sta.DynamicState.HeadSensorSpeed2 = speedParse(info.HeadSpeed2)
sta.DynamicState.TailSensorSpeed1 = speedParse(info.TailSpeed1)
sta.DynamicState.TailSensorSpeed2 = speedParse(info.TailSpeed2)
sta.DynamicState.HeadRadarSpeed = speedParse(info.HeadRadarSpeed)
sta.DynamicState.TailRadarSpeed = speedParse(info.TailRadarSpeed)
//var vs *memory.VerifyStructure
//linkId := int32(info.Link)
//for _, mapId := range simulation.MapIds {
// vm := memory.QueryMapVerifyStructure(mapId)
// if vm.LinkModelMap[linkId] == nil {
// continue
// }
// vs = vm
// break
//}
//zap.S().Debugf("原始消息:[%d-%d-%d]", info.Number, info.Link, info.LinkOffset)
//id, port, offset, runDirection, pointTo, kilometer := memory.QueryDeviceByCalcLink(vs, linkId, int64(info.LinkOffset), info.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.TrainKilometer = kilometer
//sta.RunDirection = runDirection
////判定车头方向
//sta.HeadDirection = runDirection
//if sta.VobcState != nil {
// if sta.VobcState.DirectionForward {
// sta.HeadDirection = runDirection
// } else if sta.VobcState.DirectionBackward {
// sta.HeadDirection = !runDirection
// }
//}
//if info.Speed < 0 {
// sta.RunDirection = !sta.RunDirection
//}
//// 赋值动力学信息
//sta.DynamicState.Heartbeat = int32(info.LifeSignal)
//sta.DynamicState.HeadLinkId = strconv.Itoa(int(info.Link))
//sta.DynamicState.HeadLinkOffset = int64(info.LinkOffset)
//sta.DynamicState.Slope = int32(info.Slope)
//sta.DynamicState.Upslope = info.UpSlope
//sta.DynamicState.RunningUp = info.Up
//sta.DynamicState.RunningResistanceSum = float32(info.TotalResistance) / 1000
//sta.DynamicState.AirResistance = float32(info.AirResistance) / 1000
//sta.DynamicState.RampResistance = float32(info.SlopeResistance) / 1000
//sta.DynamicState.CurveResistance = float32(info.CurveResistance) / 1000
//sta.DynamicState.Speed = speedParse(info.Speed)
//sta.DynamicState.HeadSensorSpeed1 = speedParse(info.HeadSpeed1)
//sta.DynamicState.HeadSensorSpeed2 = speedParse(info.HeadSpeed2)
//sta.DynamicState.TailSensorSpeed1 = speedParse(info.TailSpeed1)
//sta.DynamicState.TailSensorSpeed2 = speedParse(info.TailSpeed2)
//sta.DynamicState.HeadRadarSpeed = speedParse(info.HeadRadarSpeed)
//sta.DynamicState.TailRadarSpeed = speedParse(info.TailRadarSpeed)
return sta
}
@ -233,62 +258,127 @@ func dynamicsRun(verifySimulation *memory.VerifySimulation) {
})
}
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
var aPort string
if link.ARelatedSwitchRef != nil && link.ARelatedSwitchRef.SwitchDevice != nil {
aTurnoutId, _ = strconv.Atoi(link.ARelatedSwitchRef.SwitchDevice.GetIndex())
aPort = link.ARelatedSwitchRef.Port.Name()
func buildLineBaseInfo(repo *repository.Repository) *dynamics.LineBaseInfo {
info := &dynamics.LineBaseInfo{}
for _, model := range repo.LinkList() {
id, _ := strconv.Atoi(model.Id())
link := &dynamics.Link{
ID: int32(id),
Len: int32(model.Length()),
}
var bTurnoutId int
var bPort string
if link.BRelatedSwitchRef != nil && link.BRelatedSwitchRef.SwitchDevice != nil {
bTurnoutId, _ = strconv.Atoi(link.BRelatedSwitchRef.SwitchDevice.GetIndex())
bPort = link.BRelatedSwitchRef.Port.Name()
info.LinkList = append(info.LinkList, link)
if model.ARelation() != nil {
turnoutId, _ := strconv.Atoi(model.ARelation().Device().Id())
link.ARelTurnoutId = int32(turnoutId)
switch model.ARelation().Port() {
case proto.Port_A:
link.ARelTurnoutPoint = "A"
case proto.Port_B:
link.ARelTurnoutPoint = "B"
case proto.Port_C:
link.ARelTurnoutPoint = "C"
}
}
if model.BRelation() != nil {
turnoutId, _ := strconv.Atoi(model.BRelation().Device().Id())
link.BRelTurnoutId = int32(turnoutId)
switch model.BRelation().Port() {
case proto.Port_A:
link.BRelTurnoutPoint = "A"
case proto.Port_B:
link.BRelTurnoutPoint = "B"
case proto.Port_C:
link.BRelTurnoutPoint = "C"
}
}
links = append(links, &dynamics.Link{
ID: int32(id),
Len: link.Length,
ARelTurnoutId: int32(aTurnoutId),
ARelTurnoutPoint: aPort,
BRelTurnoutId: int32(bTurnoutId),
BRelTurnoutPoint: bPort,
})
}
for _, slope := range vs.SlopeModelMap {
id, _ := strconv.Atoi(slope.Index)
slopes = append(slopes, &dynamics.Slope{
for _, model := range repo.SlopeList() {
id, _ := strconv.Atoi(model.Id())
slope := &dynamics.Slope{
ID: int32(id),
StartLinkId: slope.StartLinkIndex,
StartLinkOffset: slope.StartLinkOffset,
EndLinkId: slope.EndLinkIndex,
EndLinkOffset: slope.EndLinkOffset,
DegreeTrig: slope.DegreeTrig,
})
StartLinkOffset: int32(model.StartLinkPosition().Offset()),
EndLinkOffset: int32(model.EndLinkPosition().Offset()),
DegreeTrig: model.Degree(),
}
info.SlopeList = append(info.SlopeList, slope)
startLinkId, _ := strconv.Atoi(model.StartLinkPosition().Link().Id())
slope.StartLinkId = int32(startLinkId)
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
slope.EndLinkId = int32(endLinkId)
}
for _, curve := range vs.CurveModelMap {
id, _ := strconv.Atoi(curve.Index)
curves = append(curves, &dynamics.Curve{
for _, model := range repo.SectionalCurvatureList() {
id, _ := strconv.Atoi(model.Id())
curve := &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,
StartLinkOffset: int32(model.StartLinkPosition().Offset()),
EndLinkOffset: int32(model.EndLinkPosition().Offset()),
Curvature: model.Radius(),
}
info.CurveList = append(info.CurveList, curve)
startLinkId, _ := strconv.Atoi(model.StartLinkPosition().Link().Id())
curve.StartLinkId = int32(startLinkId)
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
curve.EndLinkId = int32(endLinkId)
}
return info
}
//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
// var aPort string
// if link.ARelatedSwitchRef != nil && link.ARelatedSwitchRef.SwitchDevice != nil {
// aTurnoutId, _ = strconv.Atoi(link.ARelatedSwitchRef.SwitchDevice.GetIndex())
// aPort = link.ARelatedSwitchRef.Port.Name()
// }
// var bTurnoutId int
// var bPort string
// if link.BRelatedSwitchRef != nil && link.BRelatedSwitchRef.SwitchDevice != nil {
// bTurnoutId, _ = strconv.Atoi(link.BRelatedSwitchRef.SwitchDevice.GetIndex())
// bPort = link.BRelatedSwitchRef.Port.Name()
// }
// links = append(links, &dynamics.Link{
// ID: int32(id),
// Len: link.Length,
// ARelTurnoutId: int32(aTurnoutId),
// ARelTurnoutPoint: aPort,
// BRelTurnoutId: int32(bTurnoutId),
// BRelTurnoutPoint: bPort,
// })
// }
// 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,
// }
//}
// 解析VOBC列车信息
func decoderVobcTrainState(buf []byte) *state.TrainVobcState {
trainVobcInfo := &state.TrainVobcState{}

View File

@ -43,12 +43,12 @@ type WaysideMemory struct {
rwLock *sync.RWMutex
}
// 初始化轨旁仿真内存模型
func (memory *WaysideMemory) Create() *WaysideMemory {
memory.Status = new(VerifyStatus)
memory.ChangeStatus = &ChangeVerifyStatus{}
memory.rwLock = new(sync.RWMutex)
return memory
func NewWaysideMemory() *WaysideMemory {
return &WaysideMemory{
Status: &VerifyStatus{},
ChangeStatus: &ChangeVerifyStatus{},
rwLock: &sync.RWMutex{},
}
}
// 状态读保护操作

View File

@ -3,6 +3,7 @@ package memory
import (
"container/list"
"fmt"
"joylink.club/rtsssimulation/repository"
"math"
"sort"
"strconv"
@ -15,14 +16,16 @@ 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
var graphicSourceDataMap sync.Map
var (
graphicStorageMap sync.Map
//// 仿真存储集合 ID
//graphicDataMap sync.Map
//graphicSourceDataMap sync.Map
)
// VerifyStructure 轨旁仿真模型结构
type VerifyStructure struct {
@ -112,44 +115,58 @@ func PublishMapVerifyStructure(graphic *model.PublishedGi) *VerifyStructure {
CurvatureKiloMarkerMap: make(map[string]*graphicData.CurvatureKiloMarker),
}
graphicStorage := &graphicData.RtssGraphicStorage{}
proto.Unmarshal(graphic.Proto, graphicStorage)
err := proto.Unmarshal(graphic.Proto, graphicStorage)
if err != nil {
panic(fmt.Sprintf("proto数据反序列化失败%s", err))
}
graphicStorageMap.Store(graphic.ID, graphicStorage)
// 初始化地图结构
initGraphicStructure(graphicStorage, verifyStructure, graphicInfoMap)
// 构建设备间的关联关系(8.8 注释掉构建逻辑)
buildDeviceRef(graphicInfoMap, verifyStructure)
graphicDataMap.Store(graphic.ID, verifyStructure)
// 地图原始数据
graphicSourceDataMap.Store(graphic.ID, graphicInfoMap)
//// 构建设备间的关联关系(8.8 注释掉构建逻辑)
//buildDeviceRef(graphicInfoMap, verifyStructure)
//graphicDataMap.Store(graphic.ID, verifyStructure)
//// 地图原始数据
//graphicSourceDataMap.Store(graphic.ID, graphicInfoMap)
return verifyStructure
}
// 移除内存中的地图信息
func DeleteMapVerifyStructure(mapId int32) {
graphicDataMap.Delete(mapId)
graphicSourceDataMap.Delete(mapId)
//graphicDataMap.Delete(mapId)
//graphicSourceDataMap.Delete(mapId)
}
func QueryGraphicStorage(mapId int32) *graphicData.RtssGraphicStorage {
value, ok := graphicStorageMap.Load(mapId)
if ok {
return value.(*graphicData.RtssGraphicStorage)
}
return nil
}
// 获取内存中的地图信息
func QueryMapVerifyStructure(mapId int32) *VerifyStructure {
d, ok := graphicDataMap.Load(mapId)
if ok {
return d.(*VerifyStructure)
}
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))
}
//d, ok := graphicDataMap.Load(mapId)
//if ok {
// return d.(*VerifyStructure)
//}
//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))
//}
return nil
}
// 获取内存中地图原始信息
func QueryMapSourceDataStructure(mapId int32) *GraphicInfoMapStructure {
d, ok := graphicSourceDataMap.Load(mapId)
if ok {
return d.(*GraphicInfoMapStructure)
}
panic(fmt.Sprintf("地图【id:%d】数据不存在", mapId))
//d, ok := graphicSourceDataMap.Load(mapId)
//if ok {
// return d.(*GraphicInfoMapStructure)
//}
//panic(fmt.Sprintf("地图【id:%d】数据不存在", mapId))
return nil
}
// 根据区段道岔偏移量返回linkID和link相对偏移量
@ -276,117 +293,241 @@ Outter:
// 根据linkID和link相对偏移量返回区段道岔偏移量
// 设备ID、端口、偏移量、上下行、AB走向
func QueryDeviceByCalcLink(vm *VerifyStructure, id int32, offset int64, up, defaultRunDirection bool) (string, string, int64, bool, bool, int64) {
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 port string
var op int64
var trainOffset int64
var trainKilometer int64
var tendTo bool
if devicePosition.deviceType == 2 {
sid = devicePosition.index
op = int64(devicePosition.position.Offset)
trainKilometer = devicePosition.kilometer.Kilometer
} else {
sid = calcPosition.index
op = int64(calcPosition.position.Offset)
trainKilometer = calcPosition.kilometer.Kilometer
}
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 { // 起始点
port, trainOffset, tendTo = linkModel.ARelatedSwitchRef.Port.Name(), offset-op, !up
} else if linkModel.BRelatedSwitchRef.SwitchDevice != nil && linkModel.BRelatedSwitchRef.SwitchDevice.GetIndex() == sid { // 结束点
port, trainOffset, tendTo = linkModel.BRelatedSwitchRef.Port.Name(), op-offset, up
} else {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【index:%s】", devicePosition.index)})
}
trainKilometer = concertTrainKilometer(trainKilometer, trainOffset, tendTo)
// return sid, linkModel.ARelatedSwitchRef.Port.Name(), offset - op, runDirection, !up
// return sid, linkModel.BRelatedSwitchRef.Port.Name(), op - offset, runDirection, up
return sid, port, trainOffset, runDirection, tendTo, trainKilometer
} else {
sectionModel, ok := linkOffsetQuerySection(vm, devicePosition, calcPosition)
if ok {
isEnd := (calcPosition == nil) && (offset == int64(linkModel.Length)) // 是否已经走到尽头
pointA := sectionModel.PortAxlePoints[face.A.Name()]
var trainOffset int64
var trainKilometer int64
var tendTo bool
var bk *graphicData.KilometerSystem
if calcPosition != nil {
bk = calcPosition.kilometer
}
if devicePosition.index == pointA.GetIndex() {
trainOffset = offset - int64(devicePosition.position.Offset)
trainKilometer = devicePosition.kilometer.Kilometer
tendTo = convertPointTo(devicePosition.kilometer, bk, runDirection)
} else if calcPosition != nil {
trainOffset = int64(calcPosition.position.Offset) - offset
trainKilometer = bk.Kilometer
tendTo = convertPointTo(bk, devicePosition.kilometer, runDirection)
} else {
for _, v := range calcPositionArr {
if v.deviceType == 1 && v.index == pointA.GetIndex() { // 计轴
trainKilometer = v.kilometer.Kilometer
if isEnd {
trainOffset = offset - int64(v.position.Offset)
tendTo = convertPointTo(v.kilometer, nil, runDirection)
} else {
trainOffset = int64(v.position.Offset) - offset
tendTo = convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
}
break
}
}
if trainKilometer == 0 {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("区段【%s】A端计轴缺失", sectionModel.GraphicId)})
}
}
trainKilometer = concertTrainKilometer(trainKilometer, trainOffset, tendTo)
// return sectionModel.Index, "", offset - int64(devicePosition.position.Offset), runDirection, convertPointTo(devicePosition.kilometer, bk, runDirection)
// return sectionModel.Index, "", int64(calcPosition.position.Offset) - offset, runDirection, convertPointTo(bk, devicePosition.kilometer, runDirection)
// return sectionModel.Index, "", offset - int64(v.position.Offset), runDirection, convertPointTo(v.kilometer, nil, runDirection)
// return sectionModel.Index, "", int64(v.position.Offset) - offset, runDirection, convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
return sectionModel.Index, "", trainOffset, runDirection, tendTo, trainKilometer
} else {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到区段【index:%s-index:%s】", devicePosition.index, calcPosition.index)})
}
}
func QueryDeviceByCalcLink(repo *repository.Repository, id int32, offset int64, up, defaultRunDirection bool) (string, string, int64, bool, bool, int64) {
//link := repo.FindLink(strconv.Itoa(int(id)))
//if link == nil {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到link【%d】", id)})
//}
//if offset > link.Length() {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("偏移超出link范围【%d】", id)})
//}
//for _, model := range link.Devices() {
// physicalSection, ok := model.(*repository.PhysicalSection)
// if ok {
// if number.IsBetween(offset, physicalSection.StartLinkPosition().Offset(), physicalSection.EndLinkPosition().Offset()) {
//
// }
// }
//
//}
//
//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 port string
// var op int64
// var trainOffset int64
// var trainKilometer int64
// var tendTo bool
// if devicePosition.deviceType == 2 {
// sid = devicePosition.index
// op = int64(devicePosition.position.Offset)
// trainKilometer = devicePosition.kilometer.Kilometer
// } else {
// sid = calcPosition.index
// op = int64(calcPosition.position.Offset)
// trainKilometer = calcPosition.kilometer.Kilometer
// }
// 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 { // 起始点
// port, trainOffset, tendTo = linkModel.ARelatedSwitchRef.Port.Name(), offset-op, !up
// } else if linkModel.BRelatedSwitchRef.SwitchDevice != nil && linkModel.BRelatedSwitchRef.SwitchDevice.GetIndex() == sid { // 结束点
// port, trainOffset, tendTo = linkModel.BRelatedSwitchRef.Port.Name(), op-offset, up
// } else {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【index:%s】", devicePosition.index)})
// }
// trainKilometer = concertTrainKilometer(trainKilometer, trainOffset, tendTo)
// // return sid, linkModel.ARelatedSwitchRef.Port.Name(), offset - op, runDirection, !up
// // return sid, linkModel.BRelatedSwitchRef.Port.Name(), op - offset, runDirection, up
// return sid, port, trainOffset, runDirection, tendTo, trainKilometer
//} else {
// sectionModel, ok := linkOffsetQuerySection(vm, devicePosition, calcPosition)
// if ok {
// isEnd := (calcPosition == nil) && (offset == int64(linkModel.Length)) // 是否已经走到尽头
// pointA := sectionModel.PortAxlePoints[face.A.Name()]
// var trainOffset int64
// var trainKilometer int64
// var tendTo bool
// var bk *graphicData.KilometerSystem
// if calcPosition != nil {
// bk = calcPosition.kilometer
// }
// if devicePosition.index == pointA.GetIndex() {
// trainOffset = offset - int64(devicePosition.position.Offset)
// trainKilometer = devicePosition.kilometer.Kilometer
// tendTo = convertPointTo(devicePosition.kilometer, bk, runDirection)
// } else if calcPosition != nil {
// trainOffset = int64(calcPosition.position.Offset) - offset
// trainKilometer = bk.Kilometer
// tendTo = convertPointTo(bk, devicePosition.kilometer, runDirection)
// } else {
// for _, v := range calcPositionArr {
// if v.deviceType == 1 && v.index == pointA.GetIndex() { // 计轴
// trainKilometer = v.kilometer.Kilometer
// if isEnd {
// trainOffset = offset - int64(v.position.Offset)
// tendTo = convertPointTo(v.kilometer, nil, runDirection)
// } else {
// trainOffset = int64(v.position.Offset) - offset
// tendTo = convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
// }
// break
// }
// }
// if trainKilometer == 0 {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("区段【%s】A端计轴缺失", sectionModel.GraphicId)})
// }
// }
// trainKilometer = concertTrainKilometer(trainKilometer, trainOffset, tendTo)
// // return sectionModel.Index, "", offset - int64(devicePosition.position.Offset), runDirection, convertPointTo(devicePosition.kilometer, bk, runDirection)
// // return sectionModel.Index, "", int64(calcPosition.position.Offset) - offset, runDirection, convertPointTo(bk, devicePosition.kilometer, runDirection)
// // return sectionModel.Index, "", offset - int64(v.position.Offset), runDirection, convertPointTo(v.kilometer, nil, runDirection)
// // return sectionModel.Index, "", int64(v.position.Offset) - offset, runDirection, convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
// return sectionModel.Index, "", trainOffset, runDirection, tendTo, trainKilometer
// } else {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到区段【index:%s-index:%s】", devicePosition.index, calcPosition.index)})
// }
//}
return "", "", 0, false, false, 0
}
//// 根据linkID和link相对偏移量返回区段道岔偏移量
//// 设备ID、端口、偏移量、上下行、AB走向
//func QueryDeviceByCalcLink(vm *VerifyStructure, id int32, offset int64, up, defaultRunDirection bool) (string, string, int64, bool, bool, int64) {
// 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 port string
// var op int64
// var trainOffset int64
// var trainKilometer int64
// var tendTo bool
// if devicePosition.deviceType == 2 {
// sid = devicePosition.index
// op = int64(devicePosition.position.Offset)
// trainKilometer = devicePosition.kilometer.Kilometer
// } else {
// sid = calcPosition.index
// op = int64(calcPosition.position.Offset)
// trainKilometer = calcPosition.kilometer.Kilometer
// }
// 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 { // 起始点
// port, trainOffset, tendTo = linkModel.ARelatedSwitchRef.Port.Name(), offset-op, !up
// } else if linkModel.BRelatedSwitchRef.SwitchDevice != nil && linkModel.BRelatedSwitchRef.SwitchDevice.GetIndex() == sid { // 结束点
// port, trainOffset, tendTo = linkModel.BRelatedSwitchRef.Port.Name(), op-offset, up
// } else {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【index:%s】", devicePosition.index)})
// }
// trainKilometer = concertTrainKilometer(trainKilometer, trainOffset, tendTo)
// // return sid, linkModel.ARelatedSwitchRef.Port.Name(), offset - op, runDirection, !up
// // return sid, linkModel.BRelatedSwitchRef.Port.Name(), op - offset, runDirection, up
// return sid, port, trainOffset, runDirection, tendTo, trainKilometer
// } else {
// sectionModel, ok := linkOffsetQuerySection(vm, devicePosition, calcPosition)
// if ok {
// isEnd := (calcPosition == nil) && (offset == int64(linkModel.Length)) // 是否已经走到尽头
// pointA := sectionModel.PortAxlePoints[face.A.Name()]
// var trainOffset int64
// var trainKilometer int64
// var tendTo bool
// var bk *graphicData.KilometerSystem
// if calcPosition != nil {
// bk = calcPosition.kilometer
// }
// if devicePosition.index == pointA.GetIndex() {
// trainOffset = offset - int64(devicePosition.position.Offset)
// trainKilometer = devicePosition.kilometer.Kilometer
// tendTo = convertPointTo(devicePosition.kilometer, bk, runDirection)
// } else if calcPosition != nil {
// trainOffset = int64(calcPosition.position.Offset) - offset
// trainKilometer = bk.Kilometer
// tendTo = convertPointTo(bk, devicePosition.kilometer, runDirection)
// } else {
// for _, v := range calcPositionArr {
// if v.deviceType == 1 && v.index == pointA.GetIndex() { // 计轴
// trainKilometer = v.kilometer.Kilometer
// if isEnd {
// trainOffset = offset - int64(v.position.Offset)
// tendTo = convertPointTo(v.kilometer, nil, runDirection)
// } else {
// trainOffset = int64(v.position.Offset) - offset
// tendTo = convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
// }
// break
// }
// }
// if trainKilometer == 0 {
// panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("区段【%s】A端计轴缺失", sectionModel.GraphicId)})
// }
// }
// trainKilometer = concertTrainKilometer(trainKilometer, trainOffset, tendTo)
// // return sectionModel.Index, "", offset - int64(devicePosition.position.Offset), runDirection, convertPointTo(devicePosition.kilometer, bk, runDirection)
// // return sectionModel.Index, "", int64(calcPosition.position.Offset) - offset, runDirection, convertPointTo(bk, devicePosition.kilometer, runDirection)
// // return sectionModel.Index, "", offset - int64(v.position.Offset), runDirection, convertPointTo(v.kilometer, nil, runDirection)
// // return sectionModel.Index, "", int64(v.position.Offset) - offset, runDirection, convertPointTo(v.kilometer, devicePosition.kilometer, runDirection)
// return sectionModel.Index, "", trainOffset, runDirection, tendTo, trainKilometer
// } 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 {

View File

@ -1,7 +1,15 @@
package memory
import (
"fmt"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
"joylink.club/rtsssimulation/repository"
"joylink.club/rtsssimulation/repository/model/proto"
"joylink.club/rtsssimulation/simulation"
"sort"
"strconv"
"strings"
)
// 轨旁仿真定义
@ -14,22 +22,60 @@ type VerifySimulation struct {
SimulationId string
//仿真内存数据
Memory *WaysideMemory
//模型仓库
Repo *repository.Repository
//Rtss仿真世界的id
WorldId int
}
// 创建仿真对象
func CreateSimulation(projectId int32, mapIds []int32) *VerifySimulation {
m := &WaysideMemory{}
func CreateSimulation(projectId int32, mapIds []int32) (*VerifySimulation, error) {
//构建Repository
sort.Slice(mapIds, func(i, j int) bool {
return mapIds[i] < mapIds[j]
})
var mapIdStrSlice []string
for _, id := range mapIds {
mapIdStrSlice = append(mapIdStrSlice, strconv.Itoa(int(id)))
}
repoId := strings.Join(mapIdStrSlice, "|")
repoVersion := "0.1"
repo := repository.FindRepository(repoId, repoVersion)
if repo == nil {
var storages []*graphicData.RtssGraphicStorage
for _, mapId := range mapIds {
storages = append(storages, QueryGraphicStorage(mapId))
}
protoRepo := buildProtoRepository(storages)
newRepo, err := repository.BuildRepository(protoRepo)
repo = newRepo
if err != nil {
return nil, err
}
}
//创建仿真
worldId := simulation.CreateSimulation(repo, &simulation.WorldConfig{})
verifySimulation := &VerifySimulation{
MapIds: mapIds,
ProjectId: projectId,
Memory: m.Create(),
Memory: NewWaysideMemory(),
Repo: repo,
WorldId: worldId,
}
s := verifySimulation.Memory.Status
// 初始化构地图设备状态
for _, mapId := range mapIds {
InitFromMap(s, QueryMapVerifyStructure(mapId))
}
return verifySimulation
return verifySimulation, nil
//m := &WaysideMemory{}
//verifySimulation := &VerifySimulation{
// MapIds: mapIds,
// ProjectId: projectId,
// Memory: m.Create(),
//}
//s := verifySimulation.Memory.Status
//// 初始化构地图设备状态
//for _, mapId := range mapIds {
// InitFromMap(s, QueryMapVerifyStructure(mapId))
//}
//return verifySimulation
}
// 获取全量状态
@ -55,3 +101,240 @@ func (s *VerifySimulation) GetChangeState() *state.PushedDevicesStatus {
},
}
}
func buildProtoRepository(storages []*graphicData.RtssGraphicStorage) *proto.Repository {
repo := &proto.Repository{}
for _, storage := range storages {
fillProtoRepository(repo, storage)
}
return repo
}
func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphicStorage) {
axleCountingMap := make(map[string]*graphicData.AxleCounting)
for _, data := range storage.AxleCountings {
if data.KilometerSystem == nil {
println(fmt.Sprintf("计轴[%s]缺少公里标", data.Common.Id))
continue
}
axleCountingMap[data.Common.Id] = data
cpType := proto.CheckPointType_AxleCounter
if data.Invent {
cpType = proto.CheckPointType_Boundary
}
cp := &proto.CheckPoint{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
Type: cpType,
DevicePorts: convertDevicePorts(data.AxleCountingRef),
}
repo.CheckPoints = append(repo.CheckPoints, cp)
}
for _, data := range storage.Section {
var turnoutIds []string
if data.SectionType == graphicData.Section_TurnoutPhysical {
turnoutIds = findTurnoutIds(axleCountingMap, data.AxleCountings)
}
physicalSection := &proto.PhysicalSection{
Id: data.Common.Id,
ADevicePort: convertDevicePort(data.PaRef),
BDevicePort: convertDevicePort(data.PbRef),
TurnoutIds: turnoutIds,
}
repo.PhysicalSections = append(repo.PhysicalSections, physicalSection)
}
for _, data := range storage.Turnouts {
var km *proto.Kilometer
for _, ks := range data.KilometerSystem {
if ks.Kilometer != 0 {
km = convertKm(ks)
break
}
}
for _, kc := range buildKmConverts(data.KilometerSystem) {
repo.KilometerConverts = append(repo.KilometerConverts, kc)
}
turnout := &proto.Turnout{
Id: data.Common.Id,
Km: km,
ADevicePort: convertDevicePort(data.PaRef),
BDevicePort: convertDevicePort(data.PbRef),
CDevicePort: convertDevicePort(data.PcRef),
}
repo.Turnouts = append(repo.Turnouts, turnout)
}
for _, data := range storage.Signals {
var sectionId string
var turnoutPort *proto.DevicePort
switch data.RefDev.DeviceType {
case graphicData.RelatedRef_Section:
sectionId = data.RefDev.Id
case graphicData.RelatedRef_Turnout:
turnoutPort = convertDevicePort(data.RefDev)
}
signal := &proto.Signal{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
SectionId: sectionId,
TurnoutPort: turnoutPort,
}
repo.Signals = append(repo.Signals, signal)
}
for _, data := range storage.Transponders {
var sectionId string
var turnoutPort *proto.DevicePort
switch data.TransponderRef.DeviceType {
case graphicData.RelatedRef_Section:
sectionId = data.TransponderRef.Id
case graphicData.RelatedRef_Turnout:
turnoutPort = convertDevicePort(data.TransponderRef)
}
responder := &proto.Transponder{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
SectionId: sectionId,
TurnoutPort: turnoutPort,
}
repo.Transponders = append(repo.Transponders, responder)
}
slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker)
for _, data := range storage.SlopeKiloMarker {
slopeKsMap[data.Common.Id] = data
for _, kc := range buildKmConverts(data.KilometerSystem) {
repo.KilometerConverts = append(repo.KilometerConverts, kc)
}
}
curveKsMap := make(map[string]*graphicData.CurvatureKiloMarker)
for _, data := range storage.CurvatureKiloMarker {
curveKsMap[data.Common.Id] = data
for _, kc := range buildKmConverts(data.KilometerSystem) {
repo.KilometerConverts = append(repo.KilometerConverts, kc)
}
}
for _, data := range storage.Slopes {
var kms []*proto.Kilometer
for _, id := range data.RefDeviceId {
kms = append(kms, convertKm(slopeKsMap[id].KilometerSystem[0]))
}
slope := &proto.Slope{
Id: data.Common.Id,
Kms: kms,
Degree: data.SlopeNumber,
}
repo.Slopes = append(repo.Slopes, slope)
}
for _, data := range storage.Curvatures {
var kms []*proto.Kilometer
for _, id := range data.RefDeviceId {
kms = append(kms, convertKm(curveKsMap[id].KilometerSystem[0]))
}
slope := &proto.SectionalCurvature{
Id: data.Common.Id,
Kms: kms,
Radius: data.CurvatureNumber,
}
repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope)
}
}
func convertKm(ks *graphicData.KilometerSystem) *proto.Kilometer {
var dir proto.Direction
switch ks.Direction {
case graphicData.Direction_LEFT:
dir = proto.Direction_LEFT
case graphicData.Direction_RIGHT:
dir = proto.Direction_RIGHT
}
return &proto.Kilometer{
Value: ks.Kilometer,
CoordinateSystem: ks.CoordinateSystem,
Direction: dir,
}
}
func convertDevicePort(ref *graphicData.RelatedRef) *proto.DevicePort {
if ref == nil {
return nil
}
var deviceType proto.DeviceType
var port proto.Port
switch ref.DevicePort {
case graphicData.RelatedRef_A:
port = proto.Port_A
case graphicData.RelatedRef_B:
port = proto.Port_B
case graphicData.RelatedRef_C:
port = proto.Port_C
}
switch ref.DeviceType {
case graphicData.RelatedRef_Section:
deviceType = proto.DeviceType_DeviceType_PhysicalSection
case graphicData.RelatedRef_Turnout:
deviceType = proto.DeviceType_DeviceType_Turnout
default:
panic(fmt.Sprintf("异常的设备类型-%s", ref.DeviceType))
}
return &proto.DevicePort{
DeviceId: ref.Id,
DeviceType: deviceType,
Port: port,
}
}
func convertDevicePorts(refList []*graphicData.RelatedRef) []*proto.DevicePort {
var dps []*proto.DevicePort
for _, ref := range refList {
dps = append(dps, convertDevicePort(ref))
}
return dps
}
func findTurnoutIds(axleCountingMap map[string]*graphicData.AxleCounting, axleIds []string) []string {
if len(axleIds) <= 2 {
return nil
}
turnoutMap := make(map[string]bool)
for _, axleId := range axleIds {
axle := axleCountingMap[axleId]
relTurnoutCount := 0
var turnoutId string
for _, ref := range axle.AxleCountingRef {
if ref.DeviceType == graphicData.RelatedRef_Turnout {
relTurnoutCount++
turnoutId = ref.Id
}
}
if relTurnoutCount == 1 {
turnoutMap[turnoutId] = true
}
}
var turnoutIds []string
for id, _ := range turnoutMap {
turnoutIds = append(turnoutIds, id)
}
return turnoutIds
}
func buildKmConverts(ksList []*graphicData.KilometerSystem) []*proto.KilometerConvert {
var kmConverts []*proto.KilometerConvert
for i, ks := range ksList {
if ks.Kilometer == 0 {
continue
}
for j := i + 1; j < len(ksList); j++ {
if ks.Kilometer == 0 {
continue
}
kmConverts = append(kmConverts, buildKmConvert(ks, ksList[j]))
}
}
return kmConverts
}
func buildKmConvert(ks1 *graphicData.KilometerSystem, ks2 *graphicData.KilometerSystem) *proto.KilometerConvert {
return &proto.KilometerConvert{
KmA: convertKm(ks1),
KmB: convertKm(ks2),
SameTrend: false,
}
}

@ -1 +1 @@
Subproject commit d1f19ee2d5ee74bfdab38887d2c7137d67dd7574
Subproject commit 473f7da13f142c51c774149002e5b8752b0e6825

2
go.mod
View File

@ -80,7 +80,7 @@ require (
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
google.golang.org/protobuf v1.30.0
google.golang.org/protobuf v1.31.0
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

3
go.sum
View File

@ -682,8 +682,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -134,6 +134,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU=
github.com/ebitengine/purego v0.1.0/go.mod h1:Eh8I3yvknDYZeCuXH9kRNaPuHEwvXDCk378o9xszmHg=
github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI=
github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
@ -141,6 +142,7 @@ github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
github.com/go-faster/errors v0.6.1/go.mod h1:5MGV2/2T9yvlrbhe9pD9LO5Z/2zCSq2T8j+Jpi2LAyY=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
@ -152,6 +154,8 @@ github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkj
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/hajimehoshi/ebiten/v2 v2.4.13/go.mod h1:BZcqCU4XHmScUi+lsKexocWcf4offMFwfp8dVGIB/G4=
github.com/hajimehoshi/file2byteslice v1.0.0/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
@ -168,6 +172,7 @@ github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
github.com/jezek/xgb v1.0.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
@ -183,12 +188,16 @@ github.com/sagikazarmark/crypt v0.10.0/go.mod h1:gwTNHQVoOS3xp9Xvz5LLR+1AauC5M68
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/yohamta/donburi v1.3.8/go.mod h1:5QkyraUjkzbMVTD2b8jaPFy1Uwjm/zdFN1c1lZGaezg=
go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k=
go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4=
go.etcd.io/etcd/client/v2 v2.305.7/go.mod h1:GQGT5Z3TBuAQGvgPfhR7VPySu/SudxmEkRq9BgzFU6s=
go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c=
golang.org/x/mobile v0.0.0-20221012134814-c746ac228303/go.mod h1:M32cGdzp91A8Ex9qQtyZinr19EYxzkFqDjW2oyHzTDQ=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

BIN
protobuf/file.bin Normal file

Binary file not shown.

View File

@ -24,8 +24,32 @@ func TestBuildRepository(t *testing.T) {
}
repo := &proto2.Repository{}
//todo 数据中id为379的区段B端无计轴临时在代码里修改后续删除
storage.AxleCountings = append(storage.AxleCountings, &graphicData.AxleCounting{
Common: &graphicData.CommonInfo{
Id: "10000",
},
KilometerSystem: &graphicData.KilometerSystem{
Kilometer: 13403549,
CoordinateSystem: "MAIN_LINE",
Direction: graphicData.Direction_RIGHT,
},
AxleCountingRef: []*graphicData.RelatedRef{{
DeviceType: graphicData.RelatedRef_Section,
Id: "379",
DevicePort: graphicData.RelatedRef_B,
}},
Index: 0,
Invent: false,
Type: 0,
})
axleCountingMap := make(map[string]*graphicData.AxleCounting)
for _, data := range storage.AxleCountings {
if data.KilometerSystem == nil {
println(fmt.Sprintf("计轴[%s]缺少公里标", data.Common.Id))
continue
}
axleCountingMap[data.Common.Id] = data
cpType := proto2.CheckPointType_AxleCounter
if data.Invent {
@ -98,13 +122,13 @@ func TestBuildRepository(t *testing.T) {
case graphicData.RelatedRef_Turnout:
turnoutPort = convertDevicePort(data.TransponderRef)
}
responder := &proto2.Responder{
responder := &proto2.Transponder{
Id: data.Common.Id,
Km: convertKm(data.KilometerSystem),
SectionId: sectionId,
TurnoutPort: turnoutPort,
}
repo.Responders = append(repo.Responders, responder)
repo.Transponders = append(repo.Transponders, responder)
}
slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker)
for _, data := range storage.SlopeKiloMarker {