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.pswp.cn/news/539185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539185.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

debug error怎么解決_我要以血和淚的經歷告訴你,這個 bug 太難解決了

[npm install報錯: npm WARN tar ENOENT: no such file or directory]npm installnpm WARN deprecated request2.88.2: request has been deprecated, see request/request#3142npm WARN deprecated mkdirp0.5.1: Legacy versions of mkdirp are no longer supported. Please u…

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&#…

python爬蟲常見報錯_對Python爬蟲常見工具總結,歡迎補充

前言 以前寫爬蟲都是用requests包&#xff0c;雖然很好用&#xff0c;不過還是要封裝一些header啊什么的&#xff0c;也沒有用過無頭瀏覽器&#xff0c;今天偶然接觸了一下。 原因是在處理一個錯誤的時候&#xff0c;用到了幾個以前沒有用過的工具&#xff1b;這幾個工具也挺常…

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…

python有哪些常用的package_個人Python常用Package及其安裝

為了避免每次重裝系統時又要東翻西找&#xff0c;現在此記錄一下目前常用的Python包安裝過程。 1) Python: 2.7.11, 下載地址&#xff1a;www.python.org。由于個人喜歡使用PyQt4&#xff08;其實是不會PyQt5……&#xff09;&#xff0c;因此選擇安裝Python2.7。 安裝好Python…

html網頁設計大賽_HTML5網頁設計大賽 || 決賽名單公布

歷經數日的HTML5網頁設計大賽初賽已經落下的帷幕激動人心的決賽即將開始你們準備好了嗎&#xff1f;①決賽名單在經過評委老師多輪評選后,有以下隊伍/(個人)脫穎而出進入決賽&#xff1a;1.施佳鏞_故宮旅游網2.王永校_神秘莫測的宇宙3.黃煒岳_廣州旅游網站4.吳貴濱_NameLess5.陳…

2018.03.12、Android知識點-Java篇

1、闡述下對象的自動裝箱和拆箱 2 基本數據類型的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。自動裝箱是java編譯器在java原生類型和對應的對象包裝類型上做的自動轉換。 自動裝箱&#xff1a;Integer i 1&#xff1b;其實編譯器為你自動實現了&#x…

Hive的數據模型—桶表

概述 桶表是對數據進行哈希取值&#xff0c;然后放到不同文件中存儲。 數據加載到桶表時&#xff0c;會對字段取hash值&#xff0c;然后與桶的數量取模。把數據放到對應的文件中。 物理上&#xff0c;每個桶就是表(或分區&#xff09;目錄里的一個文件&#xff0c;一個作業產…

mysql+使用swap_MySQL避免使用SWAP

當物理內存的數量不能容納數據的時候&#xff0c;os會把虛擬內存中的數據寫到磁盤上&#xff0c;此時的交換對于運行在操作系統中的進程是透明的。交換對與MySQL性能有很大的影響&#xff0c;對于Innodb存儲引擎它對內存中的數據鎖住全局互斥量&#xff0c;如果此時導致了磁盤的…

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

一、矢量瓦片的基本原理和相關格式現階段&#xff0c;電子地圖瓦片主要使用兩種方式&#xff0c;一種是傳統的柵格瓦片&#xff0c;另外一種是新出的矢量瓦片(Vector Tiles)&#xff0c;前者是采用四叉樹金字塔模型的分級方式&#xff0c;將地圖切割成無數大小相等的矩形柵格圖…

python生成器與迭代器。

生成器 在python 中一邊循環一邊計算的機制&#xff0c;叫做生成器(generator)。 通過列表生成式&#xff0c;我們可以直接創建一個列表。但是&#xff0c;收到內存的限制&#xff0c;列表容量肯定是有限的。而且&#xff0c;創建一個包含100萬個元素的列表&#xff0c;不僅占用…

centos mysql 設置_CentOS下MySQL安裝后配置和設置-阿里云開發者社區

CentOS下MySQL安裝后配置和設置&#xff1a;1&#xff1a;安裝完成路徑:1、數據庫目錄/var/lib/mysql/2、配置文件/usr/share/mysql(mysql.server命令及配置文件)3、啟動腳本/etc/rc.d/init.d/(啟動腳本文件mysql的目錄)4、相關命令/usr/bin(mysqladmin mysqldump等命令)注:1~3…

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…