rts-sim-testing-service/third_party/message/interlock.go

185 lines
4.7 KiB
Go
Raw Normal View History

2023-10-24 09:14:54 +08:00
package message
import "fmt"
// 消息包头解析
type interlockMsgPkgHeader struct {
header1 byte //包头1 1个字节 0xFF
header2 byte //包头2 1个字节 0xFF
typeCode uint8 //类型码 1个字节 0x02
serialNumber uint8 //序列号 1个字节 序列号0~255
reserve1 byte //预留 1个字节
reserve2 byte //预留 1个字节
2023-10-24 09:14:54 +08:00
}
func newInterlockMsgPkgHeader() *interlockMsgPkgHeader {
return &interlockMsgPkgHeader{header1: 0xFF, header2: 0xFF, typeCode: 0x02}
2023-10-24 09:14:54 +08:00
}
func (h *interlockMsgPkgHeader) encode() []byte {
return []byte{h.header1, h.header2, h.typeCode, h.serialNumber, h.reserve1, h.reserve2}
}
func (h *interlockMsgPkgHeader) decode(buf []byte) error {
2023-10-24 09:14:54 +08:00
if len(buf) < 6 {
return fmt.Errorf("数据少于6个字节")
}
h.header1 = buf[0]
h.header2 = buf[1]
h.typeCode = buf[2]
h.serialNumber = buf[3]
h.reserve1 = buf[4]
h.reserve2 = buf[5]
2023-10-24 09:14:54 +08:00
return nil
}
// 消息包尾解析
type interlockMsgPkgTail struct {
tail []byte // 包尾2个字节
2023-10-24 09:14:54 +08:00
}
func newInterlockMsgPkgTail() *interlockMsgPkgTail {
return &interlockMsgPkgTail{tail: make([]byte, 2)}
}
func (t *interlockMsgPkgTail) encode() []byte {
if len(t.tail) == 0 {
2023-10-24 09:14:54 +08:00
return make([]byte, 2)
}
return t.tail
2023-10-24 09:14:54 +08:00
}
func (t *interlockMsgPkgTail) decode(buf []byte) error {
2023-10-24 09:14:54 +08:00
if len(buf) < 2 {
return fmt.Errorf("数据少于2个字节")
}
t.tail = buf[len(buf)-2:]
2023-10-24 09:14:54 +08:00
return nil
}
// 发送给联锁的采集数据
type InterlockSendMsgPkg struct {
header *interlockMsgPkgHeader // 包头
info []bool // 发给联锁的状态数据
tail *interlockMsgPkgTail // 包尾
}
func NewInterlockSendMsgPkg(info []bool) *InterlockSendMsgPkg {
return &InterlockSendMsgPkg{
header: newInterlockMsgPkgHeader(),
info: info,
tail: newInterlockMsgPkgTail(),
}
2023-10-24 09:14:54 +08:00
}
2023-10-24 10:57:04 +08:00
var boolsToByteArrLen int = 8
func (m *InterlockSendMsgPkg) SetSerialNumber(serialNumber uint8) {
m.header.serialNumber = serialNumber
}
2023-10-24 09:14:54 +08:00
func (m *InterlockSendMsgPkg) Encode() []byte {
var data []byte
data = append(data, m.header.encode()...)
for index, length, cycles := 0, len(m.info), len(m.info)/boolsToByteArrLen; index < cycles; index++ {
2023-10-24 10:57:04 +08:00
startIndex := index * boolsToByteArrLen
toByteArr := [8]bool{}
for i := 0; i < boolsToByteArrLen && startIndex < length; i++ {
startIndex = startIndex + i
toByteArr[i] = m.info[startIndex+i]
2023-10-24 10:57:04 +08:00
}
data = append(data, boolsToByte(toByteArr))
}
data = append(data, m.tail.encode()...)
2023-10-24 09:14:54 +08:00
return data
}
2023-10-24 10:57:04 +08:00
// bool数组转byte
func boolsToByte(flags [8]bool) byte {
var result uint8
2023-10-25 11:09:29 +08:00
for index, b := range flags {
2023-10-24 10:57:04 +08:00
if b {
2023-10-25 11:09:29 +08:00
result = result + (1 << index)
2023-10-24 10:57:04 +08:00
}
}
return result
}
2023-10-24 09:14:54 +08:00
// 收到联锁发来的驱动数据
type InterlockReceiveMsgPkg struct {
toagent_len int
et_out_num int
tcc_output_len int
header *interlockMsgPkgHeader // 包头
2023-10-30 15:23:56 +08:00
SyncZone []byte // 同步区状态
DriveInfo []bool // 驱动数据
TccInfo []*InterlockResponderMsgPkg // 应答器报文
tail *interlockMsgPkgTail // 包尾
2023-10-30 15:23:56 +08:00
}
// 应答器数据格式
type InterlockResponderMsgPkg struct {
Index byte
InternalIndex byte
Reserve byte
MsgInfo []byte
2023-10-24 09:14:54 +08:00
}
// ET_OUT_NUM、TOAGENTLEN、TCC_OUTPUT_LEN应答器数量*131的具体数值取决于数据配置。
func NewInterlockReceiveMsgPkg(tlen, etLen, tccLen int) *InterlockReceiveMsgPkg {
2023-10-24 09:14:54 +08:00
return &InterlockReceiveMsgPkg{
toagent_len: tlen,
et_out_num: etLen,
tcc_output_len: tccLen * 131,
header: newInterlockMsgPkgHeader(),
tail: newInterlockMsgPkgTail(),
2023-10-24 09:14:54 +08:00
}
}
func (t *InterlockReceiveMsgPkg) Decode(buf []byte) error {
if len(buf) < 8 {
return fmt.Errorf("buf 没有足够的数据")
}
var preIndex, lastIndex int = 0, 6
2023-10-24 09:14:54 +08:00
// 包头
t.header.decode(buf[preIndex:lastIndex])
2023-10-24 09:14:54 +08:00
// 同步区状态
preIndex = lastIndex
lastIndex = lastIndex + t.toagent_len
2023-10-30 15:23:56 +08:00
t.SyncZone = buf[preIndex:lastIndex]
2023-10-24 09:14:54 +08:00
// 驱动数据
preIndex = lastIndex
lastIndex = lastIndex + t.et_out_num
2023-10-24 10:57:04 +08:00
t.parseByte(t.DriveInfo, buf, preIndex, lastIndex)
2023-10-24 09:14:54 +08:00
// 应答器报文
preIndex = lastIndex
lastIndex = lastIndex + t.tcc_output_len
2023-10-30 15:23:56 +08:00
t.TccInfo = parseResponder(buf, preIndex, lastIndex)
2023-10-24 09:14:54 +08:00
// 包尾
t.tail.decode(buf)
2023-10-24 09:14:54 +08:00
return nil
}
2023-10-24 10:57:04 +08:00
func (t *InterlockReceiveMsgPkg) parseByte(r []bool, buf []byte, start, end int) {
2023-10-24 10:57:04 +08:00
for i := start; i < end; i++ {
b := buf[i]
for bit := 7; bit >= 0; bit-- {
r = append(r, (b&(1<<bit)) != 0)
}
}
}
2023-10-30 15:23:56 +08:00
func parseResponder(buf []byte, start, end int) []*InterlockResponderMsgPkg {
2023-10-30 15:23:56 +08:00
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
}