-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Custom FTC Blocks (myBlocks)
This tutorial shows how to make custom FTC Blocks, to be used in regular Blocks programs. These "myBlocks" are programmed in Java, with OnBot Java or Android Studio.
sample myBlock: operate a servo, no value returned
A myBlock can add advanced capability previously available only to teams using all-Java code. Or, a single myBlock can serve as a 'super-Function', containing robot instructions that previously needed many regular Blocks. Now your team's Blocks code can be more powerful, and simpler!
sample myBlock: return encoder target value based on inputs
Also, myBlocks programming allows some team members to begin learning and using Java, contributing valuable new features. The other team members can continue learning and working in Blocks, producing the team's official code. Nobody is held back, or left behind.
Hats off to Google engineer Liz Looney for this major development!
- This tutorial builds myBlocks with OnBot Java, a programming tool running on the Control Hub or Robot Controller (RC) phone. Students already using Android Studio can easily follow the same programming.
- This tutorial does not teach Java or OnBot Java (OBJ), beyond the bare minimum needed for basic myBlocks.
Start with a simple myBlock that creates a greeting "Hello World" (of course!).
Open a Chrome browser connected via Wi-Fi to a Control Hub or RC phone. Go to the address http://192.168.43.1:8080 (CH) or http://192.168.49.1:8080 (RC), and click the OnBot Java tab.
Note: a computer can usually connect to only one Wi-Fi network at a time. To follow this tutorial while programming, first allow this single web page to load completely, then connect to the Control Hub or RC phone. If you need internet and FTC programming together, connect an Ethernet cable to an internet router or try adding a USB Wi-Fi dongle.
Click the large plus-sign icon to open a new file; call it SampleMyBlocks.java. Use the default 'teamcode' folder location. Don't choose a Sample OpMode, and use the default setting 'Not an OpMode'. Click OK.
In the work area you see a simple/empty Java program.
Line 1 shows the default storage folder 'teamcode', and Line 4 shows the class name, same as the filename. It's public
so other classes can access it. Notice the left curly brace at Line 4 and right curly brace at Line 7. Place all your code between these curly braces.
The two forward-slash marks // indicate a comment line, all ignored by the Java software. Good programmers use lots of comments, to communicate with your FTC teammates and with your future self! You will not remember every little detail of your programs... and will thank yourself later for commenting heavily!
Programming note: A class describes methods (actions) and fields (properties) that can be used by objects (examples or instances of the class). A class called 'dogs' might contain methods 'run' and 'sleep', and fields 'friendliness' and 'appetite'. Your pets Spot and Rover would be objects or instances of the 'dogs' class.
After the class name, type extends BlocksOpModeCompanion
. This declares your new class as a subclass or child of a higher superclass or parent. The parent class BlocksOpModeCompanion contains useful tools to be inherited by your new subclass.
When you enter that line, the OBJ software automatically creates an import
statement, making the parent class available. Convenient!
Programming note: classes inherited from BlocksOpModeCompanion include OpMode, LinearOpMode, Telemetry, HardwareMap, and Gamepad. All very useful! Your myBlock method can directly use objects or instances of these classes without declaring them. Examples follow below.
Inside the curly braces, type new lines as follows:
@ExportToBlocks (
comment = "Here is a greeting for you.",
tooltip = "Greet a person or group.",
parameterLabels = {"Recipient"}
)
These are optional labels to appear on your new myBlock; you'll see below. Even if you don't want to use any of these features, you still need the annotation line @ExportToBlocks
.
When you typed that annotation, OBJ automatically added the import
statement.
Now you're ready to create the method, namely your first myBlock. Type the following lines:
public static String myGreeting (String greetingRecipient) {
return ("Hello " + greetingRecipient + "!");
}
The method's name is myGreeting
. It is a public
method, so it can be used or called from other classes. And it's a static
method, required for all myBlock methods.
The first usage of the word String
indicates the method gives or returns one output of type String or text. The second usage is inside the parentheses, indicating the method takes one input named greetingRecipient
, also of type String.
Programming note: the method's name and list of parameters (inside the parentheses) is together called the method signature.
The method contains only one line of instruction, on Line 15: three text items are joined to form a single text string. The middle text item is the input parameter greetingRecipient, to be entered by the Blocks user. The longer combined string is returned to the program that called this method. Namely, the combined string is provided to the Block that uses your new myBlock.
That's it for the Java! Click the wrench icon to Build Everything including your new class. If there are error messages, read carefully and fix any mistakes. When you see "Build Successful!", your new myBlock is ready to use.
Note: this tutorial intends for you to manually type the Java code above. OnBot Java helps by suggesting some code as you type, and by entering import statements when classes are used. Android Studio helps even more. If you require pre-typed text of this example, click here.
In the browser still connected to the RC phone or Control Hub,
- click the Blocks tab
- click Create New OpMode, name it Test_myBlocks_v01
- use the default Sample, called BasicOpMode
- click OK
You will now see a new menu choice at the bottom, called Java Classes. Open that, to see the class you created, called SampleMyBlocks. Click that, and drag your new myBlock out to the work area.
This myBlock has one grey input field or socket, containing the letter A to indicate a String or text input. Type the greeting recipient, World.
To display the myBlock's String or text output, look under Utilities for the Telemetry menu. Drag out the Telemetry.addData Block that displays text (not numbers).
In the key
socket, type A greeting for you. At the text
socket, drag and connect your new myBlock. The myBlock's text output will be read and displayed by the text version of the Telemetry.addData Block.
Place these Blocks in the repeat while (loop) section of your OpMode, before Telemetry.update. Click Save OpMode.
On a connected Driver Station device, select this OpMode called Test_myBlocks_v01, touch INIT and the Start Arrow. Look at the Driver Station (DS) screen to see the traditional greeting for new programmers.
Congratulations! You are now an OnBot Java programmer and myBlocks creator.
For extra fun: try the Telemetry.speak Block, followed by a 1500 millisecond
.sleep
Block. You can learn more about DS spoken telemetry at this separate tutorial.
This tutorial has three more sections with myBlocks guidelines, followed by six examples for you to re-type in OnBot Java and test in Blocks. Enjoy!
The required annotation @ExportToBlocks
has optional fields, which may be listed in any order. These fields allow a myBlock to have a custom comment, tooltip, parameter labels, and parameter default values.
- The comment text appears in a balloon when the Blocks user clicks the blue question-mark icon. Tell the user how to use your myBlock.
- Must be entered on a single line, with no 'line breaks'. This requirement can be met by joining text strings; an example is below.
- The blue icon will appear only if a custom comment is specified. The Blocks user can add and remove the blue icon, and can edit its text in the (re-sizeable) balloon.
- A tooltip appears with a mouseover: hovering the mouse cursor over an image or icon. Every Block has a short tooltip to indicate its purpose.
- Must be entered on a single line, with no line breaks.
- If a custom tooltip is not specified, the default tooltip will name the method, its enclosing class, and return type.
- Another tooltip, for the grey input socket (at right), is auto-generated based on parameter type.
- The parameterLabels text appears on the myBlock, each next to its grey input socket.
- Multiple labels are separated by a comma. Line breaks may be used between labels.
- For a single parameter, this also works:
parameterLabels = "sampleParameter"
.
In the Hello World example, you may have noticed that the parameter label Recipient was not the same as the Java input parameter name greetingRecipient. They don't need to be the same. One is for the Blocks user, the other is for the Java programmer. Just list them in the correct/same order, so their meanings correspond.
If you don't label the inputs, a default label will instead show each declared type (e.g. String, boolean, int, double, etc.). In any case each grey socket will contain a generic sample of the required type (e.g. A, false, 0), with an appropriate tooltip. See below to customize this value.
If the number of parameter labels does not match the actual number of Java parameters, all custom label will be ignored. Instead the default labels will be displayed.
A myBlock may have up to 21 parameters... not recommended! Keep things simple.
New for SDK version 7.2, you may specify default values for all myBlock parameters (not just some of them).
Just add the annotation field parameterDefaultValues
, formatted like the parameterLabels
field with curly braces.
- Default values are separated by a comma. Line breaks may be used between values.
- For a single parameter, curly braces can be omitted:
parameterDefaultValues = "999"
.
Be sure to list the default values in the same order as the parameters in the method signature and the list of parameter labels. Also make sure each default value is the correct Java type, matching its parameter.
If the number of default values does not match the actual number of Java parameters, all default values will be ignored. Instead the generic values will be displayed (or blank for type String).
Two more optional annotation fields are:
- heading, such as "My Amazing myBlock"
- color, without quotes, just a color number. For example 155 is green, 255 is blue. Check it out!
Here's a sample myBlock using all these features:
Notice that a default text value could be a suggested real parameter, or an instruction to the user (as shown here). Either can be edited by the user.
Again, the annotation @ExportToBlocks
must appear immediately before each myBlock method, even if not using the optional fields.
Do not type or run the following myBlock example. Its dummy inputs simply illustrate various parameter types. This myBlock does correctly read the robot battery voltage, but FTC Blocks now offers a VoltageSensor Block in the Sensors menu.
Notice that the Java parameters uno
, parola
and verita
have myBlock labels One
, Word
and Truth
. They are allowed to be different.
The comment field explains this myBlock to the Blocks user, who can edit or delete the comment. Only for display here, this sample text appears on multiple lines; normally it must be typed as a single line of text or as joined quotes (example below).
A myBlock tooltip should be brief. Note: the four tooltips don't all appear at the same time; each appears with a mouseover. One is custom, three are auto-generated based on input type.
Each input socket shows a default value of its parameter type, with a corresponding tooltip. As shown in the method signature, parameter uno
is Java type double
(a number), parola
is type String
(text), and verita
is type boolean
(true or false).
Programming tip: unlike primitive types, Strings must be compared with
Object.equals()
rather than==
. That's because a text parameter is actually an object or instance of the String class, which has its own methods equivalent to basic Java operators like==
,>
,<
, etc.
Programming tip: In this example, the variable
batteryVoltage
is declared and initialized outside the method, and thus could be used by other methods in this class.
Some final notes about parameter types:
- If your myBlock method uses a parameter declared as type
boolean
orjava.lang.Boolean
, the myBlock's input socket will accept any Block that returns (supplies) a Boolean value. - For method parameters declared as
float
,java.lang.Float
,double
, orjava.lang.Double
, the myBlock will accept any input Block that returns a number. - For method parameters declared as
byte
,java.lang.Byte
,short
,java.lang.Short
,int
,java.lang.Integer
,long
, orjava.lang.Long
, the myBlock will accept any input Block that returns a number and will round that value to the nearest whole number. - If your myBlock method uses a parameter with only one text character, you may use (instead of type
String
) typechar
orjava.lang.Character
. In that case, the myBlock's input socket will accept any Block that returns text and will use only the first character in the text string.
If you edit and re-Build a myBlock's Java code, you might need to replace that myBlock in the Blocks OpMode. It depends on whether you change the myBlock's visible or external features: annotation fields, input parameters or returned outputs.
If your Java change does affect external features, its updated myBlock is available only from the Java Classes menu in Blocks. Any such myBlock already placed in an OpMode is obsolete and may generate a Blocks warning; replace it with the new myBlock. In some cases you may need to re-open the OpMode from the top-level Blocks listing.
If your edit affects only the myBlock's internal processing, it might update automatically after "Build Everything", without needing a fresh replacement from the Java Classes menu. In some cases you might not even need to click Save OpMode in the Blocks screen -- you could simply re-run the OpMode on the Driver Station with INIT and Start. This can allow very fast testing of minor/internal changes to the myBlock.
In any case, consider adding versions to your myBlock names, such as myGreeting_v01. Copy and paste before editing, to keep all related myBlock methods in the same Java class. In Blocks, all uniquely named versions will be available in the Java Classes menu, under that single class name.
Keep the class name short and generic, such as MyBlocks, SampleMyBlocks, Team8604MyBlocks, DrivingMyBlocks, etc. It will contain all or many related myBlocks, not just one myBlock per the simple examples above.
In that single class, each myBlock method must appear after its own annotation @ExportToBlocks
. That class may contain other methods that are not myBlocks; omit the annotation before any non-myBlock methods. Such methods might be used to initialize variables, or might be (shared) submethods called by one or more myBlocks. An example is shown far below.
This tutorial has covered these basic requirements so far:
- create/store in org.firstinspires.ftc.teamcode folder/package
- class extends BlocksOpModeCompanion
- each myBlock method needs annotation @ExportToBlocks
- method must be public and static (must not be abstract)
- replace myBlocks after external edits
The rest of this tutorial gives examples that you can re-type in OnBot Java and test in Blocks. Try making changes and adding features!
Here's a very simple example to illustrate how a myBlock can access the robot hardware. Here, the Blocks user enters the servo's name as a parameter of the myBlock.
Note: this tutorial intends for you to manually type the Java code above. It's good practice! If you require pre-typed text of this example, click here.
Lines 10-11 contain two strings of text (each in quotes), joined with a "+" character to form a single text string. This is an alternate way to meet the requirement that a comment field must be a single line of text, with no 'line break'. Shorter strings allow all the text to be visible on-screen, without scrolling sideways.
Line 15: this method has 3 inputs and no outputs (keyword void).
Line 17 shows how to access hardwareMap, the configured devices list provided from BlocksOpModeCompanion. That single line of Java does this:
- declare a new variable called myServo, of type (class) Servo
- get the properties (methods and variables) of the named servo from hardwareMap
- assign those properties to the new variable myServo
Line 20 is a for loop, which you can learn about here or here. It runs the specified servo back and forth, using the specified duration and number of cycles. This for loop has the added condition opModeIsActive()
, to monitor and verify the OpMode has not been stopped.
Lines 22 and 24: the object myServo uses a method setPosition()
from the Servo class.
Lines 23 and 25: the object linearOpMode uses a method sleep()
from the class inherited from BlocksOpModeCompanion.
The Blocks user must enter the exact device name from the active configuration. Hardware device names (motors, servos, sensors) are found in the Configure Robot menu of the RC app or paired DS app. Or, it might be easier to retype the name from any Blocks drop-down list containing those device types. For example, a green Servo set .Position
Block will display all configured servo names -- make sure the correct configuration was made active before entering the Blocks session.
As an alternate, you could 'hard-code' the servo's name directly into the Java method, instead of the Blocks user entering the servo name as a parameter.
PROs of hard-coding:
- myBlock is simpler
- Blocks user doesn't need to know or enter the servo name
CONs of hard-coding:
- you need to know the exact servo name in advance
- if the name ever changes, your myBlock cannot find the servo
Note: As a programmer, you will constantly face choices like this, with pros and cons. This is part of software design, a key professional skill and career path.
A different version (gamepad-controlled, fully commented) of the above Java program is provided here. It illustrates using 5 of the 6 objects provided by BlocksOpModeCompanion, including telemetry and the gamepads. This longer example, or the short version above, could be used in an OpMode like this:
The final .sleep
Block allows any telemetry to remain visible on the DS screen, before this sample OpMode ends.
Here is the Java code (method only) for converting an inches of driving target into an encoder counts target. The conversion depends on the drive motors' counts-per-rotation (CPR), and the diameter of the drive wheels. This example assumes 1:1 gear ratio between the motor and wheel.
This method takes three inputs from the Blocks user, and returns one output (of type int
or integer) to the regular Block that calls the myBlock.
Programming tip: notice the calculation uses the variable or constant named PI, from the inherited class Math. This holds the fixed numeric value 3.14159....
Here is an example of typical usage.
Programming tip: notice the
(int)
operator at thereturn
command. This converts or casts the countsToDrive variable of typedouble
to typeint
, to be compatible with the required return type. Learn more about type casting here or here.
As programmer, you could modify this example in many ways, such as:
- handle a gear ratio between the drive motors and wheels
- the second and third parameters could be 'hard-coded' into the myBlock, if they will never change
- those 2 variables could be initialized in a non-myBlock method and used by multiple myBlock methods in that same Java class
FTC timers offer much more capability than the familiar .sleep
Block. Java programmers can learn about timers from this Blocks tutorial; you can easily apply its lessons to Java programs.
When creating myBlocks, be careful when converting or 'packaging' a section of existing Java code into a myBlock method. As a programmer, you must consider where your myBlock might be placed in the OpMode. For example, if the myBlock is placed inside a repeat while loop, the Java method will be called many times -- this may or may not be what you intended. Use the annotation comment to tell the Blocks user how your myBlock should be run, including looping (or not).
A particular caution with timers: creating or instantiating a new FTC timer also starts or resets that timer. If a timer is created inside a myBlock that's used in a Blocks repeat loop, that timer will constantly reset and never advance to the intended time limit.
The following example separates the create timer task from the reset timer task.
Line 15: this single line of Java does all this:
- declare a field called myStopwatch, of type (class) ElapsedTime
- the field is private, can be used only in this class SampleMyBlocks
- the field is static, can be used in static methods such as myBlocks
- call the constructor method ElapsedTime() to instantiate a new ElapsedTime instance
- assign that instance to the field myStopwatch
Lines 18-19 again show two strings of text (each in quotes), joined with a "+" character to form a single text string. This is an alternate way to meet the requirement that a comment field must be a single line of text, with no 'line break'.
Line 22: this method has no inputs (empty parentheses) and no outputs (keyword void). This is why the annotation @ExportToBlocks was missing the parameterLabels field.
In Line 24 the data is displayed using a formatting code, indicated by the percent sign. The .2f will display a numeric value with 2 digits to the right of the decimal point.
Also on Line 24, the object myStopwatch uses a method time()
to retrieve that timer's current value in seconds.
Line 28: the double-strokes operator || means "OR". Other operators include && ("AND"), == ("EQUALS"), and != ("NOT EQUAL TO").
Line 29: the object myStopwatch uses a method reset()
to start the timer again from zero.
So, what was the danger? A programmer might naturally place Line 15 inside the method, perhaps at Line 23. But that would reset the timer at every cycle of the repeat while loop. The stopwatch would always show zero.
Or, a programmer might use Line 15 to replace Line 29, since they "do the same thing". But the object myStopwatch is needed at Line 24 also, for telemetry. Moving the telemetry to be after Line 29 does not help. If the operator has not yet pressed gamepad button X, the object does not exist and the program will crash.
When you clicked "Build Everything" in OnBot Java, all of the code in your SampleMyBlocks class was processed. That included creating the object myStopwatch, which became available for any method in that class. It was not necessary to declare it inside the myBlock method. In this case, it needed to be outside the method.
Here's the myBlock in a repeat loop, with its comment and tooltip:
Again, the comment field is the only way to communicate with future users of your myBlock. They cannot see your Java code or its Java comments. Keep your myBlocks interface simple, and the instructions clear.
Note: this tutorial intends for you to manually type the Java code above. OnBot Java helps by suggesting some code as you type, and by entering import statements when classes are used. Android Studio helps even more. If you require pre-typed text of this example, click here. The linked copy includes more Java comments, omitted above to focus on the Java code. Also not shown are the package and import statements.
Your Java class may also contain methods that are not myBlocks. Consider this if you have multiple myBlocks that perform a shared internal process or calculation. This is a good programming practice in general, not specifically related to myBlocks.
To illustrate, consider the Driving Example above. Imagine you want to create myBlocks to support two different robots.
- Robot A has 4-inch drive wheels with AndyMark NeveRest 40 motors.
- Robot B has 3-inch drive wheels with NeveRest Orbital 20 motors.
- You want the myBlocks to be very simple for your Blocks programming teammates.
Your solution:
- One MyBlock per robot.
- Each Blocks user needs to specify only the distance to drive, in inches.
- Each myBlock uses the appropriate wheel size and motor encoder CPR.
- The myBlocks share a 'utility' method to convert distance to encoder counts.
Line 34 shows the shared method that is not a myBlock. Simply omit the annotation @ExportToBlocks. The keyword private
means the method can be called only from inside the same class. Use this whenever possible.
Lines 17 and 29 call the shared method. The method calls provide 3 parameters, which do not have the same names as the input parameters of the 'utility' method -- but their types should match.
At line 38, (int) converts, or casts, a decimal number to integer type. This is called type casting. Programmers must pay close attention to compatible data types. For example, a DC motor set .TargetPosition
Block should be given an encoder value as a simple integer, not a decimal number.
At line 15 and others, the keyword final
indicates a Java constant: a variable that cannot change value. Java constants are traditionally ALL CAPS. Can you find the Math constant in this program?
Here are the Robot A and Robot B myBlocks, each with its comment balloon and tooltip. Very simple, as you wanted!
Note: this tutorial intends for you to manually type the Java code above. If you require pre-typed text of this example, click here. The linked copy includes a proper/full amount of Java commenting, omitted above to focus on the Java code. Also not shown are the package and import statements.
The current version of regular FTC Blocks (FTC SDK 7.0) does not provide read/write access to an external file, other than automatic Log or Match Log file entries. File access is a useful capability, available so far to Java programmers only. Now it can be done with myBlocks!
Here's an example pair of myBlocks. One myBlock writes a numeric value to a specified filename, and a companion myBlock can later read that value from the same file.
The file is stored on the Control Hub or RC phone, in the FIRST/settings folder. It exists separately from the FTC app, OpModes and other FTC files.
Write and read actions can happen in the same OpMode or different OpModes, allowing various scenarios:
-
Autonomous passes information to TeleOp. For example, what was the latest value of a sensor or encoder?
-
A special set-up OpMode allows gamepad input to choose an autonomous strategy and adjust key parameters. The robot could then be idle for a long time, even turned off. When the match begins, the Autonomous OpMode would read those settings and implement the chosen/adjusted actions.
-
A dedicated log file reports key sensor data in a custom format, with optional time-stamps. For program development and debugging, this could be more efficient than working with the large standard logs or Match Logs.
The Java code for this example is available here, with extensive comments that explain some unfamiliar Java expressions. The code can be copied and pasted directly into OnBot Java or Android Studio.
Programming tip: Instead of memorizing every possible Java command, programmers often study and modify existing code for a similar task. Unfamiliar commands are explored with an internet search, reference book, at the FTC Javadoc reference, or at the official Oracle Javadoc.
This simple example supports only a single numeric value per filename. Better versions would allow multiple values and data types -- a good programming challenge!
Be careful about placing myBlocks inside loops. Expanding on the current example, your myBlock might read a larger amount of (unchanging) data from a file. If your OpMode needs that data only once, reading the file in a loop needlessly adds cycle time and might increase the risk of a corrupt or interrupted read operation.
Instead, read the file once and store the relevant data in a variable or array. Then process the variable as needed, inside the loop.
The same suggestion might apply to reading sensors and encoders, if the data are not changing and are needed only once.
Telemetry messages are sent from the Robot Controller to the Driver Station up to four time per second, by default. This maximum refresh rate can be changed with Android Studio or OnBot Java, but not with regular Blocks. Now a myBlock can provide that capability too!
This simple example allows a Blocks user to change the standard time interval from 250 milliseconds to any other interval.
A lower time interval can allow faster update of sensor or encoder data. A higher interval can ease the RC-DS communication bandwidth load.
Here's the Java code for the method only:
Note: this tutorial intends for you to manually type the Java code above. If you require pre-typed text of this example, click here. The linked copy includes the usual class declaration and package/import statements.
Want to verify this actually works? Another, slightly more advanced myBlock allows measuring the time between Telemetry updates; it's posted here. That myBlock can be used in a Blocks program like this; download the raw .blk file and click the Upload Op Mode button at the main Blocks menu. Read all comments and instructions.
MyBlocks offer great potential for creativity and robot capability. Start by programming myBlocks for tasks that an existing group of Blocks can do. Later, add functions that are not available with regular Blocks. Here are some examples of both:
-
Set one or more program variables during INIT, using the gamepad. This can be done with regular Blocks, but a good User Interface (UI) requires multiple long and complex Functions.
-
Create driving actions with multiple sensor controls. For example, gyro-based steering towards a distance goal (ultrasonic or vision target). Or Run_To_Position while following a line. A myBlock can provide Blocks users with controls previously considered too complex.
-
Provide access to External Libraries, new for FTC SDK 7.0. More info is here.
-
One of the above examples controls a servo specified by the Blocks user. This could lead to a family of separate myBlocks to interact with 1 device, 2 devices, etc. Or a generic single myBlock could interact with, say, up to 4 DC motors. The Java method would process only those DC motors with a filled-in parameter name.
-
Control the LED flashlight on the RC phone?
-
Could telemetry.speak have a myBlock equivalent of the Boolean
AndroidTextToSpeech.isSpeaking()
?
Looking for ideas? The top-level API Documentation for the FTC SDK is here. Click RobotCore to see many commonly used classes in the left-side menu, and you can also check other sections.
Do you have suggestions or a good example to share? Send to [email protected].
Here are some tips for efficiency, from the developer Liz Looney:
-
Limit the number of method calls. Calling a single myBlock that does 5 tasks uses less overhead than calling 5 myBlocks that each do one task.
-
Limit the number of parameters. If your myBlock needs certain information that won't change during the OpMode, use an initialize method that's called once at the start of the OpMode. The initialize method stores that information, to avoid repeatedly passing the same parameter each time the myBlock is called.
-
MyBlocks now provide access to the full range of Java in the FTC Software Development Kit (SDK). Blocks programming can now perform tasks previously unavailable to Blocks-only teams. This now includes External Libraries.
-
MyBlocks can neatly package previously long or complex Functions in FTC Blocks.
-
MyBlocks programming allows some team members to begin learning and using Java, contributing valuable new features. The other team members can continue learning and working in Blocks, producing the team's official code. Nobody is held back, or left behind.
-
MyBlocks can be created with OnBot Java, which runs on the RC phone or Control Hub. Building and testing are very fast. Many FTC teams do not have easy access to Android Studio, for reasons including school computers that prevent software installation.
-
By developing and sharing myBlocks, experienced FTC teams could help new teams in a more direct way, beyond simply posting a link to their Java library. The FTC community might ultimately benefit from a curated repository for tested, well documented myBlocks. Perhaps the "Blocks Store"?
.
Questions, comments and corrections to [email protected]
.
-
TensorFlow 2023-2024