增加坡度、曲线数据构建及向动力学发送

This commit is contained in:
joylink_zhangsai 2023-08-11 17:24:30 +08:00
parent 350a94259b
commit 383e599757
7 changed files with 204 additions and 113 deletions

View File

@ -4,8 +4,6 @@ import (
"net"
"strings"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/model/device"
"fmt"
"net/http"
"strconv"
@ -129,36 +127,6 @@ func convert(info *dynamics.TrainInfo, sta *state.TrainState, vs *memory.VerifyS
sta.HeadDeviceId = id
sta.DevicePort = port
sta.HeadOffset = offset
/*
modeller := vs.LinkModelMap[int32(info.Link)]
model := modeller.(*device.LinkModel)
for i, dp := range model.DevicePositions {
if uint32(dp.Offset) >= info.LinkOffset {
var minLinkRef *graphicData.RelatedRef
var minOffset int32
var maxOffset int32
if i == 0 {
minLinkRef = model.SectionLinkMap[dp.Device.GetGraphicId()]
minOffset = dp.Offset
maxOffset = model.DevicePositions[i+1].Offset
} else {
minLinkRef = model.SectionLinkMap[model.DevicePositions[i-1].Device.GetGraphicId()]
minOffset = model.DevicePositions[i-1].Offset
maxOffset = dp.Offset
}
switch minLinkRef.DevicePort {
case 0:
sta.HeadLinkId = minLinkRef.GetId()
sta.HeadLinkOffset = int64(info.LinkOffset - uint32(minOffset))
case 1:
sta.HeadLinkId = minLinkRef.GetId()
sta.HeadLinkOffset = int64(uint32(maxOffset) - info.LinkOffset)
}
break
}
}
zap.S().Debugf("转换后的消息:[%d-%s-%d]", info.Number, sta.HeadLinkId, sta.HeadLinkOffset)
*/
sta.Slope = int32(info.Slope)
sta.Upslope = info.UpSlope
sta.RunningUp = info.Up
@ -198,8 +166,9 @@ func dynamicsRun(verifySimulation *memory.VerifySimulation) {
func buildLineBaseInfo(vs *memory.VerifyStructure) *dynamics.LineBaseInfo {
var links []*dynamics.Link
for _, modeller := range vs.LinkModelMap {
link := modeller.(*device.LinkModel)
var slopes []*dynamics.Slope
var curves []*dynamics.Curve
for _, link := range vs.LinkModelMap {
id, _ := strconv.Atoi(link.Index)
var aTurnoutId int
if link.ARelatedSwitchRef.SwitchDevice != nil {
@ -218,9 +187,31 @@ func buildLineBaseInfo(vs *memory.VerifyStructure) *dynamics.LineBaseInfo {
BRelTurnoutPoint: link.BRelatedSwitchRef.Port.Name(),
})
}
for _, slope := range vs.SlopeModelMap {
id, _ := strconv.Atoi(slope.Index)
slopes = append(slopes, &dynamics.Slope{
ID: int32(id),
StartLinkId: slope.StartLinkIndex,
StartLinkOffset: slope.StartLinkOffset,
EndLinkId: slope.EndLinkIndex,
EndLinkOffset: slope.EndLinkOffset,
DegreeTrig: slope.DegreeTrig,
})
}
for _, curve := range vs.CurveModelMap {
id, _ := strconv.Atoi(curve.Index)
curves = append(curves, &dynamics.Curve{
ID: int32(id),
StartLinkId: curve.StartLinkIndex,
StartLinkOffset: curve.StartLinkOffset,
EndLinkId: curve.EndLinkIndex,
EndLinkOffset: curve.EndLinkOffset,
Curvature: curve.Curvature,
})
}
return &dynamics.LineBaseInfo{
LinkList: links,
SlopeList: nil,
CurveList: nil,
SlopeList: slopes,
CurveList: curves,
}
}

View File

@ -23,7 +23,7 @@ import (
// 仿真存储集合 ID
var graphicDataMap sync.Map
// 轨旁仿真模型结构,注意这里的key 为 Index
// VerifyStructure 轨旁仿真模型结构
type VerifyStructure struct {
//计轴检测点设备模型集合,key为索引编号
AxlePointDeviceModelMap map[string]face.AxlePointDeviceModeller
@ -40,19 +40,28 @@ type VerifyStructure struct {
//信号机模型集合,key为索引编号
SignalDeviceModelMap map[string]face.SignalDeviceModeller
//Link模型集合key为索引编号
LinkModelMap map[int32]face.DeviceModeller
LinkModelMap map[int32]*device.LinkModel
//坡度模型集合key为id
SlopeModelMap map[string]*section.SlopeModel
//曲线模型集合key为id
CurveModelMap map[string]*section.CurveModel
//点模型集合key为id
PointMap map[string]*device.PointModel
}
// 设备地图ID对应map结构体(建立关系时便于查找使用)注意这里的key 为 Common.Id
// GraphicInfoMapStructure 设备地图ID对应map结构体(建立关系时便于查找使用)
type GraphicInfoMapStructure struct {
AxlePointMap map[string]*graphicData.AxleCounting
TurnoutMap map[string]*graphicData.Turnout
LinkMap map[string]*graphicData.SectionLink
SectionLinkMap map[string]*graphicData.SectionLink
AxleSectionMap map[string]*graphicData.AxleCountingSection
PhysicalSectionMap map[string]*graphicData.Section
LogicSectionMap map[string]*graphicData.LogicSection
SignalMap map[string]*graphicData.Signal
CalcLinkMap map[string]*graphicData.CalculateLink
//key-index
CalcLinkMap map[int32]*graphicData.CalculateLink
//设备在link上的位置。key-设备id
DevicePositionMap map[string]*ref.DevicePosition
}
// 将发布的地图数据放入内存中
@ -66,18 +75,21 @@ func PublishMapVerifyStructure(graphic *model.PublishedGi) *VerifyStructure {
PhysicalSectionModelMap: make(map[string]face.PhysicalSectionModeller),
LogicalSectionModelMap: make(map[string]face.LogicalSectionModeller),
SignalDeviceModelMap: make(map[string]face.SignalDeviceModeller),
LinkModelMap: make(map[int32]face.DeviceModeller),
LinkModelMap: make(map[int32]*device.LinkModel),
SlopeModelMap: make(map[string]*section.SlopeModel),
CurveModelMap: make(map[string]*section.CurveModel),
PointMap: make(map[string]*device.PointModel),
}
// 地图数据转为map存储建立关系时方便使用
graphicInfoMap := &GraphicInfoMapStructure{
AxlePointMap: make(map[string]*graphicData.AxleCounting),
TurnoutMap: make(map[string]*graphicData.Turnout),
LinkMap: make(map[string]*graphicData.SectionLink),
SectionLinkMap: make(map[string]*graphicData.SectionLink),
AxleSectionMap: make(map[string]*graphicData.AxleCountingSection),
PhysicalSectionMap: make(map[string]*graphicData.Section),
LogicSectionMap: make(map[string]*graphicData.LogicSection),
SignalMap: make(map[string]*graphicData.Signal),
CalcLinkMap: make(map[string]*graphicData.CalculateLink),
CalcLinkMap: make(map[int32]*graphicData.CalculateLink),
}
graphicStorage := &graphicData.RtssGraphicStorage{}
proto.Unmarshal(graphic.Proto, graphicStorage)
@ -129,8 +141,7 @@ func sectionMapToLink(vm *VerifyStructure, id string, offset int64) (int32, int6
var linkId int32
// 获取计轴信息
axlePointMap := make(map[string]*ref.DevicePosition)
for k, v := range vm.LinkModelMap {
lm := v.(*device.LinkModel)
for k, lm := range vm.LinkModelMap {
for _, p := range lm.DevicePositions {
if sectionModel.AxlePoints[p.Device.GetIndex()] != nil {
axlePointMap[p.Device.GetIndex()] = p
@ -177,8 +188,7 @@ func turnoutMapToLink(vm *VerifyStructure, id string, port string, offset int64)
var link *device.LinkModel
var linkId int32
var isStart bool
for i, v := range vm.LinkModelMap {
lm := v.(*device.LinkModel)
for i, lm := range vm.LinkModelMap {
linkId = i
if lm.ARelatedSwitchRef.SwitchDevice.GetIndex() == turnoutModel.Index && lm.ARelatedSwitchRef.Port.Name() == port {
isStart = true
@ -211,11 +221,10 @@ func QueryMapDeviceByCalcLink(mapId int32, id int32, offset int64) (string, stri
}
func QueryDeviceByCalcLink(vm *VerifyStructure, id int32, offset int64) (string, string, int64) {
lm := vm.LinkModelMap[id]
if lm == nil {
linkModel := vm.LinkModelMap[id]
if linkModel == nil {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到link【%d】", id)})
}
linkModel := lm.(*device.LinkModel)
if offset > int64(linkModel.Length) {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("偏移超出link范围【%d】", id)})
}
@ -282,26 +291,111 @@ func initGraphicStructure(graphicData *graphicData.RtssGraphicStorage, verifyStr
initGraphicLogicSections(graphicData.LogicSections, verifyStructure, graphicDataMap)
// 初始化信号机信息
initGraphicSignal(graphicData.Signals, verifyStructure, graphicDataMap)
// 初始化计算link数据
initCalcLink(graphicData.CalculateLink, verifyStructure, graphicDataMap)
// 初始化Link信息
initLink(graphicData.CalculateLink, verifyStructure, graphicDataMap, graphicData)
initLinks(graphicData.CalculateLink, verifyStructure, graphicDataMap)
// 初始化坡度和曲线端点
initPoints(graphicData, verifyStructure, graphicDataMap)
// 初始化坡度
initSlopes(graphicData.Slopes, verifyStructure, graphicDataMap)
// 初始化曲线
initCurves(graphicData.Curvatures, verifyStructure, graphicDataMap)
}
func initLink(links []*graphicData.CalculateLink, vs *VerifyStructure, dataMap *GraphicInfoMapStructure, data *graphicData.RtssGraphicStorage) {
axleTurnoutIdMap := make(map[string]face.AxlePointDeviceModeller)
func initCurves(curves []*graphicData.Curvature, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
for _, curve := range curves {
startDp := dataMap.DevicePositionMap[curve.RefDeviceId[0]]
endDp := dataMap.DevicePositionMap[curve.RefDeviceId[1]]
startIndex, _ := strconv.Atoi(startDp.Device.GetIndex())
endIndex, _ := strconv.Atoi(endDp.Device.GetIndex())
vs.CurveModelMap[curve.Common.Id] = &section.CurveModel{
DeviceModel: face.DeviceModel{
GraphicId: curve.GetCommon().GetId(),
Index: curve.GetCommon().GetId(),
},
StartLinkIndex: int32(startIndex),
StartLinkOffset: startDp.Offset,
EndLinkIndex: int32(endIndex),
EndLinkOffset: endDp.Offset,
Curvature: curve.CurvatureNumber,
}
}
}
func initSlopes(slopes []*graphicData.Slope, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
for _, slope := range slopes {
startDp := dataMap.DevicePositionMap[slope.RefDeviceId[0]]
endDp := dataMap.DevicePositionMap[slope.RefDeviceId[1]]
startIndex, _ := strconv.Atoi(startDp.Device.GetIndex())
endIndex, _ := strconv.Atoi(endDp.Device.GetIndex())
vs.SlopeModelMap[slope.Common.Id] = &section.SlopeModel{
DeviceModel: face.DeviceModel{
GraphicId: slope.GetCommon().GetId(),
Index: slope.GetCommon().GetId(),
},
StartLinkIndex: int32(startIndex),
StartLinkOffset: startDp.Offset,
EndLinkIndex: int32(endIndex),
EndLinkOffset: endDp.Offset,
DegreeTrig: slope.SlopeNumber,
}
}
}
func initPoints(storage *graphicData.RtssGraphicStorage, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
for _, slopeKm := range storage.SlopeKiloMarker {
vs.PointMap[slopeKm.Common.Id] = &device.PointModel{
DeviceModel: face.DeviceModel{
GraphicId: slopeKm.Common.Id,
Index: slopeKm.Common.Id,
},
Kms: slopeKm.KilometerSystem,
}
}
for _, curvatureKm := range storage.CurvatureKiloMarker {
vs.PointMap[curvatureKm.Common.Id] = &device.PointModel{
DeviceModel: face.DeviceModel{
GraphicId: curvatureKm.Common.Id,
Index: curvatureKm.Common.Id,
},
Kms: curvatureKm.KilometerSystem,
}
}
}
func initLinks(links []*graphicData.CalculateLink, vs *VerifyStructure, dataMap *GraphicInfoMapStructure) {
deviceIdMap := make(map[string]face.DeviceModeller)
for _, modeller := range vs.AxlePointDeviceModelMap {
axleTurnoutIdMap[modeller.GetGraphicId()] = modeller
deviceIdMap[modeller.GetGraphicId()] = modeller
}
for _, modeller := range vs.SwitchDeviceModelMap {
axleTurnoutIdMap[modeller.GetGraphicId()] = modeller
deviceIdMap[modeller.GetGraphicId()] = modeller
}
for _, pointModel := range vs.PointMap {
deviceIdMap[pointModel.GetGraphicId()] = pointModel
}
for _, link := range links {
sectionLinkMap := make(map[string]*graphicData.RelatedRef)
linkModel := &device.LinkModel{
DeviceModel: face.DeviceModel{
GraphicId: link.Common.Id,
Index: strconv.Itoa(int(link.Index)),
},
Length: link.Length,
ARelatedSwitchRef: ref.SwitchRef{
SwitchDevice: deviceIdMap[link.ARelatedRef.Id],
Port: face.GetPortEnum(int8(link.ARelatedRef.DevicePort)),
},
BRelatedSwitchRef: ref.SwitchRef{
SwitchDevice: deviceIdMap[link.BRelatedRef.Id],
Port: face.GetPortEnum(int8(link.BRelatedRef.DevicePort)),
},
}
vs.LinkModelMap[link.Index] = linkModel
dataMap.CalcLinkMap[link.Index] = link
//构建DevicePositionDP切片(暂时仅计轴和道岔)
var dps []*ref.DevicePosition
for _, dp := range link.DevicePositions {
modeller := axleTurnoutIdMap[dp.DeviceId]
modeller := deviceIdMap[dp.DeviceId]
if modeller == nil {
continue
}
@ -309,51 +403,17 @@ func initLink(links []*graphicData.CalculateLink, vs *VerifyStructure, dataMap *
Device: modeller,
Offset: dp.Offset,
})
dataMap.DevicePositionMap[dp.DeviceId] = &ref.DevicePosition{
Device: linkModel,
Offset: dp.Offset,
}
}
//对DP切片按Offset排序
sort.Slice(dps, func(i, j int) bool {
return dps[i].Offset < dps[j].Offset
})
//构建SectionLinkMap
for i := 1; i < len(dps); i++ {
a := dps[i-1]
b := dps[i]
aId := a.Device.GetGraphicId()
bId := b.Device.GetGraphicId()
for _, sl := range data.SectionLinks {
if aId == sl.ASimRef.Id && bId == sl.BSimRef.Id {
sectionLinkMap[aId] = &graphicData.RelatedRef{
DeviceType: 0, //这个字段用不到,所以随便赋值
Id: strconv.Itoa(int(sl.Index)), //因为发给前端的是索引,所以这里用索引
DevicePort: 0,
}
} else if aId == sl.BSimRef.Id && bId == sl.ASimRef.Id {
sectionLinkMap[aId] = &graphicData.RelatedRef{
DeviceType: 0, //这个字段用不到,所以随便赋值
Id: strconv.Itoa(int(sl.Index)), //因为发给前端的是索引,所以这里用索引
DevicePort: 1,
}
}
}
}
vs.LinkModelMap[link.Index] = &device.LinkModel{
DeviceModel: face.DeviceModel{
GraphicId: link.Common.Id,
Index: strconv.Itoa(int(link.Index)),
},
Length: link.Length,
ARelatedSwitchRef: ref.SwitchRef{
SwitchDevice: axleTurnoutIdMap[link.ARelatedRef.Id],
Port: face.GetPortEnum(int8(link.ARelatedRef.DevicePort)),
},
BRelatedSwitchRef: ref.SwitchRef{
SwitchDevice: axleTurnoutIdMap[link.BRelatedRef.Id],
Port: face.GetPortEnum(int8(link.BRelatedRef.DevicePort)),
},
DevicePositions: dps,
SectionLinkMap: sectionLinkMap,
}
//赋值
linkModel.DevicePositions = dps
}
}
@ -393,7 +453,7 @@ func initGraphicTurnout(turnouts []*graphicData.Turnout, data *VerifyStructure,
// 初始化link信息
func initGraphicLink(links []*graphicData.SectionLink, data *VerifyStructure, graphicDataMap *GraphicInfoMapStructure) {
for _, s := range links {
graphicDataMap.LinkMap[s.Common.Id] = s
graphicDataMap.SectionLinkMap[s.Common.Id] = s
id := strconv.Itoa(int(s.Index))
data.LinkSectionModelMap[id] = &section.LinkSectionModel{
DeviceModel: face.DeviceModel{
@ -475,10 +535,7 @@ func initGraphicSignal(signals []*graphicData.Signal, data *VerifyStructure, gra
// 初始化计算link数据
func initCalcLink(calculateLinks []*graphicData.CalculateLink, verifyStructure *VerifyStructure, graphicDataMap *GraphicInfoMapStructure) {
for _, l := range calculateLinks {
id := strconv.Itoa(int(l.Index))
graphicDataMap.CalcLinkMap[id] = l
}
}
// 构建设备间的关系
@ -501,7 +558,7 @@ func buildDeviceRef(graphicData *GraphicInfoMapStructure, verifyStructure *Verif
// 构建link的关联关系端点间的轨道
func buildLinkDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for _, v := range mapData.LinkMap {
for _, v := range mapData.SectionLinkMap {
link := (verifyStructure.LinkSectionModelMap[strconv.Itoa(int(v.Index))]).(*section.LinkSectionModel)
// 轨道A端端点
linkSimRefBuildCommMethod(v.Common.Id, v.ASimRef, mapData, verifyStructure, func(f face.AxlePointDeviceModeller) {
@ -562,7 +619,7 @@ func linkRefBuildCommMethod(v *graphicData.SectionLink, mapData *GraphicInfoMapS
if r != nil {
switch r.DeviceType {
case graphicData.RelatedRef_SectionLink:
d := mapData.LinkMap[r.Id]
d := mapData.SectionLinkMap[r.Id]
if d != nil {
ls := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(d.Index))]
lr(&ref.LinkRef{LinkSection: ls, Port: face.PortEnum(r.DevicePort)})

View File

@ -1,7 +1,6 @@
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"
)
@ -14,8 +13,6 @@ type LinkModel struct {
ARelatedSwitchRef ref.SwitchRef
//B端连接的道岔端点
BRelatedSwitchRef ref.SwitchRef
//Link上的设备及位置(将A、B端的道岔也填进来了)(按offset排序)
//Link上的设备及位置(包括A、B端的设备)(按offset排序)
DevicePositions []*ref.DevicePosition
//key-在link上最小偏移量端点设备idvalue-SectionLink端点
SectionLinkMap map[string]*graphicData.RelatedRef
}

View File

@ -0,0 +1,12 @@
package device
import (
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
)
// PointModel 线上某一点(本来是想添加坡度和曲线端点,但是他俩数据没有区别,故合为一个通用概念)
type PointModel struct {
face.DeviceModel
Kms []*graphicData.KilometerSystem
}

View File

@ -0,0 +1,13 @@
package section
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
type CurveModel struct {
face.DeviceModel
StartLinkIndex int32
StartLinkOffset int32
EndLinkIndex int32
EndLinkOffset int32
//曲率(半径)mm
Curvature int32
}

View File

@ -0,0 +1,13 @@
package section
import "joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/face"
type SlopeModel struct {
face.DeviceModel
StartLinkIndex int32
StartLinkOffset int32
EndLinkIndex int32
EndLinkOffset int32
//坡度角的三角函数(应该是sin)*1000
DegreeTrig int32
}

View File

@ -19,8 +19,16 @@ func init() {
for true {
info := <-trainInfoChan
for e := handlerList.Front(); e != nil; e = e.Next() {
handler := e.Value.(TrainInfoHandler)
handler(info)
func() {
defer func() {
r := recover()
if r != nil {
zap.S().Errorf("列车信息处理函数报错")
}
}()
handler := e.Value.(TrainInfoHandler)
handler(info)
}()
}
}
}()