import RPi.GPIO as GPIO
import time
# 定義超音波感測器的引腳
TRIG = 20
ECHO = 21
# 定義馬達控制引腳
PWM_R = 18  # 右輪馬達 PWM
DIR1_R = 23  # 右輪方向 1
DIR2_R = 24  # 右輪方向 2
PWM_L = 13  # 左輪馬達 PWM
DIR1_L = 5  # 左輪方向 1
DIR2_L = 6  # 左輪方向 2
# 初始化 GPIO 設置
GPIO.setmode(GPIO.BCM)
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
GPIO.setup(PWM_R, GPIO.OUT)
GPIO.setup(DIR1_R, GPIO.OUT)
GPIO.setup(DIR2_R, GPIO.OUT)
GPIO.setup(PWM_L, GPIO.OUT)
GPIO.setup(DIR1_L, GPIO.OUT)
GPIO.setup(DIR2_L, GPIO.OUT)
# 初始化 PWM
pwm_right = GPIO.PWM(PWM_R, 1000)  # 右輪 PWM 設置為 1000Hz
pwm_left = GPIO.PWM(PWM_L, 1000)   # 左輪 PWM 設置為 1000Hz
pwm_right.start(0)  # 開始時關閉馬達
pwm_left.start(0)
# 設置馬達的方向
def set_motor_direction(motor, forward=True):
    if motor == 'right':
        GPIO.output(DIR1_R, GPIO.HIGH if forward else GPIO.LOW)
        GPIO.output(DIR2_R, GPIO.LOW if forward else GPIO.HIGH)
    elif motor == 'left':
        GPIO.output(DIR1_L, GPIO.HIGH if forward else GPIO.LOW)
        GPIO.output(DIR2_L, GPIO.LOW if forward else GPIO.HIGH)
# 設置馬達的速度
def set_motor_speed(motor, speed):
    if motor == 'right':
        pwm_right.ChangeDutyCycle(speed)
    elif motor == 'left':
        pwm_left.ChangeDutyCycle(speed)
# 停止馬達
def stop_motors():
    pwm_right.ChangeDutyCycle(0)
    pwm_left.ChangeDutyCycle(0)
# 使用超音波感測器檢測距離
def get_distance():
    # 發送超音波信號
    GPIO.output(TRIG, True)
    time.sleep(0.00001)
    GPIO.output(TRIG, False)
    # 計時回波信號
    while GPIO.input(ECHO) == 0:
        pulse_start = time.time()
    while GPIO.input(ECHO) == 1:
        pulse_end = time.time()
    # 計算距離
    pulse_duration = pulse_end - pulse_start
    distance = pulse_duration * 17150  # 乘以聲音速度的係數,單位為 cm
    distance = round(distance, 2)
    return distance
# 主程序邏輯
try:
    while True:
        # 取得障礙物的距離
        distance = get_distance()
        print(f"距離障礙物: {distance} cm")
        if distance < 30:
            # 若距離小於 30 cm,停止並向後移動
            print("障礙物太近,倒車中...")
            set_motor_direction('right', forward=False)
            set_motor_direction('left', forward=False)
            set_motor_speed('right', 50)
            set_motor_speed('left', 50)
            time.sleep(2)
            stop_motors()
            # 嘗試轉向避開障礙物
            print("左轉避開障礙物")
            set_motor_direction('right', forward=True)
            set_motor_direction('left', forward=False)
            set_motor_speed('right', 50)
            set_motor_speed('left', 50)
            time.sleep(1.5)
            stop_motors()
        else:
            # 若距離足夠,繼續前進
            print("路徑清楚,繼續前進...")
            set_motor_direction('right', forward=True)
            set_motor_direction('left', forward=True)
            set_motor_speed('right', 60)
            set_motor_speed('left', 60)
        time.sleep(0.1)
except KeyboardInterrupt:
    print("停止自動駕駛程序")
    stop_motors()
    GPIO.cleanup()