小车串口发送传感器数据并接收线速度和角速度
//需要发送的数据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 rclpyfrom rclpy.node import Nodeimport serial import structimport timeimport threadingclass 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()