666浏览
查看: 666|回复: 0

[项目分享] Maixduino麦克纳姆轮小车

[复制链接]
本帖最后由 云天 于 2021-11-8 22:02 编辑

7e655e2421da64a088a64585b2761cb5_1440w.jpg


IMG_20211107_140726.jpg



什么是麦克纳姆轮
在竞赛机器人和特殊工种机器人中,全向移动经常是一个必需的功能。「全向移动」意味着可以在平面内做出任意方向平移同时自转的动作。为了实现全向移动,一般机器人会使用「全向轮」(Omni Wheel)或「麦克纳姆轮」(Mecanum Wheel)这两种特殊轮子。
全向轮:
083fe21a6f279c1557449b5b98e86144_720w.jpg
麦克纳姆轮:
c0afec3dbaf170e179b240af4b78f22f_720w.jpg
麦克纳姆轮与普通轮子的区别在于麦克纳姆轮旋转时,由于存在斜向的从动轮,会同时产生一个斜向的力,当我们控制轮子旋转的速度与方向时,将斜向的力增强或抵消,从而实现小车的全向移动。可以完成横移、斜方向移动等普通小车无法完成的高难度动作,轮子的转动方向与小车的运动方向关系如下图:
运动示意图.jpg
【麦克纳姆轮安装】
车拆时再上图
【电机驱动L298N安装】
车拆时再上图
【电机电源及灯带安装】
车拆时再上图
【Maixduino 主控安装】
车拆时再上图
【Mind+编程】
QQ截图20211107223408.png
【Micrpython代码】

  1. # MindPlus
  2. # maixduino
  3. from network_esp32 import wifi
  4. from board import board_info
  5. from umqtt import MQTTClient
  6. from machine import Timer
  7. from pin import Pin
  8. import ubinascii
  9. import neopixel
  10. import machine
  11. import usocket
  12. import time
  13. import gc
  14. def neopixel_range(rgb, start, end, color):
  15.   trend = -1 if end < start else 1
  16.   for i in range(start, end-1 if trend < 0 else end+1, trend):
  17.     rgb[i] = (color)
  18.   rgb.write()
  19. def hostgetIP(host):
  20.         return usocket.getaddrinfo(host,8080,0,0)[0][4][0]
  21. _mqtt_topic_list = []
  22. def timer11_tick(_):
  23.   global mqtt
  24.   mqtt.check_msg()
  25. def mqtt_callback(topic, msg):
  26.   try:
  27.     topic = topic.decode('utf-8', 'ignore')
  28.     _msg = msg.decode('utf-8', 'ignore')
  29.     eval('mqtt_topic_' + bytes.decode(ubinascii.hexlify(topic)) + '("' + _msg + '")')
  30.   except:
  31.     print((topic, msg))
  32. def neopixel_rotate(rgb, offset):
  33.   steps = rgb.n
  34.   if offset == 0 or steps == 0:
  35.     return
  36.   offset = (abs(offset) % steps)*(-1 if offset < 0 else 1)
  37.   c = []
  38.   if offset > 0:
  39.     for i in range(0, offset):
  40.       c.append(rgb[steps-offset+i])
  41.     for i in range(steps-1, offset-1, -1):
  42.       rgb[i] = rgb[i-offset]
  43.     for i in range(0, offset):
  44.       rgb[i] = c[i]
  45.   else:
  46.     for i in range(0, abs(offset)):
  47.       c.append(rgb[i])
  48.     for i in range(0, steps-abs(offset)):
  49.       rgb[i] = rgb[i+abs(offset)]
  50.     for i in range(steps-abs(offset), steps):
  51.       rgb[i] = c[i-steps+abs(offset)]
  52.   rgb.write()
  53. def neopixel_hsl(h, s, l):
  54.   h = (abs(h) % 360)*(-1 if h < 0 else 1)
  55.   s = max(s, 0); s = min(s, 99); l = max(l, 0); l = min(l, 99)
  56.   c = (((100 - abs(2 * l - 100)) * s) << 8) // 10000
  57.   h1 = h // 60; h2 = (h - h1 * 60) * 256 // 60;
  58.   temp = abs((((h1 % 2) << 8) + h2) - 256);
  59.   x = (c * (256 - (temp))) >> 8; _r = _g = _b = 0
  60.   if h1 == 0:
  61.     _r = c; _g = x; _b = 0
  62.   elif h1 == 1:
  63.     _r = x; _g = c; _b = 0
  64.   elif h1 == 2:
  65.     _r = 0; _g = c; _b = x
  66.   elif h1 == 3:
  67.     _r = 0; _g = x; _b = c
  68.   elif h1 == 4:
  69.     _r = x; _g = 0; _b = c
  70.   elif h1 == 5:
  71.     _r = c; _g = 0; _b = x
  72.   m = ((l * 2 << 8) // 100 - c) // 2
  73.   r = _r + m; g = _g + m; b = _b + m
  74.   return (r, g, b)
  75. def neopixel_rainbow(rgb, start, end, start_hue, end_hue):
  76.   steps = rgb.n
  77.   if steps == 0:
  78.     return
  79.   if end < start:
  80.     num = end; end = start; start = num
  81.   start = max(start, 0); start = min(start, steps)
  82.   end = max(end, 0); end = min(end, steps)
  83.   steps = end - start + 1
  84.   saturation = 100; luminance = 50; h1 = start_hue; h2 = end_hue
  85.   hDistCW = (abs((h2 + 360) - h1) % 360)*(-1 if ((h2 + 360) - h1) < 0 else 1)
  86.   hStepCW = (hDistCW * 100) // steps; hStep = hStepCW
  87.   h1_100 = h1 * 100; s1 = saturation; s2 = saturation; sDist = s2 - s1
  88.   sStep = sDist // steps; s1_100 = s1 * 100; l1 = luminance; l2 = luminance
  89.   lDist = l2 - l1; lStep = lDist // steps; l1_100 = l1 * 100
  90.   if steps == 1:
  91.     rgb[start] =  neopixel_hsl(h1 + hStep, s1 + sStep, l1 + lStep)
  92.   else:
  93.     rgb[start] = neopixel_hsl(start_hue, saturation, luminance)
  94.     for i in range(start + 1, start + steps - 1):
  95.       h = (h1_100 + i * hStep) // 100 + 360
  96.       s = (s1_100 + i * sStep) // 100
  97.       l = (l1_100 + i * lStep) // 100
  98.       rgb[i] = neopixel_hsl(h, s, l)
  99.     rgb[start + steps - 1] = neopixel_hsl(end_hue, saturation, luminance)
  100.   rgb.write()
  101. # 自定义函数
  102. def back():
  103.   Pin.digital_write(board_info.PIN2, 1)
  104.   Pin.digital_write(board_info.PIN3, 0)
  105.   Pin.digital_write(board_info.PIN4, 1)
  106.   Pin.digital_write(board_info.PIN5, 0)
  107.   Pin.digital_write(board_info.PIN8, 0)
  108.   Pin.digital_write(board_info.PIN9, 1)
  109.   Pin.digital_write(board_info.PIN10, 0)
  110.   Pin.digital_write(board_info.PIN11, 1)
  111. def forward():
  112.   Pin.digital_write(board_info.PIN2, 0)
  113.   Pin.digital_write(board_info.PIN3, 1)
  114.   Pin.digital_write(board_info.PIN4, 0)
  115.   Pin.digital_write(board_info.PIN5, 1)
  116.   Pin.digital_write(board_info.PIN8, 1)
  117.   Pin.digital_write(board_info.PIN9, 0)
  118.   Pin.digital_write(board_info.PIN10, 1)
  119.   Pin.digital_write(board_info.PIN11, 0)
  120. def stop():
  121.   Pin.digital_write(board_info.PIN2, 0)
  122.   Pin.digital_write(board_info.PIN3, 0)
  123.   Pin.digital_write(board_info.PIN4, 0)
  124.   Pin.digital_write(board_info.PIN5, 0)
  125.   Pin.digital_write(board_info.PIN8, 0)
  126.   Pin.digital_write(board_info.PIN9, 0)
  127.   Pin.digital_write(board_info.PIN10, 0)
  128.   Pin.digital_write(board_info.PIN11, 0)
  129. def right():
  130.   Pin.digital_write(board_info.PIN10, 1)
  131.   Pin.digital_write(board_info.PIN11, 0)
  132.   Pin.digital_write(board_info.PIN2, 1)
  133.   Pin.digital_write(board_info.PIN3, 0)
  134.   Pin.digital_write(board_info.PIN8, 0)
  135.   Pin.digital_write(board_info.PIN9, 1)
  136.   Pin.digital_write(board_info.PIN4, 0)
  137.   Pin.digital_write(board_info.PIN5, 1)
  138. def left():
  139.   Pin.digital_write(board_info.PIN10, 0)
  140.   Pin.digital_write(board_info.PIN11, 1)
  141.   Pin.digital_write(board_info.PIN2, 0)
  142.   Pin.digital_write(board_info.PIN3, 1)
  143.   Pin.digital_write(board_info.PIN8, 1)
  144.   Pin.digital_write(board_info.PIN9, 0)
  145.   Pin.digital_write(board_info.PIN4, 1)
  146.   Pin.digital_write(board_info.PIN5, 0)
  147. # 事件回调函数
  148. def mqtt_topic_356e39327571424d67(_msg):
  149.   global JieGuo
  150.   if (_msg == 'G'):
  151.     forward()
  152.     time.sleep(0.2)
  153.     stop()
  154.   if (_msg == 'B'):
  155.     back()
  156.     time.sleep(0.2)
  157.     stop()
  158.   if (_msg == 'L'):
  159.     left()
  160.     time.sleep(0.2)
  161.     stop()
  162.   if (_msg == 'R'):
  163.     right()
  164.     time.sleep(0.2)
  165.     stop()
  166.   if (_msg == 'S'):
  167.     stop()
  168.   if (_msg == 'Y'):
  169.     JieGuo = 1
  170.     neopixel_rainbow(ws2812_13, 0, 15, 1, 360)
  171.   if (_msg == 'N'):
  172.     JieGuo = 0
  173.     ws2812_13.fill((0, 0, 0))
  174.     ws2812_13.write()
  175. ws2812_13 = neopixel.NeoPixel(board_info.PIN13, n=16, bpp=3, timing=1)
  176. ws2812_13.fill((0, 0, 0))
  177. ws2812_13.write()
  178. neopixel_range(ws2812_13, 0, 15, (0, 0, 255))
  179. time.sleep(3)
  180. ws2812_13.fill((0, 0, 0))
  181. ws2812_13.write()
  182. wifi.connect("sxs", "smj080823")
  183. while not (wifi.isconnected()):
  184.   pass
  185. mqtt = MQTTClient("", hostgetIP("iot.dfrobot.com.cn"), 1883, "X8jykxFnR", "u8jskbFngz", keepalive=300)
  186. try:
  187.   mqtt.connect()
  188.   print('MQTT Connected Successful')
  189. except:
  190.   print('MQTT Connection Failed')
  191. mqtt.set_callback(mqtt_callback)
  192. mqtt.subscribe("5n92uqBMg")
  193. tim11 =Timer(Timer.TIMER2,Timer.CHANNEL3,mode=Timer.MODE_PERIODIC,period=50,callback=timer11_tick)
  194. ShiJian = time.ticks_ms()
  195. JieGuo = 0
  196. neopixel_range(ws2812_13, 0, 15, (204, 0, 0))
  197. time.sleep(3)
  198. ws2812_13.fill((0, 0, 0))
  199. ws2812_13.write()
  200. while True:
  201.   if (JieGuo == 1):
  202.     if ((time.ticks_ms() - ShiJian) > 200):
  203.       neopixel_rotate(ws2812_13, 1)
  204.       ShiJian = time.ticks_ms()
  205.   if Pin.digital_read(board_info.PIN6):
  206.     gc.collect()
  207.     neopixel_range(ws2812_13, 0, 15, (0, 0, 255))
  208.     time.sleep(0.2)
  209.     ws2812_13.fill((0, 0, 0))
  210.     ws2812_13.write()
  211.     neopixel_range(ws2812_13, 0, 15, (204, 0, 0))
  212.     time.sleep(0.2)
  213.     ws2812_13.fill((0, 0, 0))
  214.     ws2812_13.write()
  215.     machine.reset()
复制代码
其中修改“mqtt = MQTTClient("", hostgetIP("iot.dfrobot.com.cn"), 1883, "X8jykxFnR", "u8jskbFngz", keepalive=300)”中的“keepalive”值改为“300”。(MQTT在建立连接的时候,我们可以传递一个 Keep Alive 参数,它的单位为秒,MQTT 协议中约定:在 1.5*Keep Alive 的时间间隔内,如果 Broker 没有收到来自 Client 的任何数据包,那么 Broker 认为它和 Client 之间的连接已经断开;同样地, 如果 Client 没有收到来自 Broker 的任何数据包,那么 Client 认为它和 Broker 之间的连接已经断开。)
【App Inventor编程】
QQ截图20211107223005.png
QQ截图20211107223327.png
QQ截图20211107223146.png
Screenshot_20211107_222856_edu.mit.appinventor.ai.jpg
【程序进一步优化】为实现小车连续运动,将APP中的按钮命令“点击”发送修改为“按下”发送,再增加“松开”命令发送“停止指令”。Maixduino程序中将接收命令后的"stop"指令去掉。
QQ截图20211108095749.png
QQ截图20211108100539.png

  1. # MindPlus
  2. # maixduino
  3. from network_esp32 import wifi
  4. from board import board_info
  5. from umqtt import MQTTClient
  6. from machine import Timer
  7. from pin import Pin
  8. import ubinascii
  9. import neopixel
  10. import usocket
  11. import time
  12. def neopixel_range(rgb, start, end, color):
  13.   trend = -1 if end < start else 1
  14.   for i in range(start, end-1 if trend < 0 else end+1, trend):
  15.     rgb[i] = (color)
  16.   rgb.write()
  17. def hostgetIP(host):
  18.         return usocket.getaddrinfo(host,8080,0,0)[0][4][0]
  19. _mqtt_topic_list = []
  20. def timer11_tick(_):
  21.   global mqtt
  22.   mqtt.check_msg()
  23. def mqtt_callback(topic, msg):
  24.   try:
  25.     topic = topic.decode('utf-8', 'ignore')
  26.     _msg = msg.decode('utf-8', 'ignore')
  27.     eval('mqtt_topic_' + bytes.decode(ubinascii.hexlify(topic)) + '("' + _msg + '")')
  28.   except:
  29.     print((topic, msg))
  30. def neopixel_rotate(rgb, offset):
  31.   steps = rgb.n
  32.   if offset == 0 or steps == 0:
  33.     return
  34.   offset = (abs(offset) % steps)*(-1 if offset < 0 else 1)
  35.   c = []
  36.   if offset > 0:
  37.     for i in range(0, offset):
  38.       c.append(rgb[steps-offset+i])
  39.     for i in range(steps-1, offset-1, -1):
  40.       rgb[i] = rgb[i-offset]
  41.     for i in range(0, offset):
  42.       rgb[i] = c[i]
  43.   else:
  44.     for i in range(0, abs(offset)):
  45.       c.append(rgb[i])
  46.     for i in range(0, steps-abs(offset)):
  47.       rgb[i] = rgb[i+abs(offset)]
  48.     for i in range(steps-abs(offset), steps):
  49.       rgb[i] = c[i-steps+abs(offset)]
  50.   rgb.write()
  51. def neopixel_hsl(h, s, l):
  52.   h = (abs(h) % 360)*(-1 if h < 0 else 1)
  53.   s = max(s, 0); s = min(s, 99); l = max(l, 0); l = min(l, 99)
  54.   c = (((100 - abs(2 * l - 100)) * s) << 8) // 10000
  55.   h1 = h // 60; h2 = (h - h1 * 60) * 256 // 60;
  56.   temp = abs((((h1 % 2) << 8) + h2) - 256);
  57.   x = (c * (256 - (temp))) >> 8; _r = _g = _b = 0
  58.   if h1 == 0:
  59.     _r = c; _g = x; _b = 0
  60.   elif h1 == 1:
  61.     _r = x; _g = c; _b = 0
  62.   elif h1 == 2:
  63.     _r = 0; _g = c; _b = x
  64.   elif h1 == 3:
  65.     _r = 0; _g = x; _b = c
  66.   elif h1 == 4:
  67.     _r = x; _g = 0; _b = c
  68.   elif h1 == 5:
  69.     _r = c; _g = 0; _b = x
  70.   m = ((l * 2 << 8) // 100 - c) // 2
  71.   r = _r + m; g = _g + m; b = _b + m
  72.   return (r, g, b)
  73. def neopixel_rainbow(rgb, start, end, start_hue, end_hue):
  74.   steps = rgb.n
  75.   if steps == 0:
  76.     return
  77.   if end < start:
  78.     num = end; end = start; start = num
  79.   start = max(start, 0); start = min(start, steps)
  80.   end = max(end, 0); end = min(end, steps)
  81.   steps = end - start + 1
  82.   saturation = 100; luminance = 50; h1 = start_hue; h2 = end_hue
  83.   hDistCW = (abs((h2 + 360) - h1) % 360)*(-1 if ((h2 + 360) - h1) < 0 else 1)
  84.   hStepCW = (hDistCW * 100) // steps; hStep = hStepCW
  85.   h1_100 = h1 * 100; s1 = saturation; s2 = saturation; sDist = s2 - s1
  86.   sStep = sDist // steps; s1_100 = s1 * 100; l1 = luminance; l2 = luminance
  87.   lDist = l2 - l1; lStep = lDist // steps; l1_100 = l1 * 100
  88.   if steps == 1:
  89.     rgb[start] =  neopixel_hsl(h1 + hStep, s1 + sStep, l1 + lStep)
  90.   else:
  91.     rgb[start] = neopixel_hsl(start_hue, saturation, luminance)
  92.     for i in range(start + 1, start + steps - 1):
  93.       h = (h1_100 + i * hStep) // 100 + 360
  94.       s = (s1_100 + i * sStep) // 100
  95.       l = (l1_100 + i * lStep) // 100
  96.       rgb[i] = neopixel_hsl(h, s, l)
  97.     rgb[start + steps - 1] = neopixel_hsl(end_hue, saturation, luminance)
  98.   rgb.write()
  99. # 自定义函数
  100. def back():
  101.   Pin.digital_write(board_info.PIN2, 1)
  102.   Pin.digital_write(board_info.PIN3, 0)
  103.   Pin.digital_write(board_info.PIN4, 1)
  104.   Pin.digital_write(board_info.PIN5, 0)
  105.   Pin.digital_write(board_info.PIN8, 0)
  106.   Pin.digital_write(board_info.PIN9, 1)
  107.   Pin.digital_write(board_info.PIN10, 0)
  108.   Pin.digital_write(board_info.PIN11, 1)
  109. def forward():
  110.   Pin.digital_write(board_info.PIN2, 0)
  111.   Pin.digital_write(board_info.PIN3, 1)
  112.   Pin.digital_write(board_info.PIN4, 0)
  113.   Pin.digital_write(board_info.PIN5, 1)
  114.   Pin.digital_write(board_info.PIN8, 1)
  115.   Pin.digital_write(board_info.PIN9, 0)
  116.   Pin.digital_write(board_info.PIN10, 1)
  117.   Pin.digital_write(board_info.PIN11, 0)
  118. def stop():
  119.   Pin.digital_write(board_info.PIN2, 0)
  120.   Pin.digital_write(board_info.PIN3, 0)
  121.   Pin.digital_write(board_info.PIN4, 0)
  122.   Pin.digital_write(board_info.PIN5, 0)
  123.   Pin.digital_write(board_info.PIN8, 0)
  124.   Pin.digital_write(board_info.PIN9, 0)
  125.   Pin.digital_write(board_info.PIN10, 0)
  126.   Pin.digital_write(board_info.PIN11, 0)
  127. def right():
  128.   Pin.digital_write(board_info.PIN10, 1)
  129.   Pin.digital_write(board_info.PIN11, 0)
  130.   Pin.digital_write(board_info.PIN2, 1)
  131.   Pin.digital_write(board_info.PIN3, 0)
  132.   Pin.digital_write(board_info.PIN8, 0)
  133.   Pin.digital_write(board_info.PIN9, 1)
  134.   Pin.digital_write(board_info.PIN4, 0)
  135.   Pin.digital_write(board_info.PIN5, 1)
  136. def left():
  137.   Pin.digital_write(board_info.PIN10, 0)
  138.   Pin.digital_write(board_info.PIN11, 1)
  139.   Pin.digital_write(board_info.PIN2, 0)
  140.   Pin.digital_write(board_info.PIN3, 1)
  141.   Pin.digital_write(board_info.PIN8, 1)
  142.   Pin.digital_write(board_info.PIN9, 0)
  143.   Pin.digital_write(board_info.PIN4, 1)
  144.   Pin.digital_write(board_info.PIN5, 0)
  145. # 事件回调函数
  146. def mqtt_topic_356e39327571424d67(_msg):
  147.   global JieGuo
  148.   if (_msg == 'G'):
  149.     forward()
  150.   if (_msg == 'B'):
  151.     back()
  152.   if (_msg == 'L'):
  153.     left()
  154.   if (_msg == 'R'):
  155.     right()
  156.   if (_msg == 'S'):
  157.     stop()
  158.   if (_msg == 'Y'):
  159.     JieGuo = 1
  160.     neopixel_rainbow(ws2812_13, 0, 15, 1, 360)
  161.   if (_msg == 'N'):
  162.     JieGuo = 0
  163.     ws2812_13.fill((0, 0, 0))
  164.     ws2812_13.write()
  165. ws2812_13 = neopixel.NeoPixel(board_info.PIN13, n=16, bpp=3, timing=1)
  166. ws2812_13.fill((0, 0, 0))
  167. ws2812_13.write()
  168. neopixel_range(ws2812_13, 0, 15, (0, 0, 255))
  169. time.sleep(3)
  170. ws2812_13.fill((0, 0, 0))
  171. ws2812_13.write()
  172. wifi.connect("sxs", "smj080823")
  173. while not (wifi.isconnected()):
  174.   pass
  175. mqtt = MQTTClient("", hostgetIP("iot.dfrobot.com.cn"), 1883, "X8jykxFnR", "u8jskbFngz", keepalive=30)
  176. try:
  177.   mqtt.connect()
  178.   print('MQTT Connected Successful')
  179. except:
  180.   print('MQTT Connection Failed')
  181. mqtt.set_callback(mqtt_callback)
  182. mqtt.subscribe("5n92uqBMg")
  183. tim11 =Timer(Timer.TIMER2,Timer.CHANNEL3,mode=Timer.MODE_PERIODIC,period=50,callback=timer11_tick)
  184. ShiJian = time.ticks_ms()
  185. JieGuo = 0
  186. neopixel_range(ws2812_13, 0, 15, (204, 0, 0))
  187. time.sleep(3)
  188. ws2812_13.fill((0, 0, 0))
  189. ws2812_13.write()
  190. while True:
  191.   if (JieGuo == 1):
  192.     if ((time.ticks_ms() - ShiJian) > 200):
  193.       neopixel_rotate(ws2812_13, 1)
  194.       ShiJian = time.ticks_ms()
复制代码

演示:麦克纳姆大战小黑
【语音控制】

1、使用软件“MaixPy IDE”,首先将asr.py上传到Maixduino板子上。选择“工具”菜单,“发送文件到开发板”。
文中用到的ASR.py是由df团队编写(感谢李工提供),具体代码如下:
  1. import time
  2. import json
  3. from Maix import GPIO, I2S
  4. from fpioa_manager import fm
  5. from speech_recognizer import isolated_word
  6. class ASR:
  7.     def __init__(self):
  8.         self.asr = None
  9.         self.i2s = None
  10.         self.model = None
  11.     def __start(self, size):
  12.         if self.asr:
  13.             del self.asr
  14.         if self.i2s:
  15.             del self.i2s
  16.         try:
  17.             fm.register(20,fm.fpioa.I2S0_IN_D0, force=True)
  18.             fm.register(18,fm.fpioa.I2S0_SCLK, force=True)
  19.             fm.register(19,fm.fpioa.I2S0_WS, force=True)
  20.             self.i2s = I2S(I2S.DEVICE_0)
  21.             self.i2s.channel_config(self.i2s.CHANNEL_0, self.i2s.RECEIVER, align_mode=I2S.STANDARD_MODE)
  22.             self.i2s.set_sample_rate(16000)
  23.             self.asr = isolated_word(dmac=2, i2s=I2S.DEVICE_0, size=size)
  24.             self.asr.set_threshold(0, 0, 15000)
  25.             return True
  26.         except:
  27.             return False
  28.     def newModel(self):
  29.         return []
  30.     def training(self, corpus, model):
  31.         if not corpus or not self.__start(1) or not self.asr:
  32.             return
  33.         rc=1
  34.         co=0
  35.         while True:
  36.             time.sleep_ms(100)
  37.             if self.asr.Done == self.asr.record(0):
  38.                 model.append({'name': corpus, 'data': self.asr.get(0)})
  39.                 print("complete")
  40.                 break
  41.             if self.asr.Speak == self.asr.state():
  42.                 if rc != -1:
  43.                     print()
  44.                 print("speak: " + str(corpus))
  45.                 rc = -1
  46.             else:
  47.                 if co%2==0:
  48.                     print("\rready" + "."*rc + " "*(3-rc), end='')
  49.                     rc += 1
  50.                     if rc > 3:
  51.                         rc = 1
  52.             co += 1
  53.     def run(self, model):
  54.         if not model or len(model)<1 or not self.__start(len(model)) or not self.asr:
  55.             return None
  56.         for i in range(len(model)):
  57.             self.asr.set(i, model[i]['data'])
  58.         self.model = model
  59.     def recognize(self):
  60.         if not self.model or len(self.model)<1 or not self.asr:
  61.             return None
  62.         for i in range(20):
  63.             if self.asr.Done == self.asr.recognize():
  64.                 result = self.asr.result()
  65.                 if result:
  66.                     return self.model[result[0]]['name']
  67.         return None
  68.     def save(self, model, path):
  69.         if not model or not path:
  70.             return False
  71.         try:
  72.             for i in range(len(model)):
  73.                 model[i]['data'] = list(model[i]['data'])
  74.                 model[i]['data'][1] = list(model[i]['data'][1])
  75.             with open(path, "wb") as f:
  76.                 json.dump(model,f)
  77.                 f.close()
  78.             return True
  79.         except:
  80.             return False
  81.     def load(self, path):
  82.         if not path:
  83.             return []
  84.         try:
  85.             with open(path, "rb") as f:
  86.                 model = json.load(f)
  87.                 for i in range(len(model)):
  88.                     model[i]['data'][1] = bytes(model[i]['data'][1])
  89.                     model[i]['data'] = tuple(model[i]['data'])
  90.                 f.close()
  91.             return model
  92.         except:
  93.             return []
  94. asr = ASR()
复制代码
2、固件要使用“maixpy_v0.6.2_72_g22a8555b5_minimum_speech_with_ide_support ”
QQ截图20211108120616.png
QQ截图20211108214040.png
https://cn.dl.sipeed.com/shareURL/MAIX/MaixPy/release/master/maixpy_v0.6.2_72_g22a8555b5
3、训练代码
  1. # MindPlus
  2. # maixduino
  3. from board import board_info
  4. from ASR import asr
  5. import time
  6. from Maix import GPIO
  7. from fpioa_manager import fm
  8. fm.register(board_info.PIN12,fm.fpioa.GPIO0)
  9. led_r=GPIO(GPIO.GPIO0,GPIO.OUT)
  10. led_r.value(0)
  11. time.sleep(1)
  12. led_r.value(1)
  13. model = asr.newModel()
  14. corpus = ['打开','关闭','退出']
  15. print('开始训练')
  16. for order in corpus:
  17.   asr.training(order, model)
  18. print('训练完成')
  19. asr.save(model, "/flash/asr.json")
  20. asr.run(asr.load("/flash/asr.json"))
  21. while True:
  22.   result = asr.recognize()
  23.   if bool(result):
  24.     print(result)
  25.     if (result == '打开'):
  26.       led_r.value(1)
  27.     if (result == '关闭'):
  28.       led_r.value(0)
  29.     if (result == '退出'):
  30.       break
  31. fm.unregister(board_info.PIN12)
复制代码


LED灯接在扩展板的12引脚上。

4、测试代码
QQ截图20211108122059.png

  1. # MindPlus
  2. # maixduino
  3. from board import board_info
  4. from ASR import asr
  5. import time
  6. from Maix import GPIO
  7. from fpioa_manager import fm
  8. fm.register(board_info.PIN12,fm.fpioa.GPIO0)
  9. led_r=GPIO(GPIO.GPIO0,GPIO.OUT)
  10. led_r.value(1)
  11. time.sleep(1)
  12. led_r.value(0)
  13. asr.run(asr.load("/flash/asr.json"))
  14. while True:
  15.   result = asr.recognize()
  16.   if bool(result):
  17.     print(result)
  18.     if (result == '打开'):
  19.       led_r.value(1)
  20.     if (result == '关闭'):
  21.       led_r.value(0)
  22.     if (result == '退出'):
  23.       break
  24. fm.unregister(board_info.PIN12)
复制代码
测试

【语音控车】1.训练程序
  1. from board import board_info
  2. from ASR import asr
  3. import time
  4. from Maix import GPIO
  5. from fpioa_manager import fm
  6. fm.register(board_info.PIN12,fm.fpioa.GPIO0)
  7. led_r=GPIO(GPIO.GPIO0,GPIO.OUT)
  8. led_r.value(0)
  9. time.sleep(1)
  10. led_r.value(1)
  11. model = asr.newModel()
  12. #corpus = ['打开','关闭','退出','前进','后退','向左','向右','停止']
  13. print('开始训练')
  14. for order in corpus:
  15.   asr.training(order, model)
  16. print('训练完成')
  17. asr.save(model, "/flash/asr.json")
复制代码

2、语音控车代码

  1. # MindPlus
  2. # maixduino
  3. from board import board_info
  4. from ASR import asr
  5. import time
  6. from Maix import GPIO
  7. from fpioa_manager import fm
  8. fm.register(board_info.PIN2,fm.fpioa.GPIO0)
  9. PIN2=GPIO(GPIO.GPIO0,GPIO.OUT)
  10. fm.register(board_info.PIN3,fm.fpioa.GPIO1)
  11. PIN3=GPIO(GPIO.GPIO1,GPIO.OUT)
  12. fm.register(board_info.PIN4,fm.fpioa.GPIO2)
  13. PIN4=GPIO(GPIO.GPIO2,GPIO.OUT)
  14. fm.register(board_info.PIN5,fm.fpioa.GPIO3)
  15. PIN5=GPIO(GPIO.GPIO3,GPIO.OUT)
  16. fm.register(board_info.PIN8,fm.fpioa.GPIO4)
  17. PIN8=GPIO(GPIO.GPIO4,GPIO.OUT)
  18. fm.register(board_info.PIN9,fm.fpioa.GPIO5)
  19. PIN9=GPIO(GPIO.GPIO5,GPIO.OUT)
  20. fm.register(board_info.PIN10,fm.fpioa.GPIO6)
  21. PIN10=GPIO(GPIO.GPIO6,GPIO.OUT)
  22. fm.register(board_info.PIN11,fm.fpioa.GPIO7)
  23. PIN11=GPIO(GPIO.GPIO7,GPIO.OUT)
  24. fm.register(board_info.PIN12,fm.fpioa.GPIOHS0)
  25. led_r=GPIO(GPIO.GPIOHS0,GPIO.OUT)
  26. # 自定义函数
  27. def back():
  28.   Pin.digital_write(PIN2, 1)
  29.   Pin.digital_write(PIN3, 0)
  30.   Pin.digital_write(PIN4, 1)
  31.   Pin.digital_write(PIN5, 0)
  32.   Pin.digital_write(PIN8, 0)
  33.   Pin.digital_write(PIN9, 1)
  34.   Pin.digital_write(PIN10, 0)
  35.   Pin.digital_write(PIN11, 1)
  36. def forward():
  37.   Pin.digital_write(PIN2, 0)
  38.   Pin.digital_write(PIN3, 1)
  39.   Pin.digital_write(PIN4, 0)
  40.   Pin.digital_write(PIN5, 1)
  41.   Pin.digital_write(PIN8, 1)
  42.   Pin.digital_write(PIN9, 0)
  43.   Pin.digital_write(PIN10, 1)
  44.   Pin.digital_write(PIN11, 0)
  45. def stop():
  46.   Pin.digital_write(PIN2, 0)
  47.   Pin.digital_write(PIN3, 0)
  48.   Pin.digital_write(PIN4, 0)
  49.   Pin.digital_write(PIN5, 0)
  50.   Pin.digital_write(PIN8, 0)
  51.   Pin.digital_write(PIN9, 0)
  52.   Pin.digital_write(PIN10, 0)
  53.   Pin.digital_write(PIN11, 0)
  54. def right():
  55.   Pin.digital_write(PIN10, 1)
  56.   Pin.digital_write(PIN11, 0)
  57.   Pin.digital_write(PIN2, 1)
  58.   Pin.digital_write(PIN3, 0)
  59.   Pin.digital_write(PIN8, 0)
  60.   Pin.digital_write(PIN9, 1)
  61.   Pin.digital_write(PIN4, 0)
  62.   Pin.digital_write(PIN5, 1)
  63. def left():
  64.   Pin.digital_write(PIN10, 0)
  65.   Pin.digital_write(PIN11, 1)
  66.   Pin.digital_write(PIN2, 0)
  67.   Pin.digital_write(PIN3, 1)
  68.   Pin.digital_write(PIN8, 1)
  69.   Pin.digital_write(PIN9, 0)
  70.   Pin.digital_write(PIN4, 1)
  71.   Pin.digital_write(PIN5, 0)
  72. led_r.value(1)
  73. time.sleep(1)
  74. led_r.value(0)
  75. asr.run(asr.load("/flash/asr.json"))
  76. while True:
  77.   result = asr.recognize()
  78.   if bool(result):
  79.     print(result)
  80.     if (result == '前进'):
  81.       forword()
  82.       time.sleep(0.2)
  83.       stop()
  84.     if (result == '后退'):
  85.       back()
  86.       time.sleep(0.2)
  87.       stop()
  88.     if (result == '向左'):
  89.       left()
  90.       time.sleep(0.2)
  91.       stop()
  92.     if (result == '向右'):
  93.       right()
  94.       time.sleep(0.2)
  95.       stop()
  96.     if (result == '打开'):
  97.       led_r.value(1)
  98.     if (result == '关闭'):
  99.       led_r.value(0)
  100.     if (result == '退出'):
  101.       break
  102. fm.unregister(board_info.PIN12)
  103. fm.unregister(board_info.PIN2)
  104. fm.unregister(board_info.PIN3)
  105. fm.unregister(board_info.PIN4)
  106. fm.unregister(board_info.PIN5)
  107. fm.unregister(board_info.PIN8)
  108. fm.unregister(board_info.PIN9)
  109. fm.unregister(board_info.PIN10)
  110. fm.unregister(board_info.PIN11)
复制代码
测试

演示




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2022 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail