小车串口发送传感器数据并接收线速度和角速度

  1. //需要发送的数据
  2. unsigned char infrared_data[48] = {0x7a,0x01,10};
  3. //发送小车数据
  4. void send_speed(void){
  5. //3
  6. float x = 1.123;
  7. //7
  8. float y = 2.123;
  9. //11
  10. float z = 3.123;
  11. //15
  12. float ax = 4.123;
  13. //20
  14. float ay = 5.123;
  15. //24
  16. float az = 6.123;
  17. //28
  18. float gx = 7.123;
  19. //32
  20. float gy = 8.123;
  21. //36
  22. float gz = 9.123;
  23. //40
  24. float v = 10.123;
  25. //44
  26. float check_sum = 0x01+10+x+y+z+ax+ay+az+gx+gy+gz+v;
  27. //数据准备
  28. memcpy(infrared_data+3,&x,4);
  29. memcpy(infrared_data+7,&y,4);
  30. memcpy(infrared_data+11,&z,4);
  31. memcpy(infrared_data+15,&ax,4);
  32. memcpy(infrared_data+19,&ay,4);
  33. memcpy(infrared_data+23,&az,4);
  34. memcpy(infrared_data+27,&gx,4);
  35. memcpy(infrared_data+31,&gy,4);
  36. memcpy(infrared_data+35,&gz,4);
  37. memcpy(infrared_data+39,&v,4);
  38. memcpy(infrared_data+43,&check_sum,4);
  39. //帧尾
  40. infrared_data[47] = 0x7b;
  41. //infrared_data[48] = '\n';
  42. //printf("%s",infrared_data);
  43. uart5_dma_send(infrared_data,sizeof(infrared_data));
  44. }

鲁班猫定义串口节点接收传感器数据并发送线速度和角速度

  1. import rclpy
  2. from rclpy.node import Node
  3. import serial
  4. import struct
  5. import time
  6. import threading
  7. class SerialNode(Node):
  8. def __init__(self,node_name):
  9. super().__init__(node_name)
  10. # 创建串口对象
  11. self.ser = serial.Serial("/dev/ttyS3",115200,timeout = 5)
  12. self.ser.flushInput()
  13. self.i = 0
  14. # 需要发送的头 类型和数据长度
  15. self.head = struct.pack('<b',0x7b)
  16. self.instruction = struct.pack('<b',0x00)
  17. self.length = struct.pack('<b',3)
  18. self.tail = struct.pack('<b',0x7a)
  19. self.t1 = threading.Thread(target=self.recv_speed)
  20. self.t2 = threading.Thread(target=self.send_speed,args=(-10.743,-4.786,9.295))
  21. # 守护线程 主线程挂掉 子线程也挂掉 需要在start之前设置
  22. self.t1.setDaemon(True)
  23. self.t1.setDaemon(True)
  24. self.t1.start()
  25. self.t2.start()
  26. # TODO 发送真实的操作指令
  27. def send_speed(self,x,y,z):
  28. while True:
  29. data = struct.pack('<f',x)+struct.pack('<f',y)+struct.pack('<f',z)
  30. # 校验和校验
  31. check_num = 0x00+3+x+y+z
  32. check = struct.pack('<f',check_num)
  33. # 需要发送的数据
  34. data = self.head+self.instruction+self.length+data+check+self.tail
  35. # 发送串口数据
  36. self.ser.write(data)
  37. time.sleep(0.06)
  38. def recv_speed(self):
  39. print('start')
  40. print(f'is_open:{self.ser.is_open}')
  41. # while True:
  42. # print(f'i:{self.i}')
  43. # self.i += 1
  44. # time.sleep(0.06)
  45. while True:
  46. self.i += 1
  47. # 获取需要接收的数据个数
  48. num = self.ser.inWaiting()
  49. # print(f'i:{self.i} start num:{num}')
  50. # num = self.ser.in_waiting()
  51. # if num<=0 or num != 48:
  52. # continue
  53. if num<=0 or num<48:
  54. continue
  55. if num>48:
  56. # 清除
  57. self.ser.read(num)
  58. continue
  59. # 正常的一帧数据
  60. print(f'num:{num}')
  61. data = self.ser.read(num)
  62. # 解析数据
  63. self.parse_speed(data)
  64. print('end')
  65. time.sleep(0.06)
  66. # TODO 通过获取到的数据进行决策
  67. def parse_speed(self,data):
  68. # 帧头
  69. head = struct.unpack('<B',data[:1])[0]
  70. if head!=122:
  71. return
  72. # 命令
  73. ins = struct.unpack('<B',data[1:2])[0]
  74. if ins!=1:
  75. return
  76. # 数据长度
  77. length = struct.unpack('<B',data[2:3])[0]
  78. if length!=10:
  79. return
  80. # 数据
  81. want_data = struct.unpack('<ffffffffff',data[3:43])
  82. # 校验位
  83. check = struct.unpack('<f',data[43:47])[0]
  84. # 帧尾
  85. tail = struct.unpack('<B',data[47:])[0]
  86. # self.get_logger().info(f'i:{self.i},帧头:{head},命令:{ins},数据长度:{length},数据:{want_data},校验位:{check},帧尾:{tail}')
  87. print(f'i:{self.i},帧头:{head},命令:{ins},数据长度:{length},数据:{want_data},校验位:{check},帧尾:{tail}')
  88. print(f'i:{self.i} end')
  89. def main():
  90. # 初始化rclpy
  91. rclpy.init()
  92. # 参数:节点名称
  93. node = SerialNode('serial_node')
  94. # 节点代码执行完之后需要销毁节点
  95. node.destroy_node()
  96. # 关闭rclpy
  97. rclpy.shutdown()
  98. if __name__ == '__main__':
  99. main()