Raspi Servo 抖动并在它应该静止的时候来回移动

问题描述

(抱歉格式化) 我正在尝试编写一个 opencv 程序来跟踪红色。 到目前为止它工作正常,但伺服是抖动的,当物体静止并居中时,伺服来回移动。我有一个 470uf 的电容器和一个外部电源。任何让它更顺畅的帮助都是天赐之物!

'''

from picamera.array import PiRGBArray 
from picamera import PiCamera
import time 
import cv2
import numpy as np
import RPi.GPIO as GPIO
import time


###SERVO SETUP###
servoPIN_x = 17
servoPIN_y = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(servoPIN_x,GPIO.OUT)
GPIO.setup(servoPIN_y,GPIO.OUT)
px = GPIO.PWM(servoPIN_x,50)
py = GPIO.PWM(servoPIN_y,50)
position_x = 7.5
position_y = 7.5
px.start(position_x)
py.start(position_y)

x_gain = 0.1#0.01 - 5.00
y_gain = 0.3#0.01 - 5.00

xon = True
yon = True

###CAMERA SETUP##
camera = PiCamera()
camera.resolution = (640,480)
camera.framerate = 32
raw_capture = PiRGBArray(camera,size=(640,480))
time.sleep(0.1)


###VIDEO CAPTURE LOOP### 
for frame in camera.capture_continuous(raw_capture,format="bgr",use_video_port=True):
    #cv2 video init
    image = frame.array
    hsv_frame = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
#color parameters
low_red = np.array([161,155,84])
high_red = np.array([179,255,255])

#find color
red_mask = cv2.inRange(hsv_frame,low_red,high_red)#create black/white mask for all reds
contours,_ = cv2.findContours(red_mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#find different red contours
contours = sorted(contours,key=lambda x:cv2.contourArea(x),reverse=True)#sort contours from largest to smallest

#set line x/y var to center
x_medium=320
y_medium=240

#loop sets x/y_medium
for cnt in contours:
    (x,y,w,h) = cv2.boundingRect(cnt)
    y_medium = int((y+y+h)/2)
    x_medium = int((x+x+w)/2)
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,0),2)
    break

#draw lines
cv2.line(image,(x_medium,480),2)
cv2.line(image,y_medium),(640,2)

#cv2.imshow('mask',red_mask)
#show regular frame
cv2.imshow("Frame",image)
key = cv2.waitKey(1) & 0xFF
raw_capture.truncate(0)

#quit 
if key == ord("q"):
    cv2.waitKey(1)
    px.stop()
    py.stop
    break



#servoX travels to place postion_x in center frame
if not xon and x_medium != 320:
    px.start(position_x)


if x_medium > 320:
    position_x = position_x - x_gain
    
elif x_medium < 320:
    position_x = position_x + x_gain
elif x_medium == 320:
    position_x = position_x
    xon = False
else:
    position_x = 7.5
    
if xon:
    px.ChangeDutyCycle(position_x)
else:
    px.stop



px.stop()
py.stop()
cv2.destroyAllWindows()
exit(0)

'''

解决方法

我在构建机器人时遇到了与这种伺服电机相同的问题。我使用另一个名为“pigpio”的库解决了这个问题,以控制 rasperry pi 的引脚。从那以后,伺服系统不再无缘无故地移动。命令非常相似。看看:

http://abyz.me.uk/rpi/pigpio/