后记:本人于2020-10-19重新使用该项目,报错,故于原文最开头记叙:
关于unbutu安装android studio困难记录:
关于gradle的问题,首先不管原项目,新建一个全新的项目,然后点File->Project Structure,记住上面的两个版本号,然后打开原项目,同样的道理,将其改为刚刚说的版本号。接着修改build.gradle中的:classpath ‘com.android.tools.build:gradle:4.1.0’,4.1.0为6.5对应的号,所以一切要对应,接着要注意的是,不要设置代理!不要设置代理,http的那个代理不要选,选则NO proxy,接着可以File->sync Project…
当然这tm还没完,当进行build ->apk时继续报错,好的,我猜测还是代理,然后把gladle中的所有有关代理的全删了,比如:
全删!
systemProp.http.proxyHost=mirrors.neusoft.edu.cn
systemProp.http.proxyPort=80
systemProp.https.proxyHost=mirrors.neusoft.edu.cn
systemProp.https.proxyPort=80
当然还差最后一点,当年这个代码用的是29,所以还要下载对应的sdk!!!,否则还会报错的。
参考链接:
- 报错Failed to load module “canberra-gtk-module”:https://blog.csdn.net/u014337397/article/details/81068991
- android studio下载及sdk配置:https://blog.csdn.net/xiaoxun2802/article/details/104003442
一.目的
本人要实现手机控制树莓派,来给机器人发指令,还可通过语音控制机器人,当然。由于控制机器人的程序是用python写的,所以可以同样实现控制电脑。
不过只实现了同一局域网下的通信,包括用python向手机发视频,手机向树莓派发控制指令等。
参考链接:https://github.com/spoonysonny/speak_raspi_ip
二.控制(python)
先给出python源码:
(在ubuntu下,可以改个.desktop来实现开机运行python脚本)
import sys
import socket
import uuid
import time
import os
import threading
import logging
import struct
from logging import handlers
import cv2
import numpy as np
import speech_recognition as sr
#from VideoCapture import Device
# 获取MAC地址
def get_mac_address():
mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
return ":".join([mac[e:e + 2] for e in range(0, 11, 2)])
# 获取IP地址
def get_host_ip():
try:
my = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
my.connect(('8.8.8.8', 80))
# ip = my.getsockname()[0]
ipList = my.getsockname()
finally:
my.close()
return ipList
def _logging(**kwargs):
level = kwargs.pop('level', None)
filename = kwargs.pop('filename', None)
datefmt = kwargs.pop('datefmt', None)
format = kwargs.pop('format', None)
if level is None:
level = logging.DEBUG
if filename is None:
filename = 'default.log'
if datefmt is None:
datefmt = '%Y-%m-%d %H:%M:%S'
if format is None:
format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
log = logging.getLogger(filename)
format_str = logging.Formatter(format, datefmt)
th = handlers.TimedRotatingFileHandler(filename=filename, when='H', backupCount=3, encoding='utf-8')
th.setFormatter(format_str)
th.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
log.addHandler(ch)
log.addHandler(th)
log.setLevel(level)
return log
def video(addr):
#读取图片,编码成二进制 bytes格式
cap = cv2.VideoCapture(0)
'''
cap.set(3,160)
cap.set(4,160)'''
while True:
ret,frame = cap.read()
if not ret:
break
frame = cv2.resize(frame,(1000,700))
pictureData= cv2.imencode(".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), 15])[1]
sYS.sendto(pictureData,(re[1][0],9999))
sYS.close()
cap.release()
def audioRec():
while True:
r = sr.Recognizer()
source=sr.Microphone()
with sr.Microphone() as source:
r.adjust_for_ambient_noise(source) # listen for 1 second to calibrate the energy threshold for ambient noise levels
print('say something')
# print("")
audio = r.listen(source)
audioString=r.recognize_sphinx(audio)
print(audioRec)
if audioString=='关机':
print('关机7')
elif audioString=='重新启动'or audioString=='重启':
print('重启7')
elif audioString=='前进':
print('前进')
elif audioString=='后退':
print('后退')
elif audioString=='左转':
print('左转')
elif audioString=='右转':
print('右转')
elif audioString=='左移':
print('左移')
elif audioString=='右移':
print('右移')
elif audioString=='抬头':
print('抬头')
elif audioString=='低头':
print('低头')
os.makedirs("logs", exist_ok=True)
mylog = _logging(filename='logs/udpserver.log')
HOST = ''
PORT = 8888
BUFSIZ = 2048
ADDRESS = (HOST, PORT)
udpServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udpServerSocket.bind(ADDRESS) # 绑定客户端口和地址
sYS= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
re = udpServerSocket.recvfrom(2048)
myname = socket.gethostname()
print("myname:" + myname)
mylog.debug("myname:" + myname)
myIPList = get_host_ip()
print("myIPList:" + str(myIPList))
mylog.debug("myIPList:" + str(myIPList))
macAddress = get_mac_address()
print("macAddress:" + macAddress)
mylog.debug("macAddress:" + macAddress)
toClose=False
data, addr = udpServerSocket.recvfrom(BUFSIZ)
def main():
global udpServerSocket
print("enslfjslfjwlfjwlfjwlkfmwlkefnwlkfnewlkn")
global toClose
while True:
data, addr = udpServerSocket.recvfrom(BUFSIZ)
print("waiting for message...")
mylog.debug("waiting for message...")
currCode = data.decode('utf-8')
print("接收到数据:" +currCode)
mylog.debug("接收到数据:"+currCode)
# content = '[%s] %s' % (bytes(ctime(), 'utf-8'), data.decode('utf-8'))
# 发送服务器时间
if currCode == "TIME":
content = "Time:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
udpServerSocket.sendto(content.encode('utf-8'), addr)
# 发送IP地址
elif currCode == "IP":
content = "IP:" + str(myIPList)
udpServerSocket.sendto(content.encode('utf-8'), addr)
# 发送mac地址
elif currCode == "MAC":
content = "MAC:" + macAddress
udpServerSocket.sendto(content.encode('utf-8'), addr)
# 发送ip mac地址
elif currCode == "IP_MAC":
content = "IP:" + str(myIPList) + "|MAC:" + macAddress
udpServerSocket.sendto(content.encode('utf-8'), addr)
# 退出UDP服务端
elif currCode == "EXIT":
content = "程序中止"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print(content)
toClose=True
# 重启
elif currCode == "REBOOT":
content = "服务端重启"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("服务端开始重启")
mylog.debug("服务端开始重启")
#os.system('reboot')
break
# 关机
elif currCode == "SHUTDOWN" :
content = "关机"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("关机")
mylog.debug("关机")
#os.system('sudo shutdown -h now')
#os.system('python3 video.py')
break
elif currCode == "MOVELEFT" :
content = "MOVELEFT"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("左移")
mylog.debug("左移")
elif currCode == "MOVERIGHT":
content = "MOVERIGHT"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("右移")
mylog.debug("右移")
elif currCode == "TURNLEFT":
content = "TURNLEFT"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("左转")
mylog.debug("左转")
elif currCode == "TURNRIGHT":
content = "TURNRIGHT"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("右转")
mylog.debug("右转")
elif currCode == "FORWARD" :
content = "FORWARD"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("前进")
mylog.debug("前进")
elif currCode == "BACK":
content = "BACK"
udpServerSocket.sendto(content.encode('utf-8'), addr)
print("后退")
mylog.debug("后退")
else:
udpServerSocket.sendto("Bad Key".encode('utf-8'), addr)
# content = '[%s] %s %s' % (bytes(ctime(), 'utf-8'), str(myIPList), macAddress)
# udpServerSocket.sendto(content.encode('utf-8'), addr)
print('...received from and returned to:', addr)
#mylog.debug('...received from and returned to:', addr)
udpServerSocket.close()
print("服务端退出")
mylog.debug('服务端退出')
def go(order):
if order=='yes':
main()
elif order=='audio':
audioRec()
else:
video(addr)
list = ['yes','audio','no']
threads = []
files = range(len(list))
#创建线程
for i in files:
t = threading.Thread(target=go,args=(list[i],))
threads.append(t)
if __name__ == '__main__':
for i in files:
threads[i].start()
里面的指令可以自己修改,改成自己需要的,难度不大,应该可以看懂。至于实现中文语音的识别,可以参考这篇文章
三.APP开发
用android studio写的,采用udp协议,错了不重发,这样视频有保证。界面如下:
电脑/树莓派与手机在同一个局域网下,android手机输入树莓派的ip地址如:192.168.0.1,电脑/树莓派上运行python,点击中间下面四个按钮的最右边按键可以实现视频的接收与暂停。
整个工程等所有文件在下述链接:
https://download.csdn.net/download/wxkhturfun/12315437