FRC 0 to Autonomous: #5 Command-Based Robot

FRC 0 to Autonomous
5 Aug 202125:04

Summary

TLDRこのビデオでは、コマンドベースのプログラミングについて学びます。シミュレータでエレベーターボットをプログラミングし、駆動系、エレベーター、インテイク、そして自動運転シーケンスをコマンドベース構造でプログラムする方法を学びます。過去のビデオでは、初期化と各ロボットモードの周期的な関数を使用してタイムベースのコード構造を使いましたが、プロジェクトが大きくなると、コマンドベース構造が必要になります。このビデオでは、タイムベースのロボットをコマンドベースに変換し、サブシステムとコマンドを使ってロボットの動作をカスタマイズする方法を紹介します。

Takeaways

  • 🤖 このエピソードでは、コマンドベースのプログラミングについて解説しています。
  • 🏗️ 実際にはロボットを操作せず、シミュレータでエレベーターボットをプログラミングします。
  • 📚 学習目標は、コマンドベース構造でドライブトレイン、エレベーター、インテイク、および自動運転シーケンスをプログラミングすることです。
  • 🔄 これまでのビデオではタイムベースのロボットコード構造が使われていましたが、プロジェクトが大きくなるとコマンドベース構造が必要になります。
  • 📂 コマンドベース構造では、サブシステムと呼ばれるファイルごとにメカニズムを分離して整理できます。
  • 🛠️ サブシステムは、モーターやセンサーのセットアップを簡単に行い、コマンドがそれらを使いやすくします。
  • 🔄 コマンドは、サブシステムの詳細に関わらず、アクションを実行するのに使用されます。
  • 🔄 ロボットの自動運転モードでは、異なるコマンドを組み合わせて自動運転ルーチンを作成できます。
  • 🎮 シミュレータでロボットコードを実行し、ロボットの動作を確認できます。
  • 🔧 ロボットコンテナーファイルでサブシステムとコマンドを管理し、ジョイスティックボタンをトリガーに設定できます。
  • 🔢 定数クラスを使用して、ロボットコード全体で使用される数値を一か所に集約して管理し、変更を容易にします。

Q & A

  • コマンドベースプログラミングとは何ですか?

    -コマンドベースプログラミングは、ロボットの動作を複数のコマンドに分割し、それぞれのコマンドが特定の機能を実行するプログラミングスタイルです。

  • タイムベースのロボットコード構造とコマンドベース構造の違いは何ですか?

    -タイムベース構造は、初期化関数と各ロボットモードの周期的な関数を使用します。一方、コマンドベース構造は、大きなプロジェクトでコードをサブシステムとコマンドに分割し、より読みやすく管理しやすくなります。

  • サブシステムとは何で、何のために使用されますか?

    -サブシステムは、ロボットの各メカニズムのモーターやセンサーの設定をまとめたファイルであり、コマンドがハードウェアの詳細に関わらず簡単に動作を実行できるようにします。

  • コマンドベース構造で使用される「コマンド」とは何を意味していますか?

    -「コマンド」は、ロボットのメカニズムが実行するアクションを記述したファイルであり、initialize、execute、end、isFinishedなどの関数で構成されています。

  • どのようにしてコマンドベースのロボットをシミュレータで操作できますか?

    -シミュレータでロボットを操作するには、まずシミュレータのリンクからシミュレータをダウンロードし、自分のコードをロボットライブにインポートして実行します。

  • ロボットのエレベーターのPIDコントローラーとは何ですか?

    -PIDコントローラーは、エレベーターの位置を制御するため使用され、設定された目標位置に近づくようにモーターの速度を調整します。

  • コマンドベースプログラミングでの「並列コマンドグループ」と「順次コマンドグループ」の違いは何ですか?

    -並列コマンドグループは、複数のコマンドを同時に実行します。一方、順次コマンドグループは、一度に一つのコマンドを実行し、前のコマンドが終了した後に次のコマンドを開始します。

  • ロボットの自走モードで実行されるコマンドグループを作成するにはどうすればよいですか?

    -自走モードで実行されるコマンドグループを作成するには、getAutonomousCommand関数を作成し、そこに実行したいコマンドグループを定義します。

  • ロボットの操作パネルでジョイスティックボタンを設定するにはどうすればよいですか?

    -ジョイスティックボタンを設定するには、RobotContainer.javaのconfigureButtonBindings関数を使用して、ボタンに関連付けたいコマンドを指定します。

  • 定数クラスを使用することの利点は何ですか?

    -定数クラスを使用することで、プロジェクト全体で使用されている数値を一か所で管理でき、変更が必要な場合でも簡単に更新できます。

Outlines

00:00

🤖 コマンドベースプログラミング入門

このエピソードでは、物理的なロボットではなく、シミュレータで作成されたエレベーターボットを使用してコマンドベースプログラミングについて学びます。最終的には、コマンドベース構造でドライブトレイン、エレベーター、インテーク、および自動運転シーケンスをプログラムする方法を学びます。これまでのビデオでは、初期化関数と各ロボットモードの周期関数を持つTimed Robot Code構造を使用してきましたが、プロジェクトが大きくなることでコマンドベース構造が必要になります。エレベーターボットの例を使って、Timed RobotからCommand-Based Robotへの変換方法を説明し、各メカニズムごとにファイルを分けることでコードの可読性を高める方法を学びます。

05:00

🔄 サブシステムとコマンドの構築

エレベーターボットの例では、サブシステムとコマンドを使ってロボットの動作を定義します。サブシステムはモーターとセンサーのセットアップを行い、コマンドはサブシステムを操作するアクションを定義します。サブシステムの例として、ドライブトレイン、エレベーター、インテークのそれぞれについて、Javaファイルを作成し、それらに必要なセットアップを記述します。コマンドの例として、エレベーターのジョイスティック操作やPID制御、ドライブトレインの前方への移動、インテークの開閉などを実行するコマンドを作成し、それらをシリアルまたは並列で実行するコマンドグループを作成する方法を学びます。

10:01

🔄 コマンドのライフサイクルと要件

コマンドのライフサイクルはinitialize、execute、endの3つの関数で構成され、これらを使ってコマンドの開始前、実行中、終了時の処理を定義します。initialize関数はコマンド開始前に1回だけ実行され、execute関数はコマンドが実行中である間繰り返し呼び出され、end関数はコマンド終了時に呼び出され、モーターを停止するなどのクリーンアップ処理を行います。コマンドは終了条件を定義するisFinished関数を持ち、他のコマンドによって中断されることも可能です。サブシステムの要件を指定することで、同じサブシステムを使用する他のコマンドが中断されるように設定できます。

15:05

🛠️ ロボットコンテナーの設定とデフォルトコマンド

RobotContainer.javaファイルは、サブシステムのインスタンスを作成し、ジョイスティックボタンをコマンドにリンクする中央的な場所です。ここでは、エレベーターのPIDコマンドやドライブフォワードコマンドなどをジョイスティックボタンに割り当て、それらのボタン操作によってコマンドが実行されるように設定します。また、サブシステムに対してデフォルトのコマンドを設定して、特定のボタンが押されていない場合の動作を定義できます。これにより、ロボットの動作を柔軟にコントロールできます。

20:05

🔧 オートノミクスモードのコマンドグループ

オートノミクスモードでは、シリアルまたは並列で実行されるコマンドグループを作成して、ロボットの行動を定義します。Sequential Command Groupを使用して、ドライブフォワードコマンドを実行した後、Parallel Command Groupでインテークとエレベーターのコマンドを同時に実行するように設定します。これにより、ロボットは自動運転モードで指定されたシーケンスを実行します。

📘 定数とシミュレータでのテスト

コード中の多数の数値を定数クラスにまとめることで、値の変更が容易になります。エレベーターの移動距離やPIDの定数、モーターポート、エンコーダーチャンネルなど、関連する数値を定数クラスに定義し、コード全体でそれらを参照します。最後に、シミュレータでロボットコードをテストする方法について説明し、シミュレータを使用してロボットの動作を確認できます。

Mindmap

Keywords

💡コマンドベースプログラミング

これはビデオの中心となるプログラミング構造です。コマンドベースプログラミングとは、ロボットの各機能を独立した「コマンド」として扱い、これらのコマンドを組み合わせて複雑な動作を実行することができるプログラミングスタイルです。ビデオでは、エレベーターボットの動作をコマンドベース構造でプログラミングすることで、より大きなプロジェクトを管理しやすくすることを示しています。

💡ドライブトレイン

ドライブトレインはロボットの移動に必要な部品の集まりを指し、ビデオでは2つのモーターと2つのエンコーダーがセットアップされています。ドライブトレインはロボットの基本的な移動機能を提供し、ビデオのエレベーターボットの動作を実現する上で欠かせない部分です。

💡エレベーター

エレベーターはロボットの垂直移動を可能にするメカニズムで、ビデオではPIDコントローラーを使用して上下を制御しています。エレベーターはロボットの機能拡張に重要な役割を果たし、ビデオのテーマであるコマンドベースプログラミングの応用例として紹介されています。

💡インテイク

インテイクはロボットの部品の一つで、物体を摂取するための機能を持ちます。ビデオではインテイクモーターを使って物体をロボットに取り込む動作を説明しており、コマンドベースプログラミングでインテイクの動作をコントロールする例として使われています。

💡サブシステム

サブシステムはロボットの各機能をカプセル化した独立したユニットで、ビデオではドライブトレイン、エレベーター、インテイクのそれぞれに対応するサブシステムを作成しています。サブシステムを使うことで、コードの可読性と管理性が向上し、ロボットの各部品のセットアップを整理することが可能になります。

💡コマンド

コマンドはサブシステムを操作する具体的なアクションを定義したもので、ビデオではエレベーターの上下移動やインテイクの開閉などの動作をコマンドとして実装しています。コマンドを使うことで、ロボットの動作を再利用可能な単位に分割し、より効率的なプログラミングが可能になります。

💡PIDコントローラー

PIDコントローラーは、プロポルショナル(P)、インテグレーション(I)、デリファレンス(D)の3つの要素から成る制御システムで、ビデオではエレベーターの位置を精密に制御するために使用されています。PIDはロボットの繰り返し精度を高めるために重要な役割を果たしており、コマンドベースプログラミングの中ではエレベーターの動作を細かく調整する例として紹介されています。

💡自動運転モード

自動運転モードはロボットが事前にプログラムされた動作を自動的に実行するモードで、ビデオではエレベーターボットが箱を運ぶ動作を自動運転モードで実行する方法を説明しています。自動運転モードの例として、1.5メートル先に進み、インテイクを閉じてエレベーターを上げることが挙げられます。

💡遠隔操作モード

遠隔操作モードは人間がジョイスティックを使ってロボットを操作するモードで、ビデオでは遠隔操作モードでジョイスティックのボタンを使ってエレベーターやインテイクの動作をトリガーする方法を紹介しています。遠隔操作モードは、人間が即時の判断を加えてロボットを操作する際に使われます。

💡シミュレータ

シミュレータは実際のロボットをコンピュータ上で模擬するツールで、ビデオではエレベーターボットの動作をシミュレートしてプログラミングをテストする方法を説明しています。シミュレータを使うことで、実際のロボットを動かす前にプログラムの動作を確認することができ、開発効率を向上させることができます。

Highlights

本集《从零到自动化》将讨论基于命令的编程,通过模拟器中的电梯机器人实例来学习。

介绍了如何将基于时间的机器人代码结构转换为基于命令的结构。

展示了在基于时间的结构中,机器人的驱动系统、电梯和进料装置的设置。

解释了将所有设置放在一个文件中会导致文件过长且难以阅读的问题。

介绍了基于命令的结构,通过创建子系统文件来分离每个机构的设置。

讨论了如何将操作封装成命令,以简化复杂的动作实现。

说明了在遥控操作模式下如何使用摇杆按钮触发命令。

展示了如何在自动模式下组合不同的命令来构建自动例程。

解释了如何使用命令组来并行或顺序运行多个命令。

讨论了子系统如何设置电机和传感器,以便命令轻松使用。

介绍了如何创建命令,包括初始化、执行和结束的生命周期。

展示了如何在RobotContainer.java中设置摇杆按钮与命令的链接。

解释了如何创建和使用PID控制器来控制电梯的移动。

讨论了如何创建驱动命令来控制机器人的移动。

介绍了如何使用供应商(Suppliers)来获取实时的摇杆输入。

展示了如何为子系统设置默认命令以处理未按下按钮时的默认行为。

讨论了如何创建命令组来构建自动模式下的例程。

解释了如何使用常量类来集中管理机器人项目中的数值。

介绍了如何在模拟器中运行机器人代码,并通过链接下载模拟器。

总结了视频内容,并鼓励观众在评论区交流心得。

Transcripts

play00:04

welcome

play00:04

in this episode of zero to autonomous we

play00:07

are going to talk about command-based

play00:09

programming

play00:11

today instead of using a physical robot

play00:14

we will be programming this elevator

play00:16

bot i made in a simulator by the end

play00:19

you'll learn how to program the

play00:21

drivetrain elevator

play00:23

intake and an autonomous sequence in the

play00:26

command based structure

play00:28

let's get started

play00:34

in the past few videos in the series

play00:36

we've always used the timed robot code

play00:38

structure

play00:39

which has an initialized function and

play00:41

periodic function for each robot mode

play00:45

and in the past few videos it has been

play00:47

fine because the projects were

play00:49

relatively small

play00:51

as we create larger projects in the

play00:52

future we'll need the command based

play00:54

structure

play00:57

so let's look at how to convert a timed

play00:59

robot

play01:00

into a command-based robot

play01:06

if we had made the robot in a time-based

play01:08

structure this is what it would look

play01:10

like

play01:12

at the top of robot.java we create all

play01:15

of our motors

play01:16

sensors and constants etc

play01:19

and we can see the first part is just

play01:21

for the drivetrain

play01:23

there are two motors two encoders and

play01:26

encoder conversion constant

play01:28

and a helpful method to quickly get the

play01:30

encoder value

play01:32

the next block is all about the elevator

play01:34

we have a motor

play01:35

a pid controller to move the elevator up

play01:38

and down

play01:39

and again we have some stuff related to

play01:41

the encoder

play01:43

finally there's the intake with two

play01:45

motors

play01:47

now these mechanisms don't have that

play01:50

many motors or sensors

play01:52

so it looks okay if we put them all in

play01:53

one file

play01:55

but if each mechanism had a lot more

play01:57

stuff it would make this file very long

play02:00

and unreadable so wouldn't it be nice if

play02:04

we can create a file

play02:05

for each mechanism and separate all the

play02:08

setup

play02:09

into each mechanism's individual file

play02:12

this is exactly what the command-based

play02:14

structure does

play02:16

in fact these files are called

play02:18

subsystems

play02:20

for this robot we have the drivetrain

play02:22

subsystem elevator subsystem

play02:24

and intake subsystem

play02:27

next let's look at our teleop periodic

play02:30

function

play02:31

in this timed robot remember from the

play02:33

previous videos

play02:34

this function runs repeatedly during the

play02:37

tele-operated control mode

play02:39

at the top we have a block of code to

play02:42

move the chassis using arcade drive

play02:45

the next spock of code controls the

play02:46

intake it has two modes

play02:49

in the mode where button 5 is pressed it

play02:51

closes the intake

play02:53

otherwise the intake will remain open

play02:56

then the next block of code deals with

play02:58

the elevator

play03:00

it again has a few possible types of

play03:02

actions

play03:03

if button 1 is pressed it will raise the

play03:06

elevator to 1.2 meters

play03:07

using pid button 2 will tell pid to

play03:11

bring it back down

play03:14

here we are using the pid controller

play03:16

from the wpi library

play03:19

first we set the setpoint then

play03:22

the calculate function takes in the

play03:23

current sensor position

play03:25

and returns the pid output

play03:29

buttons 3 and 4 are for backup if

play03:31

somehow the sensor cable breaks

play03:33

or the pid doesn't work somehow we still

play03:36

have a way to manually move the elevator

play03:40

finally if no buttons are pressed the

play03:42

default action

play03:43

is to stop the motor

play03:46

now notice how each box contains one

play03:49

action that a mechanism can use

play03:52

right now each action is really simple

play03:54

and only takes a few lines of code

play03:56

so this is okay but imagine if

play04:00

in the future we have a complicated

play04:02

action that has a few hundred lines of

play04:04

code

play04:04

it would be really messy to put them in

play04:06

these if statements

play04:08

like this also notice how we are writing

play04:11

some code many times

play04:13

i wonder if there's a way to factor out

play04:15

these actions

play04:16

so we only have to write them once to

play04:19

solve these two problems

play04:21

we can try putting each type of action

play04:23

into its own file

play04:35

in command base these files are called

play04:40

commands all right

play04:42

let's look at the autonomous mode for

play04:44

this robot and how we can combine

play04:46

different existing commands

play04:48

to construct an autonomous routine

play04:51

the goal for autonomous is to drive

play04:53

forward and pick up this box

play04:58

in autonomous net we will set the

play05:00

distance we want to drive to

play05:02

which is the current distance plus 1.5

play05:04

meters

play05:06

in autonomous periodic we will

play05:08

repeatedly check if we're there or not

play05:11

if we are not at 1.5 meters then drive

play05:14

forward

play05:15

once we get there then stop we can sort

play05:18

of see this as a kind of action as well

play05:21

an action that drives forward for 1.5

play05:23

meters then stops

play05:26

so let's put that into a command file

play05:31

okay after we have stopped we want to

play05:34

close the intake

play05:35

and raise the elevator oh hey

play05:38

we have already made a few commands to

play05:39

do those things so maybe now we can just

play05:42

use them

play05:44

now let's think of this in terms of

play05:46

commands

play05:47

we want to first run drive forward

play05:49

command

play05:50

and when that's done simultaneously run

play05:53

intake set command

play05:54

and the elevator pid command so

play05:57

we can put these two commands in the

play05:59

parallel command group

play06:01

and then put the drive forward command

play06:03

and this parallel command group

play06:05

in the bigger sequential command group

play06:09

so these are command groups they can run

play06:11

multiple commands

play06:12

in parallel or in sequence

play06:16

okay to recap the robot has three

play06:19

subsystems

play06:20

which sets up the motors and sensors for

play06:23

easy use by the commands

play06:25

then we have five commands each

play06:28

describes an

play06:29

action that can be performed by the

play06:31

three subsystems

play06:32

and the commands don't have to worry

play06:34

about the hardware details

play06:35

such as which ports the motors are

play06:37

connected to the subsystems handle that

play06:40

and commands can just use them by

play06:43

putting actions into command files

play06:45

we are also making them into building

play06:47

blocks which we can then group into more

play06:49

complex actions

play06:52

here we first group elevator pid command

play06:55

with

play06:55

intake set command in parallel to make a

play06:58

pickup box command rule

play07:00

then we combine drive foil command and

play07:02

the pickup box command rule into another

play07:05

command group

play07:06

which will automatically start doing the

play07:07

auto period

play07:09

and in the teleoperated mode we can set

play07:12

up some joystick buttons

play07:13

to trigger these commands so that's it

play07:16

for the theory

play07:18

let's start writing the robot code by

play07:19

making the subsystems

play07:24

first we are going to create a robot

play07:26

project this time we'll select command

play07:29

robot

play07:33

once everything is created we can see

play07:35

that there's a few more files here

play07:38

and we'll talk about those later for now

play07:41

to create our subsystems we want to go

play07:43

to the subsystems folder

play07:46

there is already an example subsystem

play07:48

here and we'll rename it to drive

play07:50

subsystem

play07:52

notice that this java file is a

play07:54

subsystem because it extends

play07:56

subsystem base so

play08:00

like i mentioned before we are going to

play08:02

just paste in

play08:03

all the motor and sensor setups here

play08:05

like this

play08:07

and because our commands will later on

play08:09

use this subsystem

play08:11

will also create a function to easily

play08:12

set the motor outputs

play08:15

as for the class constructor we don't

play08:17

have anything to put in here this time

play08:19

but if you have other setup to do such

play08:21

as inverting the motors with sensors

play08:23

they can go here another function here

play08:27

is the periodic function

play08:29

it's really similar to the robot

play08:30

periodic function which runs repeatedly

play08:33

regardless of which mode the robot is in

play08:36

but now we have one of these in every

play08:38

subsystem that we can use

play08:41

and for now we can send some debug

play08:43

information to the smart dashboard in

play08:45

here

play08:47

we won't be using the simulation

play08:48

periodic function

play08:50

and the subsystem is done next

play08:53

let's make the elevator subsystem

play08:56

so we'll create another file in the

play08:58

subsystem folder

play09:01

and make sure to extend subsystem based

play09:05

again we can paste in all the motor and

play09:07

sensor setup

play09:09

and like before we'll add another

play09:10

function to set the elevator motors

play09:14

finally let's send the encoder debug

play09:16

information

play09:17

to the smart dashboard again and that's

play09:20

it for the elevator subsystem

play09:23

now for the intake subsystem nothing new

play09:26

here

play09:27

create a file extend subsystem base

play09:31

paste in the setups write a function to

play09:34

use the motors

play09:35

and that's it

play09:39

great we have all of our subsystems

play09:41

created and ready to use

play09:45

the next step is to write the commands

play09:52

to do that go into the commands folder

play09:54

there's already an

play09:55

example command here and once i clean it

play09:58

up we can see there's five functions

play10:01

let's compare that to our timed robot

play10:03

example

play10:04

there we were saying if the robot is in

play10:07

this mode

play10:08

then just run this line of code

play10:10

repeatedly

play10:11

that's what the execute function does

play10:14

when this command is running

play10:15

the execute function will be called

play10:17

repeatedly

play10:18

however we have a few more features here

play10:21

for example

play10:22

if there's some setup that we have to do

play10:24

every time before this command starts

play10:26

we can put it in the initialize function

play10:29

if there's some last minute things we

play10:31

have to do before the command ends

play10:32

we can put it in the end function so

play10:36

the initialize function execute function

play10:38

and end function

play10:40

make up the whole life cycle of a

play10:41

command

play10:44

also as this command you can tell the

play10:47

robot whether this command is finished

play10:48

running or not

play10:50

if this command has finished the next

play10:51

command can take over

play10:55

there are two ways the command can be

play10:56

ended first

play10:58

the command itself can decide that it's

play11:00

done by returning true

play11:01

in the is finished function another way

play11:04

is something else

play11:05

can interrupt this command and we'll

play11:07

talk later about how that can happen

play11:10

but we can see now that the end function

play11:12

actually tells us why

play11:14

this command has been ended through the

play11:16

interrupted variable

play11:19

alright let's implement the elevator

play11:22

joystick command in this file

play11:24

first we'll rename the class

play11:28

here we want to use the elevator

play11:30

subsystem that we've already created

play11:32

however we don't want to make a new

play11:34

instance of it in every command that we

play11:36

have

play11:37

instead we only want one instance of

play11:40

every subsystem and put it in some

play11:42

central location

play11:44

we'll look at how to do that later for

play11:47

now

play11:48

we are going to assume that whoever will

play11:49

create this command

play11:51

already has access to that single

play11:53

instance of elevator subsystem

play11:56

and here we can just ask them to give it

play11:58

to us in the constructor

play12:01

another thing we are going to add in the

play12:03

constructor is the speed variable

play12:05

how fast you spin the motor this way

play12:08

our command can be reused to operate at

play12:10

any motor speed

play12:12

just by changing this variable

play12:15

now we can fill in the rest of the

play12:16

functions in execute

play12:19

we will set the motors to the desired

play12:20

speed

play12:22

in end we'll stop the motors

play12:25

it's finished it's set to false so this

play12:27

command never ends unless interrupted

play12:31

and we can add some debug information in

play12:33

initialize and end

play12:34

as well one last important line of code

play12:38

we need to add in the constructor

play12:39

is the add requirements function this

play12:42

tells the robot that this command

play12:45

uses the elevator subsystem

play12:48

and that all other commands that use the

play12:49

same subsystem

play12:51

should be interrupted and stopped before

play12:53

this one starts

play12:57

great now we are done creating a command

play13:00

let's see how to set up a joystick

play13:01

button to trigger this command

play13:05

the central place to put all of our

play13:07

commands and subsystems

play13:08

is the file robotcontainer.java

play13:12

here we will create one instance of

play13:14

every subsystem

play13:15

like this and if i clean it up a little

play13:19

bit

play13:19

we can see a function called configure

play13:22

button bindings

play13:24

this is the central place to link

play13:25

joystick buttons to your commands

play13:28

on top let's first create a joystick

play13:31

then in this function we can make a new

play13:34

joystick button object

play13:36

it wants to know which joystick this

play13:37

button is on and which index is the

play13:40

button

play13:42

and then if we scroll through its

play13:43

functions we can see it has a lot of

play13:45

triggers

play13:47

for example while active once starts the

play13:50

command when the button is pressed

play13:52

and interrupts it when the button is

play13:53

released in between

play13:55

it does not restart the command

play13:57

repeatedly

play13:58

this could be something we want when we

play14:01

press the button

play14:02

it will start elevator joystick command

play14:04

the command will keep running until

play14:06

someone interrupts it

play14:07

so when we release the button the

play14:09

trigger will interrupt our command

play14:11

stopping the motors so

play14:14

we can write new elevator joystick

play14:17

command

play14:18

and it wants the elevator subsystem and

play14:20

the speed

play14:22

fortunately we have all the instances of

play14:24

our subsystems right here

play14:26

so we can just pass it through and we

play14:29

can set the speed

play14:30

to be 0.5

play14:33

now we can create another joystick

play14:35

button on a different button index

play14:38

use the same command but have the

play14:39

operator in the opposite direction

play14:43

so that is the entire process of

play14:45

creating a command

play14:48

all right now let's create another

play14:50

command the elevator pid command

play14:53

first create a new file under the

play14:55

commands folder

play14:57

remember to extend command base to turn

play14:59

this generic java class

play15:01

into a command that the robot recognizes

play15:04

again we will have the same five

play15:06

functions

play15:08

in the constructor we will ask for a

play15:10

elevator subsystem

play15:11

instance and this time a set point

play15:14

number for the pid to go to

play15:17

we can store the subsystem in a variable

play15:19

and create a wpi

play15:21

pid controller using the setpoint and

play15:24

some pid constants

play15:26

we will also make the elevator subsystem

play15:29

a requirement of this command

play15:31

to stop other elevator commands when

play15:32

this one is running

play15:35

in initialize we'll call pid controller

play15:38

dot reset to clear any leftover

play15:40

integration term from the last time this

play15:42

command has run

play15:44

in execute we can give the pid

play15:46

controller the current encoder value

play15:49

and get the pid output speed then

play15:52

set the motors to that output

play15:56

in end we'll stop the motors just to be

play15:58

safe

play16:00

and in is finished we'll return false so

play16:03

this command runs forever until

play16:05

interrupted

play16:07

and we can add some debug info as well

play16:11

one important thing to notice is that

play16:13

although both the constructor

play16:15

and the initialize function are for

play16:17

setting things up

play16:18

the constructor runs only once when the

play16:20

robot powers on

play16:22

on the other hand the initialize

play16:24

function runs every time the command

play16:25

starts

play16:26

so that's every time we press the button

play16:29

since we don't need a new pid controller

play16:31

object every time

play16:32

we can create it in the constructor

play16:35

however

play16:36

pid controller.reset needs to run every

play16:38

time we press the button

play16:40

so it should be in initialize

play16:44

now going back to robotcontainer.java we

play16:47

can link some buttons to the elevator

play16:49

pid command

play16:50

like this so that button 1 moves the

play16:53

elevator to 1.2 meters

play16:54

button2 brings it down

play16:58

next we'll make our drive folder command

play17:02

let's create a new command file and this

play17:05

should look familiar

play17:07

we will ask for the drive frame

play17:08

subsystem and a distance value

play17:12

we'll save these values in some global

play17:14

variables and require the drivetrain

play17:16

subsystem

play17:18

because the same instance of drive

play17:20

forward command can be run multiple

play17:21

times

play17:22

we want to make sure we drive that

play17:24

additional distance every time it is

play17:26

used

play17:27

to do that we'll add an encoder setpoint

play17:29

variable

play17:30

to keep track of how far we need to go

play17:32

in this current run

play17:34

in initialize set it to the distance

play17:36

plus the current encoder reading

play17:39

in execute we drive forward at half

play17:41

speed

play17:43

and in the end we stop the robot

play17:46

in the it's finished function this time

play17:48

we will return true to have the command

play17:50

finish

play17:51

once we are at that distance so later

play17:54

when we put this command

play17:55

in the sequential command group once

play17:58

this command finishes

play17:59

the next one will start running and it's

play18:02

always good to add some debug info as

play18:04

well

play18:07

now the rkdrive command

play18:10

here's a new file and we can import and

play18:13

require the drive frame subsystem again

play18:16

however when asking for joystick inputs

play18:19

we can't just use doubles like before

play18:22

because once they are passed in they

play18:23

become static and don't change with the

play18:25

real-time joystick inputs

play18:28

what we really want to do is pass into

play18:30

functions

play18:31

that get the latest joist inputs and

play18:34

then run those functions

play18:35

every time in execute those functions

play18:39

are called suppliers for doubles

play18:41

because every time we call them they

play18:43

give us a double

play18:45

now in execute when we're implementing

play18:48

our k drive

play18:49

we use the get method of the suppliers

play18:51

to rerun those functions

play18:53

to get the latest values of the

play18:54

joysticks

play18:56

and again set the command to never

play18:58

finish and add some debug info

play19:03

finally we have the intake set command

play19:06

again new file import the intake

play19:10

subsystem

play19:12

require the subsystem ask whether to

play19:15

open or close the intake

play19:17

set the motor in execute have the

play19:20

command never finish

play19:23

and add some debug info

play19:27

back in robotcontainer.java we will link

play19:30

this command

play19:30

to button5

play19:35

one more thing we can do is to set some

play19:37

default commands to each subsystem

play19:40

for example button 5 closes the intake

play19:43

but when button 5 is not pressed we want

play19:45

the intake to default to open

play19:48

so when setting up robot container we

play19:51

can write

play19:52

intake subsystem dot set default command

play19:55

and a command to open the intake

play19:58

for the drivetrain the default can be

play20:00

arcade drive

play20:02

so we create a new arcade drive command

play20:04

and pass the two functions

play20:06

that get the joystick speed and turn

play20:08

axes

play20:09

in java this is a shorthand way to

play20:11

create functions that return the values

play20:13

of these methods

play20:16

for the elevator if no commands are

play20:18

present we can run a new one with the

play20:20

motor stopped

play20:24

okay now let's create a command group to

play20:26

construct the autonomous mode routine

play20:29

if we scroll down in robot container we

play20:31

can see a

play20:32

get autonomous command function when the

play20:35

robot starts autonomous mode

play20:36

it will call this function to ask what

play20:38

it should do

play20:40

here we can make and return the command

play20:42

group we want it to run

play20:44

there are a few ways to make a command

play20:46

group today we'll just create one right

play20:48

here

play20:50

first we want a new sequential command

play20:52

group as it can run some existing

play20:54

commands in order

play20:56

we will put the drive4 command first

play21:00

alright but for the next two commands we

play21:02

actually want to run them in parallel

play21:05

to do that we can surround them in a new

play21:07

parallel command group

play21:08

so when autonomous mode starts the

play21:11

sequential command group will run the

play21:12

drive foil command

play21:14

to drive to 1.5 meters and when that's

play21:16

done

play21:17

it will run the parallel command group

play21:19

which will trigger both the intake

play21:20

command

play21:21

and the elevator command at the same

play21:23

time

play21:25

great now let's return this whole thing

play21:30

okay by this point the robot code is

play21:33

fully functional

play21:34

but there's one last thing we can do you

play21:37

see

play21:37

there's a lot of numbers scattered

play21:39

around in this file

play21:41

for example this 1.2 makes the elevator

play21:43

go to 1.2 meters

play21:45

and that's fine until one day maybe the

play21:47

robot drive team

play21:49

tells us to change it to 1.3 meters

play21:52

then we need to hunt down and change

play21:54

every occurrence of this number in this

play21:56

entire project and that's really easy to

play21:58

mess up

play22:00

so what if we group all of these numbers

play22:03

and put them in one central location

play22:05

so they're easy to find and change

play22:08

that is what constants.java is for

play22:12

here we can define an asset class just

play22:15

for the elevator mechanism

play22:17

and all the numbers related to the

play22:18

elevator goes in here

play22:21

so we can define the number 1.2 in here

play22:23

as the

play22:24

k raised position back in robot

play22:27

container

play22:28

we will reference this variable

play22:32

next we can also include the motor port

play22:35

encoder channels

play22:36

encoder constant pid constants and some

play22:39

driver preferences here

play22:42

and we can do the same thing with the

play22:43

drivestream subsystem

play22:46

intake subsystem and for the joystick

play22:50

button mappings as well

play22:53

finally we'll replace all the standard

play22:55

numbers in the robot project

play22:56

and reference them to here

play23:11

okay that concludes the robot code now

play23:14

let's run it in the simulator

play23:17

to download the robot sim simulator go

play23:19

to this link

play23:24

if you're on windows extract the zip

play23:27

file and run the

play23:28

exe file

play23:31

you can already drive around using the

play23:33

default code

play23:34

but you run your own code download robot

play23:37

lib

play23:40

go to this url and unzip the file

play23:50

to import a real robot project into the

play23:52

simulated robot lib

play23:54

copy your entire src folder and paste it

play23:57

into robotlib

play24:06

now open robot live in visual studio

play24:08

code

play24:09

and everything you wrote in the real

play24:11

robot project also magically works here

play24:15

finally to run your program click run in

play24:18

the main.java file

play24:20

and you can see a driver station

play24:22

appeared and a smart dashboard

play24:24

automatically popped up

play24:27

now let's start autonomous mode and see

play24:29

a picture of a cube

play24:35

and for teleop mode focus on the

play24:38

simulator window

play24:39

to operate the joysticks

play24:42

for more tips and tricks such as

play24:44

changing the camera view angle

play24:46

showing debug information and enabling

play24:48

60 frames per second

play24:50

check out the documentation

play24:54

i hope you have enjoyed this video of

play24:55

zero to autonomous

play24:57

hit that like button if you learned

play24:58

something new and until next time

play25:00

happy coding

Rate This

5.0 / 5 (0 votes)

Etiquetas Relacionadas
ロボットプログラミングコマンドベースシミュレータエレベーターインタークドライブトレイン自動運転開発ツール教育コンテンツコード構造
¿Necesitas un resumen en inglés?