rts-sim-testing-service/third_party/message/interlock.go
2023-10-30 15:23:56 +08:00

162 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package message
import "fmt"
// 消息包头解析
type InterlockMsgPkgHeader struct {
Header1 byte //包头1 1个字节
Header2 byte //包头2 1个字节
TypeCode uint8 //类型码 1个字节 0x02
SerialNumber uint8 //序列号 1个字节 序列号0~255
Reserve1 byte //预留 1个字节
Reserve2 byte //预留 1个字节
}
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 {
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]
return nil
}
// 消息包尾解析
type InterlockMsgPkgTail struct {
Tail []byte // 包尾2个字节
}
func (t *InterlockMsgPkgTail) Encode() []byte {
if len(t.Tail) == 0 {
return make([]byte, 2)
}
return t.Tail
}
func (t *InterlockMsgPkgTail) Decode(buf []byte) error {
if len(buf) < 2 {
return fmt.Errorf("数据少于2个字节")
}
t.Tail = buf[len(buf)-2:]
return nil
}
// 发送给联锁的采集数据
type InterlockSendMsgPkg struct {
Header *InterlockMsgPkgHeader // 包头
Info []bool // 发给联锁的状态数据
Tail *InterlockMsgPkgTail // 包尾
}
var boolsToByteArrLen int = 8
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++ {
startIndex := index * boolsToByteArrLen
toByteArr := [8]bool{}
for i := 0; i < boolsToByteArrLen && startIndex < length; i++ {
startIndex = startIndex + i
toByteArr[i] = m.Info[startIndex+i]
}
data = append(data, boolsToByte(toByteArr))
}
data = append(data, m.Tail.Encode()...)
return data
}
// bool数组转byte
func boolsToByte(flags [8]bool) byte {
var result uint8
for index, b := range flags {
if b {
result = result + (1 << index)
}
}
return result
}
// 收到联锁发来的驱动数据
type InterlockReceiveMsgPkg struct {
toagent_len int32
et_out_num int32
tcc_output_len int32
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的具体数值取决于数据配置。
func NewInterlockReceiveMsgPkg(tlen, etLen, tccLen int32) *InterlockReceiveMsgPkg {
return &InterlockReceiveMsgPkg{
toagent_len: tlen,
et_out_num: etLen,
tcc_output_len: tccLen,
Header: &InterlockMsgPkgHeader{},
Tail: &InterlockMsgPkgTail{},
}
}
func (t *InterlockReceiveMsgPkg) Decode(buf []byte) error {
var preIndex, lastIndex int32 = 0, 6
// 包头
t.Header.Decode(buf[preIndex:lastIndex])
// 同步区状态
preIndex = lastIndex
lastIndex = lastIndex + t.toagent_len
t.SyncZone = buf[preIndex:lastIndex]
// 驱动数据
preIndex = lastIndex
lastIndex = lastIndex + t.et_out_num
t.parseByte(t.DriveInfo, buf, preIndex, lastIndex)
// 应答器报文
preIndex = lastIndex
lastIndex = lastIndex + t.tcc_output_len
t.TccInfo = parseResponder(buf, preIndex, lastIndex)
// 包尾
t.Tail.Decode(buf)
return nil
}
func (t *InterlockReceiveMsgPkg) parseByte(r []bool, buf []byte, start, end int32) {
for i := start; i < end; i++ {
b := buf[i]
for bit := 7; bit >= 0; bit-- {
r = append(r, (b&(1<<bit)) != 0)
}
}
}
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
}