38_jumpbot.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #!/usr/bin/env python
  2. #version : 2024.03.11
  3. #language : ch
  4. #hardware : PI
  5. import threading
  6. import time
  7. import queue
  8. import math
  9. import os
  10. import pyaudio
  11. import wave
  12. import sys
  13. sys.path.append('/root/')
  14. from CocoPi import QMI8658
  15. from maix import camera,display,image
  16. event=threading.Event()
  17. showLock=threading.Lock()
  18. event.set()
  19. #配置字体
  20. image.load_freetype("/root/preset/fonts/botPixel.ttf")
  21. #导入图片资源对象
  22. jumpbot_logo = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_128_128.png")
  23. jumpbot_right_jump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_right_jump.png")
  24. jumpbot_left_jump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_left_jump.png")
  25. jumpbot_middle_jump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_middle_jump.png")
  26. jumpbot_middle_nojump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_middle_nojump.png")
  27. jumpbot_left_nojump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_left_nojump.png")
  28. jumpbot_right_nojump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_right_nojump.png")
  29. #比例转换函数
  30. def numberMap(value, leftMin, leftMax, rightMin, rightMax):
  31. leftSpan = leftMax - leftMin
  32. rightSpan = rightMax - rightMin
  33. valueScaled = float(value - leftMin) / float(leftSpan)
  34. return int(rightMin + (valueScaled * rightSpan))
  35. #音量调节函数
  36. def voice_numberMap(value):
  37. valueScaled = float(value - 0) / float(100)
  38. return valueScaled * 31
  39. #创建投影用的画布
  40. img_drop=image.new(size=(320,240),mode="RGB")
  41. #屏幕显示函数
  42. def screenShow():
  43. from maix import image,display,camera
  44. import time
  45. global img_drop,lock4,lock5,queue1,queue2,screenCapture,x,y
  46. while True:
  47. event.wait()
  48. if x==1:
  49. #queue1.put(1)
  50. try:
  51. #showLock.acquire()
  52. img_drop.draw_image((screenCapture.rotate(-90,adjust=1)),0,0)
  53. #print("rotate time:"+str(time.time()))
  54. display.show(img_drop)
  55. finally:
  56. #showLock.release()
  57. pass
  58. x=0
  59. y=0
  60. else:
  61. pass
  62. #time.sleep(0.01)
  63. #播放音乐
  64. def playMusic():
  65. global lock3,jumpSound
  66. import wave
  67. import pyaudio
  68. import time
  69. p = pyaudio.PyAudio()
  70. while True:
  71. event.wait()
  72. if lock3==1:
  73. #导入音乐资源对象
  74. CHUNK = 1024
  75. jumpSound = wave.open(r"/root/preset/audio/jump1.wav", 'rb')
  76. stream = p.open(format=p.get_format_from_width(jumpSound.getsampwidth()),channels=jumpSound.getnchannels(),rate=jumpSound.getframerate(),output=True)
  77. data = jumpSound.readframes(CHUNK)
  78. while len(data) > 0:
  79. stream.write(data)
  80. data = jumpSound.readframes(CHUNK)
  81. stream.stop_stream()
  82. stream.close()
  83. #p.terminate()
  84. lock3=0
  85. else:
  86. time.sleep(0.01)
  87. #获取MPU数值
  88. def getMpuData():
  89. sys.path.append('/root/')
  90. from CocoPi import QMI8658
  91. import time
  92. global initData,lock1,lock2
  93. while True:
  94. if lock1==1:
  95. if event.is_set():
  96. event.clear()
  97. else:
  98. pass
  99. xyz=qmi8658.getPitchYawRollGxGyGz(initData)
  100. #print("xyz:"+str(xyz))
  101. pitch=round(xyz[0],2)
  102. yaw=round(xyz[1],2)
  103. #print("yaw:"+str(yaw))
  104. queue1.put(yaw)
  105. queue2.put(pitch)
  106. lock1=0
  107. lock2=1
  108. event.set()
  109. else:
  110. time.sleep(0.04)
  111. #-------------------------------
  112. #初始化色彩配置
  113. splash_theme_color = (255,255,255)
  114. splash_front_color = (60,60,60)
  115. fontcolor=255
  116. fontsize=0.75
  117. fontchange=0
  118. #开机显示
  119. splash = image.new(size=(240, 320),mode = "RGB")
  120. splash.draw_rectangle(0,0,240,320,color=splash_theme_color,thickness=-1)
  121. splash.draw_string(40, 28, "Jump", 1.6, color=(255, 200, 0))
  122. splash.draw_string(140, 28, "Cat", 1.6, color=(255, 128, 64))
  123. splash.draw_image(jumpbot_logo.rotate(0, adjust=1),54,100,alpha=1)
  124. splash.draw_string(40, 240, "NOTE:", 0.75, color=(0, 128, 255))
  125. splash.draw_string(96, 240, "PLEASE", 0.75, color=(0, 128, 255))
  126. splash.draw_string(160, 240, "PLACE", 0.75, color=(0, 128, 255))
  127. splash.draw_string(40, 260, "HORIZONTALLY", 0.75, color=(0, 128, 255))
  128. splash.draw_string(172, 260, "AND", 0.75, color=(0, 128, 255))
  129. splash.draw_string(40, 280, "REMAIN", 0.75, color=(0, 128, 255))
  130. splash.draw_string(110, 280, "STILL!", 0.75, color=(0, 128, 255))
  131. screenCapture=splash.crop(0,0,240,320)
  132. img_drop.draw_image((screenCapture.rotate(-90,adjust=1)),0,0)
  133. display.show(img_drop)
  134. time.sleep(1)
  135. #配置QMI8658
  136. qmi8658=QMI8658()
  137. qmi8658.calibrate()
  138. initData={}
  139. initData["AcX"]=qmi8658.get_accel(10)["AcX"]
  140. initData["AcY"]=qmi8658.get_accel(10)["AcY"]
  141. initData["AcZ"]=qmi8658.get_accel(10)["AcZ"]
  142. initData["GyX"]=qmi8658.get_accel(10)["GyX"]
  143. initData["GyY"]=qmi8658.get_accel(10)["GyY"]
  144. initData["GyZ"]=qmi8658.get_accel(10)["GyZ"]
  145. #配置图形角色相关参数
  146. x_speed=0
  147. y_speed=0
  148. x_pos=120
  149. y_pos=160
  150. x_change=0
  151. y_change=5
  152. fowardState=0
  153. jumpState=0
  154. Yaw=0
  155. #配置音频
  156. os.system("amixer cset numid=8,iface=MIXER,name='LINEOUT volume'voice_numberMap(25)")
  157. #创建队列
  158. queue1=queue.Queue() #用来传递开启位置计算与陀螺仪数据获取的信号YAW
  159. queue1.put(1) #用来作为第一次开启位置计算与陀螺仪数据获取的信号
  160. queue2=queue.Queue() #用于存放图像数据
  161. #创建信号锁
  162. lock1=1
  163. lock2=0
  164. lock3=0
  165. lock4=1
  166. lock5=0
  167. thread2=threading.Thread(target=getMpuData)
  168. thread2.start()
  169. thread3=threading.Thread(target=screenShow)
  170. thread3.start()
  171. #thread4=threading.Thread(target=playMusic)
  172. #thread4.start()
  173. x=0
  174. y=0
  175. while True:
  176. event.wait()
  177. if y==0:
  178. splash.clear()
  179. splash.draw_rectangle(0,0,240,320,color=splash_theme_color,thickness=-1)
  180. #splash.draw_string(80, 8, "pitch:"+str(round(xyz[0],2)), fontsize, color=(0, 0, 0))
  181. #splash.draw_string(80, 28, "yaw:"+str(round(xyz[1],2)), fontsize, color=(0, 0, 0))
  182. #splash.draw_string(80, 48, "fontcolor:"+str(fontcolor), fontsize, color=(0, 0, 0))
  183. #splash.draw_image(jumpbot_left_jump.rotate(0, adjust=1),109,149,alpha=1)
  184. #splash.draw_image(jumpbot_right_jump.rotate(0, adjust=0),109,149-int(xyz[0]),alpha=1)
  185. #splash.draw_image(jumpbot_right_jump.rotate(0, adjust=0),109-int(xyz[1]),149,alpha=1)
  186. #提示字显示
  187. splash.draw_rectangle(0,280,240,320,color=splash_front_color,thickness=-1)
  188. splash.draw_string(48, 286, "JUMP!", fontsize, color=(fontcolor,fontcolor,fontcolor))
  189. splash.draw_string(104, 286, "JUMP!", fontsize, color=(fontcolor,fontcolor,fontcolor))
  190. splash.draw_string(160, 286, "JUMP!", fontsize, color=(fontcolor,fontcolor,fontcolor))
  191. #splash.draw_string(48, 286, "PRESS", fontsize, color=(fontcolor,fontcolor,fontcolor))
  192. #splash.draw_string(104, 286, "B", fontsize, color=(fontcolor,fontcolor,fontcolor))
  193. #splash.draw_string(120, 286, "TO", fontsize, color=(fontcolor,fontcolor,fontcolor))
  194. #splash.draw_string(148, 286, "START", fontsize, color=(fontcolor,fontcolor,fontcolor))
  195. if fontcolor==splash_front_color[0]:
  196. fontchange=15
  197. elif fontcolor==255:
  198. fontchange=-15
  199. fontcolor=fontcolor+fontchange
  200. #获取Yaw值
  201. if lock2==1:
  202. Yaw=queue1.get()
  203. Pitch=queue2.get()
  204. lock2=0
  205. lock1=1
  206. else:
  207. pass
  208. if -90<=Yaw and Yaw<=0:
  209. fowardState=1
  210. x_speed=int(math.sqrt(math.fabs(Yaw)))
  211. #x_speed=numberMap(0-yaw,0,90,0,18)
  212. elif 0<Yaw and Yaw<=90:
  213. fowardState=0
  214. x_speed=-int(math.sqrt(math.fabs(Yaw)))
  215. #x_speed=numberMap(0-yaw,-90,0,-18,0)
  216. else:
  217. pass
  218. x_pos=x_pos+x_speed
  219. if x_pos<0:
  220. x_pos=240
  221. elif x_pos>240:
  222. x_pos=0
  223. else:
  224. pass
  225. if fowardState==0:
  226. sprite=jumpbot_left_nojump
  227. elif fowardState==1:
  228. sprite=jumpbot_right_nojump
  229. else:
  230. pass
  231. if y_pos+y_speed>259:
  232. y_pos=259
  233. y_speed=-35
  234. lock3=1
  235. else:
  236. y_pos=y_pos+y_speed
  237. y_speed=y_speed+y_change
  238. print("yaw:"+str(Yaw))
  239. splash.draw_image(sprite,x_pos-11,y_pos,alpha=1)
  240. splash.draw_string(136, 8, "SPEED:"+str(y_speed), fontsize, color=(0, 0, 0))
  241. splash.draw_string(144, 28, "YAW:"+str(Yaw), fontsize, color=(0, 128, 255))
  242. splash.draw_string(124, 48, "PITCH:"+str(Pitch), fontsize, color=(255, 128, 64))
  243. screenCapture=splash.crop(0,0,240,320)
  244. #queue2.put(1)
  245. x=1
  246. y=1