【新增】车库门PSL模型构建及相关ecs逻辑;

【改动】车库门ecs逻辑
This commit is contained in:
thesai 2024-03-26 13:12:17 +08:00
parent da98777b04
commit 141cc633b9
10 changed files with 241 additions and 78 deletions

View File

@ -614,7 +614,10 @@ func pslBtnOperation(c *gin.Context) {
}
simulation := checkDeviceDataAndReturn(req.SimulationId)
slog.Info("传入状态参数", req)
memory.ChangePSLButtonState(simulation, req.MapId, req.PslId, req.ButtonCode, req.Down)
var err *sys_error.BusinessError = memory.ChangePSLButtonState(simulation, req.MapId, req.PslId, req.ButtonCode, req.Down)
if err != nil {
panic(err)
}
c.JSON(http.StatusOK, "ok")
}
@ -932,34 +935,6 @@ func ckmOperation(c *gin.Context) {
c.JSON(http.StatusOK, "ok")
}
// 车库门控制盒操作
//
// @Summary 车库门控制盒操作
//
// @Security JwtAuth
//
// @Description 车库门操作
// @Tags ATS测试仿真Api
// @Accept json
// @Param Authorization header string true "JWT Token"
// @Param CkmBoxOperationReq body request_proto.CkmBoxOperationReq true "车库门控制盒操作"
//
// @Success 200 {object} string
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/simulation/ckm/operation [put]
func ckmBoxOperation(c *gin.Context) {
req := &request_proto.CkmBoxOperationReq{}
if err := c.ShouldBind(&req); err != nil {
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
}
simulation := checkDeviceDataAndReturn(req.SimulationId)
var err *sys_error.BusinessError = memory.CkmBoxOperation(simulation, req)
if err != nil {
panic(err)
}
c.JSON(http.StatusOK, "ok")
}
// 获取仿真设备数据并返回
func checkDeviceDataAndReturn(simId string) *memory.VerifySimulation {
deviceMemory := ts.FindSimulation(simId)

View File

@ -3,6 +3,7 @@ package message_server
import (
"fmt"
"joylink.club/bj-rtsts-server/dto/state_proto"
"log/slog"
"time"
"joylink.club/bj-rtsts-server/dto/data_proto"
@ -16,19 +17,34 @@ import (
func NewPSLMs(vs *memory.VerifySimulation, mapId int32) ms_api.MsgTask {
mapData := memory.QueryGiData[*data_proto.RtssGraphicStorage](mapId)
return ms_api.NewScheduleTask(fmt.Sprintf("地图[%d]综合门控箱按钮状态", mapId), func() error {
return ms_api.NewScheduleTask(fmt.Sprintf("地图[%d]PSL按钮状态", mapId), func() error {
for _, box := range mapData.GateBoxs {
did := memory.GetMapElementId(box.Common)
data_proto, err := collectGateBoxPSLState(vs.World, mapId, box)
data, err := collectGateBoxPSLState(vs.World, mapId, box)
if err != nil {
return err
}
mqtt.GetMsgClient().PubPSLState(vs.SimulationId, mapId, did, data_proto)
sendMsg(vs, mapId, did, data)
}
for _, box := range mapData.GarageDoorBoxes {
did := memory.GetMapElementId(box.Common)
data, err := collectGarageDoorBoxPSLState(vs.World, mapId, box)
if err != nil {
return err
}
sendMsg(vs, mapId, did, data)
}
return nil
}, 200*time.Millisecond)
}
func sendMsg(vs *memory.VerifySimulation, mapId int32, pslId uint32, data *state_proto.PushedDevicesStatus) {
err := mqtt.GetMsgClient().PubPSLState(vs.SimulationId, mapId, pslId, data)
if err != nil {
slog.Error(fmt.Sprintf("发送PSL状态出错%s", err.Error()))
}
}
func collectGateBoxPSLState(world ecs.World, mapId int32, box *data_proto.GatedBox) (*state_proto.PushedDevicesStatus, error) {
did := memory.GetMapElementId(box.Common)
uidStructure := memory.QueryUidStructure[*memory.StationUidStructure](mapId)
@ -67,3 +83,43 @@ func collectGateBoxPSLState(world ecs.World, mapId int32, box *data_proto.GatedB
},
}, nil
}
func collectGarageDoorBoxPSLState(world ecs.World, mapId int32, box *data_proto.GarageDoorBox) (*state_proto.PushedDevicesStatus, error) {
return nil, nil
//did := memory.GetMapElementId(box.Common)
//uidStructure := memory.QueryUidStructure[*memory.StationUidStructure](mapId)
//boxUid := uidStructure.PslIds[did].Uid
//mkxEntry, ok := entity.GetEntityByUid(world, boxUid)
//if !ok {
// return nil, fmt.Errorf("[id:%s]的门控箱实体找不到", boxUid)
//}
//mkx := component.MkxType.Get(mkxEntry)
//var buttonStateArr []*state_proto.ButtonState
//if ok {
// _, pslStorage := memory.QueryGiDataByName[*data_proto.PslGraphicStorage](box.RefGatedBoxMapCode)
// btnUidMap := make(map[string]uint32, len(pslStorage.PslButtons))
// for _, button := range pslStorage.PslButtons {
// btnUidMap[boxUid+"_"+button.Code] = memory.GetMapElementId(button.Common)
// }
// btnArr := []*ecs.Entry{mkx.PCB, mkx.PCBPL, mkx.POB, mkx.POBPL, mkx.PAB, mkx.PABPL, mkx.WRZF, mkx.WRZFPL,
// mkx.QKQR, mkx.QKQRPL, mkx.MPL, mkx.JXTCPL}
// for _, btn := range btnArr {
// if btn == nil {
// continue
// }
// btnState := component.BitStateType.Get(btn)
// buttonStateArr = append(buttonStateArr, &state_proto.ButtonState{
// Id: btnUidMap[component.UidType.Get(btn).Id],
// Down: btnState.Val,
// Active: btnState.Val,
// //Bypass: btnState.BypassEnable,
// })
// }
//}
//return &state_proto.PushedDevicesStatus{
// All: true,
// AllStatus: &state_proto.AllDevicesStatus{
// ButtonState: buttonStateArr,
// },
//}, nil
}

86
protobuf/main.go Normal file
View File

@ -0,0 +1,86 @@
package main
import (
"bufio"
"fmt"
"io/fs"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
var (
basePath, _ = os.Getwd()
protoFolder = filepath.Join(basePath, "rts-sim-testing-message", "protos")
protocPath = filepath.Join(basePath, "rts-sim-testing-message", "protoc-23.1", "bin", "win64", "protoc")
modulePrefix = "joylink.club/bj-rtsts-server"
)
func main() {
//先安装以下插件
//go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
protoFiles := getProtoFiles()
// 编译proto文件为Go文件
if err := compileProto(protoFiles); err != nil {
log.Fatalf("编译proto文件失败%v", err)
}
}
// 获取指定文件夹下的所有proto文件的绝对路径
func getProtoFiles() []string {
var protoFiles []string
err := filepath.WalkDir(protoFolder, func(path string, d fs.DirEntry, err error) error {
if !d.IsDir() {
protoFiles = append(protoFiles, path)
}
return err
})
if err != nil {
log.Fatal("获取proto文件列表失败:", err)
}
return protoFiles
}
// 编译proto文件为Go文件
func compileProto(protoFiles []string) error {
for _, fileName := range protoFiles {
file, err := os.Open(fileName)
if err != nil {
return err
}
scanner := bufio.NewScanner(file)
var outPath string
for scanner.Scan() {
text := scanner.Text()
if !strings.HasPrefix(text, "option go_package") {
continue
}
start := strings.Index(text, modulePrefix)
if start < 0 {
break
}
start += len(modulePrefix)
dir := "." + text[start:len(text)-2]
err := os.MkdirAll(dir, fs.ModeDir)
if err != nil {
panic(fmt.Sprintf("创建目录 %s 失败:%v", dir, err))
}
outPath = "paths=source_relative:" + dir
break
}
if outPath == "" {
outPath = "./"
}
cmd := exec.Command(protocPath, "-I="+protoFolder, "--go_out="+outPath, fileName)
fmt.Println(cmd.String())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
}
return nil
}

@ -1 +1 @@
Subproject commit f0a6c534ec7b4b0bb128a435c17ef2b20e481b94
Subproject commit d63be32ad560b64cf0f3306108064ed59b6f29e8

@ -1 +1 @@
Subproject commit b748c7ff3ed7d401c8caeaecd3d4ec719ae27ee2
Subproject commit 9c420a826ce6a387384ff3b16f2097036f1d094d

View File

@ -8,7 +8,6 @@ import (
appcomponent "joylink.club/bj-rtsts-server/ts/simulation/app_component"
"joylink.club/ecs"
"joylink.club/rtsssimulation/entity"
"joylink.club/rtsssimulation/fi"
"unsafe"
)
@ -22,22 +21,6 @@ func CkmOperation(simulation *VerifySimulation, req *request_proto.CkmOperationR
return nil
}
func CkmBoxOperation(sim *VerifySimulation, req *request_proto.CkmBoxOperationReq) *sys_error.BusinessError {
uid := QueryUidStructure[*StationUidStructure](req.MapId)
ckmBoxBtnUid := uid.CkmBoxIds[req.CkmBoxId].Uid
var err error
if req.Down {
err = fi.PressDownButton(sim.World, ckmBoxBtnUid+"_"+req.ButtonCode)
} else {
err = fi.PressUpButton(sim.World, ckmBoxBtnUid+"_"+req.ButtonCode)
}
if err != nil {
return sys_error.New("车库门控制盒操作失败", err)
} else {
return nil
}
}
func setParam(simulation *VerifySimulation, req *request_proto.CkmOperationReq) *sys_error.BusinessError {
uid := QueryUidByMidAndComId(req.MapId, req.DeviceId, &data_proto.GarageDoor{})
result := <-ecs.Request[ecs.EmptyType](simulation.World, func() ecs.Result[ecs.EmptyType] {

View File

@ -79,7 +79,12 @@ func GenerateElementUid(city, lineId string, stationIndexList []string, code str
idArr = append(idArr, city, lineId)
idArr = append(idArr, stationIndexList...)
idArr = append(idArr, code)
return strings.Join(idArr, "_")
return BuildUid(idArr...)
}
// GenerateElementUid 构建uid。将args用'_'连接
func BuildUid(args ...string) string {
return strings.Join(args, "_")
}
// 移除内存中的地图信息

View File

@ -45,7 +45,6 @@ type StationUidStructure struct {
SpksSwitchIds map[uint32]*elementIdStructure
IbpIds map[uint32]*elementIdStructure
CkmIds map[uint32]*elementIdStructure
CkmBoxIds map[uint32]*elementIdStructure
}
type RelayUidStructure struct {
@ -257,9 +256,8 @@ func initStationUid(data *data_proto.RtssGraphicStorage) *StationUidStructure {
PsdIds: make(map[uint32]*elementIdStructure, len(data.ScreenDoors)),
PslIds: make(map[uint32]*elementIdStructure, len(data.GateBoxs)),
//SpksSwitchIds: make(map[uint32]*elementIdStructure, len(data.SpksSwitchs)),
IbpIds: make(map[uint32]*elementIdStructure, len(data.IbpBoxs)),
CkmIds: make(map[uint32]*elementIdStructure, len(data.GarageDoors)),
CkmBoxIds: make(map[uint32]*elementIdStructure, len(data.GarageDoors)),
IbpIds: make(map[uint32]*elementIdStructure, len(data.IbpBoxs)),
CkmIds: make(map[uint32]*elementIdStructure, len(data.GarageDoors)),
}
city, lineId, _ := getUIdPrefix(data.UniqueIdPrefix)
// 处理车站信息
@ -422,6 +420,15 @@ func initStationUid(data *data_proto.RtssGraphicStorage) *StationUidStructure {
Uid: GenerateElementUid(city, lineId, nil, ckm.Code),
}
}
for _, box := range data.GarageDoorBoxes {
eid := GetMapElementId(box.Common)
ckmUid := gus.CkmIds[box.RefGarageDoorId].Uid
gus.PslIds[eid] = &elementIdStructure{
CommonId: eid,
Code: box.Code,
Uid: BuildUid(ckmUid, strconv.Itoa(int(eid))),
}
}
//// SPKS人员防护
//for _, spk := range data.SpksSwitchs {
// if spk.RefStand == 0 {

View File

@ -1,16 +1,23 @@
package memory
import (
"joylink.club/bj-rtsts-server/sys_error"
"joylink.club/rtsssimulation/fi"
)
// 操作PSL按钮
func ChangePSLButtonState(sim *VerifySimulation, mapId int32, gateBoxId uint32, btnCode string, pressDown bool) {
func ChangePSLButtonState(sim *VerifySimulation, mapId int32, gateBoxId uint32, btnCode string, pressDown bool) *sys_error.BusinessError {
uid := QueryUidStructure[*StationUidStructure](mapId)
gateBoxUid := uid.PslIds[gateBoxId].Uid
var err error
if pressDown {
fi.PressDownButton(sim.World, gateBoxUid+"_"+btnCode)
err = fi.PressDownButton(sim.World, gateBoxUid+"_"+btnCode)
} else {
fi.PressUpButton(sim.World, gateBoxUid+"_"+btnCode)
err = fi.PressUpButton(sim.World, gateBoxUid+"_"+btnCode)
}
if err != nil {
return sys_error.New("操作PSL按钮出错", err)
} else {
return nil
}
}

View File

@ -704,6 +704,10 @@ func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *data_pro
for _, platform := range repo.Platforms {
platformMap[platform.Id] = platform
}
ckmMap := make(map[string]*proto.Ckm)
for _, ckm := range repo.Ckms {
ckmMap[ckm.Id] = ckm
}
ciecs := stationMap[stationUid] //联锁集中站
if ciecs == nil {
panic(fmt.Errorf("联锁集中站[%s]不存在", stationUid))
@ -813,6 +817,27 @@ func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *data_pro
Egs: egs,
})
}
case data_proto.RelatedRef_GarageDoor: //车库门
{
ckm, ok := ckmMap[GenerateElementUid(city, lineId, nil, relationship.Code)]
if !ok {
continue
}
for _, group := range relationship.Combinationtypes {
var componentIds []string
for _, relayId := range group.RefRelays {
if relayUidStructure.RelayIds[relayId] == nil {
continue
}
componentIds = append(componentIds, relayUidStructure.RelayIds[relayId].Uid)
}
ckm.ElectronicComponentGroups = append(ckm.ElectronicComponentGroups,
&proto.ElectronicComponentGroup{
Code: group.Code,
ComponentIds: componentIds,
})
}
}
}
}
//门控箱
@ -848,24 +873,6 @@ func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *data_pro
}
}
}
//cis := stationMap[stationUid]
//// 零散组合
//for _, com := range relayGi.CombinationtypeList {
// if com.Code == "LS" { // 零散组合
// d := &proto.ElectronicGroup{Code: com.Code}
// for _, relayId := range com.RefRelays {
// if relayUidStructure.RelayIds[relayId] == nil {
// continue
// }
// d.Components = append(d.Components, &proto.ElectronicComponent{
// BaliseId: relayUidStructure.RelayIds[relayId].Uid,
// DeviceType: proto.DeviceType_DeviceType_Relay,
// })
// }
// cis.ElectronicGroup = append(cis.ElectronicGroup, d)
// fmt.Println("构建零散组合结果:", d)
// }
//}
// 处理该集中站采集、驱动配置信息
centralizedStationId := GenerateElementUid(city, lineId, nil, station)
ref := queryCentralizedStationRef(centralizedStationId, repo)
@ -1268,7 +1275,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
platformId_psdUid_map[data.GetRefPlatformId()] = psd.Id
repo.Psds = append(repo.Psds, psd)
}
//PSL
//屏蔽门PSL
for _, data := range storage.PslBoxs {
boxUidInfo := uidsMap.PslIds[GetMapElementId(data.Common)]
mkx := &proto.Mkx{
@ -1319,6 +1326,43 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
station := repoStationMap[data.RefStationId]
handlerIBPDeviceToStation(station, boxUidInfo.Uid, repo, data.RefIbpMapCode)
}
//车库门
for _, data := range storage.GarageDoors {
id := GetMapElementId(data.Common)
ckm := &proto.Ckm{
Id: uidsMap.CkmIds[id].Uid,
}
repo.Ckms = append(repo.Ckms, ckm)
}
//车库门PSL
for _, data := range storage.GarageDoorBoxes {
boxUidInfo := uidsMap.PslIds[GetMapElementId(data.Common)]
ckmPsl := &proto.CkmPsl{
Id: boxUidInfo.Uid,
CkmId: uidsMap.CkmIds[data.RefGarageDoorId].Uid,
}
repo.CkmPsls = append(repo.CkmPsls, ckmPsl)
_, pslStorage := QueryGiDataByName[*data_proto.PslGraphicStorage](data.RefPslMapCode)
for _, button := range pslStorage.PslButtons {
repoButton := &proto.Button{
Id: boxUidInfo.Uid + "_" + button.Code,
Code: button.Code,
ButtonType: proto.Button_Reset_Press,
HasLight: true,
}
repo.Buttons = append(repo.Buttons, repoButton)
switch button.Code {
case "KMA":
ckmPsl.KmaId = repoButton.Id
case "GMA":
ckmPsl.GmaId = repoButton.Id
case "MPLA":
ckmPsl.MplaId = repoButton.Id
case "MMSA":
ckmPsl.MmsaId = repoButton.Id
}
}
}
}
// 将IBP的设备关联到车站中