小车串口发送传感器数据并接收线速度和角速度
//需要发送的数据
unsigned char infrared_data[48] = {0x7a,0x01,10};
//发送小车数据
void send_speed(void){
//3
float x = 1.123;
//7
float y = 2.123;
//11
float z = 3.123;
//15
float ax = 4.123;
//20
float ay = 5.123;
//24
float az = 6.123;
//28
float gx = 7.123;
//32
float gy = 8.123;
//36
float gz = 9.123;
//40
float v = 10.123;
//44
float check_sum = 0x01+10+x+y+z+ax+ay+az+gx+gy+gz+v;
//数据准备
memcpy(infrared_data+3,&x,4);
memcpy(infrared_data+7,&y,4);
memcpy(infrared_data+11,&z,4);
memcpy(infrared_data+15,&ax,4);
memcpy(infrared_data+19,&ay,4);
memcpy(infrared_data+23,&az,4);
memcpy(infrared_data+27,&gx,4);
memcpy(infrared_data+31,&gy,4);
memcpy(infrared_data+35,&gz,4);
memcpy(infrared_data+39,&v,4);
memcpy(infrared_data+43,&check_sum,4);
//帧尾
infrared_data[47] = 0x7b;
//infrared_data[48] = '\n';
//printf("%s",infrared_data);
uart5_dma_send(infrared_data,sizeof(infrared_data));
}
鲁班猫定义串口节点接收传感器数据并发送线速度和角速度
import rclpy
from rclpy.node import Node
import serial
import struct
import time
import threading
class SerialNode(Node):
def __init__(self,node_name):
super().__init__(node_name)
# 创建串口对象
self.ser = serial.Serial("/dev/ttyS3",115200,timeout = 5)
self.ser.flushInput()
self.i = 0
# 需要发送的头 类型和数据长度
self.head = struct.pack('<b',0x7b)
self.instruction = struct.pack('<b',0x00)
self.length = struct.pack('<b',3)
self.tail = struct.pack('<b',0x7a)
self.t1 = threading.Thread(target=self.recv_speed)
self.t2 = threading.Thread(target=self.send_speed,args=(-10.743,-4.786,9.295))
# 守护线程 主线程挂掉 子线程也挂掉 需要在start之前设置
self.t1.setDaemon(True)
self.t1.setDaemon(True)
self.t1.start()
self.t2.start()
# TODO 发送真实的操作指令
def send_speed(self,x,y,z):
while True:
data = struct.pack('<f',x)+struct.pack('<f',y)+struct.pack('<f',z)
# 校验和校验
check_num = 0x00+3+x+y+z
check = struct.pack('<f',check_num)
# 需要发送的数据
data = self.head+self.instruction+self.length+data+check+self.tail
# 发送串口数据
self.ser.write(data)
time.sleep(0.06)
def recv_speed(self):
print('start')
print(f'is_open:{self.ser.is_open}')
# while True:
# print(f'i:{self.i}')
# self.i += 1
# time.sleep(0.06)
while True:
self.i += 1
# 获取需要接收的数据个数
num = self.ser.inWaiting()
# print(f'i:{self.i} start num:{num}')
# num = self.ser.in_waiting()
# if num<=0 or num != 48:
# continue
if num<=0 or num<48:
continue
if num>48:
# 清除
self.ser.read(num)
continue
# 正常的一帧数据
print(f'num:{num}')
data = self.ser.read(num)
# 解析数据
self.parse_speed(data)
print('end')
time.sleep(0.06)
# TODO 通过获取到的数据进行决策
def parse_speed(self,data):
# 帧头
head = struct.unpack('<B',data[:1])[0]
if head!=122:
return
# 命令
ins = struct.unpack('<B',data[1:2])[0]
if ins!=1:
return
# 数据长度
length = struct.unpack('<B',data[2:3])[0]
if length!=10:
return
# 数据
want_data = struct.unpack('<ffffffffff',data[3:43])
# 校验位
check = struct.unpack('<f',data[43:47])[0]
# 帧尾
tail = struct.unpack('<B',data[47:])[0]
# self.get_logger().info(f'i:{self.i},帧头:{head},命令:{ins},数据长度:{length},数据:{want_data},校验位:{check},帧尾:{tail}')
print(f'i:{self.i},帧头:{head},命令:{ins},数据长度:{length},数据:{want_data},校验位:{check},帧尾:{tail}')
print(f'i:{self.i} end')
def main():
# 初始化rclpy
rclpy.init()
# 参数:节点名称
node = SerialNode('serial_node')
# 节点代码执行完之后需要销毁节点
node.destroy_node()
# 关闭rclpy
rclpy.shutdown()
if __name__ == '__main__':
main()