基于Raspberry Pi的巡线机器人代码问题求助:质心判断与语法错误
巡线机器人问题解决指南
一、语法错误排查与修正
你的代码里有几处明显的语法问题,直接触发了SyntaxError,我帮你逐一修正:
- if语句格式错误:
if: cx>151 and cx<169写法不符合Python规范,正确格式是if 条件:,要把冒号移到判断条件后面,改成if cx > 151 and cx < 169: - elif/else缺少冒号:所有
elif和else语句结尾必须加冒号,比如elif cx <= 150:、else: - 变量名不统一:你在
elif分支里误用了x,但质心变量是cx,要保持一致,否则会报变量未定义错误 - 缺少time模块导入:代码里用到了
time.sleep(),但没导入time库,需要在开头新增import time - print语法适配:如果用Python3环境,
print需要加括号,比如print("straight")
修正后的基础代码片段:
import RoboPiLib as RPL import setup import time # 新增time模块导入 motorL = 0 motorR = 1 # 1500 = 伺服电机中点,越接近该值转速越慢 # 假设cx是你已计算好的质心x坐标 if cx > 151 and cx < 169: print("straight") RPL.servoWrite(motorL, 1000) RPL.servoWrite(motorR, 2000) time.sleep(0.1) # 缩短sleep时间,避免阻塞摄像头捕获 elif cx <= 150: print("left") RPL.servoWrite(motorL, 1000) RPL.servoWrite(motorR, 1750) time.sleep(0.1) elif cx >= 170: print("right") RPL.servoWrite(motorL, 1250) RPL.servoWrite(motorR, 2000) # 修正原代码中可能的电机转向逻辑错误 time.sleep(0.1) else: print("stop") RPL.servoWrite(motorL, 1500) RPL.servoWrite(motorR, 1500) # 回到中点停止电机
二、质心中点是否为160的确认方法
质心的水平中点完全取决于你的摄像头分辨率:
- 如果PiCamera设置的是320x240分辨率,水平像素数为320,中点就是160(320/2)
- 你可以在质心检测代码里加一行打印,确认摄像头实际宽度:
# 在捕获帧的代码后添加 print("摄像头水平分辨率:", frame.shape[1]) - 调试时可以实时打印
cx的值,观察巡线时质心的正常波动范围,再灵活调整判断阈值(比如把151-169的区间改成更贴合实际的范围)
三、优化后的巡线控制方案
你的现有逻辑用固定sleep时间会导致机器人反应滞后,建议改成实时帧控制+比例调节,让转向更平滑:
- 去掉time.sleep():改用逐帧处理,每捕获一帧就计算质心并调整电机,避免阻塞摄像头
- 比例控制(P控制):根据cx与中点(比如160)的偏差值,动态调整电机的PWM值,示例如下:
import RoboPiLib as RPL import setup import time import cv2 # 假设你用OpenCV处理图像 # 初始化电机 motorL = 0 motorR = 1 RPL.servoWrite(motorL, 1500) RPL.servoWrite(motorR, 1500) # 摄像头参数(自动计算中点) cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) CENTER_X = 320 // 2 # 自动得到中点160 KP = 2.0 # 比例系数,根据机器人实际情况调试,越大转向越灵敏 # 主循环 while True: # 捕获帧并计算质心cx(替换成你的质心检测函数) ret, frame = cap.read() cx = 你的质心检测函数(frame) if cx is None: # 未检测到线,停止机器人 print("未检测到巡线,停止") RPL.servoWrite(motorL, 1500) RPL.servoWrite(motorR, 1500) time.sleep(0.05) continue # 计算质心与中点的偏差 error = cx - CENTER_X # 动态调整电机PWM值(根据你的电机转向逻辑调整计算方式) left_speed = 1000 + error * KP right_speed = 2000 - error * KP # 限制PWM值在伺服电机有效范围(1000-2000) left_speed = max(1000, min(2000, left_speed)) right_speed = max(1000, min(2000, right_speed)) # 写入电机控制信号 RPL.servoWrite(motorL, int(left_speed)) RPL.servoWrite(motorR, int(right_speed)) # 微小延迟避免CPU占用过高 time.sleep(0.01)
- 注意:你需要根据自己的电机转向逻辑调整
left_speed和right_speed的计算方式,确保偏差为正时(质心偏右)机器人向右转,偏差为负时向左转 - 调试时可以调整
KP值,找到最平稳的转向灵敏度
内容的提问来源于stack exchange,提问作者Cinna
相关产品推荐
相关产品推荐

