2023-08-01 17:08:45 +08:00
|
|
|
|
package memory
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2024-01-17 17:02:17 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/dto/common_proto"
|
|
|
|
|
"joylink.club/bj-rtsts-server/service"
|
2023-12-05 09:37:34 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/can_btm"
|
2024-07-11 14:58:34 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
2023-10-12 10:10:23 +08:00
|
|
|
|
"log/slog"
|
2024-01-17 13:09:45 +08:00
|
|
|
|
"reflect"
|
2023-08-02 15:47:48 +08:00
|
|
|
|
"strconv"
|
2023-11-09 15:58:16 +08:00
|
|
|
|
"time"
|
2023-08-01 17:08:45 +08:00
|
|
|
|
|
2023-08-02 15:54:22 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/dto"
|
2023-11-09 17:54:31 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/sys_error"
|
2023-10-19 09:33:40 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/dynamics"
|
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
2023-11-09 15:58:16 +08:00
|
|
|
|
"joylink.club/rtsssimulation/fi"
|
2023-08-02 15:54:22 +08:00
|
|
|
|
|
2024-01-11 10:24:56 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/dto/data_proto"
|
|
|
|
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
2023-08-01 17:08:45 +08:00
|
|
|
|
)
|
|
|
|
|
|
2024-04-30 10:15:20 +08:00
|
|
|
|
const (
|
|
|
|
|
DEFULAT_TRAIN_LOAD = 160
|
|
|
|
|
DEFAULT_BRAKE_FORCE = 19040
|
|
|
|
|
)
|
|
|
|
|
|
2024-01-17 15:53:14 +08:00
|
|
|
|
func CreateMsgTrainConfig(trainId int, trainLen int64, configTrainData dto.ConfigTrainData) *message.TrainOperationConfig {
|
|
|
|
|
return &message.TrainOperationConfig{TrainIndex: trainId, Length: int(trainLen),
|
2024-01-18 17:17:48 +08:00
|
|
|
|
DavisParamA: configTrainData.DavisParamA, DavisParamB: configTrainData.DavisParamB,
|
|
|
|
|
DavisParamC: configTrainData.DavisParamC, CurveResistanceParamR1: configTrainData.CurveResistanceParamR1,
|
2024-01-17 15:53:14 +08:00
|
|
|
|
CurveResistanceParamR2: configTrainData.CurveResistanceParamR2, CurveResistanceParamR3: configTrainData.CurveResistanceParamR3,
|
|
|
|
|
CurveResistanceParamR4: configTrainData.CurveResistanceParamR4, RevolvingMassParam: configTrainData.RevolvingMassParam,
|
2024-01-29 14:22:12 +08:00
|
|
|
|
Jump: configTrainData.Jump, Slide: configTrainData.Slide,
|
|
|
|
|
SlipA: configTrainData.SlipA, SlipR: configTrainData.SlipR, SlipD: int(configTrainData.SlipD),
|
|
|
|
|
IdlingA: configTrainData.IdlingA, IdlingR: configTrainData.IdlingR, IdlingD: int(configTrainData.IdlingD),
|
2024-01-17 15:53:14 +08:00
|
|
|
|
StopSign: int(configTrainData.StopSign)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 增加列车状态
|
2024-01-17 17:02:17 +08:00
|
|
|
|
func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, configTrainData dto.ConfigTrainData, trainEndsA dto.ConfigTrainEnds,
|
2024-02-23 10:43:06 +08:00
|
|
|
|
trainEndsB dto.ConfigTrainEnds, mapId int32) *sys_error.BusinessError {
|
2024-01-17 15:53:14 +08:00
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
2024-02-23 10:43:06 +08:00
|
|
|
|
value, ok := allTrainMap.Load(status.Id)
|
2024-01-17 15:53:14 +08:00
|
|
|
|
if ok {
|
2024-02-23 10:43:06 +08:00
|
|
|
|
trainState := value.(*state_proto.TrainState)
|
|
|
|
|
if trainState.Show {
|
|
|
|
|
return sys_error.New(fmt.Sprintf("列车【%s】已存在", status.Id))
|
|
|
|
|
}
|
2024-01-17 15:53:14 +08:00
|
|
|
|
}
|
|
|
|
|
//向动力学发送初始化请求
|
|
|
|
|
trainIndex, _ := strconv.ParseUint(status.Id, 10, 16)
|
|
|
|
|
slog.Debug("添加列车", "trainIndex", trainIndex, "HeadDeviceId", status.HeadDeviceId, "HeadOffset", status.HeadOffset)
|
|
|
|
|
// 映射link、偏移量、运行方向
|
|
|
|
|
var uid string
|
|
|
|
|
if status.DevicePort == "" {
|
|
|
|
|
uid = QueryUidByMidAndComId(mapId, status.HeadDeviceId, &data_proto.Section{})
|
|
|
|
|
} else {
|
|
|
|
|
uid = QueryUidByMidAndComId(mapId, status.HeadDeviceId, &data_proto.Turnout{})
|
|
|
|
|
}
|
2024-05-20 15:21:22 +08:00
|
|
|
|
|
2024-01-17 15:53:14 +08:00
|
|
|
|
// 车头所在link、link上的偏移
|
|
|
|
|
linkId, loffset := QueryLinkAndOffsetByDevice(vs.Repo, uid, status.DevicePort, status.HeadOffset)
|
|
|
|
|
// link上的运行方向、设备上的运行方向
|
2024-05-20 15:21:22 +08:00
|
|
|
|
up, pointTo := QueryUpAndABByDevice(vs.Repo, uid, status.DevicePort, status.TrainRunUp)
|
|
|
|
|
//up, pointTo, _ = QueryDirectionAndABByDevice(vs.Repo, uid, status.DevicePort, status.TrainRunUp)
|
|
|
|
|
//fmt.Println(up2, pointTo2)
|
|
|
|
|
|
2024-01-17 15:53:14 +08:00
|
|
|
|
// 车头所在公里标
|
2024-05-20 15:21:22 +08:00
|
|
|
|
kilometer := CalcTrainKilometer(vs.Repo, uid, status.DevicePort, status.TrainRunUp, status.HeadOffset)
|
2024-01-17 15:53:14 +08:00
|
|
|
|
// 车尾相对车头link的偏移量
|
|
|
|
|
calctailOffset := calcTrailTailOffset(loffset, status.TrainLength, up)
|
|
|
|
|
// 车尾位置
|
2024-02-21 14:54:17 +08:00
|
|
|
|
tailLink, tailDeviceId, tailDevicePort, tailLOffset, tailDeviceOffset, _, e1 := CalcInitializeLink(vs, linkId, calctailOffset, up)
|
2024-01-17 15:53:14 +08:00
|
|
|
|
if e1 != nil {
|
|
|
|
|
panic(sys_error.New("添加列车失败,列车车尾占用位置计算出错", e1))
|
|
|
|
|
}
|
|
|
|
|
status.Up = up
|
2024-05-20 15:21:22 +08:00
|
|
|
|
status.DriftTo = pointTo
|
2024-01-17 15:53:14 +08:00
|
|
|
|
status.TrainKilometer = kilometer.Value
|
2024-03-19 11:00:19 +08:00
|
|
|
|
|
2024-01-17 15:53:14 +08:00
|
|
|
|
status.DynamicState = &state_proto.TrainDynamicState{
|
|
|
|
|
HeadLinkId: linkId,
|
|
|
|
|
HeadLinkOffset: loffset,
|
|
|
|
|
TailLinkId: tailLink,
|
|
|
|
|
TailLinkOffset: tailLOffset,
|
2024-05-20 15:21:22 +08:00
|
|
|
|
RunningUp: status.Up,
|
|
|
|
|
//RunningUp: status.TrainRunUp,
|
2024-01-17 15:53:14 +08:00
|
|
|
|
}
|
2024-02-21 14:54:17 +08:00
|
|
|
|
status.TailDeviceId = vs.GetComIdByUid(tailDeviceId)
|
|
|
|
|
status.TailOffset = tailDeviceOffset
|
|
|
|
|
status.TailDevicePort = tailDevicePort
|
2024-01-17 15:53:14 +08:00
|
|
|
|
//初始化列车参数状态
|
2024-01-17 17:02:17 +08:00
|
|
|
|
createOrUpdateStateDynamicConfig(status, configTrainData, trainEndsA, trainEndsB)
|
2024-04-30 10:15:20 +08:00
|
|
|
|
tl := configTrainData.TrainLoad
|
|
|
|
|
if tl <= 0 {
|
|
|
|
|
tl = DEFULAT_TRAIN_LOAD
|
|
|
|
|
}
|
2024-05-07 15:00:59 +08:00
|
|
|
|
|
2024-05-20 15:21:22 +08:00
|
|
|
|
vobc, _ := initTrainVobc(int64(tl), status.TrainRunUp)
|
|
|
|
|
status.VobcState = vobc
|
|
|
|
|
|
|
|
|
|
//status.TrainActiveDirection = trainActDir
|
|
|
|
|
|
2024-07-04 09:26:37 +08:00
|
|
|
|
status.Tcc = initTrainTcc(vs, status.TrainRunUp, DEFAULT_BRAKE_FORCE)
|
2024-06-06 17:57:30 +08:00
|
|
|
|
status.VobcBtm = &state_proto.VobcBtmState{TelegramState: make([]*state_proto.VobcBtmState_TelegramState, 0), History: make(map[uint32]*state_proto.VobcBtmState_VobcBtmHistoryState)}
|
2024-01-17 15:53:14 +08:00
|
|
|
|
slog.Debug("列车初始化", "trainIndex", trainIndex, "linkId", linkId, "loffset", loffset)
|
|
|
|
|
linkIdInt, _ := strconv.Atoi(linkId)
|
|
|
|
|
err := dynamics.Default().RequestAddTrain(&message.InitTrainInfo{
|
2024-05-20 15:21:22 +08:00
|
|
|
|
TrainIndex: uint16(trainIndex),
|
|
|
|
|
LinkIndex: uint16(linkIdInt),
|
|
|
|
|
LinkOffset: uint32(loffset),
|
|
|
|
|
Speed: status.Speed / 3.6,
|
|
|
|
|
Up: status.Up,
|
|
|
|
|
//Up: status.TrainRunUp,
|
2024-01-17 15:53:14 +08:00
|
|
|
|
TrainOperationConfig: CreateMsgTrainConfig(int(trainIndex), status.TrainLength, configTrainData),
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
|
|
|
|
|
}
|
|
|
|
|
// world中加车
|
|
|
|
|
fi.AddTrainToWorld(vs.World, status.Id)
|
|
|
|
|
fi.UpdateTrainPositionFromDynamics(vs.World, fi.TrainPositionInfo{
|
|
|
|
|
TrainId: status.Id,
|
|
|
|
|
Up: status.Up,
|
|
|
|
|
Len: uint32(status.TrainLength),
|
|
|
|
|
HeadLink: linkId,
|
|
|
|
|
HeadLinkOffset: uint32(loffset),
|
|
|
|
|
TailLink: tailLink,
|
|
|
|
|
TailLinkOffset: uint32(tailLOffset),
|
|
|
|
|
})
|
|
|
|
|
// 将信息合并到当前设备状态中
|
|
|
|
|
allTrainMap.Store(status.Id, status)
|
2024-02-23 10:43:06 +08:00
|
|
|
|
return nil
|
2024-01-17 15:53:14 +08:00
|
|
|
|
}
|
2024-03-19 08:28:50 +08:00
|
|
|
|
|
2024-04-17 09:32:25 +08:00
|
|
|
|
// 列车连接类型更新
|
2024-03-15 16:03:47 +08:00
|
|
|
|
func TrainConnTypeUpdate(vs *VerifySimulation, ct *dto.TrainConnThirdDto) {
|
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
|
data, ok := allTrainMap.Load(ct.Id)
|
|
|
|
|
if !ok {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车【%s】不存在", ct.Id)))
|
|
|
|
|
}
|
2024-04-09 08:55:33 +08:00
|
|
|
|
train := data.(*state_proto.TrainState)
|
2024-07-11 14:58:34 +08:00
|
|
|
|
if train.DynamicState.Speed != 0 {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车[%s]需要停稳才能连接半实物", train.Id)))
|
|
|
|
|
}
|
2024-04-09 08:55:33 +08:00
|
|
|
|
if ct.ConnType != state_proto.TrainConnState_NONE {
|
|
|
|
|
//列车连接 半实物或车载pc仿真
|
2024-03-15 17:50:18 +08:00
|
|
|
|
allTrainMap.Range(func(k, v any) bool {
|
|
|
|
|
tmpTrain := v.(*state_proto.TrainState)
|
2024-03-19 09:54:32 +08:00
|
|
|
|
if tmpTrain.ConnState.Conn {
|
2024-04-09 08:55:33 +08:00
|
|
|
|
connTypeName := "半实物"
|
2024-05-24 09:00:43 +08:00
|
|
|
|
if tmpTrain.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_A {
|
|
|
|
|
connTypeName = "车载pc仿真-A"
|
2024-06-13 10:06:54 +08:00
|
|
|
|
} else if tmpTrain.ConnState.ConnType == state_proto.TrainConnState_PC_SIM_B {
|
2024-05-24 09:00:43 +08:00
|
|
|
|
connTypeName = "车载pc仿真-B"
|
2024-04-09 08:55:33 +08:00
|
|
|
|
}
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车[%s]已经连接 [%v],此列车无法连接", k, connTypeName)))
|
2024-03-15 17:50:18 +08:00
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
})
|
2024-03-15 16:03:47 +08:00
|
|
|
|
}
|
2024-04-29 13:58:14 +08:00
|
|
|
|
train.ConnState.Conn = true
|
|
|
|
|
train.ConnState.ConnType = ct.ConnType
|
2024-05-24 09:00:43 +08:00
|
|
|
|
if ct.ConnType == state_proto.TrainConnState_PC_SIM_A || ct.ConnType == state_proto.TrainConnState_PC_SIM_B {
|
2024-06-13 14:16:52 +08:00
|
|
|
|
err := TrainPcSimConnOrRemoveHandle(train, true)
|
2024-04-18 11:14:05 +08:00
|
|
|
|
if err != nil {
|
2024-04-29 13:58:14 +08:00
|
|
|
|
train.ConnState.Conn = false
|
|
|
|
|
train.ConnState.ConnType = state_proto.TrainConnState_NONE
|
|
|
|
|
panic(sys_error.New(err.Error()))
|
2024-04-18 11:14:05 +08:00
|
|
|
|
}
|
2024-06-27 10:37:52 +08:00
|
|
|
|
//train_pc_sim.Default().SendDriverActive(train)
|
2024-04-18 11:14:05 +08:00
|
|
|
|
}
|
2024-04-29 13:58:14 +08:00
|
|
|
|
|
2024-04-16 17:26:37 +08:00
|
|
|
|
}
|
2024-04-17 09:32:25 +08:00
|
|
|
|
|
|
|
|
|
// 列车断开三方连接
|
2024-04-16 17:26:37 +08:00
|
|
|
|
func TrainUnConn(vs *VerifySimulation, trainId string) {
|
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
|
data, ok := allTrainMap.Load(trainId)
|
|
|
|
|
if !ok {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车【%s】不存在", trainId)))
|
|
|
|
|
}
|
|
|
|
|
train := data.(*state_proto.TrainState)
|
2024-06-13 14:16:52 +08:00
|
|
|
|
err := TrainPcSimConnOrRemoveHandle(train, false)
|
2024-06-07 13:26:46 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
panic(sys_error.New("未连接车载PC仿真,无法断开连接"))
|
2024-04-16 17:26:37 +08:00
|
|
|
|
}
|
2024-04-18 11:14:05 +08:00
|
|
|
|
train.ConnState.Conn = false
|
|
|
|
|
train.ConnState.ConnType = state_proto.TrainConnState_NONE
|
2024-04-16 17:26:37 +08:00
|
|
|
|
}
|
2024-01-17 17:02:17 +08:00
|
|
|
|
func createOrUpdateStateDynamicConfig(trainState *state_proto.TrainState, configTrainData dto.ConfigTrainData, trainEndsA dto.ConfigTrainEnds,
|
|
|
|
|
trainEndsB dto.ConfigTrainEnds) {
|
2024-01-18 10:48:04 +08:00
|
|
|
|
trainState.TrainDynamicConfig = service.TrainConfigToProtoConvert(&configTrainData)
|
2024-01-22 17:46:26 +08:00
|
|
|
|
if trainState.TrainDynamicConfig != nil {
|
2024-01-18 13:57:57 +08:00
|
|
|
|
copyTrainEnds(trainState, "TrainEndsA", trainEndsA)
|
|
|
|
|
copyTrainEnds(trainState, "TrainEndsB", trainEndsB)
|
2024-01-16 17:53:54 +08:00
|
|
|
|
}
|
2024-01-17 13:09:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-17 17:02:17 +08:00
|
|
|
|
func copyTrainEnds(trainState *state_proto.TrainState, fieldName string, configData dto.ConfigTrainEnds) {
|
2024-01-17 13:09:45 +08:00
|
|
|
|
fieldVal := reflect.ValueOf(trainState).Elem().FieldByName(fieldName)
|
2024-01-17 17:02:17 +08:00
|
|
|
|
endsVal := fieldVal.Interface().(*common_proto.TrainEndsState)
|
2024-01-17 13:09:45 +08:00
|
|
|
|
if endsVal == nil {
|
2024-01-17 17:02:17 +08:00
|
|
|
|
endsVal = &common_proto.TrainEndsState{}
|
2024-01-17 13:09:45 +08:00
|
|
|
|
fieldVal.Set(reflect.ValueOf(endsVal))
|
|
|
|
|
}
|
2024-01-17 15:53:14 +08:00
|
|
|
|
endsVal.SpeedSensorEnableA = configData.SpeedSensorEnableA
|
2024-01-18 13:57:57 +08:00
|
|
|
|
endsVal.SpeedSensorEnableB = configData.SpeedSensorEnableB
|
2024-04-28 11:01:12 +08:00
|
|
|
|
endsVal.AccOutSpeed = configData.AccOutSpeed
|
|
|
|
|
|
2024-01-17 13:09:45 +08:00
|
|
|
|
endsVal.RadarEnable = configData.RadarEnable
|
|
|
|
|
endsVal.RadarCheckTime = configData.RadarCheckTime
|
2024-04-28 11:01:12 +08:00
|
|
|
|
|
|
|
|
|
endsVal.RadarCheckSpeedDiff = configData.RadarCheckSpeedDiff
|
|
|
|
|
endsVal.RadarOutSpeed = configData.RadarOutSpeed
|
|
|
|
|
|
2024-01-26 17:57:35 +08:00
|
|
|
|
endsVal.AccEnable = configData.AccEnable
|
|
|
|
|
endsVal.AccCheckSpeedDiff = configData.AccCheckSpeedDiff
|
|
|
|
|
endsVal.AccCheckTime = configData.AccCheckTime
|
|
|
|
|
|
2024-01-16 17:53:54 +08:00
|
|
|
|
}
|
2024-01-17 15:53:14 +08:00
|
|
|
|
func UpdateConfigTrain(vs *VerifySimulation, ct *dto.ConfigTrainReqDto) {
|
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
|
data, ok := allTrainMap.Load(strconv.Itoa(ct.TrainId))
|
|
|
|
|
if !ok {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车【%s】不存在", ct.TrainId)))
|
|
|
|
|
}
|
|
|
|
|
trainState, ok := data.(*state_proto.TrainState)
|
|
|
|
|
if !ok {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车参数修改断言:列车【%s】不存在", ct.TrainId)))
|
|
|
|
|
}
|
2024-01-17 17:02:17 +08:00
|
|
|
|
createOrUpdateStateDynamicConfig(trainState, ct.ConfigData, ct.TrainEndsA, ct.TrainEndsB)
|
2024-01-17 15:53:14 +08:00
|
|
|
|
trainState.TrainLength = ct.Length
|
|
|
|
|
trainState.WheelDiameter = ct.WheelDiameter
|
2024-01-18 17:17:48 +08:00
|
|
|
|
requestDynamicConfig(ct)
|
2024-04-28 11:01:12 +08:00
|
|
|
|
trainState.TrainEndsA.RadarCheckTimeOverAt = 0
|
|
|
|
|
trainState.TrainEndsB.RadarCheckTimeOverAt = 0
|
|
|
|
|
trainState.TrainEndsA.AccCheckTimeOverAt = 0
|
|
|
|
|
trainState.TrainEndsB.AccCheckTimeOverAt = 0
|
2024-04-19 16:55:51 +08:00
|
|
|
|
if ct.TrainEndsA.RadarCheckTime > 0 {
|
|
|
|
|
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsA.RadarCheckTime)).Unix()
|
|
|
|
|
trainState.TrainEndsA.RadarCheckTimeOverAt = timeAt
|
|
|
|
|
}
|
|
|
|
|
if ct.TrainEndsB.RadarCheckTime > 0 {
|
2024-04-28 11:01:12 +08:00
|
|
|
|
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsB.RadarCheckTime)).Unix()
|
2024-04-19 16:55:51 +08:00
|
|
|
|
trainState.TrainEndsB.RadarCheckTimeOverAt = timeAt
|
|
|
|
|
}
|
|
|
|
|
if ct.TrainEndsA.AccCheckTime > 0 {
|
|
|
|
|
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsA.AccCheckTime)).Unix()
|
|
|
|
|
trainState.TrainEndsA.AccCheckTimeOverAt = timeAt
|
|
|
|
|
}
|
|
|
|
|
if ct.TrainEndsB.AccCheckTime > 0 {
|
|
|
|
|
timeAt := time.Now().Add(time.Second * time.Duration(ct.TrainEndsB.AccCheckTime)).Unix()
|
|
|
|
|
trainState.TrainEndsB.AccCheckTimeOverAt = timeAt
|
|
|
|
|
}
|
2024-01-17 15:53:14 +08:00
|
|
|
|
}
|
2024-01-16 17:53:54 +08:00
|
|
|
|
|
2024-01-17 13:09:45 +08:00
|
|
|
|
func requestDynamicConfig(ct *dto.ConfigTrainReqDto) {
|
2024-01-17 15:53:14 +08:00
|
|
|
|
msg := CreateMsgTrainConfig(ct.TrainId, ct.Length, ct.ConfigData)
|
2024-01-17 13:09:45 +08:00
|
|
|
|
err2 := dynamics.Default().TrainOperationConfig(msg)
|
|
|
|
|
err := err2
|
2024-01-16 17:53:54 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Error("列车参数变更请求动力学失败", err)
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车参数变更请求动力学失败")))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-13 15:57:32 +08:00
|
|
|
|
// 修改列车信息
|
2024-01-11 10:24:56 +08:00
|
|
|
|
func UpdateTrainInfo(vs *VerifySimulation, status *state_proto.TrainState) *state_proto.TrainState {
|
2023-11-13 15:57:32 +08:00
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
|
data, ok := allTrainMap.Load(status.Id)
|
|
|
|
|
if !ok {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车【%s】不存在", status.Id)))
|
|
|
|
|
}
|
2024-01-11 10:24:56 +08:00
|
|
|
|
sta := data.(*state_proto.TrainState)
|
2023-11-13 15:57:32 +08:00
|
|
|
|
sta.TrainLength = status.TrainLength
|
|
|
|
|
sta.WheelDiameter = status.WheelDiameter
|
2023-11-17 16:22:22 +08:00
|
|
|
|
return sta
|
2023-11-13 15:57:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-09 15:58:16 +08:00
|
|
|
|
// 根据动力学发来的信息修改列车状态
|
2024-01-11 10:24:56 +08:00
|
|
|
|
func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *message.DynamicsTrainInfo) *state_proto.TrainState {
|
2023-11-09 15:58:16 +08:00
|
|
|
|
data, ok := vs.Memory.Status.TrainStateMap.Load(trainId)
|
2023-08-01 17:45:26 +08:00
|
|
|
|
if !ok {
|
2023-11-09 17:54:31 +08:00
|
|
|
|
panic(sys_error.New(fmt.Sprintf("动力学传输数据:列车【%s】不存在", trainId)))
|
2023-11-09 15:58:16 +08:00
|
|
|
|
}
|
2024-01-11 10:24:56 +08:00
|
|
|
|
sta := data.(*state_proto.TrainState)
|
2024-05-20 17:59:40 +08:00
|
|
|
|
if !sta.Show {
|
|
|
|
|
return sta
|
|
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
|
delayTime := time.Now().UnixMilli() - sta.VobcState.UpdateTime
|
|
|
|
|
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
2024-05-20 17:23:22 +08:00
|
|
|
|
|
2024-04-15 08:44:37 +08:00
|
|
|
|
//slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
2023-11-09 15:58:16 +08:00
|
|
|
|
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
2024-05-20 15:21:22 +08:00
|
|
|
|
|
2023-11-09 17:54:31 +08:00
|
|
|
|
outLinkId, id, port, outLinkOffset, offset, kilometer, e1 := CalcInitializeLink(vs, inLinkId, inLinkOffset, info.Up)
|
|
|
|
|
if e1 != nil {
|
|
|
|
|
panic(sys_error.New("动力学传输数据:列车车头位置计算出错", e1))
|
|
|
|
|
}
|
2024-05-20 15:21:22 +08:00
|
|
|
|
//runDirection 指定的是link方向
|
|
|
|
|
//pointTO 指的是是否ab,或是否到岔心
|
2024-06-06 17:57:30 +08:00
|
|
|
|
_, pointTo := QueryDirectionAndABByDevice(vs.Repo, id, port, info.Up)
|
2024-05-20 15:21:22 +08:00
|
|
|
|
|
2024-06-06 17:57:30 +08:00
|
|
|
|
//slog.Debug("处理动力学转换后的消息", "number", info.Number, "up", info.Up, "Link", info.Link, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo, "t1Dir:", info.TrainActToMax, "t2Dir:", info.TrainActToMin)
|
2024-05-20 15:21:22 +08:00
|
|
|
|
trainHeadActUp := true
|
|
|
|
|
if info.TrainActToMax || info.TrainActToMin {
|
|
|
|
|
if info.TrainActToMin {
|
|
|
|
|
trainHeadActUp = false
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
|
// 车尾相对车头link的偏移量
|
2024-05-20 15:21:22 +08:00
|
|
|
|
//calctailOffset := calcTrailTailOffset(outLinkOffset, int64(info.Len), info.Up)
|
|
|
|
|
calctailOffset := calcTrailTailOffset(outLinkOffset, int64(info.Len), trainHeadActUp)
|
2024-04-13 09:40:25 +08:00
|
|
|
|
tailLinkId, tailDeviceId, tailDevicePort, tailLinkOffset, tailOffset, _, e2 := CalcInitializeLink(vs, outLinkId, calctailOffset, !info.Up)
|
2023-11-09 17:54:31 +08:00
|
|
|
|
if e2 != nil {
|
|
|
|
|
panic(sys_error.New("动力学传输数据:列车车尾位置计算出错", e2))
|
|
|
|
|
}
|
2023-11-28 13:30:10 +08:00
|
|
|
|
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
2024-05-20 15:21:22 +08:00
|
|
|
|
updateTrainBtmPosition(vs, info, sta, outLinkId, outLinkOffset)
|
2023-11-10 10:54:35 +08:00
|
|
|
|
// 修改world中的列车位置
|
2024-05-20 15:21:22 +08:00
|
|
|
|
handleTrainPositionFromDynamic(vs, info, sta, outLinkId, outLinkOffset, tailLinkId, tailLinkOffset)
|
|
|
|
|
//修改列车激活方向
|
|
|
|
|
updateTrainActiveDirFromDynamic(vs, info, sta, id, port, trainHeadActUp)
|
|
|
|
|
|
2023-11-09 15:58:16 +08:00
|
|
|
|
sta.HeadDeviceId = vs.GetComIdByUid(id)
|
|
|
|
|
sta.DevicePort = port
|
|
|
|
|
sta.HeadOffset = offset
|
2024-05-20 15:21:22 +08:00
|
|
|
|
sta.DriftTo = pointTo
|
2023-11-09 15:58:16 +08:00
|
|
|
|
sta.TrainKilometer = kilometer.Value
|
2024-05-20 15:21:22 +08:00
|
|
|
|
|
2024-02-06 18:00:39 +08:00
|
|
|
|
sta.TailDeviceId = vs.GetComIdByUid(tailDeviceId)
|
|
|
|
|
sta.TailOffset = tailOffset
|
2024-02-21 14:54:17 +08:00
|
|
|
|
sta.TailDevicePort = tailDevicePort
|
2023-11-09 15:58:16 +08:00
|
|
|
|
// 赋值动力学信息
|
|
|
|
|
sta.DynamicState.Heartbeat = int32(info.LifeSignal)
|
|
|
|
|
sta.DynamicState.HeadLinkId = outLinkId
|
|
|
|
|
sta.DynamicState.HeadLinkOffset = outLinkOffset
|
|
|
|
|
sta.DynamicState.TailLinkId = tailLinkId
|
|
|
|
|
sta.DynamicState.TailLinkOffset = tailLinkOffset
|
|
|
|
|
sta.DynamicState.Slope = int32(info.Slope)
|
|
|
|
|
sta.DynamicState.Upslope = info.UpSlope
|
|
|
|
|
sta.DynamicState.RunningUp = info.Up
|
|
|
|
|
sta.DynamicState.RunningResistanceSum = float32(info.TotalResistance) / 1000
|
|
|
|
|
sta.DynamicState.AirResistance = float32(info.AirResistance) / 1000
|
|
|
|
|
sta.DynamicState.RampResistance = float32(info.SlopeResistance) / 1000
|
|
|
|
|
sta.DynamicState.CurveResistance = float32(info.CurveResistance) / 1000
|
|
|
|
|
sta.DynamicState.Speed = speedParse(info.Speed)
|
2024-04-19 16:55:51 +08:00
|
|
|
|
|
2023-11-09 15:58:16 +08:00
|
|
|
|
sta.DynamicState.HeadSensorSpeed1 = speedParse(info.HeadSpeed1)
|
|
|
|
|
sta.DynamicState.HeadSensorSpeed2 = speedParse(info.HeadSpeed2)
|
|
|
|
|
sta.DynamicState.TailSensorSpeed1 = speedParse(info.TailSpeed1)
|
|
|
|
|
sta.DynamicState.TailSensorSpeed2 = speedParse(info.TailSpeed2)
|
|
|
|
|
sta.DynamicState.HeadRadarSpeed = speedParse(info.HeadRadarSpeed)
|
|
|
|
|
sta.DynamicState.TailRadarSpeed = speedParse(info.TailRadarSpeed)
|
|
|
|
|
sta.DynamicState.Acceleration = info.Acceleration
|
2024-04-19 16:55:51 +08:00
|
|
|
|
|
2024-01-26 17:57:35 +08:00
|
|
|
|
sta.DynamicState.Displacement = int32(info.Displacement)
|
2024-07-04 09:26:37 +08:00
|
|
|
|
pluseCount(sta, info.HeadSpeed1, info.HeadSpeed2, info.TailSpeed1, info.TailSpeed2)
|
2023-11-17 16:22:22 +08:00
|
|
|
|
return sta
|
2023-08-01 17:08:45 +08:00
|
|
|
|
}
|
2024-04-09 08:55:33 +08:00
|
|
|
|
|
2024-06-06 17:57:30 +08:00
|
|
|
|
// 根据动力学列车激活端方向,返回前端列车激活端
|
|
|
|
|
// 道岔 1是端口到岔心 2是岔心到端口
|
|
|
|
|
// 区段 1是a-b 2是b-a
|
2024-05-20 15:21:22 +08:00
|
|
|
|
func updateTrainActiveDirFromDynamic(vs *VerifySimulation, info *message.DynamicsTrainInfo, sta *state_proto.TrainState, id, port string, trainHeadActUp bool) {
|
|
|
|
|
sta.TrainActiveDirection = 0
|
|
|
|
|
if info.TrainActToMax || info.TrainActToMin {
|
|
|
|
|
_, pointTo2 := QueryDirectionAndABByDevice(vs.Repo, id, port, trainHeadActUp)
|
|
|
|
|
pt := pointTo2
|
|
|
|
|
if pt {
|
|
|
|
|
sta.TrainActiveDirection = 1
|
|
|
|
|
} else {
|
|
|
|
|
sta.TrainActiveDirection = 2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据列车位置修改列车应答器
|
|
|
|
|
func updateTrainBtmPosition(vs *VerifySimulation, info *message.DynamicsTrainInfo, sta *state_proto.TrainState, outLinkId string, outLinkOffset int64) {
|
|
|
|
|
// 更新BTM中列车位置信息
|
2024-06-06 17:57:30 +08:00
|
|
|
|
can_btm.Default().HandleTrainHeadPositionInfo(vs.World, sta.VobcBtm, &fi.TrainHeadPositionInfo{
|
2024-05-20 15:21:22 +08:00
|
|
|
|
TrainId: sta.Id,
|
|
|
|
|
Up: info.Up,
|
|
|
|
|
Link: outLinkId,
|
|
|
|
|
LinkOffset: outLinkOffset,
|
|
|
|
|
Speed: info.Speed,
|
|
|
|
|
Acceleration: info.Acceleration,
|
|
|
|
|
})
|
|
|
|
|
state := can_btm.Default().GetState()
|
2024-06-06 17:57:30 +08:00
|
|
|
|
//fmt.Println(state.Telegram)
|
2024-05-20 15:21:22 +08:00
|
|
|
|
sta.BtmState = &state
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据动力学修改列车位置
|
|
|
|
|
func handleTrainPositionFromDynamic(vs *VerifySimulation, info *message.DynamicsTrainInfo, sta *state_proto.TrainState, outLinkId string, outLinkOffset int64, tailLinkId string, tailLinkOffset int64) {
|
|
|
|
|
fi.UpdateTrainPositionFromDynamics(vs.World, fi.TrainPositionInfo{
|
|
|
|
|
TrainId: sta.Id,
|
|
|
|
|
Up: info.Up,
|
|
|
|
|
Len: info.Len,
|
|
|
|
|
HeadLink: outLinkId,
|
|
|
|
|
HeadLinkOffset: uint32(outLinkOffset),
|
|
|
|
|
TailLink: tailLinkId,
|
|
|
|
|
TailLinkOffset: uint32(tailLinkOffset),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-04 09:26:37 +08:00
|
|
|
|
func pluseCount(sta *state_proto.TrainState, h1, h2, t1, t2 float32) {
|
2024-04-09 08:55:33 +08:00
|
|
|
|
if sta.PluseCount == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-07-11 14:58:34 +08:00
|
|
|
|
train_pc_sim.Default().TrainPluseCount(sta, h1, h2, t1, t2)
|
2024-07-04 09:26:37 +08:00
|
|
|
|
|
2024-04-09 08:55:33 +08:00
|
|
|
|
}
|
2024-02-04 18:22:52 +08:00
|
|
|
|
func RemoveAllTrain(vs *VerifySimulation) {
|
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
|
if allTrainMap == nil {
|
|
|
|
|
slog.Info("当前没有列车不能执行")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
allTrainMap.Range(func(k any, t any) bool {
|
2024-02-23 10:43:06 +08:00
|
|
|
|
id := k.(string)
|
|
|
|
|
RemoveTrainState(vs, id)
|
2024-02-04 18:22:52 +08:00
|
|
|
|
return true
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func removeTrain(vs *VerifySimulation, trainId string, train *state_proto.TrainState) error {
|
|
|
|
|
trainIndex, _ := strconv.ParseUint(trainId, 10, 16)
|
|
|
|
|
err := dynamics.Default().RequestRemoveTrain(&message.RemoveTrainReq{
|
|
|
|
|
TrainIndex: uint16(trainIndex),
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-03-19 09:54:32 +08:00
|
|
|
|
if train.ConnState.Conn {
|
2024-04-29 13:58:14 +08:00
|
|
|
|
train.ConnState.Conn = false
|
2024-06-13 14:16:52 +08:00
|
|
|
|
err = TrainPcSimConnOrRemoveHandle(train, false)
|
2024-04-29 13:58:14 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
train.ConnState.Conn = true
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-03-19 08:28:50 +08:00
|
|
|
|
}
|
2024-05-20 17:23:22 +08:00
|
|
|
|
if train.VobcState != nil {
|
|
|
|
|
vobc := train.VobcState
|
|
|
|
|
vobc.TractionStatus = false
|
|
|
|
|
vobc.BrakingStatus = true
|
|
|
|
|
vobc.TractionForce = 0
|
|
|
|
|
vobc.BrakeForce = DEFAULT_BRAKE_FORCE
|
|
|
|
|
}
|
2024-04-29 13:58:14 +08:00
|
|
|
|
train.Show = false
|
|
|
|
|
train.ConnState.ConnType = state_proto.TrainConnState_NONE
|
2024-02-23 10:43:06 +08:00
|
|
|
|
return fi.RemoveTrainFromWorld(vs.World, trainId)
|
2024-02-04 18:22:52 +08:00
|
|
|
|
}
|
2023-08-01 17:08:45 +08:00
|
|
|
|
|
|
|
|
|
// 删除列车状态
|
2024-02-04 18:22:52 +08:00
|
|
|
|
/*func RemoveTrainState(vs *VerifySimulation, id string) {
|
2023-09-12 10:00:13 +08:00
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
2023-08-02 15:50:46 +08:00
|
|
|
|
d, ok := allTrainMap.Load(id)
|
2023-08-01 17:08:45 +08:00
|
|
|
|
if ok {
|
2024-01-11 10:24:56 +08:00
|
|
|
|
t := d.(*state_proto.TrainState)
|
2023-08-16 09:29:28 +08:00
|
|
|
|
trainIndex, _ := strconv.ParseUint(id, 10, 16)
|
2023-10-19 09:33:40 +08:00
|
|
|
|
err := dynamics.Default().RequestRemoveTrain(&message.RemoveTrainReq{
|
2023-08-16 09:29:28 +08:00
|
|
|
|
TrainIndex: uint16(trainIndex),
|
|
|
|
|
})
|
2023-10-19 09:33:40 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
|
2023-08-16 09:29:28 +08:00
|
|
|
|
}
|
2023-08-01 17:08:45 +08:00
|
|
|
|
// 从仿真内存中移除列车
|
2023-08-02 15:50:46 +08:00
|
|
|
|
t.Show = false
|
2023-11-09 15:58:16 +08:00
|
|
|
|
// 移除车
|
|
|
|
|
fi.RemoveTrainFromWorld(vs.World, id)
|
2023-08-02 15:50:46 +08:00
|
|
|
|
allTrainMap.Store(id, t)
|
2023-08-01 17:08:45 +08:00
|
|
|
|
} else {
|
|
|
|
|
panic(fmt.Sprintf("列车【%s】不存在", id))
|
|
|
|
|
}
|
2024-02-04 18:22:52 +08:00
|
|
|
|
}*/
|
|
|
|
|
func RemoveTrainState(vs *VerifySimulation, id string) {
|
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
|
d, ok := allTrainMap.Load(id)
|
|
|
|
|
if ok {
|
|
|
|
|
t := d.(*state_proto.TrainState)
|
|
|
|
|
err := removeTrain(vs, id, t)
|
2024-06-06 17:57:30 +08:00
|
|
|
|
clearTrainVobcBtmState(vs, id)
|
2024-02-04 18:22:52 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
|
|
|
|
|
}
|
|
|
|
|
allTrainMap.Store(id, t)
|
|
|
|
|
} else {
|
|
|
|
|
panic(fmt.Sprintf("列车【%s】不存在", id))
|
|
|
|
|
}
|
2023-08-01 17:08:45 +08:00
|
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
|
|
|
|
|
|
func calcTrailTailOffset(headerOffset, length int64, up bool) (calctailOffset int64) {
|
|
|
|
|
if up {
|
|
|
|
|
calctailOffset = headerOffset - length
|
|
|
|
|
} else {
|
|
|
|
|
calctailOffset = headerOffset + length
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-06-06 17:57:30 +08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|