边缘应用中,机电控制是一项非常重要的能力。当我们的智能设备在远端环境中,根据所识别的状况变化去执行应对措施,更大程度度地降低对人为操作的依赖,这些都是能产生更大经济效益的应用,包括无人驾驶车、自动机械手臂等等。
实际工业应用场景中的控制元件是非常多样化的,不过在实验室或小规模应用时,“脉冲宽度调制(PWM)模拟控制方式”是比较常用的方法,其执行原理在网上有非常丰富的专业知识,这里不多做赘述,只提供基本的控制方法与代码。
为了配合Jetson Nano完成最基本的机电控制实验,我们需要额外采购一片PCA9685控制板与一组简单的云舵机平台,二者合计大约30元人民币,如果想要实现“摄像头跟踪目标”功能,就需要再添购一个100多元的CSI摄像头(IMX-219规格),这些部件都能轻易在网上购买,并且组装难度不高,请读者自行处理。
Jetson Nano开发套件提供一组与树莓派兼容的40针扩充接口,如上图左黄色框标出的位置。透过I2C总线进行连接是最便捷的方式,Jetson Nano提供两组I2C总线,为了让整个接线最简单,这里使用针脚3(SDA)与针脚5(SCL)这组控制总线,搭配针脚1(3V3)、针脚2(5V)与针脚6(GND)的供电针脚,用“双母头杜邦线”为Jetson Nao与PCA9685按照下图进行连接,最后在PCA9685的16个组控上任选两个,分别插上不同舵机接线组,这样就完成整个实验设备的组合步骤。
以下有三个注意重点,请读者务必遵守,否则会有设备损坏的风险:
完成上述接线后,启动Jetson Nano时也会看到PCA9685控制板上的亮着电源灯(如下图),现在就能开始进行下一阶段的工作。
现在我们用远程控制Jetson Nano的方式,先检测一下目前设备连接的状态。由于,这个步骤需要使用i2c-tools工具,因此先执行以下指令进行安装:
$ sudo apt install -y i2c-tools
Jetson Nano提供I2C_1(序号为0)与I2C_2(序号为1)两组总线,前面的接线是使用I2C_2这组,因此查询总线上所连接的设备有哪些时,需要使用以下指令:
$ i2cdetect -y -r 1
执行后会看到如下图的状态,在“0x40”与“0x70”两个地址出现数字,表示检测到相关的设备。可以到hhttps://i2cdevices.org/addresses 看看这两组16进位数字代表什么设备?发现PCA9685控制芯片涵盖了从0x40到0x7f共64个地址,现在显示的状态表示已经检测到我们连线的控制板。
为了要能正常使用i2c总线,还需要执行以下的权限配置:
$ sudo usermod -aG i2c $USER
$ sudo groundadd -f -r gpio
$ sudo usermod -aG gpio $USER
然后请执行以下指令安装所需要的Python库:
$ sudo apt install -y python3-pip
$ sudo pip3 install -U pip
$ sudo -H pip3 install adafruit-circuitpython-servokit
现在就可以在Jetson Nano上,透过PCA9685控制板来控制云台的两个舵机。下面是最简单的控制代码,假设控制水平转动与垂直转动的舵机,分别接到控制板的0号组与1号组上,下面代码就能测试云台的最基本转动状态:
from adafruit_servokit import ServoKit
myCameraKit=ServoKit(channels=16)
import time
for i in range(0,180,5) : # 正向旋转:从0度到180度
myCameraKit.servo[0].angle=i # 水平转向,请根据实际连线调整编号
myCameraKit.servo[1].angle=i # 垂直转向,请根据实际连线调整编号
time.sleep(.1)
for i in range(180,0,-5) : # 反向旋转:从180度到0度
myCameraKit.servo[0].angle=i # 水平转向,请根据实际连线调整编号
myCameraKit.servo[1].angle=i # 垂直转向,请根据实际连线调整编号
time.sleep(.1)
代码正常运行的话,就会看到云台从左上角缓步移动到右下角,然后再缓步回到起点位置。这段代码十分简单,只要改变舵机的“angle”值,就能调整云台的位置。
这里有几个需要注意的地方:
现在就应该能掌握Jetson Nano控制机电设备的基础能力,接下来先关闭Jetson Nano电源,然后将IMX 219规格的CSI摄像头安装到云台上,并将软排线接到Jetson Nano的CSI插槽上(如下图)。
下面提供一段最简单启动CSI摄像头的代码:
import cv2
cap = cv2.VideoCapture( # 调用libargus库指令,并给定摄像头编号
"nvarguscamerasrc ! "
"video/x-raw(memory:NVMM), " # 数据直接存入显存
"width=1920, height=1080, format=NV12, framerate=30/1 ! " # 尺寸/格式、帧率
"nvvidconv flip-method=0 ! " # 图像旋转模式
"video/x-raw, width=1280, height=720, format=BGRx ! " # 显示图像尺寸、格式
"videoconvert ! video/x-raw, format=BGR ! appsink" # 显示图
)
while True:
_, frame = cap.read() # 读取摄像头帧
cv2.imshow("CSI Camera", frame) # 显示帧
key = cv2.waitKey(1) & 0xFF
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
一种比较简单的做法,执行这个CSI摄像头的显示代码,然后再开一个终端去执行前面的云台控制代码,这时候就能看到摄像头里显示的内容,会随着舵机的转动而改变。
进阶的技巧可以将两个代码进行组合,并且可以根据摄像头捕捉指定物体,例如一个黄色圆形物,然后计算目标物与屏幕中心点的距离,转换成需要转动的角度,再与现在的角度进行加总后算出新的角度,发送给PCA9685控制板让两个舵机进行位置的调整,这样就能创建“目标跟踪”功能的摄像头云平台应用,主要精力会耗费在角度的计算上面,总的来说难度并不是很大,适合初学者细心琢磨。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有