停车点构建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)
simulation := checkDeviceDataAndReturn(rt.SimulationId)
memory.RemoveAllTrain(simulation)
memory.RemoveAllTrain(simulation, false)
//TODO 后续调用列车删除操作
c.JSON(http.StatusOK, "ok")
}
@ -448,7 +448,7 @@ func removeTrain(c *gin.Context) {
}
slog.Debug("ATS测试仿真-移除列车,请求:", rt)
simulation := checkDeviceDataAndReturn(rt.SimulationId)
memory.RemoveTrainState(simulation, rt.TrainId)
memory.RemoveTrainState(simulation, rt.TrainId, false)
//TODO 后续调用列车删除操作
c.JSON(http.StatusOK, "ok")
}

View File

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

View File

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

View File

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

View File

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

View File

@ -126,7 +126,7 @@ func (d *trainPcSimService) findTrainConnForPort2(sta *state_proto.TrainState, t
return rd, nil
}
}
return nil, fmt.Errorf("")
return nil, fmt.Errorf("未找到对应端口的列车 对应的端口:%v", trainClientPort.String())
}
func (d *trainPcSimService) findTrainAllConn(sta *state_proto.TrainState) []*TrainPcReciverData {
@ -178,14 +178,13 @@ func (d *trainPcSimService) TrainPluseCount(sta *state_proto.TrainState, h1, h2,
return
default:
}
//slog.Info(fmt.Sprintf("接受列车速度:%v", h1))
for _, sd := range d.findTrainAllConn(sta) {
if sd.speedPlace != nil {
sd.speedPlace.PulseCount1 += sta.DynamicState.Displacement
}
}
for _, pc := range sta.PulseCountMap {
if sta.TrainRunUp {
if sta.TrainEndsA.SpeedSensorEnableA || sta.TrainEndsA.SpeedSensorEnableB {
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))
}
if rd1.success {
//rd1.aPort = true
rd1.RealTrainPort = state_proto.TrainState_PORT_A
}
if rd2.success {
@ -279,7 +277,6 @@ func (d *trainPcSimService) connServer(open bool, ip string, port uint32, rd *Tr
return nil
}
addr := fmt.Sprintf("%v:%v", ip, port)
//slog.Info(addr, "连接.,...")
client2, err := tcp.StartTcpClient(addr, rd.receiverDataHandle, rd.readError)
if err != nil {
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}
rds := d.newPcSimclientMap3[clientKey]
if rds != nil {
for index, rd := range rds {
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)
if !isCreate {
d.newCloseConn(clientKey)
}
if initTrainErr != nil {
return initTrainErr
}
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 {
initTrainErr := d.initTrain(rd, train, isCreate, msg)
if initTrainErr != nil {
return initTrainErr
}
}
}
if !isCreate {
d.newCloseConn(clientKey)
}
return nil
}
func (d *trainPcSimService) initTrain(rd *TrainPcReciverData, train *state_proto.TrainState, isCreate bool, trains *message.TrainPcSimBaseMessage) error {
@ -424,32 +417,35 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
trains := d.trainPcSimManage.GetConnTrain2()
for _, train := range trains {
if train.ConnState.Conn {
for numKey, pc := range train.PulseCountMap {
trainPort := state_proto.TrainState_TrainPort(numKey)
trainClient, _ := d.findTrainConnForPort2(train, trainPort)
if trainClient == nil {
for numKey, pc := range train.PulseCountMap {
trainPort := state_proto.TrainState_TrainPort(numKey)
trainClient, _ := d.findTrainConnForPort2(train, trainPort)
if trainClient == nil {
continue
}
if trainClient.success {
if trainClient.speedPlace == nil || trainClient.tcpClient == nil {
slog.Error(fmt.Sprintf("pc仿真速度位置脉冲对象为空 列车id:%v", train.Id))
continue
}
if trainClient.success {
if trainClient.speedPlace == nil || trainClient.tcpClient == nil {
slog.Error(fmt.Sprintf("pc仿真速度位置脉冲对象为空 列车id:%v", train.Id))
continue
}
if trainClient.ConnError() {
continue
}
s1, speed := d.pluseSpeed(pc, train.WheelDiameter)
runDir := d.trainDirection(speed, train, trainClient.RealTrainPort)
disPluse := pluseCountSpeed(train.WheelDiameter, trainClient.speedPlace.PulseCount1)
data := trainClient.speedPlace.Encode(runDir, s1, disPluse)
bm := &message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_LOCATION_INFO, Data: data}
dataCode := bm.Encode()
//slog.Info(fmt.Sprintf("发送列车速度位置,列车:%v,列车服务端:%v,列车速度:%v,计数脉冲: %v,累计里程: %v ,发送数据:%X", train.Id, trainClient.RealTrainPort.String(), speed, s1, trainClient.speedPlace.PulseCount1, dataCode))
err := trainClient.tcpClient.Send(dataCode)
if err != nil {
slog.Error(fmt.Sprintf("发送列车速度位置失败,列车:%v,发送数据:%v", train.Id, hex.EncodeToString(dataCode)))
}
if trainClient.ConnError() {
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)
runDir := d.trainDirection(speed, train, trainClient.RealTrainPort)
disPluse := pluseCountSpeed(train.WheelDiameter, trainClient.speedPlace.PulseCount1)
data := trainClient.speedPlace.Encode(runDir, s1, disPluse)
bm := &message.TrainPcSimBaseMessage{Type: message.SENDER_TRAIN_LOCATION_INFO, Data: data}
dataCode := bm.Encode()
//slog.Info(fmt.Sprintf("发送列车速度位置,列车:%v,列车服务端:%v,列车速度:%v,计数脉冲: %v,累计里程: %v ,发送数据:%X", train.Id, trainClient.RealTrainPort.String(), speed, s1, trainClient.speedPlace.PulseCount1, dataCode))
err := trainClient.tcpClient.Send(dataCode)
if err != nil {
slog.Error(fmt.Sprintf("发送列车速度位置失败,列车:%v,发送数据:%v", train.Id, hex.EncodeToString(dataCode)))
}
}
}

View File

@ -337,6 +337,8 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
}
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
// 修改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)
//修改列车激活方向
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)
}
func RemoveAllTrain(vs *VerifySimulation) {
func RemoveAllTrain(vs *VerifySimulation, realRemove bool) {
allTrainMap := &vs.Memory.Status.TrainStateMap
if allTrainMap == nil {
slog.Info("当前没有列车不能执行")
@ -468,7 +470,7 @@ func RemoveAllTrain(vs *VerifySimulation) {
}
allTrainMap.Range(func(k any, t any) bool {
id := k.(string)
RemoveTrainState(vs, id)
RemoveTrainState(vs, id, realRemove)
return true
})
}
@ -500,18 +502,22 @@ func removeTrain(vs *VerifySimulation, trainId string, train *state_proto.TrainS
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
d, ok := allTrainMap.Load(id)
if ok {
t := d.(*state_proto.TrainState)
err := removeTrain(vs, id, t)
t.VobcState.VobcBtmInfo = nil
//clearTrainVobcBtmState(vs, id)
if err != nil {
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
}
allTrainMap.Store(id, t)
if realRemove {
allTrainMap.Delete(id)
} else {
allTrainMap.Store(id, t)
}
} else {
panic(fmt.Sprintf("列车【%s】不存在", id))
}
@ -525,14 +531,3 @@ func calcTrailTailOffset(headerOffset, length int64, up bool) (calctailOffset in
}
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)))
}
// 处理半实物仿真列车控制消息
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 {
cms := make([]message.TrainControlMsg, 0)
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
@ -426,11 +398,6 @@ func (s *VerifySimulation) CollectTrainControlState() []message.TrainControlMsg
return cms
}
// 获取半实物运行配置信息
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
return &s.runConfig.Vobc
}
// 处理接到的联锁消息
func (s *VerifySimulation) HandleInterlockDriverInfo(code string, driveBytes []byte) {
wd := entity.GetWorldData(s.World)
@ -1151,6 +1118,17 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
}
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 {
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 {
return
}
simulationMap.Delete(simulationId)
simulationInfo := s.(*memory.VerifySimulation)
memory.RemoveAllTrain(simulationInfo, true)
simulationMap.Delete(simulationId)
// simulationInfo.Destroy()
// 停止ecs world
simulationInfo.World.Close()