【增加IBP盘对象映射】【半实物协议增加阻力等信息】
This commit is contained in:
parent
b698316777
commit
ac5e8f843b
@ -57,7 +57,7 @@ func init() {
|
||||
}
|
||||
trainState := sta.(*state.TrainState)
|
||||
// 给半实物仿真发送速度
|
||||
vobc.SendTrainSpeedTask(math.Abs(float64(info.Speed * 36)))
|
||||
vobc.SendTrainSpeedTask(convertVobc(info))
|
||||
// 更新列车状态
|
||||
memory.UpdateTrainState(simulation, convert(info, trainState, simulation))
|
||||
}
|
||||
@ -207,6 +207,21 @@ func convert(info *dynamics.TrainInfo, sta *state.TrainState, simulation *memory
|
||||
return sta
|
||||
}
|
||||
|
||||
// 转换成Vobc发送参数
|
||||
func convertVobc(info *dynamics.TrainInfo) *vobc.SendTrainInfo {
|
||||
param := &vobc.SendTrainInfo{
|
||||
Speed: uint16(math.Abs(float64(info.Speed * 36))),
|
||||
Upslope: info.UpSlope,
|
||||
Slope: uint16(info.Slope),
|
||||
Acceleration: uint16(info.Acceleration * 100),
|
||||
TotalResistance: uint16(info.TotalResistance / 10),
|
||||
AirResistance: uint16(info.AirResistance / 10),
|
||||
SlopeResistance: uint16(info.SlopeResistance / 10),
|
||||
CurveResistance: uint16(info.CurveResistance / 10),
|
||||
}
|
||||
return param
|
||||
}
|
||||
|
||||
func dynamicsRun(verifySimulation *memory.VerifySimulation) {
|
||||
_ = dynamics.Run(func() []*dynamics.TurnoutInfo {
|
||||
stateSlice := memory.GetAllTurnoutState(verifySimulation)
|
||||
|
@ -19,12 +19,14 @@ import (
|
||||
|
||||
var (
|
||||
giTypeMap sync.Map
|
||||
giNameMap sync.Map
|
||||
giDataMap sync.Map
|
||||
)
|
||||
|
||||
// 将发布的地图数据放入内存中
|
||||
func PublishMapVerifyStructure(graphic *model.PublishedGi) {
|
||||
giTypeMap.Store(graphic.ID, graphicData.PictureType(graphic.Type))
|
||||
giNameMap.Store(graphic.Name, graphic.ID)
|
||||
var message proto.Message
|
||||
switch graphicData.PictureType(graphic.Type) {
|
||||
case graphicData.PictureType_StationLayout:
|
||||
@ -92,6 +94,22 @@ func QueryEcsLinkByDeviceInfo(repo *repository.Repository, mapId int32, id strin
|
||||
}
|
||||
}
|
||||
|
||||
func getStorageIBPMapData(mapCode string) *graphicData.IBPGraphicStorage {
|
||||
// 处理关联的IBP盘信息
|
||||
if mapCode == "" {
|
||||
return nil
|
||||
}
|
||||
ibpId, ok := giNameMap.Load(mapCode)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
ibpMapData, ok := giDataMap.Load(ibpId)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return ibpMapData.(*graphicData.IBPGraphicStorage)
|
||||
}
|
||||
|
||||
// 根据物理区段上的偏移量(基于区段A端),找到所在link的linkId与偏移量
|
||||
func sectionMapToEcsLink(repo *repository.Repository, id string, offset int64, runDirection bool) (int32, int64, bool, bool, int64) {
|
||||
section := repo.FindPhysicalSection(id)
|
||||
|
@ -2,7 +2,6 @@ package memory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
|
||||
@ -161,21 +160,16 @@ func initStationUid(data *graphicData.RtssGraphicStorage) *stationUidStructure {
|
||||
Uid: GenerateElementUid(city, lineId, nil, s.Code),
|
||||
}
|
||||
// 处理关联的IBP盘信息
|
||||
if s.RefIbpMapCode == "" {
|
||||
continue
|
||||
}
|
||||
ibpId, _ := strconv.Atoi(s.RefIbpMapCode)
|
||||
ibpMapData, ok := giDataMap.Load(ibpId)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
initIBPUid(gus, city, lineId, s, ibpMapData.(*graphicData.IBPGraphicStorage))
|
||||
initIBPUid(gus, city, lineId, s, getStorageIBPMapData(s.RefIbpMapCode))
|
||||
}
|
||||
return gus
|
||||
}
|
||||
|
||||
// 处理IBP盘信息
|
||||
func initIBPUid(gus *stationUidStructure, city, lineId string, station *graphicData.Station, data *graphicData.IBPGraphicStorage) {
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
// 设备所属组合
|
||||
refMap := make(map[string]string)
|
||||
for _, r := range data.IbpRelatedDevices {
|
||||
@ -196,24 +190,28 @@ func initIBPUid(gus *stationUidStructure, city, lineId string, station *graphicD
|
||||
for _, d := range data.IbpButtons { // ibp按钮
|
||||
uidMap[d.Common.Id] = &elementIdStructure{
|
||||
CommonId: d.Common.Id,
|
||||
Code: d.Code,
|
||||
Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)),
|
||||
}
|
||||
}
|
||||
for _, d := range data.IbpKeys { // ibp钥匙
|
||||
uidMap[d.Common.Id] = &elementIdStructure{
|
||||
CommonId: d.Common.Id,
|
||||
Code: d.Code,
|
||||
Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)),
|
||||
}
|
||||
}
|
||||
for _, d := range data.IbpAlarms { // ibp报警器
|
||||
uidMap[d.Common.Id] = &elementIdStructure{
|
||||
CommonId: d.Common.Id,
|
||||
Code: d.Code,
|
||||
Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)),
|
||||
}
|
||||
}
|
||||
for _, d := range data.IbpLights { // ibp指示灯
|
||||
uidMap[d.Common.Id] = &elementIdStructure{
|
||||
CommonId: d.Common.Id,
|
||||
Code: d.Code,
|
||||
Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)),
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package memory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -213,6 +214,10 @@ func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *graphicD
|
||||
for _, signal := range repo.Signals {
|
||||
signalMap[signal.Id] = signal
|
||||
}
|
||||
stationMap := make(map[string]*proto.Station)
|
||||
for _, station := range repo.Stations {
|
||||
stationMap[station.Id] = station
|
||||
}
|
||||
for _, relationship := range relayGi.DeviceRelateRelayList {
|
||||
switch relationship.DeviceType {
|
||||
case graphicData.RelatedRef_Turnout:
|
||||
@ -253,6 +258,24 @@ func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *graphicD
|
||||
ComponentIds: componentIds,
|
||||
})
|
||||
}
|
||||
case graphicData.RelatedRef_station:
|
||||
station := stationMap[GenerateElementUid(city, lineId, nil, relationship.Code)]
|
||||
if station == nil {
|
||||
continue
|
||||
}
|
||||
for _, group := range relationship.Combinationtypes {
|
||||
d := &proto.ElectronicGroup{Code: group.Code}
|
||||
for _, relayId := range group.RefRelays {
|
||||
if uidsMap.RelayIds[relayId] == nil {
|
||||
continue
|
||||
}
|
||||
d.Components = append(d.Components, &proto.ElectronicComponent{
|
||||
Id: uidsMap.RelayIds[relayId].Uid,
|
||||
DeviceType: proto.DeviceType_DeviceType_Relay,
|
||||
})
|
||||
}
|
||||
station.ElectronicGroup = append(station.ElectronicGroup, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -410,6 +433,133 @@ func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphi
|
||||
SameTrend: data.SameTrend,
|
||||
})
|
||||
}
|
||||
// 初始化站场图按钮
|
||||
for _, data := range storage.EsbButtons {
|
||||
repo.Buttons = append(repo.Buttons, &proto.Button{
|
||||
Id: uidsMap.ButtonIds[data.Common.Id].Uid,
|
||||
Code: data.Code,
|
||||
ButtonType: proto.Button_Reset_Press,
|
||||
})
|
||||
}
|
||||
// 车站关联关系
|
||||
relateMap := make(map[string]*graphicData.StationRelateDevice)
|
||||
for _, data := range storage.StationRelateDeviceList {
|
||||
relateMap[data.Code] = data
|
||||
}
|
||||
// 处理车站信息
|
||||
for _, data := range storage.Stations {
|
||||
station := &proto.Station{
|
||||
Id: uidsMap.StationIds[data.Common.Id].Uid,
|
||||
Code: data.Code,
|
||||
}
|
||||
// 关联车站的设备
|
||||
refs, ok := relateMap[data.Code]
|
||||
if ok {
|
||||
for _, c := range refs.Combinationtypes {
|
||||
group := &proto.ElectronicGroup{Code: c.Code}
|
||||
for _, d := range c.RefDevices {
|
||||
var comp *proto.ElectronicComponent
|
||||
if uidsMap.ButtonIds[d] != nil { // 目前只处理按钮
|
||||
comp = &proto.ElectronicComponent{
|
||||
Id: uidsMap.ButtonIds[d].Uid,
|
||||
DeviceType: proto.DeviceType_DeviceType_Button,
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
group.Components = append(group.Components, comp)
|
||||
}
|
||||
station.ElectronicGroup = append(station.ElectronicGroup, group)
|
||||
}
|
||||
}
|
||||
// 处理车站关联IBP的设备
|
||||
handlerIBPDeviceToStation(uidsMap, station, repo, data.RefIbpMapCode)
|
||||
repo.Stations = append(repo.Stations, station)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 将IBP的设备关联到车站中
|
||||
func handlerIBPDeviceToStation(uidsMap *stationUidStructure, station *proto.Station, repo *proto.Repository, ibpMap string) {
|
||||
storage := getStorageIBPMapData(ibpMap)
|
||||
if storage == nil {
|
||||
return
|
||||
}
|
||||
ibpIdMap := uidsMap.IBPIds[station.Code] // 车站对应的UID集合
|
||||
typeMap := make(map[string]proto.DeviceType) // 对应的设备类型
|
||||
for _, data := range storage.IbpButtons { // 处理按钮
|
||||
buttonType := proto.Button_NO_Reset_Press
|
||||
if data.IsSelfReset {
|
||||
buttonType = proto.Button_Reset_Press
|
||||
}
|
||||
b := &proto.Button{
|
||||
Id: ibpIdMap[data.Common.Id].Uid,
|
||||
Code: data.Code,
|
||||
ButtonType: buttonType,
|
||||
}
|
||||
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Button
|
||||
repo.Buttons = append(repo.Buttons, b)
|
||||
}
|
||||
for _, data := range storage.IbpKeys { // 钥匙
|
||||
b := &proto.Button{
|
||||
Id: ibpIdMap[data.Common.Id].Uid,
|
||||
Code: data.Code,
|
||||
ButtonType: proto.Button_Key_Knob,
|
||||
}
|
||||
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Button
|
||||
repo.Buttons = append(repo.Buttons, b)
|
||||
}
|
||||
for _, data := range storage.IbpAlarms { // 报警器
|
||||
b := &proto.Alarm{
|
||||
Id: ibpIdMap[data.Common.Id].Uid,
|
||||
Code: data.Code,
|
||||
}
|
||||
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Alarm
|
||||
repo.Alarms = append(repo.Alarms, b)
|
||||
}
|
||||
for _, data := range storage.IbpLights { // 指示灯
|
||||
b := &proto.Light{
|
||||
Id: ibpIdMap[data.Common.Id].Uid,
|
||||
Code: data.Code,
|
||||
Aspect: converIbpLightAspect(data.Color),
|
||||
}
|
||||
typeMap[data.Common.Id] = proto.DeviceType_DeviceType_Light
|
||||
repo.Lights = append(repo.Lights, b)
|
||||
}
|
||||
// 组信息
|
||||
for _, data := range storage.IbpRelatedDevices {
|
||||
for _, c := range data.Combinationtypes {
|
||||
group := &proto.ElectronicGroup{Code: c.Code}
|
||||
for _, d := range c.RefDevices {
|
||||
deviceType, ok := typeMap[d]
|
||||
if !ok {
|
||||
slog.Debug("IBP组合类型类型不确定id:%s", d)
|
||||
continue
|
||||
}
|
||||
group.Components = append(group.Components, &proto.ElectronicComponent{
|
||||
Id: ibpIdMap[d].Uid,
|
||||
DeviceType: deviceType,
|
||||
})
|
||||
}
|
||||
station.ElectronicGroup = append(station.ElectronicGroup, group)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将IBP的灯颜色转换成repo灯颜色
|
||||
func converIbpLightAspect(color graphicData.IbpLight_IbpLightColor) proto.Light_LightAspect {
|
||||
switch color {
|
||||
case graphicData.IbpLight_white:
|
||||
return proto.Light_B
|
||||
case graphicData.IbpLight_red:
|
||||
return proto.Light_H
|
||||
case graphicData.IbpLight_green:
|
||||
return proto.Light_L
|
||||
case graphicData.IbpLight_blue:
|
||||
return proto.Light_A
|
||||
default:
|
||||
panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "未知的灯颜色类型" + color.String()})
|
||||
}
|
||||
}
|
||||
|
||||
func converCheckPointUid(data *proto.CheckPoint, uidsMap *stationUidStructure) *proto.CheckPoint {
|
||||
|
@ -208,4 +208,5 @@ gorm.io/driver/clickhouse v0.5.0/go.mod h1:cIKAlFw+IVK75g0bDcm0M9qRA4EAgsn23Si+z
|
||||
gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg=
|
||||
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
20
vobc/udp.go
20
vobc/udp.go
@ -113,16 +113,13 @@ func RunUdpServer() {
|
||||
}
|
||||
|
||||
// 发送列车速度到VOBC
|
||||
func SendTrainSpeedTask(speed float64) error {
|
||||
func SendTrainSpeedTask(trainInfo *SendTrainInfo) error {
|
||||
if running {
|
||||
return nil
|
||||
}
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
trainInfo := &SendTrainInfo{
|
||||
LifeSignal: sendTrainLifeSignal,
|
||||
Speed: uint16(speed),
|
||||
}
|
||||
trainInfo.LifeSignal = sendTrainLifeSignal
|
||||
err := sendVobcMsg(encoderVobcTrainInfo(trainInfo))
|
||||
if err != nil {
|
||||
slog.Error("发送Vobc信息失败", err)
|
||||
@ -167,5 +164,18 @@ func encoderVobcTrainInfo(info *SendTrainInfo) []byte {
|
||||
var data []byte
|
||||
data = binary.BigEndian.AppendUint16(data, info.LifeSignal)
|
||||
data = binary.BigEndian.AppendUint16(data, info.Speed)
|
||||
if info.Upslope {
|
||||
data = append(data, 1<<7)
|
||||
} else {
|
||||
data = append(data, 0)
|
||||
}
|
||||
// 中间预留一位
|
||||
data = append(data, 0)
|
||||
data = binary.BigEndian.AppendUint16(data, info.Acceleration) // 加速度 100 = 1 m/s*s
|
||||
data = binary.BigEndian.AppendUint16(data, info.TotalResistance) // 实际运行阻力 100 = 1KN
|
||||
data = binary.BigEndian.AppendUint16(data, info.AirResistance) // 空气阻力 100 = 1KN
|
||||
data = binary.BigEndian.AppendUint16(data, info.SlopeResistance) // 坡道阻力 100 = 1KN
|
||||
data = binary.BigEndian.AppendUint16(data, info.CurveResistance) // 曲线阻力 100 = 1KN
|
||||
data = binary.BigEndian.AppendUint16(data, info.Slope) // 坡度值 1= 1‰
|
||||
return data
|
||||
}
|
||||
|
@ -96,4 +96,18 @@ type SendTrainInfo struct {
|
||||
LifeSignal uint16
|
||||
// 列车速度 10=1km/h
|
||||
Speed uint16
|
||||
// 上坡
|
||||
Upslope bool
|
||||
// 坡度值 1= 1‰
|
||||
Slope uint16
|
||||
// 加速度 100 = 1 m/s*s
|
||||
Acceleration uint16
|
||||
// 实际运行阻力 100 = 1KN
|
||||
TotalResistance uint16
|
||||
// 空气阻力 100 = 1KN
|
||||
AirResistance uint16
|
||||
// 坡道阻力 100 = 1KN
|
||||
SlopeResistance uint16
|
||||
// 曲线阻力 100 = 1KN
|
||||
CurveResistance uint16
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user