diff --git a/ats/verify/protos/state/device_state.pb.go b/ats/verify/protos/state/device_state.pb.go index 2748723..511733e 100644 --- a/ats/verify/protos/state/device_state.pb.go +++ b/ats/verify/protos/state/device_state.pb.go @@ -448,27 +448,27 @@ type TrainState struct { // 列车当前运行方向,1 =上行true 0 =下行false RunningUp bool `protobuf:"varint,11,opt,name=runningUp,proto3" json:"runningUp,omitempty"` // 实际运行阻力(总),1=1KN - RunningResistanceSum int32 `protobuf:"varint,12,opt,name=runningResistanceSum,proto3" json:"runningResistanceSum,omitempty"` + RunningResistanceSum float32 `protobuf:"fixed32,12,opt,name=runningResistanceSum,proto3" json:"runningResistanceSum,omitempty"` // 阻力1(空气阻力),1=1KN - AirResistance int32 `protobuf:"varint,13,opt,name=airResistance,proto3" json:"airResistance,omitempty"` + AirResistance float32 `protobuf:"fixed32,13,opt,name=airResistance,proto3" json:"airResistance,omitempty"` // 阻力2(坡道阻力),1=1KN - RampResistance int32 `protobuf:"varint,14,opt,name=rampResistance,proto3" json:"rampResistance,omitempty"` + RampResistance float32 `protobuf:"fixed32,14,opt,name=rampResistance,proto3" json:"rampResistance,omitempty"` // 阻力3(曲线阻力),1=1KN - CurveResistance int32 `protobuf:"varint,15,opt,name=curveResistance,proto3" json:"curveResistance,omitempty"` + CurveResistance float32 `protobuf:"fixed32,15,opt,name=curveResistance,proto3" json:"curveResistance,omitempty"` // 列车运行速度,1=1km/h - Speed int32 `protobuf:"varint,16,opt,name=speed,proto3" json:"speed,omitempty"` + Speed float32 `protobuf:"fixed32,16,opt,name=speed,proto3" json:"speed,omitempty"` // 头车速传1速度值,1=1km/h - HeadSensorSpeed1 int32 `protobuf:"varint,17,opt,name=headSensorSpeed1,proto3" json:"headSensorSpeed1,omitempty"` + HeadSensorSpeed1 float32 `protobuf:"fixed32,17,opt,name=headSensorSpeed1,proto3" json:"headSensorSpeed1,omitempty"` // 头车速传2速度值,1=1km/h - HeadSensorSpeed2 int32 `protobuf:"varint,18,opt,name=headSensorSpeed2,proto3" json:"headSensorSpeed2,omitempty"` + HeadSensorSpeed2 float32 `protobuf:"fixed32,18,opt,name=headSensorSpeed2,proto3" json:"headSensorSpeed2,omitempty"` // 尾车速传1速度值,1=1km/h - TailSensorSpeed1 int32 `protobuf:"varint,19,opt,name=tailSensorSpeed1,proto3" json:"tailSensorSpeed1,omitempty"` + TailSensorSpeed1 float32 `protobuf:"fixed32,19,opt,name=tailSensorSpeed1,proto3" json:"tailSensorSpeed1,omitempty"` // 尾车速度2速度值,1=1km/h - TailSensorSpeed2 int32 `protobuf:"varint,20,opt,name=tailSensorSpeed2,proto3" json:"tailSensorSpeed2,omitempty"` + TailSensorSpeed2 float32 `protobuf:"fixed32,20,opt,name=tailSensorSpeed2,proto3" json:"tailSensorSpeed2,omitempty"` // 头车雷达速度值,1=1km/h - HeadRadarSpeed int32 `protobuf:"varint,21,opt,name=headRadarSpeed,proto3" json:"headRadarSpeed,omitempty"` + HeadRadarSpeed float32 `protobuf:"fixed32,21,opt,name=headRadarSpeed,proto3" json:"headRadarSpeed,omitempty"` // 尾车雷达速度值,1=1km/h - TailRadarSpeed int32 `protobuf:"varint,22,opt,name=tailRadarSpeed,proto3" json:"tailRadarSpeed,omitempty"` + TailRadarSpeed float32 `protobuf:"fixed32,22,opt,name=tailRadarSpeed,proto3" json:"tailRadarSpeed,omitempty"` // 列车长度,1=1mm TrainLength int64 `protobuf:"varint,23,opt,name=trainLength,proto3" json:"trainLength,omitempty"` // 列车是否显示 @@ -584,77 +584,77 @@ func (x *TrainState) GetRunningUp() bool { return false } -func (x *TrainState) GetRunningResistanceSum() int32 { +func (x *TrainState) GetRunningResistanceSum() float32 { if x != nil { return x.RunningResistanceSum } return 0 } -func (x *TrainState) GetAirResistance() int32 { +func (x *TrainState) GetAirResistance() float32 { if x != nil { return x.AirResistance } return 0 } -func (x *TrainState) GetRampResistance() int32 { +func (x *TrainState) GetRampResistance() float32 { if x != nil { return x.RampResistance } return 0 } -func (x *TrainState) GetCurveResistance() int32 { +func (x *TrainState) GetCurveResistance() float32 { if x != nil { return x.CurveResistance } return 0 } -func (x *TrainState) GetSpeed() int32 { +func (x *TrainState) GetSpeed() float32 { if x != nil { return x.Speed } return 0 } -func (x *TrainState) GetHeadSensorSpeed1() int32 { +func (x *TrainState) GetHeadSensorSpeed1() float32 { if x != nil { return x.HeadSensorSpeed1 } return 0 } -func (x *TrainState) GetHeadSensorSpeed2() int32 { +func (x *TrainState) GetHeadSensorSpeed2() float32 { if x != nil { return x.HeadSensorSpeed2 } return 0 } -func (x *TrainState) GetTailSensorSpeed1() int32 { +func (x *TrainState) GetTailSensorSpeed1() float32 { if x != nil { return x.TailSensorSpeed1 } return 0 } -func (x *TrainState) GetTailSensorSpeed2() int32 { +func (x *TrainState) GetTailSensorSpeed2() float32 { if x != nil { return x.TailSensorSpeed2 } return 0 } -func (x *TrainState) GetHeadRadarSpeed() int32 { +func (x *TrainState) GetHeadRadarSpeed() float32 { if x != nil { return x.HeadRadarSpeed } return 0 } -func (x *TrainState) GetTailRadarSpeed() int32 { +func (x *TrainState) GetTailRadarSpeed() float32 { if x != nil { return x.TailRadarSpeed } @@ -934,33 +934,33 @@ var file_device_state_proto_rawDesc = []byte{ 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x12, 0x32, 0x0a, 0x14, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x69, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x02, 0x52, 0x14, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x75, 0x6d, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x69, 0x72, 0x52, 0x65, 0x73, 0x69, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x69, 0x72, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0d, 0x61, 0x69, 0x72, 0x52, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x61, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0e, 0x72, 0x61, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x28, 0x02, 0x52, 0x0e, 0x72, 0x61, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x75, 0x72, 0x76, 0x65, 0x52, 0x65, 0x73, 0x69, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x75, 0x72, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x76, 0x65, 0x52, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, + 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x68, 0x65, 0x61, 0x64, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, - 0x53, 0x70, 0x65, 0x65, 0x64, 0x31, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x68, 0x65, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x31, 0x18, 0x11, 0x20, 0x01, 0x28, 0x02, 0x52, 0x10, 0x68, 0x65, 0x61, 0x64, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x31, 0x12, 0x2a, 0x0a, 0x10, 0x68, 0x65, 0x61, 0x64, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, - 0x64, 0x32, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x68, 0x65, 0x61, 0x64, 0x53, 0x65, + 0x64, 0x32, 0x18, 0x12, 0x20, 0x01, 0x28, 0x02, 0x52, 0x10, 0x68, 0x65, 0x61, 0x64, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x32, 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x31, 0x18, 0x13, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x10, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x31, 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x65, - 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x32, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, + 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x32, 0x18, 0x14, 0x20, 0x01, 0x28, 0x02, 0x52, 0x10, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x32, 0x12, 0x26, 0x0a, 0x0e, 0x68, 0x65, 0x61, 0x64, 0x52, 0x61, 0x64, 0x61, 0x72, 0x53, - 0x70, 0x65, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x68, 0x65, 0x61, 0x64, + 0x70, 0x65, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x68, 0x65, 0x61, 0x64, 0x52, 0x61, 0x64, 0x61, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0e, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x53, 0x70, 0x65, + 0x28, 0x02, 0x52, 0x0e, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x17, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x18, 0x20, 0x01, diff --git a/ats/verify/simulation/simulation_manage.go b/ats/verify/simulation/simulation_manage.go index 4533bbc..7295910 100644 --- a/ats/verify/simulation/simulation_manage.go +++ b/ats/verify/simulation/simulation_manage.go @@ -1,6 +1,9 @@ package simulation import ( + "go.uber.org/zap" + "joylink.club/bj-rtsts-server/ats/verify/protos/state" + "joylink.club/bj-rtsts-server/dynamics" "strconv" "sync" @@ -8,6 +11,47 @@ import ( "joylink.club/bj-rtsts-server/dto" ) +func init() { + dynamics.RegisterTrainInfoHandler(func(info *dynamics.TrainInfo) { + for _, simulation := range GetSimulationArr() { + sta, ok := simulation.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number))) + if ok { + memory.UpdateTrainState(simulation, convert(info, *sta.(*state.TrainState))) + break + } + } + //simulationMap.Range(func(key, value any) bool { + // simulation := value.(*memory.VerifySimulation) + // sta, ok := simulation.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number))) + // if ok { + // memory.UpdateTrainState(simulation, convert(info, *sta.(*state.TrainState))) + // return false + // } + // return true + //}) + }) +} + +func convert(info *dynamics.TrainInfo, sta state.TrainState) *state.TrainState { + sta.HeadLinkId = strconv.Itoa(int(info.Link)) + sta.HeadLinkOffset = int64(info.LinkOffset * 10) + sta.Slope = int32(info.Slope) + sta.Upslope = info.UpSlope + sta.RunningUp = info.Up + sta.RunningResistanceSum = info.TotalResistance + sta.AirResistance = info.AirResistance + sta.RampResistance = info.SlopeResistance + sta.CurveResistance = info.CurveResistance + sta.Speed = info.Speed + sta.HeadSensorSpeed1 = info.HeadSpeed1 + sta.HeadSensorSpeed2 = info.HeadSpeed2 + sta.TailSensorSpeed1 = info.TailSpeed1 + sta.TailSensorSpeed2 = info.TailSpeed2 + sta.HeadRadarSpeed = info.HeadRadarSpeed + sta.TailRadarSpeed = info.TailRadarSpeed + return &sta +} + // 仿真存储集合 var simulationMap sync.Map @@ -18,6 +62,25 @@ func CreateSimulation(mapId int32) string { if !e { verifySimulation := memory.CreateSimulation(mapId, simulationId) simulationMap.Store(simulationId, verifySimulation) + //道岔状态发送 + dynamics.AddTurnoutInfoFunc(simulationId, func() []*dynamics.TurnoutInfo { + stateSlice := memory.GetAllTurnoutState(verifySimulation) + var turnoutInfoSlice []*dynamics.TurnoutInfo + for _, sta := range stateSlice { + code64, err := strconv.ParseUint(sta.Id, 10, 16) + if err != nil { + zap.S().Error("id转uint16报错", err) + } + info := dynamics.TurnoutInfo{ + Code: uint16(code64), + NPosition: sta.Normal, + RPosition: sta.Reverse, + } + turnoutInfoSlice = append(turnoutInfoSlice, &info) + } + return turnoutInfoSlice + }) + // } return simulationId } @@ -25,6 +88,8 @@ func CreateSimulation(mapId int32) string { // 删除仿真对象 func DestroySimulation(simulationId string) { simulationMap.Delete(simulationId) + //移除道岔状态发送 + dynamics.RemoveTurnoutInfoFunc(simulationId) } // 创建时生成仿真Id diff --git a/ats/verify/simulation/wayside/memory/wayside_memory_train.go b/ats/verify/simulation/wayside/memory/wayside_memory_train.go index 44dd7dd..d23cee7 100644 --- a/ats/verify/simulation/wayside/memory/wayside_memory_train.go +++ b/ats/verify/simulation/wayside/memory/wayside_memory_train.go @@ -2,8 +2,14 @@ package memory import ( "fmt" + "math" + "net/http" + "strconv" "sync" + "joylink.club/bj-rtsts-server/dto" + "joylink.club/bj-rtsts-server/dynamics" + "github.com/golang/protobuf/proto" "joylink.club/bj-rtsts-server/ats/verify/protos/state" ) @@ -17,6 +23,19 @@ func AddTrainState(simulation *VerifySimulation, status *state.TrainState) { } // 显示状态 status.Show = true + //向动力学发送初始化请求 + trainIndex, _ := strconv.ParseUint(status.Id, 10, 16) + linkIndex, _ := strconv.ParseUint(status.HeadLinkId, 10, 16) + httpCode, _, err := dynamics.SendInitTrainReq(&dynamics.InitTrainInfo{ + TrainIndex: uint16(trainIndex), + LinkIndex: uint16(linkIndex), + LinkOffset: uint16(status.HeadLinkOffset / 10), + Speed: uint16(math.Round(float64(status.Speed * 10))), + Up: status.Up, + }) + if err != nil || httpCode != http.StatusOK { + panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:%s", err.Error())}) + } // 将信息合并到当前设备状态中 allTrainMap.Store(status.Id, status) // 将变更信息放入变更状态队列中 diff --git a/dynamics/example_test.go b/dynamics/example_test.go index f566759..651cc91 100644 --- a/dynamics/example_test.go +++ b/dynamics/example_test.go @@ -19,7 +19,10 @@ import ( func TestAll(t *testing.T) { loadAndChangeConfig() //注册列车信息处理逻辑 - RegisterTrainInfoHandler(&ExampleTrainInfoHandler{}) + RegisterTrainInfoHandler(func(info *TrainInfo) { + fmt.Println("处理列车信息...") + fmt.Println(info) + }) //启动udp服务 go RunUdpServer() ////启动仅用于的测试的模拟远程udp服务 @@ -32,7 +35,7 @@ func TestAll(t *testing.T) { //向远程udp服务发送数据 _ = SendTurnoutInfo(&TurnoutInfo{Code: 02}) //发送http请求 - _, _, _ = SendTrainInitReq(&InitTrainInfo{Speed: 10}) + _, _, _ = SendInitTrainReq(&InitTrainInfo{Speed: 10}) } func loadAndChangeConfig() { @@ -91,11 +94,3 @@ func (server *testUdpServer) OnTraffic(c gnet.Conn) gnet.Action { fmt.Println(buf) return gnet.None } - -type ExampleTrainInfoHandler struct { -} - -func (handler *ExampleTrainInfoHandler) HandleTrainInfo(info TrainInfo) { - fmt.Println("处理列车信息...") - fmt.Println(info) -} diff --git a/dynamics/http.go b/dynamics/http.go index 78ba398..2caf576 100644 --- a/dynamics/http.go +++ b/dynamics/http.go @@ -9,7 +9,7 @@ import ( "net/http" ) -func SendTrainInitReq(info *InitTrainInfo) (int, *[]byte, error) { +func SendInitTrainReq(info *InitTrainInfo) (int, *[]byte, error) { defer func() { if r := recover(); r != nil { zap.S().Error("发送列车初始化请求失败", r) @@ -24,9 +24,14 @@ func SendTrainInitReq(info *InitTrainInfo) (int, *[]byte, error) { url := "http://" + ip + port + uri data, _ := json.Marshal(info) - resp, _ := http.Post(url, "application/json", bytes.NewBuffer(data)) + resp, err := http.Post(url, "application/json", bytes.NewBuffer(data)) + if err != nil { + s := err.Error() + println(s) + return 0, nil, err + } var buf []byte - _, err := resp.Body.Read(buf) + _, err = resp.Body.Read(buf) if err != nil { return resp.StatusCode, nil, err } diff --git a/dynamics/httpData.go b/dynamics/httpData.go index e226d20..bc43511 100644 --- a/dynamics/httpData.go +++ b/dynamics/httpData.go @@ -4,6 +4,7 @@ type InitTrainInfo struct { TrainIndex uint16 `json:"trainIndex"` LinkIndex uint16 `json:"linkIndex"` LinkOffset uint16 `json:"linkOffset"` - Speed uint16 `json:"speed"` - Up bool `json:"up"` + //单位0.1km/h + Speed uint16 `json:"speed"` + Up bool `json:"up"` } diff --git a/dynamics/http_test.go b/dynamics/http_test.go index f6012a5..9ec79f6 100644 --- a/dynamics/http_test.go +++ b/dynamics/http_test.go @@ -1,17 +1,24 @@ package dynamics import ( + "github.com/spf13/viper" "joylink.club/bj-rtsts-server/config" "testing" + "time" ) func TestSendTrainInitReq(t *testing.T) { + viper.AddConfigPath("../") config.LoadConfig() - SendTrainInitReq(&InitTrainInfo{ - TrainIndex: 1, - LinkIndex: 2, - LinkOffset: 3, - Speed: 4, - Up: true, - }) + for i := 1; i <= 5; i++ { + info := InitTrainInfo{ + TrainIndex: uint16(i), + LinkIndex: 2, + LinkOffset: 3, + Speed: 4, + Up: true, + } + time.Sleep(time.Second) + SendInitTrainReq(&info) + } } diff --git a/dynamics/udp.go b/dynamics/udp.go index 6bb92b8..861e4dd 100644 --- a/dynamics/udp.go +++ b/dynamics/udp.go @@ -1,33 +1,53 @@ package dynamics import ( + "container/list" "encoding/binary" "fmt" "github.com/panjf2000/gnet/v2" "go.uber.org/zap" "joylink.club/bj-rtsts-server/config" "net" + "sync" "time" ) +func init() { + runSendTurnoutStateTask() +} + var ( - // TurnoutInfoChan 用来存放要发送的道岔信息 - TurnoutInfoChan = make(chan *TurnoutInfo, 1000) + m sync.Map ) -func RunSendTurnoutInfoTask() { +type TurnoutInfoFunc func() []*TurnoutInfo + +func runSendTurnoutStateTask() { go func() { - tick := time.Tick(10 * time.Millisecond) + tick := time.Tick(50 * time.Millisecond) for range tick { - info := <-TurnoutInfoChan - err := SendTurnoutInfo(info) - if err != nil { - zap.S().Error(err) - } + m.Range(func(key, value any) bool { + slice := value.(TurnoutInfoFunc)() + for _, turnoutInfo := range slice { + err := SendTurnoutInfo(turnoutInfo) + if err != nil { + zap.S().Error(err) + } + } + return true + }) } }() } +func AddTurnoutInfoFunc(simId string, tiFunc TurnoutInfoFunc) { + m.Store(simId, tiFunc) +} + +func RemoveTurnoutInfoFunc(simId string) { + m.Delete(simId) +} + // SendTurnoutInfo 发送道岔信息 func SendTurnoutInfo(info *TurnoutInfo) error { defer func() { @@ -75,6 +95,7 @@ type udpServer struct { func (server *udpServer) OnBoot(eng gnet.Engine) gnet.Action { server.eng = eng + println("udp server with multi-core=%t is listening on %s\n", server.multicore, server.addr) zap.S().Infof("udp server with multi-core=%t is listening on %s\n", server.multicore, server.addr) return gnet.None } @@ -97,33 +118,32 @@ func (server *udpServer) OnTraffic(c gnet.Conn) gnet.Action { b := buf[11] trainInfo.UpSlope = (b & (1 << 7)) != 0 trainInfo.Up = (b & (1 << 6)) != 0 - trainInfo.TotalResistance = binary.BigEndian.Uint16(buf[13:15]) - trainInfo.Resistance1 = binary.BigEndian.Uint16(buf[15:17]) - trainInfo.Resistance2 = binary.BigEndian.Uint16(buf[17:19]) - trainInfo.Resistance3 = binary.BigEndian.Uint16(buf[19:21]) - trainInfo.Speed = binary.BigEndian.Uint16(buf[21:23]) - trainInfo.HeadSpeed1 = binary.BigEndian.Uint16(buf[23:25]) - trainInfo.HeadSpeed2 = binary.BigEndian.Uint16(buf[25:27]) - trainInfo.TailSpeed1 = binary.BigEndian.Uint16(buf[27:29]) - trainInfo.TailSpeed2 = binary.BigEndian.Uint16(buf[29:31]) - trainInfo.HeadRadarSpeed = binary.BigEndian.Uint16(buf[31:33]) - trainInfo.TailRadarSpeed = binary.BigEndian.Uint16(buf[33:35]) + trainInfo.TotalResistance = float32(binary.BigEndian.Uint16(buf[13:15])) / 100 + trainInfo.AirResistance = float32(binary.BigEndian.Uint16(buf[15:17])) / 100 + trainInfo.SlopeResistance = float32(binary.BigEndian.Uint16(buf[17:19])) / 100 + trainInfo.CurveResistance = float32(binary.BigEndian.Uint16(buf[19:21])) / 100 + trainInfo.Speed = float32(binary.BigEndian.Uint16(buf[21:23])) / 10 + trainInfo.HeadSpeed1 = float32(binary.BigEndian.Uint16(buf[23:25])) / 10 + trainInfo.HeadSpeed2 = float32(binary.BigEndian.Uint16(buf[25:27])) / 10 + trainInfo.TailSpeed1 = float32(binary.BigEndian.Uint16(buf[27:29])) / 10 + trainInfo.TailSpeed2 = float32(binary.BigEndian.Uint16(buf[29:31])) / 10 + trainInfo.HeadRadarSpeed = float32(binary.BigEndian.Uint16(buf[31:33])) / 10 + trainInfo.TailRadarSpeed = float32(binary.BigEndian.Uint16(buf[33:35])) / 10 - for _, handler := range trainInfoHandlers { - handler.HandleTrainInfo(trainInfo) + for e := handlerList.Front(); e != nil; e = e.Next() { + handler := e.Value.(TrainInfoHandler) + handler(&trainInfo) } return gnet.None } -var trainInfoHandlers []TrainInfoHandler +var handlerList list.List -type TrainInfoHandler interface { - HandleTrainInfo(info TrainInfo) -} +type TrainInfoHandler func(info *TrainInfo) func RegisterTrainInfoHandler(handler TrainInfoHandler) { - trainInfoHandlers = append(trainInfoHandlers, handler) + handlerList.PushBack(handler) } func RunUdpServer() { diff --git a/dynamics/udpData.go b/dynamics/udpData.go index ecaa93d..f0ce87b 100644 --- a/dynamics/udpData.go +++ b/dynamics/udpData.go @@ -24,25 +24,25 @@ type TrainInfo struct { //列车当前运行方向(上/下行) Up bool //实际运行阻力(总)(KN) - TotalResistance uint16 + TotalResistance float32 //阻力1(空气阻力)(KN) - Resistance1 uint16 + AirResistance float32 //阻力2(坡道阻力)(KN) - Resistance2 uint16 + SlopeResistance float32 //阻力3(曲线阻力)(KN) - Resistance3 uint16 + CurveResistance float32 //列车运行速度(km/h) - Speed uint16 + Speed float32 //头车速传1速度值(km/h) - HeadSpeed1 uint16 + HeadSpeed1 float32 //头车速度2速度值 - HeadSpeed2 uint16 + HeadSpeed2 float32 //尾车速传1速度值 - TailSpeed1 uint16 + TailSpeed1 float32 //尾车速度2速度值 - TailSpeed2 uint16 + TailSpeed2 float32 //头车雷达速度值 - HeadRadarSpeed uint16 + HeadRadarSpeed float32 //尾车雷达速度值 - TailRadarSpeed uint16 + TailRadarSpeed float32 } diff --git a/dynamics/udp_test.go b/dynamics/udp_test.go index bf5a54d..bc6d757 100644 --- a/dynamics/udp_test.go +++ b/dynamics/udp_test.go @@ -2,7 +2,9 @@ package dynamics import ( "encoding/hex" + "fmt" "github.com/panjf2000/gnet/v2" + "github.com/spf13/viper" "io" "joylink.club/bj-rtsts-server/config" "net" @@ -12,18 +14,28 @@ import ( ) func TestRunUdpServer(t *testing.T) { + viper.AddConfigPath("../") config.LoadConfig() - RegisterTrainInfoHandler(&ExampleTrainInfoHandler{}) + RegisterTrainInfoHandler(func(info *TrainInfo) { + fmt.Println("处理列车信息...") + fmt.Println(info) + }) RunUdpServer() } func TestSendTurnoutInfo(t *testing.T) { + viper.AddConfigPath("../") config.LoadConfig() - SendTurnoutInfo(&TurnoutInfo{ - Code: 2, - NPosition: true, - RPosition: false, - }) + tick := time.Tick(50 * time.Millisecond) + for range tick { + for i := 1; i <= 9; i++ { + SendTurnoutInfo(&TurnoutInfo{ + Code: uint16(i), + NPosition: true, + RPosition: false, + }) + } + } } func BenchmarkUdpServer_OnTraffic(b *testing.B) { diff --git a/main.go b/main.go index fde8a86..7d64740 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,12 @@ package main import ( "fmt" - "joylink.club/bj-rtsts-server/dynamics" - swaggerFiles "github.com/swaggo/files" // swagger embed files ginSwagger "github.com/swaggo/gin-swagger" // gin-swagger middleware "joylink.club/bj-rtsts-server/api" "joylink.club/bj-rtsts-server/config" "joylink.club/bj-rtsts-server/docs" + "joylink.club/bj-rtsts-server/dynamics" "joylink.club/bj-rtsts-server/middleware" ) @@ -36,7 +35,7 @@ func main() { docs.SwaggerInfo.Title = "CBTC测试系统API" engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) - dynamics.RunSendTurnoutInfoTask() + go dynamics.RunUdpServer() serverConfig := config.Config.Server if serverConfig.Port == 0 { diff --git a/xiannccda.setting.yml b/xiannccda.setting.yml index 3e71442..54c6129 100644 --- a/xiannccda.setting.yml +++ b/xiannccda.setting.yml @@ -6,10 +6,10 @@ server: port: 9091 # 动力学端口配置 dynamics: - ip: 192.168.3.5 + ip: 192.168.3.94 udpLocalPort: 4000 udpRemotePort: 3000 - httpPort: 9092 + httpPort: 7800 # 数据源 datasource: