5. 线路追踪
本项目将使用灰度模块让 PiCar-X 沿着一条线向前移动。使用深色胶带制作一条尽可能直且 不太弯曲的线路。若 PiCar-X 偏离线路,可能需要进行一些实验调整。
运行代码
cd ~/picar-x/example
sudo python3 5.minecart_plus.py
运行代码后,PiCar-X 将沿着线路向前移动。
代码
备注
您可以 修改/重置/复制/运行/停止 以下代码。但在此之前,需进入源码路径,例如 picar-x/example
。修改代码后,您可以直接运行以查看效果。
from picarx import Picarx
from time import sleep
px = Picarx()
# px = Picarx(grayscale_pins=['A0', 'A1', 'A2'])
# 请运行 ./calibration/grayscale_calibration.py 自动校准灰度值
# 或者通过以下代码手动修改参考值
# px.set_line_reference([1400, 1400, 1400])
current_state = None
px_power = 10
offset = 20
last_state = "stop"
def outHandle():
global last_state, current_state
if last_state == 'left':
px.set_dir_servo_angle(-30)
px.backward(10)
elif last_state == 'right':
px.set_dir_servo_angle(30)
px.backward(10)
while True:
gm_val_list = px.get_grayscale_data()
gm_state = get_status(gm_val_list)
print("outHandle gm_val_list: %s, %s"%(gm_val_list, gm_state))
currentSta = gm_state
if currentSta != last_state:
break
sleep(0.001)
def get_status(val_list):
_state = px.get_line_status(val_list) # [bool, bool, bool], 0 表示线路,1 表示背景
if _state == [0, 0, 0]:
return 'stop'
elif _state[1] == 1:
return 'forward'
elif _state[0] == 1:
return 'right'
elif _state[2] == 1:
return 'left'
if __name__=='__main__':
try:
while True:
gm_val_list = px.get_grayscale_data()
gm_state = get_status(gm_val_list)
print("gm_val_list: %s, %s"%(gm_val_list, gm_state))
if gm_state != "stop":
last_state = gm_state
if gm_state == 'forward':
px.set_dir_servo_angle(0)
px.forward(px_power)
elif gm_state == 'left':
px.set_dir_servo_angle(offset)
px.forward(px_power)
elif gm_state == 'right':
px.set_dir_servo_angle(-offset)
px.forward(px_power)
else:
outHandle()
finally:
px.stop()
print("stop and exit")
sleep(0.1)
工作原理
该 Python 脚本使用灰度传感器控制 Picarx 机器人小车的导航。以下是其主要组成部分的说明:
导入与初始化:
脚本导入了控制机器人小车的 Picarx 类以及 time 模块中的 sleep 函数,用于添加延时操作。
创建了 Picarx 的实例,注释行显示了一个使用特定灰度传感器引脚的初始化方法。
from picarx import Picarx from time import sleep px = Picarx()
配置与全局变量:
current_state
、px_power
、offset
和last_state
是用于跟踪和控制小车运动的全局变量。px_power
设置电机功率,offset
用于调整转向角度。current_state = None px_power = 10 offset = 20 last_state = "stop"
outHandle
函数:当小车需要处理“脱线”情况时调用此函数。
它根据
last_state
调整小车的方向,并检查灰度传感器值以确定新状态。def outHandle(): global last_state, current_state if last_state == 'left': px.set_dir_servo_angle(-30) px.backward(10) elif last_state == 'right': px.set_dir_servo_angle(30) px.backward(10) while True: gm_val_list = px.get_grayscale_data() gm_state = get_status(gm_val_list) print("outHandle gm_val_list: %s, %s"%(gm_val_list, gm_state)) currentSta = gm_state if currentSta != last_state: break sleep(0.001)
get_status
函数:此函数解释灰度传感器数据(
val_list
),以确定小车的导航状态。根据哪个传感器检测到线路,小车的状态可以是“forward”(前进)、“left”(左转)、“right”(右转)或“stop”(停止)。
def get_status(val_list): _state = px.get_line_status(val_list) # [bool, bool, bool], 0 表示线路,1 表示背景 if _state == [0, 0, 0]: return 'stop' elif _state[1] == 1: return 'forward' elif _state[0] == 1: return 'right' elif _state[2] == 1: return 'left'
主循环:
while True
循环不断检查灰度数据并相应调整小车的运动。根据
gm_state
,它设置转向角度和运动方向。if __name__=='__main__': try: while True: gm_val_list = px.get_grayscale_data() gm_state = get_status(gm_val_list) print("gm_val_list: %s, %s"%(gm_val_list, gm_state)) if gm_state != "stop": last_state = gm_state if gm_state == 'forward': px.set_dir_servo_angle(0) px.forward(px_power) elif gm_state == 'left': px.set_dir_servo_angle(offset) px.forward(px_power) elif gm_state == 'right': px.set_dir_servo_angle(-offset) px.forward(px_power) else: outHandle()
安全与清理:
try...finally
块确保脚本中断或结束时小车能够安全停止。finally: px.stop() print("stop and exit") sleep(0.1)
总结,该脚本利用灰度传感器引导 Picarx 机器人小车沿线路导航。它通过连续读取传感器数据来确定方向,并相应调整小车的运动和转向。 outHandle
函数为小车在需要大幅调整路径时提供额外逻辑支持。