This commit is contained in:
walker 2023-10-31 11:24:39 +08:00
commit f006cfae2b
5 changed files with 198 additions and 79 deletions

View File

@ -302,7 +302,7 @@ func signalOperation(c *gin.Context) {
// @Success 200 {object} string
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/simulation/axleSection/operation [post]
func axleSectionOperation(c *gin.Context) {
func axleSectionOperation(c *gin.Context) { //操作:设置故障占用、取消故障占用、计轴直接复位、计轴预复位
req := &dto.AxleSectionOperationReqDto{}
if err := c.ShouldBind(&req); err != nil {
panic(sys_error.New("输入参数格式错误", err))

@ -1 +1 @@
Subproject commit 085bfdc6f9afc84c0724c49441aa59d734906a6a
Subproject commit e21995b69537f1ac0efbfeefc8517df3fbe9477e

View File

@ -90,11 +90,19 @@ type InterlockReceiveMsgPkg struct {
toagent_len int32
et_out_num int32
tcc_output_len int32
Header *InterlockMsgPkgHeader // 包头
SyncZone []bool // 同步区状态
DriveInfo []bool // 驱动数据
TccInfo []bool // 应答器报文
Tail *InterlockMsgPkgTail // 包尾
Header *InterlockMsgPkgHeader // 包头
SyncZone []byte // 同步区状态
DriveInfo []bool // 驱动数据
TccInfo []*InterlockResponderMsgPkg // 应答器报文
Tail *InterlockMsgPkgTail // 包尾
}
// 应答器数据格式
type InterlockResponderMsgPkg struct {
Index byte
InternalIndex byte
Reserve byte
MsgInfo []byte
}
// ET_OUT_NUM、TOAGENTLEN、TCC_OUTPUT_LEN应答器数量*131的具体数值取决于数据配置。
@ -115,7 +123,7 @@ func (t *InterlockReceiveMsgPkg) Decode(buf []byte) error {
// 同步区状态
preIndex = lastIndex
lastIndex = lastIndex + t.toagent_len
t.parseByte(t.SyncZone, buf, preIndex, lastIndex)
t.SyncZone = buf[preIndex:lastIndex]
// 驱动数据
preIndex = lastIndex
lastIndex = lastIndex + t.et_out_num
@ -123,7 +131,7 @@ func (t *InterlockReceiveMsgPkg) Decode(buf []byte) error {
// 应答器报文
preIndex = lastIndex
lastIndex = lastIndex + t.tcc_output_len
t.parseByte(t.TccInfo, buf, preIndex, lastIndex)
t.TccInfo = parseResponder(buf, preIndex, lastIndex)
// 包尾
t.Tail.Decode(buf)
return nil
@ -137,3 +145,17 @@ func (t *InterlockReceiveMsgPkg) parseByte(r []bool, buf []byte, start, end int3
}
}
}
func parseResponder(buf []byte, start, end int32) []*InterlockResponderMsgPkg {
var msgs []*InterlockResponderMsgPkg
for i := start; i < end; i = i + 128 {
b := buf[i : i+128]
msgs = append(msgs, &InterlockResponderMsgPkg{
Index: b[0],
InternalIndex: b[1],
Reserve: b[2],
MsgInfo: b[3:],
})
}
return msgs
}

View File

@ -13,27 +13,16 @@ const (
RsspCrc32C2 uint32 = 0x8ce56011 //安全通道1 CRC32生成多项式
)
func CreateRsspCrcTable() {
// InitRsspCrcTable 初始化RSSP协议中需要的CRC表
func InitRsspCrcTable() {
if crc16Table == nil {
var table = make([]uint32, 0, 256)
for bt := 0x00; bt <= 0xff; bt++ {
table = append(table, Lookup(uint32(bt), RsspCrc16GX, 16, false))
}
crc16Table = table
crc16Table = CreateCrcTable(RsspCrc16GX, 16, false)
}
if crc32C1Table == nil {
var table = make([]uint32, 0, 256)
for bt := 0x00; bt <= 0xff; bt++ {
table = append(table, Lookup(uint32(bt), RsspCrc32C1, 32, false))
}
crc32C1Table = table
crc32C1Table = CreateCrcTable(RsspCrc32C1, 32, false)
}
if crc32C2Table == nil {
var table = make([]uint32, 0, 256)
for bt := 0x00; bt <= 0xff; bt++ {
table = append(table, Lookup(uint32(bt), RsspCrc32C2, 32, false))
}
crc32C2Table = table
crc32C2Table = CreateCrcTable(RsspCrc32C2, 32, false)
}
}
func RsspCrc16(data []byte) uint16 {
@ -46,6 +35,15 @@ func RsspC2Crc32(data []byte) uint32 {
return CrcTableBased(data, 32, 0, false, false, 0, crc32C2Table)
}
// CreateCrcTable 创建CRC表支持8、16、32位
func CreateCrcTable(polynomial uint32, width int, input_reflected bool) []uint32 {
var table = make([]uint32, 0, 256)
for bt := 0x00; bt <= 0xff; bt++ {
table = append(table, lookup(uint32(bt), polynomial, width, input_reflected))
}
return table
}
/////////////////////////////////////////////////////////////////////////////
// 反转(0b00001010->0b01010000)
@ -64,8 +62,8 @@ func reflect(data uint32, width int) uint32 {
return register1 & significant_mask
}
// Lookup 计算单个数值的crc
func Lookup(data uint32,
// 计算单个数值的crc
func lookup(data uint32,
polynomial uint32,
width int,
input_reflected bool) uint32 {
@ -158,34 +156,40 @@ func CrcTableBased(
return (register1 ^ final_xor_value) & significant_mask
}
// MSB优先(字节中高位bit即最左侧bit优先)
func CrcBitOrientedMsbFirst(data []byte, polynomial uint32, width int) uint32 {
var register1 uint32 = 0
var significant_mask uint32 = 0xffffffff >> (32 - width)
var register_msb_mask uint32 = 1 << (width - 1)
var register_lsb_mask uint32 = 1
var byte_msb_mask uint32 = 0x80
func Crc(data []byte,
polynomial uint32,
width int,
initial_value uint32,
input_reflected bool,
result_reflected bool,
final_xor_value uint32) uint32 {
length := len(data)
var register1 uint32 = initial_value
var significant_mask uint32 = 0xffffffff >> (32 - width)
var register_lsb_mask uint32 = 0xff
for i := 0; i < length+(width/8); i++ {
var byteData uint32 = 0
if i < length {
byteData = uint32(data[i])
}
for j := 0; j < 8; j++ {
need_xor := (register1 & register_msb_mask) == register_msb_mask
register1 <<= 1
if input_reflected {
register1 = reflect(register1, width)
}
need_or := (byteData & byte_msb_mask) == byte_msb_mask
byteData <<= 1
for i := 0; i < length; i++ {
var byteData uint32 = uint32(data[i])
var shift_out uint32 = 0
var value uint32 = 0
if need_or {
register1 |= register_lsb_mask
}
if need_xor {
register1 ^= polynomial
}
if input_reflected {
shift_out = register1 & register_lsb_mask
value = lookup(shift_out^byteData, polynomial, width, input_reflected)
register1 = (register1 >> 8) ^ value
} else {
shift_out = (register1 >> (width - 8)) & register_lsb_mask
value = lookup(shift_out^byteData, polynomial, width, input_reflected)
register1 = (register1 << 8) ^ value
}
}
return register1 & significant_mask
if input_reflected != result_reflected {
register1 = reflect(register1, width)
}
return (register1 ^ final_xor_value) & significant_mask
}

View File

@ -346,37 +346,24 @@ func (s *VerifySimulation) GetInterlockRunConfig() *config.InterlockConfig {
// 采集联锁中的继电器消息
func (s *VerifySimulation) CollectInterlockRelayInfo() []*message.InterlockSendMsgPkg {
var msgPkgs []*message.InterlockSendMsgPkg
for _, mapId := range s.MapIds { // 获取继电器地图信息
if QueryOnlyGiType(mapId) != graphicData.PictureType_RelayCabinetLayout { // 继电器柜
for _, m := range s.Repo.CentralizedList() { // 获取继电器地图信息
if len(m.CjList) == 0 {
continue
}
mapData := QueryGiData[*graphicData.RelayCabinetGraphicStorage](mapId)
// 配置继电器为空
dataLenght := len(mapData.CiCjList.CjList) * int(mapData.CiCjList.DsCount)
if dataLenght == 0 {
continue
}
index := 0
collectInfo := make([]bool, dataLenght)
uidMap := QueryUidStructure[*RelayUidStructure](mapId)
// 遍历继电器获取继电器状态
for _, col := range mapData.CiCjList.CjList {
for _, row := range col.BitList {
rs := len(row.RefRelays) > 0
for _, j := range row.RefRelays {
u := uidMap.RelayIds[j.RelayId]
if u == nil {
panic(sys_error.New(fmt.Sprintf("地图【id:%d】不存在继电器的【comId:%s】UID映射关系", mapId, j.RelayId)))
}
if j.Position == graphicData.CjDataItem_Q {
rs = rs && fi.CollectXQCircuitState(s.World, u.Uid)
} else {
rs = rs && fi.CollectLXCircuitState(s.World, u.Uid)
}
}
collectInfo[index] = rs
index++
collectInfo := make([]bool, len(m.CjList))
for i, l := range m.CjList {
if l == nil || len(l.RefRelays) == 0 {
continue
}
rs := true
for _, j := range l.RefRelays {
if j.Position == proto.CjDataItem_Q {
rs = rs && fi.CollectXQCircuitState(s.World, j.RelayId)
} else {
rs = rs && fi.CollectLXCircuitState(s.World, j.RelayId)
}
}
collectInfo[i] = rs
}
msgPkgs = append(msgPkgs, &message.InterlockSendMsgPkg{Info: collectInfo})
}
@ -611,6 +598,99 @@ func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *graphicD
}
}
}
// 处理该集中站采集、驱动配置信息
centralizedStationId := GenerateElementUid(city, lineId, nil, station)
ref := queryCentralizedStationRef(centralizedStationId, repo)
ref.CjList = append(ref.CjList, handlerRelayGiCj(uidsMap, centralizedStationId, relayGi.CiCjList)...)
ref.QdList = append(ref.QdList, handlerRelayGiQd(uidsMap, centralizedStationId, relayGi.CiQdList)...)
}
// 查询集中站配置信息
func queryCentralizedStationRef(stationId string, repo *proto.Repository) *proto.CentralizedStationRef {
var ref *proto.CentralizedStationRef
for _, r := range repo.CentralizedStationRefs {
if r.StationId == stationId {
ref = r
break
}
}
if ref == nil {
ref = &proto.CentralizedStationRef{StationId: stationId}
repo.CentralizedStationRefs = append(repo.CentralizedStationRefs, ref)
}
return ref
}
// 处理继电器采集信息
func handlerRelayGiCj(uidsMap *RelayUidStructure, stationId string, ciCj *graphicData.CiCj) []*proto.CjData {
if ciCj == nil {
return nil
}
// 采集信息
dataLenght := len(ciCj.CjList) * int(ciCj.DsCount)
if dataLenght == 0 {
return nil
}
cjList := make([]*proto.CjData, dataLenght)
index := 0
for ci, col := range ciCj.CjList {
for ri, row := range col.BitList {
if len(row.RefRelays) == 0 {
index++
continue
}
r := &proto.CjData{Row: int32(ri), Col: int32(ci)}
for _, j := range row.RefRelays {
u := uidsMap.RelayIds[j.RelayId]
if u == nil {
panic(sys_error.New(fmt.Sprintf("集中站【id:%s】不存在继电器的【comId:%s】UID映射关系", stationId, j.RelayId)))
}
d := &proto.CjDataItem{RelayId: u.Uid}
if j.Position == graphicData.CjDataItem_H {
d.Position = proto.CjDataItem_H
} else {
d.Position = proto.CjDataItem_Q
}
r.RefRelays = append(r.RefRelays, d)
}
cjList[index] = r
index++
}
}
return cjList
}
// 处理继电器驱动信息
func handlerRelayGiQd(uidsMap *RelayUidStructure, stationId string, ciQd *graphicData.CiQd) []*proto.QdData {
if ciQd == nil {
return nil
}
// 驱动信息
dataLenght := len(ciQd.QdList) * int(ciQd.DsCount)
if dataLenght == 0 {
return nil
}
qdList := make([]*proto.QdData, dataLenght)
index := 0
for ci, col := range ciQd.QdList {
for ri, row := range col.BitList {
if len(row.RefRelays) == 0 {
index++
continue
}
r := &proto.QdData{Row: int32(ri), Col: int32(ci)}
for _, j := range row.RefRelays {
u := uidsMap.RelayIds[j]
if u == nil {
panic(sys_error.New(fmt.Sprintf("集中站【id:%s】不存在继电器的【comId:%s】UID映射关系", stationId, j)))
}
r.RefRelays = append(r.RefRelays, u.Uid)
}
qdList[index] = r
index++
}
}
return qdList
}
func convertRelayModel(modelType graphicData.Relay_ModelType) proto.Relay_Model {
@ -712,6 +792,7 @@ func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphi
}
repo.Signals = append(repo.Signals, converSignalUid(signal, uidsMap))
}
stm := make(map[string][]string)
for _, data := range storage.Transponders {
var sectionId string
var turnoutPort *proto.DevicePort
@ -728,6 +809,13 @@ func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphi
TurnoutPort: turnoutPort,
}
repo.Transponders = append(repo.Transponders, converTransponderUid(responder, uidsMap))
for _, stationName := range data.CentralizedStations {
if stm[stationName] == nil {
stm[stationName] = []string{responder.Id}
} else {
stm[stationName] = append(stm[stationName], responder.Id)
}
}
}
slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker)
for _, data := range storage.SlopeKiloMarker {
@ -810,6 +898,11 @@ func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphi
// 处理车站关联IBP的设备
handlerIBPDeviceToStation(station, repo, data.RefIbpMapCode)
repo.Stations = append(repo.Stations, station)
// 处理集中站的信息
if stm[station.Code] != nil {
ref := queryCentralizedStationRef(station.Id, repo)
ref.TransponderId = append(ref.TransponderId, stm[station.Code]...)
}
}
//门控箱
gateBoxMap := make(map[string]*proto.Mkx)