TA的每日心情 | 怒 2020-3-6 09:52 |
---|
签到天数: 13 天 连续签到: 1 天 [LV.3]偶尔看看II
|
用陀螺仪和手指触摸屏幕控制摄像头位置
需要准备的东西
硬件 | 数量 | Raspberry Pi Zero Wireless | x1 | 树莓派摄像模块 | x1 | Adafruit 16路PWM 舵机驱动板 PCA9685 | x1 | Adafruit迷你云台套件 | x1 | 软件和在线服务
RemoteMe.org cloud | |
背景故事
在上一个教程(这里)中,我展示了如何在浏览器窗口中显示树莓派相机中的图像。在本教程中,我将向您展示如何控制相机的位置。我们将以两种方式控制
- 通过在视频组件上移动鼠标/手指
- 倾斜手机并使用内置陀螺仪
所有这一切都在浏览器中打开(不论在电脑端还手机端,我都使用Chrome浏览器,因为它对webRTC协议的支持最好)。
它是如何运作的
正如通过webRTC协议发送相机图像一样,我们将使用相同的通道发送指令来控制相机的位置。来自浏览器的消息将转到RasbeprryPi上的Python脚本,此脚本将相应地驱动服务器驱动程序。这听起来很简单,所以希望发送消息完全在RemoteMe端,在python脚本中,您只需要实现一个在更改变量值后运行的函数。关于变量的更多信息点击这里
需要什么:
- Raspberry PI Zero W
- RasbperryPi专用摄像头
- 伺服控制舵机驱动板
- 两个伺服机构与倾斜兼容
- 相机倾斜
- 功率 - 这取决于电机本身以及我们使用的电池类型。我使用LiPo 4 * 1.2V电池和降压转换器
连接伺服机构
为了控制伺服机制,我们将使用兼容Adafruit的a 12-channel LED driver 16-bit PWM I2C。它通过I2C接口与树莓派通信。Adafruit提供了一个开箱即用的python库。如果在树莓派上的第二步RemoteMe安装中你选择了[Yes]选项,你已经安装了这个库;)。
连接:
SDA,SCL和接地引脚连接到RPI,如下所示:
Rpi针脚:
完整的RPI引脚图像
安装摄像头云台,这不是很难,只要注意支架的组装,需要让他直视前方,最重要的是伺服机构处于中心位置。
在图片和视频中,您可以看到安装在RPI和伺服驱动器上的绿色PCB,您可以从这里下载文件,用热转印的方法可以轻松制作。在存储库中,还有用于订购的gerber文件,例如从allpcb.com订购我的pcb。
在我们下一个课程,为我们的小车添加发动机控制时,这块板会更有用。
它是如何工作的:
对于摄像机控制,我们将使用SMALL_INTEGER_2类型的变量,它发送两个数值,其中一个我们将控制X轴与第二个Y轴。
变量将通过显示图像的电话或电脑进行更改。
可以在显示视频的区域移动鼠标/手指
使用手机上的陀螺仪,从起始位置开始旋转控制摄像头
开始吧:
我们将从创建变量开始 - tab variables - > add 完成时出现的窗口:
我们点击Submit,更多关于变量创建
然后,将我们的RasbperryPi连接到RemoteMe.org(如何连接看这里)。接下来,在已连接的树莓派上单击burger menu,“使用向导添加外部脚本”
第一步,选择变量cameraPos
多亏了这一点,在生成的代码中,我们将准备好实现与我们的变量交互的函数。
第二步,我们将设备命名为“python”和任何未使用的Id。在最后一步中,单击“Create device”。更多关于python设备的信息。
在打开的窗口中,我们将添加一个代码来支持我们的伺服机制:
- import logging
- import socket
-
- import struct
- import sys
- import os
-
- os.chdir(sys.argv[1])
- sys.path.append('../base')
-
- import remoteme
-
- import Adafruit_PCA9685 # Added
- import time # Added
- import RPi.GPIO as GPIO # Added
-
- pwm = None; # Added
-
- def setCameraPos(i1, i2):
- remoteMe.getVariables().setSmallInteger2("cameraPos", i1, i2)
-
-
-
- def onCameraPosChange(i1, i2):
- global pwm # Added
- logger.info("on camera change {} , {}".format(i1, i2)) # Added
- pwm.set_pwm(1, 0, i1) # Added
- pwm.set_pwm(0, 0, i2) # Added
- pass # Added
-
- def setupPWM(): # Added
- global pwm # Added
- pwm = Adafruit_PCA9685.PCA9685() # Added
- pwm.set_pwm_freq(80) # Added
-
- try:
-
- logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
- datefmt='%d.%m %H:%M',
- filename="logs.log")
-
- logger = logging.getLogger('application')
- setupPWM() # Added
- remoteMe = remoteme.RemoteMe()
-
- remoteMe.startRemoteMe(sys.argv)
- remoteMe.getVariables().observeSmallInteger2("cameraPos" ,onCameraPosChange);
-
- remoteMe.wait()
-
- finally:
- pass
复制代码 添加的行标有#Added注释
代码概述
- import Adafruit_PCA9685 # Added
- import time # Added
- import RPi.GPIO as GPIO # Added
-
- pwm = None; # Added
复制代码 添加库和全局变量声明pwm来控制PWM控制器(Adafruit_PCA9685)
- def onCameraPosChange(i1, i2):
- global pwm
- logger.info("on camera change {} , {}".format(i1, i2))
- pwm.set_pwm(1, 0, i1)
- pwm.set_pwm(0, 0, i2)
- pass
复制代码 想要使用智能手机或计算机更改摄像机的位置时,将调用此功能。在参数中,我们得到x和y轴的值,并设置连接到PWM控制器的位置0和1的伺服机构。我们已经接收到具有适当值的变量,例如,值(534.234)将表示摄像机的中心位置 - 因此我们只需将接收到的数字输入服务器驱动程序而不进行格式化。
- def setupPWM():
- global pwm
- pwm = Adafruit_PCA9685.PCA9685()
- pwm.set_pwm_freq(80)
复制代码 PWM控制器库初始化的功能。通过反复试验选择80的值给我的伺服机构。在主程序块中调用此函数。
保存代码后,RasbperryPi上的程序将被重置以加载新脚本。
网页
现在我们将添加一个带有两个滑块的网页,以查找摄像机的中心位置和最大摆动。在理想情况下,两个值的数字都是0.100,即发送一个值变量(50.50),我们将相机设置在中心位置,值(100,100)将其指向上和右。不幸的是,这些数字肯定会有所不同,我们必须找到它们。为此,我们将创建一个包含两个滑块的网站,这些滑块将发送变量,我们将知道变量是什么。
要添加网站 - 选择“New Device” - >“Webpage”并按如下所示完成:
添加后,单击index.html和“edit with wizard”。然后“Insert component”并完成:
有关此处组件的详细信息
重要信息
- 我们将控制CameraPos变量的两个滑块
- 对于两个轴,我们将发送的最小和最大数量为0–1000。
点击insert,关闭向导窗口,然后单击index.html并选择在新选项卡中打开页面Open in new tab。
我们将会得到我们的网站,第一个滑块负责相机的X轴(水平移动,即向左右看),第二个滑块负责Y轴(即向上、向下)。当滑块控制不同,我们替换伺服插头的机构在地方。当伺服系统没有响应时,检查它们是否插入了正确的位置。
移动滑块将相机设置在中心位置,对于我来说,它是x=564,y=474。
然后我们将相机倾斜到最小值,对于我来说是x=298,y=223。
计算出摄像机的最大偏转量,算出的中心位置的所在。
Xmax = Xcenter-Xmin + Xcenter = 564 - 298 + 564 = 830Ymax = Ycenter-Ymin + Ycenter = 474 - 223+ 474 = 725
也就是说,Xmin = 298,Xcenter = 564,Xmax = 830.轴的长度如下:
关键是值之间的距离相同,另外Xcenter值表示摄像机在水平面上的中心位置。
Y轴:Ymin = 223,Ycenter = 474,Ymax = 725
在滑块上,检查最大值是否将摄像机设置在正确的位置,而且伺服器不会卡住 - 如果卡住,则增加Xmin并重复计算(或根据Xmax计算Xmin)。
我们返回index.html页面,从页面源中删除该行的滑块:
- <variable component="slider" type="SMALL_INTEGER_2" name="cameraPos" label="camera" min="0" max="1000" valuebox="true" ></variable>
复制代码 然后我们重新打开组件向导并插入组件
相机:
状态 - 在右上角将显示连接状态:
通过从相机移动图像来控制手指/鼠标:
请注意,我已使用计算值补充了Xmin值。
陀螺仪 - 这样我们就可以通过倾斜手机来控制摄像机的位置:
我也把计算值放在这里。更多关于组件和配置的信息
在index.html来源中改变视频的大小,而不是width和height,输入style = "width: calc (100vmin); height: calc (75vmin)"- 当手机处于垂直位置时,这将填充相机图像
我们在手机端打开我们的网站 - 最简单的方法是点击index.html- > Get anymous Link- >点击二维码图标并用智能手机扫描。
我们测试通过滑动手指在屏幕上,相机时,而不是指向了其在部件向下移动<variable component = "cameraMouseTrack" index.html 变化invertX = "false"成invertX = "true"
如果相同的情况适用于Y轴,我们会更改同一组件中的值invertY
我们通过点击陀螺仪按钮打开陀螺仪 - 它会记住智能手机的位置并改变摄像机的位置 - 当触摸手机时,当移动时相反时,我们应该改变类似于前一步骤invertXinvertY但现在在组件中 <variable component = "gyroscope"。如果我们希望陀螺仪更温和地反应,我们会增加xRange和 属性的值yRange
开头的视频里有今天说的所有东西。
本文作者 Maciej
来源 hackster 地址
|
|