电子说
步骤1:安装和设置
首先,您需要在选择的计算机上安装Eclipse。 Eclipse是Oracle流行的IDE。要安装此程序,请转到https://www.eclipse.org/downloads/,并找到标有C/C ++开发人员的Eclipse IDE的下载。在完成安装过程之后,您接下来必须安装FRC roboRIO工具链,可以通过转到http://first.wpi.edu/FRC/roborio/toolchains/并选择操作系统的链接来下载该工具链。安装工具链后,您不会注意到安装了任何新应用程序。现在打开Eclipse。您将遇到一个弹出窗口,询问您要使用哪个工作空间。我建议您在文档中创建一个名为“ FRCWorkspace”的文件夹。这将是所有源文件以及各种其他文件(例如输出文件和配置文件)的位置。
如果您想查看或使用FIRST提供的示例程序,请依次选择“文件”》“新建”》“示例”。 。.》 VxWorks可下载内核模块示例项目。然后,应该为您提供已为您编写的项目列表。单击其中一个选项将显示有关其内容的更多信息。即使您希望从头开始编写所有程序,也应该使用以下示例之一启动项目,因为它们设置了所有包含,构建配置,标志等。对于本教程而言,选择IterativeTemplate。首先,您需要稍微整理一下项目。在项目浏览器中,右键单击sample.txt并选择Delete,然后按OK。然后右键单击IterativeTemplate并选择重命名。将项目名称更改为所需的任何名称。避免使用连字符或下划线以外的空格或特殊字符。我建议您做类似“ TeamName2014”的事情。确定名称并在提供的文本字段中键入名称后,请按OK。您的窗口现在看起来有些杂乱,所有边缘的盒子都占据了空间。随意将各种标签拖放到任何地方。通常,您希望中间有很多空间供文件编辑器使用,并且始终可以看到项目浏览器。
步骤2:经历默认代码
现在让我们开始有趣的部分,实际的编程!在项目资源管理器中双击MyRobot.cpp。现在在您面前的是一个工作程序,该程序将在遥控操作期间以拱廊模式驱动机器人。让我们快速遍历代码以了解到目前为止发生的事情。
#include “WPILib.h”
此行将所有WPILib函数和类添加到您的代码中。如果您想对机器人执行任何有用的操作,则将需要这些。除了包含WPILib之外,还将方便地包含string.h和iostream。
class RobotDemo : public IterativeRobot
{
这开始了名为RobotDemo的类。您可以将“ RobotDemo”更改为其他名称,但是只需确保文件中的“ RobotDemo”的每个实例也都更改为您的新名称。冒号表示IterativeRobot是RobotDemo的父类,而RobotDemo继承了IterativeRobot的所有方法。
RobotDrive myRobot;
Joystick stick;
这定义了两个私有变量:myRobot和stick。 myRobot包含驱动机器人的所有功能,stick变量显然具有从操纵杆读取输入的功能。
myRobot.setExpiration(0.1);
这为RobotDrive类中的电动机设置了以秒为单位的到期时间。 。如果电动机的看门狗在这段时间内没有送电,则将假定您的机器人程序已冻结,并且将自动停止电动机。 0.1秒应该是足够的时间,但是如果您正在运行视觉处理或其他一些CPU密集型任务,并且在原本不应该的状态下停止电动机,请尝试增加失效时间。
this-》SetPeriod(0);
以秒为单位设置两次调用定期函数之间的时间。如果设置为零,它将与驾驶员站控制数据同步(最终大约每0.02秒调用一次该函数)。如果未调用此函数,则默认值为0.0,因此此行是无用的。
RobotDemo : myRobot(1,2), stick(1)
这是一个初始化列表。正如评论所建议的,它们必须按照您声明它们的顺序进行初始化。 myRobot的参数是:机器人左马达的端口号,然后是机器人右马达的端口号。这假定您将Jaguars用作电动机控制器。操纵杆的参数是操纵杆编号。您可以转到来查看这是什么? “ DriverStation”的“选项卡”选项卡,然后查看操纵杆在列表中的位置。默认游戏杆号为1。
void RobotDemo::RobotInit() {}
此功能由WPILib在机器人开启时调用,该函数仅被调用一次,这使它成为初始化变量和分配变量的可靠场所。动态内存。
void RobotDemo::AutonomousInit() {}
void RobotDemo::TeleopInit() {}
void RobotDemo::TestInit() {}
每当更改机器人的模式时,WPILib会自动调用这些函数,无论是通过驱动程序站还是FMS(现场消息系统),其初始函数名为称为新模式。通常,所有自治代码都是用AutonomousInit函数编写的。
void RobotDemo::DisabledInit() {}
DisabledInit不遵循其他模式初始化函数的规则。只有在第一次禁用机器人时才调用DisabledInit。这很可能是因为机器人在实际游戏中只会被禁用一次。
void RobotDemo::DisabledPeriodic() {}
void RobotDemo::AutonomousPeriodic{}
void RobotDemo::TeleopPeriodic() {}
void RobotDemo::TestPeriodic() {}
在适当的模式下,每秒将调用这些功能约50次(除非您调用此功能- 》 SetPeriod()的参数不是0.02或0,在这种情况下,周期函数将每秒被调用(1/period)次。
有关init和周期函数的重要说明:周期除非初始化功能完成,否则模式下的功能将无法运行。例如,如果您有这样的事情:
void RobotDemo::AutomousInit() {
while(true) {
cout 《《 “I like dogs” 《《 endl;
}
}
void RobotDemo::AutonomousPeriodic() {
cout 《《 “But cats are better” 《《 endl;
}
您的机器人将不断输出它喜欢狗的东西,即使长时间处于自主模式,它也不会输出以下事实:猫更好。初始化函数中的长时间运行代码可能并不明显,但这始终是在对机器人进行编程时需要注意的重要问题。
};
此括号关闭了RobotDemo类。一堂课的结束是在括号后需要分号的少数情况之一。
START_ROBOT_CLASS(RobotDemo);
这应该始终是MyRobot.cpp文件中的最后一行代码。它是一个在RobotBase.h中定义的宏,它告诉WPILib的其余部分,RobotDemo类是应用于调用init函数,周期函数等的类。如果没有此行,您可能会得到No将其部署到cRIO时出现机器人代码错误。
步骤3:添加新功能
对于某些团队来说,此代码可能就是他们所需要的。但是,您更经常需要自定义代码以满足机器人的需求。由于我不确切知道您的机器人需要什么,因此您需要自己弄清一些。我只能提供一些例子,这些例子是我们团队今年为改进计划所做的。尽管可以跳过以下不适用于您的团队的步骤,但我强烈建议您阅读所有这些步骤,以使您更好地了解WPILib的工作方式以及如何添加这些功能(或类似功能)
第4步:坦克驱动与街机驱动
重要的是,您和您的团队的驱动团队知道街机和坦克驾驶之间的区别。街机驱动器使用一个操纵杆来控制机器人。前后移动操纵杆会改变速度,左右移动操纵杆会改变机器人的旋转。另一方面,坦克驾驶使用两个操纵杆。它们每个都对应于机器人一侧的轮子。向前移动右控制器时,机器人的右轮将向前移动,而机器人将向左转。许多人(尤其是游戏玩家)发现坦克驾驶非常令人困惑,但我强烈建议您的团队使用坦克驾驶。坦克驱动器可以让您更好地控制机器人的运动,并且通过一点点练习,您的驱动器将像使用街机驱动器一样驱动机器人。
街机驱动器已设置在模板中为您服务。如果要切换到油箱驱动器,则需要声明两个Joystick变量而不是一个。我建议您称它们为rightStick和leftStick之类的名称,以便您轻松区分它们。然后将它们都放在初始化列表中,将值1传递给第一个操纵杆的构造函数,将值2传递给第二个操纵杆的构造函数。最后替换行“ myRobot.ArcadeDrive(stick);”使用“ myRobot.TankDrive(leftStick,rightStick);”。塔哈,您的机器人现在在油箱驱动器中驱动!
第5步:完整的气动系统
气动对于改善机器人的功能,并且在构建和编程方面都非常容易实现。要了解气动的建筑方面,请参见Zaphod Beetlebrox的指导,他在出色地解释了气动系统的所有组件以及如何将其组合在一起方面做得很好。让我们开始通过添加压缩机来对气动系统进行编程:
Compressor compressor;
compressor(,);
compressor.Start();
第一行与其余变量定义一起出现,第二行与初始值设定项列表一起出现,第三行与您的变量定义一起出现RobotInit功能。压缩机的构造函数参数是压力开关和尖峰继电器插入数字边柜的端口号。压力开关应插入数字IO端口之一,而Spike继电器应插入继电器端口之一。这是使压缩机工作所需的全部代码,它将自动启动并继续运行,直到触发压力开关为止。使用AndyMarks的标准压力开关,该压力应为120 psi,但实际上通常比该压力要低一些(我们的触发压力为110 psi)。
对气动系统进行编程的下一步是消防螺线管。型号之间的接线和编程不同,但是有两种主要类型的螺线管,单螺线管和双螺线管。单个螺线管只有两根电线。它们默认将压力引导至一个输出,并且仅在螺线管通电时将压力引导至另一输出。双螺线管有两对线,一对线通向设备的每一侧。当一侧通电时,螺线管会将其输出切换到该侧。关闭电源后,输出将保留在任何位置。如果两个都同时打开,则输出也将保持不变。如果您使用单个电磁阀,则代码如下所示:
Solenoid solenoid;
solenoid();
solenoid.Set();
前两行与示例压缩机代码的前两行位于同一位置。第三行应放置在由按钮控制的if语句中,或者放置在您的自治代码中。将“真”值传递给“设置”功能会将螺线管的输出切换为非默认输出。同样,当设置为false时,它将使输出返回其默认位置。如果要使用双螺线管,只需将螺线管变量的类别更改为DoubleSolenoid而不是电磁阀,然后更改Set功能的参数即可。 Set函数参数不再是布尔值,因为有三个可用选项:仅打开一侧,仅打开另一侧,然后关闭两侧。要对此进行控制,请使用DoubleSolenoid :: kForward,DoubleSolenoid :: kReverse或DoubleSolenoid :: kOff作为Set函数的参数。
步骤6:操纵杆按钮
要在操纵杆按钮正常工作时运行定期代码,只需将以下代码插入您的定期模式功能之一:
if(stick.GetRawButton(1)) {
cout 《《 “Button 1 has been pressed” 《《 endl;
}
此代码将是垃圾邮件仅在按下由stick变量引用的操纵杆上的数字1时,才会出现带有“已按下按钮1”的控制台消息。释放按钮后,消息将再次停止。尽管这在某些情况下很有用,但有时您可能只是希望在按下按钮时只调用一次它。将代码修改为类似这样的代码应该可以达到您想要的结果:
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已被按下”仅在第一次按下时才输出一次,而“按钮1已被释放”则仅在一次按下时输出一次。
第7步:自定义控制器
您的驱动器团队可能会找您说,“我们想用它来移动机器人”。在此示例中,我将向您展示将代码适配到Attack3以外的控制器有多么容易。附带说明一下,Xbox控制器通常不是驱动机器人的非常好的控制器。不对称的操纵杆使油箱驱动器直行行驶成为一个挑战,操纵杆的小尺寸使其控件非常灵巧。首先,下载WPILib的Joystick Explorer实用程序。启动它并插入游戏杆。确保从下拉菜单中选择了控制器。移动操纵杆,观察轴号发生变化。您应该为每个操纵杆记录一个x轴和y轴(可能还取决于您的特定控制器的z轴)。现在,您进入代码并使用这些轴号。删除当前的myRobot.TankDrive或myRobot.ArcadeDrive函数,并在伸缩定期函数中添加以下代码。
坦克车:
myRobot.TankDrive(stick.GetRawAxis(), stick.GetRawAxis());
Z轴的坦克车速度:
myRobot.TankDrive(stick.GetRawAxis() * stick.GetRawAxis(), stick.GetRawAxis() * stick.GetRawAxis());
街机驱动器:
myRobot.ArcadeDrive(stick.GetRawAxis(), stick.GetRawAxis());
Z轴街机驱动器用于速度:
myRobot.ArcadeDrive(stick.GetRawAxis() * stick.GetRawAxis(), stick.GetRawAxis());
您当然,将需要使用《》对其进行修改,以匹配您从Joystick Explorer中记录的轴号。
步骤8:微型开关
它们发出巨大的咔嗒声,但这并不是唯一的用途!它们可用于检测自主游戏期间是否将游戏作品加载到您的机器人中或检测碰撞。也许您有自己的创意用途。无论需要什么,它们都易于接线和编程,因此您应该知道它是如何完成的。这是它们的代码:
DigitalInput microswitch;
microswitch(1) // This goes in the initialization list
microswitch.Get()
Get函数返回一个无符号的32位整数。如果要从中获取布尔值以像按钮一样进行处理,只需将返回值与零进行比较即可。根据开关的接线,可能必须使用==或!=才能获得所需的结果。
第9步:最终注释
其中一些注释非常有用重要,因此请阅读它们!
C ++ 11的功能将无法在您的程序中使用,因为Wind River编译器不支持它。
通常,无法使用cout或printf查看在标准输出流中放入的任何内容。我强烈建议您使用NetConsole。它需要最少的设置,然后您可以将其与驱动程序站一起运行,它将显示您输出的所有内容。它可以是非常有用的工具,有助于诊断出问题所在或为驾驶员提供一些反馈。
如果您需要有关FRC机器人编程的帮助,最好的地方是Chief Delphi。那里总是有经验和知识渊博的人来帮助您。您也可以对此说明发表评论,我会尽力与您联系。
确保您的cRIO映像和Wind River工作台保持最新非常重要。对于cRIO,只需找到FIRST提供的cRIO映像工具的最新副本即可。对于Wind River工作台,通常在FIRST的“技术资源”页面上有一个“ C ++更新”。
我还有几个我想写的主题,例如编程尖峰继电器,编码器,arduino通信和视觉处理。我还想详细介绍将代码部署到cRIO的细节。因此,请在几周后再次检查此说明,以更全面地了解FIRST Robotics的编程。
全部0条评论
快来发表一下你的评论吧 !