Merge branch 'develop' into local-test
Some checks failed
local-test分支打包构建docker并发布运行 / Docker-Build (push) Has been cancelled
Some checks failed
local-test分支打包构建docker并发布运行 / Docker-Build (push) Has been cancelled
This commit is contained in:
commit
8d28ac1d59
@ -239,15 +239,20 @@ func addTrain(c *gin.Context) {
|
|||||||
if req.TrainId < 0 || req.TrainId >= 255 {
|
if req.TrainId < 0 || req.TrainId >= 255 {
|
||||||
panic(sys_error.New("列车编号不能小于0,大于255"))
|
panic(sys_error.New("列车编号不能小于0,大于255"))
|
||||||
}
|
}
|
||||||
|
if req.TrainSpeed < 0 || req.TrainSpeed > 90 {
|
||||||
|
panic(sys_error.New("列车编号不能小于0,大于255"))
|
||||||
|
}
|
||||||
rsp := &state_proto.TrainState{
|
rsp := &state_proto.TrainState{
|
||||||
Id: fmt.Sprintf("%v", req.TrainId),
|
Id: fmt.Sprintf("%v", req.TrainId),
|
||||||
HeadDeviceId: req.Id,
|
HeadDeviceId: req.Id,
|
||||||
HeadOffset: req.HeadOffset,
|
HeadOffset: req.HeadOffset,
|
||||||
DevicePort: req.DevicePort,
|
DevicePort: req.DevicePort,
|
||||||
RunDirection: req.RunDirection,
|
TrainRunUp: req.RunDirection,
|
||||||
|
//RunDirection: req.RunDirection,
|
||||||
TrainLength: req.TrainLength,
|
TrainLength: req.TrainLength,
|
||||||
WheelDiameter: req.WheelDiameter,
|
WheelDiameter: req.WheelDiameter,
|
||||||
Speed: req.TrainSpeed,
|
Speed: req.TrainSpeed,
|
||||||
|
Show: true,
|
||||||
ConnState: &state_proto.TrainConnState{TrainControlMapId: req.TrainControlMapId, Conn: false, ConnType: state_proto.TrainConnState_NONE},
|
ConnState: &state_proto.TrainConnState{TrainControlMapId: req.TrainControlMapId, Conn: false, ConnType: state_proto.TrainConnState_NONE},
|
||||||
}
|
}
|
||||||
var err *sys_error.BusinessError = memory.AddTrainStateNew(simulation,
|
var err *sys_error.BusinessError = memory.AddTrainStateNew(simulation,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -293,6 +293,14 @@ func handlerSectionState(w ecs.World, uid string) *state_proto.SectionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sectionState
|
return sectionState
|
||||||
|
} else if entry.HasComponent(component.TrackCircuitType) { //轨道电路
|
||||||
|
sectionState := &state_proto.SectionState{
|
||||||
|
Occupied: component.BitStateType.Get(component.TrackCircuitType.Get(entry).GJ).Val,
|
||||||
|
AxleFault: false,
|
||||||
|
AxleDrst: false,
|
||||||
|
AxlePdrst: false,
|
||||||
|
}
|
||||||
|
return sectionState
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -443,9 +451,9 @@ func convertTrainState(v *state_proto.TrainState) *state_proto.TrainMapState {
|
|||||||
HeadDeviceId: v.HeadDeviceId,
|
HeadDeviceId: v.HeadDeviceId,
|
||||||
HeadOffset: v.HeadOffset,
|
HeadOffset: v.HeadOffset,
|
||||||
DevicePort: v.DevicePort,
|
DevicePort: v.DevicePort,
|
||||||
PointTo: v.PointTo,
|
DriftTo: v.DriftTo,
|
||||||
RunDirection: v.RunDirection,
|
TrainRunUp: v.TrainRunUp,
|
||||||
HeadDirection: v.HeadDirection,
|
TrainActiveDirection: v.TrainActiveDirection,
|
||||||
TrainKilometer: v.TrainKilometer,
|
TrainKilometer: v.TrainKilometer,
|
||||||
ControlDelayTime: v.ControlDelayTime,
|
ControlDelayTime: v.ControlDelayTime,
|
||||||
WheelDiameter: v.WheelDiameter,
|
WheelDiameter: v.WheelDiameter,
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8ccd46aa6c97a933fd12c7b308da929115c9aa8e
|
Subproject commit 468cc7896408951a5627777aa862a58716642317
|
@ -1 +1 @@
|
|||||||
Subproject commit e4c55ea4b6f9f5f875d59fc5bba51fc21bc8ef97
|
Subproject commit aac1484a6f64cc43146cabd89784b92c933a0298
|
2
third_party/dynamics/dynamics.go
vendored
2
third_party/dynamics/dynamics.go
vendored
@ -133,6 +133,7 @@ func (d *dynamics) requestStartSimulation(base *message.LineBaseInfo) error {
|
|||||||
}
|
}
|
||||||
url := d.buildUrl("/api/start/")
|
url := d.buildUrl("/api/start/")
|
||||||
data, _ := json.Marshal(base)
|
data, _ := json.Marshal(base)
|
||||||
|
fmt.Println(string(data))
|
||||||
resp, err := d.httpClient.Post(url, "application/json", bytes.NewBuffer(data))
|
resp, err := d.httpClient.Post(url, "application/json", bytes.NewBuffer(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sys_error.New("动力学开始仿真请求发送错误", err)
|
return sys_error.New("动力学开始仿真请求发送错误", err)
|
||||||
@ -171,6 +172,7 @@ func (d *dynamics) RequestAddTrain(info *message.InitTrainInfo) error {
|
|||||||
}
|
}
|
||||||
url := d.buildUrl("/api/aerodynamics/init/train/")
|
url := d.buildUrl("/api/aerodynamics/init/train/")
|
||||||
data, _ := json.Marshal(info)
|
data, _ := json.Marshal(info)
|
||||||
|
fmt.Println(string(data))
|
||||||
resp, err := d.httpClient.Post(url, "application/json", bytes.NewBuffer(data))
|
resp, err := d.httpClient.Post(url, "application/json", bytes.NewBuffer(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("动力学添加列车请求异常: %v", err)
|
return fmt.Errorf("动力学添加列车请求异常: %v", err)
|
||||||
|
23
third_party/interlock/beijing11/beijing11_const.go
vendored
Normal file
23
third_party/interlock/beijing11/beijing11_const.go
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package beijing11
|
||||||
|
|
||||||
|
var (
|
||||||
|
FrameHead byte = 0x0E //帧头
|
||||||
|
FrameTail byte = 0x0E //帧尾
|
||||||
|
ControlWord = controlWord{
|
||||||
|
HeartBeat: 0x00,
|
||||||
|
ReadRegister: 0x01,
|
||||||
|
WriteRegister: 0x02,
|
||||||
|
Response: 0x03,
|
||||||
|
Upstream: 0x06,
|
||||||
|
DownStream: 0x07,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type controlWord struct {
|
||||||
|
HeartBeat byte //心跳
|
||||||
|
ReadRegister byte //读寄存器
|
||||||
|
WriteRegister byte //写寄存器
|
||||||
|
Response byte //回复
|
||||||
|
Upstream byte //上行流数据
|
||||||
|
DownStream byte //下行流数据
|
||||||
|
}
|
126
third_party/interlock/beijing11/interlock.go
vendored
Normal file
126
third_party/interlock/beijing11/interlock.go
vendored
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// Package beijing11 北京11号线联锁通信
|
||||||
|
package beijing11
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"joylink.club/bj-rtsts-server/config"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||||
|
"log/slog"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
initMutex = sync.Mutex{}
|
||||||
|
interlockMap = make(map[string]*InterlockProxy)
|
||||||
|
logTag = "[北京11号线联锁通信]"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetInstant(c *config.InterlockConfig, msgManager MsgManager) *InterlockProxy {
|
||||||
|
initMutex.Lock()
|
||||||
|
defer initMutex.Unlock()
|
||||||
|
if interlockMap[c.Code] == nil {
|
||||||
|
interlockMap[c.Code] = &InterlockProxy{runConfig: c, msgManager: msgManager}
|
||||||
|
}
|
||||||
|
return interlockMap[c.Code]
|
||||||
|
}
|
||||||
|
|
||||||
|
type MsgManager interface {
|
||||||
|
HandleReadRegisterMsg(req *ReadRegisterReq) (*ReadRegisterRes, error)
|
||||||
|
HandleWriteRegisterMsg(req *WriteRegisterReq) error
|
||||||
|
HandleDownstreamMsg(data []byte) error
|
||||||
|
CollectUpstreamMsg() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type msgManager struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterlockProxy struct {
|
||||||
|
runConfig *config.InterlockConfig //联锁通信配置
|
||||||
|
msgManager MsgManager //消息获取与处理接口0
|
||||||
|
client udp.UdpClient //向上位机发送数据的UDP客户端
|
||||||
|
server udp.UdpServer //接收上位机数据的UDP服务端
|
||||||
|
running bool //此服务正在运行的标志
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InterlockProxy) Start() {
|
||||||
|
if i.runConfig == nil || i.runConfig.Ip == "" || !i.runConfig.Open {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if i.running {
|
||||||
|
panic("启动联锁消息服务错误: 存在正在运行的任务")
|
||||||
|
}
|
||||||
|
//UDP通信设施
|
||||||
|
i.server = udp.NewServer(fmt.Sprintf(":%d", i.runConfig.LocalPort), i.handleUpperData)
|
||||||
|
err := i.server.Listen()
|
||||||
|
if err != nil {
|
||||||
|
panic("启动联锁消息服务错误:无法启动UDP服务")
|
||||||
|
}
|
||||||
|
i.running = true
|
||||||
|
i.client = udp.NewClient(fmt.Sprintf("%v:%v", i.runConfig.Ip, i.runConfig.RemotePort))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理来自上位机的数据
|
||||||
|
func (i *InterlockProxy) handleUpperData(data []byte) {
|
||||||
|
baseData := &BaseStruct{}
|
||||||
|
err := baseData.Decode(data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "数据解析出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch baseData.ControlWord {
|
||||||
|
case ControlWord.ReadRegister:
|
||||||
|
req := &ReadRegisterReq{}
|
||||||
|
err := req.Decode(baseData.Data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "读寄存器数据解析出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := i.msgManager.HandleReadRegisterMsg(req)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "读寄存器数据处理出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resData := &BaseStruct{
|
||||||
|
ID: baseData.ID,
|
||||||
|
ControlWord: ControlWord.Response,
|
||||||
|
Data: res.Encode(),
|
||||||
|
}
|
||||||
|
i.SendToUpper(resData.Encode())
|
||||||
|
case ControlWord.WriteRegister:
|
||||||
|
req := &WriteRegisterReq{}
|
||||||
|
err := req.Decode(baseData.Data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "写寄存器数据解析出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = i.msgManager.HandleWriteRegisterMsg(req)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "写寄存器数据处理出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case ControlWord.DownStream:
|
||||||
|
err = i.msgManager.HandleDownstreamMsg(baseData.Data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(logTag + "下行数据处理出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InterlockProxy) SendToUpper(data []byte) {
|
||||||
|
err := i.client.Send(data)
|
||||||
|
slog.Error(logTag + "向上位机发送数据失败:" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InterlockProxy) Stop() {
|
||||||
|
initMutex.Lock()
|
||||||
|
defer initMutex.Unlock()
|
||||||
|
delete(interlockMap, i.runConfig.Code)
|
||||||
|
if i.client != nil {
|
||||||
|
i.client.Close()
|
||||||
|
}
|
||||||
|
if i.server != nil {
|
||||||
|
i.server.Close()
|
||||||
|
}
|
||||||
|
i.running = false
|
||||||
|
}
|
86
third_party/interlock/beijing11/msg.go
vendored
Normal file
86
third_party/interlock/beijing11/msg.go
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package beijing11
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc32"
|
||||||
|
"joylink.club/bj-rtsts-server/sys_error"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseStruct struct {
|
||||||
|
ID byte
|
||||||
|
ControlWord byte
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *BaseStruct) Decode(buf []byte) error {
|
||||||
|
if buf[0] != FrameHead {
|
||||||
|
return sys_error.New(logTag + "帧头不正确:" + fmt.Sprintf("%02X", buf[0]))
|
||||||
|
}
|
||||||
|
if buf[len(buf)-1] != FrameTail {
|
||||||
|
return sys_error.New(logTag + "帧尾不正确:" + fmt.Sprintf("%02X", buf[len(buf)-1]))
|
||||||
|
}
|
||||||
|
crc := crc32.ChecksumIEEE(buf[1 : len(buf)-5])
|
||||||
|
if crc != binary.BigEndian.Uint32(buf[len(buf)-5:len(buf)-1]) {
|
||||||
|
return sys_error.New(logTag + "CRC校验失败")
|
||||||
|
}
|
||||||
|
m.ID = buf[1]
|
||||||
|
m.ControlWord = buf[2]
|
||||||
|
m.Data = buf[5 : len(buf)-5]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *BaseStruct) Encode() []byte {
|
||||||
|
var data []byte
|
||||||
|
data = append(data, FrameHead)
|
||||||
|
data = append(data, m.ID)
|
||||||
|
data = append(data, m.ControlWord)
|
||||||
|
data = binary.BigEndian.AppendUint16(data, uint16(len(m.Data)))
|
||||||
|
data = append(data, m.Data...)
|
||||||
|
crc := crc32.ChecksumIEEE(data[1:])
|
||||||
|
data = binary.BigEndian.AppendUint32(data, crc)
|
||||||
|
data = append(data, FrameTail)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReadRegisterReq struct {
|
||||||
|
RegisterAddr []uint16 //寄存器地址
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReadRegisterReq) Decode(buf []byte) error {
|
||||||
|
if len(buf)%2 != 0 {
|
||||||
|
return sys_error.New(logTag + "读寄存器数据字节长度不是2的倍数")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(buf); i += 2 {
|
||||||
|
r.RegisterAddr = append(r.RegisterAddr, binary.BigEndian.Uint16(buf[i:i+2]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReadRegisterRes struct {
|
||||||
|
RegisterData [][]byte //寄存器数据
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReadRegisterRes) Encode() []byte {
|
||||||
|
var data []byte
|
||||||
|
for _, datum := range r.RegisterData {
|
||||||
|
data = append(data, datum...)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
type WriteRegisterReq struct {
|
||||||
|
RegisterAddr []uint16 //寄存器地址
|
||||||
|
RegisterData [][]byte //寄存器数据
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WriteRegisterReq) Decode(buf []byte) error {
|
||||||
|
if len(buf)%6 != 0 {
|
||||||
|
return sys_error.New(logTag + "写寄存器数据字节长度不是6的倍数")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(buf); i += 6 {
|
||||||
|
w.RegisterAddr = append(w.RegisterAddr, binary.BigEndian.Uint16(buf[i:i+2]))
|
||||||
|
w.RegisterData = append(w.RegisterData, buf[i+2:i+6])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
package interlock
|
// Package beijing12 北京12号线联锁通信
|
||||||
|
package beijing12
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
17
third_party/message/dynamics.go
vendored
17
third_party/message/dynamics.go
vendored
@ -78,6 +78,8 @@ type DynamicsTrainInfo struct {
|
|||||||
VobcLifeSignal uint16
|
VobcLifeSignal uint16
|
||||||
//位移(mm)
|
//位移(mm)
|
||||||
Displacement uint16
|
Displacement uint16
|
||||||
|
TrainActToMax bool
|
||||||
|
TrainActToMin bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析动力学的列车信息
|
// 解析动力学的列车信息
|
||||||
@ -89,8 +91,19 @@ func (t *DynamicsTrainInfo) Decode(buf []byte) error {
|
|||||||
t.LinkOffset = binary.BigEndian.Uint32(buf[8:12])
|
t.LinkOffset = binary.BigEndian.Uint32(buf[8:12])
|
||||||
t.Slope = binary.BigEndian.Uint16(buf[12:14])
|
t.Slope = binary.BigEndian.Uint16(buf[12:14])
|
||||||
b := buf[14]
|
b := buf[14]
|
||||||
t.UpSlope = (b & (1 << 7)) != 0
|
t.UpSlope = IsTrueForByte(GetBit(b, 7))
|
||||||
t.Up = (b & (1 << 6)) != 0
|
t.Up = IsTrueForByte(GetBit(b, 6))
|
||||||
|
t.TrainActToMax = IsTrueForByte(GetBit(b, 4))
|
||||||
|
t.TrainActToMin = IsTrueForByte(GetBit(b, 5))
|
||||||
|
|
||||||
|
//t.UpSlope = (b & (1 << 7)) != 0
|
||||||
|
//t.Up = (b & (1 << 6)) != 0
|
||||||
|
//t.TrainActToMax = (b & (1 << 5)) != 0
|
||||||
|
//t.TrainActToMin = (b & (1 << 4)) != 0
|
||||||
|
|
||||||
|
//t.TrainActToMax = (b & (1 << 4)) != 0
|
||||||
|
//t.TrainActToMin = (b & (1 << 5)) != 0
|
||||||
|
|
||||||
t.TotalResistance = int32(binary.BigEndian.Uint32(buf[16:20]))
|
t.TotalResistance = int32(binary.BigEndian.Uint32(buf[16:20]))
|
||||||
t.AirResistance = int32(binary.BigEndian.Uint32(buf[20:24]))
|
t.AirResistance = int32(binary.BigEndian.Uint32(buf[20:24]))
|
||||||
t.SlopeResistance = int32(binary.BigEndian.Uint32(buf[24:28]))
|
t.SlopeResistance = int32(binary.BigEndian.Uint32(buf[24:28]))
|
||||||
|
2
third_party/train_pc_sim/train_pc_sim.go
vendored
2
third_party/train_pc_sim/train_pc_sim.go
vendored
@ -186,7 +186,7 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
|
|||||||
|
|
||||||
s1, s2 := train.PluseCount.PulseCount1, train.PluseCount.PulseCount2
|
s1, s2 := train.PluseCount.PulseCount1, train.PluseCount.PulseCount2
|
||||||
d.speedPlace.ParsePulseCount1(s1, s2)
|
d.speedPlace.ParsePulseCount1(s1, s2)
|
||||||
data := d.speedPlace.Encode(train.RunDirection, s1, s2)
|
data := d.speedPlace.Encode(train.TrainRunUp, s1, s2)
|
||||||
bm := &message.TrainPcSimBaseMessage{Type: SENDER_TRAIN_LOCATION_INFO, Data: data}
|
bm := &message.TrainPcSimBaseMessage{Type: SENDER_TRAIN_LOCATION_INFO, Data: data}
|
||||||
train.PluseCount.PulseCount1 = 0
|
train.PluseCount.PulseCount1 = 0
|
||||||
train.PluseCount.PulseCount2 = 0
|
train.PluseCount.PulseCount2 = 0
|
||||||
|
@ -59,6 +59,20 @@ func findTrainTccGraphicDataHandler(tccG *data_proto.TccGraphicStorage, id uint3
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initTrainVobc(trainLoad int64, trainIsUp bool) (*state_proto.TrainVobcState, uint32) {
|
||||||
|
vobc := &state_proto.TrainVobcState{TrainLoad: int64(trainLoad), BrakingStatus: true, BrakeForce: DEFAULT_BRAKE_FORCE, DirectionForward: true}
|
||||||
|
var trainActDir uint32 = 0
|
||||||
|
if trainIsUp {
|
||||||
|
vobc.Tc1Active = true
|
||||||
|
trainActDir = 1
|
||||||
|
} else {
|
||||||
|
//vobc.Tc1Active = true
|
||||||
|
vobc.Tc2Active = true
|
||||||
|
trainActDir = 2
|
||||||
|
}
|
||||||
|
return vobc, trainActDir
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化列车控制数据
|
// 初始化列车控制数据
|
||||||
func initTrainTcc(vs *VerifySimulation, runDir bool) *state_proto.TrainControlState {
|
func initTrainTcc(vs *VerifySimulation, runDir bool) *state_proto.TrainControlState {
|
||||||
var tccGI *data_proto.TccGraphicStorage
|
var tccGI *data_proto.TccGraphicStorage
|
||||||
|
125
ts/simulation/wayside/memory/wayside_memory_dir_transfer.go
Normal file
125
ts/simulation/wayside/memory/wayside_memory_dir_transfer.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package memory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"joylink.club/rtsssimulation/repository"
|
||||||
|
"joylink.club/rtsssimulation/util/number"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LinkRadialToDeviceRadial Link射线转设备(道岔/区段)射线
|
||||||
|
func LinkRadialToDeviceRadial(repo *repository.Repository, linkPosition *repository.LinkPosition, toBig bool) (sr *DeviceRadial, err error) {
|
||||||
|
link := linkPosition.Link()
|
||||||
|
offset := linkPosition.Offset()
|
||||||
|
if offset > link.Length() {
|
||||||
|
return nil, errors.New(fmt.Sprintf("%d超出%s范围", offset, linkPosition.String()))
|
||||||
|
}
|
||||||
|
//先遍历所有的非道岔计轴区段
|
||||||
|
for _, section := range link.PhysicalSections() {
|
||||||
|
for _, linkRange := range section.LinkRanges() {
|
||||||
|
if linkRange.Link() != link {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if linkRange.Start() <= offset && offset <= linkRange.End() {
|
||||||
|
sectionOffset := number.Abs(offset - section.ALinkPosition().Offset())
|
||||||
|
toB := toBig == (section.BLinkPosition().Offset() > section.ALinkPosition().Offset())
|
||||||
|
aKm := convertRepoBaseKm(repo, section.AKilometer())
|
||||||
|
bKm := convertRepoBaseKm(repo, section.BKilometer())
|
||||||
|
runDirection := toB == (bKm.Value > aKm.Value)
|
||||||
|
sr = &DeviceRadial{
|
||||||
|
DeviceId: section.Id(),
|
||||||
|
Offset: sectionOffset,
|
||||||
|
PointTo: toB,
|
||||||
|
RunDirection: runDirection,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sr != nil {
|
||||||
|
return sr, nil
|
||||||
|
}
|
||||||
|
//Link位置不在非道岔计轴区段上
|
||||||
|
aLinkPosition := link.ARelation().Turnout().FindLinkPositionByPort(link.ARelation().Port())
|
||||||
|
if aLinkPosition.Offset() >= offset { //LinkPosition在A端道岔范围内
|
||||||
|
pointTo := !toBig
|
||||||
|
portKm := convertRepoBaseKm(repo, link.ARelation().Turnout().GetTurnoutKm(link.ARelation().Port()))
|
||||||
|
km := convertRepoBaseKm(repo, link.ARelation().Turnout().Km())
|
||||||
|
runDir := pointTo == (km.Value > portKm.Value)
|
||||||
|
sr = &DeviceRadial{
|
||||||
|
DeviceId: link.ARelation().Turnout().Id(),
|
||||||
|
Offset: offset,
|
||||||
|
PointTo: !toBig,
|
||||||
|
RunDirection: runDir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SectionRadialToLinkRadial 区段射线转Link射线
|
||||||
|
func SectionRadialToLinkRadial(sectionRadial *SectionRadial) (linkPosition *repository.LinkPosition, toBig bool) {
|
||||||
|
toBig = SectionDirToLinkDir(sectionRadial.Section, sectionRadial.ToB)
|
||||||
|
var offset int64
|
||||||
|
if sectionRadial.ToB == toBig { //section与link偏移变化趋势相同
|
||||||
|
offset = sectionRadial.Section.ALinkPosition().Offset() + sectionRadial.Offset
|
||||||
|
} else {
|
||||||
|
offset = sectionRadial.Section.BLinkPosition().Offset() - sectionRadial.Offset
|
||||||
|
}
|
||||||
|
linkPosition = repository.NewLinkPosition(sectionRadial.Section.ALinkPosition().Link(), offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// OperationRadialToLinkRadial 运营射线转Link射线
|
||||||
|
func OperationRadialToLinkRadial(repo *repository.Repository, section *repository.PhysicalSection, offset int64, up bool) (linkPosition *repository.LinkPosition, toBig bool) {
|
||||||
|
toB := OperationDirToSectionDir(repo, section, up)
|
||||||
|
return SectionRadialToLinkRadial(&SectionRadial{
|
||||||
|
Section: section,
|
||||||
|
Offset: offset,
|
||||||
|
ToB: toB,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SectionDirToLinkDir 区段方向转Link方向
|
||||||
|
func SectionDirToLinkDir(section *repository.PhysicalSection, toB bool) (toBig bool) {
|
||||||
|
aOffset := section.ALinkPosition().Offset()
|
||||||
|
bOffset := section.BLinkPosition().Offset()
|
||||||
|
toBig = toB == (bOffset > aOffset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SectionDirToOperationDir 区段方向转运营方向
|
||||||
|
func SectionDirToOperationDir(repo *repository.Repository, section *repository.PhysicalSection, toB bool) (up bool) {
|
||||||
|
aKm := convertRepoBaseKm(repo, section.AKilometer())
|
||||||
|
bKm := convertRepoBaseKm(repo, section.BKilometer())
|
||||||
|
return toB == (bKm.Value > aKm.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OperationDirToSectionDir 运营方向转区段方向
|
||||||
|
func OperationDirToSectionDir(repo *repository.Repository, section *repository.PhysicalSection, up bool) (toB bool) {
|
||||||
|
aKm := convertRepoBaseKm(repo, section.AKilometer())
|
||||||
|
bKm := convertRepoBaseKm(repo, section.BKilometer())
|
||||||
|
return up == (bKm.Value > aKm.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OperationDirToLinkDir 运营方向转Link方向
|
||||||
|
func OperationDirToLinkDir(repo *repository.Repository, section *repository.PhysicalSection, up bool) (toBig bool) {
|
||||||
|
toB := OperationDirToSectionDir(repo, section, up)
|
||||||
|
return SectionDirToLinkDir(section, toB)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SectionRadial 区段射线。包含一个区段位置+方向
|
||||||
|
// 加这个结构体只是因为上面函数返回值过多
|
||||||
|
type SectionRadial struct {
|
||||||
|
Section *repository.PhysicalSection
|
||||||
|
Offset int64
|
||||||
|
ToB bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceRadial 设备射线,包含一个设备位置+方向
|
||||||
|
type DeviceRadial struct {
|
||||||
|
DeviceId string //区段或道岔
|
||||||
|
Offset int64 //在设备上的偏移量
|
||||||
|
PointTo bool //与TrainState结构体中同义。区段:A->B,道岔:->岔心
|
||||||
|
RunDirection bool //与TrainState结构体中同义。公里标 上行:小 -> 大,下行:大 -> 小
|
||||||
|
}
|
@ -243,7 +243,7 @@ func findCalcLinkIdAndOffset(sim *VerifySimulation, link *repository.Link, offse
|
|||||||
}
|
}
|
||||||
// 没有找到连接信息,说明已经到尽头找不到位置
|
// 没有找到连接信息,说明已经到尽头找不到位置
|
||||||
if nextLink == nil {
|
if nextLink == nil {
|
||||||
err = sys_error.New(fmt.Sprintf("未找到对应的link信息, linkId=%s, offset=%d", link.Id(), offset))
|
err = sys_error.New(fmt.Sprintf("未找到对应的link信息, linkId=%s, Offset=%d", link.Id(), offset))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 下个link偏移
|
// 下个link偏移
|
||||||
@ -297,7 +297,7 @@ func getTurnoutNextPort(sim *VerifySimulation, turnoutId string, port string) (n
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算link offset 在道岔上的位置
|
// 计算link Offset 在道岔上的位置
|
||||||
// 入参:仿真Repository、link、是否从A端开始、link偏移量、link运行方向
|
// 入参:仿真Repository、link、是否从A端开始、link偏移量、link运行方向
|
||||||
// 输出:设备Id、设备所在端口、设备偏移量、公里标信息(地图主坐标系)
|
// 输出:设备Id、设备所在端口、设备偏移量、公里标信息(地图主坐标系)
|
||||||
func calcTurnoutOffset(repo *repository.Repository, link *repository.Link, isA bool, offset int64, up bool) (
|
func calcTurnoutOffset(repo *repository.Repository, link *repository.Link, isA bool, offset int64, up bool) (
|
||||||
@ -328,7 +328,7 @@ func calcTurnoutOffset(repo *repository.Repository, link *repository.Link, isA b
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算link offset 在区段上的位置
|
// 计算link Offset 在区段上的位置
|
||||||
// 入参:仿真Repository、link、link偏移量、link运行方向
|
// 入参:仿真Repository、link、link偏移量、link运行方向
|
||||||
// 输出:设备Id、设备所在端口、设备偏移量、公里标信息(地图主坐标系)
|
// 输出:设备Id、设备所在端口、设备偏移量、公里标信息(地图主坐标系)
|
||||||
func calcSectionOffset(repo *repository.Repository, link *repository.Link, offset int64, up bool) (
|
func calcSectionOffset(repo *repository.Repository, link *repository.Link, offset int64, up bool) (
|
||||||
|
@ -50,11 +50,6 @@ func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, conf
|
|||||||
return sys_error.New(fmt.Sprintf("列车【%s】已存在", status.Id))
|
return sys_error.New(fmt.Sprintf("列车【%s】已存在", status.Id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//tcc := createTrainControl(vs)
|
|
||||||
//status.Tcc = tcc
|
|
||||||
|
|
||||||
// 显示状态
|
|
||||||
status.Show = true
|
|
||||||
//向动力学发送初始化请求
|
//向动力学发送初始化请求
|
||||||
trainIndex, _ := strconv.ParseUint(status.Id, 10, 16)
|
trainIndex, _ := strconv.ParseUint(status.Id, 10, 16)
|
||||||
slog.Debug("添加列车", "trainIndex", trainIndex, "HeadDeviceId", status.HeadDeviceId, "HeadOffset", status.HeadOffset)
|
slog.Debug("添加列车", "trainIndex", trainIndex, "HeadDeviceId", status.HeadDeviceId, "HeadOffset", status.HeadOffset)
|
||||||
@ -65,12 +60,16 @@ func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, conf
|
|||||||
} else {
|
} else {
|
||||||
uid = QueryUidByMidAndComId(mapId, status.HeadDeviceId, &data_proto.Turnout{})
|
uid = QueryUidByMidAndComId(mapId, status.HeadDeviceId, &data_proto.Turnout{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 车头所在link、link上的偏移
|
// 车头所在link、link上的偏移
|
||||||
linkId, loffset := QueryLinkAndOffsetByDevice(vs.Repo, uid, status.DevicePort, status.HeadOffset)
|
linkId, loffset := QueryLinkAndOffsetByDevice(vs.Repo, uid, status.DevicePort, status.HeadOffset)
|
||||||
// link上的运行方向、设备上的运行方向
|
// link上的运行方向、设备上的运行方向
|
||||||
up, pointTo := QueryUpAndABByDevice(vs.Repo, uid, status.DevicePort, status.RunDirection)
|
up, pointTo := QueryUpAndABByDevice(vs.Repo, uid, status.DevicePort, status.TrainRunUp)
|
||||||
|
//up, pointTo, _ = QueryDirectionAndABByDevice(vs.Repo, uid, status.DevicePort, status.TrainRunUp)
|
||||||
|
//fmt.Println(up2, pointTo2)
|
||||||
|
|
||||||
// 车头所在公里标
|
// 车头所在公里标
|
||||||
kilometer := CalcTrainKilometer(vs.Repo, uid, status.DevicePort, status.RunDirection, status.HeadOffset)
|
kilometer := CalcTrainKilometer(vs.Repo, uid, status.DevicePort, status.TrainRunUp, status.HeadOffset)
|
||||||
// 车尾相对车头link的偏移量
|
// 车尾相对车头link的偏移量
|
||||||
calctailOffset := calcTrailTailOffset(loffset, status.TrainLength, up)
|
calctailOffset := calcTrailTailOffset(loffset, status.TrainLength, up)
|
||||||
// 车尾位置
|
// 车尾位置
|
||||||
@ -79,7 +78,7 @@ func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, conf
|
|||||||
panic(sys_error.New("添加列车失败,列车车尾占用位置计算出错", e1))
|
panic(sys_error.New("添加列车失败,列车车尾占用位置计算出错", e1))
|
||||||
}
|
}
|
||||||
status.Up = up
|
status.Up = up
|
||||||
status.PointTo = pointTo
|
status.DriftTo = pointTo
|
||||||
status.TrainKilometer = kilometer.Value
|
status.TrainKilometer = kilometer.Value
|
||||||
|
|
||||||
status.DynamicState = &state_proto.TrainDynamicState{
|
status.DynamicState = &state_proto.TrainDynamicState{
|
||||||
@ -87,7 +86,8 @@ func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, conf
|
|||||||
HeadLinkOffset: loffset,
|
HeadLinkOffset: loffset,
|
||||||
TailLinkId: tailLink,
|
TailLinkId: tailLink,
|
||||||
TailLinkOffset: tailLOffset,
|
TailLinkOffset: tailLOffset,
|
||||||
RunningUp: up,
|
RunningUp: status.Up,
|
||||||
|
//RunningUp: status.TrainRunUp,
|
||||||
}
|
}
|
||||||
status.TailDeviceId = vs.GetComIdByUid(tailDeviceId)
|
status.TailDeviceId = vs.GetComIdByUid(tailDeviceId)
|
||||||
status.TailOffset = tailDeviceOffset
|
status.TailOffset = tailDeviceOffset
|
||||||
@ -98,15 +98,13 @@ func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, conf
|
|||||||
if tl <= 0 {
|
if tl <= 0 {
|
||||||
tl = DEFULAT_TRAIN_LOAD
|
tl = DEFULAT_TRAIN_LOAD
|
||||||
}
|
}
|
||||||
status.VobcState = &state_proto.TrainVobcState{TrainLoad: int64(tl), BrakingStatus: true, BrakeForce: DEFAULT_BRAKE_FORCE, DirectionForward: true}
|
|
||||||
//status.VobcState.HistoryDir = request_proto.TrainControl_FORWARD
|
|
||||||
|
|
||||||
if status.RunDirection {
|
vobc, _ := initTrainVobc(int64(tl), status.TrainRunUp)
|
||||||
status.VobcState.Tc1Active = true
|
status.VobcState = vobc
|
||||||
} else {
|
|
||||||
status.VobcState.Tc2Active = true
|
//status.TrainActiveDirection = trainActDir
|
||||||
}
|
|
||||||
status.Tcc = initTrainTcc(vs, status.RunDirection)
|
status.Tcc = initTrainTcc(vs, status.TrainRunUp)
|
||||||
|
|
||||||
slog.Debug("列车初始化", "trainIndex", trainIndex, "linkId", linkId, "loffset", loffset)
|
slog.Debug("列车初始化", "trainIndex", trainIndex, "linkId", linkId, "loffset", loffset)
|
||||||
linkIdInt, _ := strconv.Atoi(linkId)
|
linkIdInt, _ := strconv.Atoi(linkId)
|
||||||
@ -116,6 +114,7 @@ func AddTrainStateNew(vs *VerifySimulation, status *state_proto.TrainState, conf
|
|||||||
LinkOffset: uint32(loffset),
|
LinkOffset: uint32(loffset),
|
||||||
Speed: status.Speed / 3.6,
|
Speed: status.Speed / 3.6,
|
||||||
Up: status.Up,
|
Up: status.Up,
|
||||||
|
//Up: status.TrainRunUp,
|
||||||
TrainOperationConfig: CreateMsgTrainConfig(int(trainIndex), status.TrainLength, configTrainData),
|
TrainOperationConfig: CreateMsgTrainConfig(int(trainIndex), status.TrainLength, configTrainData),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -296,58 +295,42 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
|||||||
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
||||||
//slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
//slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
||||||
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
inLinkId, inLinkOffset := strconv.Itoa(int(info.Link)), int64(info.LinkOffset)
|
||||||
|
|
||||||
outLinkId, id, port, outLinkOffset, offset, kilometer, e1 := CalcInitializeLink(vs, inLinkId, inLinkOffset, info.Up)
|
outLinkId, id, port, outLinkOffset, offset, kilometer, e1 := CalcInitializeLink(vs, inLinkId, inLinkOffset, info.Up)
|
||||||
if e1 != nil {
|
if e1 != nil {
|
||||||
panic(sys_error.New("动力学传输数据:列车车头位置计算出错", e1))
|
panic(sys_error.New("动力学传输数据:列车车头位置计算出错", e1))
|
||||||
}
|
}
|
||||||
|
//runDirection 指定的是link方向
|
||||||
|
//pointTO 指的是是否ab,或是否到岔心
|
||||||
runDirection, pointTo := QueryDirectionAndABByDevice(vs.Repo, id, port, info.Up)
|
runDirection, pointTo := QueryDirectionAndABByDevice(vs.Repo, id, port, info.Up)
|
||||||
//slog.Debug("处理动力学转换后的消息", "number", info.Number, "Link", info.Link, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo)
|
|
||||||
|
slog.Debug("处理动力学转换后的消息", "number", info.Number, "up", info.Up, "Link", info.Link, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo, "t1Dir:", info.TrainActToMax, "t2Dir:", info.TrainActToMin)
|
||||||
|
trainHeadActUp := true
|
||||||
|
if info.TrainActToMax || info.TrainActToMin {
|
||||||
|
if info.TrainActToMin {
|
||||||
|
trainHeadActUp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
// 车尾相对车头link的偏移量
|
// 车尾相对车头link的偏移量
|
||||||
calctailOffset := calcTrailTailOffset(outLinkOffset, int64(info.Len), info.Up)
|
//calctailOffset := calcTrailTailOffset(outLinkOffset, int64(info.Len), info.Up)
|
||||||
|
calctailOffset := calcTrailTailOffset(outLinkOffset, int64(info.Len), trainHeadActUp)
|
||||||
tailLinkId, tailDeviceId, tailDevicePort, tailLinkOffset, tailOffset, _, e2 := CalcInitializeLink(vs, outLinkId, calctailOffset, !info.Up)
|
tailLinkId, tailDeviceId, tailDevicePort, tailLinkOffset, tailOffset, _, e2 := CalcInitializeLink(vs, outLinkId, calctailOffset, !info.Up)
|
||||||
if e2 != nil {
|
if e2 != nil {
|
||||||
panic(sys_error.New("动力学传输数据:列车车尾位置计算出错", e2))
|
panic(sys_error.New("动力学传输数据:列车车尾位置计算出错", e2))
|
||||||
}
|
}
|
||||||
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
//slog.Debug("车尾位置", tailDeviceId, "偏移", tailDeviceOffset, "所在设备端", tailDevicePort)
|
||||||
// 更新BTM中列车位置信息
|
updateTrainBtmPosition(vs, info, sta, outLinkId, outLinkOffset)
|
||||||
can_btm.Default().HandleTrainHeadPositionInfo(vs.World, &fi.TrainHeadPositionInfo{
|
|
||||||
TrainId: trainId,
|
|
||||||
Up: info.Up,
|
|
||||||
Link: outLinkId,
|
|
||||||
LinkOffset: outLinkOffset,
|
|
||||||
Speed: info.Speed,
|
|
||||||
Acceleration: info.Acceleration,
|
|
||||||
})
|
|
||||||
state := can_btm.Default().GetState()
|
|
||||||
sta.BtmState = &state
|
|
||||||
// 修改world中的列车位置
|
// 修改world中的列车位置
|
||||||
fi.UpdateTrainPositionFromDynamics(vs.World, fi.TrainPositionInfo{
|
handleTrainPositionFromDynamic(vs, info, sta, outLinkId, outLinkOffset, tailLinkId, tailLinkOffset)
|
||||||
TrainId: trainId,
|
//修改列车激活方向
|
||||||
Up: info.Up,
|
updateTrainActiveDirFromDynamic(vs, info, sta, id, port, trainHeadActUp)
|
||||||
Len: info.Len,
|
|
||||||
HeadLink: outLinkId,
|
|
||||||
HeadLinkOffset: uint32(outLinkOffset),
|
|
||||||
TailLink: tailLinkId,
|
|
||||||
TailLinkOffset: uint32(tailLinkOffset),
|
|
||||||
})
|
|
||||||
sta.HeadDeviceId = vs.GetComIdByUid(id)
|
sta.HeadDeviceId = vs.GetComIdByUid(id)
|
||||||
sta.DevicePort = port
|
sta.DevicePort = port
|
||||||
sta.HeadOffset = offset
|
sta.HeadOffset = offset
|
||||||
sta.PointTo = pointTo
|
sta.DriftTo = pointTo
|
||||||
sta.TrainKilometer = kilometer.Value
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if info.Speed < 0 {
|
|
||||||
sta.RunDirection = !sta.RunDirection
|
|
||||||
}
|
|
||||||
sta.TailDeviceId = vs.GetComIdByUid(tailDeviceId)
|
sta.TailDeviceId = vs.GetComIdByUid(tailDeviceId)
|
||||||
sta.TailOffset = tailOffset
|
sta.TailOffset = tailOffset
|
||||||
sta.TailDevicePort = tailDevicePort
|
sta.TailDevicePort = tailDevicePort
|
||||||
@ -379,6 +362,47 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
|
|||||||
return sta
|
return sta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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中列车位置信息
|
||||||
|
can_btm.Default().HandleTrainHeadPositionInfo(vs.World, &fi.TrainHeadPositionInfo{
|
||||||
|
TrainId: sta.Id,
|
||||||
|
Up: info.Up,
|
||||||
|
Link: outLinkId,
|
||||||
|
LinkOffset: outLinkOffset,
|
||||||
|
Speed: info.Speed,
|
||||||
|
Acceleration: info.Acceleration,
|
||||||
|
})
|
||||||
|
state := can_btm.Default().GetState()
|
||||||
|
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),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 接受动力学时间15毫米
|
// 接受动力学时间15毫米
|
||||||
const RECEIVE_DYNAMIC_DATA_RATE = 15
|
const RECEIVE_DYNAMIC_DATA_RATE = 15
|
||||||
|
|
||||||
@ -390,7 +414,7 @@ func pluseCount(sta *state_proto.TrainState) {
|
|||||||
if sta.PluseCount == nil {
|
if sta.PluseCount == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if sta.RunDirection {
|
if sta.TrainRunUp {
|
||||||
p1 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
|
p1 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||||
p2 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
|
p2 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
|
||||||
if sta.TrainEndsA.SpeedSensorEnableA {
|
if sta.TrainEndsA.SpeedSensorEnableA {
|
||||||
|
@ -41,7 +41,7 @@ func ControlTrainUpdate(s *VerifySimulation, ct *request_proto.TrainControl) {
|
|||||||
if ct.ControlType == request_proto.TrainControl_EMERGENT_BUTTON {
|
if ct.ControlType == request_proto.TrainControl_EMERGENT_BUTTON {
|
||||||
tce = trainControlEB(vobc, tcc, ct.Button, ct.DeviceId, tccGraphicData)
|
tce = trainControlEB(vobc, tcc, ct.Button, ct.DeviceId, tccGraphicData)
|
||||||
} else if ct.ControlType == request_proto.TrainControl_DRIVER_KEY_SWITCH {
|
} else if ct.ControlType == request_proto.TrainControl_DRIVER_KEY_SWITCH {
|
||||||
tce = trainControlDriverKey(sta.DynamicState.Speed, vobc, tcc, ct.DriverKey, ct.DeviceId, tccGraphicData)
|
tce = trainControlDriverKey(sta, ct.DriverKey, ct.DeviceId, tccGraphicData)
|
||||||
train_pc_sim.Default().SendDriverActive(sta.ConnState, sta.VobcState)
|
train_pc_sim.Default().SendDriverActive(sta.ConnState, sta.VobcState)
|
||||||
} else if ct.ControlType == request_proto.TrainControl_DIRECTION_KEY_SWITCH {
|
} else if ct.ControlType == request_proto.TrainControl_DIRECTION_KEY_SWITCH {
|
||||||
tce = trainControlDirKey(sta.DynamicState.Speed, vobc, tcc, ct.DirKey, ct.DeviceId, tccGraphicData)
|
tce = trainControlDirKey(sta.DynamicState.Speed, vobc, tcc, ct.DirKey, ct.DeviceId, tccGraphicData)
|
||||||
@ -142,15 +142,17 @@ func trainControlDirKey(trainSpeed int32, vobc *state_proto.TrainVobcState, tcc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 列车驾驶端激活
|
// 列车驾驶端激活
|
||||||
func trainControlDriverKey(trainSpeed int32, vobc *state_proto.TrainVobcState, tcc *state_proto.TrainControlState, request *request_proto.TrainControl_DriverKeySwitch, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
|
func trainControlDriverKey(train *state_proto.TrainState, request *request_proto.TrainControl_DriverKeySwitch, deviceId uint32, tccGraphic *data_proto.TccGraphicStorage) []train_pc_sim.TrainControlEvent {
|
||||||
obj, find := findTrainTccGraphicDataKey(tccGraphic, deviceId)
|
obj, find := findTrainTccGraphicDataKey(tccGraphic, deviceId)
|
||||||
if !find {
|
if !find {
|
||||||
slog.Error("未找到对应的驾驶端激活设备deviceId:", deviceId)
|
slog.Error("未找到对应的驾驶端激活设备deviceId:", deviceId)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if trainSpeed != 0 {
|
if train.DynamicState.Speed != 0 {
|
||||||
panic(sys_error.New("因列车未停稳,不支持此操作"))
|
panic(sys_error.New("因列车未停稳,不支持此操作"))
|
||||||
}
|
}
|
||||||
|
vobc := train.VobcState
|
||||||
|
tcc := train.Tcc
|
||||||
if obj.Code == SKQYS1 {
|
if obj.Code == SKQYS1 {
|
||||||
vobc.Tc1Active = request.Val
|
vobc.Tc1Active = request.Val
|
||||||
} else if obj.Code == SKQYS2 {
|
} else if obj.Code == SKQYS2 {
|
||||||
@ -164,6 +166,14 @@ func trainControlDriverKey(trainSpeed int32, vobc *state_proto.TrainVobcState, t
|
|||||||
}
|
}
|
||||||
panic(sys_error.New("驾驶端不能同时激活"))
|
panic(sys_error.New("驾驶端不能同时激活"))
|
||||||
}
|
}
|
||||||
|
train.TrainActiveDirection = 0
|
||||||
|
if vobc.Tc1Active {
|
||||||
|
//train.TrainActiveDirection = 1
|
||||||
|
train.TrainRunUp = true
|
||||||
|
} else if vobc.Tc2Active {
|
||||||
|
//train.TrainActiveDirection = 2
|
||||||
|
train.TrainRunUp = false
|
||||||
|
}
|
||||||
var addNew = true
|
var addNew = true
|
||||||
for _, k := range tcc.DriverKey {
|
for _, k := range tcc.DriverKey {
|
||||||
if k.Id == deviceId {
|
if k.Id == deviceId {
|
||||||
|
@ -3,6 +3,7 @@ package ts
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"joylink.club/bj-rtsts-server/third_party/acc"
|
"joylink.club/bj-rtsts-server/third_party/acc"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/interlock/beijing12"
|
||||||
"joylink.club/bj-rtsts-server/third_party/radar"
|
"joylink.club/bj-rtsts-server/third_party/radar"
|
||||||
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@ -20,7 +21,6 @@ import (
|
|||||||
"joylink.club/bj-rtsts-server/mqtt"
|
"joylink.club/bj-rtsts-server/mqtt"
|
||||||
"joylink.club/bj-rtsts-server/sys_error"
|
"joylink.club/bj-rtsts-server/sys_error"
|
||||||
"joylink.club/bj-rtsts-server/third_party/dynamics"
|
"joylink.club/bj-rtsts-server/third_party/dynamics"
|
||||||
"joylink.club/bj-rtsts-server/third_party/interlock"
|
|
||||||
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
||||||
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
|
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func runThirdParty(s *memory.VerifySimulation) error {
|
|||||||
semi_physical_train.Default().Start(s)
|
semi_physical_train.Default().Start(s)
|
||||||
// 联锁启动
|
// 联锁启动
|
||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
interlock.Default(c).Start(s)
|
beijing12.Default(c).Start(s)
|
||||||
}
|
}
|
||||||
// 计轴RSSP启动
|
// 计轴RSSP启动
|
||||||
axle_device.StartLineAllRsspAxleServices(s)
|
axle_device.StartLineAllRsspAxleServices(s)
|
||||||
@ -149,7 +149,7 @@ func stopThirdParty(s *memory.VerifySimulation) {
|
|||||||
semi_physical_train.Default().Stop()
|
semi_physical_train.Default().Stop()
|
||||||
// 联锁启动
|
// 联锁启动
|
||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
interlock.Default(c).Stop()
|
beijing12.Default(c).Stop()
|
||||||
}
|
}
|
||||||
//计轴RSSP启动销毁
|
//计轴RSSP启动销毁
|
||||||
axle_device.StopLineAllRsspAxleServices()
|
axle_device.StopLineAllRsspAxleServices()
|
||||||
|
Loading…
Reference in New Issue
Block a user