• 星瞳AI VISION软件内测!可以离线标注,训练,并生成OpenMV的模型。可以替代edge impulse https://forum.singtown.com/topic/8206
  • 我们只解决官方正版的OpenMV的问题(STM32),其他的分支有很多兼容问题,我们无法解决。
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 报错为not find类,但不理解怎么解决



    • Traceback (most recent call last):
      File "", line 64, in
      Exception: IDE interrupt
      could not find module '_boot.py'
      MicroPython: v1.17-omv-r12-dirty OpenMV: v4.2.1-dirty HAL: v1.9.0 BOARD: OPENMV4P-STM32H743

      如上所示,运行一个项目的例程包,但是会报错,不知道该怎么解决。



    • 提供具体的代码,否则我没办法测试。

      如果涉及代码,需要报错提示与全部代码文本,请注意不要贴代码图片



    • 代码如下,有劳大佬指导

      ############################################################
      #                                                          #
      #                此文件实现对黑色动态物体的跟踪                 #
      #                                                          #
      ############################################################
      
      import sensor, image, time, pyb, struct, math,lcd
      import pid, data_pack, t2017_task1, t2017_task2, t2017_task3, t2017_task_plus
      ######################初始化程序##############################
      
      sensor.reset()                                                   #对openmv进行复位
      sensor.set_pixformat(sensor.GRAYSCALE)                           #以RGG565的格式读取像素信息
      sensor.set_framesize(sensor.QQVGA)                               #分辨率为QQVGA:160*120
      sensor.skip_frames(10)                                           #前10帧数据舍去,避免刚刚启动,数据不稳定造成误判
      sensor.set_auto_whitebal(False)                                  #关闭自动白平衡
      clock = time.clock()
      uart = pyb.UART(3, 500000, timeout_char = 1000)                  #打开串口3
      red_threshold_01 = (0,55)                                       #目标色块的灰度值参数范围
      flag_x_y = 0                                                     #这是一个标志位,循环调整无人机的x方向和y方向
      num_stop = 0                                                     #罚站次数,罚站即不对无人机进行位置调整
      time_flag = 0
      pid_x = pid.PID(80,0.5,30)                                   #x轴方向的pid控制,pid参数要自己调
      pid_y = pid.PID(60,0.5,30)                                   #y轴方向的pid控制
      task_number = 0                                                  #任务切换
      MV_ctrl_flag = 0                                                 #防止openmv在飞控没有准备好时进行控制
      #Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)     蜂鸣器引脚,视实际而不同
      ##################各个字母所对应的ASCII值######################
      R = ord('R')
      L = ord('L')
      S = ord('S')
      B = ord('B')
      G = ord('G')
      E = ord('E')
      H = ord('H')
      task1 = ord('a')
      task2 = ord('b')
      task3 = ord('c')
      task4 = ord('d')
      task5 = ord('e')
      
      ###########################################################
      
      
      #def send_direction_packet(direct,velcity):                       #与无人机mcu的通信协议,数据打包并发送
         # s = 0xAA+0x8C+direct+(int(velcity/256))+(int(velcity%256))   #s是校验字节,是数据包里s之前所有数据的和
        #  s = int(s % 256)                                             #因为协议里s是8位的,这里取低八位
       #   temp_flow = struct.pack("<BBBBhB",                           #数据包的封装格式,B:unsigned char; h:short
            #             0xAA,
           #              0x89,
          #               03,
         #                direct,
        #                 int(velcity),
       #                  s)
      #    uart.write(temp_flow)                                        视频所示包不重要,可去除(有单独专门的一个包)
      
      
      while(True):
          times = clock.avg()
          clock.reset()                                                 #用来测量一个循环所用的时间,单位ms,不用的话这里也可以删掉
          clock.tick()
          print("time: %d" %times)
          #task_number = 4    ######
          while(task_number == 0):                                      #获取任务ID
              task_char = uart.readchar()
      #        Buzzer.value(0)
              if task_char == task1:
                  task_number = 1
              elif task_char == task2:
                  task_number = 2
              elif task_char == task3:
                  task_number = 3
              elif task_char == task4:
                  task_number = 4
              elif task_char == task5:
                  task_number = 5
              else :
                  task_number =0
          print("task_number : %d" %task_number)
          if task_number != 2:     #2
              while(MV_ctrl_flag == 0):                                    #判断openMV是否获得控制权
                  MV_ctrl_char = uart.readchar()
                  if MV_ctrl_char == H:
                      MV_ctrl_flag = 1
          print("start work")
          if task_number == 1:
              t2017_task1.task_2017_1_1()
          elif task_number == 2:
              t2017_task2.task_2017_1_2()
          elif task_number == 3:
              t2017_task3.task_2017_1_3()
          elif (task_number == 4) or (task_number == 5):
              print("task number : %d" %task_number)
              t2017_task_plus.task_2017_2()
      
      
      ##############################################################################################
      
      
      #############################################################
      ##                                                          #
      ##                此文件实现对黑色动态物体的跟踪                 #
      ##                                                          #
      #############################################################
      
      #import sensor, image, time, pyb, struct, math
      #import pid, data_pack
      #from machine import Pin
      #######################初始化程序#############################
      
      #sensor.reset()                                                   #对openmv进行复位
      #sensor.set_pixformat(sensor.GRAYSCALE)                           #以RGG565的格式读取像素信息
      #sensor.set_framesize(sensor.QQVGA)                               #分辨率为QQVGA:160*120
      #sensor.skip_frames(10)                                           #前10帧数据舍去,避免刚刚启动,数据不稳定造成误判
      #sensor.set_auto_whitebal(False)                                  #关闭自动白平衡
      #clock = time.clock()
      #uart = pyb.UART(3, 500000, timeout_char = 1000)                  #打开串口3
      #red_threshold_01 = (0,55)                                       #目标色块的灰度值参数范围
      #flag_x_y = 0                                                     #这是一个标志位,循环调整无人机的x方向和y方向
      #num_stop = 0                                                     #罚站次数,罚站即不对无人机进行位置调整
      #start_MV_flag = 0
      #time_flag = 0
      #prepare_flag = 0
      #pid_x = pid.PID(80,0.3,0,0,30)                                   #x轴方向的pid控制,pid参数要自己调
      #pid_y = pid.PID(60,0.3,0,0,30)                                   #y轴方向的pid控制
      #Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      #none_blob_flag = 0
      ###################各个字母所对应的ASCII值######################
      #R = ord('R')
      #L = ord('L')
      #S = ord('S')
      #B = ord('B')
      #G = ord('G')
      #E = ord('E')
      #H = ord('H')
      
      #task1 = ord('a')
      #task2 = ord('b')
      #task3 = ord('c')
      #task4 = ord('d')
      #task5 = ord('e')
      ############################################################
      
      
      #def send_direction_packet(direct,velcity):                       #与无人机mcu的通信协议,数据打包并发送
          #s = 0xAA+0x8C+direct+(int(velcity/256))+(int(velcity%256))   #s是校验字节,是数据包里s之前所有数据的和
          #s = int(s % 256)                                             #因为协议里s是8位的,这里取低八位
          #temp_flow = struct.pack("<BBBBhB",                           #数据包的封装格式,B:unsigned char; h:short
                         #0xAA,
                         #0x89,
                         #03,
                         #direct,
                         #int(velcity),
                         #s)
          #uart.write(temp_flow)
      
      #def compareBlob(blob1, blob2):                                    #比较两个色块大小的函数
          #tmp = blob1.pixels() - blob2.pixels()
          #if tmp == 0:
              #return 0
          #elif tmp > 0:
              #return 1
          #else:
              #return -1
      
      #while(True):
          #times = clock.avg()
          #clock.reset()                                                  #用来测量一个循环所用的时间,单位ms,不用的话这里也可以删掉
          #clock.tick()
          #print("time: %d" %times)
          #img = sensor.snapshot().lens_corr(1.8)
          #blobs = img.find_blobs([red_threshold_01],
                  #pixels_threshold=100, merge=True)                     #寻找目标色块,低于150像素的视为噪声
          #img.binary([red_threshold_01], invert = True)                 #二值化处理
         ## Buzzer.value(1)
      
          #while(start_MV_flag == 0):
              #value_from_flyctr = uart.readchar()
              #print("value_from_flyctr : %d" %value_from_flyctr)
              #if  value_from_flyctr == H :
                  #start_MV_flag = 1                                     #悬停计时开始标志位
          #if len(blobs) == 2:                                           #如果识别到目标色块
              #print("the number of blobs is %d" %len(blobs))
              #if(abs(blobs[0].cx()-80)<5) and \
                  #(abs(blobs[0].cy()-60)<5):
                  #time_flag = 1
              #if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                  #speed_x = pid_x.IncPIDCalc(blobs[0].cx())
                 ## print("speed_x: %f" %speed_x)
                  #if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                      #send_direction_packet(L,speed_x)
                  #else:
                      #send_direction_packet(R,abs(speed_x))
                  #flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
              #else :
                  #speed_y = pid_y.IncPIDCalc(blobs[0].cy())
                  ##print("speed_y: %f" %speed_y)
                  #if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                      #send_direction_packet(G,speed_y)
                  #else:
                      #send_direction_packet(B,abs(speed_y))
                  #flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
          #elif len(blobs) == 0:
              #print("the number of blobs is %d" %len(blobs))
              #if  prepare_flag == 0:
                  #send_direction_packet(E,0)                                #没有检测到目标色块,这里让无人机原地罚站
              #else:
                  #send_direction_packet(G,5)
                  #prepare_flag = 2
      
          #else :
              #print("the number of blobs is %d" %len(blobs))
              #bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
              #for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                  #if compareBlob(bigBlob, blob_temp) == -1:
                      #bigBlob = blob_temp
              #if(abs(blobs[0].cx()-80)<5) and \
                  #(abs(blobs[0].cy()-60)<5) and \
                  #prepare_flag == 0:
                  #prepare_flag = 1
              #if(abs(blobs[0].cx()-80)<5) and \
                  #(abs(blobs[0].cy()-60)<5) and \
                  #prepare_flag == 2:
                  #time_flag = 1
              #if prepare_flag == 0 or prepare_flag == 2:
                  #if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                      #speed_x = pid_x.IncPIDCalc(bigBlob.cx())
                     ## print("speed_x: %f" %speed_x)
                      #if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                          #send_direction_packet(L,speed_x)
                      #else:
                          #send_direction_packet(R,abs(speed_x))
                      #flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                  #else :
                      #speed_y = pid_y.IncPIDCalc(bigBlob.cy())
                      ##print("speed_y: %f" %speed_y)
                      #if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                          #send_direction_packet(G,speed_y)
                      #else:
                          #send_direction_packet(B,abs(speed_y))
                      #flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
              #else:                                                         #准备就绪,进入8区
                  #send_direction_packet(G,5)
          #if time_flag == 1:
              #num_stop += 1
              #if num_stop >= 120 :                                  #100次差不多5秒钟,降落
                  #send_direction_packet(L,15)
                  #time.sleep(2000)
                  #num_stop = 0
                  #send_direction_packet(E,0)
      
      
      


    • @kidswong999 顺便问一下,PID 一般起到的是发送控制指令的作用吗?如果和飞控连接,我的老师说的是openmv部分的代码并不需要pid,所以我比较疑惑与飞控进行连接的时候,是基于什么而实现控制指令?



    • 你的代码并不是全部的代码,应该还有 pid.py data_pack.py t2017_task1.py t2017_task2.py t2017_task3.py t2017_task_plus.py

      要全部上传上来,否则我没办法测试。



    • @ugli报错为not find类,但不理解怎么解决 中说:

      @kidswong999 顺便问一下,PID 一般起到的是发送控制指令的作用吗?如果和飞控连接,我的老师说的是openmv部分的代码并不需要pid,所以我比较疑惑与飞控进行连接的时候,是基于什么而实现控制指令?

      单独的问题单独发帖子。



    • @kidswong999 import sensor, image, time, pyb, struct, math
      import pid, data_pack

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_1_1():
      red_threshold_01 = (0,55) #目标色块的灰度值参数范围
      time_flag = 0
      num_stop = 0
      pid_x = pid.PID(80,0.5,0,0,30) #x轴方向的pid控制,pid参数要自己调
      pid_y = pid.PID(60,0.5,0,0,30) #y轴方向的pid控制
      flag_x_y = 0
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      ##################各个字母所对应的ASCII值######################
      R = ord('R')
      L = ord('L')
      S = ord('S')
      B = ord('B')
      G = ord('G')
      E = ord('E')
      ###########################################################
      Buzzer.value(1)
      time.sleep(1000)
      Buzzer.value(0)
      while(True):
      print("the task number is 1 now!")
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([red_threshold_01],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([red_threshold_01], invert = True) #二值化处理
      if blobs: #如果识别到目标色块
      #print(blobs) #在终端打印出blobs的信息
      bigBlob = blobs[0] #将第一个色块赋值给最大色块
      for blob_temp in blobs: #此循环找出最大色块,进一步滤除噪声
      if compareBlob(bigBlob, blob_temp) == -1:
      bigBlob = blob_temp
      img.draw_rectangle(bigBlob[0:4]) #画个矩形框标出色块所在区域
      img.draw_cross(bigBlob[5], bigBlob[6]) #画个十字架标出色块所在区域的中心点
      if (abs(bigBlob.cx() - 80) < 5) and
      (abs(bigBlob.cy() - 60) < 5):
      time_flag = 1
      if flag_x_y == 0 : #调节x与y方向的切换标志
      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
      # print("speed_x: %f" %speed_x)
      if speed_x > 0: #说明目标当前x值偏小,无人机偏右,需要向左调整
      data_pack.send_cmd(L,speed_x)
      else:
      data_pack.send_cmd(R,abs(speed_x))
      print("RIGHT")
      flag_x_y = 1 #标志位置1,表示下次循环调整y轴方向
      else :
      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
      #print("speed_y: %f" %speed_y)
      if speed_y >= 0: #说明目标当前y值偏小,无人机偏后,需要向前调整
      data_pack.send_cmd(G,speed_y)
      else:
      data_pack.send_cmd(B,abs(speed_y))
      flag_x_y = 0 #标志位置0,表示下次循环调整x轴方向
      if time_flag == 1:
      num_stop += 1
      if num_stop >= 200 : #200次差不多15秒钟,降落
      num_stop = 0
      data_pack.send_cmd(E,0)
      else:
      data_pack.send_cmd(S,0) #没有检测到目标色块,这里让无人机原地罚站



    • @kidswong999 import sensor, image, time, pyb, struct, math

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_1_2():
      red_threshold_01 = (0,55) #目标色块的灰度值参数范围
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      time.sleep(500)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      while(True):
      print("the task number is 2 now!")
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([red_threshold_01],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([red_threshold_01], invert = True) #二值化处理
      if blobs: #如果识别到目标色块
      #print(blobs) #在终端打印出blobs的信息
      bigBlob = blobs[0] #将第一个色块赋值给最大色块
      for blob_temp in blobs: #此循环找出最大色块,进一步滤除噪声
      if compareBlob(bigBlob, blob_temp) == -1:
      bigBlob = blob_temp
      img.draw_rectangle(bigBlob[0:4]) #画个矩形框标出色块所在区域
      img.draw_cross(bigBlob[5], bigBlob[6]) #画个十字架标出色块所在区域的中心点
      print("Bigbolb.pixel: %d" %bigBlob.pixels())
      if (bigBlob.pixels() < 1500) and
      (bigBlob.pixels() > 300):
      pyb.LED(2).on()
      Buzzer.value(1)
      else:
      pyb.LED(2).off()
      Buzzer.value(0)



    • @kidswong999 import sensor, image, time, pyb, struct, math
      import pid, data_pack

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_1_3():
      red_threshold_03 = (0,55) #目标色块的灰度值参数范围
      time_flag = 0
      num_stop = 0
      pid_x = pid.PID(80,0.3,0,0,30) #x轴方向的pid控制,pid参数要自己调
      pid_y = pid.PID(60,0.3,0,0,30) #y轴方向的pid控制
      flag_x_y = 0
      prepare_flag = 0
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      ##################各个字母所对应的ASCII值######################
      R = ord('R')
      L = ord('L')
      S = ord('S')
      B = ord('B')
      G = ord('G')
      E = ord('E')
      ###########################################################
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      time.sleep(500)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      time.sleep(500)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      while(True):
      print("the task number is 3 now!")
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([red_threshold_03],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([red_threshold_03], invert = True) #二值化处理
      if len(blobs) == 2: #如果识别到目标色块
      print("the number of blobs is %d" %len(blobs))
      if(abs(blobs[0].cx()-80)<5) and
      (abs(blobs[0].cy()-60)<5):
      time_flag = 1
      if flag_x_y == 0 : #调节x与y方向的切换标志
      speed_x = pid_x.IncPIDCalc(blobs[0].cx())
      # print("speed_x: %f" %speed_x)
      if speed_x > 0: #说明目标当前x值偏小,无人机偏右,需要向左调整
      data_pack.send_cmd(L,speed_x)
      else:
      data_pack.send_cmd(R,abs(speed_x))
      flag_x_y = 1 #标志位置1,表示下次循环调整y轴方向
      else :
      speed_y = pid_y.IncPIDCalc(blobs[0].cy())
      #print("speed_y: %f" %speed_y)
      if speed_y >= 0: #说明目标当前y值偏小,无人机偏后,需要向前调整
      data_pack.send_cmd(G,speed_y)
      else:
      data_pack.send_cmd(B,abs(speed_y))
      flag_x_y = 0 #标志位置0,表示下次循环调整x轴方向
      elif len(blobs) == 0:
      print("the number of blobs is %d" %len(blobs))
      if prepare_flag == 0 or prepare_flag == 2:
      data_pack.send_cmd(E,0) #没有检测到目标色块,这里让无人机原地罚站
      else:
      data_pack.send_cmd(G,5)

          else :
              print("the number of blobs is %d" %len(blobs))
              bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
              for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                  if compareBlob(bigBlob, blob_temp) == -1:
                      bigBlob = blob_temp
      
              if prepare_flag == 1 and bigBlob.cy() > 80:
                  data_pack.send_cmd(G,5)
              elif prepare_flag == 1 and bigBlob.cy() < 40:
                  prepare_flag = 2
      
              if(abs(bigBlob.cx()-80)<5) and \
                  (abs(bigBlob.cy()-60)<5) and \
                  prepare_flag == 0:
                  prepare_flag = 1
              if(abs(bigBlob.cx()-80)<5) and \
                  (abs(bigBlob.cy()-60)<5) and \
                  prepare_flag == 2:
                  time_flag = 1
              if prepare_flag == 0 or prepare_flag == 2:
                  if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
                     # print("speed_x: %f" %speed_x)
                      if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                          data_pack.send_cmd(L,speed_x)
                      else:
                          data_pack.send_cmd(R,abs(speed_x))
                      flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                  else :
                      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
                      #print("speed_y: %f" %speed_y)
                      if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                          data_pack.send_cmd(G,speed_y)
                      else:
                          data_pack.send_cmd(B,abs(speed_y))
                      flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
              else:                                                         #准备就绪,进入8区
                  data_pack.send_cmd(G,15)
          if time_flag == 1:
              num_stop += 1
              if num_stop >= 120 :                                  #100次差不多5秒钟,降落
                  data_pack.send_cmd(L,15)
                  time.sleep(100)
                  data_pack.send_cmd(L,15)
                  time.sleep(100)
                  data_pack.send_cmd(L,15)
                  time.sleep(100)
                  num_stop = 0
                  data_pack.send_cmd(E,0)


    • @kidswong999 import sensor, image, time, pyb, struct, math
      import pid, data_pack

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_2():
      threshold_01 = (0,55) #目标色块的灰度值参数范围
      number_period = 0
      pid_x = pid.PID(80,0.5,0,0,30) #x轴方向的pid控制,pid参数要自己调
      pid_y = pid.PID(60,0.5,0,0,30) #y轴方向的pid控制
      flag_x_y = 0
      flag_buzzer = 0
      stop_flag_car = 0
      clock = time.clock()
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      uart1 = pyb.UART(1, 115200, timeout_char = 100) #打开串口1
      ##################各个字母所对应的ASCII值######################
      R = ord('R')
      L = ord('L')
      S = ord('S')
      B = ord('B')
      G = ord('G')
      E = ord('E')
      ###########################################################
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      time.sleep(400)
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      time.sleep(400)
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      time.sleep(400)
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      while(True):
      #print("the task number is 1 now!")
      clock.tick()
      number_period += 1
      if number_period >= 60 :
      number_period = 0
      if stop_flag_car != S:
      stop_flag_car = uart1.readchar()
      if stop_flag_car == S:
      if flag_buzzer == 0:
      data_pack.send_cmd(E,0)
      Buzzer.value(1)
      time.sleep(1000)
      Buzzer.value(0)
      flag_buzzer = 1
      #time.sleep(1000)
      # print("landing start!")
      #print("stop_flag_car : %s" %stop_flag_car)
      # data_pack.send_cmd(S,0)
      #print("stop_flag_car : %s" %stop_flag_car)
      #continue
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([threshold_01],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([threshold_01], invert = True) #二值化处理
      if blobs: #如果识别到目标色块
      #print(blobs) #在终端打印出blobs的信息
      bigBlob = blobs[0] #将第一个色块赋值给最大色块
      for blob_temp in blobs: #此循环找出最大色块,进一步滤除噪声
      if compareBlob(bigBlob, blob_temp) == -1:
      bigBlob = blob_temp
      img.draw_rectangle(bigBlob[0:4]) #画个矩形框标出色块所在区域
      img.draw_cross(bigBlob[5], bigBlob[6]) #画个十字架标出色块所在区域的中心点
      if flag_x_y == 0 : #调节x与y方向的切换标志
      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
      # print("speed_x: %f" %speed_x)
      if speed_x > 0: #说明目标当前x值偏小,无人机偏右,需要向左调整
      data_pack.send_cmd(L,speed_x)
      else:
      data_pack.send_cmd(R,abs(speed_x))
      flag_x_y = 1 #标志位置1,表示下次循环调整y轴方向
      else :
      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
      #print("speed_y: %f" %speed_y)
      if speed_y >= 0: #说明目标当前y值偏小,无人机偏后,需要向前调整
      data_pack.send_cmd(G,speed_y)
      else:
      data_pack.send_cmd(B,abs(speed_y))
      flag_x_y = 0 #标志位置0,表示下次循环调整x轴方向
      else:
      data_pack.send_cmd(S,0) #没有检测到目标色块,这里让无人机原地罚站



    • @kidswong999
      import sensor, image, time, math, struct ,pyb,utime
      class PID:
      def init(self, SetPoint,Proportion,Integral,Derivative,Limit):
      # WARNING: Don't use PA4-X5 or PA5-X6 as echo pin without a 1k resistor
      self.SetPoint = SetPoint #设定值
      self.Proportion = Proportion #P
      self.Integral = Integral #I
      self.Derivative = Derivative #D
      self.Limit = Limit #限幅
      self.LastError = 0 #前1次误差值
      self.PrevError = 0 #前2次误差值
      self.iError = 0 #当前误差
      self.iIncpid = 0 #增量误差
      self.Uk = 0 #输出返回\

      def IncPIDCalc(self, NextPoint):
            # 当前误差
            self.iError = self.SetPoint - NextPoint
            # 增量误差
            self.iIncpid = (self.Proportion * (self.iError - self.LastError)+ self.Integral *
                           self.iError + self.Derivative * (self.iError - 2 * self.LastError +
                           self.PrevError))
            #存储误差,用于下次计算
            self.PrevError = self.LastError
            self.LastError = self.iError
      
            self.Uk += self.iIncpid
            self.Uk = self.Limit_Amplitude(self.Uk)
           # print("NextPoint : %f" % NextPoint)
           # print("Uk : %f" % self.Uk)
            return self.Uk
      
      def Limit_Amplitude(self,num):
          if num > self.Limit :
              return self.Limit
          elif num < -self.Limit:
              return -self.Limit
          else:
              return num


    • @kidswong999 import time, pyb, struct

      C = ord('C')
      F = ord('F')
      G = ord('G')
      B = ord('B')
      R = ord('R')
      L = ord('L')
      D = ord('D')
      U = ord('U')
      E = ord('E')
      S = ord('S')
      H = ord('H')
      uart3 = pyb.UART(3, 500000, timeout_char = 1000)
      green_led = pyb.LED(2)

      def send_89(direct,velcity):
      '''
      功能字为0x89,控制前进(后退)、左(右)、上升(下降)速度大小
      speed字段必须正
      '''
      s = 0xAA+0x8C+direct+(int(velcity/256))+(int(velcity%256))
      s = int(s % 256)
      temp_flow = struct.pack("<BBBBBhB",
      0x00,
      0xAA,
      0x89,
      03,
      direct,
      int(velcity),
      s)
      uart3.write(temp_flow)

      def send_98(direct,velcity):
      '''
      功能字为0x98,控制顺(逆)时针转动速度大小
      speed字段正负一样
      '''
      s = 0xAA+0x9B+direct+(int(velcity/256))+(int(velcity%256))
      s = int(s % 256)
      temp_flow = struct.pack("<BBBBBhB",
      0x00,
      0xAA,
      0x98,
      03,
      direct,
      velcity,
      s)
      uart3.write(temp_flow)

      def send_cmd(direct,velcity):
      if direct == C or direct == F:
      send_98(direct,velcity)
      time.sleep(3)
      else:
      send_89(direct,velcity)
      if direct == S:
      time.sleep(3)



    • @kidswong999报错为not find类,但不理解怎么解决 中说:

      大佬十分抱歉,之前这段时间在忙其他事情,没能继续更进这个问题,按回复时间依次为 t2017_task1.py t2017_task2.py t2017_task3.py t2017_task_plus.py pid.py data_pack.py,求大佬不吝赐教!
      后面这是同一个教学案例包内的程序:line_calcu.py car_patro.py key_point.py
      第一个:
      import sensor, image, time

      def get_line_k(x1,x2,y1,y2):
      det_x = x2 - x1
      det_y = y2 - y1
      if det_x == 0: #考虑斜率无穷大的情况
      det_x = 1
      return (det_y/det_x)

      def get_line_b(x1,x2,y1,y2):
      k = get_line_k(x1,x2,y1,y2)
      return (y1-(k*x1))

      def get_line_cross_x(k1,k2,b1,b2):
      det_k = k1 - k2
      if det_k == 0:
      return -1
      else:
      return (b2 - b1)/(k1 - k2)

      def get_line_cross_y(k1,k2,b1,b2):
      det_k = k1 - k2
      if det_k == 0:
      return -1
      else:
      return (b1k2 - k1b2)/(k2 - k1)

      def get_cross_dot(lines):
      cross_dot = [0,0]
      x1 = lines[0].x1()
      x2 = lines[0].x2()
      x3 = lines[1].x1()
      x4 = lines[1].x2()
      y1 = lines[0].y1()
      y2 = lines[0].y2()
      y3 = lines[1].y1()
      y4 = lines[1].y2()
      k1 = get_line_k(x1,x2,y1,y2)
      k2 = get_line_k(x3,x4,y3,y4)
      b1 = get_line_b(x1,x2,y1,y2)
      b2 = get_line_b(x3,x4,y3,y4)
      cross_dot[0] = get_line_cross_x(k1,k2,b1,b2)
      cross_dot[1] = get_line_cross_y(k1,k2,b1,b2)
      return cross_dot
      第二个:
      import pyb,struct
      uart = pyb.UART(3,115200, timeout_char = 1000)
      def car_run(x1,x2):
      if x1 > 0 :
      right_value = x1
      else :
      right_value = x1
      if x2 > 0 :
      left_value = x2
      else :
      left_value = x2
      send_rpm(right_value,left_value)
      def send_rpm(right_value,left_value):
      left_rpm = int(left_value * 27)
      right_rpm = int(right_value * 27)
      left_rpm_low = left_rpm & 0x00ff
      left_rpm_high = left_rpm >> 8
      right_rpm_low = right_rpm & 0x00ff
      right_rpm_high = right_rpm >> 8
      xor = 0x6^0x3^0x4^(left_rpm_low)^(left_rpm_high)^(right_rpm_low)^(right_rpm_high)
      xor = (int(xor%256))
      temp_flow = struct.pack("<BBBBBhhB",
      0xaa,
      0x55,
      0x6,
      0x3,
      0x4,
      left_rpm,
      right_rpm,
      xor)
      ret = uart.write(temp_flow)
      print(left_rpm/27, right_rpm/27)
      第三个:
      import sensor, image, time



    • 你的代码格式不对,缩进完全不对,没办法运行。我建议这个代码是谁写的就找谁问问。



    • @kidswong999

      import sensor, image, time, pyb, struct, math
      import pid, data_pack
      
      
      
      def compareBlob(blob1, blob2):                                    #比较两个色块大小的函数
          tmp = blob1.pixels() - blob2.pixels()
          if tmp == 0:
              return 0
          elif tmp > 0:
              return 1
          else:
              return -1
      
      def task_2017_1_1():
          red_threshold_01 = (0,55)                                       #目标色块的灰度值参数范围
          time_flag = 0
          num_stop = 0
          pid_x = pid.PID(80,0.5,0,0,30)                                   #x轴方向的pid控制,pid参数要自己调
          pid_y = pid.PID(60,0.5,0,0,30)                                   #y轴方向的pid控制
          flag_x_y = 0
          Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
          ##################各个字母所对应的ASCII值######################
          R = ord('R')
          L = ord('L')
          S = ord('S')
          B = ord('B')
          G = ord('G')
          E = ord('E')
          ###########################################################
          Buzzer.value(1)
          time.sleep(1000)
          Buzzer.value(0)
          while(True):
              print("the task number is 1 now!")
              img = sensor.snapshot().lens_corr(1.8)
              blobs = img.find_blobs([red_threshold_01],
                  pixels_threshold=100, merge=True)                         #寻找目标色块,低于150像素的视为噪声
              img.binary([red_threshold_01], invert = True)                 #二值化处理
              if blobs:                                                     #如果识别到目标色块
                  #print(blobs)                                             #在终端打印出blobs的信息
                  bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
                  for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                      if compareBlob(bigBlob, blob_temp) == -1:
                          bigBlob = blob_temp
                  img.draw_rectangle(bigBlob[0:4])                          #画个矩形框标出色块所在区域
                  img.draw_cross(bigBlob[5], bigBlob[6])                    #画个十字架标出色块所在区域的中心点
                  if (abs(bigBlob.cx() - 80) < 5) and \
                      (abs(bigBlob.cy() - 60) < 5):
                      time_flag = 1
                  if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
                     # print("speed_x: %f" %speed_x)
                      if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                          data_pack.send_cmd(L,speed_x)
                      else:
                          data_pack.send_cmd(R,abs(speed_x))
                          print("RIGHT")
                      flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                  else :
                      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
                      #print("speed_y: %f" %speed_y)
                      if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                          data_pack.send_cmd(G,speed_y)
                      else:
                          data_pack.send_cmd(B,abs(speed_y))
                      flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
                  if time_flag == 1:
                      num_stop += 1
                      if num_stop >= 200 :                                  #200次差不多15秒钟,降落
                          num_stop = 0
                          data_pack.send_cmd(E,0)
              else:
                  data_pack.send_cmd(S,0)                                #没有检测到目标色块,这里让无人机原地罚站
      
      ```上面的是task1
      
      

      import sensor, image, time, pyb, struct, math

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_1_2():
      red_threshold_01 = (0,55) #目标色块的灰度值参数范围
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      time.sleep(500)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      while(True):
      print("the task number is 2 now!")
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([red_threshold_01],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([red_threshold_01], invert = True) #二值化处理
      if blobs: #如果识别到目标色块
      #print(blobs) #在终端打印出blobs的信息
      bigBlob = blobs[0] #将第一个色块赋值给最大色块
      for blob_temp in blobs: #此循环找出最大色块,进一步滤除噪声
      if compareBlob(bigBlob, blob_temp) == -1:
      bigBlob = blob_temp
      img.draw_rectangle(bigBlob[0:4]) #画个矩形框标出色块所在区域
      img.draw_cross(bigBlob[5], bigBlob[6]) #画个十字架标出色块所在区域的中心点
      print("Bigbolb.pixel: %d" %bigBlob.pixels())
      if (bigBlob.pixels() < 1500) and
      (bigBlob.pixels() > 300):
      pyb.LED(2).on()
      Buzzer.value(1)
      else:
      pyb.LED(2).off()
      Buzzer.value(0)

      
      

      import sensor, image, time, pyb, struct, math
      import pid, data_pack

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_1_3():
      red_threshold_03 = (0,55) #目标色块的灰度值参数范围
      time_flag = 0
      num_stop = 0
      pid_x = pid.PID(80,0.3,0,0,30) #x轴方向的pid控制,pid参数要自己调
      pid_y = pid.PID(60,0.3,0,0,30) #y轴方向的pid控制
      flag_x_y = 0
      prepare_flag = 0
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      ##################各个字母所对应的ASCII值######################
      R = ord('R')
      L = ord('L')
      S = ord('S')
      B = ord('B')
      G = ord('G')
      E = ord('E')
      ###########################################################
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      time.sleep(500)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      time.sleep(500)
      Buzzer.value(1)
      time.sleep(500)
      Buzzer.value(0)
      while(True):
      print("the task number is 3 now!")
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([red_threshold_03],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([red_threshold_03], invert = True) #二值化处理
      if len(blobs) == 2: #如果识别到目标色块
      print("the number of blobs is %d" %len(blobs))
      if(abs(blobs[0].cx()-80)<5) and
      (abs(blobs[0].cy()-60)<5):
      time_flag = 1
      if flag_x_y == 0 : #调节x与y方向的切换标志
      speed_x = pid_x.IncPIDCalc(blobs[0].cx())
      # print("speed_x: %f" %speed_x)
      if speed_x > 0: #说明目标当前x值偏小,无人机偏右,需要向左调整
      data_pack.send_cmd(L,speed_x)
      else:
      data_pack.send_cmd(R,abs(speed_x))
      flag_x_y = 1 #标志位置1,表示下次循环调整y轴方向
      else :
      speed_y = pid_y.IncPIDCalc(blobs[0].cy())
      #print("speed_y: %f" %speed_y)
      if speed_y >= 0: #说明目标当前y值偏小,无人机偏后,需要向前调整
      data_pack.send_cmd(G,speed_y)
      else:
      data_pack.send_cmd(B,abs(speed_y))
      flag_x_y = 0 #标志位置0,表示下次循环调整x轴方向
      elif len(blobs) == 0:
      print("the number of blobs is %d" %len(blobs))
      if prepare_flag == 0 or prepare_flag == 2:
      data_pack.send_cmd(E,0) #没有检测到目标色块,这里让无人机原地罚站
      else:
      data_pack.send_cmd(G,5)

          else :
              print("the number of blobs is %d" %len(blobs))
              bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
              for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                  if compareBlob(bigBlob, blob_temp) == -1:
                      bigBlob = blob_temp
      
              if prepare_flag == 1 and bigBlob.cy() > 80:
                  data_pack.send_cmd(G,5)
              elif prepare_flag == 1 and bigBlob.cy() < 40:
                  prepare_flag = 2
      
              if(abs(bigBlob.cx()-80)<5) and \
                  (abs(bigBlob.cy()-60)<5) and \
                  prepare_flag == 0:
                  prepare_flag = 1
              if(abs(bigBlob.cx()-80)<5) and \
                  (abs(bigBlob.cy()-60)<5) and \
                  prepare_flag == 2:
                  time_flag = 1
              if prepare_flag == 0 or prepare_flag == 2:
                  if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
                     # print("speed_x: %f" %speed_x)
                      if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                          data_pack.send_cmd(L,speed_x)
                      else:
                          data_pack.send_cmd(R,abs(speed_x))
                      flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                  else :
                      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
                      #print("speed_y: %f" %speed_y)
                      if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                          data_pack.send_cmd(G,speed_y)
                      else:
                          data_pack.send_cmd(B,abs(speed_y))
                      flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
              else:                                                         #准备就绪,进入8区
                  data_pack.send_cmd(G,15)
          if time_flag == 1:
              num_stop += 1
              if num_stop >= 120 :                                  #100次差不多5秒钟,降落
                  data_pack.send_cmd(L,15)
                  time.sleep(100)
                  data_pack.send_cmd(L,15)
                  time.sleep(100)
                  data_pack.send_cmd(L,15)
                  time.sleep(100)
                  num_stop = 0
                  data_pack.send_cmd(E,0)
      
      
      

      import sensor, image, time, pyb, struct, math
      import pid, data_pack

      def compareBlob(blob1, blob2): #比较两个色块大小的函数
      tmp = blob1.pixels() - blob2.pixels()
      if tmp == 0:
      return 0
      elif tmp > 0:
      return 1
      else:
      return -1

      def task_2017_2():
      threshold_01 = (0,55) #目标色块的灰度值参数范围
      number_period = 0
      pid_x = pid.PID(80,0.5,0,0,30) #x轴方向的pid控制,pid参数要自己调
      pid_y = pid.PID(60,0.5,0,0,30) #y轴方向的pid控制
      flag_x_y = 0
      flag_buzzer = 0
      stop_flag_car = 0
      clock = time.clock()
      Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
      uart1 = pyb.UART(1, 115200, timeout_char = 100) #打开串口1
      ##################各个字母所对应的ASCII值######################
      R = ord('R')
      L = ord('L')
      S = ord('S')
      B = ord('B')
      G = ord('G')
      E = ord('E')
      ###########################################################
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      time.sleep(400)
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      time.sleep(400)
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      time.sleep(400)
      Buzzer.value(1)
      time.sleep(400)
      Buzzer.value(0)
      while(True):
      #print("the task number is 1 now!")
      clock.tick()
      number_period += 1
      if number_period >= 60 :
      number_period = 0
      if stop_flag_car != S:
      stop_flag_car = uart1.readchar()
      if stop_flag_car == S:
      if flag_buzzer == 0:
      data_pack.send_cmd(E,0)
      Buzzer.value(1)
      time.sleep(1000)
      Buzzer.value(0)
      flag_buzzer = 1
      #time.sleep(1000)
      # print("landing start!")
      #print("stop_flag_car : %s" %stop_flag_car)
      # data_pack.send_cmd(S,0)
      #print("stop_flag_car : %s" %stop_flag_car)
      #continue
      img = sensor.snapshot().lens_corr(1.8)
      blobs = img.find_blobs([threshold_01],
      pixels_threshold=100, merge=True) #寻找目标色块,低于150像素的视为噪声
      img.binary([threshold_01], invert = True) #二值化处理
      if blobs: #如果识别到目标色块
      #print(blobs) #在终端打印出blobs的信息
      bigBlob = blobs[0] #将第一个色块赋值给最大色块
      for blob_temp in blobs: #此循环找出最大色块,进一步滤除噪声
      if compareBlob(bigBlob, blob_temp) == -1:
      bigBlob = blob_temp
      img.draw_rectangle(bigBlob[0:4]) #画个矩形框标出色块所在区域
      img.draw_cross(bigBlob[5], bigBlob[6]) #画个十字架标出色块所在区域的中心点
      if flag_x_y == 0 : #调节x与y方向的切换标志
      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
      # print("speed_x: %f" %speed_x)
      if speed_x > 0: #说明目标当前x值偏小,无人机偏右,需要向左调整
      data_pack.send_cmd(L,speed_x)
      else:
      data_pack.send_cmd(R,abs(speed_x))
      flag_x_y = 1 #标志位置1,表示下次循环调整y轴方向
      else :
      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
      #print("speed_y: %f" %speed_y)
      if speed_y >= 0: #说明目标当前y值偏小,无人机偏后,需要向前调整
      data_pack.send_cmd(G,speed_y)
      else:
      data_pack.send_cmd(B,abs(speed_y))
      flag_x_y = 0 #标志位置0,表示下次循环调整x轴方向
      else:
      data_pack.send_cmd(S,0) #没有检测到目标色块,这里让无人机原地罚站

      
      

      import sensor, image, time, math, struct ,pyb,utime
      class PID:
      def init(self, SetPoint,Proportion,Integral,Derivative,Limit):
      # WARNING: Don't use PA4-X5 or PA5-X6 as echo pin without a 1k resistor
      self.SetPoint = SetPoint #设定值
      self.Proportion = Proportion #P
      self.Integral = Integral #I
      self.Derivative = Derivative #D
      self.Limit = Limit #限幅
      self.LastError = 0 #前1次误差值
      self.PrevError = 0 #前2次误差值
      self.iError = 0 #当前误差
      self.iIncpid = 0 #增量误差
      self.Uk = 0 #输出返回\

      def IncPIDCalc(self, NextPoint):
            # 当前误差
            self.iError = self.SetPoint - NextPoint
            # 增量误差
            self.iIncpid = (self.Proportion * (self.iError - self.LastError)+ self.Integral *
                           self.iError + self.Derivative * (self.iError - 2 * self.LastError +
                           self.PrevError))
            #存储误差,用于下次计算
            self.PrevError = self.LastError
            self.LastError = self.iError
      
            self.Uk += self.iIncpid
            self.Uk = self.Limit_Amplitude(self.Uk)
           # print("NextPoint : %f" % NextPoint)
           # print("Uk : %f" % self.Uk)
            return self.Uk
      
      def Limit_Amplitude(self,num):
          if num > self.Limit :
              return self.Limit
          elif num < -self.Limit:
              return -self.Limit
          else:
              return num
      
      
      

      import time, pyb, struct

      C = ord('C')
      F = ord('F')
      G = ord('G')
      B = ord('B')
      R = ord('R')
      L = ord('L')
      D = ord('D')
      U = ord('U')
      E = ord('E')
      S = ord('S')
      H = ord('H')
      uart3 = pyb.UART(3, 500000, timeout_char = 1000)
      green_led = pyb.LED(2)

      def send_89(direct,velcity):
      '''
      功能字为0x89,控制前进(后退)、左(右)、上升(下降)速度大小
      speed字段必须正
      '''
      s = 0xAA+0x8C+direct+(int(velcity/256))+(int(velcity%256))
      s = int(s % 256)
      temp_flow = struct.pack("<BBBBBhB",
      0x00,
      0xAA,
      0x89,
      03,
      direct,
      int(velcity),
      s)
      uart3.write(temp_flow)

      def send_98(direct,velcity):
      '''
      功能字为0x98,控制顺(逆)时针转动速度大小
      speed字段正负一样
      '''
      s = 0xAA+0x9B+direct+(int(velcity/256))+(int(velcity%256))
      s = int(s % 256)
      temp_flow = struct.pack("<BBBBBhB",
      0x00,
      0xAA,
      0x98,
      03,
      direct,
      velcity,
      s)
      uart3.write(temp_flow)

      def send_cmd(direct,velcity):
      if direct == C or direct == F:
      send_98(direct,velcity)
      time.sleep(3)
      else:
      send_89(direct,velcity)
      if direct == S:
      time.sleep(3)



    • @kidswong999 这个是task2

      import sensor, image, time, pyb, struct, math
      
      def compareBlob(blob1, blob2):                                    #比较两个色块大小的函数
          tmp = blob1.pixels() - blob2.pixels()
          if tmp == 0:
              return 0
          elif tmp > 0:
              return 1
          else:
              return -1
      
      def task_2017_1_2():
          red_threshold_01 = (0,55)                                       #目标色块的灰度值参数范围
          Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
          Buzzer.value(1)
          time.sleep(500)
          Buzzer.value(0)
          time.sleep(500)
          Buzzer.value(1)
          time.sleep(500)
          Buzzer.value(0)
          while(True):
              print("the task number is 2 now!")
              img = sensor.snapshot().lens_corr(1.8)
              blobs = img.find_blobs([red_threshold_01],
                  pixels_threshold=100, merge=True)                         #寻找目标色块,低于150像素的视为噪声
              img.binary([red_threshold_01], invert = True)                 #二值化处理
              if blobs:                                                     #如果识别到目标色块
                  #print(blobs)                                             #在终端打印出blobs的信息
                  bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
                  for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                      if compareBlob(bigBlob, blob_temp) == -1:
                          bigBlob = blob_temp
                  img.draw_rectangle(bigBlob[0:4])                          #画个矩形框标出色块所在区域
                  img.draw_cross(bigBlob[5], bigBlob[6])                    #画个十字架标出色块所在区域的中心点
                  print("Bigbolb.pixel: %d" %bigBlob.pixels())
                  if (bigBlob.pixels() < 1500) and \
                      (bigBlob.pixels() > 300):
                      pyb.LED(2).on()
                      Buzzer.value(1)
                  else:
                      pyb.LED(2).off()
                      Buzzer.value(0)
      
      
      


    • @kidswong999 这个是task3

      import sensor, image, time, pyb, struct, math
      import pid, data_pack
      
      def compareBlob(blob1, blob2):                                    #比较两个色块大小的函数
          tmp = blob1.pixels() - blob2.pixels()
          if tmp == 0:
              return 0
          elif tmp > 0:
              return 1
          else:
              return -1
      
      
      def task_2017_1_3():
          red_threshold_03 = (0,55)                                       #目标色块的灰度值参数范围
          time_flag = 0
          num_stop = 0
          pid_x = pid.PID(80,0.3,0,0,30)                                   #x轴方向的pid控制,pid参数要自己调
          pid_y = pid.PID(60,0.3,0,0,30)                                   #y轴方向的pid控制
          flag_x_y = 0
          prepare_flag = 0
          Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
          ##################各个字母所对应的ASCII值######################
          R = ord('R')
          L = ord('L')
          S = ord('S')
          B = ord('B')
          G = ord('G')
          E = ord('E')
          ###########################################################
          Buzzer.value(1)
          time.sleep(500)
          Buzzer.value(0)
          time.sleep(500)
          Buzzer.value(1)
          time.sleep(500)
          Buzzer.value(0)
          time.sleep(500)
          Buzzer.value(1)
          time.sleep(500)
          Buzzer.value(0)
          while(True):
              print("the task number is 3 now!")
              img = sensor.snapshot().lens_corr(1.8)
              blobs = img.find_blobs([red_threshold_03],
                  pixels_threshold=100, merge=True)                         #寻找目标色块,低于150像素的视为噪声
              img.binary([red_threshold_03], invert = True)                 #二值化处理
              if len(blobs) == 2:                                           #如果识别到目标色块
                  print("the number of blobs is %d" %len(blobs))
                  if(abs(blobs[0].cx()-80)<5) and \
                      (abs(blobs[0].cy()-60)<5):
                      time_flag = 1
                  if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                      speed_x = pid_x.IncPIDCalc(blobs[0].cx())
                     # print("speed_x: %f" %speed_x)
                      if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                          data_pack.send_cmd(L,speed_x)
                      else:
                          data_pack.send_cmd(R,abs(speed_x))
                      flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                  else :
                      speed_y = pid_y.IncPIDCalc(blobs[0].cy())
                      #print("speed_y: %f" %speed_y)
                      if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                          data_pack.send_cmd(G,speed_y)
                      else:
                          data_pack.send_cmd(B,abs(speed_y))
                      flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
              elif len(blobs) == 0:
                  print("the number of blobs is %d" %len(blobs))
                  if  prepare_flag == 0 or prepare_flag == 2:
                      data_pack.send_cmd(E,0)                                #没有检测到目标色块,这里让无人机原地罚站
                  else:
                      data_pack.send_cmd(G,5)
      
              else :
                  print("the number of blobs is %d" %len(blobs))
                  bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
                  for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                      if compareBlob(bigBlob, blob_temp) == -1:
                          bigBlob = blob_temp
      
                  if prepare_flag == 1 and bigBlob.cy() > 80:
                      data_pack.send_cmd(G,5)
                  elif prepare_flag == 1 and bigBlob.cy() < 40:
                      prepare_flag = 2
      
                  if(abs(bigBlob.cx()-80)<5) and \
                      (abs(bigBlob.cy()-60)<5) and \
                      prepare_flag == 0:
                      prepare_flag = 1
                  if(abs(bigBlob.cx()-80)<5) and \
                      (abs(bigBlob.cy()-60)<5) and \
                      prepare_flag == 2:
                      time_flag = 1
                  if prepare_flag == 0 or prepare_flag == 2:
                      if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                          speed_x = pid_x.IncPIDCalc(bigBlob.cx())
                         # print("speed_x: %f" %speed_x)
                          if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                              data_pack.send_cmd(L,speed_x)
                          else:
                              data_pack.send_cmd(R,abs(speed_x))
                          flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                      else :
                          speed_y = pid_y.IncPIDCalc(bigBlob.cy())
                          #print("speed_y: %f" %speed_y)
                          if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                              data_pack.send_cmd(G,speed_y)
                          else:
                              data_pack.send_cmd(B,abs(speed_y))
                          flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
                  else:                                                         #准备就绪,进入8区
                      data_pack.send_cmd(G,15)
              if time_flag == 1:
                  num_stop += 1
                  if num_stop >= 120 :                                  #100次差不多5秒钟,降落
                      data_pack.send_cmd(L,15)
                      time.sleep(100)
                      data_pack.send_cmd(L,15)
                      time.sleep(100)
                      data_pack.send_cmd(L,15)
                      time.sleep(100)
                      num_stop = 0
                      data_pack.send_cmd(E,0)
      
      


    • @kidswong999 这个是task plus

      import sensor, image, time, pyb, struct, math
      import pid, data_pack
      
      
      
      def compareBlob(blob1, blob2):                                    #比较两个色块大小的函数
          tmp = blob1.pixels() - blob2.pixels()
          if tmp == 0:
              return 0
          elif tmp > 0:
              return 1
          else:
              return -1
      
      def task_2017_2():
          threshold_01 = (0,55)                                            #目标色块的灰度值参数范围
          number_period = 0
          pid_x = pid.PID(80,0.5,0,0,30)                                   #x轴方向的pid控制,pid参数要自己调
          pid_y = pid.PID(60,0.5,0,0,30)                                   #y轴方向的pid控制
          flag_x_y = 0
          flag_buzzer = 0
          stop_flag_car = 0
          clock = time.clock()
          Buzzer = pyb.Pin("P6", pyb.Pin.OUT_PP)
          uart1 = pyb.UART(1, 115200, timeout_char = 100)                  #打开串口1
          ##################各个字母所对应的ASCII值######################
          R = ord('R')
          L = ord('L')
          S = ord('S')
          B = ord('B')
          G = ord('G')
          E = ord('E')
          ###########################################################
          Buzzer.value(1)
          time.sleep(400)
          Buzzer.value(0)
          time.sleep(400)
          Buzzer.value(1)
          time.sleep(400)
          Buzzer.value(0)
          time.sleep(400)
          Buzzer.value(1)
          time.sleep(400)
          Buzzer.value(0)
          time.sleep(400)
          Buzzer.value(1)
          time.sleep(400)
          Buzzer.value(0)
          while(True):
              #print("the task number is 1 now!")
              clock.tick()
              number_period += 1
              if number_period >= 60 :
                  number_period = 0
                  if stop_flag_car != S:
                      stop_flag_car = uart1.readchar()
              if stop_flag_car == S:
                  if flag_buzzer == 0:
                      data_pack.send_cmd(E,0)
                      Buzzer.value(1)
                      time.sleep(1000)
                      Buzzer.value(0)
                      flag_buzzer = 1
                  #time.sleep(1000)
                 # print("landing start!")
                  #print("stop_flag_car : %s" %stop_flag_car)
                 # data_pack.send_cmd(S,0)
              #print("stop_flag_car : %s" %stop_flag_car)
              #continue
              img = sensor.snapshot().lens_corr(1.8)
              blobs = img.find_blobs([threshold_01],
                  pixels_threshold=100, merge=True)                         #寻找目标色块,低于150像素的视为噪声
              img.binary([threshold_01], invert = True)                     #二值化处理
              if blobs:                                                     #如果识别到目标色块
                  #print(blobs)                                             #在终端打印出blobs的信息
                  bigBlob = blobs[0]                                        #将第一个色块赋值给最大色块
                  for blob_temp in blobs:                                   #此循环找出最大色块,进一步滤除噪声
                      if compareBlob(bigBlob, blob_temp) == -1:
                          bigBlob = blob_temp
                  img.draw_rectangle(bigBlob[0:4])                          #画个矩形框标出色块所在区域
                  img.draw_cross(bigBlob[5], bigBlob[6])                    #画个十字架标出色块所在区域的中心点
                  if flag_x_y == 0 :                                        #调节x与y方向的切换标志
                      speed_x = pid_x.IncPIDCalc(bigBlob.cx())
                     # print("speed_x: %f" %speed_x)
                      if speed_x > 0:                                       #说明目标当前x值偏小,无人机偏右,需要向左调整
                          data_pack.send_cmd(L,speed_x)
                      else:
                          data_pack.send_cmd(R,abs(speed_x))
                      flag_x_y = 1                                          #标志位置1,表示下次循环调整y轴方向
                  else :
                      speed_y = pid_y.IncPIDCalc(bigBlob.cy())
                      #print("speed_y: %f" %speed_y)
                      if speed_y >= 0:                                      #说明目标当前y值偏小,无人机偏后,需要向前调整
                          data_pack.send_cmd(G,speed_y)
                      else:
                          data_pack.send_cmd(B,abs(speed_y))
                      flag_x_y = 0                                          #标志位置0,表示下次循环调整x轴方向
              else:
                  data_pack.send_cmd(S,0)                                #没有检测到目标色块,这里让无人机原地罚站
      
      


    • @kidswong999 这个是pid

      import sensor, image, time, math, struct ,pyb,utime
      class PID:
          def __init__(self, SetPoint,Proportion,Integral,Derivative,Limit):
              # WARNING: Don't use PA4-X5 or PA5-X6 as echo pin without a 1k resistor
              self.SetPoint   = SetPoint      #设定值
              self.Proportion = Proportion    #P
              self.Integral   = Integral      #I
              self.Derivative = Derivative    #D
              self.Limit      = Limit         #限幅
              self.LastError  = 0             #前1次误差值
              self.PrevError  = 0             #前2次误差值
              self.iError     = 0             #当前误差
              self.iIncpid    = 0             #增量误差
              self.Uk         = 0             #输出返回\
      
          def IncPIDCalc(self, NextPoint):
                # 当前误差
                self.iError = self.SetPoint - NextPoint
                # 增量误差
                self.iIncpid = (self.Proportion * (self.iError - self.LastError)+ self.Integral *
                               self.iError + self.Derivative * (self.iError - 2 * self.LastError +
                               self.PrevError))
                #存储误差,用于下次计算
                self.PrevError = self.LastError
                self.LastError = self.iError
      
                self.Uk += self.iIncpid
                self.Uk = self.Limit_Amplitude(self.Uk)
               # print("NextPoint : %f" % NextPoint)
               # print("Uk : %f" % self.Uk)
                return self.Uk
      
          def Limit_Amplitude(self,num):
              if num > self.Limit :
                  return self.Limit
              elif num < -self.Limit:
                  return -self.Limit
              else:
                  return num
      
      


    • @kidswong999 这个是data_pack

      import sensor, image, time
      
      def get_line_k(x1,x2,y1,y2):
          det_x = x2 - x1
          det_y = y2 - y1
          if det_x == 0:                                                #考虑斜率无穷大的情况
              det_x = 1
          return (det_y/det_x)
      
      def get_line_b(x1,x2,y1,y2):
          k = get_line_k(x1,x2,y1,y2)
          return (y1-(k*x1))
      
      def get_line_cross_x(k1,k2,b1,b2):
          det_k = k1 - k2
          if det_k == 0:
              return -1
          else:
              return (b2 - b1)/(k1 - k2)
      
      def get_line_cross_y(k1,k2,b1,b2):
          det_k = k1 - k2
          if det_k == 0:
              return -1
          else:
              return (b1*k2 - k1*b2)/(k2 - k1)
      
      def get_cross_dot(lines):
          cross_dot = [0,0]
          x1 = lines[0].x1()
          x2 = lines[0].x2()
          x3 = lines[1].x1()
          x4 = lines[1].x2()
          y1 = lines[0].y1()
          y2 = lines[0].y2()
          y3 = lines[1].y1()
          y4 = lines[1].y2()
          k1 = get_line_k(x1,x2,y1,y2)
          k2 = get_line_k(x3,x4,y3,y4)
          b1 = get_line_b(x1,x2,y1,y2)
          b2 = get_line_b(x3,x4,y3,y4)
          cross_dot[0] = get_line_cross_x(k1,k2,b1,b2)
          cross_dot[1] = get_line_cross_y(k1,k2,b1,b2)
          return cross_dot