步驟1:安裝和設(shè)置
首先,您需要在選擇的計(jì)算機(jī)上安裝Eclipse。 Eclipse是Oracle流行的IDE。要安裝此程序,請(qǐng)轉(zhuǎn)到https://www.eclipse.org/downloads/,并找到標(biāo)有C/C ++開發(fā)人員的Eclipse IDE的下載。在完成安裝過程之后,您接下來必須安裝FRC roboRIO工具鏈,可以通過轉(zhuǎn)到http://first.wpi.edu/FRC/roborio/toolchains/并選擇操作系統(tǒng)的鏈接來下載該工具鏈。安裝工具鏈后,您不會(huì)注意到安裝了任何新應(yīng)用程序?,F(xiàn)在打開Eclipse。您將遇到一個(gè)彈出窗口,詢問您要使用哪個(gè)工作空間。我建議您在文檔中創(chuàng)建一個(gè)名為“ FRCWorkspace”的文件夾。這將是所有源文件以及各種其他文件(例如輸出文件和配置文件)的位置。
如果您想查看或使用FIRST提供的示例程序,請(qǐng)依次選擇“文件”》“新建”》“示例”。 。.》 VxWorks可下載內(nèi)核模塊示例項(xiàng)目。然后,應(yīng)該為您提供已為您編寫的項(xiàng)目列表。單擊其中一個(gè)選項(xiàng)將顯示有關(guān)其內(nèi)容的更多信息。即使您希望從頭開始編寫所有程序,也應(yīng)該使用以下示例之一啟動(dòng)項(xiàng)目,因?yàn)樗鼈冊(cè)O(shè)置了所有包含,構(gòu)建配置,標(biāo)志等。對(duì)于本教程而言,選擇IterativeTemplate。首先,您需要稍微整理一下項(xiàng)目。在項(xiàng)目瀏覽器中,右鍵單擊sample.txt并選擇Delete,然后按OK。然后右鍵單擊IterativeTemplate并選擇重命名。將項(xiàng)目名稱更改為所需的任何名稱。避免使用連字符或下劃線以外的空格或特殊字符。我建議您做類似“ TeamName2014”的事情。確定名稱并在提供的文本字段中鍵入名稱后,請(qǐng)按OK。您的窗口現(xiàn)在看起來有些雜亂,所有邊緣的盒子都占據(jù)了空間。隨意將各種標(biāo)簽拖放到任何地方。通常,您希望中間有很多空間供文件編輯器使用,并且始終可以看到項(xiàng)目瀏覽器。
步驟2:經(jīng)歷默認(rèn)代碼
現(xiàn)在讓我們開始有趣的部分,實(shí)際的編程!在項(xiàng)目資源管理器中雙擊MyRobot.cpp。現(xiàn)在在您面前的是一個(gè)工作程序,該程序?qū)⒃谶b控操作期間以拱廊模式驅(qū)動(dòng)機(jī)器人。讓我們快速遍歷代碼以了解到目前為止發(fā)生的事情。
#include “WPILib.h”
此行將所有WPILib函數(shù)和類添加到您的代碼中。如果您想對(duì)機(jī)器人執(zhí)行任何有用的操作,則將需要這些。除了包含WPILib之外,還將方便地包含string.h和iostream。
class RobotDemo : public IterativeRobot
{
這開始了名為RobotDemo的類。您可以將“ RobotDemo”更改為其他名稱,但是只需確保文件中的“ RobotDemo”的每個(gè)實(shí)例也都更改為您的新名稱。冒號(hào)表示IterativeRobot是RobotDemo的父類,而RobotDemo繼承了IterativeRobot的所有方法。
RobotDrive myRobot;
Joystick stick;
這定義了兩個(gè)私有變量:myRobot和stick。 myRobot包含驅(qū)動(dòng)機(jī)器人的所有功能,stick變量顯然具有從操縱桿讀取輸入的功能。
myRobot.setExpiration(0.1);
這為RobotDrive類中的電動(dòng)機(jī)設(shè)置了以秒為單位的到期時(shí)間。 。如果電動(dòng)機(jī)的看門狗在這段時(shí)間內(nèi)沒有送電,則將假定您的機(jī)器人程序已凍結(jié),并且將自動(dòng)停止電動(dòng)機(jī)。 0.1秒應(yīng)該是足夠的時(shí)間,但是如果您正在運(yùn)行視覺處理或其他一些CPU密集型任務(wù),并且在原本不應(yīng)該的狀態(tài)下停止電動(dòng)機(jī),請(qǐng)嘗試增加失效時(shí)間。
this-》SetPeriod(0);
以秒為單位設(shè)置兩次調(diào)用定期函數(shù)之間的時(shí)間。如果設(shè)置為零,它將與駕駛員站控制數(shù)據(jù)同步(最終大約每0.02秒調(diào)用一次該函數(shù))。如果未調(diào)用此函數(shù),則默認(rèn)值為0.0,因此此行是無用的。
RobotDemo : myRobot(1,2), stick(1)
這是一個(gè)初始化列表。正如評(píng)論所建議的,它們必須按照您聲明它們的順序進(jìn)行初始化。 myRobot的參數(shù)是:機(jī)器人左馬達(dá)的端口號(hào),然后是機(jī)器人右馬達(dá)的端口號(hào)。這假定您將Jaguars用作電動(dòng)機(jī)控制器。操縱桿的參數(shù)是操縱桿編號(hào)。您可以轉(zhuǎn)到來查看這是什么? “ DriverStation”的“選項(xiàng)卡”選項(xiàng)卡,然后查看操縱桿在列表中的位置。默認(rèn)游戲桿號(hào)為1。
void RobotDemo::RobotInit() {}
此功能由WPILib在機(jī)器人開啟時(shí)調(diào)用,該函數(shù)僅被調(diào)用一次,這使它成為初始化變量和分配變量的可靠場(chǎng)所。動(dòng)態(tài)內(nèi)存。
void RobotDemo::AutonomousInit() {}
void RobotDemo::TeleopInit() {}
void RobotDemo::TestInit() {}
每當(dāng)更改機(jī)器人的模式時(shí),WPILib會(huì)自動(dòng)調(diào)用這些函數(shù),無論是通過驅(qū)動(dòng)程序站還是FMS(現(xiàn)場(chǎng)消息系統(tǒng)),其初始函數(shù)名為稱為新模式。通常,所有自治代碼都是用AutonomousInit函數(shù)編寫的。
void RobotDemo::DisabledInit() {}
DisabledInit不遵循其他模式初始化函數(shù)的規(guī)則。只有在第一次禁用機(jī)器人時(shí)才調(diào)用DisabledInit。這很可能是因?yàn)闄C(jī)器人在實(shí)際游戲中只會(huì)被禁用一次。
void RobotDemo::DisabledPeriodic() {}
void RobotDemo::AutonomousPeriodic{}
void RobotDemo::TeleopPeriodic() {}
void RobotDemo::TestPeriodic() {}
在適當(dāng)?shù)哪J较拢棵雽⒄{(diào)用這些功能約50次(除非您調(diào)用此功能- 》 SetPeriod()的參數(shù)不是0.02或0,在這種情況下,周期函數(shù)將每秒被調(diào)用(1/period)次。
有關(guān)init和周期函數(shù)的重要說明:周期除非初始化功能完成,否則模式下的功能將無法運(yùn)行。例如,如果您有這樣的事情:
void RobotDemo::AutomousInit() {
while(true) {
cout 《《 “I like dogs” 《《 endl;
}
}
void RobotDemo::AutonomousPeriodic() {
cout 《《 “But cats are better” 《《 endl;
}
您的機(jī)器人將不斷輸出它喜歡狗的東西,即使長(zhǎng)時(shí)間處于自主模式,它也不會(huì)輸出以下事實(shí):貓更好。初始化函數(shù)中的長(zhǎng)時(shí)間運(yùn)行代碼可能并不明顯,但這始終是在對(duì)機(jī)器人進(jìn)行編程時(shí)需要注意的重要問題。
};
此括號(hào)關(guān)閉了RobotDemo類。一堂課的結(jié)束是在括號(hào)后需要分號(hào)的少數(shù)情況之一。
START_ROBOT_CLASS(RobotDemo);
這應(yīng)該始終是MyRobot.cpp文件中的最后一行代碼。它是一個(gè)在RobotBase.h中定義的宏,它告訴WPILib的其余部分,RobotDemo類是應(yīng)用于調(diào)用init函數(shù),周期函數(shù)等的類。如果沒有此行,您可能會(huì)得到No將其部署到cRIO時(shí)出現(xiàn)機(jī)器人代碼錯(cuò)誤。
步驟3:添加新功能
對(duì)于某些團(tuán)隊(duì)來說,此代碼可能就是他們所需要的。但是,您更經(jīng)常需要自定義代碼以滿足機(jī)器人的需求。由于我不確切知道您的機(jī)器人需要什么,因此您需要自己弄清一些。我只能提供一些例子,這些例子是我們團(tuán)隊(duì)今年為改進(jìn)計(jì)劃所做的。盡管可以跳過以下不適用于您的團(tuán)隊(duì)的步驟,但我強(qiáng)烈建議您閱讀所有這些步驟,以使您更好地了解WPILib的工作方式以及如何添加這些功能(或類似功能)
第4步:坦克驅(qū)動(dòng)與街機(jī)驅(qū)動(dòng)
重要的是,您和您的團(tuán)隊(duì)的驅(qū)動(dòng)團(tuán)隊(duì)知道街機(jī)和坦克駕駛之間的區(qū)別。街機(jī)驅(qū)動(dòng)器使用一個(gè)操縱桿來控制機(jī)器人。前后移動(dòng)操縱桿會(huì)改變速度,左右移動(dòng)操縱桿會(huì)改變機(jī)器人的旋轉(zhuǎn)。另一方面,坦克駕駛使用兩個(gè)操縱桿。它們每個(gè)都對(duì)應(yīng)于機(jī)器人一側(cè)的輪子。向前移動(dòng)右控制器時(shí),機(jī)器人的右輪將向前移動(dòng),而機(jī)器人將向左轉(zhuǎn)。許多人(尤其是游戲玩家)發(fā)現(xiàn)坦克駕駛非常令人困惑,但我強(qiáng)烈建議您的團(tuán)隊(duì)使用坦克駕駛。坦克驅(qū)動(dòng)器可以讓您更好地控制機(jī)器人的運(yùn)動(dòng),并且通過一點(diǎn)點(diǎn)練習(xí),您的驅(qū)動(dòng)器將像使用街機(jī)驅(qū)動(dòng)器一樣驅(qū)動(dòng)機(jī)器人。
街機(jī)驅(qū)動(dòng)器已設(shè)置在模板中為您服務(wù)。如果要切換到油箱驅(qū)動(dòng)器,則需要聲明兩個(gè)Joystick變量而不是一個(gè)。我建議您稱它們?yōu)閞ightStick和leftStick之類的名稱,以便您輕松區(qū)分它們。然后將它們都放在初始化列表中,將值1傳遞給第一個(gè)操縱桿的構(gòu)造函數(shù),將值2傳遞給第二個(gè)操縱桿的構(gòu)造函數(shù)。最后替換行“ myRobot.ArcadeDrive(stick);”使用“ myRobot.TankDrive(leftStick,rightStick);”。塔哈,您的機(jī)器人現(xiàn)在在油箱驅(qū)動(dòng)器中驅(qū)動(dòng)!
第5步:完整的氣動(dòng)系統(tǒng)
氣動(dòng)對(duì)于改善機(jī)器人的功能,并且在構(gòu)建和編程方面都非常容易實(shí)現(xiàn)。要了解氣動(dòng)的建筑方面,請(qǐng)參見Zaphod Beetlebrox的指導(dǎo),他在出色地解釋了氣動(dòng)系統(tǒng)的所有組件以及如何將其組合在一起方面做得很好。讓我們開始通過添加壓縮機(jī)來對(duì)氣動(dòng)系統(tǒng)進(jìn)行編程:
Compressor compressor;
compressor(,);
compressor.Start();
第一行與其余變量定義一起出現(xiàn),第二行與初始值設(shè)定項(xiàng)列表一起出現(xiàn),第三行與您的變量定義一起出現(xiàn)RobotInit功能。壓縮機(jī)的構(gòu)造函數(shù)參數(shù)是壓力開關(guān)和尖峰繼電器插入數(shù)字邊柜的端口號(hào)。壓力開關(guān)應(yīng)插入數(shù)字IO端口之一,而Spike繼電器應(yīng)插入繼電器端口之一。這是使壓縮機(jī)工作所需的全部代碼,它將自動(dòng)啟動(dòng)并繼續(xù)運(yùn)行,直到觸發(fā)壓力開關(guān)為止。使用AndyMarks的標(biāo)準(zhǔn)壓力開關(guān),該壓力應(yīng)為120 psi,但實(shí)際上通常比該壓力要低一些(我們的觸發(fā)壓力為110 psi)。
對(duì)氣動(dòng)系統(tǒng)進(jìn)行編程的下一步是消防螺線管。型號(hào)之間的接線和編程不同,但是有兩種主要類型的螺線管,單螺線管和雙螺線管。單個(gè)螺線管只有兩根電線。它們默認(rèn)將壓力引導(dǎo)至一個(gè)輸出,并且僅在螺線管通電時(shí)將壓力引導(dǎo)至另一輸出。雙螺線管有兩對(duì)線,一對(duì)線通向設(shè)備的每一側(cè)。當(dāng)一側(cè)通電時(shí),螺線管會(huì)將其輸出切換到該側(cè)。關(guān)閉電源后,輸出將保留在任何位置。如果兩個(gè)都同時(shí)打開,則輸出也將保持不變。如果您使用單個(gè)電磁閥,則代碼如下所示:
Solenoid solenoid;
solenoid();
solenoid.Set();
前兩行與示例壓縮機(jī)代碼的前兩行位于同一位置。第三行應(yīng)放置在由按鈕控制的if語句中,或者放置在您的自治代碼中。將“真”值傳遞給“設(shè)置”功能會(huì)將螺線管的輸出切換為非默認(rèn)輸出。同樣,當(dāng)設(shè)置為false時(shí),它將使輸出返回其默認(rèn)位置。如果要使用雙螺線管,只需將螺線管變量的類別更改為DoubleSolenoid而不是電磁閥,然后更改Set功能的參數(shù)即可。 Set函數(shù)參數(shù)不再是布爾值,因?yàn)橛腥齻€(gè)可用選項(xiàng):僅打開一側(cè),僅打開另一側(cè),然后關(guān)閉兩側(cè)。要對(duì)此進(jìn)行控制,請(qǐng)使用DoubleSolenoid :: kForward,DoubleSolenoid :: kReverse或DoubleSolenoid :: kOff作為Set函數(shù)的參數(shù)。
步驟6:操縱桿按鈕
要在操縱桿按鈕正常工作時(shí)運(yùn)行定期代碼,只需將以下代碼插入您的定期模式功能之一:
if(stick.GetRawButton(1)) {
cout 《《 “Button 1 has been pressed” 《《 endl;
}
此代碼將是垃圾郵件僅在按下由stick變量引用的操縱桿上的數(shù)字1時(shí),才會(huì)出現(xiàn)帶有“已按下按鈕1”的控制臺(tái)消息。釋放按鈕后,消息將再次停止。盡管這在某些情況下很有用,但有時(shí)您可能只是希望在按下按鈕時(shí)只調(diào)用一次它。將代碼修改為類似這樣的代碼應(yīng)該可以達(dá)到您想要的結(jié)果:
if(stick.GetRawButton(1) != isButtonPressed) {
if(stick.GetRawButton(1)) {
cout 《《 “Button 1 has been pressed” 《《 endl;
isButtonPressed = true;
}
else {
cout 《《 “Button 1 has be released” 《《 endl;
isButtonPressed = false;
}
}
您必須將isButtonPressed定義為具有類范圍的布爾值(與myRobot或stick)。在這種情況下,“按鈕1已被按下”僅在第一次按下時(shí)才輸出一次,而“按鈕1已被釋放”則僅在一次按下時(shí)輸出一次。
第7步:自定義控制器
您的驅(qū)動(dòng)器團(tuán)隊(duì)可能會(huì)找您說,“我們想用它來移動(dòng)機(jī)器人”。在此示例中,我將向您展示將代碼適配到Attack3以外的控制器有多么容易。附帶說明一下,Xbox控制器通常不是驅(qū)動(dòng)機(jī)器人的非常好的控制器。不對(duì)稱的操縱桿使油箱驅(qū)動(dòng)器直行行駛成為一個(gè)挑戰(zhàn),操縱桿的小尺寸使其控件非常靈巧。首先,下載WPILib的Joystick Explorer實(shí)用程序。啟動(dòng)它并插入游戲桿。確保從下拉菜單中選擇了控制器。移動(dòng)操縱桿,觀察軸號(hào)發(fā)生變化。您應(yīng)該為每個(gè)操縱桿記錄一個(gè)x軸和y軸(可能還取決于您的特定控制器的z軸)?,F(xiàn)在,您進(jìn)入代碼并使用這些軸號(hào)。刪除當(dāng)前的myRobot.TankDrive或myRobot.ArcadeDrive函數(shù),并在伸縮定期函數(shù)中添加以下代碼。
坦克車:
myRobot.TankDrive(stick.GetRawAxis(), stick.GetRawAxis());
Z軸的坦克車速度:
myRobot.TankDrive(stick.GetRawAxis() * stick.GetRawAxis(), stick.GetRawAxis() * stick.GetRawAxis());
街機(jī)驅(qū)動(dòng)器:
myRobot.ArcadeDrive(stick.GetRawAxis(), stick.GetRawAxis());
Z軸街機(jī)驅(qū)動(dòng)器用于速度:
myRobot.ArcadeDrive(stick.GetRawAxis() * stick.GetRawAxis(), stick.GetRawAxis());
您當(dāng)然,將需要使用《》對(duì)其進(jìn)行修改,以匹配您從Joystick Explorer中記錄的軸號(hào)。
步驟8:微型開關(guān)
它們發(fā)出巨大的咔嗒聲,但這并不是唯一的用途!它們可用于檢測(cè)自主游戲期間是否將游戲作品加載到您的機(jī)器人中或檢測(cè)碰撞。也許您有自己的創(chuàng)意用途。無論需要什么,它們都易于接線和編程,因此您應(yīng)該知道它是如何完成的。這是它們的代碼:
DigitalInput microswitch;
microswitch(1) // This goes in the initialization list
microswitch.Get()
Get函數(shù)返回一個(gè)無符號(hào)的32位整數(shù)。如果要從中獲取布爾值以像按鈕一樣進(jìn)行處理,只需將返回值與零進(jìn)行比較即可。根據(jù)開關(guān)的接線,可能必須使用==或!=才能獲得所需的結(jié)果。
第9步:最終注釋
其中一些注釋非常有用重要,因此請(qǐng)閱讀它們!
C ++ 11的功能將無法在您的程序中使用,因?yàn)閃ind River編譯器不支持它。
通常,無法使用cout或printf查看在標(biāo)準(zhǔn)輸出流中放入的任何內(nèi)容。我強(qiáng)烈建議您使用NetConsole。它需要最少的設(shè)置,然后您可以將其與驅(qū)動(dòng)程序站一起運(yùn)行,它將顯示您輸出的所有內(nèi)容。它可以是非常有用的工具,有助于診斷出問題所在或?yàn)轳{駛員提供一些反饋。
如果您需要有關(guān)FRC機(jī)器人編程的幫助,最好的地方是Chief Delphi。那里總是有經(jīng)驗(yàn)和知識(shí)淵博的人來幫助您。您也可以對(duì)此說明發(fā)表評(píng)論,我會(huì)盡力與您聯(lián)系。
確保您的cRIO映像和Wind River工作臺(tái)保持最新非常重要。對(duì)于cRIO,只需找到FIRST提供的cRIO映像工具的最新副本即可。對(duì)于Wind River工作臺(tái),通常在FIRST的“技術(shù)資源”頁(yè)面上有一個(gè)“ C ++更新”。
我還有幾個(gè)我想寫的主題,例如編程尖峰繼電器,編碼器,arduino通信和視覺處理。我還想詳細(xì)介紹將代碼部署到cRIO的細(xì)節(jié)。因此,請(qǐng)?jiān)趲字芎笤俅螜z查此說明,以更全面地了解FIRST Robotics的編程。
-
機(jī)器人
+關(guān)注
關(guān)注
211文章
28466瀏覽量
207327 -
編程
+關(guān)注
關(guān)注
88文章
3619瀏覽量
93781 -
FRC
+關(guān)注
關(guān)注
1文章
9瀏覽量
18620
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論