python机器人编程——用手机web远程视频监控并控制小车驾驶(上篇vrep仿真)

目录

  • 一、前言
  • 二、技术架构
  • 三、设备端实现
  • 四、服务控制端实现
    • (1)摄像头服务模块
    • (2)web服务器
  • 五、web端实现
    • (1)视频显示
    • (2)驾驶盘的实现
    • (3)心跳
  • 六、总结
  • 七、源码或环境
  • PS.扩展阅读
    • ps1.六自由度机器人相关文章资源
    • ps2.四轴机器相关文章资源
    • ps3.移动小车相关文章资源

一、前言

在现代科技的推动下,机器人技术正逐渐进入我们的生活。而编程作为机器人技术中不可或缺的一环,也成为了众多科技爱好者追逐的目标之一。今天,我将带领大家探索一种新颖而有趣的机器人编程方式——用Python编程实现手机web远程视频监控并控制小车驾驶。

本系列博文将分为上下两篇,分别介绍了在WiFi环境下,如何实现Web端的视频监控和控制远程差速小车的驾驶。上篇将重点介绍如何利用V-REP软件进行仿真车控制,下篇将继续讲解如何实现实物车的控制。

在这个系列博文中,我们将使用Python作为主要编程语言,并利用其强大的库和框架来实现所需功能。而作为Web服务器端,我们将使用Python来搭建服务器,而Web端则使用HTML来实现。

通过这个系列博文的学习,我们将深入了解机器人编程的基本原理和技术,并通过实践来提升自己的编程能力。同时,我们还将学会如何通过手机远程监控和控制机器人,为我们的生活带来更多的便利。
上篇效果如下,左侧时web端可以运行在电脑及手机浏览器,右侧是仿真环境:
在这里插入图片描述
以下是python服务器端:
在这里插入图片描述

二、技术架构

技术架构主要三个部分,底层为硬件(或仿真环境),实现电机,摄像头和传感器及车架等的设计制造,并提供上层的接口。
中层为控制服务端,主要由python实现,可运行在笔记本和工控机,实现与下层的通讯,及与web端的通讯。主要由采集驱动系列模块,数据服务模块,及操控小车相关的逻辑模块,还有web的服务器模块,摄像头视频服务模块及UI管理操作模块组成。
上层web交互端,主要提供web客户端,UI操控界面,及相应的逻辑模块组成。
在这里插入图片描述

三、设备端实现

本篇采用VREP搭建的一个家庭环境并实现小车的活动区域,并加入差速小车配置摄像头,测距雷达等。
在这里插入图片描述
然后提供了与上位机通讯的脚本模块:
在这里插入图片描述
仿真配套资源已经上传:下载地址

四、服务控制端实现

通过python实现服务控制端。本篇主要介绍web及摄像头服务模块。其它模块处理见此前VREP小车相关博文,或者下篇。

(1)摄像头服务模块

摄像头服务模块,采用了一个知名库mjpeg_streamer,可以很容易实现一个局域网的web视频服务。几行代码就可以:


from mjpeg_streamer import MjpegServer, Streamfrom socket import *
import numpy as np
import cv2
cap = cv2.VideoCapture(0)# 设置镜头分辨率,默认是640x480
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)stream = Stream("my_camera", size=(640, 480), quality=50, fps=30)
server = MjpegServer("0.0.0.0", 8000)
server.add_stream(stream)
server.start()while True:try:_, frame = cap.read()        stream.set_frame(frame)#s.sendto(message.encode(), addr)    #cv2.putText(r_img, "server", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)cv2.imshow('server', frame)print("receive")except BlockingIOError as e:passif cv2.waitKey(1) & 0xFF == ord('q'):break
cv2.destroyAllWindows()
server.stop()
cap.release()

(2)web服务器

web服务采用了知名的fastapi库,自带websocket功能,也是几行代码就可以实现,这里主要注意的是,为了项目主逻辑运行,web要放到子线程中使用。主线程运行后,其它就不能运行了。
fastapi实现websocket也很简单:

	from fastapi import FastAPI, Response, WebSocket, WebSocketDisconnectfrom fastapi.responses import HTMLResponsefrom fastapi.staticfiles import StaticFilesfrom fastapi.templating import Jinja2Templates#from starlette.websockets import     import socket import jsonapp = FastAPI()# 设置静态文件和模板app.mount("/static", StaticFiles(directory="static"), name="static")templates = Jinja2Templates(directory="templates")# 获取本机IP地址def get_local_ip():try:s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)s.connect(("8.8.8.8", 80))ip = s.getsockname()[0]finally:s.close()return ip# HTML模板html_content = """some html"""@app.get("/", response_class=HTMLResponse)async def get():ip = get_local_ip()return HTMLResponse(html_content+ip+left+ip+tail)@app.websocket("/ws")async def websocket_endpoint(websocket: WebSocket):await websocket.accept()while True:try:data = await websocket.receive_text()print("receive:",data)if data=="ping":await websocket.send_text("pong")else:json_data = json.loads(data)                    ###do somethingresponse_data = {"code": 200,"left":round(lv_now,2),"right":round(rv_now,2)}await websocket.send_text(json.dumps(response_data))except WebSocketDisconnect:manager.disconnect(websocket)await manager.broadcast("A client disconnected.")import uvicornconfig = uvicorn.Config(app=app, host="0.0.0.0", port=9000)server = uvicorn.Server(config=config)singletonThread = threading.Thread(target=server.run)singletonThread.setDaemon(True)  singletonThread.start()

五、web端实现

web端使用与手机远程操控,主要布局设计如下:
各元素数值排列,适合手机端显示。
在这里插入图片描述

web端主要实现几个元素为:

(1)视频显示

此处采用标签连接mjpeg_streamer的流,实现视频画面的实时获取,在wif的环境下,实时性还是可以的。如web端不在与服务端同一台机器,则localhost改为服务端的ip地址,实现局域网远程获取画面。

<img style="-webkit-user-select: none; background-color: hsl(0,8%, 25%);" src="http://localhost:8000/my_camera" width="366*2" height="274*2">

在这里插入图片描述

(2)驾驶盘的实现

凭着简洁的思想,驾驶盘采用类似王者等手游的手柄效果,通过拖宅一个焦点在大圆内运动,实现小车两轮速度指令的获取。主要要点是:
1)焦点只能在大圆所在区域运动。
在这里插入图片描述
主要代码如下:

 function onMouseMove(e) {if (isDragging) {const centerX = e.clientX - bigCircle.getBoundingClientRect().left - (smallCircle.offsetWidth / 2);const centerY = e.clientY - bigCircle.getBoundingClientRect().top - (smallCircle.offsetHeight / 2);clampPosition(centerX, centerY); updateCoordinates(centerX, centerY);}}function clampPosition(centerX, centerY) {const maxRadius = bigCircle.offsetWidth / 2;let r=calculateDistanceFromCenter(centerX, centerY);let xy;if (r>maxRadius){xy=[prev_x,prev_y];}else{xy=[centerX,centerY];prev_x=centerX;prev_y=centerY;}const x=xy[0];const y=xy[1];xx=x;yy=y;// 设置小圆的左边距smallCircle.style.left = `${x}px`;// 设置小圆的上边距smallCircle.style.top = `${y}px`;}

2)当手或者鼠标释放时,焦点自动回到原心,同时速度指令缓慢归0,这样的目的是当速度较大行驶时,有个缓冲,不至于突然归0,导致击杀。

在这里插入图片描述
主要代码如下:

  function returnToCenter() {smallCircle.style.transition = 'all 0.3s ease-out';smallCircle.style.left = `${initialX}px`;smallCircle.style.top = `${initialY}px`;    decreaseValueR()}function decreaseValueR() {const interval = setInterval(() => {VL=dvv(VL);VR=dvv(VR);   console.log(`vv: ${VV},vl:${VL},vr:${VR}`);    if (VR==0 && VL==0){clearInterval(interval);console.log('R has reached 0');}    if (VV > 0) {VV -= maxV/5;if(VV<0)VV=0;//console.log(`vv: ${VV},vl:${VL},vr:${VR}`);} else if(VV<0) {    VV += maxV/5;       if(VV>0)VV=0;         }sendupdate();}, 100);}

3)捕捉小圆的角度,以及小圆离开圆心的距离,并通过一些坐标变换,换算成小车速度,左右轮速分配比例等

此处canvas坐标是x轴在上,向右为正,y轴在左,向下为正。而我们方向盘的习惯是跟常规解析几何坐标系相同,这里需要做一些变换,来计算小圆跟x轴的夹角,实际上求出来夹角正好正负相反。

function calculateAngleWithXAxis(x, y) {const centerX = initialX;const centerY = initialY;const deltaX = x - centerX;const deltaY = y - centerY;const angle = -Math.atan2(deltaY, deltaX) * (180 / Math.PI); // 夹角刚好正负相反Convert radians to degrees    return angle;}

4)设计了左右两个扇形死区。主要作用一个是避免速度在死区内振荡,因为人的手指也有抖动的时候,二个是把原地旋转刚好做到这个驾驶盘里面,实现了简洁性。
死区的处理:

if(a>=5 && a<175){//go forwardVV=r/maxRadius*maxV;VR=VV*2*rR;VL=VV*2*rL;}else if(a>-175 && a<-5){//go backwordVV=-r/maxRadius*maxV;VR=VV*2*rR;VL=VV*2*rL;}else if(a<=5&&a>=-5){VV=r/maxRadius*maxV;VR=-VV;VL=VV;}else if(a<=180&&a>=175){VV=r/maxRadius*maxV;VR=VV;VL=-VV;}else if(a>=-180&&a<=-175){VV=r/maxRadius*maxV;VR=VV;VL=-VV;}

(3)心跳

心跳主要是为了维持远程操控的生命周期,防止一旦超出wifi范围,失去心跳后,小车会立即停止。
在这里插入图片描述
在这里插入图片描述

整体的操控效果如下:
在这里插入图片描述

web端配套资源源代码已经上传,下载地址

六、总结

总体来说,在仿真环境下,操控体验还是比较顺畅。主要一些问题是,摄像头的视野较为狭窄,仿真环境中已经使用了120度的广角,一个措施是更改摄像头的安装位置,装的高一些,看到车头和更广的环境,这样有利于远程驾驶。还有就是,可以把画面做得更大一些。
仿真环境vrep的api,sim.py好像长久获取图像不是很稳定,运行一段实际会出现一些内存错误,但不影响学习研究。下篇,我们将此技术用于实际小车的操控。
在这里插入图片描述

七、源码或环境

web端配套资源源代码已经上传,下载地址
仿真配套资源已经上传:下载地址

[------------本篇完--------------------------]

PS.扩展阅读

————————————————————————————————————————

对于python机器人编程感兴趣的小伙伴,可以进入如下链接阅读相关咨询

ps1.六自由度机器人相关文章资源

(1) 对六自由度机械臂的运动控制及python实现(附源码)
在这里插入图片描述

(2) N轴机械臂的MDH正向建模,及python算法
在这里插入图片描述

ps2.四轴机器相关文章资源

(1) 文章:python机器人编程——用python实现一个写字机器人
在这里插入图片描述

在这里插入图片描述

(2)python机器人实战——0到1创建一个自动是色块机器人项目-CSDN直播

(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(4)实现了语音输入+大模型指令解析+机器视觉+机械臂流程打通
在这里插入图片描述
在这里插入图片描述

ps3.移动小车相关文章资源

(1)python做了一个极简的栅格地图行走机器人,到底能干啥?[第五弹]——解锁蒙特卡洛定位功能-CSDN博客
(2) 对应python资源:源码地址
在这里插入图片描述
在这里插入图片描述

(3)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(上篇)_agv编程-CSDN博客
(4)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇)_agv路线规划原则python-CSDN博客
对应python及仿真环境资源:源码链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1540435.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

情感类智能体——你的微信女神

智能体名称&#xff1a;你的微信女神 链接&#xff1a;文心智能体平台AgentBuilder | 想象即现实 (baidu.com)https://agents.baidu.com/agent/preview/RulbsUjIGj4wsinydlBH7AR3NQKFungt 简介 “你的微信女神”是一个直率的智能体&#xff0c;她用犀利而真实的言辞帮助用户…

Jboss CVE-2015-7501 靶场攻略

漏洞介绍 这是经典的JBoss反序列化漏洞&#xff0c;JBoss在/invoker/JMXInvokerServlet请求中读取了⽤户传⼊的对象&#xff0c;然后我们利⽤Apache Commons Collections中的 Gadget 执⾏任意代码 影响范围 JBoss Enterprise Application Platform 6.4.4,5.2.0,4.3.0_CP10 …

交易量大幅下滑,被华尔街投行下调目标价,是时候卖出Coinbase股票了吗?

猛兽财经核心观点&#xff1a; &#xff08;1&#xff09;由于交易量出现了大幅下滑&#xff0c;华尔街投行杰富瑞已经将Coinbase的目标下调到了220美元&#xff0c; &#xff08;2&#xff09;尽管2024年第二季度订阅和服务业务增长强劲&#xff0c;但Coinbase的财务业绩还是未…

Jenkins自动化部署后端项目看这篇就够了

本文主要讲解&#xff0c;使用Jenkins自动化部署后端工程。讲解怎么自动化部署前后的分离项目中的后端工程。 前提条件&#xff1a;本地需要Jenkins&#xff0c;如果你不知道怎么安装&#xff0c;可以看我的另外一篇文章。 Jenkins实现自动部署的步骤&#xff1a; 先拉取git…

9.20作业

手动封装一个顺序表&#xff08;SeqList&#xff09;,分文件编译实现 有私有成员&#xff1a; 顺序表数组的起始地址 ptr、 顺序表的总长度&#xff1a;size、顺序表的实际长度&#xff1a;len 成员函数&#xff1a; 初始化 init(int n) 判空&#xff1a;empty 判满&#xff1…

计算机毕业设计 美发管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Chat2VIS: Generating Data Visualizations via Natural Language

Chat2VIS:通过使用ChatGPT, Codex和GPT-3大型语言模型的自然语言生成数据可视化 梅西大学数学与计算科学学院&#xff0c;新西兰奥克兰 IEEE Access 1 Abstract 数据可视化领域一直致力于设计直接从自然语言文本生成可视化的解决方案。自然语言接口 (NLI) 的研究为这些技术的…

从虚拟到现实:数字孪生与数字样机的进化之路

数字化技术高速发展的当下&#xff0c;计算机辅助技术已成为产品设计研发中不可或缺的一环&#xff0c;数字样机&#xff08;Digital Prototype, DP&#xff09;与数字孪生技术便是产品研发数字化的典型方法。本文将主要介绍数字样机与数字孪生在国内外的发展&#xff0c;并针对…

Java 并发编程 —— AQS 抽象队列同步器

文章目录 什么是 AQS底层数据结构—— CLH 队列入队和出队状态标志位AQS 的代码设计思路AQS 提供的钩子方法参考资料 什么是 AQS AQS 是 JUC 提供的一个用于构建锁和同步容器的基础类&#xff0c;用于减少由于无效争夺导致的资源浪费和性能恶化。JUC 包内的许多类都是基于 AQS…

【JPCS出版】第四届电气工程与计算机技术国际学术会议(ICEECT 2024,9月27-29)

会议信息 会议官网&#xff1a;www.iceect.com 2024 4th International Conference on Electrical Engineering and Computer Technologywww.iceect.com 时间地点&#xff1a;2024年9月27日-29日 | 线上&#xff08;ZOOM&#xff09; 最终截稿时间&#xff1a;9月23日 主办…

【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略

文章目录 C类与对象前言读者须知RVO 与 NRVO 的启用条件如何确认优化是否启用&#xff1f; 1. 按值传递与拷贝省略1.1 按值传递的概念1.2 示例代码1.3 按值传递的性能影响1.3.1 完全不优化 1.4 不同编译器下的优化表现1.4.1 Visual Studio 2019普通优化1.4.2 Visual Studio 202…

2024.9.20营养小题【1】

这道题并不难&#xff0c;但是通过这道题&#xff0c;对知识有了一些更深一点的理解吧。 我们知道&#xff0c;数组名代表的其实是数组中首元素的指针&#xff1b;字符串其实是一个数组&#xff1b;所以字符串名是指向字符串中首元素地址的指针&#xff1b;strlen(字符串名&am…

Spring Boot利用dag加速Spring beans初始化

1.什么是Dag&#xff1f; 有向无环图(Directed Acyclic Graph)&#xff0c;简称DAG&#xff0c;是一种有向图&#xff0c;其中没有从节点出发经过若干条边后再回到该节点的路径。换句话说&#xff0c;DAG中不存在环路。这种数据结构常用于表示并解决具有依赖关系的问题。 DAG的…

什么是损失函数?常见的损失函数有哪些?

损失函数 什么是损失函数&#xff1f;损失函数作用如何设计损失函数常见的损失函数有哪些&#xff1f; 什么是损失函数&#xff1f; 损失函数&#xff08;Loss Function&#xff09;&#xff0c;也称为误差函数&#xff0c;是机器学习和深度学习中的一个重要概念。它用于衡量模…

python怎么打开编辑器

1、在电脑开始菜单中点击所有程序&#xff0c;找到Python程序&#xff0c;点击其中idle。 2、然后点击左上角的“File”&#xff0c;打开菜单&#xff0c;在下拉菜单中选择“New File”选项&#xff0c;就可打开python编辑器了。 3、在打开的python编辑器中就可以输入自己想写的…

105.游戏安全项目-基址的技术原理-分析技巧

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信…

如何衡量企业品牌力?判断指标有哪些?

企业品牌力是指品牌在市场中的竞争力和影响力&#xff0c;它反映了品牌的价值、知名度、忠诚度、感知质量、差异化以及市场表现等方面。要去衡量一个企业的品牌力&#xff0c;大多从品牌的知名度、忠诚度、所占市场份额、顾客口碑、社媒影响力、品牌资产价值等多方面去判断。我…

sqoop的安装与简单使用

文章目录 一、安装1、上传&#xff0c;解压&#xff0c;重命名2、修改环境变量3、修改配置文件4、上传驱动包5、拷贝jar包 二、import命令1、将mysql的数据导入到hdfs上2、将mysql的数据导入到hive上3、增量导入数据 三、export命令1、从hdfs导出到mysql中2、从hive导出到mysql…

企业微信oauth2提示应用无法使用

问题描述&#xff1a; 生成oauth2之后&#xff0c;我a公司是服务商&#xff0c;我给b公司的人去点授权链接会提示这个 应用服务商还没有在企业微信为你开通接口调用许可」&#xff0c;导致无法使用此应用&#xff0c;请联系服务商开通 正文 你先要知道一件事&#xff01;&…

Jenkins私有化部署

最终目标 与GitLab配合&#xff0c;实践前端自动化&#xff0c;详细内容移步基于Jenkins和GitLab的前端自动化实践 前置条件 一台云服务器云服务器上已安装Docker了解Docker基础 使用Docker安装Jenkins 参考github文档安装 docker run --name docker_jenkins --privilege…