The Enka-Candler Robotics Language
- Crystal 99.3%
- Just 0.7%
| .github/workflows | Add CI workflow and expand README with setup and syntax docs. | |
| examples | Rename gpad to gpad1 and add dual driver arm example. | |
| spec | Rename gpad to gpad1 and add dual driver arm example. | |
| src | Rename gpad to gpad1 and add dual driver arm example. | |
| .editorconfig | Refactor the compiler for maintainability and add a test suite. | |
| .gitignore | chore: create a justfile | |
| justfile | Refactor the compiler for maintainability and add a test suite. | |
| LICENSE | chore: initial language commit | |
| README.md | Rename gpad to gpad1 and add dual driver arm example. | |
| shard.yml | Refactor the compiler for maintainability and add a test suite. | |
Enka-Candler Robotics Language
The Enka-Candler Robotics Language (ECRL, pronounced eck-ruhl) is a language that compiles to Java and the FTC SDK. Because it compiles to the FTC SDK, this language is meant for FTC teams.
Official Locations
These are official locations of ECRL. It is recommended to only get ECRL from these locations.
Getting Started
Prerequisites
Build the compiler
just build
This produces the ecrl binary at bin/ecrl.
Compile an ECRL program
just run path/to/program.ecr
This writes Java output to path/to/program.ecr.java. You can also invoke the compiler directly:
./bin/ecrl -s path/to/program.ecr -o path/to/output.java
./bin/ecrl -s path/to/program.ecr -o path/to/output.java -p com.myteam.teleop
The -p / --package flag overrides any package directive in the source file.
Run tests
just test
Language Overview
An ECRL program has three main sections:
package "org.firstinspires.ftc.teamcode.teleop"
module "MyRobot"
define {
drivetrain {
fl: "leftFront" FORWARD
fr: "rightFront" REVERSE
bl: "leftBack" FORWARD
br: "rightBack" FORWARD
}
var speed = 1.0
dc "intake"
servo "wrist"
}
teleop "Drive Mode" group "Main" {
loop {
drive(gpad1.left_stick_y, gpad1.left_stick_x, gpad1.right_stick_x)
if gpad1.square && gpad2.triangle {
robot.intake.set_power(speed)
} else if gpad1.right_trigger >= 0.5 {
robot.intake.stop()
}
robot.wrist.set_position(0.5)
robot.tel.show("Speed", "Target: #{speed}")
robot.tel.update()
}
}
!starts a line commentpackagesets the generated Java package (default:org.firstinspires.ftc.teamcode.teleop)modulesets the generated Java class namedefinedeclares hardware, variables, and the mecanum drivetrainteleopdefines the FTC@TeleOpname, group, and main loopgpad1.*maps togamepad1.*;gpad2.*maps togamepad2.*dcdeclares motors;servodeclares servosifsupports comparisons (>,<,>=,<=,==,!=),&&, and||robot.<device>.set_power/set_velocity/stopcontrols motors;set_positioncontrols servosrobot.tel.show/updatehandles telemetry
Examples
- Limelight Robotics #23574 2025-2026 TeamCode re-creation — full competition-style teleop with multiple motors
- Dual driver arm — two-gamepad setup with servos, compound conditions, and runtime variable changes
Compile an example with:
just buildrun examples/dual_driver_arm.ecr
Or the Limelight example:
just buildrun examples/limelightrobotics_2025remake.ecr
Contributing
ECRL is open to contributions! To contribute, follow these steps:
- Fork the repository here: https://codeberg.org/zanderlewis/ecrl
- Create a new branch:
git switch -c my-awesome-new-feature - Make your changes and run
just test - Commit and submit a pull request describing your changes