一直弹框错误怎么办:MemoryError:Out of fast Frame Buffer Stack Memory!
-
经常弹这个错误,定位到find apriltags的位置。
最初弹这个错误比较少,现在越来越频繁,周期越来越短。
程序如下:## 一次设置,导入模块 ## THRESHOLD = ( 37, 100, -29, 105, 15, 97) # 设置巡回路线的阈值 import sensor, image, time, pyb, math # 调用传感器,图像,时间 from pyb import Pin, Timer, ExtInt # 导入引脚 sensor.reset() sensor.set_vflip(True) # 设置图像垂直方向翻转 sensor.set_hmirror(True) # 设置图像水平方向翻转 sensor.set_pixformat(sensor.RGB565) # 设置为彩图 sensor.set_framesize(sensor.QQQVGA) # 设置像素80x60 (4,800 pixels) - O(N^2) max = 2,3040,000. sensor.skip_frames(time = 2000) # WARNING: If you use QQVGA it may take seconds sensor.set_auto_gain(False) # must turn this off to prevent image washout... sensor.set_auto_whitebal(False) # must turn this off to prevent image washout... tag_families = 0 tag_families |= image.TAG16H5 # comment out to disable this family callback = lambda e: print("intr") #ext = ExtInt(Pin('P8'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback) clock = time.clock() # to process a frame sometimes. ain0 = Pin('P0', Pin.OUT_PP) # 伸缩杆收回右转 ain1 = Pin('P1', Pin.OUT_PP) # 伸缩杆伸出左转 ain2 = Pin('P2', Pin.OUT_PP) ain3 = Pin('P3', Pin.OUT_PP) ain4 = Pin('P4', Pin.OUT_PP) ain5 = Pin('P5', Pin.OUT_PP) pin6_in = pyb.Pin('P6', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #备用 pin7_in = pyb.Pin('P7', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #方向推杆原点位置左侧传感器,原点处时为on pin8_in = pyb.Pin('P8', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #备用 pin9_in = pyb.Pin('P9', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #方向推杆原点位置右侧传感器,原点处时为off ain1.low() #引脚初始化为低电平 ain2.low() #引脚初始化为低电平 h=0 #用于拐弯计数 z=1 #运行流程标志位,z=1 初始化,z=2 正常运行,z=0 停止运行 a=0 #存放调用子程序的序号标志位 m=0 #存放转弯进行中的标志 #--------------------------------------方向推杆初始化------ while(z==1): #初始化 if pin7_in.value()==True and pin9_in.value()==True: # 如果推杆维持右转状态,伸出推杆,回归到原点 ain0.low() ain1.high() elif pin7_in.value()==False and pin9_in.value()==False: # 如果推杆维持左转状态,收回推杆,回归到原点 ain1.low() ain0.high() elif pin7_in.value()==True and pin9_in.value()==False: # 如果推杆到原点,保持推杆位置,开始运行主程序 ain0.low() # 收回右转 ain1.low() # 伸出左转 z=2 else: ain0.low() ain1.low() #------------------------------------方向初始化完成-------- while(z==2): #正常运行 clock.tick() #关闭白平衡 img = sensor.snapshot() #截取图像 for tag in img.find_apriltags(families=tag_families): #识别apriltages标志,用于拐弯 if m==0: h=h+1 #Apriltag计数--用于拐弯 m=1 elif m==1: #直行拐弯前方向恢复原位 if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 m=2 else: ain0.low() ain1.low() elif m==2: if h==1 or h==3: ain1.low() # 伸出左转 ain0.high() # 收回右转 pyb.delay(1700) ain1.low() # 伸出左转 ain0.low() # 收回右转 pyb.delay(15000) while(m==2): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 m=0 break else: ain0.low() ain1.low() elif h==2: ain1.low() # 伸出左转 ain0.high() # 收回右转 pyb.delay(2100) ain1.low() # 伸出左转 ain0.low() # 收回右转 pyb.delay(14000) while(m==2): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 m=0 break else: ain0.low() ain1.low() else:h=0 img = sensor.snapshot().binary([THRESHOLD]) # 截取一张图片,进行阈值分割,THRESHOLD为阈值,binary图像二值化 line = img.get_regression([(100,100,0,0,0,0)], robust = True) # 使用线性回归方法,反馈得到一条直线 if h==0 or h==3: aim_width= 60 # 目标位置的偏移距离,距离目标线较近的路线上 aim_theta= 0 elif h==1 or h==2: aim_width= 23 # 目标位置的偏移距离,距离目标线较远的线路上 aim_theta= 5 else: aim_width= 0 aim_theta = 0 if (line and m==0): if line.theta()>90: # 直线的角度 theta_err = line.theta()-180 else: theta_err = line.theta() img.draw_line(line.line(), color = 127) # line.line()返回一个直线元组(x1, y1, x2, y2) rho_err = abs(line.rho())-aim_width # line.rho()返回直线p值;计算直线与目标位置的偏移距离 aimtheta_dif= theta_err - aim_theta #与目标角度的角度差 print("行驶路线标号:",h,rho_err,aimtheta_dif) #输出行驶路线标号:(0:最左;1:二左;2:二左;3:最右),偏移距离,偏移角度 if h==0 or h==3: rho_err_min = 3 # 设定近距离范围 rho_err_max1 = 4 # 向左最大偏移距离 rho_err_max2 = -4 # 向右最大偏移距离 rho_err_maxx1 = 6 # 向左急转偏移距离 rho_err_maxx2 = -6 # 向右急转偏移距离 elif h==1 or h==2: rho_err_min = 2 # 设定近距离范围 rho_err_max1 = 3 # 向左最大偏移距离 rho_err_max2 = -3 # 向右最大偏移距离 rho_err_maxx1 = 5 # 向左急转偏移距离 rho_err_maxx2 = -5 # 向右急转偏移距离 else: rho_err_min = 0 # 设定近距离范围 rho_err_max1 = 0 # 向左最大偏移距离 rho_err_max2 = 0 # 向右最大偏移距离 rho_err_maxx1 = 0 # 向左急转偏移距离 rho_err_maxx2 = 0 # 向右急转偏移距离 if abs(rho_err) <= rho_err_min and abs(aimtheta_dif) >=4: if a==0: # a=0没有调向其他子程序 theta_err_mid=(theta_err + aim_theta)/2 # 实际角度与目标角度的中间值,用作动作回位参考 if theta_err> aim_theta: a=1 # a=1近距离方向左偏,调用右转程序 elif theta_err< aim_theta: a=2 # a=2近距离方向右偏,调用左转程序 elif rho_err > rho_err_max1 and rho_err < rho_err_maxx1 and aimtheta_dif >= -4: # 在目标线路左侧,角度偏移大于-4,呈远离趋势,调用右转程序 if a==0: theta_err_mid=(theta_err + aim_theta-12)/2 # 目标角度-12度 a=1 elif rho_err < rho_err_max2 and rho_err > rho_err_maxx2 and aimtheta_dif <= 4: # 在目标线路右侧,角度偏移小于4,呈远离趋势,调用左转程序 if a==0: theta_err_mid=(theta_err + aim_theta+12)/2 # 目标角度12度 a=2 elif rho_err >= rho_err_maxx1 and aimtheta_dif >= -15: # 在目标线路左侧极限距离外,右转,靠近中心线 if a==0: theta_err_mid=(theta_err + aim_theta-20)/2 # 目标角度为-20 a=1 elif rho_err <= rho_err_maxx2 and aimtheta_dif <= 15: # 在目标线路右侧极限距离外,左转,靠近中心线 if a==0: theta_err_mid=(theta_err + aim_theta+20)/2 # 目标角度为20 a=2 if(a==1): # 右转子程序------------------------------------ if theta_err >theta_err_mid: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif (theta_err <=theta_err_mid): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 收回右转 ain0.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 a=0 else: ain0.low() ain1.low() if(a==2): # 左转子程序------------------------------------ if theta_err <theta_err_mid: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif (theta_err >=theta_err_mid): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 收回右转 ain0.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 a=0 else: ain0.low() ain1.low()
-
你的代码需要外部硬件操作,我没办法运行测试,请给我一个方便测试的代码。
-
此回复已被删除!
-
@kidswong999 这段程序拷进去,不需要硬件支持,等一段时间就会弹错误窗口。
不过最初用这个程序没有问题,现在每次都会弹错误窗口。## 一次设置,导入模块 ## THRESHOLD = ( 37, 100, -29, 105, 15, 97) # 设置巡回路线的阈值 import sensor, image, time, pyb, math # 调用传感器,图像,时间 from pyb import Pin, Timer, ExtInt # 导入引脚 sensor.reset() sensor.set_vflip(True) # 设置图像垂直方向翻转 sensor.set_hmirror(True) # 设置图像水平方向翻转 sensor.set_pixformat(sensor.RGB565) # 设置为彩图 sensor.set_framesize(sensor.QQQVGA) # 设置像素80x60 (4,800 pixels) - O(N^2) max = 2,3040,000. sensor.skip_frames(time = 2000) # WARNING: If you use QQVGA it may take seconds sensor.set_auto_gain(False) # must turn this off to prevent image washout... sensor.set_auto_whitebal(False) # must turn this off to prevent image washout... tag_families = 0 tag_families |= image.TAG16H5 # comment out to disable this family callback = lambda e: print("intr") #ext = ExtInt(Pin('P8'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback) clock = time.clock() # to process a frame sometimes. ain0 = Pin('P0', Pin.OUT_PP) # 伸缩杆收回右转 ain1 = Pin('P1', Pin.OUT_PP) # 伸缩杆伸出左转 ain2 = Pin('P2', Pin.OUT_PP) ain3 = Pin('P3', Pin.OUT_PP) ain4 = Pin('P4', Pin.OUT_PP) ain5 = Pin('P5', Pin.OUT_PP) pin6_in = pyb.Pin('P6', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #备用 pin7_in = pyb.Pin('P7', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #方向推杆原点位置左侧传感器,原点处时为on pin8_in = pyb.Pin('P8', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #备用 pin9_in = pyb.Pin('P9', pyb.Pin.IN, pyb.Pin.PULL_DOWN) #方向推杆原点位置右侧传感器,原点处时为off ain1.low() #引脚初始化为低电平 ain2.low() #引脚初始化为低电平 h=0 #用于拐弯计数 z=1 #运行流程标志位,z=1 初始化,z=2 正常运行,z=0 停止运行 a=0 #存放调用子程序的序号标志位 m=0 #存放转弯进行中的标志 #--------------------------------------方向推杆初始化------ while(z==1): #初始化 if pin7_in.value()==True and pin9_in.value()==True: # 如果推杆维持右转状态,伸出推杆,回归到原点 ain0.low() ain1.high() z=2 elif pin7_in.value()==False and pin9_in.value()==False: # 如果推杆维持左转状态,收回推杆,回归到原点 ain1.low() ain0.high() z=2 elif pin7_in.value()==True and pin9_in.value()==False: # 如果推杆到原点,保持推杆位置,开始运行主程序 ain0.low() # 收回右转 ain1.low() # 伸出左转 z=2 else: ain0.low() ain1.low() z=2 #------------------------------------方向初始化完成-------- while(z==2): #正常运行 clock.tick() #关闭白平衡 img = sensor.snapshot() #截取图像 for tag in img.find_apriltags(families=tag_families): #识别apriltages标志,用于拐弯 if m==0: h=h+1 #Apriltag计数--用于拐弯 m=1 elif m==1: #直行拐弯前方向恢复原位 if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 m=2 else: ain0.low() ain1.low() elif m==2: if h==1 or h==3: ain1.low() # 伸出左转 ain0.high() # 收回右转 pyb.delay(1700) ain1.low() # 伸出左转 ain0.low() # 收回右转 pyb.delay(15000) while(m==2): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 m=0 break else: ain0.low() ain1.low() elif h==2: ain1.low() # 伸出左转 ain0.high() # 收回右转 pyb.delay(2100) ain1.low() # 伸出左转 ain0.low() # 收回右转 pyb.delay(14000) while(m==2): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 m=0 break else: ain0.low() ain1.low() else:h=0 img = sensor.snapshot().binary([THRESHOLD]) # 截取一张图片,进行阈值分割,THRESHOLD为阈值,binary图像二值化 line = img.get_regression([(100,100,0,0,0,0)], robust = True) # 使用线性回归方法,反馈得到一条直线 if h==0 or h==3: aim_width= 60 # 目标位置的偏移距离,距离目标线较近的路线上 aim_theta= 0 elif h==1 or h==2: aim_width= 23 # 目标位置的偏移距离,距离目标线较远的线路上 aim_theta= 5 else: aim_width= 0 aim_theta = 0 if (line and m==0): if line.theta()>90: # 直线的角度 theta_err = line.theta()-180 else: theta_err = line.theta() img.draw_line(line.line(), color = 127) # line.line()返回一个直线元组(x1, y1, x2, y2) rho_err = abs(line.rho())-aim_width # line.rho()返回直线p值;计算直线与目标位置的偏移距离 aimtheta_dif= theta_err - aim_theta #与目标角度的角度差 print("行驶路线标号:",h,rho_err,aimtheta_dif) #输出行驶路线标号:(0:最左;1:二左;2:二左;3:最右),偏移距离,偏移角度 if h==0 or h==3: rho_err_min = 3 # 设定近距离范围 rho_err_max1 = 4 # 向左最大偏移距离 rho_err_max2 = -4 # 向右最大偏移距离 rho_err_maxx1 = 6 # 向左急转偏移距离 rho_err_maxx2 = -6 # 向右急转偏移距离 elif h==1 or h==2: rho_err_min = 2 # 设定近距离范围 rho_err_max1 = 3 # 向左最大偏移距离 rho_err_max2 = -3 # 向右最大偏移距离 rho_err_maxx1 = 5 # 向左急转偏移距离 rho_err_maxx2 = -5 # 向右急转偏移距离 else: rho_err_min = 0 # 设定近距离范围 rho_err_max1 = 0 # 向左最大偏移距离 rho_err_max2 = 0 # 向右最大偏移距离 rho_err_maxx1 = 0 # 向左急转偏移距离 rho_err_maxx2 = 0 # 向右急转偏移距离 if abs(rho_err) <= rho_err_min and abs(aimtheta_dif) >=4: if a==0: # a=0没有调向其他子程序 theta_err_mid=(theta_err + aim_theta)/2 # 实际角度与目标角度的中间值,用作动作回位参考 if theta_err> aim_theta: a=1 # a=1近距离方向左偏,调用右转程序 elif theta_err< aim_theta: a=2 # a=2近距离方向右偏,调用左转程序 elif rho_err > rho_err_max1 and rho_err < rho_err_maxx1 and aimtheta_dif >= -4: # 在目标线路左侧,角度偏移大于-4,呈远离趋势,调用右转程序 if a==0: theta_err_mid=(theta_err + aim_theta-12)/2 # 目标角度-12度 a=1 elif rho_err < rho_err_max2 and rho_err > rho_err_maxx2 and aimtheta_dif <= 4: # 在目标线路右侧,角度偏移小于4,呈远离趋势,调用左转程序 if a==0: theta_err_mid=(theta_err + aim_theta+12)/2 # 目标角度12度 a=2 elif rho_err >= rho_err_maxx1 and aimtheta_dif >= -15: # 在目标线路左侧极限距离外,右转,靠近中心线 if a==0: theta_err_mid=(theta_err + aim_theta-20)/2 # 目标角度为-20 a=1 elif rho_err <= rho_err_maxx2 and aimtheta_dif <= 15: # 在目标线路右侧极限距离外,左转,靠近中心线 if a==0: theta_err_mid=(theta_err + aim_theta+20)/2 # 目标角度为20 a=2 if(a==1): # 右转子程序------------------------------------ if theta_err >theta_err_mid: ain1.low() # 伸出左转 ain0.high() # 收回右转 elif (theta_err <=theta_err_mid): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 收回右转 ain0.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 a=0 else: ain0.low() ain1.low() if(a==2): # 左转子程序------------------------------------ if theta_err <theta_err_mid: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif (theta_err >=theta_err_mid): if pin7_in.value()==False and pin9_in.value()==False: ain1.low() # 收回右转 ain0.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==True: ain0.low() # 收回右转 ain1.high() # 伸出左转 elif pin7_in.value()==True and pin9_in.value()==False: ain0.low() # 收回右转 ain1.low() # 伸出左转 a=0 else: ain0.low() ain1.low()
-
应该是自动垃圾回收对你的代码可能有问题。
可以设置自动垃圾回收来解决,以下两个方案选一个就可以。你试一下应该可以解决。
1,设置阈值
在最开始import gc gc.threshold(10000)
对于OpenMV3可以设置为10000
如果是OpenMV4可以设置为1000002,在死循环里调用gc.collect()手动处罚垃圾回收。
PS:可以通过gc.mem_free()来查看还有多少内存可以用,正常来说,自动垃圾回收是可以用的。
-
@kidswong999 实验了一下,两种方案都用上,还是会弹错误窗口,格式化硬件后,错误弹出来的比较慢,但是一旦出现过一次错误,第二次错误很快就出来了
-
@3sop 你用的是OpenMV3还是OpenMV4.
-
@kidswong999 OpenMV3