diff --git a/main/camera.py b/main/camera.py new file mode 100644 index 0000000..16893ca --- /dev/null +++ b/main/camera.py @@ -0,0 +1,63 @@ +import cv2 +import numpy as np + +cap = cv2.VideoCapture(0) + +cap.set(3, 320) +cap.set(4, 240) +cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) + +ret, prev_frame = cap.read() +prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY) +prev_gray = cv2.GaussianBlur(prev_gray, (5,5), 0) + +while True: + ret, frame = cap.read() + if not ret: + break + + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + gray = cv2.GaussianBlur(gray, (5,5), 0) + + # 帧差 + diff = cv2.absdiff(prev_gray, gray) + diff = cv2.convertScaleAbs(diff, alpha=2.5) + + _, thresh = cv2.threshold(diff, 20, 255, cv2.THRESH_BINARY) + + contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + + # ===== 核心:选最大目标 ===== + target = None + max_area = 0 + + for cnt in contours: + area = cv2.contourArea(cnt) + + if area < 300: # 过滤噪声 + continue + + if area > max_area: + max_area = area + target = cnt + + # ===== 只处理一个目标 ===== + if target is not None: + x, y, w, h = cv2.boundingRect(target) + cx = x + w // 2 + cy = y + h // 2 + + cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) + cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1) + + print("唯一目标:", cx, cy, "area:", max_area) + + cv2.imshow("tracking", frame) + + prev_gray = gray.copy() + + if cv2.waitKey(1) & 0xFF == 27: + break + +cap.release() +cv2.destroyAllWindows() \ No newline at end of file diff --git a/main/motor.py b/main/motor.py new file mode 100644 index 0000000..c64f73d --- /dev/null +++ b/main/motor.py @@ -0,0 +1,104 @@ +from smbus2 import SMBus +import time + +bus = SMBus(1) +addr = 0x60 + +# ====================== +# PCA9685 初始化 +# ====================== +bus.write_byte_data(addr, 0x00, 0x00) +bus.write_byte_data(addr, 0xFE, 60) + +# ====================== +# PWM输出(0~4095) +# ====================== +def set_pwm(ch, val): + val = max(0, min(4095, val)) + base = 0x06 + 4 * ch + bus.write_byte_data(addr, base, 0) + bus.write_byte_data(addr, base+1, 0) + bus.write_byte_data(addr, base+2, val & 0xFF) + bus.write_byte_data(addr, base+3, val >> 8) + +# ====================== +# ⭐ 你的真实映射(8通道版本) +# ====================== +MOTORS = { + "M1": {"in1": 0, "in2": 1}, + "M2": {"in1": 2, "in2": 3}, + "M3": {"in1": 4, "in2": 5}, + "M4": {"in1": 6, "in2": 7}, +} + +# ====================== +# 电机控制(重点) +# ====================== +def motor(name, speed=0, direction="stop"): + m = MOTORS[name] + + # 速度限制 + speed = max(0, min(4095, speed)) + + if direction == "f": + set_pwm(m["in1"], speed) + set_pwm(m["in2"], 0) + + elif direction == "b": + set_pwm(m["in1"], 0) + set_pwm(m["in2"], speed) + + else: + set_pwm(m["in1"], 0) + set_pwm(m["in2"], 0) + +# ====================== +# 四轮控制 +# ====================== +def all_motors(speed, direction): + for m in MOTORS: + motor(m, speed, direction) + +def forward(speed=3500): + all_motors(speed, "f") + +def backward(speed=3500): + all_motors(speed, "b") + +def stop(): + all_motors(0, "stop") + +# ====================== +# 转向(差速) +# ====================== +def turn_left(speed=3500): + motor("M1", speed, "b") + motor("M3", speed, "b") + motor("M2", speed, "f") + motor("M4", speed, "f") + +def turn_right(speed=3500): + motor("M1", speed, "f") + motor("M3", speed, "f") + motor("M2", speed, "b") + motor("M4", speed, "b") + +# ====================== +# 测试 +# ====================== +if __name__ == "__main__": + + print("前进") + forward(3500) + time.sleep(3) + + print("停止") + stop() + time.sleep(1) + + print("后退") + backward(3500) + time.sleep(3) + + print("停止") + stop() \ No newline at end of file