2023-08-01 17:08:45 +08:00
|
|
|
package memory
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-10-12 10:10:23 +08:00
|
|
|
"log/slog"
|
2023-08-02 15:47:48 +08:00
|
|
|
"math"
|
|
|
|
"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
|
|
|
|
2023-11-08 11:02:41 +08:00
|
|
|
"joylink.club/bj-rtsts-server/ts/protos/graphicData"
|
2023-10-26 17:16:07 +08:00
|
|
|
"joylink.club/bj-rtsts-server/ts/protos/state"
|
2023-08-01 17:08:45 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// 增加列车状态
|
2023-09-21 17:57:50 +08:00
|
|
|
func AddTrainState(vs *VerifySimulation, status *state.TrainState, mapId int32) {
|
2023-09-12 10:00:13 +08:00
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
2023-08-01 17:08:45 +08:00
|
|
|
_, ok := allTrainMap.Load(status.Id)
|
|
|
|
if ok {
|
|
|
|
panic(fmt.Sprintf("列车【%s】已存在", status.Id))
|
|
|
|
}
|
2023-08-02 15:50:46 +08:00
|
|
|
// 显示状态
|
|
|
|
status.Show = true
|
2023-08-02 15:47:48 +08:00
|
|
|
//向动力学发送初始化请求
|
|
|
|
trainIndex, _ := strconv.ParseUint(status.Id, 10, 16)
|
2023-11-08 11:02:41 +08:00
|
|
|
slog.Debug("添加列车", "trainIndex", trainIndex, "HeadDeviceId", status.HeadDeviceId, "HeadOffset", status.HeadOffset)
|
2023-08-14 16:27:03 +08:00
|
|
|
// 映射link、偏移量、运行方向
|
2023-11-08 11:02:41 +08:00
|
|
|
var uid string
|
|
|
|
if status.DevicePort == "" {
|
|
|
|
uid = QueryUidByMidAndComId(mapId, status.HeadDeviceId, &graphicData.Section{})
|
|
|
|
} else {
|
|
|
|
uid = QueryUidByMidAndComId(mapId, status.HeadDeviceId, &graphicData.Turnout{})
|
|
|
|
}
|
|
|
|
// 车头所在link、link上的偏移
|
|
|
|
linkId, loffset := QueryLinkAndOffsetByDevice(vs.Repo, uid, status.DevicePort, status.HeadOffset)
|
|
|
|
// link上的运行方向、设备上的运行方向
|
|
|
|
up, pointTo := QueryUpAndABByDevice(vs.Repo, uid, status.DevicePort, status.RunDirection)
|
|
|
|
// 车头所在公里标
|
|
|
|
kilometer := CalcTrainKilometer(vs.Repo, uid, status.DevicePort, status.RunDirection, status.HeadOffset)
|
|
|
|
// 车尾相对车头link的偏移量
|
2023-11-10 09:28:27 +08:00
|
|
|
calctailOffset := calcTrailTailOffset(loffset, status.TrainLength, up)
|
2023-11-08 11:02:41 +08:00
|
|
|
// 车尾位置
|
2023-11-10 10:54:35 +08:00
|
|
|
tailLink, _, _, tailLOffset, _, _, e1 := CalcInitializeLink(vs, linkId, calctailOffset, up)
|
2023-11-09 17:54:31 +08:00
|
|
|
if e1 != nil {
|
|
|
|
panic(sys_error.New("添加列车失败,列车车尾占用位置计算出错", e1))
|
|
|
|
}
|
2023-08-14 16:27:03 +08:00
|
|
|
status.Up = up
|
2023-08-15 10:18:39 +08:00
|
|
|
status.PointTo = pointTo
|
2023-11-08 11:02:41 +08:00
|
|
|
status.TrainKilometer = kilometer.Value
|
|
|
|
status.DynamicState = &state.TrainDynamicState{
|
|
|
|
HeadLinkId: linkId,
|
|
|
|
HeadLinkOffset: loffset,
|
|
|
|
TailLinkId: tailLink,
|
|
|
|
TailLinkOffset: tailLOffset,
|
|
|
|
RunningUp: up,
|
|
|
|
}
|
|
|
|
status.VobcState = &state.TrainVobcState{}
|
|
|
|
slog.Debug("列车初始化", "trainIndex", trainIndex, "linkId", linkId, "loffset", loffset)
|
|
|
|
linkIdInt, _ := strconv.Atoi(linkId)
|
2023-10-19 09:33:40 +08:00
|
|
|
err := dynamics.Default().RequestAddTrain(&message.InitTrainInfo{
|
2023-08-24 10:24:56 +08:00
|
|
|
TrainIndex: uint16(trainIndex),
|
2023-11-08 11:02:41 +08:00
|
|
|
LinkIndex: uint16(linkIdInt),
|
2023-08-24 10:24:56 +08:00
|
|
|
LinkOffset: uint32(loffset),
|
|
|
|
Speed: uint16(math.Round(float64(status.Speed * 10))),
|
|
|
|
Up: status.Up,
|
2023-11-10 09:28:27 +08:00
|
|
|
TrainLength: uint32(status.TrainLength),
|
2023-08-02 15:47:48 +08:00
|
|
|
})
|
2023-10-19 09:33:40 +08:00
|
|
|
if err != nil {
|
|
|
|
panic(dto.ErrorDto{Code: dto.DynamicsError, Message: err.Error()})
|
2023-08-02 15:47:48 +08:00
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
// world中加车
|
|
|
|
fi.AddTrainToWorld(vs.World, status.Id)
|
2023-11-10 10:54:35 +08:00
|
|
|
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),
|
|
|
|
})
|
2023-08-01 17:08:45 +08:00
|
|
|
// 将信息合并到当前设备状态中
|
|
|
|
allTrainMap.Store(status.Id, status)
|
2023-08-01 17:45:26 +08:00
|
|
|
}
|
|
|
|
|
2023-11-13 15:57:32 +08:00
|
|
|
// 修改列车信息
|
|
|
|
func UpdateTrainInfo(vs *VerifySimulation, status *state.TrainState) {
|
|
|
|
allTrainMap := &vs.Memory.Status.TrainStateMap
|
|
|
|
data, ok := allTrainMap.Load(status.Id)
|
|
|
|
if !ok {
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车【%s】不存在", status.Id)))
|
|
|
|
}
|
|
|
|
sta := data.(*state.TrainState)
|
|
|
|
sta.TrainLength = status.TrainLength
|
|
|
|
sta.WheelDiameter = status.WheelDiameter
|
|
|
|
}
|
|
|
|
|
2023-11-09 15:58:16 +08:00
|
|
|
// 根据动力学发来的信息修改列车状态
|
|
|
|
func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *message.DynamicsTrainInfo) {
|
|
|
|
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
|
|
|
}
|
|
|
|
sta := data.(*state.TrainState)
|
|
|
|
delayTime := time.Now().UnixMilli() - sta.VobcState.UpdateTime
|
|
|
|
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
|
|
|
slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
|
|
|
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
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))
|
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
runDirection, pointTo := QueryDirectionAndABByDevice(vs.Repo, id, port, info.Up)
|
|
|
|
slog.Debug("处理动力学转换后的消息", "number", info.Number, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo)
|
|
|
|
// 车尾相对车头link的偏移量
|
2023-11-09 17:54:31 +08:00
|
|
|
calctailOffset := calcTrailTailOffset(outLinkOffset, int64(info.Len), info.Up)
|
|
|
|
tailLinkId, tailDeviceId, tailDevicePort, tailLinkOffset, tailDeviceOffset, _, e2 := CalcInitializeLink(vs, outLinkId, calctailOffset, info.Up)
|
|
|
|
if e2 != nil {
|
|
|
|
panic(sys_error.New("动力学传输数据:列车车尾位置计算出错", e2))
|
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
2023-11-10 10:54:35 +08:00
|
|
|
// 修改world中的列车位置
|
|
|
|
fi.UpdateTrainPositionFromDynamics(vs.World, fi.TrainPositionInfo{
|
|
|
|
TrainId: trainId,
|
|
|
|
Up: info.Up,
|
|
|
|
Len: info.Len,
|
|
|
|
HeadLink: outLinkId,
|
|
|
|
HeadLinkOffset: uint32(outLinkOffset),
|
|
|
|
TailLink: tailLinkId,
|
|
|
|
TailLinkOffset: uint32(tailLinkOffset),
|
|
|
|
})
|
2023-11-09 15:58:16 +08:00
|
|
|
sta.HeadDeviceId = vs.GetComIdByUid(id)
|
|
|
|
sta.DevicePort = port
|
|
|
|
sta.HeadOffset = offset
|
|
|
|
sta.PointTo = pointTo
|
|
|
|
sta.TrainKilometer = kilometer.Value
|
|
|
|
sta.RunDirection = runDirection
|
|
|
|
//判定车头方向
|
|
|
|
sta.HeadDirection = runDirection
|
|
|
|
if sta.VobcState != nil {
|
|
|
|
if sta.VobcState.DirectionForward {
|
|
|
|
sta.HeadDirection = runDirection
|
|
|
|
} else if sta.VobcState.DirectionBackward {
|
|
|
|
sta.HeadDirection = !runDirection
|
|
|
|
}
|
2023-08-01 17:45:26 +08:00
|
|
|
}
|
2023-11-09 15:58:16 +08:00
|
|
|
if info.Speed < 0 {
|
|
|
|
sta.RunDirection = !sta.RunDirection
|
|
|
|
}
|
|
|
|
// 赋值动力学信息
|
|
|
|
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)
|
|
|
|
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
|
2023-08-01 17:08:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 删除列车状态
|
2023-09-12 10:00:13 +08:00
|
|
|
func RemoveTrainState(vs *VerifySimulation, id string) {
|
|
|
|
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 {
|
2023-08-02 15:50:46 +08:00
|
|
|
t := d.(*state.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))
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
}
|