停车点构建proto

This commit is contained in:
tiger_zhou 2024-09-25 11:19:18 +08:00
parent 3a22950790
commit 2463edd996
11 changed files with 130 additions and 109 deletions

View File

@ -420,7 +420,7 @@ func removeAllTrain(c *gin.Context) {
} }
slog.Debug("ATS测试仿真-移除所有列车,请求:", rt) slog.Debug("ATS测试仿真-移除所有列车,请求:", rt)
simulation := checkDeviceDataAndReturn(rt.SimulationId) simulation := checkDeviceDataAndReturn(rt.SimulationId)
memory.RemoveAllTrain(simulation) memory.RemoveAllTrain(simulation, false)
//TODO 后续调用列车删除操作 //TODO 后续调用列车删除操作
c.JSON(http.StatusOK, "ok") c.JSON(http.StatusOK, "ok")
} }
@ -448,7 +448,7 @@ func removeTrain(c *gin.Context) {
} }
slog.Debug("ATS测试仿真-移除列车,请求:", rt) slog.Debug("ATS测试仿真-移除列车,请求:", rt)
simulation := checkDeviceDataAndReturn(rt.SimulationId) simulation := checkDeviceDataAndReturn(rt.SimulationId)
memory.RemoveTrainState(simulation, rt.TrainId) memory.RemoveTrainState(simulation, rt.TrainId, false)
//TODO 后续调用列车删除操作 //TODO 后续调用列车删除操作
c.JSON(http.StatusOK, "ok") c.JSON(http.StatusOK, "ok")
} }

View File

@ -4,7 +4,6 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"log/slog" "log/slog"
"strconv"
) )
// 应答器数据编解码器 // 应答器数据编解码器
@ -84,8 +83,8 @@ func checkCb(bits1023 []byte) error {
cb := getRange(bits1023, 109, 107) cb := getRange(bits1023, 109, 107)
for i, v := range cb { for i, v := range cb {
n := 109 - i n := 109 - i
name := "b" + strconv.Itoa(109-i) //name := "b" + strconv.Itoa(109-i)
slog.Info("cb", name, v) //slog.Info("cb", name, v)
if n == 109 && v == 1 { if n == 109 && v == 1 {
return buildError("控制位cb错误b109应该为0实际为1") return buildError("控制位cb错误b109应该为0实际为1")
} else if n == 108 && v == 1 { } else if n == 108 && v == 1 {
@ -131,7 +130,7 @@ func calculateS(sb []byte) uint32 {
B := ToValLeftMsb(sb) B := ToValLeftMsb(sb)
const A uint64 = 2801775573 const A uint64 = 2801775573
S := uint32((A * uint64(B)) % (1 << 32)) S := uint32((A * uint64(B)) % (1 << 32))
slog.Info("由12位加扰位计算得到整数S", "B", B, "S", S, "Sb", fmt.Sprintf("%032b", S)) //slog.Info("由12位加扰位计算得到整数S", "B", B, "S", S, "Sb", fmt.Sprintf("%032b", S))
return S return S
} }

View File

@ -1,10 +1,5 @@
package balisecodec package balisecodec
import (
"fmt"
"log/slog"
)
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位MSB的无符号整数数组除了第一个10位值其余值求和然后循环2的10次方次与其他值求和结果相加后模2的10次方若结果和第一个10位值相同则结束此值即为原始的第一个10位值将此值替换为第一个10位二进制数组依然是左边为MSB // 将830位的二进制数组以10位为单位组成一个左边为最高有效位MSB的无符号整数数组除了第一个10位值其余值求和然后循环2的10次方次与其他值求和结果相加后模2的10次方若结果和第一个10位值相同则结束此值即为原始的第一个10位值将此值替换为第一个10位二进制数组依然是左边为MSB
func revertFirst10Bits(b []byte) []byte { func revertFirst10Bits(b []byte) []byte {
if len(b) != 830 { if len(b) != 830 {
@ -37,7 +32,7 @@ func revertFirst10Bits(b []byte) []byte {
break break
} }
} }
slog.Info("还原第一个10位值", "sum", sum, "bits[0]", w10s[0], "bits[0]b", fmt.Sprintf("%010b", w10s[0])) //slog.Info("还原第一个10位值", "sum", sum, "bits[0]", w10s[0], "bits[0]b", fmt.Sprintf("%010b", w10s[0]))
bits := make([]byte, 830) bits := make([]byte, 830)
// 将整个10位数组转换为二进制数组依然是MSB // 将整个10位数组转换为二进制数组依然是MSB
u0bits := ToBitsLeftMsb(int(w10s[0]), 10) u0bits := ToBitsLeftMsb(int(w10s[0]), 10)

View File

@ -20,10 +20,11 @@ import (
) )
type BtmVobcManage interface { type BtmVobcManage interface {
SemiPhysicalBaseManager
GetBtmVobcConfig() config.BtmVobcConfig GetBtmVobcConfig() config.BtmVobcConfig
GetAllTrain() []*state_proto.TrainState //GetAllTrain() []*state_proto.TrainState
GetConnVobcTrain() *state_proto.TrainState
} }
type BtmVobcService interface { type BtmVobcService interface {
Start(btmVobcManage BtmVobcManage) Start(btmVobcManage BtmVobcManage)
@ -57,13 +58,13 @@ func BtmDefault() BtmVobcService {
func (b *BtmVobcClient) Start(btmVobcManage BtmVobcManage) { func (b *BtmVobcClient) Start(btmVobcManage BtmVobcManage) {
cfg := btmVobcManage.GetBtmVobcConfig() cfg := btmVobcManage.GetBtmVobcConfig()
if !cfg.Open { if !cfg.Open {
slog.Info("11号线 btm vobc配置未开启...") slog.Info("11号线 btm 配置未开启...")
return return
} }
udpServer := udp.NewServer(fmt.Sprintf("%v:%d", cfg.LocalUdpIp, cfg.LocalUdpPort), b.handleBtmVobcFrames) udpServer := udp.NewServer(fmt.Sprintf("%v:%d", cfg.LocalUdpIp, cfg.LocalUdpPort), b.handleBtmVobcFrames)
err := udpServer.Listen() err := udpServer.Listen()
if err != nil { if err != nil {
slog.Error("11号线 btm VOBC 服务启动失败...") slog.Error("11号线 btm 服务启动失败...")
return return
} }
// //

View File

@ -2,6 +2,7 @@ package semi_physical_train
import ( import (
"fmt" "fmt"
"joylink.club/bj-rtsts-server/dto/state_proto"
"sync" "sync"
"joylink.club/bj-rtsts-server/config" "joylink.club/bj-rtsts-server/config"
@ -20,10 +21,14 @@ type SemiPhysicalTrain interface {
// 发送列车控制消息 // 发送列车控制消息
SendTrainControlMessage(info *message.DynamicsTrainInfo) SendTrainControlMessage(info *message.DynamicsTrainInfo)
} }
type SemiPhysicalBaseManager interface {
GetConnVobcTrain() *state_proto.TrainState
}
type SemiPhysicalMessageManager interface { type SemiPhysicalMessageManager interface {
SemiPhysicalBaseManager
// 处理半实物仿真列车控制消息 // 处理半实物仿真列车控制消息
HandleSemiPhysicalTrainControlMsg(b []byte) HandleSemiPhysicalTrainControlMsg(b []byte)
HandleSemiPhysicalTrainControlMsg2(b []byte)
// 获取半实物启动参数 // 获取半实物启动参数
GetSemiPhysicalRunConfig() *config.VobcConfig GetSemiPhysicalRunConfig() *config.VobcConfig
} }
@ -88,6 +93,7 @@ func (s *semiPhysicalTrainImpl) Start(manager SemiPhysicalMessageManager) {
} }
func (s *semiPhysicalTrainImpl) Stop() { func (s *semiPhysicalTrainImpl) Stop() {
initMutex.Lock() initMutex.Lock()
defer initMutex.Unlock() defer initMutex.Unlock()
s.udpDelayRecorder.Stop() s.udpDelayRecorder.Stop()

View File

@ -126,7 +126,7 @@ func (d *trainPcSimService) findTrainConnForPort2(sta *state_proto.TrainState, t
return rd, nil return rd, nil
} }
} }
return nil, fmt.Errorf("") return nil, fmt.Errorf("未找到对应端口的列车 对应的端口:%v", trainClientPort.String())
} }
func (d *trainPcSimService) findTrainAllConn(sta *state_proto.TrainState) []*TrainPcReciverData { func (d *trainPcSimService) findTrainAllConn(sta *state_proto.TrainState) []*TrainPcReciverData {
@ -178,14 +178,13 @@ func (d *trainPcSimService) TrainPluseCount(sta *state_proto.TrainState, h1, h2,
return return
default: default:
} }
//slog.Info(fmt.Sprintf("接受列车速度:%v", h1))
for _, sd := range d.findTrainAllConn(sta) { for _, sd := range d.findTrainAllConn(sta) {
if sd.speedPlace != nil { if sd.speedPlace != nil {
sd.speedPlace.PulseCount1 += sta.DynamicState.Displacement sd.speedPlace.PulseCount1 += sta.DynamicState.Displacement
} }
} }
for _, pc := range sta.PulseCountMap { for _, pc := range sta.PulseCountMap {
if sta.TrainRunUp { if sta.TrainRunUp {
if sta.TrainEndsA.SpeedSensorEnableA || sta.TrainEndsA.SpeedSensorEnableB { if sta.TrainEndsA.SpeedSensorEnableA || sta.TrainEndsA.SpeedSensorEnableB {
pc.PulseCount1 = pluseCountSpeed(sta.WheelDiameter, h1) pc.PulseCount1 = pluseCountSpeed(sta.WheelDiameter, h1)
@ -259,7 +258,6 @@ func (d *trainPcSimService) initConn2(clientKey string) error {
return sys_error.New(fmt.Sprintf("配置:%v 端口B连接失败", clientKey)) return sys_error.New(fmt.Sprintf("配置:%v 端口B连接失败", clientKey))
} }
if rd1.success { if rd1.success {
//rd1.aPort = true
rd1.RealTrainPort = state_proto.TrainState_PORT_A rd1.RealTrainPort = state_proto.TrainState_PORT_A
} }
if rd2.success { if rd2.success {
@ -279,7 +277,6 @@ func (d *trainPcSimService) connServer(open bool, ip string, port uint32, rd *Tr
return nil return nil
} }
addr := fmt.Sprintf("%v:%v", ip, port) addr := fmt.Sprintf("%v:%v", ip, port)
//slog.Info(addr, "连接.,...")
client2, err := tcp.StartTcpClient(addr, rd.receiverDataHandle, rd.readError) client2, err := tcp.StartTcpClient(addr, rd.receiverDataHandle, rd.readError)
if err != nil { if err != nil {
return sys_error.New(fmt.Sprintf("车载atp连接失败,add:%v ,message:%v", addr, err)) return sys_error.New(fmt.Sprintf("车载atp连接失败,add:%v ,message:%v", addr, err))
@ -356,22 +353,18 @@ func (d *trainPcSimService) CreateOrRemoveTrain(train *state_proto.TrainState, i
} }
msg := &message.TrainPcSimBaseMessage{Data: data, Type: message.RECIVE_TRAIN_CREATE_REMOVE} msg := &message.TrainPcSimBaseMessage{Data: data, Type: message.RECIVE_TRAIN_CREATE_REMOVE}
rds := d.newPcSimclientMap3[clientKey] rds := d.newPcSimclientMap3[clientKey]
if rds != nil {
for index, rd := range rds { for index, rd := range rds {
slog.Info(fmt.Sprintf("index%v---rd client%v clientnil :%vsucc:%v", index, rd.tcpClient, rd.tcpClient == nil, rd.success))
if rd != nil && rd.success { if rd != nil && rd.success {
slog.Info(fmt.Sprintf("index%v---rd client%v clientnil :%v", index, rd.tcpClient, rd.tcpClient == nil))
initTrainErr := d.initTrain(rd, train, isCreate, msg) initTrainErr := d.initTrain(rd, train, isCreate, msg)
if !isCreate {
d.newCloseConn(clientKey)
}
if initTrainErr != nil { if initTrainErr != nil {
return initTrainErr return initTrainErr
} }
} }
} }
if !isCreate {
d.newCloseConn(clientKey)
} }
return nil return nil
} }
func (d *trainPcSimService) initTrain(rd *TrainPcReciverData, train *state_proto.TrainState, isCreate bool, trains *message.TrainPcSimBaseMessage) error { func (d *trainPcSimService) initTrain(rd *TrainPcReciverData, train *state_proto.TrainState, isCreate bool, trains *message.TrainPcSimBaseMessage) error {
@ -424,7 +417,6 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
trains := d.trainPcSimManage.GetConnTrain2() trains := d.trainPcSimManage.GetConnTrain2()
for _, train := range trains { for _, train := range trains {
if train.ConnState.Conn {
for numKey, pc := range train.PulseCountMap { for numKey, pc := range train.PulseCountMap {
trainPort := state_proto.TrainState_TrainPort(numKey) trainPort := state_proto.TrainState_TrainPort(numKey)
trainClient, _ := d.findTrainConnForPort2(train, trainPort) trainClient, _ := d.findTrainConnForPort2(train, trainPort)
@ -439,6 +431,11 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
if trainClient.ConnError() { if trainClient.ConnError() {
continue continue
} }
/*ds := &strings.Builder{}
for i, s := range pc.PulseCount3 {
ds.WriteString(fmt.Sprintf("i:%v,s:%v ", i, s))
}
slog.Info(fmt.Sprintf("列车速度统计 列车id:%v 列车方向:%v ,列车速度信息:%v", train.Id, trainClient.RealTrainPort.String(), ds.String()))*/
s1, speed := d.pluseSpeed(pc, train.WheelDiameter) s1, speed := d.pluseSpeed(pc, train.WheelDiameter)
runDir := d.trainDirection(speed, train, trainClient.RealTrainPort) runDir := d.trainDirection(speed, train, trainClient.RealTrainPort)
disPluse := pluseCountSpeed(train.WheelDiameter, trainClient.speedPlace.PulseCount1) disPluse := pluseCountSpeed(train.WheelDiameter, trainClient.speedPlace.PulseCount1)
@ -454,7 +451,6 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
} }
} }
} }
}
} }
func (d *trainPcSimService) trainDirection(speed float32, train *state_proto.TrainState, clientPort state_proto.TrainState_TrainPort) uint16 { func (d *trainPcSimService) trainDirection(speed float32, train *state_proto.TrainState, clientPort state_proto.TrainState_TrainPort) uint16 {

View File

@ -337,6 +337,8 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
} }
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort) //slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
// 修改world中的列车位置 // 修改world中的列车位置
slog.Debug("处理动力学转换后的消息", "number", info.Number, "up", info.Up, "Link", info.Link, "车头位置", id, "偏移", offset, "车尾位置:", tailDeviceId, "车尾偏移:", tailOffset, "车头linkOffset", outLinkOffset, "车位linkOffset", tailLinkOffset)
handleTrainPositionFromDynamic(vs, info, sta, outLinkId, outLinkOffset, tailLinkId, tailLinkOffset) handleTrainPositionFromDynamic(vs, info, sta, outLinkId, outLinkOffset, tailLinkId, tailLinkOffset)
//修改列车激活方向 //修改列车激活方向
updateTrainActiveDirFromDynamic(vs, info, sta, id, port, trainHeadActUp) updateTrainActiveDirFromDynamic(vs, info, sta, id, port, trainHeadActUp)
@ -460,7 +462,7 @@ func pluseCount(sta *state_proto.TrainState, h1, h2, t1, t2 float32) {
train_pc_sim.Default().TrainPluseCount(sta, h1, h2, t1, t2) train_pc_sim.Default().TrainPluseCount(sta, h1, h2, t1, t2)
} }
func RemoveAllTrain(vs *VerifySimulation) { func RemoveAllTrain(vs *VerifySimulation, realRemove bool) {
allTrainMap := &vs.Memory.Status.TrainStateMap allTrainMap := &vs.Memory.Status.TrainStateMap
if allTrainMap == nil { if allTrainMap == nil {
slog.Info("当前没有列车不能执行") slog.Info("当前没有列车不能执行")
@ -468,7 +470,7 @@ func RemoveAllTrain(vs *VerifySimulation) {
} }
allTrainMap.Range(func(k any, t any) bool { allTrainMap.Range(func(k any, t any) bool {
id := k.(string) id := k.(string)
RemoveTrainState(vs, id) RemoveTrainState(vs, id, realRemove)
return true return true
}) })
} }
@ -500,18 +502,22 @@ func removeTrain(vs *VerifySimulation, trainId string, train *state_proto.TrainS
return fi.RemoveTrainFromWorld(vs.World, trainId) return fi.RemoveTrainFromWorld(vs.World, trainId)
} }
func RemoveTrainState(vs *VerifySimulation, id string) { func RemoveTrainState(vs *VerifySimulation, id string, realRemove bool) {
allTrainMap := &vs.Memory.Status.TrainStateMap allTrainMap := &vs.Memory.Status.TrainStateMap
d, ok := allTrainMap.Load(id) d, ok := allTrainMap.Load(id)
if ok { if ok {
t := d.(*state_proto.TrainState) t := d.(*state_proto.TrainState)
err := removeTrain(vs, id, t) err := removeTrain(vs, id, t)
t.VobcState.VobcBtmInfo = nil t.VobcState.VobcBtmInfo = nil
//clearTrainVobcBtmState(vs, id)
if err != nil { if err != nil {
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()}) panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
} }
if realRemove {
allTrainMap.Delete(id)
} else {
allTrainMap.Store(id, t) allTrainMap.Store(id, t)
}
} else { } else {
panic(fmt.Sprintf("列车【%s】不存在", id)) panic(fmt.Sprintf("列车【%s】不存在", id))
} }
@ -525,14 +531,3 @@ func calcTrailTailOffset(headerOffset, length int64, up bool) (calctailOffset in
} }
return return
} }
func clearTrainVobcBtmState(vs *VerifySimulation, id string) {
//allTrainMap := &vs.Memory.Status.TrainStateMap
//d, ok := allTrainMap.Load(id)
//if !ok {
// slog.Error(fmt.Sprintf("vobc btm 清空操作 列车【%s】不存在", id))
// return
//}
//t := d.(*state_proto.TrainState)
//t.VobcBtm.History = nil
}

View File

@ -380,34 +380,6 @@ func speedParse(speed float32) int32 {
return int32(math.Abs(float64(speed * 3.6 * 100))) return int32(math.Abs(float64(speed * 3.6 * 100)))
} }
// 处理半实物仿真列车控制消息
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg(b []byte) {
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
train := value.(*state_proto.TrainState)
if !train.Show { // 下线列车
return true
}
connState := train.ConnState
if connState.Conn == true && connState.ConnType == state_proto.TrainConnState_VOBC {
/*trainId, err := strconv.Atoi(train.Id)
if err != nil {
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
}*/
// 存放至列车中
//接收半实物列车控制不单独发送动力学,由动力学统一发送
//d := append(b, uint8(trainId))
//dynamics.Default().SendTrainControlMessage(d)
controlMessage := &message.TrainControlMsg{}
controlMessage.Decode(b)
controlMessage.TrainId = train.Id
controlMessage.FromVobc = true
train.VobcState = controlMessage.ControlInfo
return false
}
return true
})
}
func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg { func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg {
cms := make([]message.TrainControlMsg, 0) cms := make([]message.TrainControlMsg, 0)
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool { s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
@ -426,11 +398,6 @@ func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg
return cms return cms
} }
// 获取半实物运行配置信息
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
return &s.runConfig.Vobc
}
// 处理接到的联锁消息 // 处理接到的联锁消息
func (s *VerifySimulation) HandleInterlockDriverInfo(code string, driveBytes []byte) { func (s *VerifySimulation) HandleInterlockDriverInfo(code string, driveBytes []byte) {
wd := entity.GetWorldData(s.World) wd := entity.GetWorldData(s.World)
@ -1151,6 +1118,17 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
} }
repo.CheckPoints = append(repo.CheckPoints, cp) repo.CheckPoints = append(repo.CheckPoints, cp)
} }
//列车停车点
for _, sp := range storage.StopPositions {
id := GetMapElementId(sp.Common)
psp := &proto.StopPosition{Id: id, Km: convertKm(sp.KilometerSystem)}
switch sp.GetRefDev().DeviceType {
case data_proto.RelatedRef_Section:
psp.SectionId = uidsMap.PhysicalSectionIds[sp.GetRefDev().Id].Uid
}
repo.StopPosition = append(repo.StopPosition, psp)
}
//物理区段 //物理区段
for _, data := range storage.Section { for _, data := range storage.Section {
var turnoutUids []string var turnoutUids []string

View File

@ -0,0 +1,50 @@
package memory
import (
"joylink.club/bj-rtsts-server/config"
"joylink.club/bj-rtsts-server/dto/state_proto"
"joylink.club/bj-rtsts-server/third_party/message"
)
// 获取半实物运行配置信息
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
return &s.runConfig.Vobc
}
// 处理半实物仿真列车控制消息
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg(b []byte) {
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
train := value.(*state_proto.TrainState)
if !train.Show { // 下线列车
return true
}
connState := train.ConnState
if connState.Conn == true && connState.ConnType == state_proto.TrainConnState_VOBC {
/*trainId, err := strconv.Atoi(train.Id)
if err != nil {
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
}*/
// 存放至列车中
//接收半实物列车控制不单独发送动力学,由动力学统一发送
//d := append(b, uint8(trainId))
//dynamics.Default().SendTrainControlMessage(d)
controlMessage := &message.TrainControlMsg{}
controlMessage.Decode(b)
controlMessage.TrainId = train.Id
controlMessage.FromVobc = true
train.VobcState = controlMessage.ControlInfo
return false
}
return true
})
}
// 处理半实物仿真列车控制消息
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg2(b []byte) {
//train := s.GetConnVobcTrain()
}
func aaByte1() {
}

View File

@ -90,8 +90,9 @@ func DestroySimulation(simulationId string) {
if !e { if !e {
return return
} }
simulationMap.Delete(simulationId)
simulationInfo := s.(*memory.VerifySimulation) simulationInfo := s.(*memory.VerifySimulation)
memory.RemoveAllTrain(simulationInfo, true)
simulationMap.Delete(simulationId)
// simulationInfo.Destroy() // simulationInfo.Destroy()
// 停止ecs world // 停止ecs world
simulationInfo.World.Close() simulationInfo.World.Close()