arduino 停止程序_建立Arduino机器人,第五部分:障碍规避

a2a191e6ffb90d70d726726f9ee8179e.png

欢迎阅读教程系列的第五篇文章,其中我正在构建一个基于遥控Arduino的车辆机器人。

这是我到目前为止发表的文章列表:

  • 第一部分:硬件组件
  • 第二部分:Arduino编程
  • 第三部分:组装机器人
  • 第四部分:A(不是那样)基本机器人固件
  • 第五部分:避免障碍(本文)
  • 第六部分:远程控制

在上一篇文章中,我写了我的Michelino机器人固件的第一个版本,其中包括一个电机控制器驱动程序。今天我正在增加对距离传感器的支持。

距离传感器驱动器

正如我在上一篇文章中所示,只要为其编写了设备驱动程序,我的固件就可以处理任何电机控制器板。此上下文中的设备驱动程序只不过是一个实现我为此类设备定义的通用接口的类。

距离传感器没有什么不同,可以应用相同的想法。首先,我将定义所有距离传感器设备通用的接口。这将进入文件distance_sensor.h:

/** * @file distance_sensor.h * @brief distance sensor driver definition for the Michelino robot. * @author Miguel Grinberg */namespace Michelino{ class DistanceSensorDriver { public: /** * @brief Class constructor. * @param distance The maximum distance in centimeters that needs to be tracked. */ DistanceSensorDriver(unsigned int distance) : maxDistance(distance) {} /** * @brief Return the distance to the nearest obstacle in centimeters. * @return the distance to the closest object in centimeters  * or maxDistance if no object was detected */ virtual unsigned int getDistance() = 0; protected: unsigned int maxDistance; };};

我的距离传感器驱动器非常简单,驾驶员只需提供一种方法,以厘米为单位报告距离最近物体的距离。这就是我现在所需要的,我总是可以回来并在以后为驱动程序定义添加更多功能。

驱动程序的构造函数占用最大距离。这是在getDistance()没有检测到障碍物时将返回的值。

请注意,maxDistance成员变量位于protected块中,而不是private像我在其他类中使用的块。protected对于外部仍然是私有的变量,但子类可以访问它们。我希望这个驱动程序的实现可以访问这个值,这就是我创建它的原因protected。

正如我在上一篇文章中提到的,我发现我正在使用的HC-SR04距离传感器与arduino-new-ping开源库非常相配,所以我现在将为它实现上面的驱动程序接口档案newping_distance_sensor.h:

/** * @file newping_distance_sensor.h * @brief distance sensor driver for distance sensors supported by the NewPing library. * @author Miguel Grinberg */#include "distance_sensor.h"namespace Michelino{ class DistanceSensor : public DistanceSensorDriver { public: DistanceSensor(int triggerPin, int echoPin, int maxDistance) : DistanceSensorDriver(maxDistance),  sensor(triggerPin, echoPin, maxDistance) { } virtual unsigned int getDistance() { int distance = sensor.ping_cm(); if (distance <= 0) return maxDistance; return distance; } private: NewPing sensor; };};

请注意getDistance()实现如何maxDistance访问父类中定义的成员变量。如果我在private块中定义了此变量,则此代码将无法编译。

与固件集成

作为第一次集成测试,让机器人前进并在发现障碍物时停止。

我将从我在前一篇文章中编写的固件开始,并将替换initialize()和run()方法,它们是我面向Arduino setup()和loop()函数的面向对象。如果您不熟悉,可能需要返回该文章以查看完整草图的结构。

在草图的顶部,我使用与电机控制器相同的结构包括驱动器:

#define ENABLE_NEWPING_DISTANCE_SENSOR_DRIVER#ifdef ENABLE_NEWPING_DISTANCE_SENSOR_DRIVER#include #include "newping_distance_sensor.h"#define DISTANCE_SENSOR_INIT 14,15,MAX_DISTANCE#endif

在类的private部分中创建Robot一个DistanceSensor对象:

private: DistanceSensor distanceSensor;

在Robot类构造函数中初始化对象:

Robot() : leftMotor(LEFT_MOTOR_INIT), rightMotor(RIGHT_MOTOR_INIT), distanceSensor(DISTANCE_SENSOR_INIT){ initialize();}

在initialize()方法中,我启动电机并将状态设置为运行

void initialize(){ leftMotor.setSpeed(255); rightMotor.setSpeed(255); state = stateRunning;}

并且在该run()方法中,当距离传感器发现近距离障碍时,我停止电机:

void run(){ if (state == stateRunning) { if (distanceSensor.getDistance() <= TOO_CLOSE) { state = stateStopped; leftMotor.setSpeed(0); rightMotor.setSpeed(0); } }}

我在上面的所有更改中使用了两个常量,MAX_DISTANCE并且TOO_CLOSE。这些常量在草图的顶部定义,以便在需要修改时很容易找到它们:

#define TOO_CLOSE 10#define MAX_DISTANCE (TOO_CLOSE * 20)

我将使用10厘米的距离来考虑障碍物太近。我需要跟踪的最大距离是该距离的20倍或2米。这些是我凭空掏出的数字,我真的不知道它们是否会起作用,但在我有机会测试之后我总能回来调整它们。

草图现在处于可用状态。以下是完整的michelino.ino草图源代码:

#define ENABLE_ADAFRUIT_MOTOR_DRIVER#define ENABLE_NEWPING_DISTANCE_SENSOR_DRIVER#define TOO_CLOSE 10#define MAX_DISTANCE (TOO_CLOSE * 20)#ifdef ENABLE_ADAFRUIT_MOTOR_DRIVER#include #include "adafruit_motor_driver.h"#define LEFT_MOTOR_INIT 1#define RIGHT_MOTOR_INIT 3#endif#ifdef ENABLE_NEWPING_DISTANCE_SENSOR_DRIVER#include #include "newping_distance_sensor.h"#define DISTANCE_SENSOR_INIT 14,15,MAX_DISTANCE#endifnamespace Michelino{ class Robot { public: /* * @brief Class constructor. */ Robot() : leftMotor(LEFT_MOTOR_INIT), rightMotor(RIGHT_MOTOR_INIT), distanceSensor(DISTANCE_SENSOR_INIT) { initialize(); } /* * @brief Initialize the robot state. */ void initialize() { leftMotor.setSpeed(255); rightMotor.setSpeed(255); state = stateRunning; } /* * @brief Update the state of the robot based on input from sensor and remote control. * Must be called repeatedly while the robot is in operation. */ void run() { if (state == stateRunning) { if (distanceSensor.getDistance() <= TOO_CLOSE) { state = stateStopped; leftMotor.setSpeed(0); rightMotor.setSpeed(0); } } } private: Motor leftMotor; Motor rightMotor; DistanceSensor distanceSensor; enum state_t { stateStopped, stateRunning }; state_t state; };};Michelino::Robot robot;void setup(){ robot.initialize();}void loop(){ robot.run();}

在这个草图的控制下,机器人将一直运行,直到距离墙壁或其他障碍物10厘米或更小,然后停止。

如果您正在构建一个像我一样的机器人并尝试草图,您可能会发现机器人大部分时间都按预期运行,但并非总是如此。偶尔它可能会停止,即使没有近距离障碍,或者有时它可能会不停地撞到墙上。继续阅读以了解我如何找出问题以及如何解决问题。

记录

运行上面的草图几次就可以清楚地发现意外情况正在发生,但我怎样才能知道它是什么?我真的需要看到草图正在接收的所有数据以及它如何对它做出反应以理解为什么事情不会像我预期的那样发展。换句话说,我需要调试我的草图。

调试这样的嵌入式系统非常有用的技术是将通过应用程序传递的信息写入可以查看的日志中。

为了能够从我的草图中记录,我将编写一个记录函数,该printf()函数与C标准库中的旧函数具有相同的参数,除了因为我的机器人没有屏幕,输出将转到串口,我可以从我的PC上运行的Arduino软件中捕获,或者通过蓝牙从我的手机中捕获。我打算叫这个功能log()。以下是一个示例用法:

unsigned int distance = distanceSensor.getDistance();log("distance: %u

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

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

相关文章

Yarn简单介绍及内存配置

在这篇博客中&#xff0c;主要介绍了Yarn对MRv1的改进&#xff0c;以及Yarn简单的内存配置和Yarn的资源抽象container。我么知道MRv1存在的主要问题是&#xff1a;在运行时&#xff0c;JobTracker既负责资源管理又负责任务调度&#xff0c;这导致了它的扩展性、资源利用率低等问…

mysql计算时间函数_mysql时间计算函数

当前一个业务需求&#xff0c;需要查找创建在三天以前的数据&#xff0c;表中是存了一个创建时间的&#xff1b;这个需求看起来很简单&#xff0c;直接全部查找出来然后用代码根据时间筛选一下就可以了。但这只是适用于数据量不大的情况下&#xff0c;如果数据量大&#xff0c;…

html上传文件_.NET基于WebUploader大文件分片上传、断网续传、秒传

(给DotNet加星标&#xff0c;提升.Net技能)转自&#xff1a;学习中的苦与乐cnblogs.com/xiongze520/p/10412693.html现在的项目开发基本上都用到了上传文件功能&#xff0c;或图片&#xff0c;或文档&#xff0c;或视频。我们常用的常规上传已经能够满足当前要求了&#xff0c;…

Hadoop运行任务时一直卡在: INFO mapreduce.Job: Running job

原文链接&#xff1a;http://blog.csdn.net/dai451954706/article/details/50464036 ----------------------------------------------------------------------------------------------------- 今天&#xff0c;一大清早同事就让我帮他解决Hive的问题&#xff1a;他在Hive中…

git切换用户密码_Git 最基本的命令

本人比较懒&#xff0c;不是很爱学习新东西&#xff0c;之前用Git一直在用GUI SourceTree&#xff0c;今天因为用到Cloud IDEGitHub才迫不得已用一下Git的命令行&#xff0c;如果你是Git的新手&#xff0c;也分享给你最基本的命令。新建一个Git版本库把一个本地文件夹变成一个G…

动态分区装载数据

不开启 一个个分区导入&#xff0c;分区需要做到一对一。 hive (zmgdb)> insert overwrite table p_t3 partition (cityningbo) > select name,post,address from p_t1 where cityningbo; 会启动mapreduce进行导入&#xff0c;mr卡在kill job_xxxx&#…

AI造福设计师:搭配色板这种苦差事交给GAN就好啦(教程)

本文来自AI新媒体量子位&#xff08;QbitAI&#xff09;设计师要开工&#xff0c;总是离不开配色方案&#xff0c;也就是色板。 不过&#xff0c;做色板可不是个简单的活&#xff0c;色板生成器Colormind的作者Jack Qiao&#xff08;名字来自Product Hunt&#xff0c;我们下面叫…

mapreduce yarn内存参数

1、yarn-site.xml 设置 1.1 RM设置 RM的内存资源配置&#xff0c;主要是通过下面的两个参数进行的&#xff08;这两个值是Yarn平台特性&#xff0c;应在yarn-sit.xml中配置好&#xff09;&#xff1a; yarn.scheduler.minimum-allocation-mb yarn.scheduler.maximum-allocati…

html网页设计大赛_HTML5网页设计大赛 || 决赛名单公布

历经数日的HTML5网页设计大赛初赛已经落下的帷幕激动人心的决赛即将开始你们准备好了吗&#xff1f;①决赛名单在经过评委老师多轮评选后,有以下队伍/(个人)脱颖而出进入决赛&#xff1a;1.施佳镛_故宫旅游网2.王永校_神秘莫测的宇宙3.黄炜岳_广州旅游网站4.吴贵滨_NameLess5.陈…

Hive的数据模型—桶表

概述 桶表是对数据进行哈希取值&#xff0c;然后放到不同文件中存储。 数据加载到桶表时&#xff0c;会对字段取hash值&#xff0c;然后与桶的数量取模。把数据放到对应的文件中。 物理上&#xff0c;每个桶就是表(或分区&#xff09;目录里的一个文件&#xff0c;一个作业产…

delphi bmp绘制矢量文件效率慢_聊一聊矢量瓦片的常识

一、矢量瓦片的基本原理和相关格式现阶段&#xff0c;电子地图瓦片主要使用两种方式&#xff0c;一种是传统的栅格瓦片&#xff0c;另外一种是新出的矢量瓦片(Vector Tiles)&#xff0c;前者是采用四叉树金字塔模型的分级方式&#xff0c;将地图切割成无数大小相等的矩形栅格图…

python生成器与迭代器。

生成器 在python 中一边循环一边计算的机制&#xff0c;叫做生成器(generator)。 通过列表生成式&#xff0c;我们可以直接创建一个列表。但是&#xff0c;收到内存的限制&#xff0c;列表容量肯定是有限的。而且&#xff0c;创建一个包含100万个元素的列表&#xff0c;不仅占用…

python怎样将list转化成字典_在python 中如何将 list 转化成 dictionary

原标题&#xff1a;在python 中如何将 list 转化成 dictionary 问题1&#xff1a;如何将一个list转化成一个dictionary&#xff1f; 问题描述&#xff1a;比如在python中我有一个如下的list&#xff0c;其中奇数位置对应字典的key&#xff0c;偶数位置为相应的value解决方案: 1…

vscode gcc debug dbg gdb c cpp c++ cuckoo monitor

为什么80%的码农都做不了架构师&#xff1f;>>> 装cygwin 或者mingGW&#xff0c;装gcc工具链&#xff0c;并将cygwin的bin目录加入环境变量PATH中。 ctrlshiftb {// See https://go.microsoft.com/fwlink/?LinkId733558// for the documentation about the tasks…

python爬取知网论文关键词_Python爬虫根据关键词爬取知网论文摘要并保存到数据库中...

由于实验室需要一些语料做研究&#xff0c;语料要求是知网上的论文摘要&#xff0c;但是目前最新版的知网爬起来有些麻烦&#xff0c;所以我利用的是知网的另外一个搜索接口 搜索出来的结果和知网上的结果几乎一样 在这个基础上&#xff0c;我简单看了些网页的结构&#xff0c;…

网页中查看pdf文档

2019独角兽企业重金招聘Python工程师标准>>> 介绍&#xff1a; PDFObject 是一个 JavaScript 库&#xff0c;用来在HTML中动态嵌入 PDF 文档。 实现代码&#xff1a; <script type"text/javascript" src"pdfobject.js"></script>…

python opencv 读取视频流不解码_python + opencv: 解决不能读取视频的问题

博主一开始使用python2.7和Opencv2.4.10来获取摄像头图像&#xff0c;程序如下&#xff1a; cap cv2.VideoCapture(0) ret, frame cap.read()使用这个程序能够打开摄像头并获取图像&#xff0c;一切正常。 接着想使用OpenCv播放视频&#xff0c;按照官方教程只要将VideoCaptu…

jmeter提取mysql返回值_jmeter连接数据库和提取数据库返回值

一、在MySQL命令行中&#xff0c;验证MySQL是否能正常登陆。若不能登陆&#xff0c;则重置MySQL的密码。二、下载mysql-connector-java-5.1.45-bin.jar&#xff0c;将其放入Jmeter安装目录的lib目录下。完成MySQL数据库的驱动。三、右键“线程组”->“配置元件”->“JDBC…

用python画雨滴_Python编程从入门到实践练习(雨滴)

雨滴&#xff1a;寻找一幅雨滴图像&#xff0c;并创建一系列整齐排列的雨滴。让这些雨滴往下落&#xff0c;直到到达屏幕后消失。 先说今天的问题&#xff1a; 1.在更改函数形参时&#xff0c;调用的时候也要修改&#xff0c;否则会出现AttributeError 值得注意的是&#xff1a…

Hive文件格式

Hive有四种文件格式&#xff1a;TextFile&#xff0c;SequenceFile&#xff0c;RCFile&#xff0c;ORC TextFile 默认的格式&#xff0c;文本格式。 SequenceFile 简介 见&#xff1a;http://blog.csdn.net/zengmingen/article/details/52242768 操作 hive (zmgdb)>cre…