列车pc仿真调整

This commit is contained in:
tiger_zhou 2024-04-18 11:14:05 +08:00
parent 29fc4e265b
commit 4666c84860
8 changed files with 373 additions and 72 deletions

View File

@ -2,16 +2,17 @@ package message
import "log/slog"
//BTM与ATP之间为双向通信ATP定时发送请求帧BTM在未接收到应答器报文时回复状态应答器帧和时间同步帧在接收到应答器报文时回复所有帧
// CreateBtmRspFramesData 数据帧与状态应答帧同时发送给ATP
// CreateBtmRspFramesData BTM与ATP之间为双向通信ATP定时发送请求帧BTM在未接收到应答器报文时回复状态应答器帧和时间同步帧在接收到应答器报文时回复所有帧
//
// 数据帧与状态应答帧同时发送给ATP
//
// 共17帧17X12个字节每个帧12字节
// msg - 应答器报文
// msgPackError - true BTM解包发生错误则数据帧及CRC32A/B全填“0xFF”
func CreateBtmRspFramesData(statusRsp *BtmStatusRspFrame, msg []byte, msgPackError bool, msgTimeA uint32, msgTimeB uint32, tkTimeB uint32, isTrainPcSim bool) ([]byte, bool) {
if len(msg) > 104 { //数据帧最多存储13*8个字节
/* if len(msg) > 104 { //数据帧最多存储13*8个字节
return nil, false
}
}*/
//最近一次ATP查询请求序列号
sn := statusRsp.FId.ID4
//13个BtmDataMessageFrame [0x00,0x0c]
@ -93,6 +94,101 @@ func CreateBtmRspFramesData(statusRsp *BtmStatusRspFrame, msg []byte, msgPackErr
rt = append(rt, dtACf.Encode()...)
rt = append(rt, dtBCf.Encode()...)
rt = append(rt, endCf.Encode()...)
if isTrainPcSim && len(rt) != 221 {
} else if len(rt) != 221 {
slog.Warn("len(rt)!=221")
return nil, false
}
return rt, true
}
func CreateBtmRspFramesDataForPcSim(statusRsp *BtmStatusRspFrame, msg []byte, msgPackError bool, msgTimeA uint32, msgTimeB uint32, tkTimeB uint32, isTrainPcSim bool) ([]byte, bool) {
if len(msg) > 128 { //数据帧最多存储13*8个字节
return nil, false
}
//最近一次ATP查询请求序列号
sn := statusRsp.FId.ID4
//13个BtmDataMessageFrame [0x00,0x0c]
//数据
dms := make([]*BtmDataMessageFrame, 14)
for mr := 0x00; mr <= 0x0E; mr++ {
dms[mr] = NewBtmDataMessageFrame(sn, byte(mr), isTrainPcSim)
dms[mr].Message = make([]byte, 8) //8字节数组默认值0
//
if !msgPackError {
mi := mr * 8
if mi < len(msg) { //数据帧中有<=8个字节数据
if mi+7 < len(msg) {
dms[mr].Message = msg[mi : mi+8]
} else {
for i, d := range msg[mi:] {
dms[mr].Message[i] = d
}
}
}
} else { //BTM解包发生错误则数据帧及CRC32A/B全填“0xFF”
for c := 0; c < 8; c++ {
dms[mr].Message[c] = 0xff
}
}
}
//
dtA := NewBtmDataMessageTimeAFrame(sn, isTrainPcSim)
//dtA.TimeA = msgTimeA
//if !msgPackError {
// var crc32AData []byte
// crc32AData = append(crc32AData, msg...)
// crc32AData = append(crc32AData, canTimeToBytes(dtA.TimeA)...)
// dtA.Crc32A = Can_Crc32(crc32AData) //CRC32A的校验范围是报文+时间戳A
//} else { //BTM解包发生错误则数据帧及CRC32A/B全填“0xFF”
// dtA.Crc32A = 0xff_ff_ff_ff
//}
//
dtB := NewBtmDataMessageTimeBFrame(sn, isTrainPcSim)
dtB.TimeB = msgTimeB
if !msgPackError {
var crc32BData []byte
crc32BData = append(crc32BData, msg...)
crc32BData = append(crc32BData, canTimeToBytes(dtB.TimeB)...)
dtB.Crc32B = Can_Crc32(crc32BData) //CRC32B的校验范围是报文+时间戳B
} else { //BTM解包发生错误则数据帧及CRC32A/B全填“0xFF”
dtB.Crc32B = 0xff_ff_ff_ff
}
//
end := NewBtmDataMessageEndFrame(sn, isTrainPcSim)
end.TkB = tkTimeB
//
statusCf := statusRsp.Encode()
dmsCfs := make([]*CanetFrame, 0, 13)
for _, dm := range dms {
dmsCfs = append(dmsCfs, dm.Encode())
}
dtACf := dtA.Encode()
dtBCf := dtB.Encode()
//
crc32cData := make([]byte, 0, 132)
crc32cData = append(crc32cData, statusCf.CanData...)
for _, dmCf := range dmsCfs {
crc32cData = append(crc32cData, dmCf.CanData...)
}
crc32cData = append(crc32cData, dtACf.CanData...)
crc32cData = append(crc32cData, dtBCf.CanData...)
crc32cData = append(crc32cData, canTimeToBytes(end.TkB)...)
//
end.Crc32C = Can_Crc32(crc32cData)
//
endCf := end.Encode()
//
rt := make([]byte, 0, 221) //17*13
rt = append(rt, statusCf.Encode()...)
for _, dmCf := range dmsCfs {
rt = append(rt, dmCf.Encode()...)
}
rt = append(rt, dtACf.Encode()...)
rt = append(rt, dtBCf.Encode()...)
rt = append(rt, endCf.Encode()...)
if len(rt) != 221 {
slog.Warn("len(rt)!=221")
return nil, false

View File

@ -49,16 +49,17 @@ func (p *CanetFrame) Encode() []byte {
}
func (p *CanetFrame) Decode(buf []byte) {
if len(buf) != 13 {
panic("len(buf)!=13")
}
//
if !p.IsTrainPcSim {
if len(buf) != 13 {
panic("len(buf)!=13")
}
p.FF = buf[0]&0x80 == 0x80
p.RTR = buf[0]&0x40 == 0x40
p.CanLen = buf[0] & 0x0f
}
p.CanLen = buf[0] & 0x0f
//1 2 3 4
p.CanId.ID1 = buf[1]
p.CanId.ID2 = buf[2]

View File

@ -28,7 +28,6 @@ func (tp *TrainPcSimBaseMessage) Encode() []byte {
binary.Write(dataBufs, binary.BigEndian, tp.Data)
data := dataBufs.Bytes()
pack = append(pack, data...)
pack = binary.BigEndian.AppendUint16(pack, uint16(crc.CalculateCRC(crc.CRC16, data)))
return pack
}
@ -109,6 +108,24 @@ func (tp *TrainSpeedPlaceReportMsg) Encode(runDir bool, s1, s2 uint32) []byte {
return data
}
func (tp *TrainSpeedPlaceReportMsg) Decode(d []byte) {
buf := bytes.NewBuffer(d)
var runDir uint16
binary.Read(buf, binary.BigEndian, &runDir)
var s1 uint32
binary.Read(buf, binary.BigEndian, &s1)
var s2 uint32
binary.Read(buf, binary.BigEndian, &s2)
var c1 uint32
binary.Read(buf, binary.BigEndian, &c1)
var c2 uint32
binary.Read(buf, binary.BigEndian, &c2)
var ts uint32
binary.Read(buf, binary.BigEndian, &ts)
fmt.Println(runDir, s1, s2, c1, c2, ts)
}
// 轨旁向列车pc仿真发送的命令码
const (
//钥匙开关状态

View File

@ -41,7 +41,7 @@ func StartTcpClient(rAddr string, handler func(n int, data []byte), readErr func
}
if err == io.EOF {
slog.Warn(fmt.Sprintf("TCP客户端[rAddr:%s]断开连接:", rAddr))
break
readErr(err)
}
}
handler(l, data)
@ -57,15 +57,15 @@ func (c *TcpClient) Close() {
c.conn = nil
}
}
func (c *TcpClient) Send(data []byte) {
func (c *TcpClient) Send(data []byte) error {
if c.conn == nil {
slog.Error("tcp client send error,conn is nil")
return
return fmt.Errorf("TCP未连接车载PC仿真")
}
_, err := c.conn.Write(data)
if err != nil {
slog.Error("tcp client send error", "error", err)
return err
}
return nil
}

View File

@ -1,12 +1,14 @@
package main
import (
"encoding/binary"
"fmt"
"io"
"joylink.club/bj-rtsts-server/third_party/message"
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
"log/slog"
"net"
"strconv"
)
type TcpConnHandler = func(conn net.Conn)
@ -33,14 +35,14 @@ func tcpRunAcceptTask(listen net.Listener, port int, connHandler TcpConnHandler,
func tcpRunReadTask(conn net.Conn, port int, msgHandler TcpMsgHandler) {
go func() {
defer func() {
/* defer func() {
if err := recover(); err != nil {
slog.Error(fmt.Sprintf("TCP服务端[port:%d]读数据任务异常:", port), err)
serConn.Close()
serConn = nil
}
}()
}()*/
for {
data := make([]byte, 1024)
l, err := conn.Read(data)
@ -87,6 +89,72 @@ func changeDoorMode() *message.TrainPcSimBaseMessage {
return msg
}
func boolsToByte(flags [8]bool) byte {
var result uint8
for index, b := range flags {
if b {
result = result + (1 << index)
}
}
return result
}
func pcSimInfoOut() *message.TrainPcSimBaseMessage {
msg := &message.TrainPcSimBaseMessage{}
msg.Type = train_pc_sim.RECIVE_TRAIN_INTERFACE_CABINET_OUTR
data := make([]byte, 0)
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
data = append(data, boolsToByte([8]bool{true, false, false, false, false, false, false, false}))
msg.Data = data
return msg
}
func pcSimInfoOutReport() *message.TrainPcSimBaseMessage {
msg := &message.TrainPcSimBaseMessage{}
msg.Type = train_pc_sim.RECIVE_TRAIN_INTERFACE_CABINET_OUTR_BACK
data := make([]byte, 0)
data = append(data, boolsToByte([8]bool{true, true, false, false, false, false, false, false}))
msg.Data = data
return msg
}
var autoIncNo = 0
func queryBtm() *message.TrainPcSimBaseMessage {
msg := &message.TrainPcSimBaseMessage{}
msg.Type = train_pc_sim.RECIVE_TRAIN_QUERY_STATUS
autoIncNo = autoIncNo + 1
data := make([]byte, 0)
data = append(data, 0x62)
data = append(data, 0x81)
data = append(data, 0x02)
data = append(data, byte(autoIncNo)<<3)
data = append(data, boolsToByte([8]bool{true, true, false, false, false, false, false, false}))
data = append(data, 0) //速度低位
data = append(data, 0) //当前时间高位
data = append(data, 0) //当前时间
data = append(data, 0) //当前时间
data = append(data, 0) //当前时间低位
data = append(data, 0) //当前时间低位
data = append(data, 0) //CRC16-H(MSB
data = append(data, 0) //CRC16-L(LSB)
msg.Data = data
return msg
}
func pcSimNumReportOut() *message.TrainPcSimBaseMessage {
msg := &message.TrainPcSimBaseMessage{}
msg.Type = train_pc_sim.RECIVE_TRAIN_MOCK_DATA
sd := uint16(1234)
data := make([]byte, 2)
binary.BigEndian.PutUint16(data, sd)
msg.Data = data
return msg
}
// 测试创建连接
/*func TestConn(t *testing.T) {
createServer(func(n int, data []byte) {
@ -99,16 +167,68 @@ func main() {
createServer(func(n int, data []byte) {
msg := &message.TrainPcSimBaseMessage{}
msg.Decode(data)
d := data[:n]
msg.Decode(d)
pd := fmt.Sprintf("%X", d)
if msg.Type == train_pc_sim.SENDER_TRAIN_TC_ACTIVE {
fmt.Println("接收驾驶端激活")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.SENDER_TRAIN_TC_NOT_ACTIVE {
fmt.Println("接收驾驶端未激活")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.SENDER_TRAIN_OUTR_INFO {
fmt.Println("接受列车输出数字量", msg.Data[0], msg.Data[1])
fmt.Println(pd)
t := msg.Data[0]
s := msg.Data[1]
tt := strconv.Itoa(int(t))
switch t {
case 0:
tt = "驾驶台"
case 1:
tt = "手柄向前"
case 2:
tt = "手柄向后"
case 14:
tt = "手柄归零"
case 4:
tt = "制动状态"
}
fmt.Println("接受列车输出数字量", tt, s)
fmt.Println(pd)
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE {
fmt.Println("创建或删除列车")
}
state := msg.Data[0]
if state == 0x01 {
fmt.Println("创建列车")
} else if state == 0x00 {
fmt.Println("删除列车")
}
fmt.Println(pd)
} else if msg.Type == train_pc_sim.SENDER_TRAIN_HAND_KEY_FORWARD {
fmt.Println("列车手柄向前")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD {
fmt.Println("列车手柄取消向前")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_BACKWARD {
fmt.Println("列车手柄向后")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD {
fmt.Println("列车手柄取消向后")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_BTM_HAS_DATA {
fmt.Println("有数据应答")
fmt.Println(pd)
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_BTM_NOT_DATA {
} /*else if msg.Type == train_pc_sim.SENDER_TRAIN_LOCATION_INFO {
fmt.Println("列车速度位置报告")
fmt.Println(pd)
mp := message.TrainSpeedPlaceReportMsg{}
mp.Decode(msg.Data)
}*/
})
//reader := bufio.NewReader(os.Stdin)
@ -129,6 +249,19 @@ func main() {
} else if command == "door-mode" {
msg := changeDoorMode()
serConn.Write(msg.Encode())
} else if command == "info-out" {
msg := pcSimInfoOut()
serConn.Write(msg.Encode())
} else if command == "info-out-report" {
msg := pcSimInfoOutReport()
serConn.Write(msg.Encode())
} else if command == "query-btm" {
msg := queryBtm()
serConn.Write(msg.Encode())
} else if command == "num-out" {
msg := pcSimNumReportOut()
serConn.Write(msg.Encode())
}
command = ""
/*content, _ := reader.ReadString('\n')

View File

@ -10,6 +10,7 @@ import (
"joylink.club/bj-rtsts-server/third_party/tpapi"
"joylink.club/ecs"
"log/slog"
"strconv"
"sync"
"time"
)
@ -27,7 +28,7 @@ type TrainPcSim interface {
//发送驾驶端激活
SendDriverActive(tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
//发送牵引制动手柄
SendHandleSwitch(oldTraction, oldBrakeForce int64, isBrake bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState)
//列车运行方向
//因文档说明不清楚,在调用的时候目前是注释状态,现场调试可能会用到
SendTrainDirection(trainForward, trainBackward bool)
@ -38,7 +39,7 @@ type TrainPcSim interface {
CreateOrRemoveSpeedPLace(train *state_proto.TrainState)
CreateOrRemoveTrain(msgType byte, data []byte)
CreateOrRemoveTrain(msgType byte, data []byte) error
tpapi.ThirdPartyApiService
}
@ -102,18 +103,29 @@ func (d *trainPcSimService) readError(err error) {
}
func (d *trainPcSimService) connTrainPcSim() {
reconnIndex := 0
for {
client, err := tcp.StartTcpClient(fmt.Sprintf("%v:%v", d.config.PcSimIp, d.config.PcSimPort), d.reivceData, d.readError)
if err != nil {
reconnIndex++
slog.Error("连接车载pc平台失败尝试=", reconnIndex, err)
d.updateState(tpapi.ThirdPartyState_Broken)
} else {
d.pcSimClient = client
return
ctx, ctxFun := context.WithCancel(context.Background())
go func() {
for {
select {
case <-ctx.Done():
return
default:
}
client, err := tcp.StartTcpClient(fmt.Sprintf("%v:%v", d.config.PcSimIp, d.config.PcSimPort), d.reivceData, d.readError)
if err != nil {
reconnIndex++
slog.Error("连接车载pc平台失败尝试=", strconv.Itoa(reconnIndex), err)
d.updateState(tpapi.ThirdPartyState_Broken)
} else {
d.pcSimClient = client
ctxFun()
return
}
time.Sleep(time.Second)
}
time.Sleep(time.Second * 1)
}
}()
}
func (d *trainPcSimService) Start(wd ecs.World, pcSimManage TrainPcSimManage) {
config := pcSimManage.GetTrainPcSimConfig()
@ -127,7 +139,7 @@ func (d *trainPcSimService) Start(wd ecs.World, pcSimManage TrainPcSimManage) {
d.cancleContext = ctxFun
d.trainPcSimManage = pcSimManage
FireTrainControlEventType.Subscribe(wd, d.trainControlEventHandle)
//FireTrainControlEventType.Subscribe(wd, d.trainControlEventHandle)
d.updateState(tpapi.ThirdPartyState_Normal)
go d.sendTrainLocationAndSpeedTask(ctx)
@ -153,9 +165,10 @@ func (d *trainPcSimService) CreateOrRemoveSpeedPLace(train *state_proto.TrainSta
d.speedPlace = nil
}
}
func (d *trainPcSimService) CreateOrRemoveTrain(msgType byte, data []byte) {
func (d *trainPcSimService) CreateOrRemoveTrain(msgType byte, data []byte) error {
msg := &message.TrainPcSimBaseMessage{Data: data, Type: uint16(msgType)}
d.pcSimClient.Send(msg.Encode())
return d.pcSimClient.Send(msg.Encode())
}
// 依据文档80ms发送列车速度位置
@ -167,7 +180,8 @@ func (d *trainPcSimService) sendTrainLocationAndSpeedTask(ctx context.Context) {
default:
}
train := d.trainPcSimManage.GetConnTrain()
if train != nil && train.ConnState.Conn {
if train != nil && train.ConnState.Conn && train.PluseCount != nil {
s1, s2 := train.PluseCount.PulseCount1, train.PluseCount.PulseCount2
d.speedPlace.ParsePulseCount1(s1, s2)
data := d.speedPlace.Encode(train.RunDirection, s1, s2)
@ -193,26 +207,34 @@ func (d *trainPcSimService) SendDriverActive(tc *state_proto.TrainConnState, vob
d.pcSimClient.Send(msg.Encode())
}
}
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, isBrake bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
func (d *trainPcSimService) SendHandleSwitch(oldTraction, oldBrakeForce int64, tractionState bool, tc *state_proto.TrainConnState, vobc *state_proto.TrainVobcState) {
if tc.Conn && tc.ConnType == state_proto.TrainConnState_PC_SIM {
msg := &message.TrainPcSimBaseMessage{}
newTraction := vobc.TractionForce
newBrake := vobc.BrakeForce
if isBrake {
if newBrake < oldBrakeForce && newBrake == 0 {
//手柄取消后退
msg.Type = RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD
} else if newBrake > oldBrakeForce {
//手柄后退
msg.Type = RECIVE_TRAIN_HAND_KEY_BACKWARD
}
} else {
if newTraction < oldTraction && newTraction == 0 {
newBrake := -vobc.BrakeForce
newOldBrakeForce := -oldBrakeForce
if tractionState {
if newTraction <= oldTraction && newTraction == 0 {
//手柄取消前进
msg.Type = RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD
} else if newTraction > oldTraction {
//手柄前进
msg.Type = SENDER_TRAIN_HAND_KEY_FORWARD
} else {
//手柄前进
msg.Type = SENDER_TRAIN_HAND_KEY_FORWARD
}
} else {
if newBrake >= newOldBrakeForce && newBrake == 0 {
//手柄取消后退
msg.Type = RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD
} else if newBrake < newOldBrakeForce {
//手柄后退
msg.Type = RECIVE_TRAIN_HAND_KEY_BACKWARD
} else {
//手柄后退
msg.Type = RECIVE_TRAIN_HAND_KEY_BACKWARD
}
}
d.pcSimClient.Send(msg.Encode())
@ -238,6 +260,8 @@ func (d *trainPcSimService) SendBaliseData(msgType uint16, data []byte) {
msg := &message.TrainPcSimBaseMessage{}
msg.Type = msgType
msg.Data = data
//fmt.Println(fmt.Sprintf("%X", msg.Encode()))
d.pcSimClient.Send(msg.Encode())
}
@ -254,7 +278,13 @@ func (d *trainPcSimService) PublishTrainControlEvent(world ecs.World, events []T
return
}
for _, event := range events {
FireTrainControlEventType.Publish(world, &event)
msg := &message.TrainPcSimBaseMessage{}
msg.Type = SENDER_TRAIN_OUTR_INFO
data := []byte{event.Command, event.Status}
msg.Data = data
d.pcSimClient.Send(msg.Encode())
//FireTrainControlEventType.Publish(world, &event)
}
}

View File

@ -5,6 +5,7 @@ import (
"joylink.club/bj-rtsts-server/dto/common_proto"
"joylink.club/bj-rtsts-server/service"
"joylink.club/bj-rtsts-server/third_party/can_btm"
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
"log/slog"
"math"
"reflect"
@ -149,11 +150,15 @@ func TrainConnTypeUpdate(vs *VerifySimulation, ct *dto.TrainConnThirdDto) {
return true
})
}
if ct.ConnType == state_proto.TrainConnState_PC_SIM {
err := TrainPcSimConnOrRemoveHandle(train)
if err != nil {
panic(sys_error.New("连接车载PC仿真失败"))
}
train_pc_sim.Default().SendDriverActive(train.ConnState, train.VobcState)
}
train.ConnState.Conn = true
train.ConnState.ConnType = ct.ConnType
if train.ConnState.ConnType == state_proto.TrainConnState_PC_SIM {
TrainPcSimConnOrRemoveHandle(train)
}
}
// 列车断开三方连接
@ -168,8 +173,13 @@ func TrainUnConn(vs *VerifySimulation, trainId string) {
train.ConnState.Conn = false
train.ConnState.ConnType = state_proto.TrainConnState_NONE
if oldType == state_proto.TrainConnState_PC_SIM {
TrainPcSimConnOrRemoveHandle(train)
err := TrainPcSimConnOrRemoveHandle(train)
if err != nil {
panic(sys_error.New("未连接车载PC仿真无法断开连接"))
}
}
train.ConnState.Conn = false
train.ConnState.ConnType = state_proto.TrainConnState_NONE
}
func createOrUpdateStateDynamicConfig(trainState *state_proto.TrainState, configTrainData dto.ConfigTrainData, trainEndsA dto.ConfigTrainEnds,
trainEndsB dto.ConfigTrainEnds) {
@ -334,24 +344,30 @@ func UpdateTrainStateByDynamics(vs *VerifySimulation, trainId string, info *mess
const RECEIVE_DYNAMIC_DATA_RATE = 15
func formatSpeedTime(s int32) int32 {
d3, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", s), 64)
return int32(math.Abs(math.Round(d3)))
//d3, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", s), 64)
return int32(math.Abs(math.Round(float64(s))))
}
func pluseCount(sta *state_proto.TrainState) {
if sta.PluseCount == nil {
return
}
if sta.RunDirection {
p1 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
p2 := uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
if sta.TrainEndsA.SpeedSensorEnableA {
sta.PluseCount.PulseCount1 += uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
} else if sta.TrainEndsA.SpeedSensorEnableB {
sta.PluseCount.PulseCount2 += uint32(formatSpeedTime(sta.DynamicState.HeadSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
sta.PluseCount.PulseCount1 = sta.PluseCount.PulseCount1 + p1
}
if sta.TrainEndsA.SpeedSensorEnableB {
sta.PluseCount.PulseCount2 = sta.PluseCount.PulseCount2 + p2
}
} else {
t1 := uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
t2 := uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
if sta.TrainEndsB.SpeedSensorEnableA {
sta.PluseCount.PulseCount1 += uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed1 * RECEIVE_DYNAMIC_DATA_RATE))
} else if sta.TrainEndsB.SpeedSensorEnableB {
sta.PluseCount.PulseCount2 += uint32(formatSpeedTime(sta.DynamicState.TailSensorSpeed2 * RECEIVE_DYNAMIC_DATA_RATE))
sta.PluseCount.PulseCount1 = sta.PluseCount.PulseCount1 + t1
}
if sta.TrainEndsB.SpeedSensorEnableB {
sta.PluseCount.PulseCount2 = sta.PluseCount.PulseCount2 + t2
}
}
}

View File

@ -48,9 +48,9 @@ func ControlTrainUpdate(s *VerifySimulation, ct *request_proto.TrainControl) {
} else if ct.ControlType == request_proto.TrainControl_HANDLER {
oldTraction := sta.VobcState.TractionForce
oldBrakeForce := sta.VobcState.BrakeForce
isBrake := ct.Handler.Val < 0 //是否制动
isTraction := ct.Handler.Val > 0 //是否制动
tce = trainControlHandle(sta, ct.Handler, ct.DeviceId, tccGraphicData)
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isBrake, sta.ConnState, sta.VobcState)
train_pc_sim.Default().SendHandleSwitch(oldTraction, oldBrakeForce, isTraction, sta.ConnState, sta.VobcState)
}
if sta.ConnState.Conn && sta.ConnState.ConnType == state_proto.TrainConnState_PC_SIM && tce != nil {
@ -96,7 +96,10 @@ func trainControlDirKey(trainState *state_proto.TrainState, request *request_pro
} else {
trainState.Tcc.DirKey.Val = request.Val
}
return nil
tce := make([]train_pc_sim.TrainControlEvent, 0)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: message.IsTrue(trainState.VobcState.DirectionForward)})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: message.IsTrue(trainState.VobcState.DirectionBackward)})
return tce
}
// 列车驾驶端激活
@ -141,17 +144,18 @@ func trainControlHandle(trainState *state_proto.TrainState, request *request_pro
trainState.VobcState.BrakeForce = 0
trainState.VobcState.MaintainBrakeStatus = false
tce := make([]train_pc_sim.TrainControlEvent, 0)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 0})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 0})
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 0})
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 0})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_TO_ZERO, Status: 0})
if request.Val > 0 {
trainState.VobcState.TractionStatus = true
trainState.VobcState.TractionForce = int64(request.Val * 180)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 1})
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_FORWORD, Status: 1})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 0})
} else if request.Val < 0 {
trainState.VobcState.BrakingStatus = true
trainState.VobcState.BrakeForce = int64(-request.Val * 180)
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 1})
//tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.HANDLE_BACKWORD, Status: 1})
tce = append(tce, train_pc_sim.TrainControlEvent{Command: message.TRAIN_BRAKE_STATE, Status: 1})
} else {
@ -372,13 +376,17 @@ func (s *VerifySimulation) TrainPcSimDigitalReportHandle(data []byte) {
}
// 创建/删除列车
func TrainPcSimConnOrRemoveHandle(train *state_proto.TrainState) {
func TrainPcSimConnOrRemoveHandle(train *state_proto.TrainState) error {
var data byte = 0x01
if train.ConnState.Conn == false {
data = 0x00
}
train_pc_sim.Default().CreateOrRemoveTrain(train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE, []byte{data})
crErr := train_pc_sim.Default().CreateOrRemoveTrain(train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE, []byte{data})
if crErr != nil {
return crErr
}
train_pc_sim.Default().CreateOrRemoveSpeedPLace(train)
return nil
}
// 门模式