【修改添加列车获取link逻辑】

【删除无用代码】
【修改继电器UID生成逻辑】
This commit is contained in:
weizhihong 2023-09-22 17:51:07 +08:00
parent b454d8b38a
commit e6921ad33d
21 changed files with 105 additions and 823 deletions

View File

@ -1,67 +0,0 @@
package face
import (
"fmt"
"strings"
)
// 设备模型基类
type DeviceModel struct {
//图形id,即由前端作图时生成,且全局唯一
GraphicId string
//索引编号,同类设备唯一,不同类设备不唯一
Index string
}
// 判断是否同一个设备
func (dm *DeviceModel) IsSame(other *DeviceModel) bool {
return strings.EqualFold(dm.GraphicId, other.GraphicId)
}
// 模型图形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))
}
}

View File

@ -1,42 +0,0 @@
package face
/////////////////////////////////////////////////////////////
//所有模型设备的接口定义,为了解决设备间相互依赖时循环依赖问题
type DeviceModeller interface {
//判断是否同一个模型
IsSame(other *DeviceModel) bool
//模型图形id
GetGraphicId() string
//模型索引
GetIndex() string
}
type AxlePointDeviceModeller interface {
DeviceModeller
}
type SignalDeviceModeller interface {
DeviceModeller
}
type SwitchDeviceModeller interface {
DeviceModeller
}
type AxleSectionModeller interface {
DeviceModeller
}
type LinkSectionModeller interface {
DeviceModeller
}
type LogicalSectionModeller interface {
DeviceModeller
}
type PhysicalSectionModeller interface {
DeviceModeller
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"math"
"sort"
"strconv"
"strings"
"sync"
@ -12,10 +13,6 @@ import (
"google.golang.org/protobuf/proto"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
"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/model"
"joylink.club/bj-rtsts-server/dto"
)
@ -25,40 +22,6 @@ var (
giDataMap sync.Map
)
// VerifyStructure 轨旁仿真模型结构
type VerifyStructure struct {
//计轴检测点设备模型集合,key为索引编号
AxlePointDeviceModelMap map[string]face.AxlePointDeviceModeller
//道岔设备模型集合,key为索引编号
SwitchDeviceModelMap map[string]face.SwitchDeviceModeller
//由端点确定的link模型集合,key为索引编号
LinkSectionModelMap map[string]face.LinkSectionModeller
//计轴区段模型集合,key为索引编号
AxleSectionModelMap map[string]face.AxleSectionModeller
//物理区段模型集合,key为索引编号
PhysicalSectionModelMap map[string]face.PhysicalSectionModeller
//逻辑区段模型集合,key为索引编号
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
}
// 计算link、物理区段、道岔相互转换时用到的结构体
type calcLinkPositionStruct struct {
index string // 地图元素的Index
deviceType int // 1 计轴, 2 道岔
kilometer *graphicData.KilometerSystem // 元素对应的公里标
position *ref.DevicePosition[face.DeviceModeller] // 元素在link上对应的偏移量
}
// 将发布的地图数据放入内存中
func PublishMapVerifyStructure(graphic *model.PublishedGi) {
giTypeMap.Store(graphic.ID, graphic.Type)
@ -112,145 +75,97 @@ func QueryGiData[T proto.Message](mapId int32) T {
return value.(T)
}
// 获取内存中的地图信息
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))
//}
return nil
}
// 根据区段道岔偏移量返回linkID和link相对偏移量
func QueryMapCalcLinkByDeviceInfo(mapId int32, id string, devicePort string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
vm := QueryMapVerifyStructure(mapId)
func QueryEcsLinkByDeviceInfo(repo *repository.Repository, mapId int32, id string, devicePort string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
index, err := strconv.Atoi(id)
if err != nil {
panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "类型不匹配"})
}
if devicePort == "" {
return sectionMapToLink(vm, id, offset, runDirection)
uid := QueryUidByMidAndIndex(mapId, int32(index), &graphicData.Section{})
return sectionMapToEcsLink(repo, uid, offset, runDirection)
} else {
return turnoutMapToLink(vm, id, devicePort, offset, runDirection)
uid := QueryUidByMidAndIndex(mapId, int32(index), &graphicData.Turnout{})
return turnoutMapToEcsLink(repo, uid, devicePort, offset, runDirection)
}
}
// 根据物理区段上的偏移量基于区段A端找到所在link的linkId与偏移量
func sectionMapToLink(vm *VerifyStructure, id string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
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[face.DeviceModeller])
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
func sectionMapToEcsLink(repo *repository.Repository, id string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
var section *repository.PhysicalSection
for _, s := range repo.PhysicalSectionList() {
if s.Id() == id {
section = s
break
}
}
if len(axlePointPositionMap) == 0 { // 无计轴信息
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到区段【id:%s,index:%s】所在link", sectionModel.GraphicId, id)})
if section == nil {
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("地图不存在uid:%s缓存", 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) // ab的偏移量默认B点比A点大
var bp *ref.DevicePosition[face.DeviceModeller] // 定义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)
trainKilometer := concertTrainKilometer(ak.Kilometer, offset, up)
if ao < bo {
return linkId, int64(ao) + offset, up, abDirection, trainKilometer
} else {
return linkId, int64(ao) - offset, up, abDirection, trainKilometer
}
ao, bo := section.ALinkPosition().Offset(), section.BLinkPosition().Offset()
// 是否从A到B
abDirection := ao < bo
up := runDirection
if (section.AKilometer().Value > section.BKilometer().Value) != abDirection {
up = !runDirection
}
linkId, _ := strconv.Atoi(section.ALinkPosition().Link().Identity.Id())
trainKilometer := concertTrainKilometer(section.AKilometer().Value, offset, up)
if abDirection {
return int32(linkId), ao + offset, up, abDirection, trainKilometer
} else {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("link【%d】缺失区段【id:%s,index:%s】A点缺失计轴", linkId, sectionModel.GraphicId, id)})
return int32(linkId), ao - offset, up, abDirection, trainKilometer
}
}
// 根据道岔上的偏移量基于岔心位置找到所在link的linkId与偏移量
func turnoutMapToLink(vm *VerifyStructure, id string, port string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
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
func turnoutMapToEcsLink(repo *repository.Repository, id string, port string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
var turnout *repository.Turnout
for _, t := range repo.TurnoutList() {
if t.Id() == id {
turnout = t
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)
trainKilometer := concertTrainKilometer(vp.kilometer.Kilometer, offset, pointTo)
if isStart {
return linkId, int64(vp.position.Offset) + offset, up, pointTo, trainKilometer
} else {
return linkId, int64(vp.position.Offset) - offset, up, pointTo, trainKilometer
}
if turnout == nil {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在道岔【uid:%s】", id)})
}
var portPosition *repository.LinkPosition
var crossKm, portKm *proto2.Kilometer
switch port {
case "A":
portPosition = turnout.FindLinkPositionByPort(proto2.Port_A)
portKm = turnout.GetTurnoutKm(proto2.Port_A)
case "B":
portPosition = turnout.FindLinkPositionByPort(proto2.Port_B)
portKm = turnout.GetTurnoutKm(proto2.Port_B)
case "C":
portPosition = turnout.FindLinkPositionByPort(proto2.Port_C)
portKm = turnout.GetTurnoutKm(proto2.Port_C)
default:
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("无效端口【%s】偏移量", port)})
}
// 岔心公里标
crossKm = turnout.GetTurnoutKm(proto2.Port_None)
// 关联link
link := portPosition.Link()
isStart := link.ARelation().Device().Id() == id
up := runDirection
if (portKm.Value > crossKm.Value) != isStart {
up = !runDirection
}
pointTo := (portKm.Value > crossKm.Value) == runDirection
trainKilometer := concertTrainKilometer(crossKm.Value, offset, pointTo)
linkId, _ := strconv.Atoi(link.Identity.Id())
if isStart {
return int32(linkId), offset, up, pointTo, trainKilometer
} else {
// 道岔长度
turnoutLen := int64(math.Abs(float64(portKm.Value - crossKm.Value)))
return int32(linkId), portPosition.Offset() + turnoutLen - offset, up, pointTo, trainKilometer
}
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("link【%d】缺失道岔【id:%s,index:%s】端口【%s】偏移量", linkId, turnoutModel.GraphicId, id, port)})
}
func QueryEcsLinkByDeviceInfo() {}
// 根据linkID和link相对偏移量返回区段道岔偏移量
// 设备ID、端口、偏移量、上下行、AB走向
func QueryDeviceByCalcLink(repo *repository.Repository, id string, offset int64, up bool) (
@ -302,53 +217,6 @@ func QueryDeviceByCalcLink(repo *repository.Repository, id string, offset int64,
return
}
// 将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[face.DeviceModeller], 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 direction
}
return (ak.Kilometer < bk.Kilometer) == direction
}
// 查找列车的公里标
func concertTrainKilometer(kilometer, offset int64, tendTo bool) int64 {
if tendTo {

View File

@ -127,6 +127,22 @@ func initRelayCabinetUid(graphicData *graphicData.RelayCabinetGraphicStorage) *r
RelayCabinetIds: make(map[string]*elementIdStructure, len(graphicData.RelayCabinets)),
RelayIds: make(map[string]*elementIdStructure, len(graphicData.Relays)),
}
// 获取继电器的关联关系
type relayUidPriex struct {
deviceCode string
typeCode string
}
// 继电器所属设备
refMap := make(map[string]*relayUidPriex, len(graphicData.Relays))
for _, r := range graphicData.DeviceRelateRelayList {
for _, c := range r.Combinationtypes {
p := &relayUidPriex{deviceCode: r.Code, typeCode: c.Code}
for _, i := range c.RefRelays {
refMap[i] = p
}
}
}
// 获取公共前缀
city, lineId, station := getUIdPrefix(graphicData.UniqueIdPrefix)
for _, r := range graphicData.RelayCabinets {
rus.RelayCabinetIds[r.Common.Id] = &elementIdStructure{
@ -135,11 +151,17 @@ func initRelayCabinetUid(graphicData *graphicData.RelayCabinetGraphicStorage) *r
Uid: GenerateElementUid(city, lineId, []string{station}, r.Code),
}
}
// city+line+车站+设备code+继电器组合的code+继电器的code
for _, r := range graphicData.Relays {
p := refMap[r.Common.Id]
code := r.Code
if p != nil {
code = p.deviceCode + "_" + p.typeCode + "_" + r.Code
}
rus.RelayIds[r.Common.Id] = &elementIdStructure{
CommonId: r.Common.Id,
Code: r.Code,
Uid: GenerateElementUid(city, lineId, []string{station}, r.Code),
Uid: GenerateElementUid(city, lineId, []string{station}, code),
}
}
return rus
@ -216,3 +238,14 @@ func QueryIndexByMidAndUid(mapId int32, uid string, m interface{}) int32 {
}
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("地图【id:%d】不存在【uid:%s】缓存", mapId, uid)})
}
// 根据地图Index获取UID
func QueryUidByMidAndIndex(mapId int32, index int32, m interface{}) string {
uidMap := QueryMapUidMapByType(mapId, m)
for _, u := range uidMap {
if u.Index == index {
return u.Uid
}
}
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("地图【id:%d】不存在【Index:%d】缓存", mapId, index)})
}

View File

@ -35,7 +35,7 @@ func AddTrainState(vs *VerifySimulation, status *state.TrainState, mapId int32)
//向动力学发送初始化请求
trainIndex, _ := strconv.ParseUint(status.Id, 10, 16)
// 映射link、偏移量、运行方向
linkId, loffset, up, pointTo, kilometer := QueryMapCalcLinkByDeviceInfo(mapId, status.HeadDeviceId, status.DevicePort, status.HeadOffset, status.RunDirection)
linkId, loffset, up, pointTo, kilometer := QueryEcsLinkByDeviceInfo(vs.Repo, mapId, status.HeadDeviceId, status.DevicePort, status.HeadOffset, status.RunDirection)
status.Up = up
status.PointTo = pointTo
status.TrainKilometer = kilometer

View File

@ -1,56 +0,0 @@
package device
import (
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/ref"
)
// 计轴检测点设备模型
type AxlePointDeviceModel struct {
//计轴检测点基本信息
face.DeviceModel
//端点的公里标,单位为mm
KilometerSystem *graphicData.KilometerSystem
//与该计轴点关联的道岔
//key为图形id
SwitchDevices map[string]*ref.SwitchRef
//该计轴点在非岔区物理区段的A端
LinePhysicalSectionA face.PhysicalSectionModeller
//该计轴点在非岔区物理区段的B端
LinePhysicalSectionB face.PhysicalSectionModeller
//该计轴点关联的岔区物理区段
AreaPhysicalSections map[string]face.PhysicalSectionModeller
}
// 添加关联道岔
func (dm *AxlePointDeviceModel) AddSwitchDevice(switchDeviceModel face.SwitchDeviceModeller, portEnum face.PortEnum) {
if dm.SwitchDevices == nil {
dm.SwitchDevices = make(map[string]*ref.SwitchRef)
}
dm.SwitchDevices[switchDeviceModel.GetGraphicId()] = new(ref.SwitchRef).Init(portEnum, switchDeviceModel)
}
// 添加关联非岔区物理区段
func (dm *AxlePointDeviceModel) AddPhysicalSection(physicalSectionModel face.PhysicalSectionModeller, portEnum face.PortEnum) {
switch portEnum {
case face.A:
{
dm.LinePhysicalSectionA = physicalSectionModel
break
}
case face.B:
{
dm.LinePhysicalSectionB = physicalSectionModel
break
}
}
}
// 添加关联岔区物理区段
func (dm *AxlePointDeviceModel) AddPhysicalSectionForArea(physicalSectionModel face.PhysicalSectionModeller) {
if dm.AreaPhysicalSections == nil {
dm.AreaPhysicalSections = make(map[string]face.PhysicalSectionModeller)
}
dm.AreaPhysicalSections[physicalSectionModel.GetGraphicId()] = physicalSectionModel
}

View File

@ -1,29 +0,0 @@
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[face.DeviceModeller]
}
func ConvertFromDevicePort(dp *ref.DevicePort[*LinkModel]) *ref.DevicePosition[*LinkModel] {
var offset int32 = 0
if dp.Port == face.B {
offset = dp.Device.Length
}
return &ref.DevicePosition[*LinkModel]{
Device: dp.Device,
Offset: offset,
}
}

View File

@ -1,12 +0,0 @@
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
}

View File

@ -1,14 +0,0 @@
package device
import (
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
// 信号机装置
type SignalDeviceModel struct {
//信号机基本信息
face.DeviceModel
//信号机所在公里标,单位为mm
KilometerSystem *graphicData.KilometerSystem
}

View File

@ -1,92 +0,0 @@
package device
import (
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/ref"
)
// 道岔装置(规定A端为岔尖规定B端为定位端轨道C端为反位端)
type SwitchDeviceModel struct {
//道岔基本信息
face.DeviceModel
//端点的公里标,单位为mm
//list中元素类型为graphicData.KilometerSystem
KilometerSystems []*graphicData.KilometerSystem
//道岔A端连接的sectionLink
LinkRefA *ref.LinkRef
//道岔B端连接的sectionLink
LinkRefB *ref.LinkRef
//道岔C端连接的sectionLink
LinkRefC *ref.LinkRef
// 道岔相连的计轴信息
AxlePoints map[string]*AxlePointDeviceModel
// A端连接的Link端点
ALinkPort *ref.DevicePort[*LinkModel]
// B端连接的Link端点
BLinkPort *ref.DevicePort[*LinkModel]
// C端连接的Link端点
CLinkPort *ref.DevicePort[*LinkModel]
}
// 获取道岔端口关联的轨道
func (dm *SwitchDeviceModel) FindLinkRefByPort(portEnum face.PortEnum) *ref.LinkRef {
switch portEnum {
case face.A:
{
return dm.LinkRefA
}
case face.B:
{
return dm.LinkRefB
}
case face.C:
{
return dm.LinkRefC
}
}
return nil
}
// 统计与该道岔关联的轨道数量值为3
func (dm *SwitchDeviceModel) RelationCount() int {
var count int = 0
if dm.LinkRefA != nil {
count++
}
if dm.LinkRefB != nil {
count++
}
if dm.LinkRefC != nil {
count++
}
return count
}
// 道岔A、B端连接的轨道的索引集合
// 返回值中map key、value均为索引值
func (dm *SwitchDeviceModel) AbPortsLinkIndexes() map[string]string {
var rt map[string]string = make(map[string]string)
rt[dm.LinkRefA.LinkSection.GetIndex()] = dm.LinkRefA.LinkSection.GetIndex()
rt[dm.LinkRefB.LinkSection.GetIndex()] = dm.LinkRefB.LinkSection.GetIndex()
return rt
}
// 道岔A、C端连接的轨道的索引集合
// 返回值中map key、value均为索引值
func (dm *SwitchDeviceModel) AcPortsLinkIndexes() map[string]string {
var rt map[string]string = make(map[string]string)
rt[dm.LinkRefA.LinkSection.GetIndex()] = dm.LinkRefA.LinkSection.GetIndex()
rt[dm.LinkRefC.LinkSection.GetIndex()] = dm.LinkRefC.LinkSection.GetIndex()
return rt
}
// 道岔B、C端连接的轨道的索引集合
// 返回值中map key、value均为索引值
func (dm *SwitchDeviceModel) BcPortsLinkIndexes() map[string]string {
var rt map[string]string = make(map[string]string)
rt[dm.LinkRefB.LinkSection.GetIndex()] = dm.LinkRefB.LinkSection.GetIndex()
rt[dm.LinkRefC.LinkSection.GetIndex()] = dm.LinkRefC.LinkSection.GetIndex()
return rt
}

View File

@ -1,9 +0,0 @@
package ref
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
// DevicePort 两个作用,一是表示设备的端点;而是表示以此设备为基准的方向
type DevicePort[T face.DeviceModeller] struct {
Device T
Port face.PortEnum
}

View File

@ -1,16 +0,0 @@
package ref
import (
"fmt"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
type DevicePosition[T face.DeviceModeller] struct {
Device T
Offset int32
}
func (dp *DevicePosition[T]) String() string {
return fmt.Sprintf("%s-%d", dp.Device.GetIndex(), dp.Offset)
}

View File

@ -1,13 +0,0 @@
package ref
import (
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
// link端口引用
type LinkRef struct {
//引用的轨道
LinkSection face.LogicalSectionModeller
//引用的轨道的端口
Port face.PortEnum
}

View File

@ -1,13 +0,0 @@
package ref
import (
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
// 道岔定反位引用定义
type SwitchPositionRef struct {
//道岔设备
SwitchDevice face.SwitchDeviceModeller
//true-定位false-反位
Normal bool
}

View File

@ -1,20 +0,0 @@
package ref
import (
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
// 道岔端口引用
type SwitchRef struct {
//道岔设备
SwitchDevice face.SwitchDeviceModeller
//道岔端口
Port face.PortEnum
}
// 初始化
func (ref *SwitchRef) Init(port face.PortEnum, switchDevice face.SwitchDeviceModeller) *SwitchRef {
ref.Port = port
ref.SwitchDevice = switchDevice
return ref
}

View File

@ -1,49 +0,0 @@
package section
import (
"container/list"
"fmt"
"sort"
"strings"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
// 相邻计轴检测点(车档为特殊的计轴检测点)定义的计轴区段由LinkSection组成
type AxleSectionModel struct {
//计轴区段基本信息
face.DeviceModel
//计轴区段的A端的计轴检测点
AxlePointA face.AxlePointDeviceModeller
//计轴区段的B端的计轴检测点
AxlePointB face.AxlePointDeviceModeller
//如果该计轴区段经过岔区,则所经过的道岔应该所处的定反位
//ref.SwitchPositionRef
ViaSwitchPositions *list.List
//PathLayer中收集: 该计轴区段经过的轨道
//face.LinkSectionModeller
ViaLinks *list.List
//计轴区段的两侧计轴点的图形id形成的key
pointsKey string
}
// 计轴区段的两侧计轴点的图形id形成的key
func (asm *AxleSectionModel) GetPointsKey() string {
if len(strings.TrimSpace(asm.pointsKey)) == 0 {
var pointsKeySlice = make([]string, 0, 2)
pointsKeySlice = append(pointsKeySlice, asm.AxlePointA.GetGraphicId())
pointsKeySlice = append(pointsKeySlice, asm.AxlePointB.GetGraphicId())
sort.Strings(pointsKeySlice)
asm.pointsKey = fmt.Sprintf("%s_%s", pointsKeySlice[0], pointsKeySlice[1])
}
return asm.pointsKey
}
// 计轴区段中轨道个数,即计轴区段是由几个轨道组成
func (asm *AxleSectionModel) LinksCount() int {
if asm.ViaSwitchPositions == nil {
return 1
} else {
return 1 + asm.ViaSwitchPositions.Len()
}
}

View File

@ -1,13 +0,0 @@
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
}

View File

@ -1,117 +0,0 @@
package section
import (
"fmt"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/ref"
)
// 相邻端点(车档、计轴检测点、道岔岔心)定义的Link区段
// 地图做数据时link区段的A端在左link区段的B端在右即上行方向A->B,下行方向B->A
type LinkSectionModel struct {
//轨道基本信息
face.DeviceModel
//true - 上行false - 下行
Up bool
//link 的A端连接道岔
SwitchRefA *ref.SwitchRef
//link 的B端连接道岔
SwitchRefB *ref.SwitchRef
//link 的A端连接另一个link
LinkRefA *ref.LinkRef
//link 的B端连接另一个link
LinkRefB *ref.LinkRef
//link 的A端关联的计轴检测点
AxlePointA face.AxlePointDeviceModeller
//link 的B端关联的计轴检测点
AxlePointB face.AxlePointDeviceModeller
}
// 获取A端端点的图形id
func (dm *LinkSectionModel) FindPointAGraphicId() (string, error) {
if dm.SwitchRefA != nil {
return dm.SwitchRefA.SwitchDevice.GetGraphicId(), nil
}
if dm.AxlePointA != nil {
return dm.AxlePointA.GetGraphicId(), nil
}
return "", fmt.Errorf("gid为[%s]的A端端点不存在", dm.GraphicId)
}
// 获取B端端点的图形id
func (dm *LinkSectionModel) FindPointBGraphicId() (string, error) {
if dm.SwitchRefB != nil {
return dm.SwitchRefB.SwitchDevice.GetGraphicId(), nil
}
if dm.AxlePointB != nil {
return dm.AxlePointB.GetGraphicId(), nil
}
return "", fmt.Errorf("gid为[%s]的B端端点不存在", dm.GraphicId)
}
// 统计轨道端点数量值为2才是正确的
func (dm *LinkSectionModel) EndPointsCount() int {
var count int = 0
if dm.AxlePointA != nil {
count++
}
if dm.AxlePointB != nil {
count++
}
if dm.SwitchRefA != nil {
count++
}
if dm.SwitchRefB != nil {
count++
}
return count
}
// 统计轨道两端连接设备的数量,值为1或2
func (dm *LinkSectionModel) RelationCount() int {
var count int = 0
if dm.SwitchRefA != nil {
count++
}
if dm.SwitchRefB != nil {
count++
}
if dm.LinkRefA != nil {
count++
}
if dm.LinkRefB != nil {
count++
}
return count
}
// 获取该轨道某个端口连接的轨道,如果有
func (dm *LinkSectionModel) FindLinkRefByPort(portEnum face.PortEnum) *ref.LinkRef {
switch portEnum {
case face.A:
{
return dm.LinkRefA
}
case face.B:
{
return dm.LinkRefB
}
}
return nil
}
// 获取该轨道某个端口连接的道岔,如果有
func (dm *LinkSectionModel) FindSwitchRefByPort(portEnum face.PortEnum) *ref.SwitchRef {
switch portEnum {
case face.A:
{
return dm.SwitchRefA
}
case face.B:
{
return dm.SwitchRefB
}
}
return nil
}

View File

@ -1,15 +0,0 @@
package section
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
// 逻辑区段分两种类型
// 逻辑区段(单个计轴区段、单个Link区段、计轴区段内划分的一段)
type LogicalSectionModel struct {
//逻辑区段基本信息
face.DeviceModel
//该逻辑区段所在的计轴区段
AxleSection face.AxleSectionModeller
//该逻辑区段所在的道岔(如果该逻辑区段道岔的C端关联的link)
//非岔区逻辑区段,则该字段为空
SwitchDevice face.SwitchDeviceModeller
}

View File

@ -1,29 +0,0 @@
package section
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
// 物理区段(一整个计轴区段、岔区几个计轴检测点限定的区域)物理区段(一整个计轴区段、岔区几个计轴检测点限定的区域)物理区段(一整个计轴区段、岔区几个计轴检测点限定的区域)物理区段(一整个计轴区段、岔区几个计轴检测点限定的区域)物理区段(一整个计轴区段、岔区几个计轴检测点限定的区域)v
type PhysicalSectionModel struct {
//物理区段基本信息
face.DeviceModel
//true - 岔区物理区段false - 非岔区物理区段
SwitchArea bool
//限定物理区段的计轴检测点
//key-图形id
AxlePoints map[string]face.AxlePointDeviceModeller
//该物理区段中包含的所有计轴区段
//key-图形id
AxleSections map[string]face.AxleSectionModeller
// 端口对应的计轴信息
PortAxlePoints map[string]face.AxlePointDeviceModeller
}
// 添加计轴检测点
func (psm *PhysicalSectionModel) AddAxlePoint(axlePointDeviceModel face.AxlePointDeviceModeller) {
psm.AxlePoints[axlePointDeviceModel.GetGraphicId()] = axlePointDeviceModel
}
// 添加计轴区段
func (psm *PhysicalSectionModel) AddAxleSection(axleSectionModel face.AxleSectionModeller) {
psm.AxleSections[axleSectionModel.GetGraphicId()] = axleSectionModel
}

View File

@ -1,13 +0,0 @@
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
}