Final Lab de Control
Código para detectar carril y control de carro autonomounknown
python
3 years ago
7.2 kB
7
Indexable
# OpenCV program to perform Edge detection in real time by Jonathan Gaona
# Proyecto Final Lab de Control
# import libraries of python OpenCV
import cv2
import RPi.GPIO as GPIO
import numpy as np
import time
from time import sleep
prev_frame_time=0
new_frame_time=0
in1 = 26 #Puente H entradas de control
in2 = 19
enA = 11
in4 = 13
in3 = 6
enB = 5
GPIO.setmode(GPIO.BCM)
GPIO.setup(in1,GPIO.OUT) #inicializacion de las salidas
GPIO.setup(in2,GPIO.OUT)
GPIO.setup(enA,GPIO.OUT)
GPIO.setup(in3,GPIO.OUT)
GPIO.setup(in4,GPIO.OUT)
GPIO.setup(enB,GPIO.OUT)
GPIO.output(in1,GPIO.LOW)
GPIO.output(in2,GPIO.LOW)
GPIO.output(in3,GPIO.LOW)
GPIO.output(in4,GPIO.LOW)
p=GPIO.PWM(enA,1000)
p2=GPIO.PWM(enB,1000)
p.start(36)
p2.start(36)
#FUNCIONES para encontrar el centro entre las lineas de Hough
def findCenter(p1,p2):
center = ((p1[0] + p2[0]) // 2, (p1[1] + p2[1]) // 2)
return center
def minmax_centerPoints(tergetList,pos):
if len(tergetList) > 0:
maximum = max(tergetList, key = lambda i: i[pos])
minimum = min(tergetList, key = lambda i: i[pos])
return [maximum,minimum]
else:
return None
#Funcion principal del procesamiento de imagen
def detectedlane(imageFrame):
center1= 0
center2 = 0
cv2.imshow('Original',imageFrame) #mostrar imagen original
width,height = 360,180
pts1 = [[0,160],[320,240],[300,30],[20,20]]
pts2 = [[0, height], [width, height],[width,0], [0,0]]
target = np.float32(pts1)
destination = np.float32(pts2)
#Algoritmo de transformacion de perspectiva
matrix = cv2.getPerspectiveTransform(target, destination)
result = cv2.warpPerspective(frame, matrix, (width,height))
cv2.imshow('Perspectiva', result) #mostrar ajuste de perspectiva
gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY) #cambiar a blanco y negro
threshold = cv2.inRange(gray, 190,300 )#metodo de umbralizacion
cv2.imshow('Blanco y Negro',gray) #mostrar imagen blanco y negro
cv2.imshow('Threshold',threshold) #mostrar imagen threshold
#creacion de la linea horizontal roja de la perspectiva
firstSquareCenters1 = findCenter((pts2[1][0], pts2[1][1]), (pts2[2][0], pts2[2][1]))
firstSquareCenters2 = findCenter((pts2[3][0], pts2[3][1]), (pts2[0][0], pts2[0][1]))
cv2.line(result, firstSquareCenters1, firstSquareCenters2, (0, 0, 255), 1)
mainFrameCenter = findCenter(firstSquareCenters1,firstSquareCenters2)
#Metodo de lineas de Hough
lines = cv2.HoughLinesP(threshold, 1, np.pi/180, 90,minLineLength=50, maxLineGap=450)
centerPoints = []
left = []
right = []
if lines is not None:
for line in lines:
x1,y1,x2,y2 = line[0]
cv2.line(result, (x1, y1), (x2, y2), (0, 255, 0), 5)
if 0<=x1 <=width and 0<= x2 <=width :
center = findCenter((x1,y1),(x2,y2))
if center[0] < (width//2):
center1 = center
left.append((x1, y1))
left.append((x2,y2))
else:
center2 = center
right.append((x1, y1))
right.append((x2,y2))
if center1 !=0 and center2 !=0:
centroid1 = findCenter(center1,center2)
centerPoints.append(centroid1)
centers = minmax_centerPoints(centerPoints,1)
laneCenters = 0
mainCenterPosition = 0
if centers is not None:
laneframeCenter = findCenter(centers[0],centers[1])
#print(mainFrameCenter,laneframeCenter)
mainCenterPosition = mainFrameCenter[0] - laneframeCenter[0]
laneCenters = centers
return[laneCenters,result,mainCenterPosition]
# Capturar video de la camara
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH,320) # set the width to 320 p
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,240) # set the height to 240 p
#Variables para controlar
maincenter=0
kp = 1.35
kd = 0.025
ki = 0.02
kp2 = 1.35
kd2 = 0.025
ki2 = 0.02
e1prev=0
e2prev=0
e1sum=0
e2sum=0
pwm=0
pwm2=0
fps=0
# loop runs if capturing has been initialized
while(1):
# reads frames from a camera
ret, frame = cap.read()
if ret == True:
# Se llama la funcion de procesamiento de imagen
laneimage1 = detectedlane(frame)
if laneimage1 is not None:
maincenter = laneimage1[2]
lcenter=laneimage1[0]
cv2.putText(laneimage1[1],"Pos="+str(maincenter),(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255))
cv2.putText(laneimage1[1],"Fps="+str(fps),(290, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255))
cv2.imshow('FinalWindow',laneimage1[1]) #mostrar imagen final
else:
cv2.imshow('FinalWindow', frame)
#limites de velocidad
limit1=64
limit2=-64
#error (angulo)
error=maincenter
error2=maincenter
#incrementar el limite de velocidad
if error>25:
limit1=70
elif error>40:
limit1=75
if error2<-23:
limit2=-70
elif error2<-40:
limit2=-75
#Controlador PID
pwm += (error * kp) + (e1prev*kd)+(e1sum*ki)
if pwm>=limit1:
pwm=limit1
elif pwm<0:
pwm=10
#PID 2
pwm2 += (error2 * kp2) + (e2prev*kd2)+(e2sum*ki2)
if pwm2<=limit2:
pwm2=limit2
elif pwm2>-10:
pwm2=-10
#Se mantiene un margen donde se considera que va en la
# trayectoria correcta
if maincenter <=6 and maincenter >= -6:
#print("Sigue Derecho")
GPIO.output(in1,GPIO.HIGH)
GPIO.output(in2,GPIO.LOW)
GPIO.output(in3,GPIO.HIGH)
GPIO.output(in4,GPIO.LOW)
p.ChangeDutyCycle(37)
p2.ChangeDutyCycle(37)
elif maincenter >6:
p.ChangeDutyCycle(int(abs(pwm2)))
p2.ChangeDutyCycle(int(abs(pwm)))
#A Lazo cerrado solo se usa la velocidad fija
#p.ChangeDutyCycle(10)
#p2.ChangeDutyCycle(limit1)
else:
p.ChangeDutyCycle(int(abs(pwm2)))
p2.ChangeDutyCycle(int(abs(pwm)))
#p.ChangeDutyCycle(abs(limit2))
#p2.ChangeDutyCycle(10)
#Variables para el controlador
e1prev=error
e2prev=error
e1sum += error
e2sum += error
#calculo de fps
new_frame_time=time.time()
fps=1/(new_frame_time-prev_frame_time)
prev_frame_time=new_frame_time
fps=int(fps)
# al presionar tecla ESC se termina el programa
k = cv2.waitKey(5) & 0xFF
if k == 27:
GPIO.cleanup()
break
# Close the window
cap.release()
# De-allocate any associated memory usage
cv2.destroyAllWindows()Editor is loading...