Сервоприводы не будут отслеживать лицо из-за того, что застряли в другой функции - PullRequest
0 голосов
/ 18 января 2020

Мой код прост, когда Serial.available () равен 0, что означает, что данные не поступают, выполните функцию что-то () . Но когда Serial.read () получает любой другой номер, это означает, что лицо обнаружено, и оно должно прекратить выполнение функции что-то () и запустить отслеживание лица, выполнить функцию track ().

Когда я запускаю код, и камера не обнаруживает лица, она делает, как я хочу, сервопривод вращается взад и вперед. Но как только он обнаруживает лицо, сервопривод игнорирует движение с лицом и продолжает запускать функцию что-то () .

Как заставить его просто следовать за моим лицом, когда обнаруживается, а затем go возвращается к повороту назад и вперед, когда лицо не обнаружено. если я избавлюсь от функции что-то () , код будет работать нормально, и сервоприводы будут перемещаться относительно положения моего лица. Но когда я добавляю в функцию что-то () , она не покидает эту функцию, даже если лицо обнаружено, если оно обнаружено.

*. Ino

#include <Servo.h> 

Servo servoVer; //Vertical Servo
Servo servoHor; //Horizontal Servo
int x;
int y;
int prevX;
int prevY;
int pos = 0;


void setup()
{
  Serial.begin(9600);
  servoVer.attach(5); //Attach Vertical Servo to Pin 5
  servoHor.attach(6); //Attach Horizontal Servo to Pin 6
  servoVer.write(90);
  servoHor.write(90);
} 

void Pos()
{
  if (prevX != x || prevY != y)
  {
    int servoX = map(x, 450, 0, 0, 180);
    int servoY = map(y, 450, 0, 180, 0);
    servoX = min(servoX, 180);
    servoX = max(servoX, 0);
    servoY = min(servoY, 180);
    servoY = max(servoY, 0);
    servoHor.write(servoX);
    servoVer.write(servoY);
  }
}

void something(){
   for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    servoHor.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  }
}

void track(){
    if(Serial.available() > 0);
    {
      if (Serial.read() == 'X')
      {
        x = Serial.parseInt();
        if (Serial.read() == 'Y')
        {
          y = Serial.parseInt();
          Pos();
        }
      }
      while (Serial.available() > 0)
      {
        Serial.read();
      }
    }
  }

void loop()
{
  if ( ! Serial.available() ) 
  {
    something();
  }
  else
  {
    track();
  }
}





*. py

import numpy as np
import serial
import time
import sys
import cv2

arduino = serial.Serial('COM5', 9600)
time.sleep(2)
print("Connection to arduino...")


face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)

while 1:
    ret, img = cap.read()
    img = cv2.flip(img,1)
    cv2.resizeWindow('img', 500,500)
    cv2.line(img,(500,250),(0,250),(0,255,0),1)
    cv2.line(img,(250,0),(250,500),(0,255,0),1)
    cv2.circle(img, (250, 250), 5, (255, 255, 255), -1)
    gray  = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3)

    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),5)
        roi_gray  = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]

        arr = {y:y+h, x:x+w}
        print (arr)

        print ('X :' +str(x))
        print ('Y :'+str(y))
        print ('x+w :' +str(x+w))
        print ('y+h :' +str(y+h))

        xx = int((x+(x+h))/2)
        yy = int((y+(y+w))/2)

        print (xx)
        print (yy)

        center = (xx,yy)

        print("Center of Rectangle is :", center)
        data = "X{0:d}Y{1:d}Z".format(xx, yy)
        print ("output = '" +data+ "'")
        # arduino.write(data)
        arduino.write(data.encode())

    cv2.imshow('img',img)

    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

1 Ответ

1 голос
/ 19 января 2020

Я вижу несколько проблем с вашим кодом.

  1. Он всегда вернется к something(), потому что ваш код Arduino работает быстрее, чем ваш python код, поэтому ваш Arduino проверяет наличие Serial.available() чаще, чем код python, может выводить новый символ. Поэтому, когда он не увидит новый символ в буфере, он вернется к something(). Попытайтесь добавить небольшую задержку в функцию track() в конце, чтобы преодолеть это.

  2. Вы никогда не обновите prevX и prevY, поэтому if (prevX != x || prevY != y) выполняется каждый раз , Также эта часть servoX = min(servoX, 180); servoX = max(servoX, 0); servoY = min(servoY, 180); servoY = max(servoY, 0);

    на самом деле ничего не делает, она всегда будет выводить исходное значение serveoX и servoY

Но узнайте, как долго выполнение кода python и добавление задержки немного дольше, чем в функции track().

...