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

有了前面颜色识别跟踪的基础之后,我们就可以设定颜色路径,让无人车沿着指定线路做自动驾驶了,视频: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)

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在业务中体现TCC事务模型?

在分布式系统设计中&#xff0c;随着微服务的流行&#xff0c;通常一个业务操作被拆分为多个子任务&#xff0c;比如电商系统的下单和支付操作&#xff0c;就涉及到了创建和更新订单、扣减账户余额、扣减库存、发送物流消息等&#xff0c;那么在复杂业务开发中&#xff0c;如何…

关于丢失安卓秘钥的撞sha-1值的办法

实验得知&#xff0c;安卓sha-1和keytool生成秘钥签名文件的时间有关。 前提条件是&#xff0c;开发者必须知道生成秘钥的所有细节参数 以下是撞文件代码&#xff08;重复生成&#xff09; import time import osidx 0while True:cmdkeytool -keyalg RSA -genkeypair -alia…

比特鹏哥-数据类型和变量【自用笔记】

这里写目录标题 1.数据类型介绍字符&#xff0c;整型&#xff0c;浮点型&#xff0c;布尔类型 2.signed 和unsigned3.数据类型的取值范围sizeof 展示字节大小--- 计算机中单位&#xff1a;字节 4.变量 常量4.1 变量创建变量&#xff08;数据类型 变量名&#xff09;创建变量的时…

【Spring Cloud 七】Sleuth+Zipkin 链路追踪

Sleuth链路追踪 系列博客背景一、 什么是链路追踪二、为什么要有链路追踪三、Sleuth与ZipkinSleuthZipkinSleuth和Zipkin的关系是什么&#xff1f; 四、使用Sleuthzipkin进行链路追踪4.1下载zipkin4.2案例说明项目代码服务提供者pom文件yml配置文件项目启动类controller 抽离出…

Tensorflow2-初识

TensorFlow2是一个深度学习框架&#xff0c;可以理解为一个工具&#xff0c;有谷歌的全力支持&#xff0c;具有易用、灵活、可扩展、性能优越、良好的社区资源等优点。 1、环境的搭建 1.1 Anaconda3的安装 https://www.anaconda.com/ Python全家桶&#xff0c;包括Python环境和…

jmeter使用步骤

jmeter 使用步骤 1&#xff0c;进入jmeter目录中的bin目录&#xff0c;双击jmeter.bat 打开 2&#xff0c;右键test plan 创建线程组 3&#xff0c;配置线程组参数 4&#xff0c;右键刚刚创建的线程组&#xff0c;创建请求&#xff0c;填写请求地址 5&#xff0c;需要携带to…

Spring Boot如何整合mybatisplus

文章目录 1. 相关配置和代码2. 整合原理2.1 spring boot自动配置2.2 MybatisPlusAutoConfiguration2.3 debug流程2.3.1 MapperScannerRegistrar2.3.2MapperScannerConfigurer2.3.3 创建MybatisPlusAutoConfiguration2.3.4 创建sqlSessionFactory2.3.5 创建SqlSessionTemplate2.…

科研热点|5本Scopus期刊不再被收录,Scopus期刊目录更新(附下载)!

此次Scopus期刊目录更新后&#xff0c;有5本期刊不再被收录&#xff08;Discontinued titles July 2023&#xff09;&#xff0c;同上次更新时相比&#xff0c;此次又新增139本期刊(Accepted titles)进入Scopus数据库。目前Scopus 来源出版物列表&#xff08;Scopus Sources&am…

全志F1C200S嵌入式驱动开发(soc系统集成)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 任何一个嵌入式设备都是由很多的子系统组成的。这里面有硬件、有软件,还可能有机械,并不一定就是大家看到的消费电子那样,即一个soc构成了所有的系统。现实情况是,要构建一个系…

使用Python将图像转换为PDF:一次性解决您的批量转换需求

导语&#xff1a; 在数字化时代&#xff0c;我们经常需要处理大量的图像文件。将这些图像转换为PDF格式可以方便地存档、分享和打印。本文将介绍如何使用Python编程语言将图像批量转换为PDF&#xff0c;并提供了一个简单易用的图形界面来跟踪转换进度。 准备工作 在开始之前…

一个Linux驱动工程师必知的内核编译机制

Linux内核的编译主要过程&#xff1a;配置、编译、安装。 配置主要由Kconfig提供图形界面完成编译主要基于Kbuild编译系统&#xff0c;执行make完成编译安装主要也是基于Kbuild提供的脚本&#xff0c;然后执行make完成安装 Kconfig Kconfig用于内核的配置&#xff0c;make m…

Kafka入门,保姆级教学

文章目录 Kafka概念消息中间件对比消息中间件对比-选择建议Kafka常用名词介绍Kafka入门1. Kafka安装配置2.Kafka生产者与消费者关系3.Kafka依赖4.生产者发消息5.消费者接受消息6.Kafka高可用性设计6.1集群Kafka备份机制(Reolication) 7.kafka生产者详解7.1 发送类型7.2参数详解…

任务12、Quality指令加持,Midjourney生成电影级数码作品

12.1 任务概述 本次实验任务旨在帮助你掌握Midjourney AI绘画中的Quality指令。通过深入介绍Quality指令的概念和作用,我们将解释为什么它在绘画中至关重要。通过测试不同的Quality参数对绘画效果的影响,并提供实战演示,你将学会如何在Midjourney中设置Quality参数以达到更…

背包问题一维写法(状态压缩)实战,其二(目标和、零一和)

给定一个非负整数数组&#xff0c;a1, a2, ..., an, 和一个目标数&#xff0c;S。现在你有两个符号 和 -。对于数组中的任意一个整数&#xff0c;你都可以从 或 -中选择一个符号添加在前面。 返回可以使最终数组和为目标数 S 的所有添加符号的方法数。 示例&#xff1a; 输…

node上传文件 + vue3 + elementPlus 组件封装

一、node 1.在node环境中安装multer(node.js中间件)包&#xff0c;用于处理 multipart/form-data 类型的表单数据 npm install --save multer 2.userRouter var express require(express); const multer require(multer) const upload multer({ dest: public/avataruplo…

“实现数字化转型:探索会议OA项目的高级技术与创新应用“

文章目录 引言&#xff1a;1.项目背景和需求分析&#xff1a;2.技术选型和架构设计&#xff1a;3.项目实现和功能亮点&#xff1a;3.0 layui实现登录及注册3.1 会议管理模块3.1.1 会议发布3.1.2 我的会议3.1.3 我的审批3.1.4 会议通知3.1.5 待开会议3.1.6 历史会议3.1.7 所有会…

学生管理系统(升级版)

import java.util.ArrayList; import java.util.Random; import java.util.Scanner;public class Demo_学生管理系统 {public static void main(String[] args) {ArrayList<User> list new ArrayList<>();Scanner sc new Scanner(System.in);while (true) {Syste…

浅谈新电改背景下电网企业综合能源服务商业模式研究及发展方向

安科瑞 华楠 摘要: 新电改方案实施后&#xff0c;由于输配电价的改革和售电侧的放开&#xff0c;电网企业的盈利模式也随之发生了变化。这就要求电网企业转变服务理念与经营方式&#xff0c;来寻求竞争优势。基于“魏朱六要素商业模式”模型&#xff0c;对电网企业综合能源服务…

每天五分钟机器学习:梯度下降算法和正规方程的比较

本文重点 梯度下降算法和正规方程是两种常用的机器学习算法,用于求解线性回归问题。它们各自有一些优点和缺点,下面将分别对它们进行详细的讨论。 区别 1. 梯度下降算法是一种迭代的优化算法,通过不断迭代调整参数来逼近最优解。它的基本思想是根据目标函数的梯度方向,沿…

陪诊小程序开发|陪诊系统定制|数字化医疗改善就医条件

健康问题这几年成为人们关注的焦点之一&#xff0c;然而看病却是一个非常麻烦的过程&#xff0c;特别是对于那些身处陌生城市或者不熟悉就医流程的人来说。幸运的是现在有了陪诊小程序下&#xff0c;为您提供便捷的助医服务&#xff0c;使得就医过程得更加简单和轻松。 陪诊系统…