Tipping Point - Season code request

Worlds for the tipping point season is over.

Preserve your amazing autonomous and driver control programming forever !

As I do every year, I would like any teams that think their programing may help future generations to send me the code or (preferably) a link to a git repo I can fork, I will add to a github organization as I have done in previous years. The code can be programmed using any development system, not just VEXcode, as long as I can create a git repo for it (so blocks programs may be difficult to archive). FYI, the names of these old archives actually have nothing to do with what we now call VEXcode, I started setting these up years before we even thought of that.

code from the past six years is here

Nothing but Net - github.com/vexcode-2015
Starstruck - github.com/vexcode-2016
In the Zone - github.com/vexcode-2017
Turning point - github.com/vexcode-2018
Tower Takeover - github.com/vexcode-2019
Change Up - github.com/vexcode-2020


Well, I guess I will kick it off this year.

We are 4253B from Taipei Taiwan. The code is written by me and my teammate Jason. I worked mainly on the control algorithms, while he worked on pathing the autonomous on field. The repository below contains our code this year, which actually won us the Think Award at the Live Remote Worlds this year.

Here are some of the videos of our code:

Features (More information can be found on the readme.md file on github)

  1. Rather than using traditional tank or arcade control, we used something called curvature drive instead. Essentially, the left stick controls the throttle and the right stick controls the curvature (inverse of radius) the robot drives in. You basically control how large of an arc your robot drives in, and increasing speed doesn’t affect the rate you’re curving. (The implementation can be found in src/ryanlib/ExpandedSkidSteerModel.cpp)

  2. For autonomous, we controlled our chassis using what is called an S Curve Motion Profile. By inputting the desired distance to travel, as well as the robot’s max velocity, acceleration and jerk, it is able to generate a set of velocity that respects the robot’s kinematic constraints and travels the desired distance when followed perfectly. Since the kinematic constraints are obeyed, minimal slipping will occur, improving the overall accuracy and precision of the chassis.

  3. Our code also allows curved motions by creating trajectories. Our trajectories are generated given a bezier curve and the robot’s kinematic constraints. Similar to the S Curve Motion Profile above, it also generates a set of velocity that when followed, will follow the bezier curve perfectly. Since the trajectories are generated from our computers, then pasted into this code, so you won’t see any trajectory generation code here.

  4. Because the S Curve Motion Profiles output target velocity and acceleration, we needed some way to feed the output to the motor. We used a mainly feedforward based controller that takes into consideration the target velocity, acceleration, and position as well as the current motor state to accurately control the motor velocities. With motion profiles and our velocity controller, we were able to get our control to be within 0.1" of accuracy and basically 0 variance.

  5. Another feature of our code is that all the subsystems are asynchronous. By using threads, the control functions are all non-blocking, meaning we are able to control multiple subsystems at once, improving the efficiency of our runs. The code is also thread safe through the use of mutexes.

  6. We also made an auton selector that uses an SD Card.

  7. The code is unit checked using the unit framework included in okapi to make sure that dimensional analysis matches up.

  8. Very clean code, with everything documented and written in classes. Most of our motion control codes are contained within the ryanlib folder (which is built upon okapilib). By simply applying the library and giving new system constraints, we are able to use the same code again on different robots. For example, below are the code we use to create our S Curve Motion Profile controllers:

MotorGroup leftDrive({-3, -2});
MotorGroup rightDrive({17, 20});
ProfileConstraint moveLimit({3_ftps, 7_ftps2, 7_ftps2, 30_ftps3});

auto chassis = ChassisControllerBuilder()
    .withMotors(leftDrive, rightDrive)
    .withDimensions({AbstractMotor::gearset::green, 5.0/7.0}, {{3.25_in, 1.294_ft}, imev5BlueTPR})

auto profiler = AsyncMotionProfilerBuilder()

Future Plans

Our team is made up of 4 juniors and 1 sophomore. However, we are not sure if we will compete next year. I might just move on and mentor younger teams and continue developing my code. Most of the reusable code written this year will be incorporated into lib4253, another programming library I’ve been developing since around February last year. It includes powerful features such as pure pursuit, RAMSETE (and hopefully custom trajectory generation too), and I plan on finishing the code around summer / early Spin Up and releasing it to the public.


This is fantastic code @Ryan_4253B ! Roboteers would be well advised to include your library and learn the programming techniques you have employed!

1 Like

Thanks @Ryan_4253B
The new collection is now here.

Any code is welcome, if it’s just a VEXcode project with no repo then zip up the project and I will handle making a suitable repo for it.


Wow, amazing code! Taiwan always has the best programming.

We use PID with heading correction. Not as good as any Taiwanese powerhouse teams, but it works. (sort of)


Here’s the code from VEXU Team USC over the last few years. Not the cleanest, but it got the job done!



While our code has no major robotics innovation, I think it’s a nice basic PROS codebase. It’s also the first major robot codebase that I put together myself, so it will always be special to me.

Here are some of the cool features:


  1. OkapiLib folks (for literally all the complex drive, PID, odometry this does and UNITS are RAD!!!)
  2. PROS makers (for the framework and toolchain)
  3. EZ-Template (for the auton-selector and ideas about stuck monitoring (cool feature #3))
  4. PROS-Grafana-CLI (I used this a little bit here, I’m really excited about its potential for my spin up code)
  5. Belton High School for funding this, @pietro.giustino for teaching us and helping us do this, and my entire team for making the bot I put this code on
  6. Vex and RECF for making this even be a thing


Custom OkapiLib required for this to work:

Edit after @Mentor_355v’s post:

Yes, with OkapiLib, adding a tile = 24 inches unit can be really useful for autonomous.
I’d recommend everyone copy the following into your Okapi projects. I’ll see if they want to upstream it

namespace okapi
    constexpr QLength tile = 24 * inch;
    namespace literals
        constexpr QLength operator"" _tile(unsigned long long int x)
            return static_cast<double>(x) * tile;

        constexpr QLength operator"" _tile(long double x)
            return static_cast<double>(x) * tile;

is there a reason why you guys chose to use the S curve motion profiloling over pure pursuit?

1 Like

I really like your usage of units, including your custom “tile” unit of distance!


What exactly is a ramsete controller? I’ve heard it mentioned before in random papers I’ve read, but I’ve never found anything that actually explains how it works

1 Like

not very creative or useful, but it exists


Here’s one example implementation:

Basic idea:

Given a current Pose (x, y, heading) and a desired Pose (x1, y1, h1) and a desired velocity and curvature, return left and right wheel speeds that correct for the error between current and desired poses. Generally, the desired poses will be generated via motion profiling and include at least Pose, Velocity, Curvature (e.g. how much the robot is turning)


Got it, thank you.

1 Like

This is what I always post when someone asks what RAMSETE is. This comes from my teammate asking questions on the FRC discord.

“If it works it works”, but essentially when given a trajectory and your robot’s current position, it can modify the trajectory’s output to help better follow the path. It has gained popularity in the past few years in FRC as it is extremely robust and effective.


To add on to Ryan, RAMSETE is just a cleaner way of following paths while also adjusting to error.

Just to make sure y’all are on the same page, here is how path following usually works.

  1. Generate the trajectory - basically, a long array of the desired velocity of each side of the drive train per 10 milliseconds.
  2. Follow the trajectory step by step and change the velocity per time stamp (in this example it would be 10 ms)

An issue with this approach is that it doesn’t adjust for positional error. Let’s say at one point on the path, the robot gets pushed a little. As a result, the chassis will be slightly off for the rest of the path. Thus, many teams in vex implement Pure Pursuit.

Pure pursuit works well enough, but it’s difficult to have a very precise ending. What I mean by this is, pure pursuit will consistently get the chassis near the target, but it’s difficult for it to get to the exact position. But with RAMSETE, you are able to be quite precise and adapt for error.

  • Jason 4253B

The best part of my code base was the X drive control, but it wasn’t utilised this year :frowning:
oh the pure pursuit was quite cool too


This was my first time using GitHub and the code in there is great for beginners.


Here’s the code from MS Team 23900B.
This is the first time ever using C++ for me.
I have a custom command library for each of my motors, and a thread that prints temperatures to the robot brain every ten seconds.



I thought I recognized this code, It’s cool to see my code shared here so long after writing it! :slight_smile:

RAMSETE is a quality control algorithm, I’m glad that it’s being used more in VEX. Shameless plug - I just wrote an article on RAMSETE for the BLRS wiki to help provide some more information on how to set up a RAMSETE controller: