Tracking

import cv2
import numpy as np
import math
import time
#import serial


uart_baud = 115200
#ser = serial.Serial("/dev/ttyUSB0", uart_baud)


black_min=(0,43,46)
black_max=(10,255,255)
angle_exp=0
distance_exp=0

#get the mid line of the track
def liner(img,result):
    # print(img)
    n=[len(img[:,0]),len(img[0,:])]
    # print(n,'n')
    (x_point,y_point)=np.nonzero(img)
    if len(x_point)<2:
        return 0
    f1 = np.polyfit(x_point, y_point,1)
    p1 = np.poly1d(f1)
    point1=(int(p1(0)),0)
    point2=(int(p1(n[0])),n[0])
    #print(point2,point1)
    #print((int(n[1]/2),0) , (int(n[1]/2),n[0]))
    cv2.line(result, (int(n[1]/2),0) , (int(n[1]/2),n[0]), (0, 0, 255),2)
    cv2.line(result,point1,point2,(0,255,0),2)
    
    
    cv2.imshow('inside',result)
    #print(math.atan(f1[0])*180/math.pi)
    #print([n[1]/2-p1(n[0]),f1[1]],'ret')
    angle_now=math.atan(f1[0])*180/math.pi # i'm not sure, maybe i should add a -...
    distance_now = n[1]/2-p1(n[0]) # the same as upper
    return [distance_now,angle_now]

#PID control
class Pid():

    def __init__(self, exp_val, now_val,kp,kd):
        self.KP = kp
        self.KD = kd
        self.exp_val = exp_val
        self.now_val = now_val
        #self.sum_err = 0
        self.now_err = 0
        self.last_err = 0

    def cmd_pid(self):
        self.last_err = self.now_err
        self.now_err = self.exp_val - self.now_val
        #self.sum_err += self.now_err

        self.now_val = self.KP * (self.exp_val - self.now_val) + self.KD * (self.now_err - self.last_err)
        return self.now_val


def int_transform_4hex(str_list_16nums):
    str_list_16nums=list(str_list_16nums)
    
    if len(str_list_16nums) == 4:
        
        str_list_16nums.insert(2, ' ')
        
    elif len(str_list_16nums) == 3:
        
        str_list_16nums.insert(0, '0')
        str_list_16nums.insert(2, ' ')
    elif len(str_list_16nums) == 2:
        
        str_list_16nums.insert(0, '0')
        str_list_16nums.insert(0, '0')
        str_list_16nums.insert(2, ' ')  
    elif len(str_list_16nums) == 1:
        str_list_16nums.insert(0, '0')        
        str_list_16nums.insert(0, '0')
        str_list_16nums.insert(0, '0')
        str_list_16nums.insert(2, ' ')   
    else:
        pass
    str_list_16nums = ''.join(str_list_16nums)
    
    return str_list_16nums.upper()

def trans(adjust_speed,rotate_speed):
    upper=65535
    direction_adjust='00'
    direction_rotate='00'
    adjust_speed=int(adjust_speed/0.001)
    rotate_speed=int(rotate_speed/0.01)
    if adjust_speed>0:
       direction_adjust = '01'  # to judge the direction , if not right please add a -
    if rotate_speed>0:
       direction_rotate ='01'
    adjust_speed=abs(adjust_speed)
    rotate_speed=abs(rotate_speed)
    if adjust_speed>upper:
       adjust_speed=upper
    if rotate_speed>upper:
       rotate_speed=upper
    adjust_trans=hex(adjust_speed).replace('0x','')
    rotate_trans=hex(rotate_speed).replace('0x','')
    adjust_trans=int_transform_4hex(adjust_trans)
    rotate_trans=int_transform_4hex(rotate_trans)
    #print(adjust_trans,rotate_trans)
    control_cmd='CD 0A 01 00 03 20'+' '+direction_adjust+' '+adjust_trans+' '+direction_rotate+' '+rotate_trans+' 3A'
    #print(control_cmd)
    return control_cmd
    

#main func

if __name__ == '__main__':
    cap = cv2.VideoCapture(0)  
    while True:  
        ret, frame = cap.read()  
        grid_RGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
        grid_HSV = cv2.cvtColor(grid_RGB, cv2.COLOR_RGB2HSV)
 
        lower1 = np.array([0,43,46])
        upper1 = np.array([10,255,255])
        mask1 = cv2.inRange(grid_HSV, lower1, upper1)      
        res1 = cv2.bitwise_and(grid_RGB, grid_RGB, mask=mask1)

        lower2 = np.array([156,43,46])
        upper2 = np.array([180,255,255])
        mask2 = cv2.inRange(grid_HSV, lower2, upper2)
        res2 = cv2.bitwise_and(grid_RGB,grid_RGB, mask=mask2)
 
        mask = mask1 + mask2
        #mask=cv2.inRange(frame,black_min,black_max)
        kernel=np.ones((3,3),np.uint8)
        erode=cv2.morphologyEx(mask,cv2.MORPH_ERODE,kernel)
        #cv2.imshow('mask', mask)
        #cv2.imshow('erode', erode)
        
        cv2.imshow('frame', frame)
        c = cv2.waitKey(1)
        control_val=liner(mask,frame)#calculate angle and distance
        #no.1 is dis while no.2 is angle

        adjust_speed=Pid(distance_exp,control_val[0],0.1,0.15)# expected transverse v to adjust distance , here to adjust
        rotate_speed=Pid(angle_exp,control_val[1],0.1,0.15)# expected rotate to adjust angle , here to adjust
        control_cmd=trans(adjust_speed.now_val,rotate_speed.now_val)
        d=bytes.fromhex(control_cmd)
        print(d)
        ser.flushInput()
        ############serial has not sent control_cmd yet


        time.sleep(0.05)#control period 50ms  
        if c == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值