问题描述
我正在遵循此tutorial,并添加了扫描程序。一旦检测到对象,扫描循环就会中断,并从教程恢复为跟踪模式。问题在于,跟踪模式的默认位置是激活时的默认位置,该位置通常不在扫描过程中对象所在的FOV范围内。
伺服角由PID控制器更新。因此,我需要找到一种方法来将初始值设置为在激活跟踪模式之前扫描与伺服之间的最后角度,然后从PID控制器进行更新以跟踪对象。我从教程资料库中处理的主要文档是manager.py:
import logging
from multiprocessing import Value,Process,Manager,Queue
import pantilthat as pth
import signal
import sys
import time
import RPi.GPIO as GPIO
from rpi_deep_pantilt.detect.util.visualization import visualize_Boxes_and_labels_on_image_array
from rpi_deep_pantilt.detect.camera import run_pantilt_detect
from rpi_deep_pantilt.control.pid import PIDController
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(8,GPIO.OUT)
logging.basicConfig()
LOGLEVEL = logging.getLogger().getEffectiveLevel()
RESOLUTION = (320,320)
SERVO_MIN = -90
SERVO_MAX = 90
CENTER = (
RESOLUTION[0] // 2,RESOLUTION[1] // 2
)
# function to handle keyboard interrupt
def signal_handler(sig,frame):
# print a status message
print("[INFO] You pressed `ctrl + c`! Exiting...")
# disable the servos
pth.servo_enable(1,False)
pth.servo_enable(2,False)
GPIO.output(8,GPIO.LOW)
# exit
sys.exit()
def in_range(val,start,end):
# determine the input value is in the supplied range
return (val >= start and val <= end)
def set_servos(pan,tilt,scan):
# signal trap to handle keyboard interrupt
signal.signal(signal.SIGINT,signal_handler)
pn = 90
tt = 25
while scan.value == 't':
print('Scanning')
pth.pan(pn)
pth.tilt(tt)
pn = pn-1
if pn <= -90:
pn = 90
time.sleep(0.1)
continue
pan.value = -1*pn
tilt.value = tt
g=0
while True:
# if g<1:
# pan.value = -1*pn
# tilt.value = tt
pan_angle = -1 * pan.value
tilt_angle = tilt.value
if g<6:
print(pan_angle)
print(tilt_angle)
g=g+1
# if the pan angle is within the range,pan
if in_range(pan_angle,SERVO_MIN,SERVO_MAX):
pth.pan(pan_angle)
else:
logging.info(f'pan_angle not in range {pan_angle}')
if in_range(tilt_angle,SERVO_MAX):
pth.tilt(tilt_angle)
else:
logging.info(f'tilt_angle not in range {tilt_angle}')
def pid_process(output,p,i,d,Box_coord,origin_coord,action):
# signal trap to handle keyboard interrupt
signal.signal(signal.SIGINT,signal_handler)
# create a PID and initialize it
p = PIDController(p.value,i.value,d.value)
p.reset()
# loop indefinitely
while True:
error = origin_coord - Box_coord.value
output.value = p.update(error)
# logging.info(f'{action} error {error} angle: {output.value}')
def pantilt_process_manager(
model_cls,labels=('Raspi',),rotation=0
):
pth.servo_enable(1,True)
pth.servo_enable(2,True)
with Manager() as manager:
scan = manager.Value('c','t')
# set initial bounding Box (x,y)-coordinates to center of frame
center_x = manager.Value('i',0)
center_y = manager.Value('i',0)
center_x.value = RESOLUTION[0] // 2
center_y.value = RESOLUTION[1] // 2
# pan and tilt angles updated by independent PID processes
pan = manager.Value('i',0)
tilt = manager.Value('i',0)
# PID gains for panning
pan_p = manager.Value('f',0.05)
# 0 time integral gain until inferencing is faster than ~50ms
pan_i = manager.Value('f',0.1)
pan_d = manager.Value('f',0)
# PID gains for tilting
tilt_p = manager.Value('f',0.15)
# 0 time integral gain until inferencing is faster than ~50ms
tilt_i = manager.Value('f',0.2)
tilt_d = manager.Value('f',0)
detect_processr = Process(target=run_pantilt_detect,args=(center_x,center_y,labels,model_cls,rotation,scan))
pan_process = Process(target=pid_process,args=(pan,pan_p,pan_i,pan_d,center_x,CENTER[0],'pan'))
tilt_process = Process(target=pid_process,args=(tilt,tilt_p,tilt_i,tilt_d,CENTER[1],'tilt'))
servo_process = Process(target=set_servos,scan))
detect_processr.start()
pan_process.start()
tilt_process.start()
servo_process.start()
detect_processr.join()
pan_process.join()
tilt_process.join()
servo_process.join()
if __name__ == '__main__':
pantilt_process_manager()
我在set_servos函数中添加了代码以显示我要完成的工作。但是,它不起作用,因为一旦伺服器移至最后一个扫描位置,就会出现以下循环,它们将恢复为默认的初始pan.value / tilt.value角度,通常角度约为-10deg。平移,倾斜10度。
这是我运行该脚本时的终端脚本,它在5度(水平)和25度(倾斜)处检测到该对象:
$ rpi-deep-pantilt track Raspi
Scanning
Scanning
Scanning
Scanning
Scanning
Scanning
Object Detected
5
25
5
25
5
12.55306363105774
-0.28837611675262453
12.55306363105774
-0.28837611675262453
12.55306363105774
-0.28837611675262453
12.656980562210084
Object Detected
^C[INFO] You pressed `ctrl + c`! Exiting...
这是PID脚本,对我来说这很乱:
# import necessary packages
import time
class PIDController:
def __init__(self,kP=1,kI=0,kD=0):
# initialize gains
self.kP = kP
self.kI = kI
self.kD = kD
def reset(self):
# intialize the current and prevIoUs time
self.time_curr = time.time()
self.time_prev = self.time_curr
# initialize the prevIoUs error
self.error_prev = 0
# initialize the term result variables
self.cP = 0
self.cI = 0
self.cD = 0
def update(self,error,sleep=0.01):
time.sleep(sleep)
# grab the current time and calculate delta time / error
self.time_curr = time.time()
time_delta = self.time_curr - self.time_prev
error_delta = error - self.error_prev
# proportional term
self.cP = error
# integral term
self.cI += error * time_delta
# derivative term and prevent divide by zero
self.cD = (error_delta / time_delta) if time_delta > 0 else 0
# save prevIoUs time and error for the next update
self.time_prev = self.time_curr
self.error_prev = error
# sum the terms and return
return sum([
self.kP * self.cP,self.kI * self.cI,self.kD * self.cD]
)
有趣的一点是,一旦物体被跟踪并被相机遗失,它就不会恢复到任何位置,它会一直停留在原来的位置,直到再次检测到为止。因此,我不明白为什么传递初始p / t值时,直到再次拾取物体之前,它都不会停留在该位置。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)