Announcement: Beta Release of Rust for V5 Runtime

Hello VEX world,

Queen’s VEX U Robotics Team (QUEEN) is happy to announce the beta release of our Rust for V5 runtime, which allows you to write code for the V5 brain in the Rust programming language. This is a project which VP (Technical) Tim Morland and I have been working on for a few months now, and which our team is committed to using in the future as our primary means of writing code for the V5.

Before I delve into the technical part, you can take a look at the code on our team GitLab, and view the generated API docs on Docs.RS.

What?

Rust is a general-purpose programming language which was originally developed by Mozilla Research, and now features a range of community and corporate backers, from Mozilla to Amazon and Google. It is used in a variety of projects, from Firefox’s CSS engine to parts of the Discord backend. Recently, it has steadily been expanding into the world of embedded systems, through better support for running “baremetal” (i.e., without a proper operating system).

Our project provides a means for compiling Rust code into a program which can be uploaded to the V5 and a comprehensive Rust API for interacting with hardware and building robust programs, all built on top of PROS. Currently, this includes full support for the controller inputs and smart motors, as well as a large multitasking support library and support for smart ports in generic serial mode; we will be adding support for the ADI and smart sensors over the course of the beta, with the goal of having a fully-capable version 1.0 release by April-ish.

Why?

Rust’s features give it a significant edge over C++ for almost any use-case, including robotics control systems. Like C++, it compiles to efficient machine code; unlike C++, and thanks to the fact that it’s not trying to maintain backwards-compatibility with code from the 1970s, it has a robust method of memory safety which prevents the programmer from making many common mistakes to do with object lifetimes and data races, preventing a whole class of bugs. If you never use the unsafe keyword in your code (which you should never need to as you are not writing code to interact with the underlying hardware), you will never get a “data abort exception” or any other result of incorrect memory management. Code that crashes—or doesn’t crash, but gets in some unpredictable state—can ruin your ability to compete; Rust is designed to prevent exactly this problem.

How?

The runtime works behind the scenes by calling into the PROS C API. Everything from motor outputs to spawning tasks is done this way. In this way, we are building on top of an established, trusted framework.

Note: we currently only run on Linux and Mac OS X. Windows support is Coming Soon™; you can try yourself, but your mileage may vary. The following instructions also assume you have some comfort using the command line.

Installing the Toolchain

Our entire system is built on top of PROS, so you will need all the development tools that you would need to work with PROS code (the PROS editor is not required). See the PROS getting started docs here if you don’t already have those set up.

Next, you’ll need the Rust toolchain. This can be installed from rustup.rs. This will add a command-line utility rustup to manage the Rust toolchain, as well as cargo, Rust’s package manager. Run the following command to add a Cargo utility, cargo-generate, which helps with generating Rust projects from templates:

cargo install cargo-generate

Finally, you’ll need a couple extra packages, namely libclang-dev and llvm-config (or whatever these may be called on your system). On Ubuntu, for example, you can install those with apt-get install -yqq libclang-dev llvm-config.

(If you’re interested, we also have a Docker container, used to run our CI, which includes all of these).

Writing Code

We recommend Visual Studio Code as the editor to use for Rust projects. If you use our template (see below) using VS Code, it should prompt you to install some extensions which will provide all the integrations that you’d expect from a modern development enviornment.

We’ve provided a template project to get started. To make a new project, run the following command after setting up the toolchain:

cargo generate --git https://gitlab.com/qvex/vex-rt-template.git

Once your project is created, open it in VS Code. It should prompt you to install the recommended extensions and download the latest rust-analyzer, which is the tool it uses to show you errors and warnings in your code. You can then open a terminal in it and run cargo build to compile your code, or cargo run to compile and upload. (This internally runs prosv5 ut after generating the required files.) The README.md file contains more info on that.

Contributing

If you’re interested in contributing to this project, feel free to do so via issues and merge requests on GitLab. Contact me if you have any questions about this.

Cheers,

Nick

48 Likes

In the meantime, Windows users can use WSL 2 to set up a rust environment. Popular tools for writing rust code like VS Code and CLion allow you to connect to your WSL 2 instance. You can even call out to your windows install of the PROS CLI by specifying the extension (.exe).

20 Likes

15 Likes

I just learned what this is today, and I’ve already had it come up twice. Quite odd.

3 Likes

oh wow this looks a whole lot better looking than that mistake of a “rust support” I made a couple years ago. I may have to give this a try.

3 Likes

If you are using this on a fresh install of ubuntu, normal or WSL, you may need to run

sudo apt-get install build-essential

before installing cargo-generate. Also I needed to install libssl-dev and pkg-config

3 Likes

Update: version 0.3.0 is released! In addition to some minor changes, thanks to contributions from @geometrically1, we now have support for 3-wire encoders. See an example on using them here; we’d love any feedback on the API.

9 Likes

Is this project still under active development? There hasn’t been a commit on any branch since around 4 months ago. I’d love to use it for competition, and I currently have part of a drivetrain navigation crate written for it, but it’d be nice to know if it’s still being maintained.

1 Like

Hi,

We (team QUEEN) used it last season and intend to use it this season again. We didn’t end up having time to work on it at all over the summer break (May-August for us) but we will be working to clean it up based on lessons learned from last season. A few of the younger team members are will be taking over responsibility for it from me this fall. So yes, it will still be maintained.

Glad to hear there are other teams interested in using it! Feel free to reach out if you have any questions or comments on the project.

8 Likes

That’s really great to hear! Using the runtime has been pretty smooth so far (aside from threading, which rust makes very verbose, especially for my use-case). The one thing i’ve ran into is that there doesn’t seem to be a safe way to join tasks (yet). I assume this is just because the bindings aren’t fully feature-complete yet. For now i’ve just resorted to passing around an AtomicBool to the thread to indicate when it’s ready to stop execution, then unsafely calling delete after setting the bool to false through a mutex. I’m not completely sure if this is sound to do, or if there’s a better way to join RTOS tasks currently.

Also, just as a sidenote for anyone in the future; I’ve managed to get a successful build of this (not upload, but hope to test that tomorrow) on native windows after fiddling around with toolchains. These are the things I needed:

Note: You have to check the box to add the toolchain to PATH or else uploading will fail.

  • LLVM Toolchain (https://releases.llvm.org/), because it includes libclang.
  • rustup target add armv7a-none-eabi (not completely sure if this is required, but I did it anyways).
  • For uploading: PROS CLI (needs to be in PATH as well).
  • Some way to run .sh files (I just used git bash, which ships with Git for Windows, but something like cygwin or mingw-w64 with bash would probably work too).
1 Like

Glad to hear it’s been useful! On the note of joining tasks, while we don’t have support for that specifically, there are lots of higher-level concurrency APIs that you can use. For something like that, try a Promise; you can see an example usage here.

4 Likes

This project looks nice, hope to switch my team’s robot to it, thanks for making it!
If I may ask, when do you plan to get to 1.0 release, since the Gitlab milestone is out of date?

1 Like

Glad to hear you’re interested! Good question… it’s a constant work in progress, but we are currently working on changes based on lessons learned from last season, so I expect a proper 1.0 release, will full documentation etc., sometime in the next couple months. In the meantime, the 1.0.0-beta releases do in fact work, as that is what we used at Worlds last year, as do the 0.* releases.

2 Likes