背景:
我正在尝试为我的机器人编写一个简单的“物体避免”程序。
没有键盘中断事件的初始版本可以工作,但是当我尝试使用 CTL-C 退出时,程序停止,但机器人继续移动,直到我物理抓住它并将其关闭。
解决方案:
使用在不同程序中使用的技巧来侦听键盘事件,然后在检测到键盘事件时停止机器人。
代码:
有效代码的示例非常大(它是一个基于网络的 FPV 远程控制机器人),因此我没有逐字逐句地包含它,而是在 MediaFire 上包含了它的链接,因此这个问题不会成为长得难以忍受。
即:
是有困难的代码(对象避免代码)要短得多,所以我已经将它逐字包含了。
# Object Avoidance Robot
# Drives in a straight line untill it reaches an obsticle within "X" cm.
# It then stops, backs up a few cm, turns a random amount, and then proceeds.
import easygopigo3 as easy
import time
import random
import signal
import os
import sys
gpg = easy.EasyGoPiGo3()
gpg = easy.EasyGoPiGo3()
servo_1 = gpg.init_servo('SERVO1')
servo_2 = gpg.init_servo('SERVO2')
sleep_time = 0.50 # pause time in seconds
my_distance_portI2C = gpg.init_distance_sensor('I2C')
time.sleep(0.1)
# for triggering the shutdown procedure when a signal is detected
keyboard_trigger = Event()
def signal_handler(signal, frame):
print("Signal detected. Stopping threads.")
gpg.stop()
keyboard_trigger.set()
print("Running: Test Servos.\n")
# Read the connected robot's serial number
serial_number = gpg.get_id() # read and display the serial number
# For testing only - "invalid" serial number
# serial_number = "invalid"
print("This robot's serial number is\n"+serial_number+"\n")
# Servo constants for each robot
# Each robot is identified by its unique serial number
# Charlene:
if serial_number == "A0F6E45F4E514B4B41202020FF152B11":
# Charlene's servo constants
print("Robot is \"Charlene\"")
center_1 = 86 # Horizontal centering - smaller is further right.
center_2 = 76 # Vertical centering - smaller is further up.
# Charlie:
elif serial_number == "64B61037514E343732202020FF111A05":
# Charlie's servo constants
print("Robot is \"Charlie\"")
center_1 = 86 # Horizontal centering - smaller is further right.
center_2 = 90 # Vertical centering - smaller is further up.
else:
# Unknown serial number
print("I don't know who robot", serial_number, "is,")
print("If we got this far, it's obviously a GoPiGo robot")
print("But I don't know what robot it is, so I'm using")
print("the default centering constants of 90/90.\n")
# Default servo constants
print("Robot is \"Unknown\"")
print("Please record the robot's serial number, name,")
print("and derived centering constants.")
center_1 = 90
center_2 = 90
# Start Test Servos
# Define excursions
right = center_1 - 45
left = center_1 + 45
up = center_2 - 45
down = center_2 + 45
def test_servos():
# Test servos
print("\nStarting test:")
print("Using centering constants "+str(center_1)+"/"+str(center_2), "for this robot")
print("\nCenter Both Servos")
servo_1.rotate_servo(center_1)
servo_2.rotate_servo(center_2)
time.sleep(sleep_time)
print("Test Servo 1 (horizontal motion)")
servo_1.rotate_servo(right)
time.sleep(sleep_time)
servo_1.rotate_servo(left)
time.sleep(sleep_time)
servo_1.rotate_servo(center_1)
time.sleep(sleep_time)
print("Test Servo 2 (vertical motion)")
servo_2.rotate_servo(up)
time.sleep(sleep_time)
servo_2.rotate_servo(down)
time.sleep(sleep_time)
print("Re-Center Both Servos")
servo_1.rotate_servo(center_1)
servo_2.rotate_servo(center_2)
time.sleep(sleep_time)
servo_1.disable_servo()
servo_2.disable_servo()
print("Complete: Test Servos - Exiting.")
def avoid():
while True:
while my_distance_portI2C.read_inches() > 20:
gpg.forward()
gpg.stop()
time.sleep(1)
gpg.backward()
time.sleep(1)
gpg.stop()
test_servos()
gpg.backward()
time.sleep(4)
gpg.stop()
time.sleep(1)
gpg.turn_degrees((random.randint(90, 270)), blocking=True)
time.sleep(1) # slowdown
#------------------------------------
# Main routine entry point is here
#------------------------------------
if __name__ == "__main__":
# registering both types of termination signals
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
test_servos() # make sure servos are centered
avoid()
logging.info("Finished!")
sys.exit(0)
while not keyboard_trigger.is_set():
sleep(0.25)
# until some keyboard event is detected
print("\n ==========================\n\n")
print("A \"shutdown\" command event was received!\n")
gpg.stop()
exit()
问题:
当我在 VS Code 中运行 New_Remote_Camera_Robot.py 代码时,它可以工作。 (实际上,这不是因为机器人操作系统的这个特定安装尚未安装 nginx - 但它不会因
event
问题而失败。)
当我在 VS Code 中运行上面的 object_avoidance.py 代码时,它失败并显示:
pi@Charlene:~/Project_Files/object_avoidance $ /usr/bin/python /home/pi/Project_Files/object_avoidance/Object_Avoidence.py
Traceback (most recent call last):
File "/home/pi/Project_Files/object_avoidance/Object_Avoidence.py", line 22, in <module>
keyboard_trigger = Event()
NameError: name 'Event' is not defined
pi@Charlene:~/Project_Files/object_avoidance $
我绝对确定我错过了
某些东西
。 我同样确信这绝对是愚蠢的事情。 预先感谢您提供的任何帮助。
该错误是由于代码中未定义 Event 对象造成的。在Python中,Event对象来自线程模块,但似乎您还没有在Object_Avoidence.py脚本中导入它。