笔记如下:
GPIO.setmode(GPIO.BCM) #设置GPIO引脚编号的模式,这里引脚编号采用BCM编码方式
GPIO.setwarnings(False) #如果RPi.GRIO检测到一个引脚已经被设置成了非默认值,那么你将看到一个警告信息。你可以通过这个代码禁用警告:
key = 22
#如果输入引脚处于悬空状态,引脚的值将是漂动的。换句话说,读取到的值是未知的,因为它并没有被连接到任何的信号上,直到按下一个按钮或开关。
# 由于干扰的影响,输入的值可能会反复的变化。使用如下代码可以解决问题:(需要注意的是,上面的读取代码只是获取当前一瞬间的引脚输入信号)
GPIO.setup(key, GPIO.IN, GPIO.PUD_UP)
if cap.isOpened(): #如果先前对VideoCapture构造函数或VideoCapture :: open()的调用成功,则该方法返回。 真正。
ret, orgFrame = cap.read() #读取一桢图像,前一个返回值是是否成功,后一个返回值是图像本身
if ret:
t1 = cv2.getTickCount() #该函数返回特定事件后的滴答数(例如,打开机器时)。 它可以用于初始化RNG或通过读取来测量函数执行时间。 函数调用前后的滴答计数。
try:
orgFrame = cv2.resize(orgFrame, (320,240), interpolation = cv2.INTER_CUBIC) #将图片缩放到 320*240
except Exception as e:
print(e)
continue
if orgFrame is not None: #当X为None, False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()这些时,not X为真,即无法分辨出他们之间的不同
img_h, img_w = orgFrame.shape[:2] #获得当前桢彩色图像的大小
orgFrame = lens_distortion_adjustment(orgFrame)
# # 画图像中心点
# img = cv.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
# 作用:给定一个图像img,连接点pt1和pt2的坐标,在图中画一条直线,color表明线的颜色
# import cv2 as cv
# 在(10, 0)和(0, 100)之间画条直线,直线的颜色为蓝色
# cv.line(img, (0, 10), (100, 0), (255, 0, 0))
cv2.line(orgFrame, (int(img_w / 2) - 20, int(img_h / 2)), (int(img_w / 2) + 20, int(img_h / 2)), (0, 0, 255), 1)
cv2.line(orgFrame, (int(img_w / 2),int(img_h / 2) - 20), (int(img_w / 2), int(img_h / 2) + 20), (0, 0, 255), 1)
t2 = cv2.getTickCount() #滴答的次数
time_r = (t2 - t1) / cv2.getTickFrequency() #得到两次滴答的时间差
fps = 1.0/time_r #实时计算每秒的帧数
if debug:
cv2.putText(orgFrame, "fps:" + str(int(fps)),
(10, orgFrame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) #(0, 0, 255)BGR
# 图像,文字内容, 坐标 ,字体,大小,颜色,字体厚度
cv2.imshow("orgFrame", orgFrame)
cv2.waitKey(1)
else:
time.sleep(0.01)
GPIO.setwarnings(False) #如果RPi.GRIO检测到一个引脚已经被设置成了非默认值,那么你将看到一个警告信息。你可以通过下列代码禁用警告:
GPIO.setup(key, GPIO.IN, GPIO.PUD_UP)
#上拉和下拉是指GPIO输出高电位(上拉)还是低电位(下拉)。上拉就是输入高电平,然后接一个上拉电阻(起保护作用),知道上拉就表示该端口在默认情况下输入为高电平。下拉就是输入低电平,然后接一个下拉电阻。
# 我们在做管脚的上下拉时,在电路设计上一般都是加上下拉电阻,但在树莓派身上如何不改变电路通过python去控制呢?
# 在python的GPIO初始化上可以用GPIO.setup(pinx,GPIO.IN,pull_up_down=GPIO.PUD_UP/GPIO.DOWN)来控制上下拉
# 校准标志
th1= threading.Thread(target=setDeviation) ##声明setDeviaton这个子线程
th1.setDaemon(True) #setDaemon()方法。主线程A中,创建了子线程B,并且在主线程A中调用了B.setDaemon(),这个的意思是,把主线程A设置为守护线程,这时候,要是主线程A执行结束了,
#就不管子线程B是否完成,一并和主线程A退出.这就是setDaemon方法的含义,这基本和join是相反的。
# 此外,还有个要特别注意的:必须在start() 方法调用之前设
th1.start()
Servos[servoId - 1].setPosition(pos, time)
# -1是因为数组是从0开始的,在Python的解释器内部,当我们调用Servos[servoId - 1].setPosition(pos, time)时,
# 实际上Python解释成PWM_Servo.setPosition(Servos[servoId - 1], pos, time),也就是说把self替换成类的实例。
if os.path.exists(actNum) is True: # 如果存在该动作组,如果path指向一个已存在的路径或已打开的文件描述符,返回True,对于失效的符号链接,返回 False。
ag = sql.connect(actNum) # sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri])
# 打开数据库actNum连接 SQLite 数据库 database。默认返回 Connection 对象,除非使用了自定义的 factory 参数。
#database 是准备打开的数据库文件的路径(绝对路径或相对于当前目录的相对路径),它是 path-like object。你也可以用 ":memory:" 在内存中打开一个数据库。
cu = ag.cursor() #定义了一个游标cursor(factory=Cursor)
#这个方法接受一个可选参数 factory,如果要指定这个参数,它必须是一个可调用对象,而且必须返回 Cursor 类的一个实例或者子类。
cu.execute("select * from ActionGroup") # 查询execute(sql[, parameters])
#这是一个非标准的快捷方法,它会调用 cursor() 方法来创建一个游标对象,并使用给定的 parameters 参数来调用游标对象的 execute() 方法,最后返回这个游标对象。