当前位置: 首页 > news >正文

无人车沿着指定线路自动驾驶与远程控制的实践应用

有了前面颜色识别跟踪的基础之后,我们就可以设定颜色路径,让无人车沿着指定线路做自动驾驶了,视频:PID控制无人车自动驾驶

有了前几章的知识铺垫,就比较简单了,也是属于颜色识别的一种应用,主要是掌握自动驾驶中的一些基础知识,这样就可以进一步去了解在无人驾驶当中遇到的各种问题

1、导入库并初始化

from jetbotmini import Camera
from jetbotmini import bgr8_to_jpeg
from IPython.display import display
from jetbotmini import Robot
import numpy as np
import torch
import torchvision
import cv2
import traitlets
import ipywidgets.widgets as widgets
import numpy as np#初始化摄像头
camera = Camera.instance(width=300, height=300)
#初始化机器人马达
robot = Robot()#使用PID控制
import PIDturn_gain = 1.7
turn_gain_pid = PID.PositionalPID(0.15, 0, 0.05)

这部分很简单,依然是初始化摄像头用来颜色识别,机器人也叫马达,用来驱动轮子的运动,加一个PID控制,让无人车更加的平稳。

2、显示部件

# 红色数组
color_lower=np.array([156,43,46])
color_upper = np.array([180, 255, 255])image_widget = widgets.Image(format='jpeg', width=300, height=300)
speed_widget = widgets.FloatSlider(value=0.4, min=0.0, max=1.0, description='speed')display(widgets.VBox([widgets.HBox([image_widget]),speed_widget,
]))width = int(image_widget.width)
height = int(image_widget.height)def execute(change):global turn_gaintarget_value_speed = 0#更新图片值frame = camera.valueframe = cv2.resize(frame, (300, 300))frame = cv2.GaussianBlur(frame,(5,5),0)                    hsv =cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)mask=cv2.inRange(hsv,color_lower,color_upper)  mask=cv2.erode(mask,None,iterations=2)mask=cv2.dilate(mask,None,iterations=2)mask=cv2.GaussianBlur(mask,(3,3),0)     cnts=cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2] # 检测到目标if len(cnts)>0:cnt = max (cnts,key=cv2.contourArea)(color_x,color_y),color_radius=cv2.minEnclosingCircle(cnt)if color_radius > 10:# 将检测到的颜色标记出来cv2.circle(frame,(int(color_x),int(color_y)),int(color_radius),(255,0,255),2)  # 中心偏移量center = (150 - color_x)/150#转向增益PID调节turn_gain_pid.SystemOutput = centerturn_gain_pid.SetStepSignal(0)turn_gain_pid.SetInertiaTime(0.2, 0.1)#将转向增益限制在有效范围内target_value_turn_gain = 0.15 + abs(turn_gain_pid.SystemOutput)if target_value_turn_gain < 0:target_value_turn_gain = 0elif target_value_turn_gain > 2:target_value_turn_gain = 2#将输出电机速度保持在有效行驶范围内target_value_speedl = speed_widget.value - target_value_turn_gain * centertarget_value_speedr = speed_widget.value + target_value_turn_gain * centerif target_value_speedl<0.3:target_value_speedl=0elif target_value_speedl>1:target_value_speedl = 1if target_value_speedr<0.3:target_value_speedr=0elif target_value_speedr>1:target_value_speedr = 1#设置马达速度robot.set_motors(target_value_speedl, target_value_speedr)# 没有检测到目标else:robot.stop()# 更新图像显示至小部件image_widget.value = bgr8_to_jpeg(frame)

这里是关键部分,检测目标(这里是红颜色),然后通过其检测的位置来控制左右马达的速度,驱动无人车的行驶与转弯,后台通过图像部件来显示无人车的跟踪情况,方便看到无人车在整个行驶过程中的各种状态。

3、调用并执行

execute({'new': camera.value})
camera.unobserve_all()
camera.observe(execute, names='value')

这里就是前面介绍的,通过调用observer方法来更新摄像头的数据,使用的是一个上面定义的execute的一个回调方法。

4、停止无人车

import time
camera.unobserve_all()
time.sleep(1.0)
robot.stop()

5、倒车

前面介绍的是向前行驶和转弯,还缺少一个能倒车的功能,恩,很简单,调用backward函数即可

robot.backward(0.8)
time.sleep(0.5)
robot.stop()

6、调节颜色数组

我这里是用红色的胶带粘贴在地板上,所以使用的是红色的数组,当然这里我们可以显示mask来测试颜色数组是否设置的比较恰当,代码如下

from  matplotlib import pyplot as plt
%matplotlib inline
from IPython import displayfor i in range(10):frame = camera.valueframe = cv2.resize(frame, (300, 300))frame_=cv2.GaussianBlur(frame,(5,5),0)                    hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)mask=cv2.inRange(hsv,color_lower,color_upper) # 颜色数组的取值范围mask=cv2.erode(mask,None,iterations=2)mask=cv2.dilate(mask,None,iterations=2)mask=cv2.GaussianBlur(mask,(3,3),0)  plt.imshow(mask)plt.show()#display.clear_output(wait=True)

这里我将display.clear_output(wait=True)注释,将会连续生成10张图片,全部在Jupyter中展示出来。我们也可以去掉注释,这样每次的生成将会清除上一次的图片,这样便于更好地观察。10张连续图片也做成了动图便于大家了解:

 如果这里没有出现mask或者比较少的情况,就需要调节颜色数组,让其更好地匹配线路。

7、模拟方向盘

有些时候不想要自动驾驶来控制,而且很多场景更需要人来远程控制,比如在矿山等危险地方,最好的方法就是能够远程去控制工程车去进行作业。
有了上面的向前向后和转弯的了解后,我们就可以制作一个模拟方向盘来控制无人车了。

7.1、按钮部件

# 创建按钮
button_layout = widgets.Layout(width='100px', height='80px', align_self='center')
stop_button = widgets.Button(description='停止', button_style='danger', layout=button_layout)
forward_button = widgets.Button(description='向前', layout=button_layout)
backward_button = widgets.Button(description='向后', layout=button_layout)
left_button = widgets.Button(description='向左', layout=button_layout)
right_button = widgets.Button(description='向右', layout=button_layout)# 显示按钮
middle_box = widgets.HBox([left_button, stop_button, right_button], layout=widgets.Layout(align_self='center'))
controls_box = widgets.VBox([forward_button, middle_box, backward_button])
display(controls_box)

如图:

方向盘的布局,通过widgets.Layout创建层,在这个上面通过widgets.Button创建按钮,然后将按钮通过widgets.HBoxwidgets.VBox进行横向和垂直的排版即可。Horizontal:水平的,横向。Vertical:垂直的

7.2、方向控制方法

def stop(change):robot.stop()def step_forward(change):robot.forward(0.8)time.sleep(0.5)robot.stop()def step_backward(change):robot.backward(0.8)time.sleep(0.5)robot.stop()def step_left(change):robot.left(0.6)time.sleep(0.5)robot.stop()def step_right(change):robot.right(0.6)time.sleep(0.5)robot.stop()

前后左右加停止按钮的方法,方法体很简单,就是控制左右马达的速度。

7.3、按钮动作

定义好了各自方法之后,只需要将方法绑定到各自的按钮就可以了。

stop_button.on_click(stop)
forward_button.on_click(step_forward)
backward_button.on_click(step_backward)
left_button.on_click(step_left)
right_button.on_click(step_right)

这样就可以点击按钮,远程控制无人车了。

8、心跳开关

最后就是介绍下心跳开关,检测无人车与浏览器的连接是否还存在的一种简单方法。可以通过下面显示的滑块调整心跳周期(以秒为单位),如果两次心跳之内不能在浏览器之间往返通信的,那么心跳的status(状态)属性值将会设置为dead,一旦连接恢复连接,status属性将设置为alive

from jetbotmini import Heartbeatheartbeat = Heartbeat()# 这个函数将在心跳状态改变时被调用
def handle_heartbeat_status(change):if change['new'] == Heartbeat.Status.dead:robot.stop()heartbeat.observe(handle_heartbeat_status, names='status')period_slider = widgets.FloatSlider(description='period', min=0.001, max=0.5, step=0.01, value=0.5)
traitlets.dlink((period_slider, 'value'), (heartbeat, 'period'))display(period_slider, heartbeat.pulseout)

 自动驾驶的相关知识点介绍完毕,有错误之处,请指正,一起学习与进步!

相关文章:

无人车沿着指定线路自动驾驶与远程控制的实践应用

有了前面颜色识别跟踪的基础之后&#xff0c;我们就可以设定颜色路径&#xff0c;让无人车沿着指定线路做自动驾驶了&#xff0c;视频&#xff1a;PID控制无人车自动驾驶 有了前几章的知识铺垫&#xff0c;就比较简单了&#xff0c;也是属于颜色识别的一种应用&#xff0c;主要…...

C++ 多态性——纯虚函数与抽象类

抽象类是一种特殊的类&#xff0c;它为一个类族提供统一的操作界面。抽象类是为了抽象和设计的目的而建立的。可以说&#xff0c;建立抽象类&#xff0c;就是为了通过它多态地使用其中的成员函数。抽象类处于类层次的上层&#xff0c;一个抽象类自身无法实例化&#xff0c;也就…...

小程序如何使用防抖和节流?

防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;都是用来优化函数执行频率的技术&#xff0c;特别在处理用户输入、滚动等频繁触发的情况下&#xff0c;它们可以有效减少函数的执行次数&#xff0c;从而提升性能和用户体验。但它们的工作方式和应…...

计算机三级网络技术(持续更新)

BGP考点 A S&#xff1a;自治系统 BGP: Border Gateway Protocol&#xff08;当前使用的版本是 BGP-4&#xff09;外部网关协议 动态路由协议可以按照工作范围分为IGP以及EGP。IGP工作在同一个AS内&#xff0c;主要用来发现和计算路由&#xff0c;为AS内提供路由信息的交换&…...

Django Rest_Framework(二)

文章目录 1. http请求响应1.1. 请求与响应1.1.1 Request1.1.1.1 常用属性1&#xff09;.data2&#xff09;.query_params3&#xff09;request._request 基本使用 1.1.2 Response1.1.2.1 构造方式1.1.2.2 response对象的属性1&#xff09;.data2&#xff09;.status_code3&…...

Kotlin~Visitor访问者模式

概念 将数据结构和操作分离&#xff0c;使操作集合可以独立于数据结构变化。 角色介绍 Visitor&#xff1a;抽象访问者&#xff0c;为对象结构每个具体元素类声明一个访问操作。Element&#xff1a;抽象元素&#xff0c;定义一个accept方法ConcreteElement&#xff1a;具体元…...

LVS-DR模式集群构建过程演示

一、工作原理 LVS的工作原理 1.当用户向负载均衡调度器&#xff08;Director Server&#xff09;发起请求&#xff0c;调度器将请求发往至内核空间 2.PREROUTING链首先会接收到用户请求&#xff0c;判断目标IP确定是本机IP&#xff0c;将数据包发往INPUT链 3.IPVS是工作在IN…...

UML-A 卷-知识考卷

UML-A 卷-知识考卷 UML有多少种图&#xff0c;请列出每种图的名字&#xff1a; 常用的几种UML图&#xff1a; 类图&#xff08;Class Diagram&#xff09;&#xff1a;类图是描述类、接口、关联关系和继承关系的图形化表示。它展示了系统中各个类之间的静态结构和关系。时序…...

BpBinder与PPBinder调用过程——Android开发Binder IPC通信技术

在Android系统中&#xff0c;进程间通信&#xff08;IPC&#xff09;是一个非常重要的话题。Android系统通过Binder IPC机制实现进程间通信&#xff0c;而Binder IPC通信技术则是Android系统中最为重要的进程间通信技术之一。本文将介绍Binder IPC通信技术的原理&#xff0c;并…...

篇十五:模板方法模式:固定算法的步骤

篇十五&#xff1a;"模板方法模式&#xff1a;固定算法的步骤" 设计模式是软件开发中的重要知识&#xff0c;模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一个算法的骨架&#xff0c;将算法中一些步骤的具…...

web-ssrf

目录 ssrf介绍 以pikachu靶场为例 curl 访问外网链接 利用file协议查看本地文件 利用dict协议扫描内网主机开放端口 file_get_content 利用file协议查看本地文件&#xff1a; fsockopen() 防御方式: ssrf介绍 服务器端请求伪造&#xff0c;是一种由攻击者构造形成…...

【HarmonyOS】【续集】实现从视频提取音频并保存到pcm文件功能(API6 Java)

【关键字】 视频提取类Extractor、视频编解码、保存pcm文件、getAudioTime 【背景和问题】 上篇中介绍了从视频提取音频并保存到pcm文件功能&#xff0c;请参考文档&#xff1a;https://developer.huawei.com/consumer/cn/forum/topic/0209125665541017202?fid0101591351254…...

MySQL为什么要使用 B+Tree 作为索引结构?

MySQL为什么要使用 BTree 作为索引结构&#xff1f; 基本情况 常规的数据库存储引擎 &#xff0c;一般都是采用 B 树或者 B树来实现索引的存储。B树是一种多路平衡树&#xff0c;用这种存储结构来存储大量数据&#xff0c;它的整个高度 会相比二叉树来说 &#xff0c;会矮很多…...

Three.js阴影

目录 Three.js入门 Three.js光源 Three.js阴影 使用灯光后&#xff0c;场景中就会产生阴影。物体的背面确实在黑暗中&#xff0c;这称为核心阴影&#xff08;core shadow&#xff09;。我们缺少的是落下的阴影&#xff08;drop shadow&#xff09;&#xff0c;即对象在其他…...

VSCode Remote-SSH (Windows)

1. VSCode 安装 VSCode 2. 安装扩展 Remote SSH Getting started Follow the step-by-step tutorial or if you have a simple SSH host setup, connect to it as follows: Press F1 and run the Remote-SSH: Open SSH Host… command.Enter your user and host/IP in the …...

现代C++中的从头开始深度学习【1/8】:基础知识

一、说明 提及机器学习框架与研究和工业的相关性。现在很少有项目不使用Google TensorFlow或Meta PyTorch&#xff0c;在于它们的可扩展性和灵活性。也就是说&#xff0c;花时间从头开始编码机器学习算法似乎违反直觉&#xff0c;即没有任何基本框架。然而&#xff0c;事实并非…...

Jwt(Json web token)——使用token的权限验证方法 用户+角色+权限表设计 SpringBoot项目应用

目录 引出使用token的权限验证方法流程 用户、角色、权限表设计权限表角色表角色-权限关联表用户表查询用户的权限&#xff08;四表联查&#xff09;数据库的视图 项目中的应用自定义注解拦截器controller层DTO返回给前端枚举类型的json化日期json问题 实体类-DAO 总结 引出 1.…...

SpringWeb项目核心功能总结

SpringWeb项目核心功能总结 文章目录 SpringWeb项目核心功能总结1.浏览器与Java程序的连接&#xff08;个人偏好使用RequestMapping&#xff09;2.参数的传入3.结果的返回请求转发和请求重定向的区别 核心功能用到的注解&#xff1a; RestControllerControllerResponseBodyRequ…...

Django------信号

Django 框架包含了一个信号机制&#xff0c;它允许若干个发送者&#xff08;sender&#xff09;通知一组接收者&#xff08;receiver&#xff09;某些特定操作或事件(events)已经发生了&#xff0c; 接收者收到指令信号(signals)后再去执行特定的操作。本文主要讲解Django信号(…...

HTML5 中新增了哪些表单元素?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ HTML5 中新增了的表单元素⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...